├── .gitignore ├── img ├── find.png ├── favicon.ico ├── journey.png ├── departure.png ├── isochrons.png ├── auto_complete.png ├── route_schedules.png ├── pictos │ ├── MapMarker.svg │ ├── Location.svg │ ├── CheckOut.svg │ ├── CheckIn.svg │ ├── Unknown.svg │ ├── Map.svg │ ├── Air.svg │ ├── Walking.svg │ ├── HearingImpairment.svg │ ├── Boat.svg │ ├── Metro.svg │ ├── Shuttle.svg │ ├── Escalator.svg │ ├── Train.svg │ ├── Bus.svg │ ├── Tramway.svg │ ├── Car.svg │ ├── AirConditioning.svg │ ├── Funicular.svg │ ├── Wheelchair.svg │ ├── Shelter.svg │ ├── BikeSharingService.svg │ ├── Taxi.svg │ ├── MentalDisorder.svg │ ├── Coach.svg │ ├── Elevator.svg │ ├── Bike.svg │ ├── RideSharing.svg │ ├── SchoolBus.svg │ ├── VisualImpairment.svg │ └── BikeAccepted.svg ├── duration.svg ├── save.svg ├── delete.svg ├── picto_doc.svg ├── n_playground.svg └── visuel_pro.svg ├── screenshots ├── request.png └── response.png ├── scss ├── style.scss ├── response │ ├── _response.scss │ ├── _json.scss │ ├── _button.scss │ └── _object.scss ├── _defs.scss ├── _header.scss ├── request │ └── _request.scss ├── index │ └── index.scss ├── _jquery-ui.scss └── _global.scss ├── bower.json ├── config.js ├── README.md ├── package.json ├── LICENSE ├── .travis.yml ├── app ├── file.html ├── play.html └── index.html ├── js ├── storage.js ├── pictos.js ├── utils.js ├── response.js ├── request.js ├── extended.js └── map.js ├── .jshintrc └── gulpfile.js /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /dist/ 3 | /node_modules/ 4 | *~ 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /img/find.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/img/find.png -------------------------------------------------------------------------------- /img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/img/favicon.ico -------------------------------------------------------------------------------- /img/journey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/img/journey.png -------------------------------------------------------------------------------- /img/departure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/img/departure.png -------------------------------------------------------------------------------- /img/isochrons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/img/isochrons.png -------------------------------------------------------------------------------- /img/auto_complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/img/auto_complete.png -------------------------------------------------------------------------------- /img/route_schedules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/img/route_schedules.png -------------------------------------------------------------------------------- /screenshots/request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/screenshots/request.png -------------------------------------------------------------------------------- /screenshots/response.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/navitia-playground/master/screenshots/response.png -------------------------------------------------------------------------------- /scss/style.scss: -------------------------------------------------------------------------------- 1 | @import 'defs'; 2 | @import 'global'; 3 | @import 'header'; 4 | @import 'jquery-ui'; 5 | @import 'request/request'; 6 | @import 'response/response'; 7 | @import 'response/object'; 8 | @import 'response/button'; 9 | @import 'response/json'; 10 | -------------------------------------------------------------------------------- /img/pictos/MapMarker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/duration.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scss/response/_response.scss: -------------------------------------------------------------------------------- 1 | #status { 2 | margin: 0 0 3em 0; 3 | text-align: center; 4 | } 5 | .leaflet-tooltip { 6 | background: $dark-gray; 7 | border-color: $dark-gray; 8 | color: white; 9 | font-weight: bold; 10 | } 11 | .leaflet-tooltip-left::before { 12 | border-left-color: $dark-gray; 13 | } 14 | .leaflet-tooltip-right::before { 15 | border-right-color: $dark-gray; 16 | } 17 | .leaflet-control-layers-toggle { 18 | background-image: url(../lib/img/leaflet/dist/images/layers.png); 19 | } 20 | .leaflet-retina .leaflet-control-layers-toggle { 21 | background-image: url(../lib/img/leaflet/dist/images/layers-2x.png); 22 | } 23 | -------------------------------------------------------------------------------- /scss/response/_json.scss: -------------------------------------------------------------------------------- 1 | div.object pre.renderjson { 2 | padding: 0.5em 1em; 3 | background-color: $dark-gray; 4 | color: $gray; 5 | overflow-x: auto; 6 | font-size: 1em; 7 | 8 | * { 9 | background: none; 10 | } 11 | .disclosure { 12 | font-size: 1.5em; 13 | } 14 | a { 15 | text-decoration: none; 16 | color: $light-blue; 17 | } 18 | .key { 19 | color: $light-green; 20 | } 21 | .string { 22 | color: $light-orange; 23 | } 24 | .number { 25 | color: $light-purple; 26 | } 27 | .boolean { 28 | color: $light-purple; 29 | } 30 | .keyword { 31 | color: $light-purple; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /img/pictos/Location.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "navitia playground", 3 | "description": "Web UI for the navitia API", 4 | "main": "js/request.js", 5 | "authors": [ 6 | "CanalTP" 7 | ], 8 | "license": "MIT", 9 | "homepage": "", 10 | "ignore": [ 11 | "**/.*", 12 | "node_modules", 13 | "bower_components", 14 | "test", 15 | "tests" 16 | ], 17 | "dependencies": { 18 | "jquery": "^2.2.3", 19 | "sass-core": "^0.1.7", 20 | "renderjson": "^1.2.2", 21 | "urijs": "uri.js#^1.18.0", 22 | "jquery-ui": "=1.11.4", 23 | "jqueryui-timepicker-addon": "^1.6.3", 24 | "sprintf": "=1.1.0", 25 | "leaflet": "^1.3.1", 26 | "notifyjs": "^0.4.2", 27 | "wkt2geojson": "https://github.com/CanalTP/wkt2geojson.git#gh-pages" 28 | }, 29 | "devDependencies": {} 30 | } 31 | -------------------------------------------------------------------------------- /scss/response/_button.scss: -------------------------------------------------------------------------------- 1 | div.object { 2 | label.objectButton { 3 | display: inline-block; 4 | } 5 | 6 | label.objectButton span { 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | height: 2.6em; 11 | width: 2.6em; 12 | margin-left: 0.25em; 13 | border: none; 14 | border-radius: 0.25em; 15 | text-align:center; 16 | background-color: $light-gray; 17 | color: $dark-gray; 18 | font: 1em; 19 | text-transform: uppercase; 20 | font-weight: bold; 21 | cursor: pointer; 22 | } 23 | 24 | label.objectButton input { 25 | display: none; 26 | } 27 | 28 | label.objectButton input:checked + span { 29 | background-color: $dark-blue; 30 | color: white; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /img/pictos/CheckOut.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /img/pictos/CheckIn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /img/pictos/Unknown.svg: -------------------------------------------------------------------------------- 1 | picto_what -------------------------------------------------------------------------------- /img/pictos/Map.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | var src = 'app'; 2 | var build = 'dist'; 3 | var dev = build + '/dev'; 4 | var prod = build + '/prod'; 5 | 6 | 7 | module.exports = { 8 | dev: dev, 9 | prod: prod, 10 | browsersync: { 11 | dev: { 12 | server: { 13 | baseDir: [dev, build, src] 14 | }, 15 | port: 4242, 16 | files: [ 17 | dev + '/*.html', 18 | dev + '/css/**', 19 | dev + '/js/*.js', 20 | dev + '/img/**', 21 | dev + '/fonts/*' 22 | ] 23 | }, 24 | prod: { 25 | server: { 26 | baseDir: [prod, build, src] 27 | }, 28 | port: 4243, 29 | files: [ 30 | prod + '/css/*.css', 31 | prod + '/js/*.js', 32 | prod + '/img/**', 33 | prod + '/fonts/*' 34 | ] 35 | } 36 | }, 37 | del : { 38 | all: [build], 39 | dev: [dev], 40 | prod: [prod] 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /scss/_defs.scss: -------------------------------------------------------------------------------- 1 | @function set-lightness($color, $lightness) { 2 | @return hsl(hue($color), saturation($color), $lightness) 3 | } 4 | @function very-light($color) { 5 | @return set-lightness($color, 93%) 6 | } 7 | @function light($color) { 8 | @return set-lightness($color, 80%) 9 | } 10 | @function dark($color) { 11 | @return set-lightness($color, 45%) 12 | } 13 | 14 | $gray: #DEDEDE; 15 | $light-gray: #EFEFEF; 16 | $dark-gray: #353535; 17 | 18 | $blue: #89C6E5; 19 | $light-blue: light($blue); 20 | $dark-blue: dark($blue); 21 | 22 | $purple: #CBB6E4; 23 | $light-purple: light($purple); 24 | $dark-purple: dark($purple); 25 | 26 | $orange: #EFBF8F; 27 | $light-orange: light($orange); 28 | $dark-orange: dark($orange); 29 | 30 | $green: #CED480; 31 | $light-green: light($green); 32 | $dark-green: dark($green); 33 | 34 | $yellow: #D0A900; 35 | $light-yellow: light($yellow); 36 | $dark-yello: dark($yellow); 37 | 38 | $red: red; 39 | $light-red: light($red); 40 | $dark-red: dark($red); 41 | -------------------------------------------------------------------------------- /img/pictos/Air.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /img/save.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![navitia playground](https://rawgithub.com/CanalTP/navitia-playground/master/img/n_playground.svg) [![Build status](https://travis-ci.org/CanalTP/navitia-playground.svg?branch=master)](https://travis-ci.org/CanalTP/navitia-playground) 2 | 3 | Web UI for the [navitia](https://github.com/CanalTP/navitia) API. You can get a token [here](http://www.navitia.io) and then use this UI [here](http://canaltp.github.io/navitia-playground/). 4 | 5 | ## Screenshots 6 | 7 | ![Request](screenshots/request.png) ![Response](screenshots/response.png) 8 | 9 | ## Setting your dev environment to contribute 10 | 11 | ### Requirements 12 | - node v8.x LTS ([nvm](https://github.com/creationix/nvm) is recommanded for installing node) 13 | 14 | ### Installation 15 | ```bash 16 | npm install && npx bower install 17 | ``` 18 | 19 | ### Launch the application 20 | ```bash 21 | npx gulp dev 22 | ``` 23 | 24 | ## License 25 | 26 | This project is under the [MIT license](LICENSE). See the [bower file](bower.json) for the running dependencies and the [npm file](package.json) for dev dependencies. 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "navitia-playground", 3 | "version": "0.0.1", 4 | "description": "Web UI for the navitia API", 5 | "main": "request.js", 6 | "dependencies": { 7 | "gulp-jslint": "^1.0.1" 8 | }, 9 | "devDependencies": { 10 | "bower": "^1.8.2", 11 | "browser-sync": "^2.12.7", 12 | "del": "^2.2.0", 13 | "gulp": "^3.9.1", 14 | "gulp-bower-src": "^0.1.0", 15 | "gulp-clean-css": "^2.0.7", 16 | "gulp-concat": "^2.6.0", 17 | "gulp-filter": "^4.0.0", 18 | "gulp-htmlmin": "^2.0.0", 19 | "gulp-if": "^2.0.1", 20 | "gulp-image": "^1.3.1", 21 | "gulp-jshint": "^2.0.1", 22 | "gulp-order": "^1.1.1", 23 | "gulp-rename": "^1.2.2", 24 | "gulp-sass": "^4.0.1", 25 | "gulp-uglify": "^1.5.3", 26 | "gulp-useref": "^3.1.0", 27 | "jshint": "^2.9.2", 28 | "jshint-stylish": "^2.2.0", 29 | "main-bower-files": "^2.13.0", 30 | "run-sequence": "^1.1.5" 31 | }, 32 | "scripts": { 33 | "test": "echo \"Error: no test specified\" && exit 1" 34 | }, 35 | "author": "CanalTP", 36 | "license": "MIT" 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 CanalTP 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /img/pictos/Walking.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: "8" 3 | sudo: false 4 | before_script: 5 | - npx bower install 6 | script: npx gulp dev:build && npx gulp prod:build 7 | after_success: | 8 | [ $TRAVIS_BRANCH = master ] && 9 | [ $TRAVIS_PULL_REQUEST = false ] && 10 | pip install --user ghp-import && 11 | export PATH="$PATH:$HOME/.local/bin" && 12 | ghp-import -n dist/dev && 13 | git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages 14 | env: 15 | global: 16 | - secure: Ap8pEa4SHNuLPjcEF15MnCnTpyEFnpaLOAtk6P3W1ufvPjS/VBnwmUbHlxuXoo8n403QmCx8XUwMD0zTt3C0qp07RZ0LaG0BtMMdzNVLGhLiLxn52+6c13jhRZKV/nifwAlTIrgvqI/rzKFRSWS0cH/Ty2w+uz9TmgNBwlw3gItd7MB+JZchR+uGV0BUiSyTeTkbo/xbVpNLOksbu6T2ub/WO35neKM6kcBdbQuO0g02+3p5kWz1zcLx25tQlRViyIR5g2PVNiho2SYHOp3/C/oZz1Gpv5Mlcd3dDhLHb8m4KJ5tyIjDW2f+SkaiSocfJtn9jtFshsjwSxPjYMgV0lLEbgLBnGJhQuGnGWkcGxEAec72kIJUYe9L5lW5t5vdaoOdDZ5el+eg83ob/tfcyO0iZLDv3o/HxAbkioHI01JGcxamnPcYGmyeliNTjUTyKyD0yTM52unuNrdh0QOKKLeTf3zSANjgi4kYrwWWnO9imbAOT8C4LIsiXozQokD/APYi425SbSsG1UTJteTe/CHx6x8eRajzhMFjqi9z4+EL03k7JTynL99xGP6+TcHPU22gsG/0Tcz0HFbJM09en6OVVystP2dPqfcQGNOHGgR7SzjH1rU38o+2selQc7Kb86GKtKVGaa3DMEH4h5qL/cpVvPqYazBGfSLE/fv3wO0= 17 | -------------------------------------------------------------------------------- /img/delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /img/pictos/HearingImpairment.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/pictos/Boat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 14 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /img/pictos/Metro.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 14 | 15 | 17 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /img/pictos/Shuttle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /img/pictos/Escalator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/pictos/Train.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /img/pictos/Bus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /img/pictos/Tramway.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 14 | 15 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /img/pictos/Car.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /img/pictos/AirConditioning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/pictos/Funicular.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 14 | 16 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /scss/_header.scss: -------------------------------------------------------------------------------- 1 | #header{ 2 | width: 100%; 3 | background: #FFF; 4 | height: 6em; 5 | padding: 0; 6 | margin: 0; 7 | display: flex; 8 | flex-flow: row; 9 | justify-content: space-between; 10 | border-bottom: solid 0.15em $light-gray; 11 | } 12 | 13 | #back{ 14 | padding: 0; 15 | } 16 | 17 | #logo{ 18 | width: 23em; 19 | height: auto; 20 | margin: 1.2em 0 0 1.6em; 21 | } 22 | 23 | #picto{ 24 | vertical-align: middle; 25 | height: 3ex; 26 | width: 3ex; 27 | } 28 | 29 | #doc{ 30 | float: left; 31 | padding: 2.1em 1.6em 0 1em; 32 | border-top: solid 0.4em transparent; 33 | text-transform: uppercase; 34 | text-decoration: none; 35 | color: $dark-gray; 36 | } 37 | 38 | #doc:hover{ 39 | border-top: solid 0.4em $dark-blue; 40 | color: $dark-gray; 41 | } 42 | 43 | li{ 44 | list-style: none; 45 | } 46 | 47 | #urlheader{ 48 | margin: 1.6em; 49 | } 50 | 51 | @media screen and (max-width:62em) { 52 | #urlheader{ 53 | display: none; 54 | } 55 | } 56 | 57 | @media screen and (max-width:33.438em) { 58 | #header{ 59 | flex-direction: column; 60 | height: auto; 61 | } 62 | #logo{ 63 | float: left; 64 | margin: 0 0 0 1em; 65 | width: 15em; 66 | } 67 | #picto{ 68 | height: 2.5ex; 69 | width: 2.5ex; 70 | margin: 0 auto; 71 | padding: 0.05em 0.2em 0 1.3em; 72 | } 73 | #doc{ 74 | padding: 0em 1em 0.5em 1em; 75 | margin: 0 auto; 76 | border-bottom: solid 0.2em transparent; 77 | border-top: none; 78 | } 79 | #doc:hover{ 80 | border-bottom: solid 0.2em $dark-blue; 81 | border-top: none; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /img/pictos/Wheelchair.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/pictos/Shelter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/pictos/BikeSharingService.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 23 | 24 | -------------------------------------------------------------------------------- /img/pictos/Taxi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 14 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /img/picto_doc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | picto_doc 9 | 10 | 16 | 18 | 20 | 22 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /img/pictos/MentalDisorder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/pictos/Coach.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 24 | 25 | -------------------------------------------------------------------------------- /img/pictos/Elevator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /scss/request/_request.scss: -------------------------------------------------------------------------------- 1 | #request { 2 | background-color: white; 3 | overflow-x: hidden; 4 | 5 | #credentials, #path, #parameters { 6 | display: flex; 7 | flex-flow: row wrap; 8 | width: calc(100% + 1em); 9 | height: auto; 10 | } 11 | 12 | .templateInput { 13 | box-shadow: 0 0 0.5em $dark-blue; 14 | } 15 | 16 | button::-moz-focus-inner { 17 | border-style: none; 18 | padding: 0; 19 | } 20 | 21 | @mixin request-parts($color) { 22 | .key { 23 | background-color: very-light($color); 24 | } 25 | .inputDiv { 26 | border-color: dark($color); 27 | border-radius: 0.25em 0.25em 0 0; 28 | } 29 | .templateInput { 30 | box-shadow: 0 0 0.5em dark($color); 31 | } 32 | .inputDiv button { 33 | color: dark($color); 34 | } 35 | .inputDiv button:disabled { 36 | color: $gray; 37 | } 38 | .tooltips { 39 | white-space: nowrap; 40 | } 41 | } 42 | #credentials { @include request-parts($orange); } 43 | #path { @include request-parts($green); } 44 | #parameters { @include request-parts($blue); } 45 | #feature.inputDiv { border-color: $dark-purple; } 46 | 47 | #urlDiv { 48 | width: 100%; 49 | } 50 | #requestUrl{ 51 | margin: 0.5em; 52 | overflow-x: auto; 53 | a { 54 | color: inherit; 55 | } 56 | 57 | @mixin url-colors($color) { 58 | background-color: light($color); 59 | 60 | .focusedParam { 61 | background-color: dark($color); 62 | color: white; 63 | } 64 | } 65 | 66 | .api { @include url-colors($orange); } 67 | .path { @include url-colors($green); } 68 | .feature { @include url-colors($purple); } 69 | .parameters { @include url-colors($blue); } 70 | } 71 | #submitDiv { 72 | text-align: center; 73 | margin: 0 0 1.25em 0; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /img/pictos/Bike.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 14 | 24 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/file.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | navitia playground 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 34 | 35 |
36 | 37 |
38 |
39 |

Give your Json

40 |

41 | 42 | 43 |

44 | 45 |

or drag it on the page.

46 |
47 |
48 | 49 |
50 | 51 |
52 |
53 |

Explore the response

54 |
Waiting for your Json...
55 |
56 |
57 |
58 |
59 | 60 | 65 | 66 | 67 | 68 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /img/pictos/RideSharing.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /img/pictos/SchoolBus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/pictos/VisualImpairment.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /scss/index/index.scss: -------------------------------------------------------------------------------- 1 | @import '../defs'; 2 | @import '../global'; 3 | @import '../header'; 4 | 5 | #raw{ 6 | display: flex; 7 | width: 100%; 8 | flex-flow: row wrap; 9 | overflow:auto; 10 | } 11 | 12 | .col{ 13 | display: flex; 14 | width: 65%; 15 | flex-flow: row wrap; 16 | background: $light-gray; 17 | padding: 0 0 3em 0; 18 | } 19 | 20 | #krakensuperhero{ 21 | display: flex; 22 | flex-flow: row; 23 | margin: 0 auto; 24 | width: 21.875em; 25 | height: 11.813em; 26 | padding: 2em 0 1em 0; 27 | } 28 | 29 | .col > h2{ 30 | width: 100%; 31 | } 32 | 33 | h2{ 34 | width: auto; 35 | font-weight: normal; 36 | color: #353535; 37 | text-align: center; 38 | margin: 0; 39 | padding: 2em 0; 40 | } 41 | 42 | h3{ 43 | font-weight: normal; 44 | font-size: 100%; 45 | padding: 0; 46 | text-align: center; 47 | } 48 | 49 | .pictofeatures{ 50 | height: 4em; 51 | width: 4em; 52 | } 53 | 54 | .rubriques{ 55 | display: flex; 56 | flex-direction: column; 57 | padding: 0 1em 1em 1em; 58 | margin: 0 auto; 59 | width: 20em; 60 | 61 | a::before { 62 | float: right; 63 | content: ">"; 64 | } 65 | a{ 66 | display: list-item; 67 | list-style-type: none; 68 | font-family: 'OpenSans', sans-serif; 69 | text-decoration: none; 70 | text-align: left; 71 | padding: 0.5em 1em 0.5em 2em; 72 | margin: 0; 73 | color: $dark-gray; 74 | } 75 | a:hover{ 76 | color: $dark-blue; 77 | } 78 | } 79 | 80 | 81 | /* --------------------------------- 82 | PRO 83 | --------------------------------- */ 84 | #urlForm{ 85 | width: 35%; 86 | background: #FFF; 87 | padding-bottom: 2em; 88 | } 89 | 90 | #urlForm form{ 91 | text-align: center; 92 | padding: 1em 0; 93 | margin: 0; 94 | } 95 | 96 | #urlinput{ 97 | width: 100%; 98 | } 99 | 100 | #urlDiv.inputDiv{ 101 | margin: 1.2em 2.5em; 102 | width: auto; 103 | } 104 | 105 | .or{ 106 | display: flex; 107 | flex-flow: row; 108 | margin: 0 auto; 109 | } 110 | 111 | .or form { 112 | width: 100%; 113 | margin: 0 auto; 114 | } 115 | 116 | .ou{ 117 | text-align: center; 118 | } 119 | 120 | button{ 121 | margin: 0 auto; 122 | } 123 | 124 | /* --------------------------------- 125 | RESPONSIVE 126 | --------------------------------- */ 127 | @media screen and (max-width: 64em) { 128 | .col, #urlForm{ 129 | width: 100%; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /scss/_jquery-ui.scss: -------------------------------------------------------------------------------- 1 | .ui-widget, .notifyjs-navitia-base { 2 | border-style: solid; 3 | border-width: 0.1ex; 4 | border-color: $gray; 5 | background: white; 6 | box-shadow: 0 0 0.5em rgba(0,0,0,0.2); 7 | } 8 | .notifyjs-navitia-base { 9 | font-weight: bold; 10 | padding: 0.5em; 11 | } 12 | .ui-widget-header { 13 | border-style: solid; 14 | border-width: 0 0 0.1ex 0; 15 | border-color: $gray; 16 | background: $light-gray; 17 | padding: 0.5em; 18 | } 19 | .ui-helper-hidden-accessible { 20 | display: none; 21 | } 22 | 23 | .ui-autocomplete { 24 | max-height: 20em; 25 | overflow-y: auto; 26 | padding: 0; 27 | position: absolute; 28 | .ui-menu-item { 29 | padding: 0.2em 0.5em; 30 | line-height: 1.5em; 31 | } 32 | .ui-state-focus { 33 | background: $light-blue; 34 | } 35 | } 36 | 37 | .ui-datepicker-header { 38 | span.ui-icon { 39 | display: none; 40 | } 41 | a { 42 | color: inherit; 43 | text-decoration: none; 44 | } 45 | a.ui-datepicker-prev:after { 46 | content: '<'; 47 | } 48 | a.ui-datepicker-prev { 49 | display: block; 50 | float: left; 51 | cursor: pointer; 52 | } 53 | a.ui-datepicker-next:after { 54 | content: '>'; 55 | } 56 | a.ui-datepicker-next { 57 | display: block; 58 | float: right; 59 | cursor: pointer; 60 | } 61 | .ui-datepicker-title { 62 | text-align: center; 63 | } 64 | } 65 | 66 | table.ui-datepicker-calendar { 67 | width: 100%; 68 | border-spacing: 0.5em; 69 | a { 70 | color: inherit; 71 | text-decoration: none; 72 | } 73 | td { 74 | text-align: right; 75 | } 76 | .ui-datepicker-today { 77 | font-weight: bold; 78 | } 79 | .ui-datepicker-current-day { 80 | background: $light-blue; 81 | } 82 | } 83 | 84 | .ui-timepicker-div.ui-timepicker-oneLine { 85 | padding: 0.5em; 86 | dl { 87 | margin: 0; 88 | } 89 | dt.ui_tpicker_time_label { 90 | padding: 0.5em; 91 | padding-left: 0; 92 | } 93 | select { 94 | background: $light-gray; 95 | border: 0.1em solid $gray; 96 | padding: 0.3em; 97 | font-family: inherit; 98 | font-size: inherit; 99 | } 100 | } 101 | 102 | .ui-datepicker-buttonpane { 103 | padding: 0.5em; 104 | button { 105 | padding: 0.5em; 106 | } 107 | button.ui-datepicker-close { 108 | float: right; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /img/pictos/BikeAccepted.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /scss/_global.scss: -------------------------------------------------------------------------------- 1 | body { 2 | color: $dark-gray; 3 | background-color: $light-gray; 4 | margin: 0; 5 | padding-bottom: 3.2em; 6 | font-family: 'OpenSans', sans-serif; 7 | font-size: 100%; 8 | min-height: calc(100vh - 3.2em); 9 | position: relative; 10 | } 11 | 12 | footer { 13 | position: absolute; 14 | bottom: 0; 15 | left: 0; 16 | width: 100%; 17 | text-align: center; 18 | padding: 1em 0; 19 | line-height: 1.2em; 20 | background-color: $dark-gray; 21 | color: $light-gray; 22 | 23 | a { 24 | color: inherit; 25 | } 26 | } 27 | 28 | h2 { 29 | text-align: center; 30 | margin: 1.5em 0 1em 0; 31 | font-size: 1.5em; 32 | } 33 | 34 | p.center { 35 | text-align: center; 36 | margin: 2em 0; 37 | } 38 | 39 | #content { 40 | margin: 0; 41 | } 42 | 43 | .hContainer { 44 | padding: 0.5em; 45 | max-width: 103em; 46 | margin: auto; 47 | } 48 | 49 | #give { 50 | background: white; 51 | 52 | #file-input { 53 | display: none; 54 | } 55 | #file-input + label { 56 | padding: 0.5em 2em; 57 | border: none; 58 | border-radius: 0.25em; 59 | color: white; 60 | background-color: $dark-blue; 61 | text-transform: uppercase; 62 | font: inherit; 63 | font-weight: bold; 64 | cursor: pointer; 65 | } 66 | } 67 | 68 | hr { 69 | display: block; 70 | height: 0; 71 | width: 0; 72 | margin: 0 auto -1em auto; 73 | border-style: solid; 74 | border-width: 2em 2em 0 2em; 75 | border-color: white transparent transparent transparent; 76 | } 77 | 78 | button { 79 | padding: 0.5em 2em; 80 | margin: 0 0.5em; 81 | border: none; 82 | border-radius: 0.25em; 83 | color: white; 84 | background-color: $dark-blue; 85 | text-transform: uppercase; 86 | font: inherit; 87 | font-weight: bold; 88 | } 89 | 90 | :focus { 91 | outline: 0.05em dotted $dark-gray; 92 | outline-offset: -0.05em; 93 | } 94 | 95 | a { 96 | color: $dark-blue; 97 | text-decoration: underline; 98 | } 99 | 100 | .inputDiv { 101 | display: flex; 102 | flex-flow: row nowrap; 103 | align-items: stretch; 104 | width: 25em; 105 | margin: 0 1em 1.25em 0; 106 | padding: 0; 107 | line-height: 1.2em; 108 | background-color: white; 109 | border-style: solid; 110 | border-width: 0 0 0.2em 0; 111 | border-color: $light-gray; 112 | 113 | input { 114 | width: 100%; 115 | min-width: 5em; 116 | border: none; 117 | padding: 0.5em; 118 | background-color: transparent; 119 | font: inherit; 120 | text-overflow: ellipsis; 121 | } 122 | .key { 123 | margin: 0; 124 | padding: 0.5em; 125 | font-weight: bold; 126 | background-color: $light-gray; 127 | border-radius: 0.25em 0 0 0; 128 | } 129 | button { 130 | background-color: transparent; 131 | width: auto; 132 | height: auto; 133 | padding: 0.5em 0.25em; 134 | margin: 0; 135 | font: inherit; 136 | font-weight: bold; 137 | color: $dark-blue; 138 | text-transform: uppercase; 139 | } 140 | button:disabled { 141 | color: $gray; 142 | } 143 | button img { 144 | vertical-align: text-top; 145 | height: 1.2em; 146 | } 147 | button:disabled img { 148 | opacity: 0.2; 149 | } 150 | } 151 | 152 | -------------------------------------------------------------------------------- /js/storage.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 CanalTP 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in all 11 | // copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | // SOFTWARE. 20 | 21 | 'use strict'; 22 | 23 | // fake includes 24 | var request; 25 | 26 | var storage = {}; 27 | 28 | storage._storagePrefix = 'navitia-playground.'; 29 | storage._apiStoragePrefix = storage._storagePrefix + 'api.'; 30 | storage._layerStorageKey = storage._storagePrefix + 'layer'; 31 | storage._boundsStorageKey = storage._storagePrefix + 'bounds'; 32 | 33 | storage._localStorageAvailable = function() { 34 | try { 35 | var x = '__storage_test__'; 36 | window.localStorage.setItem(x, x); 37 | window.localStorage.removeItem(x); 38 | return true; 39 | } 40 | catch(e) { 41 | return false; 42 | } 43 | }; 44 | 45 | storage.getApis = function() { 46 | if (! storage._localStorageAvailable()) { return []; } 47 | var apis = []; 48 | for (var elt in window.localStorage) { 49 | if (elt.indexOf(storage._apiStoragePrefix) === 0 ) { 50 | apis.push(elt.slice(storage._apiStoragePrefix.length)); 51 | } 52 | } 53 | return apis; 54 | }; 55 | 56 | storage.saveTokenFromRequest = function() { 57 | var api = $('input.api').val(); 58 | var token = $('input.token').val(); 59 | storage.saveToken(api, token); 60 | }; 61 | 62 | storage.saveToken = function(api, token) { 63 | if (! storage._localStorageAvailable()) { return; } 64 | var key = storage._apiStoragePrefix + api; 65 | window.localStorage.setItem(key, token); 66 | request.setSaveTokenButtonStatus(); 67 | }; 68 | 69 | storage.getToken = function(api) { 70 | if (! storage._localStorageAvailable()) { return; } 71 | return window.localStorage.getItem(storage._apiStoragePrefix + api); 72 | }; 73 | 74 | storage.saveLayer = function(data) { 75 | if (! storage._localStorageAvailable()) { return; } 76 | window.localStorage.setItem(storage._layerStorageKey, data.name); 77 | }; 78 | 79 | storage.getLayer = function() { 80 | if (! storage._localStorageAvailable()) { return null; } 81 | return window.localStorage.getItem(storage._layerStorageKey); 82 | }; 83 | 84 | storage.saveBounds = function(bounds) { 85 | if (! storage._localStorageAvailable()) { return; } 86 | var data = [ 87 | [bounds.getSouth(), bounds.getWest()], 88 | [bounds.getNorth(), bounds.getEast()] 89 | ]; 90 | window.localStorage.setItem(storage._boundsStorageKey, JSON.stringify(data)); 91 | }; 92 | 93 | storage.getBounds = function() { 94 | if (! storage._localStorageAvailable()) { return null; } 95 | return JSON.parse(window.localStorage.getItem(storage._boundsStorageKey)); 96 | }; 97 | -------------------------------------------------------------------------------- /scss/response/_object.scss: -------------------------------------------------------------------------------- 1 | .with-bg-color { 2 | display: inline-block; 3 | border: none; 4 | border-radius: 3em;// more than height/2 to have circle borders 5 | text-align: center;// to have the code centered if smaller than min-width 6 | 7 | // min-width + 2 * horizontal padding == line-height + 2 * vertical padding 8 | // to have a circle if small enough 9 | line-height: 1.2em; 10 | min-width: 1em; 11 | padding: 0.2em 0.3em; 12 | } 13 | 14 | .old-datetime { 15 | text-decoration: line-through; 16 | } 17 | 18 | .outofdate, .error { 19 | color: $dark-red; 20 | } 21 | .almost_outofdate { 22 | color: $dark-orange; 23 | } 24 | 25 | .stands-status.unavailable { 26 | color: $dark-orange; 27 | } 28 | 29 | .stands-status.closed { 30 | color: $dark-red; 31 | } 32 | 33 | img.picto { 34 | vertical-align: middle; 35 | height: 1.6em;// height of line_code 36 | } 37 | 38 | .mode-and-code { 39 | white-space: nowrap; 40 | } 41 | 42 | .section-additional-block { 43 | white-space: nowrap; 44 | } 45 | .section-additional-block:before { 46 | content: " "; 47 | word-spacing: 2em; 48 | white-space: normal; 49 | } 50 | 51 | div.object { 52 | margin: 0.5em 0 0.5em 1em; 53 | padding: 0; 54 | border-style: solid; 55 | border-width: 0 0 0 0.2em; 56 | border-color: $dark-blue; 57 | 58 | div.head { 59 | display: flex; 60 | flex-flow: row nowrap; 61 | justify-content: space-between; 62 | align-items: stretch; 63 | background-color: white; 64 | border-radius: 0 0.25em 0.25em 0; 65 | } 66 | div.name, div.button, div.summary { 67 | display: flex; 68 | align-items: center; 69 | padding: 0.5em; 70 | } 71 | div.name { 72 | font-weight: bold; 73 | padding: 0.5em 1em; 74 | a { 75 | color: inherit; 76 | } 77 | } 78 | div.summary { 79 | flex: 1; 80 | padding: 0.5em 1em; 81 | } 82 | div.data { 83 | border-style: none; 84 | margin: 0; 85 | padding: 0; 86 | } 87 | div.leaflet, .renderjson { 88 | margin: 0.5em 0; 89 | border-radius: 0 0.25em 0.25em 0; 90 | } 91 | 92 | div.leaflet { 93 | height: 80vh; 94 | } 95 | 96 | div.table { 97 | overflow-x: auto; 98 | margin: 0.5em 0 0.5em 0.5em; 99 | 100 | table { 101 | background-color: white; 102 | border-spacing: 0; 103 | border-collapse: collapse; 104 | text-align: center; 105 | 106 | th { 107 | font-weight: bold; 108 | padding: 0.5ex; 109 | border: 0.1ex solid $gray; 110 | color: inherit; 111 | } 112 | 113 | td { 114 | padding: 0.5ex; 115 | border: 0.1ex solid $gray; 116 | white-space: nowrap; 117 | } 118 | 119 | td.stop-point { 120 | text-align: right; 121 | } 122 | 123 | td.time { 124 | text-align: left; 125 | } 126 | } 127 | } 128 | } 129 | 130 | @mixin object-color($color) { 131 | border-color: dark($color); 132 | div.name { 133 | background-color: very-light($color); 134 | } 135 | } 136 | 137 | // Will generate something like ($a n + $b as in nth-child): 138 | // div.object{$a n + $b} { @include object-color($color); } 139 | // with a limit of depth 10, i.e. for $a = 3 and $b = 2: 140 | // div.object div.object, 141 | // div.object div.object div.object div.object div.object, 142 | // div.object div.object div.object div.object div.object div.object div.object div.object { 143 | // @include object-color($color); 144 | // } 145 | @mixin deep-object($a, $b, $color) { 146 | $res: ''; 147 | $selector: ''; 148 | @for $i from 1 through 10 { 149 | $selector: $selector + ' div.object'; 150 | @if $i % $a == $b { 151 | @if $res != '' { $res: $res + ', ' } 152 | $res: $res + $selector; 153 | } 154 | } 155 | @if $res != '' { 156 | #{$res} { @include object-color($color); } 157 | } 158 | } 159 | 160 | @include deep-object(2, 1, $blue); 161 | @include deep-object(2, 0, $yellow); 162 | 163 | @media screen and (max-width:35em) { 164 | div.object { 165 | margin-left: 1em; 166 | div.head { 167 | flex-wrap: wrap; 168 | } 169 | div.summary { 170 | order: 3; 171 | min-width: 80%; 172 | } 173 | } 174 | } 175 | 176 | #data > div { 177 | margin: 0; 178 | } 179 | -------------------------------------------------------------------------------- /js/pictos.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 CanalTP 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in all 11 | // copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | // SOFTWARE. 20 | 21 | 'use strict'; 22 | 23 | var pictos = {}; 24 | 25 | pictos.makePtPicto = function(json) { 26 | if ($.isArray(json)) { 27 | var res = $(''); 28 | json.forEach(function(elt) { 29 | res.append(pictos.makePtPicto(elt)); 30 | }); 31 | return res; 32 | } 33 | 34 | if (!(json instanceof Object) || !('id' in json)) { 35 | return $(''); 36 | } 37 | var img = 'Unknown'; 38 | switch (json.id) { 39 | case 'physical_mode:Air': img = 'Air'; break; 40 | case 'physical_mode:Bike': img = 'Bike'; break; 41 | case 'physical_mode:BikeSharingService': img = 'BikeSharingService'; break; 42 | case 'physical_mode:Car': img = 'Car'; break; 43 | case 'physical_mode:Coach': img = 'Coach'; break; 44 | case 'physical_mode:Funicular': img = 'Funicular'; break; 45 | case 'physical_mode:Metro': img = 'Metro'; break; 46 | case 'physical_mode:Taxi': img = 'Taxi'; break; 47 | case 'physical_mode:Tramway': img = 'Tramway'; break; 48 | case 'physical_mode:Walking': img = 'Walking'; break; 49 | case 'physical_mode:CheckIn': img = 'CheckIn'; break; 50 | case 'physical_mode:CheckOut': img = 'CheckOut'; break; 51 | case 'physical_mode:Shuttle': img = 'Shuttle'; break; 52 | 53 | case 'physical_mode:Bus': 54 | case 'physical_mode:BusRapidTransit': 55 | case 'physical_mode:Trolleybus': 56 | img = 'Bus'; break; 57 | 58 | case 'physical_mode:RapidTransit': 59 | case 'physical_mode:LocalTrain': 60 | case 'physical_mode:LongDistanceTrain': 61 | case 'physical_mode:Train': 62 | img = 'Train'; break; 63 | 64 | case 'physical_mode:Boat': 65 | case 'physical_mode:Ferry': 66 | img = 'Boat'; break; 67 | 68 | default: 69 | break; 70 | } 71 | 72 | return pictos.makeImg(img, json.name); 73 | }; 74 | 75 | pictos.makeImg = function(img, name) { 76 | return pictos.makeImgFromUrl(sprintf('img/pictos/%s.svg', img), name); 77 | }; 78 | 79 | pictos.makeImgFromUrl = function(img, name) { 80 | var tag = $('') 81 | .addClass('picto') 82 | .attr('src', img); 83 | if (name) { tag.attr('alt', name); tag.attr('title', name); } 84 | return tag; 85 | }; 86 | 87 | pictos.makeSnPicto = function(mode) { 88 | var img = 'Unknown'; 89 | if (mode === 'walking') { 90 | img = 'Walking'; 91 | } else if (mode === 'bike') { 92 | img = 'Bike'; 93 | } else if (mode.indexOf('bss') === 0) { 94 | img = 'BikeSharingService'; 95 | } else if (mode === 'car' || mode === 'park' || mode === 'leave_parking') { 96 | img = 'Car'; 97 | } else if (mode === 'ridesharing') { 98 | img = 'RideSharing'; 99 | } 100 | return pictos.makeImg(img, mode); 101 | }; 102 | 103 | pictos.makeEquipmentPicto = function(equipment) { 104 | var img = 'Unknown'; 105 | switch (equipment) { 106 | case 'has_wheelchair_accessibility': 107 | case 'has_wheelchair_boarding': 108 | img = 'Wheelchair'; break; 109 | case 'has_bike_accepted': 110 | case 'has_bike_depot': 111 | img = 'BikeAccepted'; break; 112 | case 'has_air_conditioned': img = 'AirCoditioning'; break; 113 | case 'has_visual_announcement': img = 'HearingImpairment'; break; 114 | case 'has_audible_announcement': img = 'VisualImpairment'; break; 115 | case 'has_appropriate_escort': img = ''; break; 116 | case 'has_appropriate_signage': img = 'MentalDisorder'; break; 117 | case 'has_school_vehicle': img = 'SchoolBus'; break; 118 | case 'has_elevator': img = 'Elevator'; break; 119 | case 'has_escalator': img = 'Escalator'; break; 120 | case 'has_sheltered': img = 'Shelter'; break; 121 | } 122 | return pictos.makeImg(img, equipment); 123 | }; 124 | -------------------------------------------------------------------------------- /app/play.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | navitia playground 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 34 | 35 |
36 |
37 |
38 |

Create a request

39 |
40 |

Fill out credential info

41 |
42 |
43 | API 44 | 50 |
51 |
52 | Token 53 | 54 | 58 |
59 |
60 |
61 |
62 |

Build your path

63 |
64 |
65 | 70 | 71 |
72 |
73 | 79 |
80 |
81 |
82 |
83 |

Add parameters

84 |
85 |
86 | 91 | 92 |
93 |
94 |
95 |
96 |

Send the request

97 |
98 |
URL
99 |
100 |
101 |
102 | 103 | or Ctrl+Enter 104 |
105 |
106 |
107 |
108 | 109 |
110 | 111 |
112 |
113 |

Explore the response

114 |
Loading...
115 |
116 |
117 |
118 |
119 | 120 | 125 | 126 | 127 | 128 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // JSHint Default Configuration File (as on JSHint website) 3 | // See http://jshint.com/docs/ for more details 4 | 5 | "maxerr" : 50, // {int} Maximum error before stopping 6 | 7 | // Enforcing 8 | "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) 9 | "camelcase" : false, // true: Identifiers must be in camelCase 10 | "curly" : true, // true: Require {} for every new block or scope 11 | "eqeqeq" : true, // true: Require triple equals (===) for comparison 12 | "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() 13 | "freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc. 14 | "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` 15 | "latedef" : true, // true: Require variables/functions to be defined before being used 16 | "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()` 17 | "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` 18 | "noempty" : true, // true: Prohibit use of empty blocks 19 | "nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters. 20 | "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment) 21 | "plusplus" : false, // true: Prohibit use of `++` and `--` 22 | "quotmark" : "single", // Quotation mark consistency: 23 | // false : do nothing (default) 24 | // true : ensure whatever is used is consistent 25 | // "single" : require single quotes 26 | // "double" : require double quotes 27 | "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) 28 | "unused" : true, // Unused variables: 29 | // true : all variables, last function parameter 30 | // "vars" : all variables only 31 | // "strict" : all variables, all function parameters 32 | "strict" : false, // true: Requires all functions run in ES5 Strict Mode 33 | "maxparams" : true, // {int} Max number of formal params allowed per function 34 | "maxdepth" : false, // {int} Max depth of nested blocks (within functions) 35 | "maxstatements" : false, // {int} Max number statements per function 36 | "maxcomplexity" : false, // {int} Max cyclomatic complexity per function 37 | "maxlen" : 132, // {int} Max number of characters per line 38 | "varstmt" : false, // true: Disallow any var statements. Only `let` and `const` are allowed. 39 | 40 | // Relaxing 41 | "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) 42 | "boss" : false, // true: Tolerate assignments where comparisons would be expected 43 | "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. 44 | "eqnull" : false, // true: Tolerate use of `== null` 45 | "esversion" : 5, // {int} Specify the ECMAScript version to which the code must adhere. 46 | "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) 47 | // (ex: `for each`, multiple try/catch, function expression…) 48 | "evil" : false, // true: Tolerate use of `eval` and `new Function()` 49 | "expr" : false, // true: Tolerate `ExpressionStatement` as Programs 50 | "funcscope" : false, // true: Tolerate defining variables inside control statements 51 | "globalstrict" : true, // true: Allow global "use strict" (also enables 'strict') 52 | "iterator" : false, // true: Tolerate using the `__iterator__` property 53 | "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block 54 | "laxbreak" : false, // true: Tolerate possibly unsafe line breakings 55 | "laxcomma" : false, // true: Tolerate comma-first style coding 56 | "loopfunc" : true, // true: Tolerate functions being defined in loops 57 | "multistr" : false, // true: Tolerate multi-line strings 58 | "noyield" : false, // true: Tolerate generator functions with no yield statement in them. 59 | "notypeof" : false, // true: Tolerate invalid typeof operator values 60 | "proto" : false, // true: Tolerate using the `__proto__` property 61 | "scripturl" : false, // true: Tolerate script-targeted URLs 62 | "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` 63 | "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation 64 | "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` 65 | "validthis" : false, // true: Tolerate using this in a non-constructor function 66 | 67 | // Environments 68 | "browser" : true, // Web Browser (window, document, etc) 69 | "browserify" : false, // Browserify (node.js code in the browser) 70 | "couch" : false, // CouchDB 71 | "devel" : false, // Development/debugging (alert, confirm, etc) 72 | "dojo" : false, // Dojo Toolkit 73 | "jasmine" : false, // Jasmine 74 | "jquery" : true, // jQuery 75 | "mocha" : false, // Mocha 76 | "mootools" : false, // MooTools 77 | "node" : false, // Node.js 78 | "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) 79 | "phantom" : false, // PhantomJS 80 | "prototypejs" : false, // Prototype and Scriptaculous 81 | "qunit" : false, // QUnit 82 | "rhino" : false, // Rhino 83 | "shelljs" : false, // ShellJS 84 | "typed" : false, // Globals for typed array constructions 85 | "worker" : false, // Web Workers 86 | "wsh" : false, // Windows Scripting Host 87 | "yui" : false, // Yahoo User Interface 88 | // Custom Globals 89 | "globals" : { // additional predefined global variables 90 | "sprintf": false, 91 | "L": false, 92 | "wkt2geojson": false, 93 | "URI": false, 94 | "renderjson": false 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | navitia playground 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 25 | 26 |
27 | 70 | 71 |
72 |

Or, you’re an expert?

73 | 74 |
75 |
76 |
URL
77 | 78 | 79 |
80 |
81 |

or

82 |
83 |
84 |
85 |

or

86 |
87 |
88 |
89 |
90 |
91 | 92 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | // Include gulp 2 | var gulp = require('gulp'); 3 | 4 | // Include Our Plugins 5 | var jshint = require('gulp-jshint'); 6 | var jslint = require('gulp-jslint'); 7 | var sass = require('gulp-sass'); 8 | var cleanCSS = require('gulp-clean-css'); 9 | var concat = require('gulp-concat'); 10 | var uglify = require('gulp-uglify'); 11 | var rename = require('gulp-rename'); 12 | var htmlmin = require('gulp-htmlmin'); 13 | var bower = require('gulp-bower-src'); 14 | var image = require('gulp-image'); 15 | var gulpFilter = require('gulp-filter'); 16 | var gulpif = require('gulp-if') 17 | var browserSync = require('browser-sync').create(); 18 | var runSequence = require('run-sequence'); 19 | var del = require('del'); 20 | var config = require('./config'); 21 | var delConfig = config.del; 22 | 23 | function isProd(env) { 24 | return env == 'prod'; 25 | } 26 | // Lint Task 27 | function lint(env) { 28 | return function() { 29 | return gulp.src('js/**/*.js') 30 | .pipe(jshint()) 31 | .pipe(jshint.reporter('unix')) 32 | .pipe(jshint.reporter('fail')); 33 | } 34 | } 35 | gulp.task('dev:lint', lint('dev')); 36 | gulp.task('prod:lint', lint('prod')); 37 | 38 | // Compile Sass 39 | function compile_sass(env) { 40 | return function() { 41 | return gulp.src('scss/**/*.scss') 42 | .pipe(sass()) 43 | .pipe(gulpFilter(['**/style.css', '**/index.css'])) 44 | .pipe(gulpif(isProd(env), cleanCSS())) 45 | .pipe(gulp.dest(config[env] + '/css')); 46 | } 47 | } 48 | gulp.task('dev:sass', compile_sass('dev')); 49 | gulp.task('prod:sass', compile_sass('prod')); 50 | 51 | // Concatenate & Minify JS 52 | function compile_js(env) { 53 | return function () { 54 | return gulp.src('js/**/*.js') 55 | .pipe(concat('app.min.js')) 56 | .pipe(gulpif(isProd(env), uglify())) 57 | .pipe(gulp.dest(config[env] + '/js')); 58 | } 59 | } 60 | gulp.task('dev:scripts', compile_js('dev')); 61 | gulp.task('prod:scripts', compile_js('prod')); 62 | 63 | // Concatenate & Minify vendor js 64 | function compile_vendor_js(env){ 65 | return function(){ 66 | return bower() 67 | .pipe(gulpFilter([ 68 | '**/jquery/dist/jquery.js', 69 | '**/jquery-ui/jquery-ui.js', 70 | '**/renderjson/renderjson.js', 71 | '**/urijs/src/URI.js', 72 | '**/jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.js', 73 | '**/sprintf/src/sprintf.js', 74 | '**/leaflet/dist/leaflet-src.js', 75 | '**/notifyjs/dist/notify.js', 76 | '**/wkt2geojson/wkt2geojson.js', 77 | '**/leaflet.label/leaflet.label.js'])) 78 | .pipe(concat('lib.min.js')) 79 | .pipe(gulpif(isProd(env),uglify())) 80 | .pipe(gulp.dest(config[env] + '/lib')); 81 | } 82 | } 83 | gulp.task('dev:bowerJs', compile_vendor_js('dev')); 84 | gulp.task('prod:bowerJs', compile_vendor_js('prod')); 85 | 86 | // Concatenate & Minify vendor css 87 | function compile_vendor_css(env){ 88 | return function(){ 89 | return bower() 90 | .pipe(gulpFilter([ 91 | '**/jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.css', 92 | '**/leaflet/dist/leaflet.css', 93 | '**/leaflet.label/leaflet.label.css', 94 | '**/notifyjs/dist/styles/metro/notify-metro.css'])) 95 | .pipe(concat('vendor.min.css')) 96 | .pipe(gulpif(isProd(env),cleanCSS())) 97 | .pipe(gulp.dest(config[env] + '/css')); 98 | } 99 | } 100 | gulp.task('dev:bowerCss', compile_vendor_css('dev')); 101 | gulp.task('prod:bowerCss', compile_vendor_css('prod')); 102 | 103 | // Concatenate & Minify vendor css 104 | function copy_vendor_image(env){ 105 | 106 | return function(){ 107 | return bower() 108 | .pipe(gulpFilter([ 109 | '**/leaflet/dist/images/*.png' 110 | ] 111 | )) 112 | .pipe(image({ 113 | pngquant: true, 114 | optipng: false, 115 | zopflipng: true, 116 | advpng: true, 117 | jpegRecompress: false, 118 | jpegoptim: true, 119 | mozjpeg: true, 120 | gifsicle: true, 121 | svgo: true 122 | })) 123 | .pipe(gulp.dest(config[env] + '/lib/img')); 124 | } 125 | } 126 | gulp.task('dev:bowerImg', copy_vendor_image('dev')); 127 | gulp.task('prod:bowerImg', copy_vendor_image('prod')); 128 | 129 | gulp.task('dev:bower', function(cb){ 130 | runSequence(['dev:bowerJs', 'dev:bowerCss', 'dev:bowerImg'], cb); 131 | }); 132 | 133 | gulp.task('prod:bower', function(cb){ 134 | runSequence(['prod:bowerJs', 'prod:bowerCss', 'prod:bowerImg'], cb); 135 | }); 136 | 137 | // Compress img 138 | function compress_img(env) { 139 | return function(){ 140 | return gulp.src('img/**') 141 | .pipe(image({ 142 | pngquant: true, 143 | optipng: false, 144 | zopflipng: true, 145 | advpng: true, 146 | jpegRecompress: false, 147 | jpegoptim: true, 148 | mozjpeg: true, 149 | gifsicle: true, 150 | svgo: true 151 | })) 152 | .pipe(gulp.dest(config[env] + '/img')); 153 | } 154 | } 155 | gulp.task('dev:img', compress_img('dev')); 156 | gulp.task('prod:img', compress_img('prod')); 157 | 158 | // Minify html 159 | function compile_html(env){ 160 | return function() { 161 | return gulp.src('app/*.html') 162 | .pipe(htmlmin({collapseWhitespace: isProd(env)})) 163 | .pipe(gulp.dest(config[env])) 164 | } 165 | } 166 | gulp.task('dev:minify_html', compile_html('dev')); 167 | gulp.task('prod:minify_html', compile_html('prod')); 168 | 169 | // Watch Files For Changes 170 | function watch(env){ 171 | return function() { 172 | gulp.watch('js/**/*.js', [env + ':scripts']); 173 | gulp.watch('scss/**/*.scss', [env + ':sass']); 174 | gulp.watch('img/**', [env + ':img']); 175 | gulp.watch('app/**', [env + ':minify_html']); 176 | browserSync.init(config.browsersync[env]); 177 | } 178 | } 179 | gulp.task('dev:watch', watch('dev')); 180 | gulp.task('prod:watch', watch('prod')); 181 | 182 | // build sequence 183 | function build(env) { 184 | return function(cb){ 185 | runSequence( 186 | env + ':scripts', 187 | env + ':lint', 188 | [env + ':sass', 189 | env + ':bower', 190 | env + ':img', 191 | env + ':minify_html'], cb); 192 | } 193 | } 194 | gulp.task('dev:build', build('dev')); 195 | gulp.task('prod:build', build('prod')); 196 | 197 | gulp.task('dev', function (cb) { 198 | runSequence('dev:build', 'dev:watch', cb); 199 | }); 200 | gulp.task('prod', function (cb) { 201 | runSequence('prod:build', 'prod:watch', cb); 202 | }); 203 | 204 | gulp.task('all:clean', function(cb){ 205 | del(delConfig.all, cb); 206 | }) 207 | 208 | gulp.task('dev:clean', function(cb){ 209 | del(delConfig.dev, cb); 210 | }) 211 | 212 | gulp.task('prod:clean', function(cb){ 213 | del(delConfig.prod, cb); 214 | }) 215 | -------------------------------------------------------------------------------- /js/utils.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 CanalTP 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in all 11 | // copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | // SOFTWARE. 20 | 21 | 'use strict'; 22 | 23 | // fake includes 24 | var summary; 25 | var response; 26 | 27 | var utils = {}; 28 | 29 | utils.isDatetimeType = function(str) { 30 | return $.inArray(str, ['since', 'until']) !== -1 || str.match(/datetime$/); 31 | }; 32 | 33 | utils.htmlEncode = function(value) { 34 | return $('
').text(value).html(); 35 | }; 36 | 37 | utils.durationToString = function(duration) { 38 | var res = ''; 39 | var seconds = duration % 60; 40 | var minutes = Math.floor(duration / 60) % 60; 41 | var hours = Math.floor(duration / (60 * 60)) % 24; 42 | var days = Math.floor(duration / (24 * 60 * 60)); 43 | 44 | if (days !== 0) { res += sprintf('%sd', days); } 45 | if (hours !== 0) { res += sprintf('%sh', hours); } 46 | if (minutes !== 0) { res += sprintf('%smin', minutes); } 47 | if (seconds !== 0) { res += sprintf('%ss', seconds); } 48 | 49 | if (! res) { 50 | return '0s'; 51 | } else { 52 | return res; 53 | } 54 | }; 55 | 56 | utils.isTemplate = function(str) { 57 | return str.slice(0, 1) === '{' && str.slice(-1) === '}'; 58 | }; 59 | 60 | utils.flatMap = function(array, f) { 61 | var result = []; 62 | 63 | array.forEach(function(obj, i, array) { 64 | result = result.concat(f(obj, i, array)); 65 | }); 66 | return result; 67 | }; 68 | 69 | $.notify.addStyle('navitia', { 70 | html: '
', 71 | classes: { 72 | error: { 73 | 'color': '#B94A48', 74 | 'background-color': '#F2DEDE', 75 | 'border-color': '#EED3D7', 76 | }, 77 | success: { 78 | 'color': '#468847', 79 | 'background-color': '#DFF0D8', 80 | 'border-color': '#D6E9C6', 81 | }, 82 | info: { 83 | 'color': '#3A87AD', 84 | 'background-color': '#D9EDF7', 85 | 'border-color': '#BCE8F1', 86 | }, 87 | warn: { 88 | 'color': '#C09853', 89 | 'background-color': '#FCF8E3', 90 | 'border-color': '#FBEED5', 91 | } 92 | } 93 | }); 94 | 95 | utils.errorMessage = function(url, xhr, status/*, error*/) { 96 | var message; 97 | if (url.lastIndexOf('http:', 0) === 0 && window.location.protocol === 'https:') { 98 | message = $('').text( 99 | 'You cannot request the API using http if ' + 100 | 'you are connected to navitia-playground ' + 101 | 'using https. Please request the API using ' + 102 | 'https or connect to navitia-playground ' + 103 | 'using http.'); 104 | } else if (xhr.readyState === 0) { 105 | message = $('').text('Network error'); 106 | } else if (xhr.responseJSON) { 107 | message = $(summary.run(new response.Context(xhr.responseJSON), 108 | 'response', 109 | xhr.responseJSON)); 110 | } else { 111 | message = $('').text(status); 112 | } 113 | return message; 114 | }; 115 | 116 | utils.notifyOnError = function(typeError, url, xhr, status, error) { 117 | if (xhr.status === 401) { 118 | $('#token').addClass('templateInput'); 119 | } 120 | var message = utils.errorMessage(url, xhr, status, error); 121 | $.notify({ 122 | text: $('').text(sprintf('%s error: ', typeError)).append(message) 123 | }, { 124 | position: 'right bottom', 125 | style: 'navitia', 126 | }); 127 | }; 128 | 129 | utils.notifyWarn = function(message) { 130 | $.notify({ 131 | text: message 132 | }, { 133 | position: 'right bottom', 134 | className: 'warn', 135 | style: 'navitia', 136 | }); 137 | }; 138 | 139 | utils.notifyInfo = function(message) { 140 | $.notify({ 141 | text: message 142 | }, { 143 | position: 'right bottom', 144 | className: 'info', 145 | style: 'navitia', 146 | }); 147 | }; 148 | 149 | utils.getType = function(key) { 150 | if (!key || typeof key !== 'string') { 151 | return null; 152 | } 153 | // hardcoded cases: 154 | switch (key) { 155 | case 'places_nearby': return 'place'; 156 | case 'addresses': return 'address'; 157 | case 'from': return 'place'; 158 | case 'to': return 'place'; 159 | } 160 | // generic plural 161 | if (key.slice(-1) === 's') { return key.slice(0, -1); } 162 | 163 | // just the key 164 | return key; 165 | }; 166 | 167 | utils.getTextColor = function(json) { 168 | function _toNum(c, i) { return +('0x' + c.slice(i, i + 2)); } 169 | 170 | if (json.text_color) { 171 | return '#' + json.text_color; 172 | } 173 | if (json.color) { 174 | var c = json.color; 175 | var grey = 0.21 * _toNum(c, 0) + 0.72 * _toNum(c, 2) + 0.07 * _toNum(c, 4); 176 | if (grey < 128) { 177 | return 'white'; 178 | } 179 | } 180 | return 'black'; 181 | }; 182 | 183 | utils.computeColorFromRatio = function(ratio) { 184 | var r = 255; 185 | var g = 255; 186 | if (ratio < 1/2) { 187 | r = Math.ceil(255 * ratio * 2); 188 | } else { 189 | g = Math.ceil(255 * (1 - ratio) * 2); 190 | } 191 | return {red: r, green: g, blue: 0}; 192 | }; 193 | 194 | utils.toCssColor = function(c, alpha) { 195 | if (alpha) { 196 | return sprintf('rgba(%s, %s, %s, %s)', c.red, c.green, c.blue, alpha); 197 | } else { 198 | return sprintf('#%02x%02x%02x', c.red, c.green, c.blue); 199 | } 200 | }; 201 | 202 | utils.getColorFromRatio = function(ratio) { 203 | return utils.toCssColor(utils.computeColorFromRatio(ratio)); 204 | }; 205 | 206 | utils.manageToken = function(token) { 207 | return token ? { Authorization: 'Basic ' + btoa(token + ':') } : {}; 208 | }; 209 | 210 | utils.deepClone = function(obj) { 211 | return JSON.parse(JSON.stringify(obj)); 212 | }; 213 | 214 | utils.makeDistanceSummary = function(d) { 215 | var format = '%f %s'; 216 | if (d >= 1000) { return sprintf(format, d / 1000.0, 'km'); } 217 | return sprintf(format, d, 'm'); 218 | }; 219 | -------------------------------------------------------------------------------- /js/response.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 CanalTP 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in all 11 | // copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | // SOFTWARE. 20 | 21 | 'use strict'; 22 | 23 | // fake includes 24 | var summary; 25 | var extended; 26 | var map; 27 | var storage; 28 | var autocomplete; 29 | var utils; 30 | var request; 31 | 32 | var response = {}; 33 | 34 | response.setStatus = function(message, status, start_time) { 35 | var res = $('').text('Status: ').append(message); 36 | res.append(utils.htmlEncode(sprintf(' (%s)', status))); 37 | if (typeof start_time === 'number') { 38 | var duration = new Date().getTime() - start_time; 39 | res.append(sprintf(', duration of the request: %dms', duration)); 40 | } 41 | $('#status').html(res); 42 | }; 43 | 44 | response.responseCollectionName = function(json) { 45 | if (! (json instanceof Object)) { return null; } 46 | var key = null; 47 | var notCollectionKeys = ['disruptions', 'links', 'feed_publishers', 'exceptions', 'notes', 'warnings', 'tickets']; 48 | for (var k in json) { 49 | if ($.isArray(json[k]) && 50 | $.inArray(k, notCollectionKeys) === -1) { 51 | key = k; 52 | } 53 | } 54 | // disruptions may be an object list only if there is no other object list 55 | if (key === null && 'disruptions' in json) { 56 | key = 'disruptions'; 57 | } 58 | return key; 59 | }; 60 | 61 | response.makeObjectButton = function(name, handle) { 62 | // TODO call handle on toggle 63 | return $('