From 115ebf1524d789e55677c573691cecf4b697412b Mon Sep 17 00:00:00 2001 From: btfou Date: Tue, 1 Sep 2015 01:17:46 -0700 Subject: [PATCH 001/216] a little housekeeping --- Gruntfile.js | 1 + viewer/index.html | 29 +++++++++++------------ viewer/js/config/viewer.js | 47 +++++++++++++++++++++++--------------- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 44ad2291d..ac8d86f17 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,3 +1,4 @@ +/* global module */ module.exports = function(grunt) { // middleware for grunt.connect diff --git a/viewer/index.html b/viewer/index.html index 8cbf2bdbb..927192f81 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -34,21 +34,6 @@ - @@ -62,7 +47,19 @@ file = 'config/' + file; } } - require(['viewer/Controller', file], function(Controller, config){ + require({ + async: true, + packages: [{ + name: 'viewer', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/viewer' + },{ + name: 'config', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/config' + },{ + name: 'gis', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/gis' + }] + }, ['viewer/Controller', file], function(Controller, config){ Controller.startup(config); }); diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 8067cb55e..ac0b9c7d4 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -1,20 +1,31 @@ define([ - 'esri/units', - 'esri/geometry/Extent', - 'esri/config', - 'esri/tasks/GeometryService', - 'esri/layers/ImageParameters' -], function (units, Extent, esriConfig, GeometryService, ImageParameters) { + 'dojo/_base/lang', + 'esri/units', + 'esri/geometry/Extent', + 'esri/config', + /*'esri/urlUtils',*/ + 'esri/tasks/GeometryService', + 'esri/layers/ImageParameters' +], function (lang, units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters) { - // url to your proxy page, must be on same machine hosting you app. See proxy folder for readme. + // esri config + esriConfig.defaults.geometryService = new GeometryService('https://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'); esriConfig.defaults.io.proxyUrl = 'proxy/proxy.ashx'; esriConfig.defaults.io.alwaysUseProxy = false; - // url to your geometry server. - esriConfig.defaults.geometryService = new GeometryService('http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'); + // esriConfig.defaults.io.corsDetection = false; + // urlUtils.addProxyRule({ + // urlPrefix: 'geocode.arcgis.com', + // proxyUrl: 'proxy/proxy.ashx' + // }); - //image parameters for dynamic services, set to png32 for higher quality exports. - var imageParameters = new ImageParameters(); - imageParameters.format = 'png32'; + // additional functions, defines, etc you may need in config go here + function ipMix(params) { + return lang.mixin(new ImageParameters(), params); + } + + var imageParams = ipMix({ + format: 'png32' + }); return { // used for debugging your app @@ -80,7 +91,7 @@ define([ title: 'My layer' } } - }, { + }, { type: 'feature', url: 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', title: 'San Francisco 311 Incidents', @@ -91,7 +102,7 @@ define([ outFields: ['req_type', 'req_date', 'req_time', 'address', 'district'], mode: 0 } - }, { + }, { type: 'dynamic', url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', title: 'Louisville Public Safety', @@ -99,7 +110,7 @@ define([ id: 'louisvillePubSafety', opacity: 1.0, visible: true, - imageParameters: imageParameters + imageParameters: imageParams }, identifyLayerInfos: { layerIds: [2, 4, 5, 8, 12, 21] @@ -109,7 +120,7 @@ define([ hideLayers: [21] } } - }, { + }, { type: 'dynamic', url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/MapServer', title: 'Damage Assessment', @@ -117,7 +128,7 @@ define([ id: 'DamageAssessment', opacity: 1.0, visible: true, - imageParameters: imageParameters + imageParameters: imageParams }, legendLayerInfos: { exclude: true @@ -127,7 +138,7 @@ define([ metadataUrl: true, expanded: true } - }], + }], // set include:true to load. For titlePane type set position the the desired order in the sidebar widgets: { growler: { From 4abc00dc2efd1faa9a2c57b19f035532f9e3922f Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 7 Sep 2015 18:08:53 -0700 Subject: [PATCH 002/216] Revert "a little housekeeping" This reverts commit 115ebf1524d789e55677c573691cecf4b697412b. --- Gruntfile.js | 1 - viewer/index.html | 29 ++++++++++++----------- viewer/js/config/viewer.js | 47 +++++++++++++++----------------------- 3 files changed, 34 insertions(+), 43 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index ac8d86f17..44ad2291d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,4 +1,3 @@ -/* global module */ module.exports = function(grunt) { // middleware for grunt.connect diff --git a/viewer/index.html b/viewer/index.html index 927192f81..8cbf2bdbb 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -34,6 +34,21 @@ + @@ -47,19 +62,7 @@ file = 'config/' + file; } } - require({ - async: true, - packages: [{ - name: 'viewer', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/viewer' - },{ - name: 'config', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/config' - },{ - name: 'gis', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/gis' - }] - }, ['viewer/Controller', file], function(Controller, config){ + require(['viewer/Controller', file], function(Controller, config){ Controller.startup(config); }); diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index ac0b9c7d4..8067cb55e 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -1,31 +1,20 @@ define([ - 'dojo/_base/lang', - 'esri/units', - 'esri/geometry/Extent', - 'esri/config', - /*'esri/urlUtils',*/ - 'esri/tasks/GeometryService', - 'esri/layers/ImageParameters' -], function (lang, units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters) { + 'esri/units', + 'esri/geometry/Extent', + 'esri/config', + 'esri/tasks/GeometryService', + 'esri/layers/ImageParameters' +], function (units, Extent, esriConfig, GeometryService, ImageParameters) { - // esri config - esriConfig.defaults.geometryService = new GeometryService('https://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'); + // url to your proxy page, must be on same machine hosting you app. See proxy folder for readme. esriConfig.defaults.io.proxyUrl = 'proxy/proxy.ashx'; esriConfig.defaults.io.alwaysUseProxy = false; - // esriConfig.defaults.io.corsDetection = false; - // urlUtils.addProxyRule({ - // urlPrefix: 'geocode.arcgis.com', - // proxyUrl: 'proxy/proxy.ashx' - // }); + // url to your geometry server. + esriConfig.defaults.geometryService = new GeometryService('http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'); - // additional functions, defines, etc you may need in config go here - function ipMix(params) { - return lang.mixin(new ImageParameters(), params); - } - - var imageParams = ipMix({ - format: 'png32' - }); + //image parameters for dynamic services, set to png32 for higher quality exports. + var imageParameters = new ImageParameters(); + imageParameters.format = 'png32'; return { // used for debugging your app @@ -91,7 +80,7 @@ define([ title: 'My layer' } } - }, { + }, { type: 'feature', url: 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', title: 'San Francisco 311 Incidents', @@ -102,7 +91,7 @@ define([ outFields: ['req_type', 'req_date', 'req_time', 'address', 'district'], mode: 0 } - }, { + }, { type: 'dynamic', url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', title: 'Louisville Public Safety', @@ -110,7 +99,7 @@ define([ id: 'louisvillePubSafety', opacity: 1.0, visible: true, - imageParameters: imageParams + imageParameters: imageParameters }, identifyLayerInfos: { layerIds: [2, 4, 5, 8, 12, 21] @@ -120,7 +109,7 @@ define([ hideLayers: [21] } } - }, { + }, { type: 'dynamic', url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/MapServer', title: 'Damage Assessment', @@ -128,7 +117,7 @@ define([ id: 'DamageAssessment', opacity: 1.0, visible: true, - imageParameters: imageParams + imageParameters: imageParameters }, legendLayerInfos: { exclude: true @@ -138,7 +127,7 @@ define([ metadataUrl: true, expanded: true } - }], + }], // set include:true to load. For titlePane type set position the the desired order in the sidebar widgets: { growler: { From 5734d5c4cd70c12cf62b74a18516342f42d45868 Mon Sep 17 00:00:00 2001 From: btfou Date: Tue, 8 Sep 2015 13:38:01 -0700 Subject: [PATCH 003/216] add /* global module */ to Gruntfile --- Gruntfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Gruntfile.js b/Gruntfile.js index 44ad2291d..ac8d86f17 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,3 +1,4 @@ +/* global module */ module.exports = function(grunt) { // middleware for grunt.connect From 9500fa8818f28de0e97494ade7395589ab82436b Mon Sep 17 00:00:00 2001 From: btfou Date: Tue, 8 Sep 2015 13:48:48 -0700 Subject: [PATCH 004/216] add addProxyRule to viewer.js --- viewer/js/config/viewer.js | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 8067cb55e..4a7c41709 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -1,14 +1,23 @@ define([ - 'esri/units', - 'esri/geometry/Extent', - 'esri/config', - 'esri/tasks/GeometryService', - 'esri/layers/ImageParameters' -], function (units, Extent, esriConfig, GeometryService, ImageParameters) { + 'esri/units', + 'esri/geometry/Extent', + 'esri/config', + /*'esri/urlUtils',*/ + 'esri/tasks/GeometryService', + 'esri/layers/ImageParameters' +], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters) { // url to your proxy page, must be on same machine hosting you app. See proxy folder for readme. esriConfig.defaults.io.proxyUrl = 'proxy/proxy.ashx'; esriConfig.defaults.io.alwaysUseProxy = false; + + // add a proxy rule to force specific domain requests through proxy + // be sure the domain is added in proxy.config + /*urlUtils.addProxyRule({ + urlPrefix: 'www.example.com', + proxyUrl: 'proxy/proxy.ashx' + });*/ + // url to your geometry server. esriConfig.defaults.geometryService = new GeometryService('http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'); @@ -80,7 +89,7 @@ define([ title: 'My layer' } } - }, { + }, { type: 'feature', url: 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', title: 'San Francisco 311 Incidents', @@ -91,7 +100,7 @@ define([ outFields: ['req_type', 'req_date', 'req_time', 'address', 'district'], mode: 0 } - }, { + }, { type: 'dynamic', url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', title: 'Louisville Public Safety', @@ -109,7 +118,7 @@ define([ hideLayers: [21] } } - }, { + }, { type: 'dynamic', url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/MapServer', title: 'Damage Assessment', @@ -127,7 +136,7 @@ define([ metadataUrl: true, expanded: true } - }], + }], // set include:true to load. For titlePane type set position the the desired order in the sidebar widgets: { growler: { From e29610a17edba0c132419e63ff72894dd0252216 Mon Sep 17 00:00:00 2001 From: btfou Date: Tue, 8 Sep 2015 13:58:02 -0700 Subject: [PATCH 005/216] add buildImageParameters helper to viewer.js --- viewer/js/config/viewer.js | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 4a7c41709..6e77756f0 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -21,9 +21,24 @@ define([ // url to your geometry server. esriConfig.defaults.geometryService = new GeometryService('http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'); - //image parameters for dynamic services, set to png32 for higher quality exports. - var imageParameters = new ImageParameters(); - imageParameters.format = 'png32'; + // helper function returning ImageParameters for dynamic layers + // example: + // imageParameters: buildImageParameters({ + // layerIds: [0], + // layerOption: 'show' + // }) + function buildImageParameters(config) { + config = config || {}; + var ip = new ImageParameters(); + //image parameters for dynamic services, set to png32 for higher quality exports + ip.format = 'png32'; + for (var key in config) { + if (config.hasOwnProperty(key)) { + ip[key] = config[key]; + } + } + return ip; + } return { // used for debugging your app @@ -108,7 +123,7 @@ define([ id: 'louisvillePubSafety', opacity: 1.0, visible: true, - imageParameters: imageParameters + imageParameters: buildImageParameters() }, identifyLayerInfos: { layerIds: [2, 4, 5, 8, 12, 21] @@ -126,7 +141,7 @@ define([ id: 'DamageAssessment', opacity: 1.0, visible: true, - imageParameters: imageParameters + imageParameters: buildImageParameters() }, legendLayerInfos: { exclude: true From 17703e0cd35a22e807faefacfe3ce60b3bb2d5c1 Mon Sep 17 00:00:00 2001 From: btfou Date: Tue, 8 Sep 2015 14:45:33 -0700 Subject: [PATCH 006/216] add app.js to load the app and bump font awesome to v4.4.0 --- viewer/index.html | 33 +++------------------------------ viewer/js/config/app.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 30 deletions(-) create mode 100644 viewer/js/config/app.js diff --git a/viewer/index.html b/viewer/index.html index 8cbf2bdbb..b22a91097 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -8,7 +8,7 @@ Configurable Map Viewer - + @@ -34,37 +34,10 @@ - - - + + diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js new file mode 100644 index 000000000..6d4b1de2a --- /dev/null +++ b/viewer/js/config/app.js @@ -0,0 +1,32 @@ +(function () { + + // globel dojoConfig is required for async loading of gmaps api + window.dojoConfig = { + async: true, + packages: [{ + name: 'viewer', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/viewer' + }, { + name: 'config', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/config' + }, { + name: 'gis', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/gis' + }] + }; + + // get the config file from the url if present + var file = 'config/viewer', + s = window.location.search, + q = s.match(/config=([^&]*)/i); + if (q && q.length > 0) { + file = q[1]; + if (file.indexOf('/') < 0) { + file = 'config/' + file; + } + } + + require(window.dojoConfig, ['viewer/Controller', file, 'dojo/domReady!'], function (Controller, config) { + Controller.startup(config); + }); +})(); \ No newline at end of file From b39680f6593c972233cbe2200cef810d32c21457 Mon Sep 17 00:00:00 2001 From: btfou Date: Tue, 8 Sep 2015 14:48:51 -0700 Subject: [PATCH 007/216] fix stack exchange url in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9418b3fe8..efb59a017 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ There are many ways to contribute to CMV: 2. __Create documentation__ Please contribute to the [cmv documentation repo](https://github.com/cmv/cmv-docs). -3. __Answer Questions at Stack Exchange__ - [gis.stackexchange.com](https://gis.stackexchange.com/tag/cmv) is the prime destination for our Frequently Asked Questions (FAQs). Please answer questions and help new developers get more comfortable with CMV. +3. __Answer Questions at Stack Exchange__ - [gis.stackexchange.com](https://gis.stackexchange.com/tags/cmv) is the prime destination for our Frequently Asked Questions (FAQs). Please answer questions and help new developers get more comfortable with CMV. 4. __Join the Chat Room__ - Lots of us in CMV community hang out in the chat room on [Gitter](https://gitter.im/cmv/cmv-app/). Feel free to hangout with us, answer questions and throw out ideas. From 023f5f4e077709837a077026a396c6b4277bea0a Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Tue, 8 Sep 2015 21:56:51 -0700 Subject: [PATCH 008/216] Allow `mapStartBasemap` & `basemapsToShow` as optional in basemap widget. Also clean up some unused properties and code. --- viewer/js/config/basemaps.js | 18 ++++++++++++----- viewer/js/gis/dijit/Basemaps.js | 35 ++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 49a91a5cf..7cafcaf89 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -6,11 +6,19 @@ define([ return { map: true, // needs a refrence to the map mode: 'agol', //must be either 'agol' or 'custom' - title: 'Basemaps', // tilte for widget - mapStartBasemap: 'streets', // must match one of the basemap keys below - //basemaps to show in menu. define in basemaps object below and reference by name here - // TODO Is this array necessary when the same keys are explicitly included/excluded below? - basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'national-geographic', 'osm', 'oceans'], + title: 'Basemaps', // title for widget + + /* optional starting basemap + / otherwise uses the basemap from the map + / must match one of the keys in basemaps object below + */ + //mapStartBasemap: 'streets', + + /* optional array of basemaps to show in menu. + / otherwise uses keys in basemaps object below + / values in array must match keys in basemaps object + */ + //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'national-geographic', 'osm', 'oceans'], // define all valid custom basemaps here. Object of Basemap objects. For custom basemaps, the key name and basemap id must match. basemaps: { // agol basemaps diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index 12cfc45ad..9ee9335f5 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -23,14 +23,31 @@ define([ i18n: i18n, mode: 'agol', title: i18n.title, - //baseClass: 'gis_Basemaps_Dijit', - //buttonClass: 'gis_Basemaps_Button', - //menuClass: 'gis_Basemaps_Menu', - mapStartBasemap: 'streets', - basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'gray', 'oceans', 'national-geographic', 'osm'], - validBasemaps: [], + + mapStartBasemap: null, + basemapsToShow: null, + postCreate: function () { this.inherited(arguments); + + // if the basemaps to show is not explicitly set, + // get them from the basemap object + if (!this.basemapsToShow) { + this.basemapsToShow = Object.keys(this.basemaps); + } + + // if the starting basemap is not explicitly set, + // get it from the map + if (!this.mapStartBasemap) { + this.mapStartBasemap = this.map.getBasemap(); + } + + // check to make sure the starting basemap + // is found in the basemaps object + if (!this.basemaps.hasOwnProperty(this.mapStartBasemap)) { + this.mapStartBasemap = this.basemapsToShow[0]; + } + this.currentBasemap = this.mapStartBasemap || null; if (this.mode === 'custom') { @@ -41,15 +58,11 @@ define([ return map.basemap; }) }); - // if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the title of custom basemaps in viewer.js config - // this.gallery.select(this.mapStartBasemap); - // } this.gallery.startup(); } this.menu = new DropDownMenu({ - style: 'display: none;' //, - //baseClass: this.menuClass + style: 'display: none;' }); array.forEach(this.basemapsToShow, function (basemap) { From 88db914f4d6738fb721c8d62969818dec7a8a38d Mon Sep 17 00:00:00 2001 From: David Spriggs Date: Tue, 20 Oct 2015 07:18:19 +0300 Subject: [PATCH 009/216] Removed STLJS Hometown Meetup layer that was deleted. --- viewer/js/config/viewer.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 6e77756f0..6717649e4 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -86,10 +86,10 @@ define([ // 3 'mode' options: MODE_SNAPSHOT = 0, MODE_ONDEMAND = 1, MODE_SELECTION = 2 operationalLayers: [{ type: 'feature', - url: 'http://services1.arcgis.com/g2TonOxuRkIqSOFx/arcgis/rest/services/MeetUpHomeTowns/FeatureServer/0', - title: 'STLJS Meetup Home Towns', + url: 'http://services1.arcgis.com/6bXbLtkf4y11TosO/arcgis/rest/services/Restaurants/FeatureServer/0', + title: 'Restaurants', options: { - id: 'meetupHometowns', + id: 'restaurants', opacity: 1.0, visible: true, outFields: ['*'], @@ -101,7 +101,7 @@ define([ legendLayerInfos: { exclude: false, layerInfo: { - title: 'My layer' + title: 'Restaurants' } } }, { From 8b349f0950b6eb2842f76ff15f08788106cf85dc Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Thu, 22 Oct 2015 09:02:28 -0700 Subject: [PATCH 010/216] add meta tags and favicon. --- viewer/favicon.png | Bin 0 -> 2814 bytes viewer/index.html | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 viewer/favicon.png diff --git a/viewer/favicon.png b/viewer/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8dda524bda94b72e8d654ef4f0cda9c58ccd31ad GIT binary patch literal 2814 zcmVhasNXA4)$NIPyW`-|Z@U7J7l@(-W9=+1vliHiZ*zUHRx`FjuCnXJ~=+M$}k8~W0g zRr1oQr%%nBy=l#^NA|xP&i;S8V33`2KJv-t(ZVB+>&2$-X=#BmpaZ}|pa@9#g#AE5uDe+nb3og%J|l=r&tH

ng1QUUqIGOTfGMGSQ%qdsvo#S4xb<5GyKizWe@4N3h$d;v_>e#UNM`zAmf9&Q( zZBIXWd-q)%*S6kyTe~igV`?rY3_)u^U?!b^qu%&bF?kdM#N;nRppC)P`n7VP?tOk} z?B8!+{efwx;BN#XKJyjH_Pd3F2;hm1D{pp6W1H=i9iRE^HthCR@B^e}AuS6_2!xbK zDG)*+gq#?50a8eWlo+Ei+MuF{Fbq*jp|zg;n?Xv65dzO}yrQBzKJcEo4_*|=-l5@- zcO(>Ff^!LlqY%c5K= zQ>v8FS|fxc?l?4L8*pL{K@gx+NT?J+7!rjcc5{vs-}o+v@4n|D=cCu$a^ugol;08L znO|JfGe7;mpJ|b!mj%W;(O>U5(v6xNZ)p>q+oP#<=sBbfS@#?P@WLm7T|IS#Y55`bn zGzN>hN#WoVBcRfA55@2=C~m!yzHZBK^n{xC_0g!KKQ8>9r0|*@5nx#w z9l_Ynh2+2UGPS-wY6~x6&} z5c)pFN{vBMbT&00F=(TSlxF|X85-g?mv(hf9662Aig+SHrXhoJJqG{n`;ae^mT@8` z>J1p2Anfhm@@QZmtIxZuclDmqOo9BL9XG7=WWryR=p!wvAPmtc&^DXoSJ&Z-GD?8? z@;_qtzeHeaWdHgWTIVmo+S^ZL#|SY*Ktd~`LJ4(n0J&feI*O=PD%6z0X~^OGK1N9b zDLGjv(~?OtyD`JKA2L!b(UOSax-P~*==mtmpNIlx5@IqeDzvgg!(X$nTfMzBnN&19 z_VC_cu5={&Kfy?pAl7L}v}Py=G1N#Nmx!i7(?pVhfR>gPa$o#2qWbH#YHGxU0X1Gi zR_ny#akK&DyVOKwB7>nRR9%|V3EI+0#;SGtPoAbN@Ca>)bVR5^v=oqtp)ja((Ewo# zk!^+5&W_vcw`Q!RD}Q-^VR!q+q^K=Hh>2F!VYFpXks>mhYA!#PUM<$rG!Kes#W*Z8N2#I&>ILh-;TBD-q z?WPoAsEFA%ZSCz;U7v-y1eGKG6VprDjMh93o;pkZa37bY1|4F^OXt$>Th+Q^hK(ogE-VV0x?Dhw%AYAjr^ z0MGL$s=M!zUcQ77s2fG3HT6{DSmBbM>+afiPia~ZfXuSuKlJ&_-Z!A;Ue#AiE%uGS zE0v5RBMog$6fW-t4BqfC_5BBkoER!pD0P0Dg1M}B5#6(95gI{jCPAlE%x`e$Oed&% zK9LZ-|NYBx90%X`QIR4jRY+gC6uY&DvUc$rQu_<@=dJ$SzMr0}?AE4Do2Fx7X3vIv z>&#nE%$~KrbokWigRz*sqFk*P0@#(;`myv&2d*$tS!yRm;-jlj)hb#?(^{k=LZxVK zZla~78EIKySrbz!ous>aCcO(6o`X2oE(ow1vxF+-<6!B)C%tQ(n@@U<5 z?!5kr6bho3@elN1^0i^8Hf|%upOZ@Wbu2Dkjxki}N zLu|opQe88M&1fe!f9^?Xv~3Itz!DH5@U@`^BCmyb%{T0cgxGZ`viJYXr`G&NA0#gL z9r@9mk6)J=9s5Dd^%EF_K_D#)0R&M%4UY;w<5;yqD*IPFyY0u_#j~-%_2LF;NvT8I zj{Cc@Yv1|Ahx`k2;@toNxc92{Gdd0p+!?RbZm>huIrUvj2mzK=j53*@>sdW_tl9I> zp^J6&opezkQ~K`e_3!N%IQ6AWq4b9sk@3>;C-Xfs{&oG!+n;+EeEhZaf8syf{e~1E QC;$Ke07*qoM6N<$f~8S>^Z)<= literal 0 HcmV?d00001 diff --git a/viewer/index.html b/viewer/index.html index b22a91097..89bba9499 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -6,6 +6,10 @@ + + + + Configurable Map Viewer From 678e8dce1b84f87bc8961005529f2fc6cea9edae Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Thu, 22 Oct 2015 09:07:55 -0700 Subject: [PATCH 011/216] Update Proj4JS to 2.3.12 --- viewer/js/gis/dijit/MapInfo.js | 2 +- viewer/js/gis/dijit/StreetView.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/js/gis/dijit/MapInfo.js b/viewer/js/gis/dijit/MapInfo.js index 380c772b5..afc42b826 100644 --- a/viewer/js/gis/dijit/MapInfo.js +++ b/viewer/js/gis/dijit/MapInfo.js @@ -10,7 +10,7 @@ define([ 'dojo/dom-style', 'dojo/number', 'dojo/topic', - '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js', + '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12/proj4.js', 'xstyle/css!./MapInfo/css/MapInfo.css' ], function ( declare, diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index de426f265..669f52b22 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -17,7 +17,7 @@ define([ 'esri/geometry/Point', 'esri/SpatialReference', 'dijit/MenuItem', - '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js', + '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12/proj4.js', 'dojo/i18n!./StreetView/nls/resource', 'dijit/form/Button', From 7ba49fd044058faa1e62f8cc45066367be39f0e2 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Thu, 22 Oct 2015 09:26:30 -0700 Subject: [PATCH 012/216] make the favicon square 32.x32 --- viewer/favicon.png | Bin 2814 -> 2308 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/viewer/favicon.png b/viewer/favicon.png index 8dda524bda94b72e8d654ef4f0cda9c58ccd31ad..9ac1f0f7d9049266b965a5ed9b792737ff8cec4e 100644 GIT binary patch delta 2270 zcmV<42qE|W6@(HYiBL{Q4GJ0x0000DNk~Le0000W0000W2nGNE0CReJ^pPPN3l;qU z02TcK&2Uj+kwz+i2!2UKK~z|U#g}=I6xAKaKd-xIdS+*KX7+%EJWB%vC5a+2DWHr3L4(043WzJmE=2Y|XJ_Z= z*WK^E{Gp~?L%gucZ&m-(f4tA9`uBa^uZ1y&uQJwGN(Y>OFMGjF4f{q_){mRma^13T z_Wt&X@xzkUm7&p=Z9Ac`tyYyt?s5kT8>eO8*b5-Oj1h>-?i4TIF!$S4QD=c|^x4sh zRHpx*Z?f~8*-X$i#4HDGKnX)A1VJ>iy>Z$}r(Cw~G4F^+@LJ=6>F+MPWL<46@xg3ef$5Ma$Ews@|Ruut%3ync(BOK{h!51jumc31rN0hmL zbcGlfgg%z#P+65B418MKTJb%JuxyfvB#DT_==&R*&KdH7ZUOI_Ny=JIjq3;QPU@X zr44H%1(`y3VNRL?%NCiirxy?+ol0R@Heu*9Fpy`USfu1+$d^i3S`+xe`}br>F;IBg zV_+apbyXF95aRg(1wY*IIH7NfU`iQA(kd0tAWj1b*OCs|M)k=%iBy6t$r(TR^rPq}H{t z+!(3yB*kJ8>3I}`@YyS7o_X-F0weY|9q)vyHeZ=}_OHph$?_*xzOM6m5px`WVzC%H z3^7`xj3&^E(IZD8B2iqwL``1{^58y9$02BXo8ev`mTglvz78QQN~IE|AS`49eeXw^ zg9PFO`J=petabC^g_r95mRMoQP3JnUOER6tXpJdPqSI+~vrA zdFR~H)>l)`J55BVPQnL*w;GUZ{!F-GJ*sH1ANm!}*TzvlVLU^J4y8YvrQ~_IF&8%) z#b`smP(XT;lF~a`uy6f%=LQLMkEm(zBF-xSg;J@kihjIDm!qdnqPX;b9^``$Q_3Ac zi6rH#SE42zL)h7c3KecNN_BNL+GsqlM6u|-Up&u4hN`b1>?^OIb9Udy1qPi5PT0|C zzx9prYFl6S)Zo?Ee;K>*$EP`tqVnW3$ZuFjH-=K8oKdSEBRO*#UgH5&5Tdju2tz^@ z;L8Bt_mRHD_arh@zHeE7b1$AXbM43B|04jfx2t<@Bn+M`TEt897E!i&6Cr6jM3kT= z&e;2YM(Uz-C^r5Ztu&!hA6y~6lt}60OCR6&@B)Q|%P*NT>xsj`;V_@$GPml~m=SSf z2@_s94}nW7QCc$*YF9r*<@`Am_a8)sico99P@z;v;QL7FBRy$<0$bn z?JvJ}*G02tKKM!S!6Vos;$AVj!d7~Asdh!A*PTb_wC~V$<5hSsY-ZH*-;+lYRt_h# z>;_^NoQp!^wRa(Z2L@2dGD@DLdG%W4^0km_K4-BhuKP5B|L%f4*<%+~IbD?*I(L>A zZ#^;pufSLrTrMilm_o<6S`NA~(oe0$>TRR_nuRzkR^y&O3vv8Jf*}=jZGBC3KfKaT z?|zqYqDDH$o!|6n@Ig;t)yAvpw2nA4Gf%Imi1kd(?HFl)`oFbF^r$L&TDQ|>+Z5hx zAo~1EB;MFfkZo5UPR@LN;-3aCJnvxq=f7E28|r9ER8Yv2|NXYRFFa%G71!#|B+#&J zwy2B#?N*HVX;hTTg(aY*@yn;smRL?_egwJp*Xa!;eNyWFZEr8Axqs!p=BbkpE#0!J z<=Mp4o2yEH#XAIoAYxOjuDEkQ0zaH=s#*;&=_6v@RHPn}h!dROSWei2d?K`V~3M*XGeas2tM{jsw&f*ax8=9^y z>*<>rDS5*Y?2?JHO}%4BJhfok)4M+l_`^5=J-Vi)U!@;E>%}#j{xEI9s`qqV;`I1S z=O(TGV+VA);a=;S$M3Ey(=fUbz)>n|d;Th029I@*9o@5d_nMyW4-OcgH^Laht6Qf} sa*Syum~zTy?~5#QB>7VQ4UZ)M0d^r_uHH)JEC2ui07*qoM6N<$g0UB6+W-In delta 2780 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 Date: Sun, 25 Oct 2015 17:51:36 -0700 Subject: [PATCH 013/216] migrated from jshint to eslint for more consistency in coding styles. modified JS files so they pass extensive eslint tests updated package.json and Gruntfile.js for hinting locally using `grunt hint` and on build with travis-ci for each commit. The travis run should fail if there are eslint errors. --- .eslintrc | 250 ++++ .jshintrc | 102 -- Gruntfile.js | 316 ++--- package.json | 49 +- viewer/js/config/app.js | 53 +- viewer/js/config/basemaps.js | 4 +- viewer/js/config/bookmarks.js | 32 +- viewer/js/config/find.js | 193 +-- viewer/js/config/identify.js | 126 +- viewer/js/config/viewer.js | 3 +- viewer/js/gis/dijit/Basemaps.js | 13 +- viewer/js/gis/dijit/Bookmarks.js | 71 +- viewer/js/gis/dijit/Directions.js | 35 +- viewer/js/gis/dijit/Draw.js | 109 +- viewer/js/gis/dijit/Editor.js | 1 + viewer/js/gis/dijit/Find.js | 1132 +++++++++-------- viewer/js/gis/dijit/Find/nls/resource.js | 50 +- viewer/js/gis/dijit/FloatingTitlePane.js | 4 +- viewer/js/gis/dijit/FloatingWidgetDialog.js | 26 +- viewer/js/gis/dijit/Geocoder.js | 2 + viewer/js/gis/dijit/Growler.js | 36 +- viewer/js/gis/dijit/Help.js | 79 +- viewer/js/gis/dijit/Identify.js | 16 +- viewer/js/gis/dijit/LayerControl.js | 36 +- .../js/gis/dijit/LayerControl/controls/CSV.js | 2 + .../dijit/LayerControl/controls/Dynamic.js | 2 + .../dijit/LayerControl/controls/Feature.js | 2 + .../gis/dijit/LayerControl/controls/GeoRSS.js | 2 + .../gis/dijit/LayerControl/controls/Image.js | 2 + .../LayerControl/controls/ImageVector.js | 2 + .../js/gis/dijit/LayerControl/controls/KML.js | 2 + .../gis/dijit/LayerControl/controls/Raster.js | 2 + .../gis/dijit/LayerControl/controls/Stream.js | 2 + .../gis/dijit/LayerControl/controls/Tiled.js | 2 + .../js/gis/dijit/LayerControl/controls/WMS.js | 2 + .../dijit/LayerControl/controls/WebTiled.js | 2 + .../dijit/LayerControl/controls/_Control.js | 1 + .../LayerControl/controls/_DynamicFolder.js | 3 +- .../LayerControl/controls/_DynamicSublayer.js | 61 +- .../js/gis/dijit/LayerControl/nls/resource.js | 2 +- .../dijit/LayerControl/plugins/LayerMenu.js | 29 +- .../LayerControl/plugins/Transparency.js | 2 + .../dijit/LayerControl/plugins/legendUtil.js | 3 + viewer/js/gis/dijit/LocateButton.js | 112 +- viewer/js/gis/dijit/MapInfo.js | 2 + viewer/js/gis/dijit/Measurement.js | 7 +- viewer/js/gis/dijit/Print.js | 98 +- viewer/js/gis/dijit/StreetView.js | 552 ++++---- viewer/js/gis/dijit/Vim.js | 100 +- viewer/js/gis/dijit/_FloatingWidgetMixin.js | 38 +- viewer/js/gis/plugins/async.js | 8 +- viewer/js/viewer/Controller.js | 1084 ++++++++-------- 52 files changed, 2556 insertions(+), 2308 deletions(-) create mode 100644 .eslintrc delete mode 100644 .jshintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..891a5be59 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,250 @@ +/* https://github.com/eslint/eslint/tree/master/docs/rules */ +{ + "rules": { + + /* + Possible Errors + The follow rules point out areas where you + might have made mistakes. + */ + "comma-dangle": [2, "never"], + "no-cond-assign": 2, + "no-console": 2, + "no-constant-condition": 2, + "no-control-regex": 2, + "no-debugger": 1, + "no-dupe-args": 2, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-empty-character-class": 2, + "no-empty": 2, + "no-ex-assign": 2, + "no-extra-boolean-cast": 2, + "no-extra-semi": 2, + "no-func-assign": 2, + "no-inner-declarations": 2, + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-negated-in-lhs": 2, + "no-obj-calls": 2, + "no-regex-spaces": 2, + "no-sparse-arrays": 2, + "no-unexpected-multiline": 2, + "no-unreachable": 2, + "use-isnan": 2, + "valid-jsdoc": 2, + "valid-typeof": 2, + + // ignored possible errors + "no-extra-parens": 0, + + + /* + Best Practices + These are rules designed to prevent you from making + mistakes. They either prescribe a better way of + doing something or help you avoid footguns. + */ + "accessor-pairs": [2, { + "getWithoutSet": true + }], + "block-scoped-var": 2, + "complexity": [2, 20], /** TODO should try to get this lower **/ + "consistent-return": 2, + "curly": 2, + "default-case": 2, + "dot-location": [2, "property"], + "dot-notation": 2, + "eqeqeq": 2, + "guard-for-in": 2, + "no-alert": 2, + "no-caller": 2, + "no-div-regex": 2, + "no-empty-label": 2, + "no-empty-pattern": 2, + "no-eq-null": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-fallthrough": 2, + "no-floating-decimal": 2, + "no-implicit-coercion": 2, + "no-implied-eval": 2, + "no-iterator": 2, + "no-labels": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-multi-spaces": 2, + "no-multi-str": 2, + "no-native-reassign": 2, + "no-new-func": 2, + "no-new-wrappers": 2, + "no-new": 2, + "no-octal-escape": 2, + "no-octal": 2, + "no-process-env": 2, + "no-proto": 2, + "no-redeclare": 2, + "no-return-assign": 2, + "no-script-url": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-throw-literal": 2, + "no-unused-expressions": 2, + "no-useless-call": 2, + "no-useless-concat": 2, + "no-void": 2, + "no-with": 2, + "radix": 2, + "wrap-iife": [2, "inside"], + "yoda": 2, + + // ignored best practices rules + "no-else-return": 0, + "no-invalid-this": 0, + "no-magic-numbers": 0, + "no-param-reassign": 0, + "no-warning-comments": 0, + "vars-on-top": 0, + + + /* + Strict Mode + */ + "strict": 2, + + + /* + Variables + These rules have to do with variable declarations. + */ + "no-catch-shadow": 2, + "no-delete-var": 2, + "no-label-var": 2, + "no-shadow-restricted-names": 2, + "no-shadow": 2, + "no-undef-init": 2, + "no-undef": 2, + "no-unused-vars": 2, + "no-use-before-define": 2, + + // ignore variable rules + "init-declarations": 0, + "no-undefined": 0, + + + /* + Stylistic Issues + These rules are purely matters of style and + are quite subjective. + */ + "array-bracket-spacing": [2, "never"], + "block-spacing": [2, "always"], + "brace-style": [2, "1tbs", { + "allowSingleLine": false + }], + "camelcase": 2, + "comma-spacing": [2, { + "before": false, + "after": true + }], + "comma-style": 2, + "computed-property-spacing": [2, "never"], + "consistent-this": [2, "self"], + "constructor-super": 2, + "func-style": [2, "declaration"], + "id-match": [2, "^[a-z]+([A-Z][a-z]+)*$", {"properties": true}], + "indent": [2, 4], + "key-spacing": [2, { + "beforeColon": false, + "afterColon": true, + "mode": "strict" + }], + "max-nested-callbacks": [2, 4], + "new-cap": 2, + "new-parens": 2, + "no-array-constructor": 2, + "no-continue": 2, + "no-lonely-if": 2, + "no-mixed-spaces-and-tabs": 2, + "no-multiple-empty-lines": 2, + "object-curly-spacing": [2, "never"], + "operator-assignment": 2, + "operator-linebreak": 2, + "quotes": [2, "single"], + "semi-spacing": [2, { + "before": false, + "after": true + }], + "semi": [2, "always"], + "space-after-keywords": [2, "always"], + "space-before-blocks": [2, "always"], + "space-before-function-paren": [2, "always"], + "space-before-keywords": [2, "always"], + "space-in-parens": [2, "never"], + "space-infix-ops": 2, + "space-return-throw-case": 2, + "wrap-regex": 2, + + // ignored stylistic rules + "eol-last": 0, + "func-names": 0, + "id-match": 0, + "jsx-quotes": 0, + "lines-around-comment": 0, + "linebreak-style": 0, + "newline-after-var": 0, + "no-inline-comments": 0, + "no-negated-condition": 0, + "no-underscore-dangle": 0, + "one-var": 0, + "padded-blocks": 0, + "quote-props": 0, + "require-jsdoc": 0, + "space-unary-ops": 0, + "spaced-comment": 0, + + + /* + ECMAScript 6 + These rules are only relevant to ES6 environments. + */ + "arrow-parens": [2, "always"], + "arrow-spacing": [2, { + "before": true, + "after": true + }], + "constructor-super": 2, + "generator-star-spacing": [2, { + "before": true, + "after": true + }], + "no-class-assign": 2, + "no-const-assign": 2, + "no-dupe-class-members": 2, + "no-this-before-super": 2, + "prefer-const": 2, + "prefer-spread": 2, + "require-yield": 2, + + // ignored ECMA6 rules + "no-arrow-condition": 0, + "no-var": 0, + "object-shorthand": 0, + "prefer-arrow-callback": 0, + "prefer-reflect": 0, + "prefer-template": 0 + + }, + "env": { + "amd": true, + "es6": true, + "browser": true + }, + "globals": { + "define": false, + "require": false + }, + "parser": "babel-eslint", + "extends": "eslint:recommended" +} \ No newline at end of file diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 248185ccb..000000000 --- a/.jshintrc +++ /dev/null @@ -1,102 +0,0 @@ -{ - // JSHint Configuration, esri jsapi - // Modified from [jshint web defaults][1]. - // Differences between the default and our file are noted - // Options that are commented out completely are uneccesary or problematic for our codebase - // [1] : https://github.com/jshint/jshint/blob/2.x/examples/.jshintrc - // See http://jshint.com/docs/ for more details - - "maxerr" : 5000, // {int} Maximum error before stopping ** Get ALL the errors ** - - // Enforcing - true = enforce this rule, false = don't enforce this rule - "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) - "camelcase" : false, // true: Identifiers must be in camelCase - "curly" : true, // true: Require {} for every new block or scope - "eqeqeq" : false, // true: Require triple equals (===) for comparison ** Just use triples with undefined, null, false, 0 and 1 ** - "es3" : true, // true: Adhere to ECMAScript 3 specification ** Still needed until IE8 support is dropped ** - "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() ** Still needed until IE8 support is dropped ** - "immed" : true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` ** Avoids confusion and minification errors ** - "latedef" : false, // true: Require variables/functions to be defined before being used - "newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()` ** Coding style enforcement ** - "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` - "noempty" : true, // true: Prohibit use of empty blocks - "nonew" : true, // true: Prohibit use of constructors for side-effects (without assignment) ** Coding style enforcement ** - "plusplus" : false, // true: Prohibit use of `++` & `--` - "quotmark" : "single", // Quotation mark consistency: ** Use the same style. Doubles should be used in most cases ** - // false : do nothing (default) - // true : ensure whatever is used is consistent - // "single" : require single quotes - // "double" : require double quotes - "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) - "unused" : "strict", // Warns when you define and never use your variables - // true : allow unused parameters that are followed by a used parameter. - // "vars" : to only check for variables, not function parameters - // "strict" : to check all variables and parameters. - "strict" : false, // true: Requires all functions run in ES5 Strict Mode ** Dojo style and existing codebase conflicts ** - "trailing" : false, // true: Prohibit trailing whitespaces - "indent" : 4, // {int} Number of spaces to use for indentation - //"maxparams" : false, // {int} Max number of formal params allowed per function - //"maxdepth" : false, // {int} Max depth of nested blocks (within functions) - //"maxstatements" : false, // {int} Max number statements per function - //"maxcomplexity" : false, // {int} Max cyclomatic complexity per function - //"maxlen" : false, // {int} Max number of characters per line - - // Relaxing - false = continue to enforce this rule, true = don't enforce this rule (relax it) - "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) - "boss" : false, // true: Tolerate assignments where comparisons would be expected - "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. - "eqnull" : true, // true: Tolerate use of `== null` - "es5" : false, // true: Allow ES5 syntax (ex: getters and setters) - "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`) - "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) - // (ex: `for each`, multiple try/catch, function expression…) - "evil" : false, // true: Tolerate use of `eval` and `new Function()` - "expr" : false, // true: Tolerate `ExpressionStatement` as Programs - "funcscope" : true, // true: Tolerate defining variables inside control statements ** Other variable checks keep use from abusing this ** - "globalstrict" : false, // true: Allow global "use strict" (also enables 'strict') - "iterator" : false, // true: Tolerate using the `__iterator__` property - "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block - "laxbreak" : false, // true: Tolerate possibly unsafe line breakings - "laxcomma" : false, // true: Tolerate comma-first style coding - "loopfunc" : true, // true: Tolerate functions being defined in loops ** Almost required in some callback & promise style code ** - "multistr" : false, // true: Tolerate multi-line strings - "proto" : false, // true: Tolerate using the `__proto__` property - "scripturl" : true, // true: Tolerate script-targeted URLs ** If this is being used, there is probably a good reason ** - "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment - "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` - "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation - "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` - "validthis" : true, // true: Tolerate using this in a non-constructor function ** We don't run in `strict mode` & coding style conflicts ** - - // Environments - "browser" : true, // Web Browser (window, document, etc) - "devel" : true, // Development/debugging (alert, confirm, etc) - "couch" : false, // CouchDB - "dojo" : false, // Dojo Toolkit ** Don't use global dojo objects. Use AMD style coding ** - "jquery" : false, // jQuery - "mootools" : false, // MooTools - "node" : false, // Node.js - "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) - "prototypejs" : false, // Prototype and Scriptaculous - "rhino" : false, // Rhino - "worker" : false, // Web Workers ** Make a jshint comment when this is `true` ** - "wsh" : false, // Windows Scripting Host - "yui" : false, // Yahoo User Interface - - // Legacy ** According to jshint docs, these options are NOT to be used or relied on. Removing them. - //"nomen" : false, // true: Prohibit dangling `_` in variables - //"onevar" : false, // true: Allow only one `var` statement per function - //"passfail" : false, // true: Stop on first error - //"white" : false, // true: Check against strict whitespace and indentation rules - - // Custom Globals - additional predefined global variables - // Using both `predef` and `globals` to support tools with older jshint parsers - "predef" : [ - "define", - "require" - ], - "globals" : { // ** `false` = don't allow variable to be redefined locally - "define": false, - "require": false - } -} diff --git a/Gruntfile.js b/Gruntfile.js index ac8d86f17..d9bab2a13 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,168 +1,170 @@ /* global module */ -module.exports = function(grunt) { +module.exports = function (grunt) { - // middleware for grunt.connect - var middleware = function(connect, options, middlewares) { - // inject a custom middleware into the array of default middlewares for proxy page - var proxypage = require('proxypage'); - var proxyRe = /\/proxy\/proxy.ashx/i; + // middleware for grunt.connect + var middleware = function (connect, options, middlewares) { + // inject a custom middleware into the array of default middlewares for proxy page + var proxypage = require('proxypage'); + var proxyRe = /\/proxy\/proxy.ashx/i; - var enableCORS = function(req, res, next) { - res.setHeader('Access-Control-Allow-Origin', req.headers.origin); - res.setHeader('Access-Control-Allow-Credentials', true); - res.setHeader('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE'); - res.setHeader('Access-Control-Allow-Headers', req.headers['access-control-request-headers']); - return next(); - }; + var enableCORS = function (req, res, next) { + res.setHeader('Access-Control-Allow-Origin', req.headers.origin); + res.setHeader('Access-Control-Allow-Credentials', true); + res.setHeader('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE'); + res.setHeader('Access-Control-Allow-Headers', req.headers['access-control-request-headers']); + return next(); + }; + + var proxyMiddleware = function (req, res, next) { + if (!proxyRe.test(req.url)) { + return next(); + } + proxypage.proxy(req, res); + }; - var proxyMiddleware = function(req, res, next) { - if (!proxyRe.test(req.url)) { - return next(); - } - proxypage.proxy(req, res); + middlewares.unshift(proxyMiddleware); + middlewares.unshift(enableCORS); + middlewares.unshift(connect.json()); //body parser, see https://github.com/senchalabs/connect/wiki/Connect-3.0 + middlewares.unshift(connect.urlencoded()); //body parser + return middlewares; }; - middlewares.unshift(proxyMiddleware); - middlewares.unshift(enableCORS); - middlewares.unshift(connect.json()); //body parser, see https://github.com/senchalabs/connect/wiki/Connect-3.0 - middlewares.unshift(connect.urlencoded()); //body parser - return middlewares; - }; + // grunt task config + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + tag: { + banner: '/* <%= pkg.name %>\n' + + ' * version <%= pkg.version %>\n' + + ' * Project: <%= pkg.homepage %>\n' + + ' */\n' + }, + copy: { + build: { + cwd: 'viewer', + src: ['**'], + dest: 'dist/viewer', + expand: true + } + }, + clean: { + build: { + src: ['dist'] + } + }, + autoprefixer: { + build: { + expand: true, + cwd: 'dist/viewer', + src: ['**/*.css'], + dest: 'dist/viewer' + } + }, + cssmin: { + build: { + expand: true, + cwd: 'dist/viewer', + src: ['**/*.css'], + dest: 'dist/viewer' + } + }, - // grunt task config - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - tag: { - banner: '/* <%= pkg.name %>\n' + - ' * version <%= pkg.version %>\n' + - ' * Project: <%= pkg.homepage %>\n' + - ' */\n' - }, - copy: { - build: { - cwd: 'viewer', - src: ['**'], - dest: 'dist/viewer', - expand: true - } - }, - clean: { - build: { - src: ['dist'] - } - }, - autoprefixer: { - build: { - expand: true, - cwd: 'dist/viewer', - src: ['**/*.css'], - dest: 'dist/viewer' - } - }, - cssmin: { - build: { - expand: true, - cwd: 'dist/viewer', - src: ['**/*.css'], - dest: 'dist/viewer' - } - }, - jshint: { - build: { - src: ['viewer/**/*.js'], - options: { - jshintrc: '.jshintrc', - reporter: require('jshint-stylish') - } - } - }, - uglify: { - build: { - files: [{ - expand: true, - cwd: 'dist/viewer', - src: ['**/*.js', '!**/config/**'], - dest: 'dist/viewer', - ext: '.js' - }], - options: { - banner: '<%= tag.banner %>', - sourceMap: true, - sourceMapIncludeSources: true, - compress: { - drop_console: true - } - } - } - }, - watch: { - dev: { - files: ['viewer/**'], - tasks: ['jshint'] - }, - build: { - files: ['dist/viewer/**'], - tasks: ['jshint'] - } - }, - connect: { - dev: { - options: { - port: 3000, - base: 'viewer', - hostname: '*', - middleware: middleware - } - }, - build: { - options: { - port: 3001, - base: 'dist/viewer', - hostname: '*', - middleware: middleware - } - } - }, - open: { - dev_browser: { - path: 'http://localhost:3000/index.html' - }, - build_browser: { - path: 'http://localhost:3001/index.html' - } - }, - compress: { - build: { - options: { - archive: 'dist/viewer.zip' + eslint: { + build: { + src: ['viewer/**/*.js'], + options: { + eslintrc: '.eslintrc', + reporter: require('eslint-stylish') + } + } + }, + + uglify: { + build: { + files: [{ + expand: true, + cwd: 'dist/viewer', + src: ['**/*.js', '!**/config/**'], + dest: 'dist/viewer', + ext: '.js' + }], + options: { + banner: '<%= tag.banner %>', + sourceMap: true, + sourceMapIncludeSources: true, + compress: { + 'drop_console': true + } + } + } }, - files: [{ - expand: true, - cwd: 'dist/viewer', - src: ['**', '!**/dijit.css'] - }] - } - } - }); + watch: { + dev: { + files: ['viewer/**'], + tasks: ['jshint'] + }, + build: { + files: ['dist/viewer/**'], + tasks: ['jshint'] + } + }, + connect: { + dev: { + options: { + port: 3000, + base: 'viewer', + hostname: '*', + middleware: middleware + } + }, + build: { + options: { + port: 3001, + base: 'dist/viewer', + hostname: '*', + middleware: middleware + } + } + }, + open: { + 'dev_browser': { + path: 'http://localhost:3000/index.html' + }, + 'build_browser': { + path: 'http://localhost:3001/index.html' + } + }, + compress: { + build: { + options: { + archive: 'dist/viewer.zip' + }, + files: [{ + expand: true, + cwd: 'dist/viewer', + src: ['**', '!**/dijit.css'] + }] + } + } + }); - // load the tasks - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-autoprefixer'); - grunt.loadNpmTasks('grunt-contrib-cssmin'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-contrib-connect'); - grunt.loadNpmTasks('grunt-newer'); - grunt.loadNpmTasks('grunt-open'); - grunt.loadNpmTasks('grunt-contrib-compress'); + // load the tasks + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-autoprefixer'); + grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-eslint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-newer'); + grunt.loadNpmTasks('grunt-open'); + grunt.loadNpmTasks('grunt-contrib-compress'); - // define the tasks - grunt.registerTask('default', 'Watches the project for changes, automatically builds them and runs a web server and opens default browser to preview.', ['jshint', 'connect:dev', 'open:dev_browser', 'watch:dev']); - grunt.registerTask('build', 'Compiles all of the assets and copies the files to the build directory.', ['clean', 'copy', 'scripts', 'stylesheets', 'compress:build']); - grunt.registerTask('build-view', 'Compiles all of the assets and copies the files to the build directory starts a web server and opens browser to preview app.', ['clean', 'copy', 'scripts', 'stylesheets', 'compress:build', 'connect:build', 'open:build_browser', 'watch:build']); - grunt.registerTask('scripts', 'Compiles the JavaScript files.', ['jshint', 'uglify']); - grunt.registerTask('stylesheets', 'Auto prefixes css and compiles the stylesheets.', ['autoprefixer', 'cssmin']); - grunt.registerTask('hint', 'Run simple jshint.', ['jshint']); + // define the tasks + grunt.registerTask('default', 'Watches the project for changes, automatically builds them and runs a web server and opens default browser to preview.', ['eslint', 'connect:dev', 'open:dev_browser', 'watch:dev']); + grunt.registerTask('build', 'Compiles all of the assets and copies the files to the build directory.', ['clean', 'copy', 'scripts', 'stylesheets', 'compress:build']); + grunt.registerTask('build-view', 'Compiles all of the assets and copies the files to the build directory starts a web server and opens browser to preview app.', ['clean', 'copy', 'scripts', 'stylesheets', 'compress:build', 'connect:build', 'open:build_browser', 'watch:build']); + grunt.registerTask('scripts', 'Compiles the JavaScript files.', ['eslint', 'uglify']); + grunt.registerTask('stylesheets', 'Auto prefixes css and compiles the stylesheets.', ['autoprefixer', 'cssmin']); + grunt.registerTask('hint', 'Run simple eslint.', ['eslint']); }; \ No newline at end of file diff --git a/package.json b/package.json index 86287a665..2f5c6a243 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,27 @@ { - "name": "ConfigurableMapViewerCMV", - "version": "1.3.4", - "author": "cmv.io - https://github.com/cmv/", - "license": "MIT", - "year": "2015", - "homepage": "http://cmv.io/", - "repository": "https://github.com/cmv/cmv-app/", - "dependencies": { - "grunt": "0.4.x", - "grunt-autoprefixer": "0.7.x", - "grunt-contrib-clean": "0.5.x", - "grunt-contrib-connect": "0.7.x", - "grunt-contrib-copy": "0.5.x", - "grunt-contrib-cssmin": "0.9.x", - "grunt-contrib-jshint": "0.10.x", - "jshint-stylish": "0.2.x", - "grunt-contrib-uglify": "0.4.x", - "grunt-contrib-watch": "0.6.x", - "grunt-newer": "0.7.x", - "grunt-open": "0.2.x", - "grunt-contrib-compress": "0.10.x", - "proxypage": "*" - }, - "engine": "node >= 0.10" + "name": "ConfigurableMapViewerCMV", + "version": "1.3.4", + "author": "cmv.io - https://github.com/cmv/", + "license": "MIT", + "year": "2015", + "homepage": "http://cmv.io/", + "repository": "https://github.com/cmv/cmv-app/", + "dependencies": { + "babel-eslint": "4.1.x", + "eslint": "1.7.3", + "grunt": "0.4.x", + "grunt-autoprefixer": "0.7.x", + "grunt-contrib-clean": "0.5.x", + "grunt-contrib-connect": "0.7.x", + "grunt-contrib-copy": "0.5.x", + "grunt-contrib-cssmin": "0.9.x", + "grunt-eslint": "17.3.x", + "grunt-contrib-uglify": "0.4.x", + "grunt-contrib-watch": "0.6.x", + "grunt-newer": "0.7.x", + "grunt-open": "0.2.x", + "grunt-contrib-compress": "0.10.x", + "proxypage": "*" + }, + "engine": "node >= 0.10" } \ No newline at end of file diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 6d4b1de2a..7ba02bf62 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -1,32 +1,33 @@ (function () { + 'use strict'; - // globel dojoConfig is required for async loading of gmaps api - window.dojoConfig = { - async: true, - packages: [{ - name: 'viewer', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/viewer' - }, { - name: 'config', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/config' - }, { - name: 'gis', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/gis' - }] - }; + // globel dojoConfig is required for async loading of gmaps api + window.dojoConfig = { + async: true, + packages: [{ + name: 'viewer', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/viewer' + }, { + name: 'config', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/config' + }, { + name: 'gis', + location: location.pathname.replace(/[^\/]+$/, '') + 'js/gis' + }] + }; - // get the config file from the url if present - var file = 'config/viewer', - s = window.location.search, - q = s.match(/config=([^&]*)/i); - if (q && q.length > 0) { - file = q[1]; - if (file.indexOf('/') < 0) { - file = 'config/' + file; + // get the config file from the url if present + var file = 'config/viewer', + s = window.location.search, + q = s.match(/config=([^&]*)/i); + if (q && q.length > 0) { + file = q[1]; + if (file.indexOf('/') < 0) { + file = 'config/' + file; + } } - } - require(window.dojoConfig, ['viewer/Controller', file, 'dojo/domReady!'], function (Controller, config) { - Controller.startup(config); - }); + require(window.dojoConfig, ['viewer/Controller', file, 'dojo/domReady!'], function (Controller, config) { + Controller.startup(config); + }); })(); \ No newline at end of file diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 7cafcaf89..73ace0bc2 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -2,7 +2,9 @@ define([ //'esri/dijit/Basemap', //'esri/dijit/BasemapLayer', //'esri/layers/osm' -], function ( /* Basemap, BasemapLayer, osm */ ) { +], function (/* Basemap, BasemapLayer, osm */) { + 'use strict'; + return { map: true, // needs a refrence to the map mode: 'agol', //must be either 'agol' or 'custom' diff --git a/viewer/js/config/bookmarks.js b/viewer/js/config/bookmarks.js index de9952abf..cf89998e3 100644 --- a/viewer/js/config/bookmarks.js +++ b/viewer/js/config/bookmarks.js @@ -1,18 +1,18 @@ define({ - map: true, - editable: true, - bookmarks: [ - { - extent: { - xmin: -15489130.48708616, - ymin: 398794.4860580916, - xmax: -5891085.7193757, - ymax: 8509680.431452557, - spatialReference: { - wkid: 102100 - } - }, - name: 'USA' - } - ] + map: true, + editable: true, + bookmarks: [ + { + extent: { + xmin: -15489130.48708616, + ymin: 398794.4860580916, + xmax: -5891085.7193757, + ymax: 8509680.431452557, + spatialReference: { + wkid: 102100 + } + }, + name: 'USA' + } + ] }); \ No newline at end of file diff --git a/viewer/js/config/find.js b/viewer/js/config/find.js index 7e01c3e65..760c7b0bb 100644 --- a/viewer/js/config/find.js +++ b/viewer/js/config/find.js @@ -1,85 +1,112 @@ +/*eslint strict: 0, no-console: 0, no-alert: 0*/ define({ - map: true, - zoomExtentFactor: 2, - queries: [ - { - description: 'Find A Public Safety Location By Name', - url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', - layerIds: [1, 2, 3, 4, 5, 6, 7], - searchFields: ['FDNAME, PDNAME', 'NAME', 'RESNAME'], - minChars: 2, - gridColumns: [ - { field: 'Name', label: 'Name' }, - { field: 'layerName', label: 'Layer', width: 100, sortable: false, resizable: false } - ], - sort: [ - { - attribute: 'Name', - descending: false - } - ], - prompt: 'fdname, pdname, name or resname', - selectionMode: 'single' - }, - { - description: 'Find Incident By Code/Description', - url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', - layerIds: [15, 17, 18], - searchFields: ['FCODE', 'DESCRIPTION'], - minChars: 4, - gridColumns: [ - { field: 'layerName', label: 'Layer', width: 100, sortable: false, resizable: false }, - { field: 'Fcode', label: 'Fcode', width: 100 }, - { field: 'Description', label: 'Descr' }, - { field: 'SORT_VALUE', visible: false, get: function (findResult){ - return findResult.layerName + ' ' + findResult.feature.attributes.Fcode; //seems better to use attributes[ 'Fcode' ] but fails build. Attribute names will be aliases and may contain spaces and mixed cases. - } } - ], - sort: [ - { - attribute: 'SORT_VALUE', - descending: false - } - ], - prompt: 'fdname, pdname, name or resname', - customGridEventHandlers: [ - { - event: '.dgrid-row:click', - handler: function ( event ) { - alert( 'You clicked a row!' ); - console.log( event ); - } - } - ] - } - ], - selectionSymbols: { - polygon: { - type : 'esriSFS', - style : 'esriSFSSolid', - color : [255, 0, 0, 62], - outline: { - type : 'esriSLS', - style: 'esriSLSSolid', - color: [255, 0, 0, 255], - width: 3 - } - }, - point: { - type : 'esriSMS', - style : 'esriSMSCircle', - size : 25, - color : [255, 0, 0, 62], - angle : 0, - xoffset: 0, - yoffset: 0, - outline: { - type : 'esriSLS', - style: 'esriSLSSolid', - color: [255, 0, 0, 255], - width: 2 - } - } - }, - selectionMode : 'extended' + map: true, + zoomExtentFactor: 2, + queries: [ + { + description: 'Find A Public Safety Location By Name', + url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', + layerIds: [1, 2, 3, 4, 5, 6, 7], + searchFields: ['FDNAME, PDNAME', 'NAME', 'RESNAME'], + minChars: 2, + gridColumns: [ + { + field: 'Name', + label: 'Name' + }, + { + field: 'layerName', + label: 'Layer', + width: 100, + sortable: false, + resizable: false + } + ], + sort: [ + { + attribute: 'Name', + descending: false + } + ], + prompt: 'fdname, pdname, name or resname', + selectionMode: 'single' + }, + { + description: 'Find Incident By Code/Description', + url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', + layerIds: [15, 17, 18], + searchFields: ['FCODE', 'DESCRIPTION'], + minChars: 4, + gridColumns: [ + { + field: 'layerName', + label: 'Layer', + width: 100, + sortable: false, + resizable: false + }, + { + field: 'Fcode', + label: 'Fcode', + width: 100 + }, + { + field: 'Description', + label: 'Descr' + }, + { + field: 'SORT_VALUE', + visible: false, + get: function (findResult) { + return findResult.layerName + ' ' + findResult.feature.attributes.Fcode; //seems better to use attributes[ 'Fcode' ] but fails build. Attribute names will be aliases and may contain spaces and mixed cases. + } + } + ], + sort: [ + { + attribute: 'SORT_VALUE', + descending: false + } + ], + prompt: 'fdname, pdname, name or resname', + customGridEventHandlers: [ + { + event: '.dgrid-row:click', + handler: function (event) { + alert('You clicked a row!'); + console.log(event); + } + } + ] + } + ], + selectionSymbols: { + polygon: { + type: 'esriSFS', + style: 'esriSFSSolid', + color: [255, 0, 0, 62], + outline: { + type: 'esriSLS', + style: 'esriSLSSolid', + color: [255, 0, 0, 255], + width: 3 + } + }, + point: { + type: 'esriSMS', + style: 'esriSMSCircle', + size: 25, + color: [255, 0, 0, 62], + angle: 0, + xoffset: 0, + yoffset: 0, + outline: { + type: 'esriSLS', + style: 'esriSLSSolid', + color: [255, 0, 0, 255], + width: 2 + } + } + }, + selectionMode: 'extended' }); \ No newline at end of file diff --git a/viewer/js/config/identify.js b/viewer/js/config/identify.js index 2baefba3e..ba781edda 100644 --- a/viewer/js/config/identify.js +++ b/viewer/js/config/identify.js @@ -1,68 +1,68 @@ define({ - map: true, - mapClickMode: true, - mapRightClickMenu: true, - identifyLayerInfos: true, - identifyTolerance: 5, + map: true, + mapClickMode: true, + mapRightClickMenu: true, + identifyLayerInfos: true, + identifyTolerance: 5, - // config object definition: - // {:{ - // :{ - // - // } - // }, - // :{ - // :{ - // - // } - // } - // } + // config object definition: + // {:{ + // :{ + // + // } + // }, + // :{ + // :{ + // + // } + // } + // } - // for details on pop-up definition see: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html + // for details on pop-up definition see: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html - identifies: { - meetupHometowns: { - 0: { - title: 'Hometowns', - fieldInfos: [{ - fieldName: 'Location', - visible: true - }] - } - }, - louisvillePubSafety: { - 2: { - title: 'Police Station', - fieldInfos: [{ - fieldName: 'Name', - visible: true - }, { - fieldName: 'Address', - visible: true - }, { - fieldName: 'Type', - visible: true - }, { - fieldName: 'Police Function', - visible: true - }, { - fieldName: 'Last Update Date', - visible: true - }] - }, - 8: { - title: 'Traffic Camera', - description: '{Description} lasted updated: {Last Update Date}', - mediaInfos: [{ - title: '', - caption: '', - type: 'image', - value: { - sourceURL: '{Location URL}', - linkURL: '{Location URL}' - } - }] - } - } - } + identifies: { + meetupHometowns: { + 0: { + title: 'Hometowns', + fieldInfos: [{ + fieldName: 'Location', + visible: true + }] + } + }, + louisvillePubSafety: { + 2: { + title: 'Police Station', + fieldInfos: [{ + fieldName: 'Name', + visible: true + }, { + fieldName: 'Address', + visible: true + }, { + fieldName: 'Type', + visible: true + }, { + fieldName: 'Police Function', + visible: true + }, { + fieldName: 'Last Update Date', + visible: true + }] + }, + 8: { + title: 'Traffic Camera', + description: '{Description} lasted updated: {Last Update Date}', + mediaInfos: [{ + title: '', + caption: '', + type: 'image', + value: { + sourceURL: '{Location URL}', + linkURL: '{Location URL}' + } + }] + } + } + } }); \ No newline at end of file diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 6717649e4..8ed10af85 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -6,6 +6,7 @@ define([ 'esri/tasks/GeometryService', 'esri/layers/ImageParameters' ], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters) { + 'use strict'; // url to your proxy page, must be on same machine hosting you app. See proxy folder for readme. esriConfig.defaults.io.proxyUrl = 'proxy/proxy.ashx'; @@ -27,7 +28,7 @@ define([ // layerIds: [0], // layerOption: 'show' // }) - function buildImageParameters(config) { + function buildImageParameters (config) { config = config || {}; var ip = new ImageParameters(); //image parameters for dynamic services, set to png32 for higher quality exports diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index 9ee9335f5..fdee8dcc5 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', @@ -70,7 +71,7 @@ define([ var menuItem = new MenuItem({ id: basemap, label: this.basemaps[basemap].title, - iconClass: (basemap == this.mapStartBasemap) ? 'selectedIcon' : 'emptyIcon', + iconClass: (basemap === this.mapStartBasemap) ? 'selectedIcon' : 'emptyIcon', onClick: lang.hitch(this, function () { if (basemap !== this.currentBasemap) { this.currentBasemap = basemap; @@ -81,7 +82,7 @@ define([ } var ch = this.menu.getChildren(); array.forEach(ch, function (c) { - if (c.id == basemap) { + if (c.id === basemap) { c.set('iconClass', 'selectedIcon'); } else { c.set('iconClass', 'emptyIcon'); @@ -102,11 +103,9 @@ define([ if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the title of custom basemaps in viewer.js config this.gallery.select(this.mapStartBasemap); } - } else { - if (this.mapStartBasemap) { - if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the agol basemap name - this.map.setBasemap(this.mapStartBasemap); - } + } else if (this.mapStartBasemap) { + if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the agol basemap name + this.map.setBasemap(this.mapStartBasemap); } } } diff --git a/viewer/js/gis/dijit/Bookmarks.js b/viewer/js/gis/dijit/Bookmarks.js index 194c66972..3f6572934 100644 --- a/viewer/js/gis/dijit/Bookmarks.js +++ b/viewer/js/gis/dijit/Bookmarks.js @@ -1,41 +1,42 @@ +/*eslint strict: 0*/ define([ - 'dojo/_base/declare', - 'dijit/_WidgetBase', - 'esri/dijit/Bookmarks', - 'dojo/json', - 'dojo/cookie', - 'dojo/_base/lang', - 'xstyle/css!./Bookmarks/css/Bookmarks.css' + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'esri/dijit/Bookmarks', + 'dojo/json', + 'dojo/cookie', + 'dojo/_base/lang', + 'xstyle/css!./Bookmarks/css/Bookmarks.css' ], function (declare, _WidgetBase, Bookmarks, json, cookie, lang) { - return declare([_WidgetBase], { - declaredClass: 'gis.digit.Bookmarks', - postCreate: function () { - this.inherited(arguments); - var bookmarks = this.bookmarks; // from the options passed in - this.bookmarkItems = cookie('bookmarkItems'); - if (this.bookmarkItems === undefined) { - this.bookmarkItems = []; - } else { - this.bookmarkItems = json.parse(this.bookmarkItems); - } + return declare([_WidgetBase], { + declaredClass: 'gis.digit.Bookmarks', + postCreate: function () { + this.inherited(arguments); + var bookmarks = this.bookmarks; // from the options passed in + this.bookmarkItems = cookie('bookmarkItems'); + if (this.bookmarkItems === undefined) { + this.bookmarkItems = []; + } else { + this.bookmarkItems = json.parse(this.bookmarkItems); + } - this.bookmarks = new Bookmarks({ - map: this.map, - editable: this.editable, - bookmarks: lang.mixin(this.bookmarkItems, bookmarks) - }, this.domNode); + this.bookmarks = new Bookmarks({ + map: this.map, + editable: this.editable, + bookmarks: lang.mixin(this.bookmarkItems, bookmarks) + }, this.domNode); - this.connect(this.bookmarks, 'onEdit', 'setBookmarks'); - this.connect(this.bookmarks, 'onRemove', 'setBookmarks'); - }, - setBookmarks: function () { - cookie('bookmarkItems', json.stringify(this.bookmarks.toJson()), { - expires: 365 - }); - }, - _export: function () { - return json.stringify(this.bookmarks.toJson()); - } - }); + this.connect(this.bookmarks, 'onEdit', 'setBookmarks'); + this.connect(this.bookmarks, 'onRemove', 'setBookmarks'); + }, + setBookmarks: function () { + cookie('bookmarkItems', json.stringify(this.bookmarks.toJson()), { + expires: 365 + }); + }, + _export: function () { + return json.stringify(this.bookmarks.toJson()); + } + }); }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Directions.js b/viewer/js/gis/dijit/Directions.js index 7c61df263..a0b031b80 100644 --- a/viewer/js/gis/dijit/Directions.js +++ b/viewer/js/gis/dijit/Directions.js @@ -1,18 +1,19 @@ +/*eslint strict: 0*/ define([ - 'dojo/_base/declare', - 'dijit/_WidgetBase', - 'dijit/_TemplatedMixin', - 'esri/dijit/Directions', - 'dojo/text!./Directions/templates/Directions.html', - 'dojo/_base/lang', - 'dijit/Menu', - 'dijit/MenuItem', - 'dijit/PopupMenuItem', - 'dijit/MenuSeparator', - 'esri/geometry/Point', - 'esri/SpatialReference', - 'dojo/topic', - 'dojo/i18n!./Directions/nls/resource' + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'esri/dijit/Directions', + 'dojo/text!./Directions/templates/Directions.html', + 'dojo/_base/lang', + 'dijit/Menu', + 'dijit/MenuItem', + 'dijit/PopupMenuItem', + 'dijit/MenuSeparator', + 'esri/geometry/Point', + 'esri/SpatialReference', + 'dojo/topic', + 'dojo/i18n!./Directions/nls/resource' ], function (declare, _WidgetBase, _TemplatedMixin, Directions, template, lang, Menu, MenuItem, PopupMenuItem, MenuSeparator, Point, SpatialReference, topic, i18n) { return declare([_WidgetBase, _TemplatedMixin], { @@ -25,13 +26,13 @@ define([ }, this.options), this.directionsNode); this.directions.startup(); - //temp fix for 3.12 and 3.13 map click button. + //temp fix for 3.12 and 3.13 map click button. if (this.directions._activateButton) { this.directions._activateButton.style.display = 'none'; } else if (this.directions._activateButtonNode) { this.directions._activateButtonNode.style.display = 'none'; - this.directions._addDestinationNode.style['float'] = 'inherit'; - this.directions._optionsButtonNode.style['float'] = 'inherit'; + this.directions._addDestinationNode.style.float = 'inherit'; + this.directions._optionsButtonNode.style.float = 'inherit'; this.directions._optionsButtonNode.style.marginRight = '5px'; } diff --git a/viewer/js/gis/dijit/Draw.js b/viewer/js/gis/dijit/Draw.js index 7a04c7cb8..2d5b11219 100644 --- a/viewer/js/gis/dijit/Draw.js +++ b/viewer/js/gis/dijit/Draw.js @@ -1,27 +1,28 @@ +/*eslint strict: 0*/ define([ - 'dojo/_base/declare', - 'dijit/_WidgetBase', - 'dijit/_TemplatedMixin', - 'dijit/_WidgetsInTemplateMixin', - 'dojo/_base/lang', - 'dojo/_base/Color', - 'esri/toolbars/draw', - 'esri/layers/GraphicsLayer', - 'esri/graphic', - 'esri/renderers/SimpleRenderer', - 'dojo/text!./Draw/templates/Draw.html', - 'esri/renderers/UniqueValueRenderer', - 'esri/symbols/SimpleMarkerSymbol', - 'esri/symbols/SimpleLineSymbol', - 'esri/symbols/SimpleFillSymbol', - 'esri/layers/FeatureLayer', - 'dojo/topic', - 'dojo/aspect', - 'dojo/i18n!./Draw/nls/resource', + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_WidgetsInTemplateMixin', + 'dojo/_base/lang', + 'dojo/_base/Color', + 'esri/toolbars/draw', + 'esri/layers/GraphicsLayer', + 'esri/graphic', + 'esri/renderers/SimpleRenderer', + 'dojo/text!./Draw/templates/Draw.html', + 'esri/renderers/UniqueValueRenderer', + 'esri/symbols/SimpleMarkerSymbol', + 'esri/symbols/SimpleLineSymbol', + 'esri/symbols/SimpleFillSymbol', + 'esri/layers/FeatureLayer', + 'dojo/topic', + 'dojo/aspect', + 'dojo/i18n!./Draw/nls/resource', - 'dijit/form/Button', - 'xstyle/css!./Draw/css/Draw.css', - 'xstyle/css!./Draw/css/adw-icons.css' + 'dijit/form/Button', + 'xstyle/css!./Draw/css/Draw.css', + 'xstyle/css!./Draw/css/adw-icons.css' ], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, Color, Draw, GraphicsLayer, Graphic, SimpleRenderer, drawTemplate, UniqueValueRenderer, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, FeatureLayer, topic, aspect, i18n) { // main draw dijit @@ -94,12 +95,12 @@ define([ mode: FeatureLayer.MODE_SNAPSHOT }); this.polygonRenderer = new UniqueValueRenderer(new SimpleFillSymbol(), 'ren', null, null, ', '); - this.polygonRenderer.addValue({ - value: 1, - symbol: new SimpleFillSymbol({ - color: [255,170,0,255], + this.polygonRenderer.addValue({ + value: 1, + symbol: new SimpleFillSymbol({ + color: [255, 170, 0, 255], outline: { - color: [255,170,0,255], + color: [255, 170, 0, 255], width: 1, type: 'esriSLS', style: 'esriSLSSolid' @@ -146,36 +147,36 @@ define([ disconnectMapClick: function () { topic.publish('mapClickMode/setCurrent', 'draw'); this.enableStopButtons(); - // dojo.disconnect(this.mapClickEventHandle); - // this.mapClickEventHandle = null; + // dojo.disconnect(this.mapClickEventHandle); + // this.mapClickEventHandle = null; }, connectMapClick: function () { topic.publish('mapClickMode/setDefault'); this.disableStopButtons(); - // if (this.mapClickEventHandle === null) { - // this.mapClickEventHandle = dojo.connect(this.map, 'onClick', this.mapClickEventListener); - // } + // if (this.mapClickEventHandle === null) { + // this.mapClickEventHandle = dojo.connect(this.map, 'onClick', this.mapClickEventListener); + // } }, onDrawToolbarDrawEnd: function (evt) { this.drawToolbar.deactivate(); this.drawModeTextNode.innerText = this.i18n.labels.currentDrawModeNone; var graphic; switch (evt.geometry.type) { - case 'point': - graphic = new Graphic(evt.geometry); - this.pointGraphics.add(graphic); - break; - case 'polyline': - graphic = new Graphic(evt.geometry); - this.polylineGraphics.add(graphic); - break; - case 'polygon': - graphic = new Graphic(evt.geometry, null, { - ren: 1 - }); - this.polygonGraphics.add(graphic); - break; - default: + case 'point': + graphic = new Graphic(evt.geometry); + this.pointGraphics.add(graphic); + break; + case 'polyline': + graphic = new Graphic(evt.geometry); + this.polylineGraphics.add(graphic); + break; + case 'polygon': + graphic = new Graphic(evt.geometry, null, { + ren: 1 + }); + this.polygonGraphics.add(graphic); + break; + default: } this.connectMapClick(); }, @@ -197,20 +198,20 @@ define([ this.disableStopButtons(); }, disableStopButtons: function () { - this.stopDrawingButton.set( 'disabled', true ); - this.eraseDrawingButton.set( 'disabled', !this.noGraphics() ); + this.stopDrawingButton.set('disabled', true); + this.eraseDrawingButton.set('disabled', !this.noGraphics()); }, enableStopButtons: function () { - this.stopDrawingButton.set( 'disabled', false ); - this.eraseDrawingButton.set( 'disabled', !this.noGraphics() ); + this.stopDrawingButton.set('disabled', false); + this.eraseDrawingButton.set('disabled', !this.noGraphics()); }, noGraphics: function () { - if ( this.pointGraphics.graphics.length > 0 ) { + if (this.pointGraphics.graphics.length > 0) { return true; - } else if ( this.polylineGraphics.graphics.length > 0 ) { + } else if (this.polylineGraphics.graphics.length > 0) { return true; - } else if ( this.polygonGraphics.graphics.length > 0 ) { + } else if (this.polygonGraphics.graphics.length > 0) { return true; } else { return false; diff --git a/viewer/js/gis/dijit/Editor.js b/viewer/js/gis/dijit/Editor.js index 094377bec..4e50d0a59 100644 --- a/viewer/js/gis/dijit/Editor.js +++ b/viewer/js/gis/dijit/Editor.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Find.js b/viewer/js/gis/dijit/Find.js index b39eb675e..dfa737b3b 100644 --- a/viewer/js/gis/dijit/Find.js +++ b/viewer/js/gis/dijit/Find.js @@ -1,596 +1,598 @@ -define( - [ - 'dojo/_base/declare', - 'dijit/_WidgetBase', - 'dijit/_TemplatedMixin', - 'dijit/_WidgetsInTemplateMixin', - 'dojo/dom-construct', - 'dojo/_base/lang', - 'dojo/_base/array', - 'dojo/on', - 'dojo/keys', - 'dojo/dom-style', - 'dojo/store/Memory', - 'dgrid/OnDemandGrid', - 'dgrid/Selection', - 'dgrid/Keyboard', - 'dgrid/extensions/ColumnResizer', - 'esri/layers/GraphicsLayer', - 'esri/symbols/jsonUtils', - 'esri/graphicsUtils', - 'esri/tasks/FindTask', - 'esri/tasks/FindParameters', - 'esri/geometry/Extent', - 'dojo/text!./Find/templates/Find.html', - 'dojo/i18n!./Find/nls/resource', +/*eslint strict: 0*/ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_WidgetsInTemplateMixin', + 'dojo/dom-construct', + 'dojo/_base/lang', + 'dojo/_base/array', + 'dojo/on', + 'dojo/keys', + 'dojo/dom-style', + 'dojo/store/Memory', + 'dgrid/OnDemandGrid', + 'dgrid/Selection', + 'dgrid/Keyboard', + 'dgrid/extensions/ColumnResizer', + 'esri/layers/GraphicsLayer', + 'esri/symbols/jsonUtils', + 'esri/graphicsUtils', + 'esri/tasks/FindTask', + 'esri/tasks/FindParameters', + 'esri/geometry/Extent', + 'dojo/text!./Find/templates/Find.html', + 'dojo/i18n!./Find/nls/resource', - 'dijit/form/Form', - 'dijit/form/DropDownButton', - 'dijit/TooltipDialog', - 'dijit/form/FilteringSelect', - 'dijit/form/ValidationTextBox', - 'dijit/form/CheckBox', - 'xstyle/css!./Find/css/Find.css' - ], function ( - declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, domConstruct, lang, array, on, keys, domStyle, Memory, - OnDemandGrid, Selection, Keyboard, ColumnResizer, GraphicsLayer, symbolUtils, graphicsUtils, FindTask, FindParameters, Extent, - FindTemplate, i18n - ) { - return declare( - [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { - widgetsInTemplate: true, - templateString: FindTemplate, - baseClass: 'gis_AdvancedFindDijit', - i18n: i18n, - spatialReference: null, - showOptionsButton: false, - zoomOptions: { - select: true, - deselect: false + 'dijit/form/Form', + 'dijit/form/DropDownButton', + 'dijit/TooltipDialog', + 'dijit/form/FilteringSelect', + 'dijit/form/ValidationTextBox', + 'dijit/form/CheckBox', + 'xstyle/css!./Find/css/Find.css' +], function ( + declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, domConstruct, lang, array, on, keys, domStyle, Memory, + OnDemandGrid, Selection, Keyboard, ColumnResizer, GraphicsLayer, symbolUtils, graphicsUtils, FindTask, FindParameters, Extent, + FindTemplate, i18n +) { + + return declare( + [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { + widgetsInTemplate: true, + templateString: FindTemplate, + baseClass: 'gis_AdvancedFindDijit', + i18n: i18n, + spatialReference: null, + showOptionsButton: false, + zoomOptions: { + select: true, + deselect: false + }, + defaultResultsSymbols: { + point: { + type: 'esriSMS', + style: 'esriSMSCircle', + size: 25, + color: [0, 255, 255, 32], + angle: 0, + xoffset: 0, + yoffset: 0, + outline: { + type: 'esriSLS', + style: 'esriSLSSolid', + color: [0, 255, 255, 255], + width: 2 + } }, - defaultResultsSymbols: { - point: { - type: 'esriSMS', - style: 'esriSMSCircle', - size: 25, - color: [0, 255, 255, 32], - angle: 0, - xoffset: 0, - yoffset: 0, - outline: { - type: 'esriSLS', - style: 'esriSLSSolid', - color: [0, 255, 255, 255], - width: 2 - } - }, - polyline: { + polyline: { + type: 'esriSLS', + style: 'esriSLSSolid', + color: [0, 255, 255, 255], + width: 3 + }, + polygon: { + type: 'esriSFS', + style: 'esriSFSSolid', + color: [0, 255, 255, 32], + outline: { type: 'esriSLS', style: 'esriSLSSolid', color: [0, 255, 255, 255], width: 3 - }, - polygon: { - type: 'esriSFS', - style: 'esriSFSSolid', - color: [0, 255, 255, 32], - outline: { - type: 'esriSLS', - style: 'esriSLSSolid', - color: [0, 255, 255, 255], - width: 3 - } } - }, - defaultSelectionSymbols: { - point: { - type: 'esriSMS', - style: 'esriSMSCircle', - size: 25, - color: [4, 156, 219, 32], - angle: 0, - xoffset: 0, - yoffset: 0, - outline: { - type: 'esriSLS', - style: 'esriSLSSolid', - color: [4, 156, 219, 255], - width: 2 - } - }, - polyline: { + } + }, + defaultSelectionSymbols: { + point: { + type: 'esriSMS', + style: 'esriSMSCircle', + size: 25, + color: [4, 156, 219, 32], + angle: 0, + xoffset: 0, + yoffset: 0, + outline: { type: 'esriSLS', style: 'esriSLSSolid', color: [4, 156, 219, 255], - width: 3 - }, - polygon: { - type: 'esriSFS', - style: 'esriSFSSolid', - color: [4, 156, 219, 32], - outline: { - type: 'esriSLS', - style: 'esriSLSSolid', - color: [4, 156, 219, 255], - width: 3 - } + width: 2 } }, - postCreate: function () { - this.inherited(arguments); - if (this.showOptionsButton) { - domStyle.set(this.optionsDropDownDijit.domNode, 'display', 'inline-block'); - } - this.initializeGlobalVariables(); - this.addKeyUpHandlerToSearchInput(); - this.initializeQueries(); - this.updateSearchPrompt(); + polyline: { + type: 'esriSLS', + style: 'esriSLSSolid', + color: [4, 156, 219, 255], + width: 3 }, - initializeGlobalVariables: function () { - this.queryIdx = 0; - this.currentQueryEventHandlers = []; - this.gridColumns = null; - if (!this.selectionMode) { - this.selectionMode = 'single'; - } - if (!this.zoomExtentFactor) { - this.zoomExtentFactor = 1.5; - } - if (!this.spatialReference) { - this.spatialReference = this.map.spatialReference.wkid; - } - if (!this.pointExtentSize) { - this.pointExtentSize = this.spatialReference === 4326 ? 0.0001 : 25; + polygon: { + type: 'esriSFS', + style: 'esriSFSSolid', + color: [4, 156, 219, 32], + outline: { + type: 'esriSLS', + style: 'esriSLSSolid', + color: [4, 156, 219, 255], + width: 3 } - }, - addKeyUpHandlerToSearchInput: function () { - this.own( - on( - this.searchTextDijit, 'keyup', lang.hitch( - this, function (evt) { - if (evt.keyCode === keys.ENTER) { - this.search(); - } + } + }, + postCreate: function () { + this.inherited(arguments); + if (this.showOptionsButton) { + domStyle.set(this.optionsDropDownDijit.domNode, 'display', 'inline-block'); + } + this.initializeGlobalVariables(); + this.addKeyUpHandlerToSearchInput(); + this.initializeQueries(); + this.updateSearchPrompt(); + }, + initializeGlobalVariables: function () { + this.queryIdx = 0; + this.currentQueryEventHandlers = []; + this.gridColumns = null; + if (!this.selectionMode) { + this.selectionMode = 'single'; + } + if (!this.zoomExtentFactor) { + this.zoomExtentFactor = 1.5; + } + if (!this.spatialReference) { + this.spatialReference = this.map.spatialReference.wkid; + } + if (!this.pointExtentSize) { + this.pointExtentSize = this.spatialReference === 4326 ? 0.0001 : 25; + } + }, + addKeyUpHandlerToSearchInput: function () { + this.own( + on( + this.searchTextDijit, 'keyup', lang.hitch( + this, function (evt) { + if (evt.keyCode === keys.ENTER) { + this.search(); } - ) + } ) - ); - }, - initializeQueries: function () { - var k = 0, - queryLen = this.queries.length; - for (k = 0; k < queryLen; k++) { - this.queries[k].id = k; - } - this.querySelectDom.style.display = 'none'; - if (queryLen > 1) { - var queryStore = new Memory({ - data: this.queries - }); - this.querySelectDijit.set('store', queryStore); - this.querySelectDijit.set('value', this.queryIdx); - this.querySelectDom.style.display = 'block'; - } - }, - search: function () { - if (this.userInputIsInvalid()) { - this.displayInvalidUserInputMessage(); - return; - } - if (this.queryConfigurationIsInvalid()) { - this.displayInvalidQueryConfigurationMessage(); - return; - } - this.createOrResetResultsGrid(); - this.displayFindMessage(this.i18n.searching); - this.executeFindTask(); - }, - executeFindTask: function () { - var url = this.getQueryInput().query.url; - var findParams = this.getFindParams(); - var findTask = new FindTask(url); - findTask.execute(findParams, lang.hitch(this, this.showResults)); - }, - getQueryInput: function () { - return { - query: this.queries[this.queryIdx] || {}, - searchText: this.searchTextDijit.get('value') - }; - }, - queryConfigurationIsInvalid: function () { - var query = this.getQueryInput().query; - if (!query.url || !query.searchFields || !query.layerIds) { - return true; - } - return false; - }, - userInputIsInvalid: function () { - var userInput = this.getQueryInput().searchText; - if (userInput.length === 0 || this.userInputLessThanMinLength()) { - return true; - } - return false; - }, - userInputLessThanMinLength: function () { - var queryInput = this.getQueryInput(); - if (queryInput.query.minChars && (queryInput.searchText.length < queryInput.query.minChars)) { - return true; - } - return false; - }, - displayInvalidQueryConfigurationMessage: function () { - this.displayFindMessage('There is a problem with the query configuration.'); + ) + ); + }, + initializeQueries: function () { + var k = 0, + queryLen = this.queries.length; + for (k = 0; k < queryLen; k++) { + this.queries[k].id = k; + } + this.querySelectDom.style.display = 'none'; + if (queryLen > 1) { + var queryStore = new Memory({ + data: this.queries + }); + this.querySelectDijit.set('store', queryStore); + this.querySelectDijit.set('value', this.queryIdx); + this.querySelectDom.style.display = 'block'; + } + }, + search: function () { + if (this.userInputIsInvalid()) { + this.displayInvalidUserInputMessage(); return; - }, - displayInvalidUserInputMessage: function () { - var minChars = this.getQueryInput().query.minChars; - this.displayFindMessage('You must enter at least ' + minChars + ' characters.'); + } + if (this.queryConfigurationIsInvalid()) { + this.displayInvalidQueryConfigurationMessage(); return; - }, - displayFindMessage: function (message) { - domConstruct.empty(this.findResultsNode); - this.findResultsNode.innerHTML = message; - this.findResultsNode.style.display = 'block'; - }, - getFindParams: function () { - var queryInput = this.getQueryInput(); - var findParams = new FindParameters(); - findParams.returnGeometry = true; - findParams.layerIds = queryInput.query.layerIds; - findParams.searchFields = queryInput.query.searchFields; - findParams.layerDefinitions = queryInput.query.layerDefs; - findParams.searchText = queryInput.searchText; - findParams.contains = !this.containsSearchText.checked; - findParams.outSpatialReference = { - wkid: this.spatialReference - }; - return findParams; - }, - createOrResetResultsGrid: function () { - if (!this.resultsGrid) { - this.createResultsStore(); - this.createResultsGrid(); - this.attachStandardEventHandlersToResultsGrid(); - } - this.clearResultsGrid(); - this.clearFeatures(); - this.resetResultsGridColumns(); - this.resetResultsGridSort(); - this.resetGridSelectionMode(); - this.attachCustomEventHandlersToResultsGrid(); - }, - createResultsStore: function () { - if (!this.resultsStore) { - this.resultsStore = new Memory({ - idProperty: 'id', - data: [] - }); - } - }, - createResultsGrid: function () { - var Grid = declare([OnDemandGrid, Keyboard, Selection, ColumnResizer]); - this.resultsGrid = new Grid({ - selectionMode: this.selectionMode, - cellNavigation: false, - showHeader: true, - store: this.resultsStore - }, this.findResultsGrid); - this.resultsGrid.startup(); - }, - resetResultsGridColumns: function () { - if (!this.resultsGrid) { - return; - } - var columns = this.queries[this.queryIdx].gridColumns || { - layerName: 'Layer', - foundFieldName: 'Field', - value: 'Result' - }; - if (columns instanceof Array) { - columns = array.filter( - columns, function (column) { - if (typeof column.visible === 'undefined') { - column.visible = true; - } - return column.visible; - } - ); - } - this.resultsGrid.setColumns(columns); - }, - resetResultsGridSort: function () { - if (!this.resultsGrid) { - return; - } - var sort = this.queries[this.queryIdx].sort || [ - { - attribute: 'value', - descending: false - } - ]; - this.resultsGrid.set('sort', sort); - }, - resetGridSelectionMode: function () { - if (!this.resultsGrid) { - return; - } - var selectionMode = this.queries[this.queryIdx].selectionMode || this.selectionMode; - this.resultsGrid.set('selectionMode', selectionMode); - }, - attachStandardEventHandlersToResultsGrid: function () { - if (!this.resultsGrid) { - return; - } - this.own( - this.resultsGrid.on('dgrid-select', lang.hitch(this, 'onResultsGridSelect')) - ); - this.own( - this.resultsGrid.on('dgrid-deselect', lang.hitch(this, 'onResultsGridDeselect')) - ); - this.own( - this.resultsGrid.on('.dgrid-row:dblclick', lang.hitch(this, 'onResultsGridRowClick')) - ); - }, - attachCustomEventHandlersToResultsGrid: function () { - if (!this.resultsGrid) { - return; - } - array.forEach(this.currentQueryEventHandlers, function (handler) { - handler.handle.remove(); - }); - var queryEventHandlers = this.queries[this.queryIdx].customGridEventHandlers || []; - array.forEach(queryEventHandlers, lang.hitch(this, function (handler) { - handler.handle = this.resultsGrid.on(handler.event, lang.hitch(this, handler.handler)); - })); - this.currentQueryEventHandlers = queryEventHandlers; - }, - showResults: function (results) { - var resultText = this.i18n.noResultsLabel; - this.results = results; - if (this.results.length > 0) { - var s = (this.results.length === 1) ? '' : this.i18n.resultsLabel.multipleResultsSuffix; - resultText = this.results.length + ' ' + this.i18n.resultsLabel.labelPrefix + s + ' ' + this.i18n.resultsLabel.labelSuffix; - this.createGraphicsLayerAndSymbols(); - this.parseGridColumnProperties(); - this.addResultsToGraphicsLayer(); - this.zoomToGraphics(this.graphicsLayer.graphics); - this.showResultsGrid(); - } - this.displayFindMessage(resultText); - }, - createGraphicsLayerAndSymbols: function () { - if (!this.graphicsLayer) { - this.graphicsLayer = this.createGraphicsLayer(); - } - if (!this.graphicsSymbols) { - this.graphicsSymbols = this.createGraphicsSymbols(); - } - }, - createGraphicsLayer: function () { - var graphicsLayer = new GraphicsLayer({ - id: this.id + '_findGraphics', - title: 'Find' + } + this.createOrResetResultsGrid(); + this.displayFindMessage(this.i18n.searching); + this.executeFindTask(); + }, + executeFindTask: function () { + var url = this.getQueryInput().query.url; + var findParams = this.getFindParams(); + var findTask = new FindTask(url); + findTask.execute(findParams, lang.hitch(this, this.showResults)); + }, + getQueryInput: function () { + return { + query: this.queries[this.queryIdx] || {}, + searchText: this.searchTextDijit.get('value') + }; + }, + queryConfigurationIsInvalid: function () { + var query = this.getQueryInput().query; + if (!query.url || !query.searchFields || !query.layerIds) { + return true; + } + return false; + }, + userInputIsInvalid: function () { + var userInput = this.getQueryInput().searchText; + if (userInput.length === 0 || this.userInputLessThanMinLength()) { + return true; + } + return false; + }, + userInputLessThanMinLength: function () { + var queryInput = this.getQueryInput(); + if (queryInput.query.minChars && (queryInput.searchText.length < queryInput.query.minChars)) { + return true; + } + return false; + }, + displayInvalidQueryConfigurationMessage: function () { + this.displayFindMessage('There is a problem with the query configuration.'); + return; + }, + displayInvalidUserInputMessage: function () { + var minChars = this.getQueryInput().query.minChars; + this.displayFindMessage('You must enter at least ' + minChars + ' characters.'); + return; + }, + displayFindMessage: function (message) { + domConstruct.empty(this.findResultsNode); + this.findResultsNode.innerHTML = message; + this.findResultsNode.style.display = 'block'; + }, + getFindParams: function () { + var queryInput = this.getQueryInput(); + var findParams = new FindParameters(); + findParams.returnGeometry = true; + findParams.layerIds = queryInput.query.layerIds; + findParams.searchFields = queryInput.query.searchFields; + findParams.layerDefinitions = queryInput.query.layerDefs; + findParams.searchText = queryInput.searchText; + findParams.contains = !this.containsSearchText.checked; + findParams.outSpatialReference = { + wkid: this.spatialReference + }; + return findParams; + }, + createOrResetResultsGrid: function () { + if (!this.resultsGrid) { + this.createResultsStore(); + this.createResultsGrid(); + this.attachStandardEventHandlersToResultsGrid(); + } + this.clearResultsGrid(); + this.clearFeatures(); + this.resetResultsGridColumns(); + this.resetResultsGridSort(); + this.resetGridSelectionMode(); + this.attachCustomEventHandlersToResultsGrid(); + }, + createResultsStore: function () { + if (!this.resultsStore) { + this.resultsStore = new Memory({ + idProperty: 'id', + data: [] }); - graphicsLayer.on('click', lang.hitch(this, 'onGraphicsLayerClick')); - this.map.addLayer(graphicsLayer); - return graphicsLayer; - }, - onGraphicsLayerClick: function (event) { - var zoomOnSelect = this.zoomOptions.select; - this.zoomOptions.select = false; - var row = this.resultsGrid.row(event.graphic.storeid); - this.resultsGrid.select(row); - this.resultsGrid.focus(row.element); - row.element.focus(); - this.zoomOptions.select = zoomOnSelect; - }, - createGraphicsSymbols: function () { - var graphicSymbols = {}, resultSymbolDefinitions, selectionSymbolDefinitions; - resultSymbolDefinitions = lang.mixin(this.defaultResultsSymbols, this.resultsSymbols || {}); - graphicSymbols.resultsSymbols = {}; - graphicSymbols.resultsSymbols.point = symbolUtils.fromJson(resultSymbolDefinitions.point); - graphicSymbols.resultsSymbols.polyline = symbolUtils.fromJson(resultSymbolDefinitions.polyline); - graphicSymbols.resultsSymbols.polygon = symbolUtils.fromJson(resultSymbolDefinitions.polygon); - selectionSymbolDefinitions = lang.mixin( - this.defaultSelectionSymbols, this.selectionSymbols || {} + } + }, + createResultsGrid: function () { + var Grid = declare([OnDemandGrid, Keyboard, Selection, ColumnResizer]); + this.resultsGrid = new Grid({ + selectionMode: this.selectionMode, + cellNavigation: false, + showHeader: true, + store: this.resultsStore + }, this.findResultsGrid); + this.resultsGrid.startup(); + }, + resetResultsGridColumns: function () { + if (!this.resultsGrid) { + return; + } + var columns = this.queries[this.queryIdx].gridColumns || { + layerName: 'Layer', + foundFieldName: 'Field', + value: 'Result' + }; + if (columns instanceof Array) { + columns = array.filter( + columns, function (column) { + if (typeof column.visible === 'undefined') { + column.visible = true; + } + return column.visible; + } ); - graphicSymbols.selectionSymbols = {}; - graphicSymbols.selectionSymbols.point = symbolUtils.fromJson(selectionSymbolDefinitions.point); - graphicSymbols.selectionSymbols.polyline = symbolUtils.fromJson(selectionSymbolDefinitions.polyline); - graphicSymbols.selectionSymbols.polygon = symbolUtils.fromJson(selectionSymbolDefinitions.polygon); - return graphicSymbols; - }, - parseGridColumnProperties: function () { - if (this.queries[this.queryIdx].gridColumns) { - array.forEach( - this.results, function (result) { - array.forEach( - this.queries[this.queryIdx].gridColumns, function (column) { - var shouldGetValueFromAttributes = function (column, result) { - if (column.field && !result.hasOwnProperty(column.field) && result.feature.attributes.hasOwnProperty(column.field)) { - return true; - } - return false; - }; - var shouldGetValueFromGetFunction = function (column, result) { - if (column.field && !result.hasOwnProperty(column.field) && column.get) { - return true; - } - return false; - }; - if (shouldGetValueFromAttributes(column, this)) { - this[column.field] = this.feature.attributes[column.field]; - } else if (shouldGetValueFromGetFunction(column, this)) { - this[column.field] = column.get(this); - } - }, result - ); - }, this - ); - } - }, - addResultsToGraphicsLayer: function () { - var unique = 0; + } + this.resultsGrid.setColumns(columns); + }, + resetResultsGridSort: function () { + if (!this.resultsGrid) { + return; + } + var sort = this.queries[this.queryIdx].sort || [ + { + attribute: 'value', + descending: false + } + ]; + this.resultsGrid.set('sort', sort); + }, + resetGridSelectionMode: function () { + if (!this.resultsGrid) { + return; + } + var selectionMode = this.queries[this.queryIdx].selectionMode || this.selectionMode; + this.resultsGrid.set('selectionMode', selectionMode); + }, + attachStandardEventHandlersToResultsGrid: function () { + if (!this.resultsGrid) { + return; + } + this.own( + this.resultsGrid.on('dgrid-select', lang.hitch(this, 'onResultsGridSelect')) + ); + this.own( + this.resultsGrid.on('dgrid-deselect', lang.hitch(this, 'onResultsGridDeselect')) + ); + this.own( + this.resultsGrid.on('.dgrid-row:dblclick', lang.hitch(this, 'onResultsGridRowClick')) + ); + }, + attachCustomEventHandlersToResultsGrid: function () { + if (!this.resultsGrid) { + return; + } + array.forEach(this.currentQueryEventHandlers, function (handler) { + handler.handle.remove(); + }); + var queryEventHandlers = this.queries[this.queryIdx].customGridEventHandlers || []; + array.forEach(queryEventHandlers, lang.hitch(this, function (handler) { + handler.handle = this.resultsGrid.on(handler.event, lang.hitch(this, handler.handler)); + })); + this.currentQueryEventHandlers = queryEventHandlers; + }, + showResults: function (results) { + var resultText = this.i18n.noResultsLabel; + this.results = results; + if (this.results.length > 0) { + var s = (this.results.length === 1) ? '' : this.i18n.resultsLabel.multipleResultsSuffix; + resultText = this.results.length + ' ' + this.i18n.resultsLabel.labelPrefix + s + ' ' + this.i18n.resultsLabel.labelSuffix; + this.createGraphicsLayerAndSymbols(); + this.parseGridColumnProperties(); + this.addResultsToGraphicsLayer(); + this.zoomToGraphics(this.graphicsLayer.graphics); + this.showResultsGrid(); + } + this.displayFindMessage(resultText); + }, + createGraphicsLayerAndSymbols: function () { + if (!this.graphicsLayer) { + this.graphicsLayer = this.createGraphicsLayer(); + } + if (!this.graphicsSymbols) { + this.graphicsSymbols = this.createGraphicsSymbols(); + } + }, + createGraphicsLayer: function () { + var graphicsLayer = new GraphicsLayer({ + id: this.id + '_findGraphics', + title: 'Find' + }); + graphicsLayer.on('click', lang.hitch(this, 'onGraphicsLayerClick')); + this.map.addLayer(graphicsLayer); + return graphicsLayer; + }, + onGraphicsLayerClick: function (event) { + var zoomOnSelect = this.zoomOptions.select; + this.zoomOptions.select = false; + var row = this.resultsGrid.row(event.graphic.storeid); + this.resultsGrid.select(row); + this.resultsGrid.focus(row.element); + row.element.focus(); + this.zoomOptions.select = zoomOnSelect; + }, + createGraphicsSymbols: function () { + var graphicSymbols = {}, resultSymbolDefinitions, selectionSymbolDefinitions; + resultSymbolDefinitions = lang.mixin(this.defaultResultsSymbols, this.resultsSymbols || {}); + graphicSymbols.resultsSymbols = {}; + graphicSymbols.resultsSymbols.point = symbolUtils.fromJson(resultSymbolDefinitions.point); + graphicSymbols.resultsSymbols.polyline = symbolUtils.fromJson(resultSymbolDefinitions.polyline); + graphicSymbols.resultsSymbols.polygon = symbolUtils.fromJson(resultSymbolDefinitions.polygon); + selectionSymbolDefinitions = lang.mixin( + this.defaultSelectionSymbols, this.selectionSymbols || {} + ); + graphicSymbols.selectionSymbols = {}; + graphicSymbols.selectionSymbols.point = symbolUtils.fromJson(selectionSymbolDefinitions.point); + graphicSymbols.selectionSymbols.polyline = symbolUtils.fromJson(selectionSymbolDefinitions.polyline); + graphicSymbols.selectionSymbols.polygon = symbolUtils.fromJson(selectionSymbolDefinitions.polygon); + return graphicSymbols; + }, + parseGridColumnProperties: function () { + if (this.queries[this.queryIdx].gridColumns) { array.forEach( this.results, function (result) { - result.id = unique; - result.feature.storeid = result.id; - unique++; - this.setGraphicSymbol(result.feature, false); - this.graphicsLayer.add(result.feature); + array.forEach( + this.queries[this.queryIdx].gridColumns, function (column) { + function shouldGetValueFromAttributes (col, res) { + if (col.field && !result.hasOwnProperty(col.field) && res.feature.attributes.hasOwnProperty(col.field)) { + return true; + } + return false; + } + + function shouldGetValueFromGetFunction (col, res) { + if (col.field && !res.hasOwnProperty(col.field) && col.get) { + return true; + } + return false; + } + + if (shouldGetValueFromAttributes(column, this)) { + this[column.field] = this.feature.attributes[column.field]; + } else if (shouldGetValueFromGetFunction (column, this)) { + this[column.field] = column.get(this); + } + }, result + ); }, this ); - }, - showResultsGrid: function () { - var queryInput = this.getQueryInput(); - this.resultsGrid.store.setData(this.results); - this.resultsGrid.refresh(); - var lyrDisplay = 'block'; - if (queryInput.query.layerIds.length === 1) { - lyrDisplay = 'none'; - } - this.resultsGrid.styleColumn('layerName', 'display:' + lyrDisplay); - if (queryInput.query && queryInput.query.hideGrid !== true) { - this.findResultsGrid.style.display = 'block'; - } - }, - onResultsGridSelect: function (event) { - array.forEach( - event.rows, lang.hitch( - this, function (row) { - var feature = row.data.feature; - this.setGraphicSymbol(feature, true); - if (feature && feature.getDojoShape()) { - feature.getDojoShape().moveToFront(); - } - } - ) - ); - this.graphicsLayer.redraw(); - if (this.zoomOptions.select) { - this.zoomToSelectedGraphics(); - } - }, - onResultsGridDeselect: function (event) { - array.forEach( - event.rows, lang.hitch( - this, function (row) { - var feature = row.data.feature; - this.setGraphicSymbol(feature, false); + } + }, + addResultsToGraphicsLayer: function () { + var unique = 0; + array.forEach( + this.results, function (result) { + result.id = unique; + result.feature.storeid = result.id; + unique++; + this.setGraphicSymbol(result.feature, false); + this.graphicsLayer.add(result.feature); + }, this + ); + }, + showResultsGrid: function () { + var queryInput = this.getQueryInput(); + this.resultsGrid.store.setData(this.results); + this.resultsGrid.refresh(); + var lyrDisplay = 'block'; + if (queryInput.query.layerIds.length === 1) { + lyrDisplay = 'none'; + } + this.resultsGrid.styleColumn('layerName', 'display:' + lyrDisplay); + if (queryInput.query && queryInput.query.hideGrid !== true) { + this.findResultsGrid.style.display = 'block'; + } + }, + onResultsGridSelect: function (event) { + array.forEach( + event.rows, lang.hitch( + this, function (row) { + var feature = row.data.feature; + this.setGraphicSymbol(feature, true); + if (feature && feature.getDojoShape()) { + feature.getDojoShape().moveToFront(); } - ) - ); - this.graphicsLayer.redraw(); - if (this.zoomOptions.deselect) { - this.zoomToSelectedGraphics(); - } - }, - onResultsGridRowClick: function (event) { - var row = this.resultsGrid.row(event); - var feature = row.data.feature; - setTimeout(lang.hitch(this, function () { - if (this.resultsGrid.selection.hasOwnProperty(row.id)) { - this.zoomToGraphics([feature]); } - }), 100); - }, - setGraphicSymbol: function (graphic, isSelected) { - var symbol = isSelected ? this.graphicsSymbols.selectionSymbols[graphic.geometry.type] : this.graphicsSymbols.resultsSymbols[graphic.geometry.type]; - graphic.setSymbol(symbol); - }, - zoomToSelectedGraphics: function () { - var selectedGraphics = []; - var selection = this.resultsGrid.selection; - for (var id in selection) { - if (selection.hasOwnProperty(id)) { - selectedGraphics.push(this.resultsGrid.row(id).data.feature); - } - } - if (selectedGraphics.length === 0) { - return; - } - this.zoomToGraphics(selectedGraphics); - }, - zoomToGraphics: function (graphics) { - var zoomExtent = null; - if (graphics.length > 1) { - zoomExtent = graphicsUtils.graphicsExtent(graphics); - } else if (graphics.length === 1) { - zoomExtent = this.getExtentFromGraphic(graphics[0]); - } - if (zoomExtent) { - this.setMapExtent(zoomExtent); - } - }, - getExtentFromGraphic: function (graphic) { - var extent = null; - switch (graphic.geometry.type) { - case 'point': - extent = this.getExtentFromPoint(graphic); - break; - default: - extent = graphicsUtils.graphicsExtent([graphic]); - break; - } - return extent; - }, - getExtentFromPoint: function (point) { - var sz = this.pointExtentSize; // hack - var pointGeometry = point.geometry; - return new Extent({ - 'xmin': pointGeometry.x - sz, - 'ymin': pointGeometry.y - sz, - 'xmax': pointGeometry.x + sz, - 'ymax': pointGeometry.y + sz, - 'spatialReference': { - wkid: this.spatialReference + ) + ); + this.graphicsLayer.redraw(); + if (this.zoomOptions.select) { + this.zoomToSelectedGraphics(); + } + }, + onResultsGridDeselect: function (event) { + array.forEach( + event.rows, lang.hitch( + this, function (row) { + var feature = row.data.feature; + this.setGraphicSymbol(feature, false); } - }); - }, - setMapExtent: function (extent) { - this.map.setExtent(extent.expand(this.zoomExtentFactor)); - }, - clearResults: function () { - this.results = null; - this.clearResultsGrid(); - this.clearFeatures(); - this.searchFormDijit.reset(); - this.querySelectDijit.setValue(this.queryIdx); - domConstruct.empty(this.findResultsNode); - }, - clearResultsGrid: function () { - if (this.resultStore) { - this.resultsStore.setData([]); - } - if (this.resultsGrid) { - this.resultsGrid.refresh(); - } - this.findResultsNode.style.display = 'none'; - this.findResultsGrid.style.display = 'none'; - }, - clearFeatures: function () { - if (this.graphicsLayer) { - this.graphicsLayer.clear(); + ) + ); + this.graphicsLayer.redraw(); + if (this.zoomOptions.deselect) { + this.zoomToSelectedGraphics(); + } + }, + onResultsGridRowClick: function (event) { + var row = this.resultsGrid.row(event); + var feature = row.data.feature; + setTimeout(lang.hitch(this, function () { + if (this.resultsGrid.selection.hasOwnProperty(row.id)) { + this.zoomToGraphics([feature]); + } + }), 100); + }, + setGraphicSymbol: function (graphic, isSelected) { + var symbol = isSelected ? this.graphicsSymbols.selectionSymbols[graphic.geometry.type] : this.graphicsSymbols.resultsSymbols[graphic.geometry.type]; + graphic.setSymbol(symbol); + }, + zoomToSelectedGraphics: function () { + var selectedGraphics = []; + var selection = this.resultsGrid.selection; + for (var id in selection) { + if (selection.hasOwnProperty(id)) { + selectedGraphics.push(this.resultsGrid.row(id).data.feature); } - }, - _onQueryChange: function (queryIdx) { - if (queryIdx >= 0 && queryIdx < this.queries.length) { - this.queryIdx = queryIdx; - this.updateSearchPrompt(); + } + if (selectedGraphics.length === 0) { + return; + } + this.zoomToGraphics(selectedGraphics); + }, + zoomToGraphics: function (graphics) { + var zoomExtent = null; + if (graphics.length > 1) { + zoomExtent = graphicsUtils.graphicsExtent(graphics); + } else if (graphics.length === 1) { + zoomExtent = this.getExtentFromGraphic(graphics[0]); + } + if (zoomExtent) { + this.setMapExtent(zoomExtent); + } + }, + getExtentFromGraphic: function (graphic) { + var extent = null; + switch (graphic.geometry.type) { + case 'point': + extent = this.getExtentFromPoint(graphic); + break; + default: + extent = graphicsUtils.graphicsExtent([graphic]); + break; + } + return extent; + }, + getExtentFromPoint: function (point) { + var sz = this.pointExtentSize; // hack + var pointGeometry = point.geometry; + return new Extent({ + 'xmin': pointGeometry.x - sz, + 'ymin': pointGeometry.y - sz, + 'xmax': pointGeometry.x + sz, + 'ymax': pointGeometry.y + sz, + 'spatialReference': { + wkid: this.spatialReference } - }, - updateSearchPrompt: function () { - var prompt = this.queries[this.queryIdx].prompt || i18n.searchText.placeholder; - this.searchTextDijit.set('placeholder', prompt); - this.searchTextDijit.set('value', null); - }, - onZoomOptionsSelectChange: function (value) { - this.zoomOptions.select = value; - }, - onZoomOptionsDeselectChange: function (value) { - this.zoomOptions.deselect = value; + }); + }, + setMapExtent: function (extent) { + this.map.setExtent(extent.expand(this.zoomExtentFactor)); + }, + clearResults: function () { + this.results = null; + this.clearResultsGrid(); + this.clearFeatures(); + this.searchFormDijit.reset(); + this.querySelectDijit.setValue(this.queryIdx); + domConstruct.empty(this.findResultsNode); + }, + clearResultsGrid: function () { + if (this.resultStore) { + this.resultsStore.setData([]); + } + if (this.resultsGrid) { + this.resultsGrid.refresh(); + } + this.findResultsNode.style.display = 'none'; + this.findResultsGrid.style.display = 'none'; + }, + clearFeatures: function () { + if (this.graphicsLayer) { + this.graphicsLayer.clear(); + } + }, + _onQueryChange: function (queryIdx) { + if (queryIdx >= 0 && queryIdx < this.queries.length) { + this.queryIdx = queryIdx; + this.updateSearchPrompt(); } + }, + updateSearchPrompt: function () { + var prompt = this.queries[this.queryIdx].prompt || i18n.searchText.placeholder; + this.searchTextDijit.set('placeholder', prompt); + this.searchTextDijit.set('value', null); + }, + onZoomOptionsSelectChange: function (value) { + this.zoomOptions.select = value; + }, + onZoomOptionsDeselectChange: function (value) { + this.zoomOptions.deselect = value; } - ); - } -); \ No newline at end of file + } + ); +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Find/nls/resource.js b/viewer/js/gis/dijit/Find/nls/resource.js index 395533c06..0d5c82f74 100644 --- a/viewer/js/gis/dijit/Find/nls/resource.js +++ b/viewer/js/gis/dijit/Find/nls/resource.js @@ -1,29 +1,29 @@ // http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ - root: { - selectQuery: 'Select query', - searchText: { - label: 'Search for', - placeholder: 'Enter the text you want to search for.' - }, - exactMatches: 'Find exact matches only', - searchButton: { - label: 'Search', - busyLabel: 'searching' - }, - clearButton: { - label: 'Clear' - }, - searching: 'Searching...', - resultsLabel: { - multipleResultsSuffix: 's', - labelPrefix: 'Result', - labelSuffix: 'found' - }, - noResultsLabel: 'No results found.', - optionsLabel: 'Options', - zoomOnSelect: 'Zoom on select', - zoomOnDeselect: 'Zoom on deselect' - } + root: { + selectQuery: 'Select query', + searchText: { + label: 'Search for', + placeholder: 'Enter the text you want to search for.' + }, + exactMatches: 'Find exact matches only', + searchButton: { + label: 'Search', + busyLabel: 'searching' + }, + clearButton: { + label: 'Clear' + }, + searching: 'Searching...', + resultsLabel: { + multipleResultsSuffix: 's', + labelPrefix: 'Result', + labelSuffix: 'found' + }, + noResultsLabel: 'No results found.', + optionsLabel: 'Options', + zoomOnSelect: 'Zoom on select', + zoomOnDeselect: 'Zoom on deselect' + } }); diff --git a/viewer/js/gis/dijit/FloatingTitlePane.js b/viewer/js/gis/dijit/FloatingTitlePane.js index 6963190bb..414d1241a 100644 --- a/viewer/js/gis/dijit/FloatingTitlePane.js +++ b/viewer/js/gis/dijit/FloatingTitlePane.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/TitlePane', @@ -15,6 +16,7 @@ define([ 'dojo/dom-class', 'xstyle/css!./FloatingTitlePane/css/FloatingTitlePane.css' ], function (declare, TitlePane, on, lang, Moveable, aspect, topic, win, winUtils, domGeom, domStyle, domConstruct, domAttr, domClass) { + return declare([TitlePane], { sidebarPosition: null, postCreate: function () { @@ -35,7 +37,7 @@ define([ aspect.after(this._moveable, 'onMove', lang.hitch(this, '_dragging'), true); aspect.after(this._moveable, 'onMoveStop', lang.hitch(this, '_endDrag'), true); aspect.after(this._moveable, 'onMoveStart', lang.hitch(this, '_startDrag'), true); - + // ensure that dragging the movable stops no matter // when/where the mouse is released or a touch is completed on(document, 'mouseup, touchend', lang.hitch(this, '_endDrag')); diff --git a/viewer/js/gis/dijit/FloatingWidgetDialog.js b/viewer/js/gis/dijit/FloatingWidgetDialog.js index 7979e76d4..87e781c04 100644 --- a/viewer/js/gis/dijit/FloatingWidgetDialog.js +++ b/viewer/js/gis/dijit/FloatingWidgetDialog.js @@ -1,15 +1,17 @@ define([ - 'dojo/_base/declare', - 'dijit/Dialog' + 'dojo/_base/declare', + 'dijit/Dialog' ], function (declare, Dialog) { - return declare([Dialog], { - declaredClass: 'gis.dijit.FloatingWidget', - title: 'Floating Widget', - draggable: true, - 'class': 'floatingWidget', - close: function () { - this.hide(); - }, - focus: function () {} - }); + 'use strict'; + + return declare([Dialog], { + declaredClass: 'gis.dijit.FloatingWidget', + title: 'Floating Widget', + draggable: true, + 'class': 'floatingWidget', + close: function () { + this.hide(); + }, + focus: function () {} + }); }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Geocoder.js b/viewer/js/gis/dijit/Geocoder.js index 694b18d7d..fcdd1e29c 100644 --- a/viewer/js/gis/dijit/Geocoder.js +++ b/viewer/js/gis/dijit/Geocoder.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ // adapted from https://github.com/esri/arcgis-dijit-geocoder-button-js/ define([ 'dojo/_base/declare', @@ -19,6 +20,7 @@ define([ 'xstyle/css!./Geocoder/css/Geocoder.css' ], function (declare, _WidgetBase, _TemplatedMixin, a11yclick, lang, on, domClass, domStyle, Geocoder, MenuItem, SimpleMarkerSymbol, Graphic, InfoTemplate, GraphicsLayer, template, i18n) { + return declare([_WidgetBase, _TemplatedMixin], { templateString: template, i18n: i18n, diff --git a/viewer/js/gis/dijit/Growler.js b/viewer/js/gis/dijit/Growler.js index 732342808..89ac59df0 100644 --- a/viewer/js/gis/dijit/Growler.js +++ b/viewer/js/gis/dijit/Growler.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', @@ -11,23 +12,6 @@ define([ 'xstyle/css!./Growler/css/Growler.css' ], function (declare, _WidgetBase, _TemplatedMixin, lang, Style, domConstruct, fx, domClass, topic) { - // main growler dijit container - var Growler = declare([_WidgetBase, _TemplatedMixin], { - templateString: '

', - postCreate: function () { - this.inherited(arguments); - this.own(topic.subscribe('growler/growl', lang.hitch(this, 'growl'))); - }, - growl: function (props) { - props = props || {}; - lang.mixin(props, { - _container: this.containerNode - }); - var g = new Growl(props); - g.startup(); - } - }); - // the growl itself var Growl = declare([_WidgetBase, _TemplatedMixin], { templateString: '

${title}

', @@ -82,5 +66,23 @@ define([ }, 250, null, lang.partial(domConstruct.destroy, this.domNode)); } }); + + // main growler dijit container + var Growler = declare([_WidgetBase, _TemplatedMixin], { + templateString: '
', + postCreate: function () { + this.inherited(arguments); + this.own(topic.subscribe('growler/growl', lang.hitch(this, 'growl'))); + }, + growl: function (props) { + props = props || {}; + lang.mixin(props, { + _container: this.containerNode + }); + var g = new Growl(props); + g.startup(); + } + }); + return Growler; }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Help.js b/viewer/js/gis/dijit/Help.js index 2e605fecc..1c0d8fa0a 100644 --- a/viewer/js/gis/dijit/Help.js +++ b/viewer/js/gis/dijit/Help.js @@ -1,5 +1,6 @@ +/*eslint strict: 0*/ define([ - 'dojo/_base/declare', + 'dojo/_base/declare', 'dijit/_WidgetBase', 'dijit/_TemplatedMixin', 'dijit/_WidgetsInTemplateMixin', @@ -8,45 +9,45 @@ define([ 'dojo/on', 'dojo/_base/lang', 'dojo/aspect', - 'dojo/text!./Help/templates/HelpDialog.html', + 'dojo/text!./Help/templates/HelpDialog.html', 'dijit/form/Button', - 'dijit/layout/TabContainer', - 'dijit/layout/ContentPane', - 'xstyle/css!./Help/css/Help.css' + 'dijit/layout/TabContainer', + 'dijit/layout/ContentPane', + 'xstyle/css!./Help/css/Help.css' ], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, domConstruct, on, lang, aspect, template) { - return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin], { - widgetsInTemplate: true, - templateString: template, - title: 'Help', - html: 'Help', - domTarget: 'helpDijit', - draggable: false, - baseClass: 'helpDijit', - postCreate: function () { - this.inherited(arguments); - this.parentWidget.draggable = this.draggable; - if (this.parentWidget.toggleable) { - this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { - this.containerNode.resize(); - }))); - } else { - var help = domConstruct.place(this.html, this.domTarget); - on(help, 'click', lang.hitch(this.parentWidget, 'show')); - } - }, - onOpen: function () { - // Make sure the content is visible when the dialog - // is shown/opened. Something like this may be needed - // for all floating windows that don't open on startup? - if (!this.openOnStartup) { - this.containerNode.resize(); - } - }, - close: function () { - if (this.parentWidget.hide) { - this.parentWidget.hide(); - } - } - }); + return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin], { + widgetsInTemplate: true, + templateString: template, + title: 'Help', + html: 'Help', + domTarget: 'helpDijit', + draggable: false, + baseClass: 'helpDijit', + postCreate: function () { + this.inherited(arguments); + this.parentWidget.draggable = this.draggable; + if (this.parentWidget.toggleable) { + this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { + this.containerNode.resize(); + }))); + } else { + var help = domConstruct.place(this.html, this.domTarget); + on(help, 'click', lang.hitch(this.parentWidget, 'show')); + } + }, + onOpen: function () { + // Make sure the content is visible when the dialog + // is shown/opened. Something like this may be needed + // for all floating windows that don't open on startup? + if (!this.openOnStartup) { + this.containerNode.resize(); + } + }, + close: function () { + if (this.parentWidget.hide) { + this.parentWidget.hide(); + } + } + }); }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Identify.js b/viewer/js/gis/dijit/Identify.js index 1a7775fd5..103dd6c75 100644 --- a/viewer/js/gis/dijit/Identify.js +++ b/viewer/js/gis/dijit/Identify.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', @@ -23,6 +24,7 @@ define([ 'dijit/form/FilteringSelect', 'xstyle/css!./Identify/css/Identify.css' ], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, MenuItem, lang, array, all, topic, query, domStyle, domClass, Moveable, Memory, IdentifyTask, IdentifyParameters, PopupTemplate, IdentifyTemplate, i18n) { + return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { widgetsInTemplate: true, templateString: IdentifyTemplate, @@ -129,7 +131,7 @@ define([ setupDraggable: function () { var popups, handles, pointers, movable; // the popup, handle (title) and pointers (arrows) - popups = query('div.esriPopup'); + popups = query('div.esriPopup'); handles = query('div.esriPopup div.titlePane div.title'); pointers = query('div.esriPopup div.outerPointer, div.esriPopup div.pointer'); @@ -180,7 +182,7 @@ define([ })); if (identifies.length > 0) { - this.map.infoWindow.setTitle( this.i18n.mapInfoWindow.identifyingTitle ); + this.map.infoWindow.setTitle(this.i18n.mapInfoWindow.identifyingTitle); this.map.infoWindow.setContent('
'); this.map.infoWindow.show(mapPoint); all(identifies).then(lang.hitch(this, 'identifyCallback', identifiedlayers), lang.hitch(this, 'identifyError')); @@ -308,7 +310,7 @@ define([ }, getInfoTemplate: function (layer, layerId, result) { - var popup = null, + var popup = null, content = null; if (result) { layerId = result.layerId; @@ -544,11 +546,9 @@ define([ } // remove any infoTemplates that might // interfere with clicking on a feature - } else { - if (layer.infoTemplate) { - this.infoTemplates[layer.id] = lang.clone(layer.infoTemplate); - layer.infoTemplate = null; - } + } else if (layer.infoTemplate) { + this.infoTemplates[layer.id] = lang.clone(layer.infoTemplate); + layer.infoTemplate = null; } } }, this); diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 7d76297f0..fb951e3e6 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/array', @@ -28,6 +29,7 @@ define([ esriConfig, require ) { + var LayerControl = declare([WidgetBase, Container], { map: null, layerInfos: [], @@ -151,8 +153,8 @@ define([ })); }, // create layer control and add to appropriate _container - _addControl: function (layerInfo, LayerControl) { - var layerControl = new LayerControl({ + _addControl: function (layerInfo, Control) { + var layerControl = new Control({ controller: this, layer: (typeof layerInfo.layer === 'string') ? this.map.getLayer(layerInfo.layer) : layerInfo.layer, // check if we have a layer or just a layer id layerTitle: layerInfo.title, @@ -263,25 +265,23 @@ define([ var map = this.map; if (layer.spatialReference === map.spatialReference) { map.setExtent(layer.fullExtent, true); - } else { - if (esriConfig.defaults.geometryService) { - esriConfig.defaults.geometryService.project(lang.mixin(new ProjectParameters(), { - geometries: [layer.fullExtent], - outSR: map.spatialReference - }), function (r) { - map.setExtent(r[0], true); - }, function (e) { - topic.publish('viewer/handleError', { - source: 'LayerControl._zoomToLayer', - error: e - }); - }); - } else { + } else if (esriConfig.defaults.geometryService) { + esriConfig.defaults.geometryService.project(lang.mixin(new ProjectParameters(), { + geometries: [layer.fullExtent], + outSR: map.spatialReference + }), function (r) { + map.setExtent(r[0], true); + }, function (e) { topic.publish('viewer/handleError', { source: 'LayerControl._zoomToLayer', - error: 'esriConfig.defaults.geometryService is not set' + error: e }); - } + }); + } else { + topic.publish('viewer/handleError', { + source: 'LayerControl._zoomToLayer', + error: 'esriConfig.defaults.geometryService is not set' + }); } }, // layer swiper diff --git a/viewer/js/gis/dijit/LayerControl/controls/CSV.js b/viewer/js/gis/dijit/LayerControl/controls/CSV.js index d5efc3784..cd9687c80 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/CSV.js +++ b/viewer/js/gis/dijit/LayerControl/controls/CSV.js @@ -13,6 +13,8 @@ define([ _Control, legendUtil ) { + 'use strict'; + var CSVControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant _esriLayerType: 'csv', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js index caa52aa16..c872142d7 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js @@ -39,6 +39,8 @@ define([ legendUtil, i18n ) { + 'use strict'; + var DynamicControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant _esriLayerType: 'dynamic', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Feature.js b/viewer/js/gis/dijit/LayerControl/controls/Feature.js index 2da71fec8..6722e36ae 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Feature.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Feature.js @@ -13,6 +13,8 @@ define([ _Control, legendUtil ) { + 'use strict'; + var FeatureControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant _esriLayerType: 'feature', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js b/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js index c149b7411..119d18aaa 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js +++ b/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js @@ -11,6 +11,8 @@ define([ _Contained, _Control ) { + 'use strict'; + var GeoRSSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant _esriLayerType: 'georss', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Image.js b/viewer/js/gis/dijit/LayerControl/controls/Image.js index 6d0f1c597..d7b2253a1 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Image.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Image.js @@ -13,6 +13,8 @@ define([ _Control, legendUtil ) { + 'use strict'; + var ImageControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant _esriLayerType: 'image', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js b/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js index add67e581..decdb0aca 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js +++ b/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js @@ -13,6 +13,8 @@ define([ _Control, legendUtil ) { + 'use strict'; + var ImageVectorControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant _esriLayerType: 'imagevector', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/KML.js b/viewer/js/gis/dijit/LayerControl/controls/KML.js index 21a32944d..f7fd04c7d 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/KML.js +++ b/viewer/js/gis/dijit/LayerControl/controls/KML.js @@ -13,6 +13,8 @@ define([ _Control, legendUtil ) { + 'use strict'; + var KMLControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant _esriLayerType: 'kml', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Raster.js b/viewer/js/gis/dijit/LayerControl/controls/Raster.js index c31195189..2dfb5e508 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Raster.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Raster.js @@ -11,6 +11,8 @@ define([ _Contained, _Control ) { + 'use strict'; + var RasterControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant _esriLayerType: 'raster', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Stream.js b/viewer/js/gis/dijit/LayerControl/controls/Stream.js index 3f711d3d2..e77b88d92 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Stream.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Stream.js @@ -13,6 +13,8 @@ define([ _Control, legendUtil ) { + 'use strict'; + var StreamControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant _esriLayerType: 'raster', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Tiled.js b/viewer/js/gis/dijit/LayerControl/controls/Tiled.js index 4e57b229b..f1cd9106a 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Tiled.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Tiled.js @@ -13,6 +13,8 @@ define([ _Control, legendUtil ) { + 'use strict'; + var TiledControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant _esriLayerType: 'tiled', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/WMS.js b/viewer/js/gis/dijit/LayerControl/controls/WMS.js index 443e13232..db7ff9949 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/WMS.js +++ b/viewer/js/gis/dijit/LayerControl/controls/WMS.js @@ -11,6 +11,8 @@ define([ _Contained, _Control ) { + 'use strict'; + var WMSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant _esriLayerType: 'wms', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js b/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js index 7393cd952..f29e56a3b 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js +++ b/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js @@ -11,6 +11,8 @@ define([ _Contained, _Control ) { + 'use strict'; + var WebTiledControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant _esriLayerType: 'webtiled', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/_Control.js b/viewer/js/gis/dijit/LayerControl/controls/_Control.js index 4e39f478a..b716ffa5a 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_Control.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_Control.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/lang', diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js index ffca235af..2631e34ba 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/lang', @@ -25,7 +26,7 @@ define([ TemplatedMixin, folderTemplate ) { - var _DynamicFolder = declare([WidgetBase, TemplatedMixin], { + var _DynamicFolder = declare([WidgetBase, TemplatedMixin], { control: null, sublayerInfo: null, icons: null, diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js index 159427057..cbe35b987 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/lang', @@ -16,23 +17,23 @@ define([ 'dojo/text!./templates/Sublayer.html', 'dojo/i18n!./../nls/resource' ], function ( - declare, - lang, - array, - on, - domClass, - domStyle, - domAttr, - fx, - html, - Menu, - MenuItem, - topic, - WidgetBase, - TemplatedMixin, - sublayerTemplate, - i18n - ) { + declare, + lang, + array, + on, + domClass, + domStyle, + domAttr, + fx, + html, + Menu, + MenuItem, + topic, + WidgetBase, + TemplatedMixin, + sublayerTemplate, + i18n +) { var _DynamicSublayer = declare([WidgetBase, TemplatedMixin], { control: null, sublayerInfo: null, @@ -70,7 +71,7 @@ define([ } //set up menu if (this.control.controlOptions.menu && - this.control.controlOptions.menu.length) { + this.control.controlOptions.menu.length) { domClass.add(this.labelNode, 'menuLink'); domClass.add(this.iconNode, 'menuLink'); this.menu = new Menu({ @@ -84,15 +85,15 @@ define([ }, _addMenuItem: function (menuItem) { //create the menu item - var item = new MenuItem(menuItem); + var item = new MenuItem(menuItem); item.set('onClick', lang.hitch(this, function () { - topic.publish('LayerControl/' + menuItem.topic, { - layer: this.control.layer, - subLayer: this.sublayerInfo, - iconNode: this.iconNode, - menuItem: item - }); - })); + topic.publish('LayerControl/' + menuItem.topic, { + layer: this.control.layer, + subLayer: this.sublayerInfo, + iconNode: this.iconNode, + menuItem: item + }); + })); this.menu.addChild(item); }, // add on event to expandClickNode @@ -100,7 +101,7 @@ define([ var i = this.icons; this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, function () { var expandNode = this.expandNode, - iconNode = this.expandIconNode; + iconNode = this.expandIconNode; if (domStyle.get(expandNode, 'display') === 'none') { fx.wipeIn({ node: expandNode, @@ -131,9 +132,9 @@ define([ // check scales and add/remove disabled classes from checkbox _checkboxScaleRange: function () { var node = this.checkNode, - scale = this.control.layer.getMap().getScale(), - min = this.sublayerInfo.minScale, - max = this.sublayerInfo.maxScale; + scale = this.control.layer.getMap().getScale(), + min = this.sublayerInfo.minScale, + max = this.sublayerInfo.maxScale; domClass.remove(node, 'layerControlCheckIconOutScale'); if ((min !== 0 && scale > min) || (max !== 0 && scale < max)) { domClass.add(node, 'layerControlCheckIconOutScale'); diff --git a/viewer/js/gis/dijit/LayerControl/nls/resource.js b/viewer/js/gis/dijit/LayerControl/nls/resource.js index 889ba522d..3910c23cb 100644 --- a/viewer/js/gis/dijit/LayerControl/nls/resource.js +++ b/viewer/js/gis/dijit/LayerControl/nls/resource.js @@ -7,7 +7,7 @@ // if need be or checkout the link above and submit a PR define({ root: { - noLegend: 'No Legend', + noLegend: 'No Legend', moveUp: 'Move Up', moveDown: 'Move Down', zoomTo: 'Zoom to Layer', diff --git a/viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js b/viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js index ac2dea328..c5767ff95 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/Menu', @@ -25,7 +26,7 @@ define([ controlOptions = control.controlOptions, controller = control.controller, layerType = control._layerType, - menu = this; + self = this; //reorder menu items if ((layerType === 'vector' && controller.vectorReorder) || (layerType === 'overlay' && controller.overlayReorder)) { control._reorderUp = new MenuItem({ @@ -34,23 +35,23 @@ define([ controller._moveUp(control); } }); - menu.addChild(control._reorderUp); + self.addChild(control._reorderUp); control._reorderDown = new MenuItem({ label: i18n.moveDown, onClick: function () { controller._moveDown(control); } }); - menu.addChild(control._reorderDown); - menu.addChild(new MenuSeparator()); + self.addChild(control._reorderDown); + self.addChild(new MenuSeparator()); } // toggle all dynamic sublayers if (control._dynamicToggleMenuItems) { - control._dynamicToggleMenuItems(menu); + control._dynamicToggleMenuItems(self); } //zoom to layer if ((controlOptions.noZoom !== true && controller.noZoom !== true) || (controller.noZoom === true && controlOptions.noZoom === false)) { - menu.addChild(new MenuItem({ + self.addChild(new MenuItem({ label: i18n.zoomTo, onClick: function () { controller._zoomToLayer(layer); @@ -59,7 +60,7 @@ define([ } //transparency if ((controlOptions.noTransparency !== true && controller.noTransparency !== true) || (controller.noTransparency === true && controlOptions.noTransparency === false)) { - menu.addChild(new Transparency({ + self.addChild(new Transparency({ label: i18n.transparency, layer: layer })); @@ -87,7 +88,7 @@ define([ } })); } - menu.addChild(new PopupMenuItem({ + self.addChild(new PopupMenuItem({ label: i18n.layerSwipe, popup: swipeMenu })); @@ -95,8 +96,8 @@ define([ // metadata link // service url if (controlOptions.metadataUrl === true && layer.url) { - menu.addChild(new MenuSeparator()); - menu.addChild(new MenuItem({ + self.addChild(new MenuSeparator()); + self.addChild(new MenuItem({ label: i18n.metadata, onClick: function () { window.open(layer.url, '_blank'); @@ -105,8 +106,8 @@ define([ } // custom url if (controlOptions.metadataUrl && typeof controlOptions.metadataUrl === 'string') { - menu.addChild(new MenuSeparator()); - menu.addChild(new MenuItem({ + self.addChild(new MenuSeparator()); + self.addChild(new MenuItem({ label: i18n.metadata, onClick: function () { window.open(controlOptions.metadataUrl, '_blank'); @@ -114,9 +115,9 @@ define([ })); } //if last child is a separator remove it - var lastChild = menu.getChildren()[menu.getChildren().length - 1]; + var lastChild = self.getChildren()[self.getChildren().length - 1]; if (lastChild && lastChild.isInstanceOf(MenuSeparator)) { - menu.removeChild(lastChild); + self.removeChild(lastChild); } } }); diff --git a/viewer/js/gis/dijit/LayerControl/plugins/Transparency.js b/viewer/js/gis/dijit/LayerControl/plugins/Transparency.js index d4a9e591e..54f4344e7 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/Transparency.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/Transparency.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ /* transparency component */ define([ 'dojo/_base/declare', @@ -20,6 +21,7 @@ define([ HorizontalSlider, HorizontalRuleLabels ) { + return declare(PopupMenuItem, { layer: null, constructor: function (options) { diff --git a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js index ef23f0c1f..714fab7ec 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js @@ -1,3 +1,4 @@ +/*eslint camelcase: 0*/ define([ 'dojo/_base/array', 'dojo/_base/lang', @@ -31,7 +32,9 @@ define([ i18n ) { 'use strict'; + esriBundle.widgets.legend.NLS_noLegend = i18n.noLegend; + return { ///////////////////// // utility methods // diff --git a/viewer/js/gis/dijit/LocateButton.js b/viewer/js/gis/dijit/LocateButton.js index e2f6f6387..1c7d9e3ab 100644 --- a/viewer/js/gis/dijit/LocateButton.js +++ b/viewer/js/gis/dijit/LocateButton.js @@ -1,61 +1,63 @@ define([ - 'dojo/_base/declare', - 'dojo/_base/lang', - 'esri/dijit/LocateButton', - 'esri/renderers/SimpleRenderer', - 'esri/symbols/PictureMarkerSymbol', - 'esri/layers/GraphicsLayer', - 'esri/InfoTemplate', - 'dojo/topic' + 'dojo/_base/declare', + 'dojo/_base/lang', + 'esri/dijit/LocateButton', + 'esri/renderers/SimpleRenderer', + 'esri/symbols/PictureMarkerSymbol', + 'esri/layers/GraphicsLayer', + 'esri/InfoTemplate', + 'dojo/topic' ], function (declare, lang, LocateButton, SimpleRenderer, PictureMarkerSymbol, GraphicsLayer, InfoTemplate, topic) { - return declare(null, { - growlTemplate: 'latitude: {latitude}
longitude: {longitude}
accuracy: {accuracy}
altitude: {altitude}
altitude accuracy: {altitudeAccuracy}
heading: {heading}
speed: {speed}', - constructor: function (options, node) { - this.options = options; - this.parentNode = node; - }, - startup: function () { - var symbol = new PictureMarkerSymbol('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAmCAYAAACoPemuAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABJhJREFUeNrcmN9PW2UYx7/n9ATKj7QMMUCxmSxlCRI3BzF6MRO9WOyVN5sJFxqvNCa7MmbphTG78Iprwx+weEMiF8bdLNFojBhNDEwu3ObWjo2uLUXKaIFSCqdnz7e8hx1WdOcUij+e5ElLOe3zyfd93ud9nlezLAte7LOv0S4vZ8VPi0eU72dx5bPiU+Jr9j8+fevpcTS3YALUIy/viUdRn10TvyK+cChgTwL5dOCZNqA7CARbgIB//+8VSkB+A8jmgdw6YFb2AgrcQt1gAsUli4m3E6gnAAx0A61N3qQqloE7WZGqsAvIZR0TuCnPYAJ1UV4u8H2oAzhZB9B+gLcFML2y+9GkwI27BhOomL10g71AfxcO1eaWgJuZx0srcGNPBbOV4tK9emInjxphzL9f7u4ubY1y+j45VV2+RkLR+NuMoeyCil0LpnZfzF6+RkI54RhLWUwx1CjGktDORD/snPo7YyzGZGzF8BhMkUaZV9x9R22M6duRKGqrpjvUqtapg5aEeowxGdvJoquzr6rWgEe1uJ8rFrSy+EYFOp3v+ZnlEW5gr2rthjqQq8eMF7UYvGRBL5jwFbZhFCs76rfqqAQMbAd8MP0aKroGy61qZFhcrf551lBdQvXs8wK1VoFvoYym+5vwT6ceBrMrq36YW+gOtJRGng/ljzej1NOEcrsO0y0cGRTYacNuW9yWB0agUoSaLpiBianfw5l7ydbBvle0Yi6Dn+IT1s8n+ouj588nR441F55rxmaLBlNzWT6URXbB/qpLqAETtbh8VGrih9nwYHi47e33TyErx3Lhfhc6Zl7Ufrs62TaxfiXc9eEHCS4rl1RzoZqDIaJ73UHbbGkkp64/WAqm/7jROvAacGtTzj5Zgrvii5YJq/N1pH/8tvX6rTtBPrtdx071DGaKYkz0zFLOf/LZF7TMn0BqXlqaJJBZLCOVzwEbq7CWwlpmPunns/yO1zhG3cVHEn0rn8bq3DBK0s4UimsoPlzZaboyImFB1tY06/55z4r5JFdYEno7g6W5+HfW9vwGyullbKSkl7knaiXyVdcqv1q9faESn/W53JUHAqPETOgz/eF8KDJYnPnmC6wncrASotRN6aFnRKnclwi9ca545tRQns8adSoWt3t0N8bdxeLJOjX6zrvJQMfq+vJXFy1c/Rz4fhz68kdW3zn/+ugnl5N8hs9qLhVzMMQNBRZh4+amZDCLuf1ZPEc6/YWuSx8npt+MBrMPUn5UKugOXSqNDL+0W2CrpcJD8+gE49wX5TQTPuZSZlGAFZ3Fk0t1/OWhUnFk6EBHEo0MymYNNYzGOGJxWHB7XjIgKzqDdxrYsksCE91QS+6lRjA2GZRN6dJrc5S6xt6bI5YX0xRgEyFFKTrf6x6haIyt+n8OJ2v2ruSEXC1BJD9qY0zGdrLo6i5hwVbtdvbowW6k96i18GQdI+kah1HOfUdljKVaHabUeE2BVaTVwZPDqGPrNswYwzH4jql8r6386i5hku85jDYSzh54HVcFU//NK4JGX6ow0VVOeb9U+VdfQzX44m7cmej/r6vOf+py+JEAAwDRMD/uB0XQuQAAAABJRU5ErkJggg==', 38, 38); - this.graphics = new GraphicsLayer({ - id: 'GeoLocationGraphics' - }); - var renderer = new SimpleRenderer(symbol); - renderer.label = 'GPS Position'; - renderer.description = 'GPS Position'; - this.graphics.setRenderer(renderer); - this.options.map.addLayer(this.graphics); - this.options.graphicsLayer = this.graphics; - this.options.infoTemplate = new InfoTemplate('GPS Position', '${*}'); - this.options.symbol = null; + 'use strict'; - this.locateButton = new LocateButton(this.options, this.parentNode); - this.locateButton.startup(); - this.locateButton.on('locate', lang.hitch(this, '_growlLocation')); - }, - _growlLocation: function (evt) { - var stats = { - accuracy: (evt.position.coords.accuracy) ? evt.position.coords.accuracy : '', - altitude: (evt.position.coords.altitude) ? evt.position.coords.altitude : '', - altitudeAccuracy: (evt.position.coords.altitudeAccuracy) ? evt.position.coords.altitudeAccuracy : '', - heading: (evt.position.coords.heading) ? evt.position.coords.heading : '', - latitude: (evt.position.coords.latitude) ? evt.position.coords.latitude : '', - longitude: (evt.position.coords.longitude) ? evt.position.coords.longitude : '', - speed: (evt.position.coords.speed) ? evt.position.coords.speed : '' - }; + return declare(null, { + growlTemplate: 'latitude: {latitude}
longitude: {longitude}
accuracy: {accuracy}
altitude: {altitude}
altitude accuracy: {altitudeAccuracy}
heading: {heading}
speed: {speed}', + constructor: function (options, node) { + this.options = options; + this.parentNode = node; + }, + startup: function () { + var symbol = new PictureMarkerSymbol('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAmCAYAAACoPemuAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABJhJREFUeNrcmN9PW2UYx7/n9ATKj7QMMUCxmSxlCRI3BzF6MRO9WOyVN5sJFxqvNCa7MmbphTG78Iprwx+weEMiF8bdLNFojBhNDEwu3ObWjo2uLUXKaIFSCqdnz7e8hx1WdOcUij+e5ElLOe3zyfd93ud9nlezLAte7LOv0S4vZ8VPi0eU72dx5bPiU+Jr9j8+fevpcTS3YALUIy/viUdRn10TvyK+cChgTwL5dOCZNqA7CARbgIB//+8VSkB+A8jmgdw6YFb2AgrcQt1gAsUli4m3E6gnAAx0A61N3qQqloE7WZGqsAvIZR0TuCnPYAJ1UV4u8H2oAzhZB9B+gLcFML2y+9GkwI27BhOomL10g71AfxcO1eaWgJuZx0srcGNPBbOV4tK9emInjxphzL9f7u4ubY1y+j45VV2+RkLR+NuMoeyCil0LpnZfzF6+RkI54RhLWUwx1CjGktDORD/snPo7YyzGZGzF8BhMkUaZV9x9R22M6duRKGqrpjvUqtapg5aEeowxGdvJoquzr6rWgEe1uJ8rFrSy+EYFOp3v+ZnlEW5gr2rthjqQq8eMF7UYvGRBL5jwFbZhFCs76rfqqAQMbAd8MP0aKroGy61qZFhcrf551lBdQvXs8wK1VoFvoYym+5vwT6ceBrMrq36YW+gOtJRGng/ljzej1NOEcrsO0y0cGRTYacNuW9yWB0agUoSaLpiBianfw5l7ydbBvle0Yi6Dn+IT1s8n+ouj588nR441F55rxmaLBlNzWT6URXbB/qpLqAETtbh8VGrih9nwYHi47e33TyErx3Lhfhc6Zl7Ufrs62TaxfiXc9eEHCS4rl1RzoZqDIaJ73UHbbGkkp64/WAqm/7jROvAacGtTzj5Zgrvii5YJq/N1pH/8tvX6rTtBPrtdx071DGaKYkz0zFLOf/LZF7TMn0BqXlqaJJBZLCOVzwEbq7CWwlpmPunns/yO1zhG3cVHEn0rn8bq3DBK0s4UimsoPlzZaboyImFB1tY06/55z4r5JFdYEno7g6W5+HfW9vwGyullbKSkl7knaiXyVdcqv1q9faESn/W53JUHAqPETOgz/eF8KDJYnPnmC6wncrASotRN6aFnRKnclwi9ca545tRQns8adSoWt3t0N8bdxeLJOjX6zrvJQMfq+vJXFy1c/Rz4fhz68kdW3zn/+ugnl5N8hs9qLhVzMMQNBRZh4+amZDCLuf1ZPEc6/YWuSx8npt+MBrMPUn5UKugOXSqNDL+0W2CrpcJD8+gE49wX5TQTPuZSZlGAFZ3Fk0t1/OWhUnFk6EBHEo0MymYNNYzGOGJxWHB7XjIgKzqDdxrYsksCE91QS+6lRjA2GZRN6dJrc5S6xt6bI5YX0xRgEyFFKTrf6x6haIyt+n8OJ2v2ruSEXC1BJD9qY0zGdrLo6i5hwVbtdvbowW6k96i18GQdI+kah1HOfUdljKVaHabUeE2BVaTVwZPDqGPrNswYwzH4jql8r6386i5hku85jDYSzh54HVcFU//NK4JGX6ow0VVOeb9U+VdfQzX44m7cmej/r6vOf+py+JEAAwDRMD/uB0XQuQAAAABJRU5ErkJggg==', 38, 38); + this.graphics = new GraphicsLayer({ + id: 'GeoLocationGraphics' + }); + var renderer = new SimpleRenderer(symbol); + renderer.label = 'GPS Position'; + renderer.description = 'GPS Position'; + this.graphics.setRenderer(renderer); + this.options.map.addLayer(this.graphics); + this.options.graphicsLayer = this.graphics; + this.options.infoTemplate = new InfoTemplate('GPS Position', '${*}'); + this.options.symbol = null; - if (this.graphics.graphics.length > 0) { - this.graphics.graphics[0].attributes = stats; - } + this.locateButton = new LocateButton(this.options, this.parentNode); + this.locateButton.startup(); + this.locateButton.on('locate', lang.hitch(this, '_growlLocation')); + }, + _growlLocation: function (evt) { + var stats = { + accuracy: (evt.position.coords.accuracy) ? evt.position.coords.accuracy : '', + altitude: (evt.position.coords.altitude) ? evt.position.coords.altitude : '', + altitudeAccuracy: (evt.position.coords.altitudeAccuracy) ? evt.position.coords.altitudeAccuracy : '', + heading: (evt.position.coords.heading) ? evt.position.coords.heading : '', + latitude: (evt.position.coords.latitude) ? evt.position.coords.latitude : '', + longitude: (evt.position.coords.longitude) ? evt.position.coords.longitude : '', + speed: (evt.position.coords.speed) ? evt.position.coords.speed : '' + }; - if (this.options.publishGPSPosition) { - topic.publish('growler/growl', { - title: 'GPS Position', - message: lang.replace(this.growlTemplate, stats), - level: 'default', //can be: 'default', 'warning', 'info', 'error', 'success'. - timeout: 10000, //set to 0 for no timeout - opacity: 1.0 - }); - } - } - }); + if (this.graphics.graphics.length > 0) { + this.graphics.graphics[0].attributes = stats; + } + + if (this.options.publishGPSPosition) { + topic.publish('growler/growl', { + title: 'GPS Position', + message: lang.replace(this.growlTemplate, stats), + level: 'default', //can be: 'default', 'warning', 'info', 'error', 'success'. + timeout: 10000, //set to 0 for no timeout + opacity: 1.0 + }); + } + } + }); }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/MapInfo.js b/viewer/js/gis/dijit/MapInfo.js index 380c772b5..baab285df 100644 --- a/viewer/js/gis/dijit/MapInfo.js +++ b/viewer/js/gis/dijit/MapInfo.js @@ -169,6 +169,8 @@ define([ this._project(pnt); } break; + default: + break; } }, _project: function (pnt) { diff --git a/viewer/js/gis/dijit/Measurement.js b/viewer/js/gis/dijit/Measurement.js index c6acdf0ea..1d7ad28a6 100644 --- a/viewer/js/gis/dijit/Measurement.js +++ b/viewer/js/gis/dijit/Measurement.js @@ -1,3 +1,4 @@ +/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', @@ -35,10 +36,8 @@ define([ this.connectMapClick(); } // a measurement tool is active - } else { - if (this.mapClickMode !== 'measure') { - this.disconnectMapClick(); - } + } else if (this.mapClickMode !== 'measure') { + this.disconnectMapClick(); } }, disconnectMapClick: function () { diff --git a/viewer/js/gis/dijit/Print.js b/viewer/js/gis/dijit/Print.js index bb6a6efed..df22c0e1f 100644 --- a/viewer/js/gis/dijit/Print.js +++ b/viewer/js/gis/dijit/Print.js @@ -1,3 +1,4 @@ +/*eslint strict: 0, no-eval: 0 */ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', @@ -31,6 +32,47 @@ define([ 'xstyle/css!./Print/css/Print.css' ], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, PrintTask, Memory, lang, array, topic, Style, domConstruct, domClass, printTemplate, printResultTemplate, PrintTemplate, PrintParameters, esriRequest, i18n) { + // Print result dijit + var PrintResultDijit = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { + widgetsInTemplate: true, + templateString: printResultTemplate, + i18n: i18n, + url: null, + fileHandle: null, + postCreate: function () { + this.inherited(arguments); + this.fileHandle.then(lang.hitch(this, '_onPrintComplete'), lang.hitch(this, '_onPrintError')); + }, + _onPrintComplete: function (data) { + if (data.url) { + this.url = data.url; + this.nameNode.innerHTML = '' + this.docName + ''; + domClass.add(this.resultNode, 'printResultHover'); + } else { + this._onPrintError(this.i18n.printResults.errorMessage); + } + }, + _onPrintError: function (err) { + topic.publish('viewer/handleError', { + source: 'Print', + error: err + }); + this.nameNode.innerHTML = '' + i18n.printResults.errorMessage + ''; + domClass.add(this.resultNode, 'printResultError'); + }, + _openPrint: function () { + if (this.url !== null) { + window.open(this.url); + } + }, + _handleStatusUpdate: function (event) { + var jobStatus = event.jobInfo.jobStatus; + if (jobStatus === 'esriJobFailed') { + this._onPrintError(this.i18n.printResults.errorMessage); + } + } + }); + // Main print dijit var PrintDijit = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { widgetsInTemplate: true, @@ -69,7 +111,7 @@ define([ }, operationalLayersInspector: function (opLayers) { array.forEach(opLayers, function (layer) { - if (layer.id == 'Measurement_graphicslayer') { + if (layer.id === 'Measurement_graphicslayer') { array.forEach(layer.featureCollection.layers, function (fcLayer) { array.forEach(fcLayer.featureSet.features, function (feature) { delete feature.attributes; @@ -92,17 +134,17 @@ define([ this.printTask = new PrintTask(this.printTaskURL, { async: data.executionType === 'esriExecutionTypeAsynchronous' }); - var Layout_Template = array.filter(data.parameters, function (param) { + var layoutTemplate = array.filter(data.parameters, function (param) { return param.name === 'Layout_Template'; }); - if (Layout_Template.length === 0) { + if (layoutTemplate.length === 0) { topic.publish('viewer/handleError', { source: 'Print', error: 'Print service parameters name for templates must be \'Layout_Template\'' }); return; } - var layoutItems = array.map(Layout_Template[0].choiceList, function (item) { + var layoutItems = array.map(layoutTemplate[0].choiceList, function (item) { return { name: item, id: item @@ -118,7 +160,7 @@ define([ if (this.defaultLayout) { this.layoutDijit.set('value', this.defaultLayout); } else { - this.layoutDijit.set('value', Layout_Template[0].defaultValue); + this.layoutDijit.set('value', layoutTemplate[0].defaultValue); } var Format = array.filter(data.parameters, function (param) { @@ -164,9 +206,7 @@ define([ var template = new PrintTemplate(); template.format = form.format; template.layout = form.layout; - /*jslint evil: true */ template.preserveScale = eval(form.preserveScale); //turns a string 'true' into true - /*jslint evil: false */ template.label = form.title; template.exportOptions = mapOnlyForm; template.layoutOptions = { @@ -187,8 +227,8 @@ define([ fileHandle: fileHandle }).placeAt(this.printResultsNode, 'last'); - if ( this.printTask.async ) { - result.own( this.printTask.printGp.on( 'status-update', lang.hitch( result, '_handleStatusUpdate' ) ) ); + if (this.printTask.async) { + result.own(this.printTask.printGp.on('status-update', lang.hitch(result, '_handleStatusUpdate'))); } @@ -205,45 +245,5 @@ define([ } }); - // Print result dijit - var PrintResultDijit = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { - widgetsInTemplate: true, - templateString: printResultTemplate, - i18n: i18n, - url: null, - fileHandle: null, - postCreate: function () { - this.inherited(arguments); - this.fileHandle.then(lang.hitch(this, '_onPrintComplete'), lang.hitch(this, '_onPrintError')); - }, - _onPrintComplete: function (data) { - if (data.url) { - this.url = data.url; - this.nameNode.innerHTML = '' + this.docName + ''; - domClass.add(this.resultNode, 'printResultHover'); - } else { - this._onPrintError( this.i18n.printResults.errorMessage ); - } - }, - _onPrintError: function (err) { - topic.publish('viewer/handleError', { - source: 'Print', - error: err - }); - this.nameNode.innerHTML = '' + i18n.printResults.errorMessage + ''; - domClass.add(this.resultNode, 'printResultError'); - }, - _openPrint: function () { - if (this.url !== null) { - window.open(this.url); - } - }, - _handleStatusUpdate: function ( event ) { - var jobStatus = event.jobInfo.jobStatus; - if ( jobStatus === 'esriJobFailed' ){ - this._onPrintError( this.i18n.printResults.errorMessage ); - } - } - }); return PrintDijit; }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index de426f265..964c34f6f 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -1,296 +1,296 @@ /*global google */ -/*jshint unused:true */ +/*eslint strict: 0*/ define([ - 'dojo/_base/declare', - 'dijit/_WidgetBase', - 'dijit/_TemplatedMixin', - 'dijit/_WidgetsInTemplateMixin', - 'dojo/_base/lang', - 'dojo/aspect', - 'dojo/topic', - 'esri/layers/GraphicsLayer', - 'esri/graphic', - 'esri/renderers/SimpleRenderer', - 'dojo/text!./StreetView/templates/StreetView.html', - 'esri/symbols/PictureMarkerSymbol', - 'dojo/dom-style', - 'esri/geometry/Point', - 'esri/SpatialReference', - 'dijit/MenuItem', - '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js', - 'dojo/i18n!./StreetView/nls/resource', + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_WidgetsInTemplateMixin', + 'dojo/_base/lang', + 'dojo/aspect', + 'dojo/topic', + 'esri/layers/GraphicsLayer', + 'esri/graphic', + 'esri/renderers/SimpleRenderer', + 'dojo/text!./StreetView/templates/StreetView.html', + 'esri/symbols/PictureMarkerSymbol', + 'dojo/dom-style', + 'esri/geometry/Point', + 'esri/SpatialReference', + 'dijit/MenuItem', + '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js', + 'dojo/i18n!./StreetView/nls/resource', - 'dijit/form/Button', - 'xstyle/css!./StreetView/css/StreetView.css', - 'gis/plugins/async!//maps.google.com/maps/api/js?v=3&sensor=false' + 'dijit/form/Button', + 'xstyle/css!./StreetView/css/StreetView.css', + 'gis/plugins/async!//maps.google.com/maps/api/js?v=3&sensor=false' ], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, aspect, topic, GraphicsLayer, Graphic, SimpleRenderer, template, PictureMarkerSymbol, domStyle, Point, SpatialReference, MenuItem, proj4, i18n) { - return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { - widgetsInTemplate: true, - templateString: template, - i18n: i18n, - mapClickMode: null, + return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { + widgetsInTemplate: true, + templateString: template, + i18n: i18n, + mapClickMode: null, - panoOptions: { - addressControlOptions: { - position: google.maps.ControlPosition.TOP_RIGHT - }, - linksControl: false, - panControl: false, - zoomControlOptions: { - style: google.maps.ZoomControlStyle.SMALL - }, - enableCloseButton: false - }, + panoOptions: { + addressControlOptions: { + position: google.maps.ControlPosition.TOP_RIGHT + }, + linksControl: false, + panControl: false, + zoomControlOptions: { + style: google.maps.ZoomControlStyle.SMALL + }, + enableCloseButton: false + }, - // in case this changes some day - proj4BaseURL: 'http://spatialreference.org/', + // in case this changes some day + proj4BaseURL: 'http://spatialreference.org/', - // options are ESRI, EPSG and SR-ORG - // See http://spatialreference.org/ for more information - proj4Catalog: 'EPSG', + // options are ESRI, EPSG and SR-ORG + // See http://spatialreference.org/ for more information + proj4Catalog: 'EPSG', - // if desired, you can load a projection file from your server - // instead of using one from spatialreference.org - // i.e., http://server/projections/102642.js - projCustomURL: null, + // if desired, you can load a projection file from your server + // instead of using one from spatialreference.org + // i.e., http://server/projections/102642.js + projCustomURL: null, - postCreate: function () { - this.inherited(arguments); - this.createGraphicsLayer(); - this.map.on('click', lang.hitch(this, 'getStreetView')); + postCreate: function () { + this.inherited(arguments); + this.createGraphicsLayer(); + this.map.on('click', lang.hitch(this, 'getStreetView')); - this.own(topic.subscribe('mapClickMode/currentSet', lang.hitch(this, 'setMapClickMode'))); + this.own(topic.subscribe('mapClickMode/currentSet', lang.hitch(this, 'setMapClickMode'))); - if (this.parentWidget) { - if (this.parentWidget.toggleable) { - this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { - this.onLayoutChange(this.parentWidget.open); - }))); - } - this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, function () { - if (this.panorama) { - google.maps.event.trigger(this.panorama, 'resize'); - } - }))); - } + if (this.parentWidget) { + if (this.parentWidget.toggleable) { + this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { + this.onLayoutChange(this.parentWidget.open); + }))); + } + this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, function () { + if (this.panorama) { + google.maps.event.trigger(this.panorama, 'resize'); + } + }))); + } - // spatialreference.org uses the old - // Proj4js style so we need an alias - // https://github.com/proj4js/proj4js/issues/23 - window.Proj4js = proj4; + // spatialreference.org uses the old + // Proj4js style so we need an alias + // https://github.com/proj4js/proj4js/issues/23 + window.Proj4js = proj4; - if (this.mapRightClickMenu) { - this.addRightClickMenu(); - } - }, - createGraphicsLayer: function () { - this.pointSymbol = new PictureMarkerSymbol(require.toUrl('gis/dijit/StreetView/images/blueArrow.png'), 30, 30); - this.pointGraphics = new GraphicsLayer({ - id: 'streetview_graphics', - title: 'Street View' - }); - this.pointRenderer = new SimpleRenderer(this.pointSymbol); - this.pointRenderer.label = 'Street View'; - this.pointRenderer.description = 'Street View'; - this.pointGraphics.setRenderer(this.pointRenderer); - this.map.addLayer(this.pointGraphics); - }, - addRightClickMenu: function () { - this.map.on('MouseDown', lang.hitch(this, function (evt) { - this.mapRightClickPoint = evt.mapPoint; - })); - this.mapRightClickMenu.addChild(new MenuItem({ - label: this.i18n.rightClickMenuItem.label, - onClick: lang.hitch(this, 'streetViewFromMapRightClick') - })); - }, - onOpen: function () { - this.pointGraphics.show(); - if (!this.panorama || !this.panoramaService) { - this.panorama = new google.maps.StreetViewPanorama(this.panoNode, this.panoOptions); - this.panoramaService = new google.maps.StreetViewService(); - } - if (this.panorama) { - google.maps.event.trigger(this.panorama, 'resize'); - } - }, - onClose: function () { - // end streetview on close of title pane - this.pointGraphics.hide(); - if (this.mapClickMode === 'streetview') { - this.connectMapClick(); - } - }, - onLayoutChange: function (open) { - if (open) { - this.onOpen(); - } else { - this.onClose(); - } - }, - placePoint: function () { - this.disconnectMapClick(); - //get map click, set up listener in post create - }, - disconnectMapClick: function () { - this.map.setMapCursor('crosshair'); - topic.publish('mapClickMode/setCurrent', 'streetview'); - }, - connectMapClick: function () { - this.map.setMapCursor('auto'); - topic.publish('mapClickMode/setDefault'); - }, - clearGraphics: function () { - this.pointGraphics.clear(); - domStyle.set(this.noStreetViewResults, 'display', 'block'); - }, - enableStreetViewClick: function () { - this.disconnectMapClick(); - }, - disableStreetViewClick: function () { - this.connectMapClick(); - }, - getStreetView: function (evt, overRide) { - if (this.mapClickMode === 'streetview' || overRide) { - var mapPoint = evt.mapPoint; - if (!mapPoint) { - return; - } + if (this.mapRightClickMenu) { + this.addRightClickMenu(); + } + }, + createGraphicsLayer: function () { + this.pointSymbol = new PictureMarkerSymbol(require.toUrl('gis/dijit/StreetView/images/blueArrow.png'), 30, 30); + this.pointGraphics = new GraphicsLayer({ + id: 'streetview_graphics', + title: 'Street View' + }); + this.pointRenderer = new SimpleRenderer(this.pointSymbol); + this.pointRenderer.label = 'Street View'; + this.pointRenderer.description = 'Street View'; + this.pointGraphics.setRenderer(this.pointRenderer); + this.map.addLayer(this.pointGraphics); + }, + addRightClickMenu: function () { + this.map.on('MouseDown', lang.hitch(this, function (evt) { + this.mapRightClickPoint = evt.mapPoint; + })); + this.mapRightClickMenu.addChild(new MenuItem({ + label: this.i18n.rightClickMenuItem.label, + onClick: lang.hitch(this, 'streetViewFromMapRightClick') + })); + }, + onOpen: function () { + this.pointGraphics.show(); + if (!this.panorama || !this.panoramaService) { + this.panorama = new google.maps.StreetViewPanorama(this.panoNode, this.panoOptions); + this.panoramaService = new google.maps.StreetViewService(); + } + if (this.panorama) { + google.maps.event.trigger(this.panorama, 'resize'); + } + }, + onClose: function () { + // end streetview on close of title pane + this.pointGraphics.hide(); + if (this.mapClickMode === 'streetview') { + this.connectMapClick(); + } + }, + onLayoutChange: function (open) { + if (open) { + this.onOpen(); + } else { + this.onClose(); + } + }, + placePoint: function () { + this.disconnectMapClick(); + //get map click, set up listener in post create + }, + disconnectMapClick: function () { + this.map.setMapCursor('crosshair'); + topic.publish('mapClickMode/setCurrent', 'streetview'); + }, + connectMapClick: function () { + this.map.setMapCursor('auto'); + topic.publish('mapClickMode/setDefault'); + }, + clearGraphics: function () { + this.pointGraphics.clear(); + domStyle.set(this.noStreetViewResults, 'display', 'block'); + }, + enableStreetViewClick: function () { + this.disconnectMapClick(); + }, + disableStreetViewClick: function () { + this.connectMapClick(); + }, + getStreetView: function (evt, overRide) { + if (this.mapClickMode === 'streetview' || overRide) { + var mapPoint = evt.mapPoint; + if (!mapPoint) { + return; + } - if (this.parentWidget && !this.parentWidget.open) { - this.parentWidget.toggle(); - } + if (this.parentWidget && !this.parentWidget.open) { + this.parentWidget.toggle(); + } - // convert the map point's coordinate system into lat/long - var geometry = null, - wkid = mapPoint.spatialReference.wkid; - if (wkid === 102100) { - wkid = 3857; - } - var key = this.proj4Catalog + ':' + wkid; - if (!proj4.defs[key]) { - var url = this.proj4CustomURL || this.proj4BaseURL + 'ref/' + this.proj4Catalog.toLowerCase() + '/' + wkid + '/proj4js/'; - require([url], lang.hitch(this, 'getStreetView', evt, true)); - return; - } - // only need one projection as we are - // converting to WGS84 lat/long - var projPoint = proj4(proj4.defs[key]).inverse([mapPoint.x, mapPoint.y]); - if (projPoint) { - geometry = { - x: projPoint[0], - y: projPoint[1] - }; - } + // convert the map point's coordinate system into lat/long + var geometry = null, + wkid = mapPoint.spatialReference.wkid; + if (wkid === 102100) { + wkid = 3857; + } + var key = this.proj4Catalog + ':' + wkid; + if (!proj4.defs[key]) { + var url = this.proj4CustomURL || this.proj4BaseURL + 'ref/' + this.proj4Catalog.toLowerCase() + '/' + wkid + '/proj4js/'; + require([url], lang.hitch(this, 'getStreetView', evt, true)); + return; + } + // only need one projection as we are + // converting to WGS84 lat/long + var projPoint = proj4(proj4.defs[key]).inverse([mapPoint.x, mapPoint.y]); + if (projPoint) { + geometry = { + x: projPoint[0], + y: projPoint[1] + }; + } - if (geometry) { - domStyle.set(this.noStreetViewResults, 'display', 'none'); - domStyle.set(this.loadingStreetView, 'display', 'inline-block'); - this.getPanoramaLocation(geometry); - } else { - this.setPanoPlace = null; - this.clearGraphics(); - domStyle.set(this.noStreetViewResults, 'display', 'block'); - } - } + if (geometry) { + domStyle.set(this.noStreetViewResults, 'display', 'none'); + domStyle.set(this.loadingStreetView, 'display', 'inline-block'); + this.getPanoramaLocation(geometry); + } else { + this.setPanoPlace = null; + this.clearGraphics(); + domStyle.set(this.noStreetViewResults, 'display', 'block'); + } + } - }, - getPanoramaLocation: function (geoPoint) { - var place = new google.maps.LatLng(geoPoint.y, geoPoint.x); - this.panoramaService.getPanoramaByLocation(place, 50, lang.hitch(this, 'getPanoramaByLocationComplete', geoPoint)); - // Panorama Events -- Changed location - google.maps.event.addListener(this.panorama, 'position_changed', lang.hitch(this, 'setPlaceMarkerPosition')); - // Panorama Events -- Changed Rotation - google.maps.event.addListener(this.panorama, 'pov_changed', lang.hitch(this, 'setPlaceMarkerRotation')); - }, - getPanoramaByLocationComplete: function (geoPoint, StreetViewPanoramaData, StreetViewStatus) { - domStyle.set(this.loadingStreetView, 'display', 'none'); - if (StreetViewStatus === 'OK') { - this.disableStreetViewClick(); - var place = new google.maps.LatLng(geoPoint.y, geoPoint.x); - this.setPanoPlace = place; - this.firstSet = true; - this.panorama.setPosition(place); - } else if (StreetViewStatus === 'ZERO_RESULTS') { - this.setPanoPlace = null; - this.clearGraphics(); - // reset default map click mode - this.connectMapClick(); - domStyle.set(this.noStreetViewResults, 'display', 'block'); - } else { - this.setPanoPlace = null; - this.clearGraphics(); - topic.publish('viewer/handleError', { - source: 'StreetView', - error: 'Unknown.' - }); - } - }, - setPlaceMarkerPosition: function () { - if (!this.placeMarker || this.pointGraphics.graphics.length === 0) { - this.placeMarker = new Graphic(); - // Add graphic to the map - this.pointGraphics.add(this.placeMarker); - } - // get the new lat/long from streetview - var panoPosition = this.panorama.getPosition(); - var positionLat = panoPosition.lat(); - var positionLong = panoPosition.lng(); - // Make sure they are numbers - if (!isNaN(positionLat) && !isNaN(positionLong)) { - // convert the resulting lat/long to the map's spatial reference - var xy = null, - wkid = this.map.spatialReference.wkid; - if (wkid === 102100) { - wkid = 3857; - } - var key = this.proj4Catalog + ':' + wkid; - if (!proj4.defs[key]) { - var url = this.proj4CustomURL || this.proj4BaseURL + 'ref/' + this.proj4Catalog.toLowerCase() + '/' + wkid + '/proj4js/'; - require([url], lang.hitch(this, 'setPlaceMarkerPosition')); - return; - } - // only need the one projection as we are - // converting from WGS84 lat/long - xy = proj4(proj4.defs[key]).forward([positionLong, positionLat]); - if (xy) { - var point = new Point(xy, new SpatialReference({ - wkid: wkid - })); + }, + getPanoramaLocation: function (geoPoint) { + var place = new google.maps.LatLng(geoPoint.y, geoPoint.x); + this.panoramaService.getPanoramaByLocation(place, 50, lang.hitch(this, 'getPanoramaByLocationComplete', geoPoint)); + // Panorama Events -- Changed location + google.maps.event.addListener(this.panorama, 'position_changed', lang.hitch(this, 'setPlaceMarkerPosition')); + // Panorama Events -- Changed Rotation + google.maps.event.addListener(this.panorama, 'pov_changed', lang.hitch(this, 'setPlaceMarkerRotation')); + }, + getPanoramaByLocationComplete: function (geoPoint, StreetViewPanoramaData, StreetViewStatus) { + domStyle.set(this.loadingStreetView, 'display', 'none'); + if (StreetViewStatus === 'OK') { + this.disableStreetViewClick(); + var place = new google.maps.LatLng(geoPoint.y, geoPoint.x); + this.setPanoPlace = place; + this.firstSet = true; + this.panorama.setPosition(place); + } else if (StreetViewStatus === 'ZERO_RESULTS') { + this.setPanoPlace = null; + this.clearGraphics(); + // reset default map click mode + this.connectMapClick(); + domStyle.set(this.noStreetViewResults, 'display', 'block'); + } else { + this.setPanoPlace = null; + this.clearGraphics(); + topic.publish('viewer/handleError', { + source: 'StreetView', + error: 'Unknown.' + }); + } + }, + setPlaceMarkerPosition: function () { + if (!this.placeMarker || this.pointGraphics.graphics.length === 0) { + this.placeMarker = new Graphic(); + // Add graphic to the map + this.pointGraphics.add(this.placeMarker); + } + // get the new lat/long from streetview + var panoPosition = this.panorama.getPosition(); + var positionLat = panoPosition.lat(); + var positionLong = panoPosition.lng(); + // Make sure they are numbers + if (!isNaN(positionLat) && !isNaN(positionLong)) { + // convert the resulting lat/long to the map's spatial reference + var xy = null, + wkid = this.map.spatialReference.wkid; + if (wkid === 102100) { + wkid = 3857; + } + var key = this.proj4Catalog + ':' + wkid; + if (!proj4.defs[key]) { + var url = this.proj4CustomURL || this.proj4BaseURL + 'ref/' + this.proj4Catalog.toLowerCase() + '/' + wkid + '/proj4js/'; + require([url], lang.hitch(this, 'setPlaceMarkerPosition')); + return; + } + // only need the one projection as we are + // converting from WGS84 lat/long + xy = proj4(proj4.defs[key]).forward([positionLong, positionLat]); + if (xy) { + var point = new Point(xy, new SpatialReference({ + wkid: wkid + })); - // change point position on the map - this.placeMarker.setGeometry(point); - if (this.setPanoPlace && !this.firstSet) { - var heading = google.maps.geometry.spherical.computeHeading(panoPosition, this.setPanoPlace); - this.panorama.setPov({ - heading: heading, - pitch: 0 - }); - setTimeout(lang.hitch(this, function () { - this.setPanoPlace = null; - }), 1000); - } else { - this.firstSet = false; - } - } - } - }, - setPlaceMarkerRotation: function () { - if (this.placeMarker) { - var pov = this.panorama.getPov(); - this.pointSymbol.setAngle(pov.heading); - this.pointGraphics.refresh(); - } - }, - streetViewFromMapRightClick: function () { - var evt = { - mapPoint: this.mapRightClickPoint - }; - this.getStreetView(evt, true); - }, - setMapClickMode: function (mode) { - this.mapClickMode = mode; - } - }); + // change point position on the map + this.placeMarker.setGeometry(point); + if (this.setPanoPlace && !this.firstSet) { + var heading = google.maps.geometry.spherical.computeHeading(panoPosition, this.setPanoPlace); + this.panorama.setPov({ + heading: heading, + pitch: 0 + }); + setTimeout(lang.hitch(this, function () { + this.setPanoPlace = null; + }), 1000); + } else { + this.firstSet = false; + } + } + } + }, + setPlaceMarkerRotation: function () { + if (this.placeMarker) { + var pov = this.panorama.getPov(); + this.pointSymbol.setAngle(pov.heading); + this.pointGraphics.refresh(); + } + }, + streetViewFromMapRightClick: function () { + var evt = { + mapPoint: this.mapRightClickPoint + }; + this.getStreetView(evt, true); + }, + setMapClickMode: function (mode) { + this.mapClickMode = mode; + } + }); }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Vim.js b/viewer/js/gis/dijit/Vim.js index 3c55acffa..8ad012dc1 100644 --- a/viewer/js/gis/dijit/Vim.js +++ b/viewer/js/gis/dijit/Vim.js @@ -2,54 +2,58 @@ // Used to serialize/deserialize the identitymanager storing // credential objects (tokens) in either local storage or a cookie // usage: -// param 1: the name of the cookie/localstorage key -// new Vim(idStateName); +// param 1: the name of the cookie/localstorage key +// new Vim(idStateName); define([ - 'dojo/_base/declare', - 'esri/kernel', - 'dojo/cookie', - 'dojo/json', - 'dojo/_base/unload', - 'dojo/_base/lang' -], function(declare, kernel, cookie, JSON, baseUnload, lang) { - return declare(null, { - constructor: function(idStateName) { - this.idStateName = idStateName || 'esri_jsapi_id_manager_data'; - baseUnload.addOnUnload(lang.hitch(this, 'storeCredentials')); - this.loadCredentials(); - }, - loadCredentials: function() { - var idJson, idObject; - if (this._supportsLocalStorage()) { - idJson = window.localStorage.getItem(this.idStateName); - } else { - idJson = cookie(this.idStateName); - } - if (idJson && idJson != 'null' && idJson.length > 4) { - idObject = JSON.parse(idJson); - kernel.id.initialize(idObject); - } - }, - storeCredentials: function() { - if (kernel.id.credentials.length === 0) { - return; - } - var idString = JSON.stringify(kernel.id.toJson()); - if (this._supportsLocalStorage()) { - window.localStorage.setItem(this.idStateName, idString); - } else { - cookie(this.idStateName, idString, { - expires: 1 - }); - } - }, - _supportsLocalStorage: function() { - try { - return 'localStorage' in window && window.localStorage !== null; - } catch (e) { - return false; - } - } - }); + 'dojo/_base/declare', + 'esri/kernel', + 'dojo/cookie', + 'dojo/json', + 'dojo/_base/unload', + 'dojo/_base/lang' +], function (declare, kernel, cookie, JSON, baseUnload, lang) { + 'use strict'; + + return declare(null, { + constructor: function (idStateName) { + this.idStateName = idStateName || 'esri_jsapi_id_manager_data'; + baseUnload.addOnUnload(lang.hitch(this, 'storeCredentials')); + this.loadCredentials(); + }, + loadCredentials: function () { + var idJson, idObject; + if (this._supportsLocalStorage()) { + idJson = window.localStorage.getItem(this.idStateName); + } else { + idJson = cookie(this.idStateName); + } + if (idJson && idJson !== 'null' && idJson.length > 4) { + idObject = JSON.parse(idJson); + kernel.id.initialize(idObject); + } + }, + + storeCredentials: function () { + if (kernel.id.credentials.length === 0) { + return; + } + var idString = JSON.stringify(kernel.id.toJson()); + if (this._supportsLocalStorage()) { + window.localStorage.setItem(this.idStateName, idString); + } else { + cookie(this.idStateName, idString, { + expires: 1 + }); + } + }, + + _supportsLocalStorage: function () { + try { + return 'localStorage' in window && window.localStorage !== null; + } catch (e) { + return false; + } + } + }); }); diff --git a/viewer/js/gis/dijit/_FloatingWidgetMixin.js b/viewer/js/gis/dijit/_FloatingWidgetMixin.js index 23e35706d..3163d78d7 100644 --- a/viewer/js/gis/dijit/_FloatingWidgetMixin.js +++ b/viewer/js/gis/dijit/_FloatingWidgetMixin.js @@ -1,22 +1,24 @@ +/*eslint strict: 0*/ define([ - 'dojo/_base/declare', - 'dojo/on', - 'dojo/_base/lang' + 'dojo/_base/declare', + 'dojo/on', + 'dojo/_base/lang' ], function (declare, on, lang) { - return declare(null, { - startup: function () { - // var parentWidget = this.getParent(); - if (this.parentWidget && this.parentWidget.declaredClass === 'gis.dijit.FloatingWidget' && this.onOpen) { - on(this.parentWidget, 'show', lang.hitch(this, 'onOpen')); - } - if (this.parentWidget && this.parentWidget.declaredClass === 'gis.dijit.FloatingWidget' && this.onClose) { - on(this.parentWidget, 'hide', lang.hitch(this, 'onClose')); - } - if (this.parentWidget && this.parentWidget.declaredClass === 'gis.dijit.FloatingWidget' && this.openOnStartup) { - this.parentWidget.show(); - } - this.inherited(arguments); - } - }); + return declare(null, { + startup: function () { + // var parentWidget = this.getParent(); + if (this.parentWidget && this.parentWidget.declaredClass === 'gis.dijit.FloatingWidget' && this.onOpen) { + on(this.parentWidget, 'show', lang.hitch(this, 'onOpen')); + } + if (this.parentWidget && this.parentWidget.declaredClass === 'gis.dijit.FloatingWidget' && this.onClose) { + on(this.parentWidget, 'hide', lang.hitch(this, 'onClose')); + } + if (this.parentWidget && this.parentWidget.declaredClass === 'gis.dijit.FloatingWidget' && this.openOnStartup) { + this.parentWidget.show(); + } + + this.inherited(arguments); + } + }); }); \ No newline at end of file diff --git a/viewer/js/gis/plugins/async.js b/viewer/js/gis/plugins/async.js index 97d8f22fc..4e63ab811 100644 --- a/viewer/js/gis/plugins/async.js +++ b/viewer/js/gis/plugins/async.js @@ -1,14 +1,14 @@ -/*global dojoConfig */ -/*jshint unused:true */ define(function () { + 'use strict'; + var cb = '_asyncApiLoaderCallback'; return { load: function (param, req, loadCallback) { if (!cb) { return; } else { - dojoConfig[cb] = function () { - delete dojoConfig[cb]; + window.dojoConfig[cb] = function () { + delete window.dojoConfig[cb]; cb = null; loadCallback(); }; diff --git a/viewer/js/viewer/Controller.js b/viewer/js/viewer/Controller.js index 0073c6967..f455607b4 100644 --- a/viewer/js/viewer/Controller.js +++ b/viewer/js/viewer/Controller.js @@ -1,573 +1,583 @@ +/*eslint no-console: 0*/ define([ - 'esri/map', - 'dojo/dom', - 'dojo/dom-style', - 'dojo/dom-geometry', - 'dojo/dom-class', - 'dojo/on', - 'dojo/_base/array', - 'dijit/layout/BorderContainer', - 'dijit/layout/ContentPane', - 'gis/dijit/FloatingTitlePane', - 'dojo/_base/lang', - 'dojo/text!./templates/mapOverlay.html', - 'gis/dijit/FloatingWidgetDialog', - 'put-selector', - 'dojo/aspect', - 'dojo/has', - 'dojo/topic', - 'esri/dijit/PopupMobile', - 'dijit/Menu', - 'esri/IdentityManager' + 'esri/map', + 'dojo/dom', + 'dojo/dom-style', + 'dojo/dom-geometry', + 'dojo/dom-class', + 'dojo/on', + 'dojo/_base/array', + 'dijit/layout/BorderContainer', + 'dijit/layout/ContentPane', + 'gis/dijit/FloatingTitlePane', + 'dojo/_base/lang', + 'dojo/text!./templates/mapOverlay.html', + 'gis/dijit/FloatingWidgetDialog', + 'put-selector', + 'dojo/aspect', + 'dojo/has', + 'dojo/topic', + 'esri/dijit/PopupMobile', + 'dijit/Menu', + 'esri/IdentityManager' ], function (Map, dom, domStyle, domGeom, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, lang, mapOverlay, FloatingWidgetDialog, put, aspect, has, topic, PopupMobile, Menu) { + 'use strict'; - return { - legendLayerInfos: [], - editorLayerInfos: [], - identifyLayerInfos: [], - layerControlLayerInfos: [], - panes: { - left: { - id: 'sidebarLeft', - placeAt: 'outer', - collapsible: true, - region: 'left' - }, - center: { - id: 'mapCenter', - placeAt: 'outer', - region: 'center', - content: mapOverlay - } - }, - collapseButtons: {}, - startup: function (config) { - this.config = config; - this.mapClickMode = { - current: config.defaultMapClickMode, - defaultMode: config.defaultMapClickMode - }; - // simple feature detection. kinda like dojox/mobile without the overhead - if (has('touch') && (has('ios') || has('android') || has('bb'))) { - has.add('mobile', true); - if (screen.availWidth < 500 || screen.availHeight < 500) { - has.add('phone', true); - } else { - has.add('tablet', true); - } - } - if (config.titles) { - this.addTitles(); - } - this.addTopics(); - this.initPanes(); + return { + legendLayerInfos: [], + editorLayerInfos: [], + identifyLayerInfos: [], + layerControlLayerInfos: [], + panes: { + left: { + id: 'sidebarLeft', + placeAt: 'outer', + collapsible: true, + region: 'left' + }, + center: { + id: 'mapCenter', + placeAt: 'outer', + region: 'center', + content: mapOverlay + } + }, + collapseButtons: {}, + startup: function (config) { + this.config = config; + this.mapClickMode = { + current: config.defaultMapClickMode, + defaultMode: config.defaultMapClickMode + }; + // simple feature detection. kinda like dojox/mobile without the overhead + if (has('touch') && (has('ios') || has('android') || has('bb'))) { + has.add('mobile', true); + if (screen.availWidth < 500 || screen.availHeight < 500) { + has.add('phone', true); + } else { + has.add('tablet', true); + } + } + if (config.titles) { + this.addTitles(); + } + this.addTopics(); + this.initPanes(); - if (config.isDebug) { - window.app = this; //dev only - } - }, - // add topics for subscribing and publishing - addTopics: function () { - // toggle a sidebar pane - topic.subscribe('viewer/togglePane', lang.hitch(this, function (args) { - this.togglePane(args.pane, args.show); - })); + if (config.isDebug) { + window.app = this; //dev only + } + }, + // add topics for subscribing and publishing + addTopics: function () { + // toggle a sidebar pane + topic.subscribe('viewer/togglePane', lang.hitch(this, function (args) { + this.togglePane(args.pane, args.show); + })); - // load a widget - topic.subscribe('viewer/loadWidget', lang.hitch(this, function (args) { - this.widgetLoader(args.options, args.position); - })); + // load a widget + topic.subscribe('viewer/loadWidget', lang.hitch(this, function (args) { + this.widgetLoader(args.options, args.position); + })); - // setup error handler. centralize the debugging - if (this.config.isDebug) { - topic.subscribe('viewer/handleError', lang.hitch(this, 'handleError')); - } + // setup error handler. centralize the debugging + if (this.config.isDebug) { + topic.subscribe('viewer/handleError', lang.hitch(this, 'handleError')); + } - // set the current mapClickMode - topic.subscribe('mapClickMode/setCurrent', lang.hitch(this, function (mode) { - this.mapClickMode.current = mode; - topic.publish('mapClickMode/currentSet', mode); - })); + // set the current mapClickMode + topic.subscribe('mapClickMode/setCurrent', lang.hitch(this, function (mode) { + this.mapClickMode.current = mode; + topic.publish('mapClickMode/currentSet', mode); + })); - // set the current mapClickMode to the default mode - topic.subscribe('mapClickMode/setDefault', lang.hitch(this, function () { - topic.publish('mapClickMode/setCurrent', this.mapClickMode.defaultMode); - })); + // set the current mapClickMode to the default mode + topic.subscribe('mapClickMode/setDefault', lang.hitch(this, function () { + topic.publish('mapClickMode/setCurrent', this.mapClickMode.defaultMode); + })); - }, - // set titles (if any) - addTitles: function () { - var titles = this.config.titles; - if (titles.header) { - var headerTitleNode = dom.byId('headerTitleSpan'); - if (headerTitleNode) { - headerTitleNode.innerHTML = titles.header; - } - } - if (titles.subHeader) { - var subHeaderTitle = dom.byId('subHeaderTitleSpan'); - if (subHeaderTitle) { - subHeaderTitle.innerHTML = titles.subHeader; - } - } - if (titles.pageTitle) { - document.title = titles.pageTitle; - } - }, - // setup all the sidebar panes - initPanes: function () { - var key, panes = this.config.panes || {}; - for (key in this.panes) { - if (this.panes.hasOwnProperty(key)) { - panes[key] = lang.mixin(this.panes[key], panes[key]); - } - } + }, + // set titles (if any) + addTitles: function () { + var titles = this.config.titles; + if (titles.header) { + var headerTitleNode = dom.byId('headerTitleSpan'); + if (headerTitleNode) { + headerTitleNode.innerHTML = titles.header; + } + } + if (titles.subHeader) { + var subHeaderTitle = dom.byId('subHeaderTitleSpan'); + if (subHeaderTitle) { + subHeaderTitle.innerHTML = titles.subHeader; + } + } + if (titles.pageTitle) { + document.title = titles.pageTitle; + } + }, + // setup all the sidebar panes + initPanes: function () { + var key, + panes = this.config.panes || {}; + for (key in this.panes) { + if (this.panes.hasOwnProperty(key)) { + panes[key] = lang.mixin(this.panes[key], panes[key]); + } + } - this.panes.outer = new BorderContainer({ - id: 'borderContainerOuter', - design: 'sidebar', - gutters: false - }).placeAt(document.body); + this.panes.outer = new BorderContainer({ + id: 'borderContainerOuter', + design: 'sidebar', + gutters: false + }).placeAt(document.body); - var options, placeAt, type; - for (key in panes) { - if (panes.hasOwnProperty(key)) { - options = lang.clone(panes[key]); - placeAt = this.panes[options.placeAt] || this.panes.outer; - options.id = options.id || key; - type = options.type; - delete options.placeAt; - delete options.type; - delete options.collapsible; - if (placeAt) { - if (type === 'border') { - this.panes[key] = new BorderContainer(options).placeAt(placeAt); - } else if (options.region) { - this.panes[key] = new ContentPane(options).placeAt(placeAt); - } - } - } - } - this.panes.outer.startup(); - this.initMap(); + var options, placeAt, type; + for (key in panes) { + if (panes.hasOwnProperty(key)) { + options = lang.clone(panes[key]); + placeAt = this.panes[options.placeAt] || this.panes.outer; + options.id = options.id || key; + type = options.type; + delete options.placeAt; + delete options.type; + delete options.collapsible; + if (placeAt) { + if (type === 'border') { + this.panes[key] = new BorderContainer(options).placeAt(placeAt); + } else if (options.region) { + this.panes[key] = new ContentPane(options).placeAt(placeAt); + } + } + } + } + this.panes.outer.startup(); + this.initMap(); + this.createPanes(panes); - // where to place the buttons - // either the center map pane or the outer pane? - this.collapseButtonsPane = this.config.collapseButtonsPane || 'outer'; + this.panes.outer.resize(); + }, - for (key in panes) { - if (panes.hasOwnProperty(key)) { - if (panes[key].collapsible) { - this.collapseButtons[key] = put(this.panes[this.collapseButtonsPane].domNode, 'div.sidebarCollapseButton.sidebar' + key + 'CollapseButton.sidebarCollapseButton' + ((key === 'bottom' || key === 'top') ? 'Vert' : 'Horz') + ' div.dijitIcon.button.close').parentNode; - on(this.collapseButtons[key], 'click', lang.hitch(this, 'togglePane', key)); - this.positionSideBarToggle(key); - if (this.collapseButtonsPane === 'outer') { - var splitter = this.panes[key]._splitterWidget; - if (splitter) { - aspect.after(splitter, '_startDrag', lang.hitch(this, 'splitterStartDrag', key)); - aspect.after(splitter, '_stopDrag', lang.hitch(this, 'splitterStopDrag', key)); - } - } - if (panes[key].open !== undefined) { - this.togglePane(key, panes[key].open); - } - } - if (key !== 'center' && this.panes[key]._splitterWidget) { - domClass.add(this.map.root.parentNode, 'pane' + key); - if (key === 'right' && this.panes.top) { - domClass.add(this.panes.top.domNode, 'pane' + key); - } - if (key === 'right' && this.panes.bottom) { - domClass.add(this.panes.bottom.domNode, 'pane' + key); - } - if (key === 'left' && this.panes.top) { - domClass.add(this.panes.top.domNode, 'pane' + key); - } - if (key === 'left' && this.panes.bottom) { - domClass.add(this.panes.bottom.domNode, 'pane' + key); - } - } - } - } + createPanes: function (panes) { + var key; + // where to place the buttons + // either the center map pane or the outer pane? + this.collapseButtonsPane = this.config.collapseButtonsPane || 'outer'; - // respond to media query changes - // matchMedia works in most browsers (http://caniuse.com/#feat=matchmedia) - if (window.matchMedia) { - window.matchMedia('(max-width: 991px)').addListener(lang.hitch(this, 'repositionSideBarButtons')); - window.matchMedia('(max-width: 767px)').addListener(lang.hitch(this, 'repositionSideBarButtons')); - } + for (key in panes) { + if (panes.hasOwnProperty(key)) { + if (panes[key].collapsible) { + this.collapseButtons[key] = put(this.panes[this.collapseButtonsPane].domNode, 'div.sidebarCollapseButton.sidebar' + key + 'CollapseButton.sidebarCollapseButton' + ((key === 'bottom' || key === 'top') ? 'Vert' : 'Horz') + ' div.dijitIcon.button.close').parentNode; + on(this.collapseButtons[key], 'click', lang.hitch(this, 'togglePane', key)); + this.positionSideBarToggle(key); + if (this.collapseButtonsPane === 'outer') { + var splitter = this.panes[key]._splitterWidget; + if (splitter) { + aspect.after(splitter, '_startDrag', lang.hitch(this, 'splitterStartDrag', key)); + aspect.after(splitter, '_stopDrag', lang.hitch(this, 'splitterStopDrag', key)); + } + } + if (panes[key].open !== undefined) { + this.togglePane(key, panes[key].open); + } + } + if (key !== 'center' && this.panes[key]._splitterWidget) { + domClass.add(this.map.root.parentNode, 'pane' + key); + if (key === 'right' && this.panes.top) { + domClass.add(this.panes.top.domNode, 'pane' + key); + } + if (key === 'right' && this.panes.bottom) { + domClass.add(this.panes.bottom.domNode, 'pane' + key); + } + if (key === 'left' && this.panes.top) { + domClass.add(this.panes.top.domNode, 'pane' + key); + } + if (key === 'left' && this.panes.bottom) { + domClass.add(this.panes.bottom.domNode, 'pane' + key); + } + } + } + } - this.panes.outer.resize(); - }, - initMap: function () { - if (has('phone') && !this.config.mapOptions.infoWindow) { - this.config.mapOptions.infoWindow = new PopupMobile(null, put('div')); - } - this.map = new Map('mapCenter', this.config.mapOptions); - if (this.config.mapOptions.basemap) { - this.map.on('load', lang.hitch(this, 'initLayers')); - } else { - this.initLayers(); - } - if (this.config.operationalLayers && this.config.operationalLayers.length > 0) { - on.once(this.map, 'layers-add-result', lang.hitch(this, 'initWidgets')); - } else { - this.initWidgets(); - } - }, - initLayers: function () { - this.map.on('resize', function (evt) { - var pnt = evt.target.extent.getCenter(); - setTimeout(function () { - evt.target.centerAt(pnt); - }, 100); - }); + }, - this.layers = []; - var layerTypes = { - csv: 'CSV', - dataadapter: 'DataAdapterFeature', //untested - dynamic: 'ArcGISDynamicMapService', - feature: 'Feature', - georss: 'GeoRSS', - image: 'ArcGISImageService', - imagevector: 'ArcGISImageServiceVector', - kml: 'KML', - label: 'Label', //untested - mapimage: 'MapImage', //untested - osm: 'OpenStreetMap', - raster: 'Raster', - stream: 'Stream', - tiled: 'ArcGISTiledMapService', - webtiled: 'WebTiled', - wms: 'WMS', - wmts: 'WMTS' //untested - }; - // loading all the required modules first ensures the layer order is maintained - var modules = []; - array.forEach(this.config.operationalLayers, function (layer) { - var type = layerTypes[layer.type]; - if (type) { - modules.push('esri/layers/' + type + 'Layer'); - } else { - this.handleError({ - source: 'Controller', - error: 'Layer type "' + layer.type + '"" isnot supported: ' - }); - } - }, this); - require(modules, lang.hitch(this, function () { - array.forEach(this.config.operationalLayers, function (layer) { - var type = layerTypes[layer.type]; - if (type) { - require(['esri/layers/' + type + 'Layer'], lang.hitch(this, 'initLayer', layer)); - } - }, this); - this.map.addLayers(this.layers); - })); - }, - initLayer: function (layer, Layer) { - var l = new Layer(layer.url, layer.options); - this.layers.unshift(l); //unshift instead of push to keep layer ordering on map intact - //Legend LayerInfos array - var excludeLayerFromLegend = false; - if ( typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.exclude !== 'undefined' ) { + initMap: function () { + if (has('phone') && !this.config.mapOptions.infoWindow) { + this.config.mapOptions.infoWindow = new PopupMobile(null, put('div')); + } + this.map = new Map('mapCenter', this.config.mapOptions); + if (this.config.mapOptions.basemap) { + this.map.on('load', lang.hitch(this, 'initLayers')); + } else { + this.initLayers(); + } + if (this.config.operationalLayers && this.config.operationalLayers.length > 0) { + on.once(this.map, 'layers-add-result', lang.hitch(this, 'initWidgets')); + } else { + this.initWidgets(); + } + }, + initLayers: function () { + this.map.on('resize', function (evt) { + var pnt = evt.target.extent.getCenter(); + setTimeout(function () { + evt.target.centerAt(pnt); + }, 100); + }); + + this.layers = []; + var layerTypes = { + csv: 'CSV', + dataadapter: 'DataAdapterFeature', //untested + dynamic: 'ArcGISDynamicMapService', + feature: 'Feature', + georss: 'GeoRSS', + image: 'ArcGISImageService', + imagevector: 'ArcGISImageServiceVector', + kml: 'KML', + label: 'Label', //untested + mapimage: 'MapImage', //untested + osm: 'OpenStreetMap', + raster: 'Raster', + stream: 'Stream', + tiled: 'ArcGISTiledMapService', + webtiled: 'WebTiled', + wms: 'WMS', + wmts: 'WMTS' //untested + }; + // loading all the required modules first ensures the layer order is maintained + var modules = []; + array.forEach(this.config.operationalLayers, function (layer) { + var type = layerTypes[layer.type]; + if (type) { + modules.push('esri/layers/' + type + 'Layer'); + } else { + this.handleError({ + source: 'Controller', + error: 'Layer type "' + layer.type + '"" isnot supported: ' + }); + } + }, this); + require(modules, lang.hitch(this, function () { + array.forEach(this.config.operationalLayers, function (layer) { + var type = layerTypes[layer.type]; + if (type) { + require(['esri/layers/' + type + 'Layer'], lang.hitch(this, 'initLayer', layer)); + } + }, this); + this.map.addLayers(this.layers); + })); + }, + initLayer: function (layer, Layer) { + var l = new Layer(layer.url, layer.options); + this.layers.unshift(l); //unshift instead of push to keep layer ordering on map intact + //Legend LayerInfos array + var excludeLayerFromLegend = false; + if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.exclude !== 'undefined') { excludeLayerFromLegend = layer.legendLayerInfos.exclude; } - if ( !excludeLayerFromLegend ) { + if (!excludeLayerFromLegend) { var configuredLayerInfo = {}; - if ( typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.layerInfo !== 'undefined' ) { + if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.layerInfo !== 'undefined') { configuredLayerInfo = layer.legendLayerInfos.layerInfo; } - var layerInfo = lang.mixin( { + var layerInfo = lang.mixin({ layer: l, title: layer.title || null - }, configuredLayerInfo ); - this.legendLayerInfos.unshift ( layerInfo ); //unshift instead of push to keep layer ordering in legend intact - } - //LayerControl LayerInfos array - this.layerControlLayerInfos.unshift({ //unshift instead of push to keep layer ordering in LayerControl intact - layer: l, - type: layer.type, - title: layer.title, - controlOptions: layer.layerControlLayerInfos - }); - if (layer.type === 'feature') { - var options = { - featureLayer: l - }; - if (layer.editorLayerInfos) { - lang.mixin(options, layer.editorLayerInfos); - } - if (options.exclude !== true) { - this.editorLayerInfos.push(options); - } - } - if (layer.type === 'dynamic' || layer.type === 'feature') { - var idOptions = { - layer: l, - title: layer.title - }; - if (layer.identifyLayerInfos) { - lang.mixin(idOptions, layer.identifyLayerInfos); - } - if (idOptions.exclude !== true) { - this.identifyLayerInfos.push(idOptions); - } - } - }, - initWidgets: function () { - var widgets = [], - paneWidgets; + }, configuredLayerInfo); + this.legendLayerInfos.unshift(layerInfo); //unshift instead of push to keep layer ordering in legend intact + } + //LayerControl LayerInfos array + this.layerControlLayerInfos.unshift({ //unshift instead of push to keep layer ordering in LayerControl intact + layer: l, + type: layer.type, + title: layer.title, + controlOptions: layer.layerControlLayerInfos + }); + if (layer.type === 'feature') { + var options = { + featureLayer: l + }; + if (layer.editorLayerInfos) { + lang.mixin(options, layer.editorLayerInfos); + } + if (options.exclude !== true) { + this.editorLayerInfos.push(options); + } + } + if (layer.type === 'dynamic' || layer.type === 'feature') { + var idOptions = { + layer: l, + title: layer.title + }; + if (layer.identifyLayerInfos) { + lang.mixin(idOptions, layer.identifyLayerInfos); + } + if (idOptions.exclude !== true) { + this.identifyLayerInfos.push(idOptions); + } + } + }, + initWidgets: function () { + var widgets = [], + paneWidgets; + + for (var key in this.config.widgets) { + if (this.config.widgets.hasOwnProperty(key)) { + var widget = lang.clone(this.config.widgets[key]); + if (widget.include) { + widget.position = (typeof (widget.position) !== 'undefined') ? widget.position : 10000; + widgets.push(widget); + } + } + } + + function getPaneWidgets (pane) { + paneWidgets = array.filter(widgets, function (paneWidget) { + return (paneWidget.placeAt && paneWidget.placeAt === pane); + }); + return paneWidgets; + } - for (var key in this.config.widgets) { - if (this.config.widgets.hasOwnProperty(key)) { - var widget = lang.clone(this.config.widgets[key]); - if (widget.include) { - widget.position = ('undefined' !== typeof (widget.position)) ? widget.position : 10000; - widgets.push(widget); - } - } - } - for (var pane in this.panes) { - if (this.panes.hasOwnProperty(pane) && (pane !== 'outer' || pane !== 'center')) { - paneWidgets = array.filter(widgets, function (widget) { - return (widget.placeAt && widget.placeAt === pane); - }); - paneWidgets.sort(function (a, b) { - return a.position - b.position; - }); - array.forEach(paneWidgets, function (widget, i) { - this.widgetLoader(widget, i); - }, this); - } - } - paneWidgets = array.filter(widgets, function (widget) { - return !widget.placeAt; - }); - paneWidgets.sort(function (a, b) { - return a.position - b.position; - }); + for (var pane in this.panes) { + if (this.panes.hasOwnProperty(pane) && (pane !== 'outer' || pane !== 'center')) { + paneWidgets = getPaneWidgets(pane); + paneWidgets.sort(function (a, b) { + return a.position - b.position; + }); + array.forEach(paneWidgets, function (paneWidget, i) { + this.widgetLoader(paneWidget, i); + }, this); + } + } + paneWidgets = array.filter(widgets, function (paneWidget) { + return !paneWidget.placeAt; + }); + paneWidgets.sort(function (a, b) { + return a.position - b.position; + }); - array.forEach(paneWidgets, function (widget, i) { - this.widgetLoader(widget, i); - }, this); - }, - togglePane: function (id, show) { - if (!this.panes[id]) { - return; - } - var domNode = this.panes[id].domNode; - if (domNode) { - var disp = (show && typeof (show) === 'string') ? show : (domStyle.get(domNode, 'display') === 'none') ? 'block' : 'none'; - domStyle.set(domNode, 'display', disp); - if (this.panes[id]._splitterWidget) { // show/hide the splitter, if found - domStyle.set(this.panes[id]._splitterWidget.domNode, 'display', disp); - } - this.positionSideBarToggle(id); - if (this.panes.outer) { - this.panes.outer.resize(); - } - } - }, - positionSideBarToggle: function (id) { - var pane = this.panes[id]; - var btn = this.collapseButtons[id]; - if (!pane || !btn) { - return; - } - var disp = domStyle.get(pane.domNode, 'display'); - var rCls = (disp === 'none') ? 'close' : 'open'; - var aCls = (disp === 'none') ? 'open' : 'close'; - domClass.remove(btn.children[0], rCls); - domClass.add(btn.children[0], aCls); + array.forEach(paneWidgets, function (paneWidget, i) { + this.widgetLoader(paneWidget, i); + }, this); + }, + togglePane: function (id, show) { + if (!this.panes[id]) { + return; + } + var domNode = this.panes[id].domNode; + if (domNode) { + var disp = (show && typeof (show) === 'string') ? show : (domStyle.get(domNode, 'display') === 'none') ? 'block' : 'none'; + domStyle.set(domNode, 'display', disp); + if (this.panes[id]._splitterWidget) { // show/hide the splitter, if found + domStyle.set(this.panes[id]._splitterWidget.domNode, 'display', disp); + } + this.positionSideBarToggle(id); + if (this.panes.outer) { + this.panes.outer.resize(); + } + } + }, + positionSideBarToggle: function (id) { + var pane = this.panes[id]; + var btn = this.collapseButtons[id]; + if (!pane || !btn) { + return; + } + var disp = domStyle.get(pane.domNode, 'display'); + var rCls = (disp === 'none') ? 'close' : 'open'; + var aCls = (disp === 'none') ? 'open' : 'close'; + domClass.remove(btn.children[0], rCls); + domClass.add(btn.children[0], aCls); - // extra management required when the buttons - // are not in the center map pane - if (this.collapseButtonsPane === 'outer') { - var pos = (pane._splitterWidget) ? 0 : -1; - var orie = (id === 'bottom' || id === 'top') ? 'h' : 'w'; - if (disp === 'block') { // pane is open - pos += domGeom.getMarginBox(pane.domNode)[orie]; - } - if (pane._splitterWidget) { // account for a splitter - pos += domGeom.getMarginBox(pane._splitterWidget.domNode)[orie]; - } - domStyle.set(btn, id, pos.toString() + 'px'); - domStyle.set(btn, 'display', 'block'); - } - }, + // extra management required when the buttons + // are not in the center map pane + if (this.collapseButtonsPane === 'outer') { + var pos = (pane._splitterWidget) ? 0 : -1; + var orie = (id === 'bottom' || id === 'top') ? 'h' : 'w'; + if (disp === 'block') { // pane is open + pos += domGeom.getMarginBox(pane.domNode)[orie]; + } + if (pane._splitterWidget) { // account for a splitter + pos += domGeom.getMarginBox(pane._splitterWidget.domNode)[orie]; + } + domStyle.set(btn, id, pos.toString() + 'px'); + domStyle.set(btn, 'display', 'block'); + } + }, - repositionSideBarButtons: function () { - var btns = ['left', 'right', 'top', 'bottom']; - array.forEach(btns, lang.hitch(this, function (id) { - this.positionSideBarToggle(id); - })); - }, + repositionSideBarButtons: function () { + var btns = ['left', 'right', 'top', 'bottom']; + array.forEach(btns, lang.hitch(this, function (id) { + this.positionSideBarToggle(id); + })); + }, - // extra management of splitters required when the buttons - // are not in the center map pane - splitterStartDrag: function (id) { - var btn = this.collapseButtons[id]; - domStyle.set(btn, 'display', 'none'); - }, - splitterStopDrag: function (id) { - this.positionSideBarToggle(id); - }, + // extra management of splitters required when the buttons + // are not in the center map pane + splitterStartDrag: function (id) { + var btn = this.collapseButtons[id]; + domStyle.set(btn, 'display', 'none'); + }, + splitterStopDrag: function (id) { + this.positionSideBarToggle(id); + }, - _createTitlePaneWidget: function (parentId, title, position, open, canFloat, placeAt) { - var tp, options = { - title: title || 'Widget', - open: open || false, - canFloat: canFloat || false - }; - if (parentId) { - options.id = parentId; - } - if (typeof (placeAt) === 'string') { - placeAt = this.panes[placeAt]; - } - if (!placeAt) { - placeAt = this.panes.left; - } - if (placeAt) { - options.sidebar = placeAt; - tp = new FloatingTitlePane(options).placeAt(placeAt, position); - tp.startup(); - } - return tp; - }, - _createFloatingWidget: function (parentId, title) { - var options = { - title: title - }; - if (parentId) { - options.id = parentId; - } - var fw = new FloatingWidgetDialog(options); - fw.startup(); - return fw; - }, - _createContentPaneWidget: function (parentId, title, className, region, placeAt) { - var cp, options = { - title: title, - region: region || 'center' - }; - if (className) { - options.className = className; - } - if (parentId) { - options.id = parentId; - } - if (!placeAt) { - placeAt = this.panes.sidebar; - } else if (typeof (placeAt) === 'string') { - placeAt = this.panes[placeAt]; - } - if (placeAt) { - cp = new ContentPane(options).placeAt(placeAt); - cp.startup(); - } - return cp; - }, - widgetLoader: function (widgetConfig, position) { - var parentId, pnl; + _createTitlePaneWidget: function (parentId, title, position, open, canFloat, placeAt) { + var tp, + options = { + title: title || 'Widget', + open: open || false, + canFloat: canFloat || false + }; + if (parentId) { + options.id = parentId; + } + if (typeof (placeAt) === 'string') { + placeAt = this.panes[placeAt]; + } + if (!placeAt) { + placeAt = this.panes.left; + } + if (placeAt) { + options.sidebar = placeAt; + tp = new FloatingTitlePane(options).placeAt(placeAt, position); + tp.startup(); + } + return tp; + }, + _createFloatingWidget: function (parentId, title) { + var options = { + title: title + }; + if (parentId) { + options.id = parentId; + } + var fw = new FloatingWidgetDialog(options); + fw.startup(); + return fw; + }, + _createContentPaneWidget: function (parentId, title, className, region, placeAt) { + var cp, + options = { + title: title, + region: region || 'center' + }; + if (className) { + options.className = className; + } + if (parentId) { + options.id = parentId; + } + if (!placeAt) { + placeAt = this.panes.sidebar; + } else if (typeof (placeAt) === 'string') { + placeAt = this.panes[placeAt]; + } + if (placeAt) { + cp = new ContentPane(options).placeAt(placeAt); + cp.startup(); + } + return cp; + }, + widgetLoader: function (widgetConfig, position) { + var parentId, pnl; - // only proceed for valid widget types - var widgetTypes = ['titlePane', 'contentPane', 'floating', 'domNode', 'invisible', 'map']; - if (array.indexOf(widgetTypes, widgetConfig.type) < 0) { - this.handleError({ - source: 'Controller', - error: 'Widget type "' + widgetConfig.type + '" (' + widgetConfig.title + ') at position ' + position + ' is not supported.' - }); - return; - } + // only proceed for valid widget types + var widgetTypes = ['titlePane', 'contentPane', 'floating', 'domNode', 'invisible', 'map']; + if (array.indexOf(widgetTypes, widgetConfig.type) < 0) { + this.handleError({ + source: 'Controller', + error: 'Widget type "' + widgetConfig.type + '" (' + widgetConfig.title + ') at position ' + position + ' is not supported.' + }); + return; + } - // build a titlePane or floating widget as the parent - if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating') && (widgetConfig.id && widgetConfig.id.length > 0)) { - parentId = widgetConfig.id + '_parent'; - if (widgetConfig.type === 'titlePane') { - pnl = this._createTitlePaneWidget(parentId, widgetConfig.title, position, widgetConfig.open, widgetConfig.canFloat, widgetConfig.placeAt); - } else if (widgetConfig.type === 'contentPane') { - pnl = this._createContentPaneWidget(parentId, widgetConfig.title, widgetConfig.className, widgetConfig.region, widgetConfig.placeAt); - } else if (widgetConfig.type === 'floating') { - pnl = this._createFloatingWidget(parentId, widgetConfig.title); - } - widgetConfig.parentWidget = pnl; - } + // build a titlePane or floating widget as the parent + if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating') && (widgetConfig.id && widgetConfig.id.length > 0)) { + parentId = widgetConfig.id + '_parent'; + if (widgetConfig.type === 'titlePane') { + pnl = this._createTitlePaneWidget(parentId, widgetConfig.title, position, widgetConfig.open, widgetConfig.canFloat, widgetConfig.placeAt); + } else if (widgetConfig.type === 'contentPane') { + pnl = this._createContentPaneWidget(parentId, widgetConfig.title, widgetConfig.className, widgetConfig.region, widgetConfig.placeAt); + } else if (widgetConfig.type === 'floating') { + pnl = this._createFloatingWidget(parentId, widgetConfig.title); + } + widgetConfig.parentWidget = pnl; + } - // 2 ways to use require to accommodate widgets that may have an optional separate configuration file - if (typeof (widgetConfig.options) === 'string') { - require([widgetConfig.options, widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig)); - } else { - require([widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig, widgetConfig.options)); - } - }, - createWidget: function (widgetConfig, options, WidgetClass) { - // set any additional options - options.id = widgetConfig.id + '_widget'; - options.parentWidget = widgetConfig.parentWidget; + // 2 ways to use require to accommodate widgets that may have an optional separate configuration file + if (typeof (widgetConfig.options) === 'string') { + require([widgetConfig.options, widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig)); + } else { + require([widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig, widgetConfig.options)); + } + }, + createWidget: function (widgetConfig, options, WidgetClass) { + // set any additional options + options.id = widgetConfig.id + '_widget'; + options.parentWidget = widgetConfig.parentWidget; - //replace config map, layerInfos arrays, etc - if (options.map) { - options.map = this.map; - } - if (options.mapRightClickMenu) { - // create right-click menu - if (!this.mapRightClickMenu) { - this.mapRightClickMenu = new Menu({ - targetNodeIds: [this.map.root], - selector: '.layersDiv' // restrict to map only - }); - this.mapRightClickMenu.startup(); - } - options.mapRightClickMenu = this.mapRightClickMenu; - } - if (options.mapClickMode) { - options.mapClickMode = this.mapClickMode.current; - } - if (options.legendLayerInfos) { - options.layerInfos = this.legendLayerInfos; - } - if (options.layerControlLayerInfos) { - options.layerInfos = this.layerControlLayerInfos; - } - if (options.editorLayerInfos) { - options.layerInfos = this.editorLayerInfos; - } - if (options.identifyLayerInfos) { - options.layerInfos = this.identifyLayerInfos; - } + //replace config map, layerInfos arrays, etc + if (options.map) { + options.map = this.map; + } + if (options.mapRightClickMenu) { + // create right-click menu + if (!this.mapRightClickMenu) { + this.mapRightClickMenu = new Menu({ + targetNodeIds: [this.map.root], + selector: '.layersDiv' // restrict to map only + }); + this.mapRightClickMenu.startup(); + } + options.mapRightClickMenu = this.mapRightClickMenu; + } + if (options.mapClickMode) { + options.mapClickMode = this.mapClickMode.current; + } + if (options.legendLayerInfos) { + options.layerInfos = this.legendLayerInfos; + } + if (options.layerControlLayerInfos) { + options.layerInfos = this.layerControlLayerInfos; + } + if (options.editorLayerInfos) { + options.layerInfos = this.editorLayerInfos; + } + if (options.identifyLayerInfos) { + options.layerInfos = this.identifyLayerInfos; + } - // create the widget - var pnl = options.parentWidget; - if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating')) { - this[widgetConfig.id] = new WidgetClass(options, put('div')).placeAt(pnl.containerNode); - } else if (widgetConfig.type === 'domNode') { - this[widgetConfig.id] = new WidgetClass(options, widgetConfig.srcNodeRef); - } else { - this[widgetConfig.id] = new WidgetClass(options); - } + // create the widget + var pnl = options.parentWidget; + if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating')) { + this[widgetConfig.id] = new WidgetClass(options, put('div')).placeAt(pnl.containerNode); + } else if (widgetConfig.type === 'domNode') { + this[widgetConfig.id] = new WidgetClass(options, widgetConfig.srcNodeRef); + } else { + this[widgetConfig.id] = new WidgetClass(options); + } - // start up the widget - if (this[widgetConfig.id] && this[widgetConfig.id].startup && !this[widgetConfig.id]._started) { - this[widgetConfig.id].startup(); - } - }, - //centralized error handler - handleError: function (options) { - if (this.config.isDebug) { - if (typeof (console) === 'object') { - for (var option in options) { - if (options.hasOwnProperty(option)) { - console.log(option, options[option]); - } - } - } - } else { - // add growler here? - return; - } - } - }; + // start up the widget + if (this[widgetConfig.id] && this[widgetConfig.id].startup && !this[widgetConfig.id]._started) { + this[widgetConfig.id].startup(); + } + }, + //centralized error handler + handleError: function (options) { + if (this.config.isDebug) { + if (typeof (console) === 'object') { + for (var option in options) { + if (options.hasOwnProperty(option)) { + console.log(option, options[option]); + } + } + } + } else { + // add growler here? + return; + } + } + }; }); \ No newline at end of file From e9e8f5a530cea8540d542c08b0e32a6383f6ce87 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 25 Oct 2015 17:53:24 -0700 Subject: [PATCH 014/216] Added 'sudo: false' so travis builds start and execute faster using new container-based infrastructure. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 1f46d5c9f..cec756b2c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ language: node_js node_js: - '0.10' +sudo: false before_install: npm install -g grunt-cli before_script: grunt build --verbose deploy: From 28fc8f91a9f59d1569e3cd09954bb20d5fa6f599 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 25 Oct 2015 18:01:23 -0700 Subject: [PATCH 015/216] removed `eslint-stylish` since this cause travis build fail eslint-stylish is now included with eslint so should not be required. --- Gruntfile.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index d9bab2a13..42fe32a32 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -72,8 +72,7 @@ module.exports = function (grunt) { build: { src: ['viewer/**/*.js'], options: { - eslintrc: '.eslintrc', - reporter: require('eslint-stylish') + eslintrc: '.eslintrc' } } }, From 76dfb7b17d3901e35a8ff6665393e0753088217b Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 25 Oct 2015 18:05:04 -0700 Subject: [PATCH 016/216] Add 2 intentional eslint errors to verify the travis build process will fail when elint fails. --- viewer/js/viewer/Controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/js/viewer/Controller.js b/viewer/js/viewer/Controller.js index f455607b4..2b0e49c11 100644 --- a/viewer/js/viewer/Controller.js +++ b/viewer/js/viewer/Controller.js @@ -20,10 +20,10 @@ define([ 'esri/dijit/PopupMobile', 'dijit/Menu', 'esri/IdentityManager' -], function (Map, dom, domStyle, domGeom, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, lang, mapOverlay, FloatingWidgetDialog, put, aspect, has, topic, PopupMobile, Menu) { +], function(Map, dom, domStyle, domGeom, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, lang, mapOverlay, FloatingWidgetDialog, put, aspect, has, topic, PopupMobile, Menu) { 'use strict'; - return { + return{ legendLayerInfos: [], editorLayerInfos: [], identifyLayerInfos: [], From 2d1cc3887a62116bcc49943f7da1f8926f07fc2d Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 25 Oct 2015 18:08:36 -0700 Subject: [PATCH 017/216] reverting previously placed intentional errors. travis build failed as expected with errors listed in build job log. --- viewer/js/viewer/Controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/js/viewer/Controller.js b/viewer/js/viewer/Controller.js index 2b0e49c11..f455607b4 100644 --- a/viewer/js/viewer/Controller.js +++ b/viewer/js/viewer/Controller.js @@ -20,10 +20,10 @@ define([ 'esri/dijit/PopupMobile', 'dijit/Menu', 'esri/IdentityManager' -], function(Map, dom, domStyle, domGeom, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, lang, mapOverlay, FloatingWidgetDialog, put, aspect, has, topic, PopupMobile, Menu) { +], function (Map, dom, domStyle, domGeom, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, lang, mapOverlay, FloatingWidgetDialog, put, aspect, has, topic, PopupMobile, Menu) { 'use strict'; - return{ + return { legendLayerInfos: [], editorLayerInfos: [], identifyLayerInfos: [], From 15cbd8ef6e414c732cacdc8bf9c018a617eeb8f9 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 26 Oct 2015 17:56:39 -0700 Subject: [PATCH 018/216] add csslint --- .csslintrc | 38 ++++++++++++++++++++++++++++++++++++++ Gruntfile.js | 23 ++++++++++++++++++----- package.json | 2 ++ 3 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 .csslintrc diff --git a/.csslintrc b/.csslintrc new file mode 100644 index 000000000..d1dac24ba --- /dev/null +++ b/.csslintrc @@ -0,0 +1,38 @@ +/* https://github.com/CSSLint/csslint/wiki/Rules */ +{ + "important": false, + "adjoining-classes": false, + "known-properties": false, + "box-sizing": false, + "box-model": false, + "overqualified-elements": false, + "display-property-grouping": false, + "bulletproof-font-face": false, + "compatible-vendor-prefixes": false, + "regex-selectors": false, + "errors": true, + "duplicate-background-images": false, + "duplicate-properties": false, + "empty-rules": false, + "selector-max-approaching": false, + "gradients": false, + "fallback-colors": false, + "font-sizes": false, + "font-faces": false, + "floats": false, + "star-property-hack": false, + "outline-none": false, + "import": false, + "ids": false, + "underscore-property-hack": false, + "rules-count": false, + "qualified-headings": false, + "selector-max": false, + "shorthand": false, + "text-indent": false, + "unique-headings": false, + "universal-selector": false, + "unqualified-attributes": false, + "vendor-prefix": false, + "zero-units": false +} \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index 42fe32a32..76dd07503 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -68,6 +68,18 @@ module.exports = function (grunt) { } }, + csslint: { + strict: { + src: ['viewer/**/*.css', '!viewer/css/theme/**/*.css'] + }, + lax: { + src: ['viewer/**/*.css', '!viewer/css/theme/**/*.css'], + options: { + csslintrc: '.csslintrc' + } + } + }, + eslint: { build: { src: ['viewer/**/*.js'], @@ -99,11 +111,11 @@ module.exports = function (grunt) { watch: { dev: { files: ['viewer/**'], - tasks: ['jshint'] + tasks: ['eslint', 'csslint'] }, build: { files: ['dist/viewer/**'], - tasks: ['jshint'] + tasks: ['eshint', 'csslint'] } }, connect: { @@ -151,6 +163,7 @@ module.exports = function (grunt) { grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-autoprefixer'); grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-eslint'); grunt.loadNpmTasks('grunt-contrib-watch'); @@ -160,10 +173,10 @@ module.exports = function (grunt) { grunt.loadNpmTasks('grunt-contrib-compress'); // define the tasks - grunt.registerTask('default', 'Watches the project for changes, automatically builds them and runs a web server and opens default browser to preview.', ['eslint', 'connect:dev', 'open:dev_browser', 'watch:dev']); + grunt.registerTask('default', 'Watches the project for changes, automatically builds them and runs a web server and opens default browser to preview.', ['eslint', 'csslint:strict', 'connect:dev', 'open:dev_browser', 'watch:dev']); grunt.registerTask('build', 'Compiles all of the assets and copies the files to the build directory.', ['clean', 'copy', 'scripts', 'stylesheets', 'compress:build']); grunt.registerTask('build-view', 'Compiles all of the assets and copies the files to the build directory starts a web server and opens browser to preview app.', ['clean', 'copy', 'scripts', 'stylesheets', 'compress:build', 'connect:build', 'open:build_browser', 'watch:build']); grunt.registerTask('scripts', 'Compiles the JavaScript files.', ['eslint', 'uglify']); - grunt.registerTask('stylesheets', 'Auto prefixes css and compiles the stylesheets.', ['autoprefixer', 'cssmin']); - grunt.registerTask('hint', 'Run simple eslint.', ['eslint']); + grunt.registerTask('stylesheets', 'Auto prefixes css and compiles the stylesheets.', ['csslint:lax', 'autoprefixer', 'cssmin']); + grunt.registerTask('lint', 'Run eslint and csslint.', ['eslint', 'csslint:strict']); }; \ No newline at end of file diff --git a/package.json b/package.json index 2f5c6a243..2b71ed472 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "repository": "https://github.com/cmv/cmv-app/", "dependencies": { "babel-eslint": "4.1.x", + "csslint": "0.10.x", "eslint": "1.7.3", "grunt": "0.4.x", "grunt-autoprefixer": "0.7.x", @@ -15,6 +16,7 @@ "grunt-contrib-connect": "0.7.x", "grunt-contrib-copy": "0.5.x", "grunt-contrib-cssmin": "0.9.x", + "grunt-contrib-csslint": "0.5.x", "grunt-eslint": "17.3.x", "grunt-contrib-uglify": "0.4.x", "grunt-contrib-watch": "0.6.x", From 0203941d113eaedb6c9aacbc34450f98af39ea75 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Tue, 27 Oct 2015 19:40:21 -0700 Subject: [PATCH 019/216] Fixing conflict in StreetView.js from recent merge --- viewer/js/gis/dijit/StreetView.js | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index def05c9d8..5ba63ed57 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -1,7 +1,6 @@ /*global google */ /*eslint strict: 0*/ define([ -<<<<<<< HEAD 'dojo/_base/declare', 'dijit/_WidgetBase', 'dijit/_TemplatedMixin', @@ -18,28 +17,8 @@ define([ 'esri/geometry/Point', 'esri/SpatialReference', 'dijit/MenuItem', - '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js', + '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12/proj4.js', 'dojo/i18n!./StreetView/nls/resource', -======= - 'dojo/_base/declare', - 'dijit/_WidgetBase', - 'dijit/_TemplatedMixin', - 'dijit/_WidgetsInTemplateMixin', - 'dojo/_base/lang', - 'dojo/aspect', - 'dojo/topic', - 'esri/layers/GraphicsLayer', - 'esri/graphic', - 'esri/renderers/SimpleRenderer', - 'dojo/text!./StreetView/templates/StreetView.html', - 'esri/symbols/PictureMarkerSymbol', - 'dojo/dom-style', - 'esri/geometry/Point', - 'esri/SpatialReference', - 'dijit/MenuItem', - '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12/proj4.js', - 'dojo/i18n!./StreetView/nls/resource', ->>>>>>> develop 'dijit/form/Button', 'xstyle/css!./StreetView/css/StreetView.css', From b6932a1b9906f0b5b328c3ed425f6a97cc18c302 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Thu, 29 Oct 2015 15:03:02 -0700 Subject: [PATCH 020/216] refactor Controller with Mixins. --- viewer/js/config/app.js | 74 ++-- viewer/js/viewer/Controller.js | 583 ---------------------------- viewer/js/viewer/_ConfigMixin.js | 62 +++ viewer/js/viewer/_ControllerBase.js | 37 ++ viewer/js/viewer/_LayoutMixin.js | 294 ++++++++++++++ viewer/js/viewer/_MapMixin.js | 197 ++++++++++ viewer/js/viewer/_WidgetsMixin.js | 227 +++++++++++ 7 files changed, 866 insertions(+), 608 deletions(-) delete mode 100644 viewer/js/viewer/Controller.js create mode 100644 viewer/js/viewer/_ConfigMixin.js create mode 100644 viewer/js/viewer/_ControllerBase.js create mode 100644 viewer/js/viewer/_LayoutMixin.js create mode 100644 viewer/js/viewer/_MapMixin.js create mode 100644 viewer/js/viewer/_WidgetsMixin.js diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 7ba02bf62..fbd746e44 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -1,33 +1,57 @@ (function () { 'use strict'; - - // globel dojoConfig is required for async loading of gmaps api + var path = location.pathname.replace(/[^\/]+$/, ''); window.dojoConfig = { async: true, - packages: [{ - name: 'viewer', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/viewer' - }, { - name: 'config', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/config' - }, { - name: 'gis', - location: location.pathname.replace(/[^\/]+$/, '') + 'js/gis' - }] + packages: [ + { + name: 'viewer', + location: path + 'js/viewer' + }, { + name: 'gis', + location: path + 'js/gis' + }, { + name: 'config', + location: path + 'js/config' + } + ] }; - // get the config file from the url if present - var file = 'config/viewer', - s = window.location.search, - q = s.match(/config=([^&]*)/i); - if (q && q.length > 0) { - file = q[1]; - if (file.indexOf('/') < 0) { - file = 'config/' + file; - } - } - - require(window.dojoConfig, ['viewer/Controller', file, 'dojo/domReady!'], function (Controller, config) { - Controller.startup(config); + require(window.dojoConfig, [ + 'dojo/_base/declare', + + // minimal Base Controller + 'viewer/_ControllerBase', + + // *** Controller Mixins + // Use the core mixins, add custom mixins + // or replace core mixins with your own + 'viewer/_ConfigMixin', // manage the Configuration + 'viewer/_LayoutMixin', // build and manage the Page Layout and User Interface + 'viewer/_MapMixin', // build and manage the Map + 'viewer/_WidgetsMixin' // build and manage the Widgets + + //'config/_customMixin' + + ], function ( + declare, + + _ControllerBase, + _ConfigMixin, + _LayoutMixin, + _MapMixin, + _WidgetsMixin + + //_MyCustomMixin + + ) { + var controller = new (declare([ + _ControllerBase, + _ConfigMixin, + _LayoutMixin, + _MapMixin, + _WidgetsMixin + ]))(); + controller.startup(); }); })(); \ No newline at end of file diff --git a/viewer/js/viewer/Controller.js b/viewer/js/viewer/Controller.js deleted file mode 100644 index f455607b4..000000000 --- a/viewer/js/viewer/Controller.js +++ /dev/null @@ -1,583 +0,0 @@ -/*eslint no-console: 0*/ -define([ - 'esri/map', - 'dojo/dom', - 'dojo/dom-style', - 'dojo/dom-geometry', - 'dojo/dom-class', - 'dojo/on', - 'dojo/_base/array', - 'dijit/layout/BorderContainer', - 'dijit/layout/ContentPane', - 'gis/dijit/FloatingTitlePane', - 'dojo/_base/lang', - 'dojo/text!./templates/mapOverlay.html', - 'gis/dijit/FloatingWidgetDialog', - 'put-selector', - 'dojo/aspect', - 'dojo/has', - 'dojo/topic', - 'esri/dijit/PopupMobile', - 'dijit/Menu', - 'esri/IdentityManager' -], function (Map, dom, domStyle, domGeom, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, lang, mapOverlay, FloatingWidgetDialog, put, aspect, has, topic, PopupMobile, Menu) { - 'use strict'; - - return { - legendLayerInfos: [], - editorLayerInfos: [], - identifyLayerInfos: [], - layerControlLayerInfos: [], - panes: { - left: { - id: 'sidebarLeft', - placeAt: 'outer', - collapsible: true, - region: 'left' - }, - center: { - id: 'mapCenter', - placeAt: 'outer', - region: 'center', - content: mapOverlay - } - }, - collapseButtons: {}, - startup: function (config) { - this.config = config; - this.mapClickMode = { - current: config.defaultMapClickMode, - defaultMode: config.defaultMapClickMode - }; - // simple feature detection. kinda like dojox/mobile without the overhead - if (has('touch') && (has('ios') || has('android') || has('bb'))) { - has.add('mobile', true); - if (screen.availWidth < 500 || screen.availHeight < 500) { - has.add('phone', true); - } else { - has.add('tablet', true); - } - } - if (config.titles) { - this.addTitles(); - } - this.addTopics(); - this.initPanes(); - - if (config.isDebug) { - window.app = this; //dev only - } - }, - // add topics for subscribing and publishing - addTopics: function () { - // toggle a sidebar pane - topic.subscribe('viewer/togglePane', lang.hitch(this, function (args) { - this.togglePane(args.pane, args.show); - })); - - // load a widget - topic.subscribe('viewer/loadWidget', lang.hitch(this, function (args) { - this.widgetLoader(args.options, args.position); - })); - - // setup error handler. centralize the debugging - if (this.config.isDebug) { - topic.subscribe('viewer/handleError', lang.hitch(this, 'handleError')); - } - - // set the current mapClickMode - topic.subscribe('mapClickMode/setCurrent', lang.hitch(this, function (mode) { - this.mapClickMode.current = mode; - topic.publish('mapClickMode/currentSet', mode); - })); - - // set the current mapClickMode to the default mode - topic.subscribe('mapClickMode/setDefault', lang.hitch(this, function () { - topic.publish('mapClickMode/setCurrent', this.mapClickMode.defaultMode); - })); - - }, - // set titles (if any) - addTitles: function () { - var titles = this.config.titles; - if (titles.header) { - var headerTitleNode = dom.byId('headerTitleSpan'); - if (headerTitleNode) { - headerTitleNode.innerHTML = titles.header; - } - } - if (titles.subHeader) { - var subHeaderTitle = dom.byId('subHeaderTitleSpan'); - if (subHeaderTitle) { - subHeaderTitle.innerHTML = titles.subHeader; - } - } - if (titles.pageTitle) { - document.title = titles.pageTitle; - } - }, - // setup all the sidebar panes - initPanes: function () { - var key, - panes = this.config.panes || {}; - for (key in this.panes) { - if (this.panes.hasOwnProperty(key)) { - panes[key] = lang.mixin(this.panes[key], panes[key]); - } - } - - this.panes.outer = new BorderContainer({ - id: 'borderContainerOuter', - design: 'sidebar', - gutters: false - }).placeAt(document.body); - - var options, placeAt, type; - for (key in panes) { - if (panes.hasOwnProperty(key)) { - options = lang.clone(panes[key]); - placeAt = this.panes[options.placeAt] || this.panes.outer; - options.id = options.id || key; - type = options.type; - delete options.placeAt; - delete options.type; - delete options.collapsible; - if (placeAt) { - if (type === 'border') { - this.panes[key] = new BorderContainer(options).placeAt(placeAt); - } else if (options.region) { - this.panes[key] = new ContentPane(options).placeAt(placeAt); - } - } - } - } - this.panes.outer.startup(); - this.initMap(); - this.createPanes(panes); - - this.panes.outer.resize(); - }, - - createPanes: function (panes) { - var key; - // where to place the buttons - // either the center map pane or the outer pane? - this.collapseButtonsPane = this.config.collapseButtonsPane || 'outer'; - - for (key in panes) { - if (panes.hasOwnProperty(key)) { - if (panes[key].collapsible) { - this.collapseButtons[key] = put(this.panes[this.collapseButtonsPane].domNode, 'div.sidebarCollapseButton.sidebar' + key + 'CollapseButton.sidebarCollapseButton' + ((key === 'bottom' || key === 'top') ? 'Vert' : 'Horz') + ' div.dijitIcon.button.close').parentNode; - on(this.collapseButtons[key], 'click', lang.hitch(this, 'togglePane', key)); - this.positionSideBarToggle(key); - if (this.collapseButtonsPane === 'outer') { - var splitter = this.panes[key]._splitterWidget; - if (splitter) { - aspect.after(splitter, '_startDrag', lang.hitch(this, 'splitterStartDrag', key)); - aspect.after(splitter, '_stopDrag', lang.hitch(this, 'splitterStopDrag', key)); - } - } - if (panes[key].open !== undefined) { - this.togglePane(key, panes[key].open); - } - } - if (key !== 'center' && this.panes[key]._splitterWidget) { - domClass.add(this.map.root.parentNode, 'pane' + key); - if (key === 'right' && this.panes.top) { - domClass.add(this.panes.top.domNode, 'pane' + key); - } - if (key === 'right' && this.panes.bottom) { - domClass.add(this.panes.bottom.domNode, 'pane' + key); - } - if (key === 'left' && this.panes.top) { - domClass.add(this.panes.top.domNode, 'pane' + key); - } - if (key === 'left' && this.panes.bottom) { - domClass.add(this.panes.bottom.domNode, 'pane' + key); - } - } - } - } - - }, - - initMap: function () { - if (has('phone') && !this.config.mapOptions.infoWindow) { - this.config.mapOptions.infoWindow = new PopupMobile(null, put('div')); - } - this.map = new Map('mapCenter', this.config.mapOptions); - if (this.config.mapOptions.basemap) { - this.map.on('load', lang.hitch(this, 'initLayers')); - } else { - this.initLayers(); - } - if (this.config.operationalLayers && this.config.operationalLayers.length > 0) { - on.once(this.map, 'layers-add-result', lang.hitch(this, 'initWidgets')); - } else { - this.initWidgets(); - } - }, - initLayers: function () { - this.map.on('resize', function (evt) { - var pnt = evt.target.extent.getCenter(); - setTimeout(function () { - evt.target.centerAt(pnt); - }, 100); - }); - - this.layers = []; - var layerTypes = { - csv: 'CSV', - dataadapter: 'DataAdapterFeature', //untested - dynamic: 'ArcGISDynamicMapService', - feature: 'Feature', - georss: 'GeoRSS', - image: 'ArcGISImageService', - imagevector: 'ArcGISImageServiceVector', - kml: 'KML', - label: 'Label', //untested - mapimage: 'MapImage', //untested - osm: 'OpenStreetMap', - raster: 'Raster', - stream: 'Stream', - tiled: 'ArcGISTiledMapService', - webtiled: 'WebTiled', - wms: 'WMS', - wmts: 'WMTS' //untested - }; - // loading all the required modules first ensures the layer order is maintained - var modules = []; - array.forEach(this.config.operationalLayers, function (layer) { - var type = layerTypes[layer.type]; - if (type) { - modules.push('esri/layers/' + type + 'Layer'); - } else { - this.handleError({ - source: 'Controller', - error: 'Layer type "' + layer.type + '"" isnot supported: ' - }); - } - }, this); - require(modules, lang.hitch(this, function () { - array.forEach(this.config.operationalLayers, function (layer) { - var type = layerTypes[layer.type]; - if (type) { - require(['esri/layers/' + type + 'Layer'], lang.hitch(this, 'initLayer', layer)); - } - }, this); - this.map.addLayers(this.layers); - })); - }, - initLayer: function (layer, Layer) { - var l = new Layer(layer.url, layer.options); - this.layers.unshift(l); //unshift instead of push to keep layer ordering on map intact - //Legend LayerInfos array - var excludeLayerFromLegend = false; - if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.exclude !== 'undefined') { - excludeLayerFromLegend = layer.legendLayerInfos.exclude; - } - if (!excludeLayerFromLegend) { - var configuredLayerInfo = {}; - if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.layerInfo !== 'undefined') { - configuredLayerInfo = layer.legendLayerInfos.layerInfo; - } - var layerInfo = lang.mixin({ - layer: l, - title: layer.title || null - }, configuredLayerInfo); - this.legendLayerInfos.unshift(layerInfo); //unshift instead of push to keep layer ordering in legend intact - } - //LayerControl LayerInfos array - this.layerControlLayerInfos.unshift({ //unshift instead of push to keep layer ordering in LayerControl intact - layer: l, - type: layer.type, - title: layer.title, - controlOptions: layer.layerControlLayerInfos - }); - if (layer.type === 'feature') { - var options = { - featureLayer: l - }; - if (layer.editorLayerInfos) { - lang.mixin(options, layer.editorLayerInfos); - } - if (options.exclude !== true) { - this.editorLayerInfos.push(options); - } - } - if (layer.type === 'dynamic' || layer.type === 'feature') { - var idOptions = { - layer: l, - title: layer.title - }; - if (layer.identifyLayerInfos) { - lang.mixin(idOptions, layer.identifyLayerInfos); - } - if (idOptions.exclude !== true) { - this.identifyLayerInfos.push(idOptions); - } - } - }, - initWidgets: function () { - var widgets = [], - paneWidgets; - - for (var key in this.config.widgets) { - if (this.config.widgets.hasOwnProperty(key)) { - var widget = lang.clone(this.config.widgets[key]); - if (widget.include) { - widget.position = (typeof (widget.position) !== 'undefined') ? widget.position : 10000; - widgets.push(widget); - } - } - } - - function getPaneWidgets (pane) { - paneWidgets = array.filter(widgets, function (paneWidget) { - return (paneWidget.placeAt && paneWidget.placeAt === pane); - }); - return paneWidgets; - } - - for (var pane in this.panes) { - if (this.panes.hasOwnProperty(pane) && (pane !== 'outer' || pane !== 'center')) { - paneWidgets = getPaneWidgets(pane); - paneWidgets.sort(function (a, b) { - return a.position - b.position; - }); - array.forEach(paneWidgets, function (paneWidget, i) { - this.widgetLoader(paneWidget, i); - }, this); - } - } - paneWidgets = array.filter(widgets, function (paneWidget) { - return !paneWidget.placeAt; - }); - paneWidgets.sort(function (a, b) { - return a.position - b.position; - }); - - array.forEach(paneWidgets, function (paneWidget, i) { - this.widgetLoader(paneWidget, i); - }, this); - }, - togglePane: function (id, show) { - if (!this.panes[id]) { - return; - } - var domNode = this.panes[id].domNode; - if (domNode) { - var disp = (show && typeof (show) === 'string') ? show : (domStyle.get(domNode, 'display') === 'none') ? 'block' : 'none'; - domStyle.set(domNode, 'display', disp); - if (this.panes[id]._splitterWidget) { // show/hide the splitter, if found - domStyle.set(this.panes[id]._splitterWidget.domNode, 'display', disp); - } - this.positionSideBarToggle(id); - if (this.panes.outer) { - this.panes.outer.resize(); - } - } - }, - positionSideBarToggle: function (id) { - var pane = this.panes[id]; - var btn = this.collapseButtons[id]; - if (!pane || !btn) { - return; - } - var disp = domStyle.get(pane.domNode, 'display'); - var rCls = (disp === 'none') ? 'close' : 'open'; - var aCls = (disp === 'none') ? 'open' : 'close'; - domClass.remove(btn.children[0], rCls); - domClass.add(btn.children[0], aCls); - - // extra management required when the buttons - // are not in the center map pane - if (this.collapseButtonsPane === 'outer') { - var pos = (pane._splitterWidget) ? 0 : -1; - var orie = (id === 'bottom' || id === 'top') ? 'h' : 'w'; - if (disp === 'block') { // pane is open - pos += domGeom.getMarginBox(pane.domNode)[orie]; - } - if (pane._splitterWidget) { // account for a splitter - pos += domGeom.getMarginBox(pane._splitterWidget.domNode)[orie]; - } - domStyle.set(btn, id, pos.toString() + 'px'); - domStyle.set(btn, 'display', 'block'); - } - }, - - repositionSideBarButtons: function () { - var btns = ['left', 'right', 'top', 'bottom']; - array.forEach(btns, lang.hitch(this, function (id) { - this.positionSideBarToggle(id); - })); - }, - - // extra management of splitters required when the buttons - // are not in the center map pane - splitterStartDrag: function (id) { - var btn = this.collapseButtons[id]; - domStyle.set(btn, 'display', 'none'); - }, - splitterStopDrag: function (id) { - this.positionSideBarToggle(id); - }, - - _createTitlePaneWidget: function (parentId, title, position, open, canFloat, placeAt) { - var tp, - options = { - title: title || 'Widget', - open: open || false, - canFloat: canFloat || false - }; - if (parentId) { - options.id = parentId; - } - if (typeof (placeAt) === 'string') { - placeAt = this.panes[placeAt]; - } - if (!placeAt) { - placeAt = this.panes.left; - } - if (placeAt) { - options.sidebar = placeAt; - tp = new FloatingTitlePane(options).placeAt(placeAt, position); - tp.startup(); - } - return tp; - }, - _createFloatingWidget: function (parentId, title) { - var options = { - title: title - }; - if (parentId) { - options.id = parentId; - } - var fw = new FloatingWidgetDialog(options); - fw.startup(); - return fw; - }, - _createContentPaneWidget: function (parentId, title, className, region, placeAt) { - var cp, - options = { - title: title, - region: region || 'center' - }; - if (className) { - options.className = className; - } - if (parentId) { - options.id = parentId; - } - if (!placeAt) { - placeAt = this.panes.sidebar; - } else if (typeof (placeAt) === 'string') { - placeAt = this.panes[placeAt]; - } - if (placeAt) { - cp = new ContentPane(options).placeAt(placeAt); - cp.startup(); - } - return cp; - }, - widgetLoader: function (widgetConfig, position) { - var parentId, pnl; - - // only proceed for valid widget types - var widgetTypes = ['titlePane', 'contentPane', 'floating', 'domNode', 'invisible', 'map']; - if (array.indexOf(widgetTypes, widgetConfig.type) < 0) { - this.handleError({ - source: 'Controller', - error: 'Widget type "' + widgetConfig.type + '" (' + widgetConfig.title + ') at position ' + position + ' is not supported.' - }); - return; - } - - // build a titlePane or floating widget as the parent - if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating') && (widgetConfig.id && widgetConfig.id.length > 0)) { - parentId = widgetConfig.id + '_parent'; - if (widgetConfig.type === 'titlePane') { - pnl = this._createTitlePaneWidget(parentId, widgetConfig.title, position, widgetConfig.open, widgetConfig.canFloat, widgetConfig.placeAt); - } else if (widgetConfig.type === 'contentPane') { - pnl = this._createContentPaneWidget(parentId, widgetConfig.title, widgetConfig.className, widgetConfig.region, widgetConfig.placeAt); - } else if (widgetConfig.type === 'floating') { - pnl = this._createFloatingWidget(parentId, widgetConfig.title); - } - widgetConfig.parentWidget = pnl; - } - - // 2 ways to use require to accommodate widgets that may have an optional separate configuration file - if (typeof (widgetConfig.options) === 'string') { - require([widgetConfig.options, widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig)); - } else { - require([widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig, widgetConfig.options)); - } - }, - createWidget: function (widgetConfig, options, WidgetClass) { - // set any additional options - options.id = widgetConfig.id + '_widget'; - options.parentWidget = widgetConfig.parentWidget; - - //replace config map, layerInfos arrays, etc - if (options.map) { - options.map = this.map; - } - if (options.mapRightClickMenu) { - // create right-click menu - if (!this.mapRightClickMenu) { - this.mapRightClickMenu = new Menu({ - targetNodeIds: [this.map.root], - selector: '.layersDiv' // restrict to map only - }); - this.mapRightClickMenu.startup(); - } - options.mapRightClickMenu = this.mapRightClickMenu; - } - if (options.mapClickMode) { - options.mapClickMode = this.mapClickMode.current; - } - if (options.legendLayerInfos) { - options.layerInfos = this.legendLayerInfos; - } - if (options.layerControlLayerInfos) { - options.layerInfos = this.layerControlLayerInfos; - } - if (options.editorLayerInfos) { - options.layerInfos = this.editorLayerInfos; - } - if (options.identifyLayerInfos) { - options.layerInfos = this.identifyLayerInfos; - } - - // create the widget - var pnl = options.parentWidget; - if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating')) { - this[widgetConfig.id] = new WidgetClass(options, put('div')).placeAt(pnl.containerNode); - } else if (widgetConfig.type === 'domNode') { - this[widgetConfig.id] = new WidgetClass(options, widgetConfig.srcNodeRef); - } else { - this[widgetConfig.id] = new WidgetClass(options); - } - - // start up the widget - if (this[widgetConfig.id] && this[widgetConfig.id].startup && !this[widgetConfig.id]._started) { - this[widgetConfig.id].startup(); - } - }, - //centralized error handler - handleError: function (options) { - if (this.config.isDebug) { - if (typeof (console) === 'object') { - for (var option in options) { - if (options.hasOwnProperty(option)) { - console.log(option, options[option]); - } - } - } - } else { - // add growler here? - return; - } - } - }; -}); \ No newline at end of file diff --git a/viewer/js/viewer/_ConfigMixin.js b/viewer/js/viewer/_ConfigMixin.js new file mode 100644 index 000000000..62e0115a1 --- /dev/null +++ b/viewer/js/viewer/_ConfigMixin.js @@ -0,0 +1,62 @@ +define([ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/Deferred' +], function ( + declare, + lang, + Deferred +) { + 'use strict'; + + return declare(null, { + + initConfigAsync: function () { + var returnDeferred = new Deferred(); + // get the config file from the url if present + var file = 'config/viewer', + s = window.location.search, + q = s.match(/config=([^&]*)/i); + if (q && q.length > 0) { + file = q[1]; + if (file.indexOf('/') < 0) { + file = 'config/' + file; + } + } + require([file], function (config) { + returnDeferred.resolve(config); + }); + return returnDeferred; + }, + + initConfigSuccess: function (config) { + this.config = config; + + if (config.isDebug) { + window.app = this; //dev only + } + + // setup the map click mode + this.mapClickMode = { + current: config.defaultMapClickMode, + defaultMode: config.defaultMapClickMode + }; + + // in _LayoutMixin + this.initLayout(); + + // in _MapMixin + this.initMapAsync().then( + lang.hitch(this, 'initMapComplete'), + lang.hitch(this, 'initMapError') + ); + }, + + initConfigError: function (err) { + this.handleError({ + source: 'Controller', + error: err + }); + } + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/_ControllerBase.js b/viewer/js/viewer/_ControllerBase.js new file mode 100644 index 000000000..4fc35620d --- /dev/null +++ b/viewer/js/viewer/_ControllerBase.js @@ -0,0 +1,37 @@ +/*eslint strict: 0, no-console: 0*/ +define([ + 'dojo/_base/declare', + 'dojo/_base/lang' +], function ( + declare, + lang +) { + return declare(null, { + + startup: function () { + this.inherited(arguments); + + // in _ConfigMixin + this.initConfigAsync().then( + lang.hitch(this, 'initConfigSuccess'), + lang.hitch(this, 'initConfigError') + ); + }, + + //centralized error handler + handleError: function (options) { + if (this.config.isDebug) { + if (typeof (console) === 'object') { + for (var option in options) { + if (options.hasOwnProperty(option)) { + console.log(option, options[option]); + } + } + } + } else { + // add growler here? + return; + } + } + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/_LayoutMixin.js b/viewer/js/viewer/_LayoutMixin.js new file mode 100644 index 000000000..8bd2eef67 --- /dev/null +++ b/viewer/js/viewer/_LayoutMixin.js @@ -0,0 +1,294 @@ +define([ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/topic', + 'dojo/_base/array', + 'dojo/on', + 'dojo/aspect', + 'dojo/dom', + 'dojo/query', + 'dojo/dom-style', + 'dojo/dom-class', + 'dojo/dom-geometry', + 'dojo/sniff', + + 'put-selector', + + 'dijit/layout/BorderContainer', + 'dijit/layout/ContentPane', + + 'esri/dijit/PopupMobile', + + 'dojo/text!./templates/mapOverlay.html' +], function ( + declare, + lang, + topic, + array, + on, + aspect, + dom, + domQuery, + domStyle, + domClass, + domGeom, + has, + + put, + + BorderContainer, + ContentPane, + + PopupMobile, + + mapOverlay +) { + 'use strict'; + return declare(null, { + + panes: { + left: { + id: 'sidebarLeft', + placeAt: 'outer', + collapsible: true, + region: 'left' + }, + center: { + id: 'mapCenter', + placeAt: 'outer', + region: 'center', + content: mapOverlay + } + }, + collapseButtons: {}, + + initLayout: function () { + this.config.layout = this.config.layout || {}; + + this.addTopics(); + this.addTitles(); + this.detectTouchDevices(); + this.initPanes(); + }, + + // add topics for subscribing and publishing + addTopics: function () { + // toggle a sidebar pane + topic.subscribe('viewer/togglePane', lang.hitch(this, function (args) { + this.toggleSidebar(args.pane, args.show); + })); + + // load a widget + topic.subscribe('viewer/loadWidget', lang.hitch(this, function (args) { + this.widgetLoader(args.options, args.position); + })); + + // setup error handler. centralize the debugging + if (this.config.isDebug) { + topic.subscribe('viewer/handleError', lang.hitch(this, 'handleError')); + } + + // set the current mapClickMode + topic.subscribe('mapClickMode/setCurrent', lang.hitch(this, function (mode) { + this.mapClickMode.current = mode; + topic.publish('mapClickMode/currentSet', mode); + })); + + // set the current mapClickMode to the default mode + topic.subscribe('mapClickMode/setDefault', lang.hitch(this, function () { + topic.publish('mapClickMode/setCurrent', this.mapClickMode.defaultMode); + })); + + }, + + // set titles (if any) + addTitles: function () { + if (!this.config.titles) { + return; + } + var titles = this.config.titles; + if (titles.header) { + var headerTitleNode = dom.byId('headerTitleSpan'); + if (headerTitleNode) { + headerTitleNode.innerHTML = titles.header; + } + } + if (titles.subHeader) { + var subHeaderTitle = dom.byId('subHeaderTitleSpan'); + if (subHeaderTitle) { + subHeaderTitle.innerHTML = titles.subHeader; + } + } + if (titles.pageTitle) { + document.title = titles.pageTitle; + } + }, + // setup all the sidebar panes + initPanes: function () { + var key, + panes = this.config.panes || {}; + for (key in this.panes) { + if (this.panes.hasOwnProperty(key)) { + panes[key] = lang.mixin(this.panes[key], panes[key]); + } + } + + var container = dom.byId(this.config.layout.container) || document.body; + this.panes.outer = new BorderContainer({ + id: 'borderContainerOuter', + design: 'sidebar', + gutters: false + }).placeAt(container); + + var options, placeAt, type; + for (key in panes) { + if (panes.hasOwnProperty(key)) { + options = lang.clone(panes[key]); + placeAt = this.panes[options.placeAt] || this.panes.outer; + options.id = options.id || key; + type = options.type; + delete options.placeAt; + delete options.type; + delete options.collapsible; + if (placeAt) { + if (type === 'border') { + this.panes[key] = new BorderContainer(options).placeAt(placeAt); + } else if (options.region) { + this.panes[key] = new ContentPane(options).placeAt(placeAt); + } + } + } + } + this.panes.outer.startup(); + this.createPanes(panes); + }, + + createPanes: function (panes) { + var key; + // where to place the buttons + // either the center map pane or the outer pane? + this.collapseButtonsPane = this.config.collapseButtonsPane || 'outer'; + + for (key in panes) { + if (panes.hasOwnProperty(key)) { + if (panes[key].collapsible) { + this.collapseButtons[key] = put(this.panes[this.collapseButtonsPane].domNode, 'div.sidebarCollapseButton.sidebar' + key + 'CollapseButton.sidebarCollapseButton' + ((key === 'bottom' || key === 'top') ? 'Vert' : 'Horz') + ' div.dijitIcon.button.close').parentNode; + on(this.collapseButtons[key], 'click', lang.hitch(this, 'togglePane', key)); + this.positionSideBarToggle(key); + if (this.collapseButtonsPane === 'outer') { + var splitter = this.panes[key]._splitterWidget; + if (splitter) { + aspect.after(splitter, '_startDrag', lang.hitch(this, '_splitterStartDrag', key)); + aspect.after(splitter, '_stopDrag', lang.hitch(this, '_splitterStopDrag', key)); + } + } + if (panes[key].open !== undefined) { + this.togglePane(key, panes[key].open); + } + } + if (key !== 'center' && this.panes[key]._splitterWidget) { + domClass.add(this.map.root.parentNode, 'pane' + key); + if (key === 'right' && this.panes.top) { + domClass.add(this.panes.top.domNode, 'pane' + key); + } + if (key === 'right' && this.panes.bottom) { + domClass.add(this.panes.bottom.domNode, 'pane' + key); + } + if (key === 'left' && this.panes.top) { + domClass.add(this.panes.top.domNode, 'pane' + key); + } + if (key === 'left' && this.panes.bottom) { + domClass.add(this.panes.bottom.domNode, 'pane' + key); + } + } + } + } + + }, + + togglePane: function (id, show) { + if (!this.panes[id]) { + return; + } + var domNode = this.panes[id].domNode; + if (domNode) { + var disp = (show && typeof (show) === 'string') ? show : (domStyle.get(domNode, 'display') === 'none') ? 'block' : 'none'; + domStyle.set(domNode, 'display', disp); + if (this.panes[id]._splitterWidget) { // show/hide the splitter, if found + domStyle.set(this.panes[id]._splitterWidget.domNode, 'display', disp); + } + this.positionSideBarToggle(id); + if (this.panes.outer) { + this.panes.outer.resize(); + } + } + }, + + positionSideBarToggle: function (id) { + var pane = this.panes[id]; + var btn = this.collapseButtons[id]; + if (!pane || !btn) { + return; + } + var disp = domStyle.get(pane.domNode, 'display'); + var rCls = (disp === 'none') ? 'close' : 'open'; + var aCls = (disp === 'none') ? 'open' : 'close'; + domClass.remove(btn.children[0], rCls); + domClass.add(btn.children[0], aCls); + + // extra management required when the buttons + // are not in the center map pane + if (this.collapseButtonsPane === 'outer') { + var pos = (pane._splitterWidget) ? 0 : -1; + var orie = (id === 'bottom' || id === 'top') ? 'h' : 'w'; + if (disp === 'block') { // pane is open + pos += domGeom.getMarginBox(pane.domNode)[orie]; + } + if (pane._splitterWidget) { // account for a splitter + pos += domGeom.getMarginBox(pane._splitterWidget.domNode)[orie]; + } + domStyle.set(btn, id, pos.toString() + 'px'); + domStyle.set(btn, 'display', 'block'); + } + }, + + repositionSideBarButtons: function () { + var btns = ['left', 'right', 'top', 'bottom']; + array.forEach(btns, lang.hitch(this, function (id) { + this.positionSideBarToggle(id); + })); + }, + + resizeLayout: function () { + this.panes.outer.resize(); + }, + + // extra management of splitters required when the buttons + // are not in the center map pane + _splitterStartDrag: function (id) { + var btn = this.collapseButtons[id]; + domStyle.set(btn, 'display', 'none'); + }, + _splitterStopDrag: function (id) { + this.positionSideBarToggle(id); + }, + + // simple feature detection. kinda like dojox/mobile without the overhead + detectTouchDevices: function () { + if (has('touch') && (has('ios') || has('android') || has('bb'))) { + has.add('mobile', true); + if (screen.availWidth < 500 || screen.availHeight < 500) { + has.add('phone', true); + } else { + has.add('tablet', true); + } + + // use the mobile popup for phones + if (has('phone') && !this.config.mapOptions.infoWindow) { + this.config.mapOptions.infoWindow = new PopupMobile(null, put('div')); + } + } + + } + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js new file mode 100644 index 000000000..e8f5902d6 --- /dev/null +++ b/viewer/js/viewer/_MapMixin.js @@ -0,0 +1,197 @@ +define([ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/on', + 'dojo/dom', + 'dojo/_base/array', + 'dojo/Deferred', + + 'esri/map', + + 'esri/IdentityManager' + +], function ( + declare, + lang, + on, + dom, + array, + Deferred, + + Map +) { + 'use strict'; + return declare(null, { + + initMapAsync: function () { + var returnDeferred = new Deferred(); + var returnWarnings = []; + + var container = dom.byId(this.config.layout.map) || 'mapCenter'; + this.map = new Map(container, this.config.mapOptions); + + if (this.config.mapOptions.basemap) { + this.map.on('load', lang.hitch(this, '_initLayers', returnWarnings)); + } else { + this._initLayers(returnWarnings); + } + + if (this.config.operationalLayers && this.config.operationalLayers.length > 0) { + on.once(this.map, 'layers-add-result', lang.hitch(this, '_onLayersAddResult', returnDeferred, returnWarnings)); + } else { + returnDeferred.resolve(returnWarnings); + } + return returnDeferred; + }, + + _onLayersAddResult: function (returnDeferred, returnWarnings, lyrsResult) { + array.forEach(lyrsResult.layers, function (addedLayer) { + if (addedLayer.success !== true) { + returnWarnings.push(addedLayer.error); + } + }, this); + returnDeferred.resolve(returnWarnings); + }, + + _initLayers: function (returnWarnings) { + this.layers = []; + var layerTypes = { + csv: 'CSV', + dataadapter: 'DataAdapterFeature', //untested + dynamic: 'ArcGISDynamicMapService', + feature: 'Feature', + georss: 'GeoRSS', + image: 'ArcGISImageService', + imagevector: 'ArcGISImageServiceVector', + kml: 'KML', + label: 'Label', //untested + mapimage: 'MapImage', //untested + osm: 'OpenStreetMap', + raster: 'Raster', + stream: 'Stream', + tiled: 'ArcGISTiledMapService', + webtiled: 'WebTiled', + wms: 'WMS', + wmts: 'WMTS' //untested + }; + // loading all the required modules first ensures the layer order is maintained + var modules = []; + array.forEach(this.config.operationalLayers, function (layer) { + var type = layerTypes[layer.type]; + if (type) { + modules.push('esri/layers/' + type + 'Layer'); + } else { + returnWarnings.push('Layer type "' + layer.type + '"" isnot supported: '); + } + }, this); + + require(modules, lang.hitch(this, function () { + array.forEach(this.config.operationalLayers, function (layer) { + var type = layerTypes[layer.type]; + if (type) { + require(['esri/layers/' + type + 'Layer'], lang.hitch(this, '_initLayer', layer)); + } + }, this); + this.map.addLayers(this.layers); + })); + }, + + _initLayer: function (layer, Layer) { + var l = new Layer(layer.url, layer.options); + this.layers.unshift(l); //unshift instead of push to keep layer ordering on map intact + + //Legend LayerInfos array + var excludeLayerFromLegend = false; + if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.exclude !== 'undefined') { + excludeLayerFromLegend = layer.legendLayerInfos.exclude; + } + if (!excludeLayerFromLegend) { + var configuredLayerInfo = {}; + if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.layerInfo !== 'undefined') { + configuredLayerInfo = layer.legendLayerInfos.layerInfo; + } + var layerInfo = lang.mixin({ + layer: l, + title: layer.title || null + }, configuredLayerInfo); + this.legendLayerInfos.unshift(layerInfo); //unshift instead of push to keep layer ordering in legend intact + } + + //LayerControl LayerInfos array + this.layerControlLayerInfos.unshift({ //unshift instead of push to keep layer ordering in LayerControl intact + layer: l, + type: layer.type, + title: layer.title, + controlOptions: layer.layerControlLayerInfos + }); + + if (layer.type === 'feature') { + var options = { + featureLayer: l + }; + if (layer.editorLayerInfos) { + lang.mixin(options, layer.editorLayerInfos); + } + if (options.exclude !== true) { + this.editorLayerInfos.push(options); + } + } + + if (layer.type === 'dynamic' || layer.type === 'feature') { + var idOptions = { + layer: l, + title: layer.title + }; + if (layer.identifyLayerInfos) { + lang.mixin(idOptions, layer.identifyLayerInfos); + } + if (idOptions.exclude !== true) { + this.identifyLayerInfos.push(idOptions); + } + } + }, + + initMapComplete: function (warnings) { + if (warnings && warnings.length > 0) { + this.handleError({ + source: 'Controller', + error: warnings.join(', ') + }); + } + + this.map.on('resize', function (evt) { + var pnt = evt.target.extent.getCenter(); + setTimeout(function () { + evt.target.centerAt(pnt); + }, 100); + }); + + // in _LayoutsMixin + this.resizeLayout(); + + // in _WidgetsMixin + this.initWidgets(); + }, + + initMapError: function (err) { + this.handleError({ + source: 'Controller', + error: err + }); + }, + + resizeMap: function () { + if (this.map) { + this.map.resize(); + } + }, + + getMapHeight: function () { + if (this.map) { + return this.map.height; + } else { + return 0; + } + } + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js new file mode 100644 index 000000000..8179ed87f --- /dev/null +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -0,0 +1,227 @@ +define([ + 'dojo/_base/declare', + 'dojo/_base/array', + 'dojo/_base/lang', + + 'put-selector', + + 'dijit/Menu', + 'dijit/layout/ContentPane', + + 'gis/dijit/FloatingTitlePane', + 'gis/dijit/FloatingWidgetDialog' + +], function ( + declare, + array, + lang, + + put, + + Menu, + ContentPane, + + FloatingTitlePane, + FloatingWidgetDialog +) { + + 'use strict'; + return declare(null, { + + legendLayerInfos: [], + editorLayerInfos: [], + identifyLayerInfos: [], + layerControlLayerInfos: [], + + initWidgets: function () { + var widgets = [], + paneWidgets; + + for (var key in this.config.widgets) { + if (this.config.widgets.hasOwnProperty(key)) { + var widget = lang.clone(this.config.widgets[key]); + if (widget.include) { + widget.position = (typeof (widget.position) !== 'undefined') ? widget.position : 10000; + widgets.push(widget); + } + } + } + + function getPaneWidgets (pane) { + paneWidgets = array.filter(widgets, function (paneWidget) { + return (paneWidget.placeAt && paneWidget.placeAt === pane); + }); + return paneWidgets; + } + + for (var pane in this.panes) { + if (this.panes.hasOwnProperty(pane) && (pane !== 'outer' || pane !== 'center')) { + paneWidgets = getPaneWidgets(pane); + paneWidgets.sort(function (a, b) { + return a.position - b.position; + }); + array.forEach(paneWidgets, function (paneWidget, i) { + this.widgetLoader(paneWidget, i); + }, this); + } + } + paneWidgets = array.filter(widgets, function (paneWidget) { + return !paneWidget.placeAt; + }); + paneWidgets.sort(function (a, b) { + return a.position - b.position; + }); + + array.forEach(paneWidgets, function (paneWidget, i) { + this.widgetLoader(paneWidget, i); + }, this); + }, + + widgetLoader: function (widgetConfig, position) { + var parentId, pnl; + + // only proceed for valid widget types + var widgetTypes = ['titlePane', 'contentPane', 'floating', 'domNode', 'invisible', 'map']; + if (array.indexOf(widgetTypes, widgetConfig.type) < 0) { + this.handleError({ + source: 'Controller', + error: 'Widget type "' + widgetConfig.type + '" (' + widgetConfig.title + ') at position ' + position + ' is not supported.' + }); + return; + } + + // build a titlePane or floating widget as the parent + if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating') && (widgetConfig.id && widgetConfig.id.length > 0)) { + parentId = widgetConfig.id + '_parent'; + if (widgetConfig.type === 'titlePane') { + pnl = this._createTitlePaneWidget(parentId, widgetConfig.title, position, widgetConfig.open, widgetConfig.canFloat, widgetConfig.placeAt); + } else if (widgetConfig.type === 'contentPane') { + pnl = this._createContentPaneWidget(parentId, widgetConfig.title, widgetConfig.className, widgetConfig.region, widgetConfig.placeAt); + } else if (widgetConfig.type === 'floating') { + pnl = this._createFloatingWidget(parentId, widgetConfig.title); + } + widgetConfig.parentWidget = pnl; + } + + // 2 ways to use require to accommodate widgets that may have an optional separate configuration file + if (typeof (widgetConfig.options) === 'string') { + require([widgetConfig.options, widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig)); + } else { + require([widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig, widgetConfig.options)); + } + }, + + createWidget: function (widgetConfig, options, WidgetClass) { + // set any additional options + options.id = widgetConfig.id + '_widget'; + options.parentWidget = widgetConfig.parentWidget; + + //replace config map, layerInfos arrays, etc + if (options.map) { + options.map = this.map; + } + if (options.mapRightClickMenu) { + // create right-click menu + if (!this.mapRightClickMenu) { + this.mapRightClickMenu = new Menu({ + targetNodeIds: [this.map.root], + selector: '.layersDiv' // restrict to map only + }); + this.mapRightClickMenu.startup(); + } + options.mapRightClickMenu = this.mapRightClickMenu; + } + if (options.mapClickMode) { + options.mapClickMode = this.mapClickMode.current; + } + if (options.legendLayerInfos) { + options.layerInfos = this.legendLayerInfos; + } + if (options.layerControlLayerInfos) { + options.layerInfos = this.layerControlLayerInfos; + } + if (options.editorLayerInfos) { + options.layerInfos = this.editorLayerInfos; + } + if (options.identifyLayerInfos) { + options.layerInfos = this.identifyLayerInfos; + } + + // create the widget + var pnl = options.parentWidget; + if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating')) { + this[widgetConfig.id] = new WidgetClass(options, put('div')).placeAt(pnl.containerNode); + } else if (widgetConfig.type === 'domNode') { + this[widgetConfig.id] = new WidgetClass(options, widgetConfig.srcNodeRef); + } else { + this[widgetConfig.id] = new WidgetClass(options); + } + + // start up the widget + if (this[widgetConfig.id] && this[widgetConfig.id].startup && !this[widgetConfig.id]._started) { + this[widgetConfig.id].startup(); + } + }, + + _createTitlePaneWidget: function (parentId, title, position, open, canFloat, placeAt) { + var tp, + options = { + title: title || 'Widget', + open: open || false, + canFloat: canFloat || false + }; + if (parentId) { + options.id = parentId; + } + if (typeof (placeAt) === 'string') { + placeAt = this.panes[placeAt]; + } + if (!placeAt) { + placeAt = this.panes.left; + } + if (placeAt) { + options.sidebar = placeAt; + tp = new FloatingTitlePane(options).placeAt(placeAt, position); + tp.startup(); + } + return tp; + }, + + _createFloatingWidget: function (parentId, title) { + var options = { + title: title + }; + if (parentId) { + options.id = parentId; + } + var fw = new FloatingWidgetDialog(options); + fw.startup(); + return fw; + }, + + _createContentPaneWidget: function (parentId, title, className, region, placeAt) { + var cp, + options = { + title: title, + region: region || 'center' + }; + if (className) { + options.className = className; + } + if (parentId) { + options.id = parentId; + } + if (!placeAt) { + placeAt = this.panes.sidebar; + } else if (typeof (placeAt) === 'string') { + placeAt = this.panes[placeAt]; + } + if (placeAt) { + cp = new ContentPane(options).placeAt(placeAt); + cp.startup(); + } + return cp; + } + + }); +}); \ No newline at end of file From 5dacdd29d7bfa86301cb790655720dbd1e14053d Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 6 Nov 2015 11:55:43 -0800 Subject: [PATCH 021/216] Added new `layerIds` option to layerControl configuration. This array determines which sublayer and folder controls are visible. The visibility of the actual sublayers is not affected. Also includes `layerIds` array in imageParameters to demonstrate how to set the initial visibility of sublayers. --- viewer/js/config/viewer.js | 8 +++++++- .../js/gis/dijit/LayerControl/controls/_DynamicFolder.js | 4 ++++ .../gis/dijit/LayerControl/controls/_DynamicSublayer.js | 4 ++++ viewer/js/gis/dijit/LayerControl/css/LayerControl.css | 7 +++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 8ed10af85..b22497e15 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -124,11 +124,17 @@ define([ id: 'louisvillePubSafety', opacity: 1.0, visible: true, - imageParameters: buildImageParameters() + imageParameters: buildImageParameters({ + layerIds: [0, 2, 4, 5, 8, 10, 12, 21], + layerOption: 'show' + }) }, identifyLayerInfos: { layerIds: [2, 4, 5, 8, 12, 21] }, + layerControlLayerInfos: { + layerIds: [0, 2, 4, 5, 8, 9, 10, 12, 21] + }, legendLayerInfos: { layerInfo: { hideLayers: [21] diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js index 2631e34ba..8c949d037 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js @@ -35,6 +35,10 @@ define([ _expandClickHandler: null, postCreate: function () { this.inherited(arguments); + // Should the control be visible or hidden? + if (this.control.controlOptions.layerIds && this.control.controlOptions.layerIds.indexOf(this.sublayerInfo.id) < 0) { + domClass.add(this.domNode, 'layerControlHidden'); + } var checkNode = this.checkNode; domAttr.set(checkNode, 'data-sublayer-id', this.sublayerInfo.id); domClass.add(checkNode, this.control.layer.id + '-layerControlSublayerCheck'); diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js index cbe35b987..2f545c073 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js @@ -45,6 +45,10 @@ define([ _expandClickHandler: null, postCreate: function () { this.inherited(arguments); + // Should the control be visible or hidden? + if (this.control.controlOptions.layerIds && this.control.controlOptions.layerIds.indexOf(this.sublayerInfo.id) < 0) { + domClass.add(this.domNode, 'layerControlHidden'); + } var checkNode = this.checkNode; domAttr.set(checkNode, 'data-sublayer-id', this.sublayerInfo.id); domClass.add(checkNode, this.control.layer.id + '-layerControlSublayerCheck'); diff --git a/viewer/js/gis/dijit/LayerControl/css/LayerControl.css b/viewer/js/gis/dijit/LayerControl/css/LayerControl.css index f805803da..2a09ad53e 100644 --- a/viewer/js/gis/dijit/LayerControl/css/LayerControl.css +++ b/viewer/js/gis/dijit/LayerControl/css/LayerControl.css @@ -67,6 +67,13 @@ text-align: center; } +.layerControlDijit .layerControlHidden { + display: none; +} +.layerControlDijit .layerControlVisible { + display: block; +} + .layerControlDijit .layerControlIndent { padding-left: 22px; } From c9e0b0c879c49ab82692560ee736f7532f56fa2f Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 6 Nov 2015 12:28:47 -0800 Subject: [PATCH 022/216] Update the ESRI JavaScript API to version 3.15 The api is available now for testing. The official release is not expected for a few weeks. --- viewer/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/index.html b/viewer/index.html index 89bba9499..4899cf70a 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -11,7 +11,7 @@ Configurable Map Viewer - + @@ -41,7 +41,7 @@ - + From 8ebacf8be3c2e55b6c5c0a645dc5e48fa2a6ef71 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 6 Nov 2015 18:08:03 -0800 Subject: [PATCH 023/216] Exclude `special` fields from default infoTemplate for identify. --- viewer/js/gis/dijit/Identify.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/viewer/js/gis/dijit/Identify.js b/viewer/js/gis/dijit/Identify.js index 103dd6c75..9518799d3 100644 --- a/viewer/js/gis/dijit/Identify.js +++ b/viewer/js/gis/dijit/Identify.js @@ -39,6 +39,12 @@ define([ draggable: false, layerSeparator: '||', allLayersId: '***', + excludedFields: [ + 'objectid', 'esri_oid', 'shape', + 'shape.len', 'shape_length', + 'shape_len', 'shape.stlength()', + 'shape.area', 'shape_area', 'shape.starea()' + ], postCreate: function () { this.inherited(arguments); @@ -339,13 +345,13 @@ define([ // if no Popup config found, create one with all attributes or layer fields if (!popup) { - popup = this.createInfoTemplate(layer, layerId, result); + popup = this.createDefaultInfoTemplate(layer, layerId, result); } return popup; }, - createInfoTemplate: function (layer, layerId, result) { + createDefaultInfoTemplate: function (layer, layerId, result) { var popup = null, fieldInfos = []; var layerName = this.getLayerName(layer); @@ -359,8 +365,9 @@ define([ if (attributes) { for (var prop in attributes) { if (attributes.hasOwnProperty(prop)) { - fieldInfos.push({ + this.addDefaultFieldInfo(fieldInfos, { fieldName: prop, + label: prop.replace(/_/g, ' '), visible: true }); } @@ -371,29 +378,29 @@ define([ } else if (layer._outFields && (layer._outFields.length) && (layer._outFields[0] !== '*')) { var fields = layer.fields; - array.forEach(layer._outFields, function (fieldName) { + array.forEach(layer._outFields, lang.hitch(this, function (fieldName) { var foundField = array.filter(fields, function (field) { return (field.name === fieldName); }); if (foundField.length > 0) { - fieldInfos.push({ + this.addDefaultFieldInfo(fieldInfos, { fieldName: foundField[0].name, label: foundField[0].alias, visible: true }); } - }); + })); // from the fields layer } else if (layer.fields) { - array.forEach(layer.fields, function (field) { - fieldInfos.push({ + array.forEach(layer.fields, lang.hitch(this, function (field) { + this.addDefaultFieldInfo(fieldInfos, { fieldName: field.name, label: field.alias, visible: true }); - }); + })); } if (fieldInfos.length > 0) { @@ -411,6 +418,13 @@ define([ return popup; }, + addDefaultFieldInfo: function (fieldInfos, field) { + var nameLC = field.fieldName.toLowerCase(); + if (array.indexOf(this.excludedFields, nameLC) < 0) { + fieldInfos.push(field); + } + }, + createIdentifyLayerList: function () { var id = null; var identifyItems = []; From f809998308432b3c8401cd9b17e4d253ad6dbdbc Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 23 Nov 2015 11:05:17 -0700 Subject: [PATCH 024/216] replace `indexOf` with dojo's array.indexOf for compatibility with IE8. --- viewer/js/gis/dijit/Identify.js | 6 +++--- viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js | 2 +- .../js/gis/dijit/LayerControl/controls/_DynamicSublayer.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/viewer/js/gis/dijit/Identify.js b/viewer/js/gis/dijit/Identify.js index 9518799d3..0bd7793a9 100644 --- a/viewer/js/gis/dijit/Identify.js +++ b/viewer/js/gis/dijit/Identify.js @@ -65,7 +65,7 @@ define([ // Identify (Feature Service), create an // infoTemplate for the graphic features. Create // it only if one does not already exist. - if (layer.capabilities && layer.capabilities.toLowerCase().indexOf('data') < 0) { + if (layer.capabilities && array.indexOf(layer.capabilities.toLowerCase(), 'data') < 0) { if (!layer.infoTemplate) { var infoTemplate = this.getInfoTemplate(layer, layer.layerId); if (infoTemplate) { @@ -200,7 +200,7 @@ define([ // handle feature layers that come from a feature service // and may already have an info template var layer = evt.graphic._layer; - if (layer.infoTemplate || (layer.capabilities && layer.capabilities.toLowerCase().indexOf('data') < 0)) { + if (layer.infoTemplate || (layer.capabilities && array.indexOf(layer.capabilities.toLowerCase(), 'data') < 0)) { return false; } @@ -262,7 +262,7 @@ define([ } else if ((ref.declaredClass === 'esri.layers.FeatureLayer') && !isNaN(ref.layerId)) { // feature layer // do not allow feature layer that does not support // Identify (Feature Service) - if (ref.capabilities && ref.capabilities.toLowerCase().indexOf('data') > 0) { + if (ref.capabilities && array.indexOf(ref.capabilities.toLowerCase(), 'data') >= 0) { layerIds = [ref.layerId]; } } else if (ref.layerInfos) { diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js index 8c949d037..a48e7115e 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js @@ -36,7 +36,7 @@ define([ postCreate: function () { this.inherited(arguments); // Should the control be visible or hidden? - if (this.control.controlOptions.layerIds && this.control.controlOptions.layerIds.indexOf(this.sublayerInfo.id) < 0) { + if (this.control.controlOptions.layerIds && array.indexOf(this.control.controlOptions.layerIds, this.sublayerInfo.id) < 0) { domClass.add(this.domNode, 'layerControlHidden'); } var checkNode = this.checkNode; diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js index 2f545c073..e5749ee90 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js @@ -46,7 +46,7 @@ define([ postCreate: function () { this.inherited(arguments); // Should the control be visible or hidden? - if (this.control.controlOptions.layerIds && this.control.controlOptions.layerIds.indexOf(this.sublayerInfo.id) < 0) { + if (this.control.controlOptions.layerIds && array.indexOf(this.control.controlOptions.layerIds, this.sublayerInfo.id) < 0) { domClass.add(this.domNode, 'layerControlHidden'); } var checkNode = this.checkNode; From 557e67d9e61ee1da5fc6b3adc29fedee6d2679d3 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 23 Nov 2015 11:10:46 -0700 Subject: [PATCH 025/216] Google maps api no longer requires the `sensor` parameter. --- viewer/js/gis/dijit/StreetView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index 5ba63ed57..dde884fdb 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -22,7 +22,7 @@ define([ 'dijit/form/Button', 'xstyle/css!./StreetView/css/StreetView.css', - 'gis/plugins/async!//maps.google.com/maps/api/js?v=3&sensor=false' + 'gis/plugins/async!//maps.google.com/maps/api/js?v=3' ], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, aspect, topic, GraphicsLayer, Graphic, SimpleRenderer, template, PictureMarkerSymbol, domStyle, Point, SpatialReference, MenuItem, proj4, i18n) { return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { From 65bd7465821ccfebdcb4d8dd0edcb79231dfe463 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 23 Nov 2015 15:10:06 -0700 Subject: [PATCH 026/216] Add `VectorTileLayer` as a new type of operational layer. requires at least v3.15 or v4.0 beta 2 of the ESRI JS API --- viewer/js/gis/dijit/LayerControl.js | 1 + .../dijit/LayerControl/controls/VectorTile.js | 24 +++++++++++++++++++ viewer/js/viewer/_MapMixin.js | 8 ++++++- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 viewer/js/gis/dijit/LayerControl/controls/VectorTile.js diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index fb951e3e6..ec2d89265 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -70,6 +70,7 @@ define([ georss: './LayerControl/controls/GeoRSS', wms: './LayerControl/controls/WMS', kml: './LayerControl/controls/KML', + vectortile: './LayerControl/controls/VectorTile', webtiled: './LayerControl/controls/WebTiled', imagevector: './LayerControl/controls/ImageVector', raster: './LayerControl/controls/Raster', diff --git a/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js b/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js new file mode 100644 index 000000000..189bca3bb --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js @@ -0,0 +1,24 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_Contained', + './_Control' // layer control base class +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + _Contained, + _Control +) { + 'use strict'; + + var VectorTileControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { + _layerType: 'overlay', // constant + _esriLayerType: 'vectortile', // constant + _layerTypeInit: function () { + this._expandRemove(); + } + }); + return VectorTileControl; +}); \ No newline at end of file diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index e8f5902d6..6b3c72027 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -70,6 +70,7 @@ define([ raster: 'Raster', stream: 'Stream', tiled: 'ArcGISTiledMapService', + vectortile: 'VectorTile', webtiled: 'WebTiled', wms: 'WMS', wmts: 'WMTS' //untested @@ -97,7 +98,12 @@ define([ }, _initLayer: function (layer, Layer) { - var l = new Layer(layer.url, layer.options); + var l; + if (layer.url) { + l = new Layer(layer.url, layer.options); + } else { + l = new Layer(layer.options); + } this.layers.unshift(l); //unshift instead of push to keep layer ordering on map intact //Legend LayerInfos array From 5a59ec279efb84a97fa0c5d3514bd250fa4f61a0 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 23 Nov 2015 15:11:57 -0700 Subject: [PATCH 027/216] add examples of using vector tile basemaps for basemap widget. requires at least v3.15 or v4.0 beta 2 of the ESRI JS API --- viewer/js/config/basemaps.js | 101 +++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 73ace0bc2..28bd4bd92 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -98,6 +98,107 @@ define([ })] }) }*/ + + // example using vector tile basemaps (beta in v3.15) + + /* + streets: { + title: 'Streets', + basemap: new Basemap({ + id: 'streets', + layers: [new BasemapLayer({ + 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/3b8814f6ddbd485cae67e8018992246e/resources/styles/root.json', + 'type': 'VectorTileLayer' + })] + }) + }, + satellite: { + title: 'Satellite', + basemap: new Basemap({ + id: 'satellite', + layers: [new BasemapLayer({ + url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' + })] + }) + }, + hybrid: { + title: 'Hybrid', + basemap: new Basemap({ + id: 'hybrid', + layers: [ + new BasemapLayer({ + url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' + }), + new BasemapLayer({ + 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/1854498c7e35420b963a514a32689c80/resources/styles/root.json', + 'type': 'VectorTileLayer', + isReference: true + }) + ] + }) + }, + lightGray: { + title: 'Light Gray Canvas', + basemap: new Basemap({ + id: 'lightGray', + layers: [new BasemapLayer({ + 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', + 'type': 'VectorTileLayer' + })] + }) + }, + darkGray: { + title: 'Dark Gray Canvas', + basemap: new Basemap({ + id: 'darkGray', + layers: [new BasemapLayer({ + 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/3e3099d7302f4d99bc6f916dcc07ed59/resources/styles/root.json', + 'type': 'VectorTileLayer' + })] + }) + }, + navigation: { + title: 'Navigation', + basemap: new Basemap({ + id: 'navigation', + layers: [new BasemapLayer({ + 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/styles/root.json', + 'type': 'VectorTileLayer' + })] + }) + }, + streetsNight: { + title: 'Streets Night', + basemap: new Basemap({ + id: 'streetsNight', + layers: [new BasemapLayer({ + 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/f96366254a564adda1dc468b447ed956/resources/styles/root.json', + 'type': 'VectorTileLayer' + })] + }) + }, + streetsRelief: { + title: 'Streets w/ Relief', + basemap: new Basemap({ + id: 'streetsRelief', + layers: [new BasemapLayer({ + 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/ad06088bd1174866aad2dddbf5ec9642/resources/styles/root.json', + 'type': 'VectorTileLayer' + })] + }) + }, + topo: { + title: 'Topographic', + basemap: new Basemap({ + id: 'topo', + layers: [new BasemapLayer({ + 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/be44936bcdd24db588a1ae5076e36f34/resources/styles/root.json', + 'type': 'VectorTileLayer' + })] + }) + } + */ + } }; }); \ No newline at end of file From b1554d7771c197275eae311ae5c15800574a7731 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 23 Nov 2015 15:18:12 -0700 Subject: [PATCH 028/216] add examples of using vector tile layers as operational layers. requires at least v3.15 or v4.0 beta 2 of the ESRI JS API --- viewer/js/config/viewer.js | 57 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index b22497e15..20dfcb33e 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -158,6 +158,63 @@ define([ metadataUrl: true, expanded: true } + /* + //examples of vector tile layers (beta in v3.15) + }, { + type: 'vectortile', + title: 'Light Gray Canvas Vector', + url: '//www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', + options: { + id: 'vectortile1', + opacity: 0.8, + visible: true + } + }, { + // taken from this demo: https://github.com/ycabon/presentations/blob/gh-pages/2015-berlin-plenary/demos/3.15-vectortile/create-by-style-object.html + type: 'vectortile', + title: 'Custom Vector Style', + options: { + id: 'vectortile2', + opacity: 1.0, + visible: true, + 'glyphs': '//www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/fonts/{fontstack}/{range}.pbf', + 'sprite': '//www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/sprites/sprite', + 'version': 8, + 'sources': { + 'esri': { + 'url': '//basemapsdev.arcgis.com/arcgis/rest/services/World_Basemap/VectorTileServer', + 'type': 'vector' + } + }, + 'layers': [{ + 'id': 'background', + 'type': 'background', + 'paint': { + 'background-color': '#556688' + } + }, { + 'id': 'Land', + 'type': 'fill', + 'source': 'esri', + 'source-layer': 'Land', + 'paint': { + 'fill-color': '#273344' + }, + }, { + 'id': 'roads', + 'type': 'line', + 'source': 'esri', + 'source-layer': 'Road', + 'layout': { + 'line-join': 'round' + }, + 'paint': { + 'line-width': 1, + 'line-color': '#131622' + } + }] + } + */ }], // set include:true to load. For titlePane type set position the the desired order in the sidebar widgets: { From 1d8ab3d134bf4c7f228e03c2065522628729153f Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 16 Dec 2015 12:34:39 -0800 Subject: [PATCH 029/216] Allow for a widget's `id` to be optional so that the ESRI Search widget can be used with CMV. --- viewer/js/viewer/_WidgetsMixin.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index 8179ed87f..18884f6c0 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -113,7 +113,9 @@ define([ createWidget: function (widgetConfig, options, WidgetClass) { // set any additional options - options.id = widgetConfig.id + '_widget'; + if (widgetConfig.id) { + options.id = widgetConfig.id + '_widget'; + } options.parentWidget = widgetConfig.parentWidget; //replace config map, layerInfos arrays, etc From 29bb313224df2bba913e720af376e0d45681cd72 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 16 Dec 2015 12:50:58 -0800 Subject: [PATCH 030/216] replace geocoder widget with ESRI search widget. ESRI geocoder widget has been deprecated. NOTE: right-click menu is no longer implemented with this change. moved geocoder to over the map and collapsed by default. mobile-first! --- viewer/js/config/viewer.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 20dfcb33e..c0ee61064 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -228,19 +228,15 @@ define([ }, geocoder: { include: true, - id: 'geocoder', type: 'domNode', - path: 'gis/dijit/Geocoder', - srcNodeRef: 'geocodeDijit', + path: 'esri/dijit/Search', + srcNodeRef: 'geocoderButton', options: { map: true, - mapRightClickMenu: true, - geocoderOptions: { - autoComplete: true, - arcgisGeocoder: { - placeholder: 'Enter an address or place' - } - } + visible: true, + enableInfoWindow: false, + enableButtonMode: true, + expanded: false } }, identify: { From c621af9d313b3ec2a71677b5c3312a8af8693d62 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 16 Dec 2015 13:17:59 -0800 Subject: [PATCH 031/216] Add new `_createMap` method to allow custom mixins to override the method. This is useful when using CMV with BootstrapMap (https://github.com/Esri/bootstrap-map-js). --- viewer/js/viewer/_MapMixin.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index 6b3c72027..8d272db58 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -27,8 +27,7 @@ define([ var returnDeferred = new Deferred(); var returnWarnings = []; - var container = dom.byId(this.config.layout.map) || 'mapCenter'; - this.map = new Map(container, this.config.mapOptions); + this._createMap(); if (this.config.mapOptions.basemap) { this.map.on('load', lang.hitch(this, '_initLayers', returnWarnings)); @@ -44,6 +43,11 @@ define([ return returnDeferred; }, + _createMap: function () { + var container = dom.byId(this.config.layout.map) || 'mapCenter'; + this.map = new Map(container, this.config.mapOptions); + }, + _onLayersAddResult: function (returnDeferred, returnWarnings, lyrsResult) { array.forEach(lyrsResult.layers, function (addedLayer) { if (addedLayer.success !== true) { From 2a7556e66469c2e5723d9e18e868614b0a1fa77f Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 13 Jan 2016 08:31:11 -0800 Subject: [PATCH 032/216] remove duplicate rule i eslintrc --- .eslintrc | 1 - 1 file changed, 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index 891a5be59..d755fc467 100644 --- a/.eslintrc +++ b/.eslintrc @@ -153,7 +153,6 @@ "consistent-this": [2, "self"], "constructor-super": 2, "func-style": [2, "declaration"], - "id-match": [2, "^[a-z]+([A-Z][a-z]+)*$", {"properties": true}], "indent": [2, 4], "key-spacing": [2, { "beforeColon": false, From ac7efe6d5c299c687c565fd0b6ce92952e564c86 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 13 Jan 2016 08:36:35 -0800 Subject: [PATCH 033/216] remove another duplicate rule in eslintrc --- .eslintrc | 1 - 1 file changed, 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index d755fc467..c7653194b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -151,7 +151,6 @@ "comma-style": 2, "computed-property-spacing": [2, "never"], "consistent-this": [2, "self"], - "constructor-super": 2, "func-style": [2, "declaration"], "indent": [2, 4], "key-spacing": [2, { From 18bbfdfdc58525bbdbe4171b43d3ac1ccdbf4211 Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Wed, 13 Jan 2016 20:13:28 -0600 Subject: [PATCH 034/216] Added support to add & remove layer(s) from the Layer Control //add new layer function _setupSampleLayer(args) { var layer = args.layer; var target = args.target; layer.setVisibility(true); layer.opacity = 1; for (var i = 0; i < 8; i++) { var eLayerInfo = layer.layerInfos[i]; eLayerInfo.defaultVisibility = true } }; function _loadSampleLayer() { var imageParameters = new esri.layers.ImageParameters(); imageParameters.layerIds = [0,1,2,3,4,5,6,7]; imageParameters.layerOption = esri.layers.ImageParameters.LAYER_OPTION_SHOW; var layer = new esri.layers.ArcGISDynamicMapServiceLayer("http:///arcgis/rest/services//MapServer", {id: "MyMapService", visible : true, imageParameters : imageParameters } ); layer.on("load", function(args) { _setupSampleLayer(args); }); layer.on("error", function(args) { debugger; }); this.app.map.addLayer(layer); this.app.map.on("layer-add-result", function(args) { var layer = args.layer; var error = args.error; var layerInfo = { title : "My Sample Title", type : "dynamic", layer : layer } dojo.publish('layerControl/addLayerControls', [[layerInfo]]); }); } //remove layer dojo.publish("layerControl/removeLayerControls", [["My Sample Title"]]) --- viewer/js/gis/dijit/LayerControl.js | 44 +++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index ec2d89265..9a380bb1b 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -118,10 +118,22 @@ define([ this.overlayReorder = false; this.vectorReorder = false; } - // load only the modules we need + this._addLayerControls(this.layerInfos); + this._subscribeToTopics(); + }, + _subscribeToTopics() { + this._removeLayerControlsHandler = topic.subscribe('layerControl/removeLayerControls', lang.hitch(this, function (layerTitles) { + this._removeLayerControls(layerTitles); + })); + this._addLayerControlsHandler = topic.subscribe('layerControl/addLayerControls', lang.hitch(this, function (layerInfos) { + this._addLayerControls(layerInfos); + })); + }, + _addLayerControls: function(layerInfos) { + // load only the modules we need var modules = []; // push layer control mods - array.forEach(this.layerInfos, function (layerInfo) { + array.forEach(layerInfos, function (layerInfo) { // check if control is excluded var controlOptions = layerInfo.controlOptions; if (controlOptions && controlOptions.exclude === true) { @@ -139,7 +151,7 @@ define([ }, this); // load and go require(modules, lang.hitch(this, function () { - array.forEach(this.layerInfos, function (layerInfo) { + array.forEach(layerInfos, function (layerInfo) { // exclude from widget var controlOptions = layerInfo.controlOptions; if (controlOptions && controlOptions.exclude === true) { @@ -152,6 +164,32 @@ define([ }, this); this._checkReorder(); })); + }, + // remove the control given an array of layerTitles + _removeLayerControls: function (layerTitles) { + // helper function to determine which children's title have a match in the layerTitles parameter + var _filterList = function (entry) { + return layerTitles.reduce(function(prior,curr){ return (curr === entry.layerTitle)||prior}, false); + } + // get a list of ALL the layers that meet the criteria + var layerControlList = this._overlayContainer.getChildren().filter( function(c) { return _filterList(c)}).concat( + this._vectorContainer.getChildren().filter( function(c) { return _filterList(c)}).concat( + this.getChildren().filter( function(c) { return _filterList(c)}) + ) + ); + // follow the same logic as when the layers were added + array.forEach(layerControlList, lang.hitch(this, function (layerControl) { + if (this.separated) { + if (layerControl._layerType === 'overlay') { + this._overlayContainer.removeChild(layerControl); + } else { + this._vectorContainer.removeChild(layerControl); + } + } + else { + this.removeChild(layerControl); + } + })); }, // create layer control and add to appropriate _container _addControl: function (layerInfo, Control) { From cdf2533ef36d6ea1490074b95d558f6bbe7fff72 Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Thu, 14 Jan 2016 13:36:16 -0600 Subject: [PATCH 035/216] Corrected file according to eslint standardized the format of the .js file --- viewer/js/gis/dijit/LayerControl.js | 71 ++++++++++++++++------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 9a380bb1b..bea969f22 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -118,19 +118,19 @@ define([ this.overlayReorder = false; this.vectorReorder = false; } - this._addLayerControls(this.layerInfos); - this._subscribeToTopics(); + this._addLayerControls(this.layerInfos); + this._subscribeToTopics(); }, - _subscribeToTopics() { + _subscribeToTopics: function () { this._removeLayerControlsHandler = topic.subscribe('layerControl/removeLayerControls', lang.hitch(this, function (layerTitles) { - this._removeLayerControls(layerTitles); + this._removeLayerControls(layerTitles); })); this._addLayerControlsHandler = topic.subscribe('layerControl/addLayerControls', lang.hitch(this, function (layerInfos) { - this._addLayerControls(layerInfos); + this._addLayerControls(layerInfos); })); - }, - _addLayerControls: function(layerInfos) { - // load only the modules we need + }, + _addLayerControls: function (layerInfos) { + // load only the modules we need var modules = []; // push layer control mods array.forEach(layerInfos, function (layerInfo) { @@ -164,32 +164,39 @@ define([ }, this); this._checkReorder(); })); - }, + }, // remove the control given an array of layerTitles _removeLayerControls: function (layerTitles) { - // helper function to determine which children's title have a match in the layerTitles parameter - var _filterList = function (entry) { - return layerTitles.reduce(function(prior,curr){ return (curr === entry.layerTitle)||prior}, false); - } - // get a list of ALL the layers that meet the criteria - var layerControlList = this._overlayContainer.getChildren().filter( function(c) { return _filterList(c)}).concat( - this._vectorContainer.getChildren().filter( function(c) { return _filterList(c)}).concat( - this.getChildren().filter( function(c) { return _filterList(c)}) - ) - ); - // follow the same logic as when the layers were added - array.forEach(layerControlList, lang.hitch(this, function (layerControl) { - if (this.separated) { - if (layerControl._layerType === 'overlay') { - this._overlayContainer.removeChild(layerControl); - } else { - this._vectorContainer.removeChild(layerControl); - } - } - else { - this.removeChild(layerControl); - } - })); + // helper function to determine which children's title have a match in the layerTitles parameter + function _filterList (entry) { + return layerTitles.reduce(function (prior, curr) { + return (curr === entry.layerTitle) || prior; + }, false); + } + // get a list of ALL the layers that meet the criteria + var layerControlList = this._overlayContainer.getChildren().filter(function (c) { + return _filterList(c); + }).concat( + this._vectorContainer.getChildren().filter(function (c) { + return _filterList(c); + })).concat( + this.getChildren().filter(function (c) { + return _filterList(c); + })); + + + // follow the same logic as when the layers were added + array.forEach(layerControlList, lang.hitch(this, function (layerControl) { + if (this.separated) { + if (layerControl._layerType === 'overlay') { + this._overlayContainer.removeChild(layerControl); + } else { + this._vectorContainer.removeChild(layerControl); + } + } else { + this.removeChild(layerControl); + } + })); }, // create layer control and add to appropriate _container _addControl: function (layerInfo, Control) { From f1fa53c5f8d6b6d8fcc38f70371f9ec079bbfd1b Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Tue, 19 Jan 2016 16:07:47 -0600 Subject: [PATCH 036/216] Handle the case where a layer is added and re-added and destroying controls when necessary var myLayer; function _setupSampleLayer(args) { var layer = args.layer; var target = args.target; layer.setVisibility(true); layer.opacity = 1; for (var i = 0; i < 8; i++) { var eLayerInfo = layer.layerInfos[i]; eLayerInfo.defaultVisibility = true } }; function _loadSampleLayer() { var imageParameters = new esri.layers.ImageParameters(); imageParameters.layerIds = [0,1,2,3,4,5,6,7]; imageParameters.layerOption = esri.layers.ImageParameters.LAYER_OPTION_SHOW; myLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://hougissrv02:6080/arcgis/rest/services/Integrations_iApps/DEN_iAppsBase/MapServer", {id: "MyMapService", visible : true, imageParameters : imageParameters } ); myLayer.on("load", function(args) { _setupSampleLayer(args); }); myLayer.on("error", function(args) { debugger; }); this.app.map.addLayer(myLayer); this.app.map.on("layer-add-result", function(args) { var layer = args.layer; var error = args.error; var layerInfo = { title : "My Sample Title", type : "dynamic", layer : layer } dojo.publish('layerControl/addLayerControls', [[layerInfo]]); }); } dojo.publish("layerControl/removeLayerControls", [[myLayer]]) --- viewer/js/gis/dijit/LayerControl.js | 15 +++--- .../LayerControl/controls/_DynamicFolder.js | 17 +++++-- .../LayerControl/controls/_DynamicSublayer.js | 50 +++++++++++-------- .../dijit/LayerControl/plugins/legendUtil.js | 22 ++++---- 4 files changed, 62 insertions(+), 42 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index bea969f22..1b9f71e43 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -122,8 +122,8 @@ define([ this._subscribeToTopics(); }, _subscribeToTopics: function () { - this._removeLayerControlsHandler = topic.subscribe('layerControl/removeLayerControls', lang.hitch(this, function (layerTitles) { - this._removeLayerControls(layerTitles); + this._removeLayerControlsHandler = topic.subscribe('layerControl/removeLayerControls', lang.hitch(this, function (layers) { + this._removeLayerControls(layers); })); this._addLayerControlsHandler = topic.subscribe('layerControl/addLayerControls', lang.hitch(this, function (layerInfos) { this._addLayerControls(layerInfos); @@ -165,12 +165,12 @@ define([ this._checkReorder(); })); }, - // remove the control given an array of layerTitles - _removeLayerControls: function (layerTitles) { - // helper function to determine which children's title have a match in the layerTitles parameter + // remove the control given an array of layers + _removeLayerControls: function (layers) { + // helper function to determine which children's layer have a match in the layers parameter function _filterList (entry) { - return layerTitles.reduce(function (prior, curr) { - return (curr === entry.layerTitle) || prior; + return layers.reduce(function (prior, curr) { + return (curr === entry.layer) || prior; }, false); } // get a list of ALL the layers that meet the criteria @@ -196,6 +196,7 @@ define([ } else { this.removeChild(layerControl); } + layerControl.destroy(); })); }, // create layer control and add to appropriate _container diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js index a48e7115e..184512574 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js @@ -33,6 +33,7 @@ define([ // ^args templateString: folderTemplate, _expandClickHandler: null, + _handlers: [], postCreate: function () { this.inherited(arguments); // Should the control be visible or hidden? @@ -47,7 +48,7 @@ define([ } else { this._setSublayerCheckbox(false, checkNode); } - on(checkNode, 'click', lang.hitch(this, function () { + this._handlers.push(on(checkNode, 'click', lang.hitch(this, function () { if (domAttr.get(checkNode, 'data-checked') === 'checked') { this._setSublayerCheckbox(false, checkNode); } else { @@ -55,18 +56,18 @@ define([ } this.control._setVisibleLayers(); this._checkboxScaleRange(); - })); + }))); html.set(this.labelNode, this.sublayerInfo.name); this._expandClick(); if (this.sublayerInfo.minScale !== 0 || this.sublayerInfo.maxScale !== 0) { this._checkboxScaleRange(); - this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')); + this._handlers.push(this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange'))); } }, // add on event to expandClickNode _expandClick: function () { var i = this.icons; - this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, function () { + this._handlers.push(this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, function () { var expandNode = this.expandNode, iconNode = this.expandIconNode; if (domStyle.get(expandNode, 'display') === 'none') { @@ -82,7 +83,7 @@ define([ }).play(); domClass.replace(iconNode, i.folder, i.folderOpen); } - })); + }))); }, // set checkbox based on layer so it's always in sync _setSublayerCheckbox: function (checked, checkNode) { @@ -106,6 +107,12 @@ define([ if ((min !== 0 && scale > min) || (max !== 0 && scale < max)) { domClass.add(node, 'layerControlCheckIconOutScale'); } + }, + destroy: function () { + this.inherited(arguments); + this._handlers.forEach(function (h) { + h.remove(); + }); } }); return _DynamicFolder; diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js index e5749ee90..051d96202 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js @@ -17,23 +17,23 @@ define([ 'dojo/text!./templates/Sublayer.html', 'dojo/i18n!./../nls/resource' ], function ( - declare, - lang, - array, - on, - domClass, - domStyle, - domAttr, - fx, - html, - Menu, - MenuItem, - topic, - WidgetBase, - TemplatedMixin, - sublayerTemplate, - i18n -) { + declare, + lang, + array, + on, + domClass, + domStyle, + domAttr, + fx, + html, + Menu, + MenuItem, + topic, + WidgetBase, + TemplatedMixin, + sublayerTemplate, + i18n + ) { var _DynamicSublayer = declare([WidgetBase, TemplatedMixin], { control: null, sublayerInfo: null, @@ -43,6 +43,7 @@ define([ templateString: sublayerTemplate, i18n: i18n, _expandClickHandler: null, + _handlers: [], postCreate: function () { this.inherited(arguments); // Should the control be visible or hidden? @@ -58,7 +59,7 @@ define([ this._setSublayerCheckbox(false, checkNode); } - on(checkNode, 'click', lang.hitch(this, function () { + this._handlers.push(on(checkNode, 'click', lang.hitch(this, function () { if (domAttr.get(checkNode, 'data-checked') === 'checked') { this._setSublayerCheckbox(false, checkNode); } else { @@ -66,16 +67,16 @@ define([ } this.control._setVisibleLayers(); this._checkboxScaleRange(); - })); + }))); html.set(this.labelNode, this.sublayerInfo.name); this._expandClick(); if (this.sublayerInfo.minScale !== 0 || this.sublayerInfo.maxScale !== 0) { this._checkboxScaleRange(); - this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')); + this._handlers.push(this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange'))); } //set up menu if (this.control.controlOptions.menu && - this.control.controlOptions.menu.length) { + this.control.controlOptions.menu.length) { domClass.add(this.labelNode, 'menuLink'); domClass.add(this.iconNode, 'menuLink'); this.menu = new Menu({ @@ -120,6 +121,7 @@ define([ domClass.replace(iconNode, i.expand, i.collapse); } })); + this._handlers.push(this._expandClickHandler); }, // set checkbox based on layer so it's always in sync _setSublayerCheckbox: function (checked, checkNode) { @@ -143,6 +145,12 @@ define([ if ((min !== 0 && scale > min) || (max !== 0 && scale < max)) { domClass.add(node, 'layerControlCheckIconOutScale'); } + }, + destroy: function () { + this.inherited(arguments); + this._handlers.forEach(function (h) { + h.remove(); + }); } }); return _DynamicSublayer; diff --git a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js index 714fab7ec..2ad840d60 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js @@ -172,15 +172,19 @@ define([ }, row, 'last'); domConst.place(this._image(legend, layerId, layer), symbol); - }, this); - // place legend in the appropriate sublayer expandNode - // or if a single layer use control expandNode - if (layer.layerInfos.length > 1) { - var sublayerExpandNode = registry.byId(layer.id + '-' + _layer.layerId + '-sublayer-control').expandNode; - html.set(sublayerExpandNode, ''); //clear "No Legend" placeholder - domConst.place(table, sublayerExpandNode); - } else { - domConst.place(table, expandNode); + }, this); + if (layer.layerInfos.reduce(function (prior, curr) { + return (curr.id === _layer.layerId) || prior; + }, false)) { + // place legend in the appropriate sublayer expandNode + // or if a single layer use control expandNode + if (layer.layerInfos.length > 1) { + var sublayerExpandNode = registry.byId(layer.id + '-' + _layer.layerId + '-sublayer-control').expandNode; + html.set(sublayerExpandNode, ''); //clear "No Legend" placeholder + domConst.place(table, sublayerExpandNode); + } else { + domConst.place(table, expandNode); + } } }, this); }, From ab3186e23827ffed9ce7d6d292f9b55cfc7cd67a Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Tue, 19 Jan 2016 17:08:38 -0600 Subject: [PATCH 037/216] Add ability to control ordering of new layer in LayerControl var myLayer; function _setupSampleLayer(args) { var layer = args.layer; var target = args.target; layer.setVisibility(true); layer.opacity = 1; for (var i = 0; i < 8; i++) { var eLayerInfo = layer.layerInfos[i]; eLayerInfo.defaultVisibility = true } }; function _loadSampleLayer(requestedPosition) { var imageParameters = new esri.layers.ImageParameters(); imageParameters.layerIds = [0,1,2,3,4,5,6,7]; imageParameters.layerOption = esri.layers.ImageParameters.LAYER_OPTION_SHOW; myLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http:///arcgis/rest/services//MapServer", {id: "MyMapService", visible : true, imageParameters : imageParameters } ); myLayer.on("load", function(args) { _setupSampleLayer(args); }); myLayer.on("error", function(args) { debugger; }); this.app.map.addLayer(myLayer ); var signal = this.app.map.on("layer-add-result", function(args) { signal.remove() var layer = args.layer; var error = args.error; var layerInfo = { title : "My Sample Title", type : "dynamic", layer : layer, position : requestedPosition } dojo.publish('layerControl/addLayerControls', [[layerInfo]]); }); } // function _removeSampleLayer() { dojo.publish("layerControl/removeLayerControls", [[myLayer]]); this.app.map.removeLayer(myLayer); } _loadSampleLayer(0); _removeSampleLayer(); //pause _loadSampleLayer(1); _removeSampleLayer(); //pause _loadSampleLayer(2); _removeSampleLayer(); --- viewer/js/gis/dijit/LayerControl.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 1b9f71e43..d25f0e7d2 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -177,14 +177,12 @@ define([ var layerControlList = this._overlayContainer.getChildren().filter(function (c) { return _filterList(c); }).concat( - this._vectorContainer.getChildren().filter(function (c) { - return _filterList(c); - })).concat( - this.getChildren().filter(function (c) { - return _filterList(c); - })); - - + this._vectorContainer.getChildren().filter(function (c) { + return _filterList(c); + })).concat( + this.getChildren().filter(function (c) { + return _filterList(c); + })); // follow the same logic as when the layers were added array.forEach(layerControlList, lang.hitch(this, function (layerControl) { if (this.separated) { @@ -216,14 +214,15 @@ define([ }, layerInfo.controlOptions) }); layerControl.startup(); + var position = layerInfo.position || 0; if (this.separated) { if (layerControl._layerType === 'overlay') { - this._overlayContainer.addChild(layerControl, 'first'); + this._overlayContainer.addChild(layerControl, position); } else { - this._vectorContainer.addChild(layerControl, 'first'); + this._vectorContainer.addChild(layerControl, position); } } else { - this.addChild(layerControl, 'first'); + this.addChild(layerControl, position); } }, // move control up in controller and layer up in map From 46ab98cfa611616b002f9515c4b34a87b07daa8b Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 28 Jan 2016 17:03:21 -0600 Subject: [PATCH 038/216] Change topic 'LayerControl' to 'layerControl' --- viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js index e5749ee90..72aa7dcaf 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js @@ -91,7 +91,7 @@ define([ //create the menu item var item = new MenuItem(menuItem); item.set('onClick', lang.hitch(this, function () { - topic.publish('LayerControl/' + menuItem.topic, { + topic.publish('layerControl/' + menuItem.topic, { layer: this.control.layer, subLayer: this.sublayerInfo, iconNode: this.iconNode, @@ -146,4 +146,4 @@ define([ } }); return _DynamicSublayer; -}); \ No newline at end of file +}); From a6a565ef44e22b722d7aa3ea16c34a307509f406 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 29 Jan 2016 15:36:58 -0800 Subject: [PATCH 039/216] Adding support for the WFS layer added to the ESRI API at v3.14. This layer is still considered beta in version 3.15. --- viewer/js/gis/dijit/LayerControl.js | 1 + .../js/gis/dijit/LayerControl/controls/WFS.js | 26 +++++++++++++++++++ viewer/js/viewer/_MapMixin.js | 1 + 3 files changed, 28 insertions(+) create mode 100644 viewer/js/gis/dijit/LayerControl/controls/WFS.js diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index ec2d89265..05936dd0c 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -69,6 +69,7 @@ define([ csv: './LayerControl/controls/CSV', georss: './LayerControl/controls/GeoRSS', wms: './LayerControl/controls/WMS', + wfs: './LayerControl/controls/WFS', kml: './LayerControl/controls/KML', vectortile: './LayerControl/controls/VectorTile', webtiled: './LayerControl/controls/WebTiled', diff --git a/viewer/js/gis/dijit/LayerControl/controls/WFS.js b/viewer/js/gis/dijit/LayerControl/controls/WFS.js new file mode 100644 index 000000000..7ce625934 --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/controls/WFS.js @@ -0,0 +1,26 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_Contained', + './_Control', // layer control base class + './../plugins/legendUtil' +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + _Contained, + _Control, + legendUtil +) { + 'use strict'; + + var WFSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { + _layerType: 'vector', // constant + _esriLayerType: 'wfs', // constant + _layerTypeInit: function () { + this._expandRemove(); + } + }); + return WFSControl; +}); \ No newline at end of file diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index 8d272db58..ca0e9a8c5 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -76,6 +76,7 @@ define([ tiled: 'ArcGISTiledMapService', vectortile: 'VectorTile', webtiled: 'WebTiled', + wfs: 'WFS', wms: 'WMS', wmts: 'WMTS' //untested }; From e6363b64388e6b7edda96aa5e6f4165bca3c34b8 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 29 Jan 2016 16:08:53 -0800 Subject: [PATCH 040/216] removed unused `legendUtil` var --- viewer/js/gis/dijit/LayerControl/controls/WFS.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl/controls/WFS.js b/viewer/js/gis/dijit/LayerControl/controls/WFS.js index 7ce625934..51e3415e7 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/WFS.js +++ b/viewer/js/gis/dijit/LayerControl/controls/WFS.js @@ -10,8 +10,7 @@ define([ _WidgetBase, _TemplatedMixin, _Contained, - _Control, - legendUtil + _Control ) { 'use strict'; From 12d0865e08255f1b7c86dc8d670f36a20deebcef Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Tue, 1 Mar 2016 13:46:29 -0600 Subject: [PATCH 041/216] Add dynamic layer legend to LayerList Control for DynamicMapServices Use the layerDrawingOptions of a dynamic map service to generate the LayerList legend --- .../dijit/LayerControl/plugins/legendUtil.js | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js index 2ad840d60..a77212ed6 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js @@ -58,14 +58,22 @@ define([ }, // request legend json _legendRequest: function (layer, expandNode, callback, errback) { + var content = { + f: 'json', + token: (typeof layer._getToken === 'function') ? layer._getToken() : null + }, + options = {disableIdentityLookup: false, + usePost: false, + useProxy: false}; + if (layer.layerDrawingOptions && layer.layerDrawingOptions.length > 0) { + content.dynamicLayers = this._createDynamicLayerParameter(layer); + options.usePost = true; + } esriRequest({ url: layer.url + '/legend', callbackParamName: 'callback', - content: { - f: 'json', - token: (typeof layer._getToken === 'function') ? layer._getToken() : null - } - }).then( + content: content + }, options).then( lang.hitch(this, callback, layer, expandNode), lang.hitch(this, errback, layer, expandNode) ); @@ -172,7 +180,7 @@ define([ }, row, 'last'); domConst.place(this._image(legend, layerId, layer), symbol); - }, this); + }, this); if (layer.layerInfos.reduce(function (prior, curr) { return (curr.id === _layer.layerId) || prior; }, false)) { @@ -305,6 +313,30 @@ define([ // place legend in expandNode domConst.place(table, expandNode); }, this); + }, + _createDynamicLayerParameter: function (layer) { + if (layer.dynamicLayerInfos && layer.dynamicLayerInfos.length > 0 || layer.layerDrawingOptions && layer.layerDrawingOptions.length > 0) { + layer.dynamicLayerInfos = layer.createDynamicLayerInfosFromLayerInfos(); + var dlis = layer.dynamicLayerInfos, + param = []; + dlis.forEach(function (dli) { + if (!dli.subLayerIds) { + var e, i = dli.id; + e = { + id: i, + name: dli.name + }; + if (dli.source) { + e.source = dli.source.toJson(); + } + if (layer.layerDrawingOptions && layer.layerDrawingOptions[i]) { + e.drawingInfo = layer.layerDrawingOptions[i].toJson(); + } + param.push(e); + } + }, this); + return JSON.stringify(param); + } } }; }); \ No newline at end of file From 4b3156a33a2a583ed140697496e374e0fb7d457c Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Tue, 1 Mar 2016 14:52:41 -0600 Subject: [PATCH 042/216] Control dynamic map service sublayers These changes allow the user to have granular control over each subLayer in a dynamic Map service. Now, instead of having to just use the name of the layer in the map, you can override it to whatever you'd like. you can also redefine the min/max scale of the subLayer. see the layerInfo properties defined here: https://developers.arcgis.com/javascript/jsapi/layerinfo-amd.html In addition to the subLayerInfo support, i've added two other properties to the layerControlLayerInfos object. 1) subLayerInfos : array of layerInfos that should override the dynamic map service's default layerInfos 2) excludedLayers : an array of layer ids that should not be exposed in the map service 3) includeUnspecifiedLayers: boolean --> if true, then all layers in the dynamic map service will be added, not just the ones listed in subLayerInfos. the excludeLayers list will still be honored. layerControlLayerInfos: { //layerIds: [0, 2, 4, 5, 8, 9, 10, 12, 21] includeUnspecifiedLayers : true, excludedLayers : [1,3], subLayerInfos: [{id:0,name:"Layer 1",defaultVisibility:false},{id:2,name:"Layer 2"},{id:4,name:"Layer 3"},{id:5,name:"Layer 4"},{id:8,name:"Layer 5"},{id:9},{id:10},{id:12,name:"Layer 6"},{id:21,name:"Layer 7"}] }, --- viewer/js/config/viewer.js | 5 +- .../dijit/LayerControl/controls/Dynamic.js | 47 +++++++++------ .../LayerControl/controls/_DynamicFolder.js | 9 +++ .../LayerControl/controls/_DynamicSublayer.js | 10 +++- viewer/js/viewer/_MapMixin.js | 59 ++++++++++++++++++- 5 files changed, 109 insertions(+), 21 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index c0ee61064..6547c2ff3 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -133,7 +133,10 @@ define([ layerIds: [2, 4, 5, 8, 12, 21] }, layerControlLayerInfos: { - layerIds: [0, 2, 4, 5, 8, 9, 10, 12, 21] + //layerIds: [0, 2, 4, 5, 8, 9, 10, 12, 21] + includeUnspecifiedLayers : true, + //excludedLayers : [1,3], + subLayerInfos: [{id:0,name:"Layer 1",defaultVisibility:false},{id:2,name:"Layer 2"},{id:4,name:"Layer 3"},{id:5,name:"Layer 4"},{id:8,name:"Layer 5"},{id:9},{id:10},{id:12,name:"Layer 6"},{id:21,name:"Layer 7"}] }, legendLayerInfos: { layerInfo: { diff --git a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js index c872142d7..974139148 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js @@ -100,29 +100,40 @@ define([ _createSublayers: function (layer) { // check for single sublayer - if so no sublayer/folder controls if (layer.layerInfos.length > 1) { + var allLayers = array.map(layer.layerInfos, function (l) { + return l.id; + }); array.forEach(layer.layerInfos, lang.hitch(this, function (info) { + // see if there was any override needed from the subLayerInfos array in the controlOptions + var sublayerInfo = array.filter(this.controlOptions.subLayerInfos, function (sli) { + return sli.id === info.id; + }).shift(); + lang.mixin(info, sublayerInfo); var pid = info.parentLayerId, slids = info.subLayerIds, controlId = layer.id + '-' + info.id + '-sublayer-control', control; - if (pid === -1 && slids === null) { - // it's a top level sublayer - control = new DynamicSublayer({ - id: controlId, - control: this, - sublayerInfo: info, - icons: this.icons - }); - domConst.place(control.domNode, this.expandNode, 'last'); - } else if (pid === -1 && slids !== null) { - // it's a top level folder - control = new DynamicFolder({ - id: controlId, - control: this, - sublayerInfo: info, - icons: this.icons - }); - domConst.place(control.domNode, this.expandNode, 'last'); + // it's a top level + if (pid === -1 || allLayers.indexOf(pid) === -1) { + if (slids === null) { + // it's a top level sublayer + control = new DynamicSublayer({ + id: controlId, + control: this, + sublayerInfo: info, + icons: this.icons + }); + domConst.place(control.domNode, this.expandNode, 'last'); + } else if (slids !== null) { + // it's a top level folder + control = new DynamicFolder({ + id: controlId, + control: this, + sublayerInfo: info, + icons: this.icons + }); + domConst.place(control.domNode, this.expandNode, 'last'); + } } else if (pid !== -1 && slids !== null) { // it's a nested folder control = new DynamicFolder({ diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js index 184512574..f70c9ca65 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js @@ -36,6 +36,15 @@ define([ _handlers: [], postCreate: function () { this.inherited(arguments); + // Should the control be visible or hidden (depends on subLayerInfos)? + if (this.control.controlOptions.subLayerInfos && !this.control.controlOptions.includeUnspecifiedLayers) { + var subLayerInfos = array.map(this.control.controlOptions.subLayerInfos, function (sli) { + return sli.id; + }); + if (array.indexOf(subLayerInfos, this.sublayerInfo.id) < 0) { + domClass.add(this.domNode, 'layerControlHidden'); + } + } // Should the control be visible or hidden? if (this.control.controlOptions.layerIds && array.indexOf(this.control.controlOptions.layerIds, this.sublayerInfo.id) < 0) { domClass.add(this.domNode, 'layerControlHidden'); diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js index c245e5548..e9a7d0fbd 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js @@ -46,6 +46,15 @@ define([ _handlers: [], postCreate: function () { this.inherited(arguments); + // Should the control be visible or hidden (depends on subLayerInfos)? + if (this.control.controlOptions.subLayerInfos && !this.control.controlOptions.includeUnspecifiedLayers) { + var subLayerInfos = array.map(this.control.controlOptions.subLayerInfos, function (sli) { + return sli.id; + }); + if (array.indexOf(subLayerInfos, this.sublayerInfo.id) < 0) { + domClass.add(this.domNode, 'layerControlHidden'); + } + } // Should the control be visible or hidden? if (this.control.controlOptions.layerIds && array.indexOf(this.control.controlOptions.layerIds, this.sublayerInfo.id) < 0) { domClass.add(this.domNode, 'layerControlHidden'); @@ -56,7 +65,6 @@ define([ if (array.indexOf(this.control.layer.visibleLayers, this.sublayerInfo.id) !== -1) { this._setSublayerCheckbox(true, checkNode); } else { - this._setSublayerCheckbox(false, checkNode); } this._handlers.push(on(checkNode, 'click', lang.hitch(this, function () { diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index ca0e9a8c5..396db7094 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -159,9 +159,66 @@ define([ if (idOptions.exclude !== true) { this.identifyLayerInfos.push(idOptions); } + if (layer.layerControlLayerInfos) { + l.on('load', lang.hitch(this, '_applyLayerControlOptions', layer.layerControlLayerInfos)); + } + } + }, + _applyLayerControlOptions: function (controlOptions, args) { + if (typeof controlOptions.includeUnspecifiedLayers === 'undefined' && typeof controlOptions.subLayerInfos === 'undefined' && typeof controlOptions.excludedLayers === 'undefined') { + return; + } + var esriLayerInfos = [], + layer = args.layer; + // Case 1: only show the layers that are explicitly listed + if (!controlOptions.includeUnspecifiedLayers && controlOptions.subLayerInfos && controlOptions.subLayerInfos.length !== 0) { + var subLayerInfos = array.map(controlOptions.subLayerInfos, function (sli) { + return sli.id; + }); + array.forEach(layer.layerInfos, function (li) { + if (array.indexOf(subLayerInfos, li.id) !== -1) { + esriLayerInfos.push(li); + } + }); + // Case 2: show ALL layers except those in the excluded list + } else if (controlOptions.excludedLayers) { + array.forEach(layer.layerInfos, function (li) { + if (array.indexOf(controlOptions.excludedLayers, li.id) === -1) { + esriLayerInfos.push(li); + } + }); + // Case 3: just override the values found in the subLayerInfos + } else if (controlOptions.subLayerInfos) { + // show ALL layers that are in the map service's layerInfos, but take care to override the properties of each subLayerInfo as configured + this._mixinLayerInfos(layer.layerInfos, controlOptions.subLayerInfos); + return; + } + // Finally, if we made use of the esriLayerInfos, make sure to apply all the subLayerInfos that were defined to our new array of esri layer infos + if (controlOptions.subLayerInfos) { + this._mixinLayerInfos(esriLayerInfos, controlOptions.subLayerInfos); + } + layer.layerInfos = esriLayerInfos; + }, + _mixinLayerInfos: function (esriLayerInfos, subLayerInfos) { + // for each of the sublayers, go through the subLayerInfos from the controlOptions and see if defaultVisiblity is set to true or false + // then set each of the layer.layerInfos defaultVisibility appropriately + // assume defaultVisibility is true if it's not defined + if (subLayerInfos && subLayerInfos.length !== 0) { + array.forEach(subLayerInfos, function (sli) { + if (typeof sli.defaultVisibility === 'undefined') { + sli.defaultVisibility = true; + } + }); + array.forEach(esriLayerInfos, function (li) { + var sli = array.filter(subLayerInfos, function (s) { + return s.id === li.id; + }).shift(); + if (sli) { + lang.mixin(li, sli); + } + }); } }, - initMapComplete: function (warnings) { if (warnings && warnings.length > 0) { this.handleError({ From 6627e80a3caf848f36d4480823a717af7045c665 Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Tue, 1 Mar 2016 14:55:04 -0600 Subject: [PATCH 043/216] reverted viewer.js reverted viewer.js --- viewer/js/config/viewer.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 6547c2ff3..c0ee61064 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -133,10 +133,7 @@ define([ layerIds: [2, 4, 5, 8, 12, 21] }, layerControlLayerInfos: { - //layerIds: [0, 2, 4, 5, 8, 9, 10, 12, 21] - includeUnspecifiedLayers : true, - //excludedLayers : [1,3], - subLayerInfos: [{id:0,name:"Layer 1",defaultVisibility:false},{id:2,name:"Layer 2"},{id:4,name:"Layer 3"},{id:5,name:"Layer 4"},{id:8,name:"Layer 5"},{id:9},{id:10},{id:12,name:"Layer 6"},{id:21,name:"Layer 7"}] + layerIds: [0, 2, 4, 5, 8, 9, 10, 12, 21] }, legendLayerInfos: { layerInfo: { From bf69c2a55a39f79eadef87c580713d73a6306b30 Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Tue, 1 Mar 2016 14:58:15 -0600 Subject: [PATCH 044/216] Reorganize _Control in order to destroy Reorganize _Control in order to destroy --- .../dijit/LayerControl/controls/_Control.js | 93 ++++++++++--------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl/controls/_Control.js b/viewer/js/gis/dijit/LayerControl/controls/_Control.js index b716ffa5a..6dd6a8b08 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_Control.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_Control.js @@ -44,6 +44,7 @@ define([ if (params.controller) { this.icons = params.controller.icons; } // if not you've got bigger problems + this._handlers = []; }, postCreate: function () { this.inherited(arguments); @@ -67,7 +68,7 @@ define([ if (this.layer.loaded) { this._initialize(); } else { - this.layer.on('load', lang.hitch(this, '_initialize')); + this._handlers.push(this.layer.on('load', lang.hitch(this, '_initialize'))); } }, // initialize the control @@ -80,17 +81,8 @@ define([ controlOptions = this.controlOptions; // set checkbox this._setLayerCheckbox(layer, this.checkNode); - // wire up layer visibility - on(this.checkNode, 'click', lang.hitch(this, '_setLayerVisibility', layer, this.checkNode)); // set title html.set(this.labelNode, this.layerTitle); - // wire up updating indicator - layer.on('update-start', lang.hitch(this, function () { - domStyle.set(this.layerUpdateNode, 'display', 'inline-block'); //font awesome display - })); - layer.on('update-end', lang.hitch(this, function () { - domStyle.set(this.layerUpdateNode, 'display', 'none'); - })); // create layer menu if ((controlOptions.noMenu !== true && this.controller.noMenu !== true) || (this.controller.noMenu === true && controlOptions.noMenu === false)) { this.layerMenu = new LayerMenu({ @@ -109,19 +101,6 @@ define([ this._checkboxScaleRange(); this._scaleRangeHandler = layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')); } - // if layer scales change - this.layer.on('scale-range-change', lang.hitch(this, function () { - if (layer.minScale !== 0 || layer.maxScale !== 0) { - this._checkboxScaleRange(); - this._scaleRangeHandler = layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')); - } else { - this._checkboxScaleRange(); - if (this._scaleRangeHandler) { - this._scaleRangeHandler.remove(); - this._scaleRangeHandler = null; - } - } - })); // a function in each control widget for layer type specifics like legends and such this._layerTypeInit(); // show expandNode @@ -131,30 +110,36 @@ define([ } // esri layer's don't inherit from Stateful // connect to update events to handle "watching" layers - layer.on('update-start', lang.hitch(this, '_updateStart')); - layer.on('update-end', lang.hitch(this, '_updateEnd')); - layer.on('visibility-change', lang.hitch(this, '_visibilityChange')); + this._handlers.push( + on(this.checkNode, 'click', lang.hitch(this, '_setLayerVisibility', layer, this.checkNode)), + layer.on('scale-range-change', lang.hitch(this, '_scaleRangeChange')), + layer.on('update-start', lang.hitch(this, '_updateStart')), + layer.on('update-end', lang.hitch(this, '_updateEnd')), + layer.on('visibility-change', lang.hitch(this, '_visibilityChange')) + ); }, // add on event to expandClickNode _expandClick: function () { - var i = this.icons; - this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, function () { - var expandNode = this.expandNode, - iconNode = this.expandIconNode; - if (domStyle.get(expandNode, 'display') === 'none') { - fx.wipeIn({ - node: expandNode, - duration: 300 - }).play(); - domClass.replace(iconNode, i.collapse, i.expand); - } else { - fx.wipeOut({ - node: expandNode, - duration: 300 - }).play(); - domClass.replace(iconNode, i.expand, i.collapse); - } - })); + this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, '_expandClicked')); + this._handlers.push(this._expandClickHandler); + }, + _expandClicked: function () { + var i = this.icons, + expandNode = this.expandNode, + iconNode = this.expandIconNode; + if (domStyle.get(expandNode, 'display') === 'none') { + fx.wipeIn({ + node: expandNode, + duration: 300 + }).play(); + domClass.replace(iconNode, i.collapse, i.expand); + } else { + fx.wipeOut({ + node: expandNode, + duration: 300 + }).play(); + domClass.replace(iconNode, i.expand, i.collapse); + } }, // removes the icons and cursor:pointer from expandClickNode and destroys expandNode _expandRemove: function () { @@ -206,8 +191,21 @@ define([ domClass.add(node, 'layerControlCheckIconOutScale'); } }, + _scaleRangeChange: function () { + if (this.layer.minScale !== 0 || this.layer.maxScale !== 0) { + this._checkboxScaleRange(); + this._scaleRangeHandler = this.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')); + } else { + this._checkboxScaleRange(); + if (this._scaleRangeHandler) { + this._scaleRangeHandler.remove(); + this._scaleRangeHandler = null; + } + } + }, // anything the widget may need to do before update _updateStart: function () { + domStyle.set(this.layerUpdateNode, 'display', 'inline-block'); //font awesome display // clone a layer state before layer updates for use after update this._layerState = lang.clone({ visible: this.layer.visible, @@ -216,6 +214,7 @@ define([ }, // anything the widget may need to do after update _updateEnd: function () { + domStyle.set(this.layerUpdateNode, 'display', 'none'); // how to handle external layer.setVisibleLayers() ??? // // without topics to get/set sublayer state this will be challenging @@ -234,6 +233,12 @@ define([ if ((r.visible && domAttr.get(this.checkNode, 'data-checked') === 'unchecked') || (!r.visible && domAttr.get(this.checkNode, 'data-checked') === 'checked')) { this._setLayerCheckbox(this.layer, this.checkNode); } + }, + destroy: function () { + this.inherited(arguments); + this._handlers.forEach(function (h) { + h.remove(); + }); } }); return _Control; From cd1e2b908e57343e5c010462688e0e7536d5a24f Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Thu, 3 Mar 2016 16:02:49 -0600 Subject: [PATCH 045/216] Update the basemap via publish We can change the basemap with events dojo.publish('basemaps/updateBasemap',['gray']) --- viewer/js/gis/dijit/Basemaps.js | 42 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index fdee8dcc5..7ce37ddb4 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -8,6 +8,7 @@ define([ 'dijit/DropDownMenu', 'dijit/MenuItem', 'dojo/_base/array', + 'dojo/topic', 'dojox/lang/functional', 'dojo/text!./Basemaps/templates/Basemaps.html', 'esri/dijit/BasemapGallery', @@ -15,7 +16,7 @@ define([ 'dijit/form/DropDownButton', 'xstyle/css!./Basemaps/css/Basemaps.css' -], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, DropDownMenu, MenuItem, array, functional, template, BasemapGallery, i18n) { +], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, DropDownMenu, MenuItem, array, topic, functional, template, BasemapGallery, i18n) { // main basemap widget return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { @@ -72,31 +73,32 @@ define([ id: basemap, label: this.basemaps[basemap].title, iconClass: (basemap === this.mapStartBasemap) ? 'selectedIcon' : 'emptyIcon', - onClick: lang.hitch(this, function () { - if (basemap !== this.currentBasemap) { - this.currentBasemap = basemap; - if (this.mode === 'custom') { - this.gallery.select(basemap); - } else { - this.map.setBasemap(basemap); - } - var ch = this.menu.getChildren(); - array.forEach(ch, function (c) { - if (c.id === basemap) { - c.set('iconClass', 'selectedIcon'); - } else { - c.set('iconClass', 'emptyIcon'); - } - }); - } - }) + onClick: lang.hitch(this, 'updateBasemap', basemap) }); this.menu.addChild(menuItem); } }, this); - + topic.subscribe('basemaps/updateBasemap', lang.hitch(this, 'updateBasemap')); this.dropDownButton.set('dropDown', this.menu); }, + updateBasemap: function (basemap) { + if (basemap !== this.currentBasemap && (array.indexOf(this.basemapsToShow, basemap) !== -1)) { + this.currentBasemap = basemap; + if (this.mode === 'custom') { + this.gallery.select(basemap); + } else { + this.map.setBasemap(basemap); + } + var ch = this.menu.getChildren(); + array.forEach(ch, function (c) { + if (c.id === basemap) { + c.set('iconClass', 'selectedIcon'); + } else { + c.set('iconClass', 'emptyIcon'); + } + }); + } + }, startup: function () { this.inherited(arguments); if (this.mode === 'custom') { From 11498e251899cbdcb6a10a0f7ec7a605ba0bf1bd Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 4 Mar 2016 20:42:20 -0800 Subject: [PATCH 046/216] Update the ESRI JavaScript API to version 3.16 --- viewer/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/index.html b/viewer/index.html index 4899cf70a..ca69ab38d 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -11,7 +11,7 @@ Configurable Map Viewer - + @@ -41,7 +41,7 @@ - + From aa66fd4fd554e9306c0846781beb4e0e103d581f Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 4 Mar 2016 20:43:25 -0800 Subject: [PATCH 047/216] Add additional ESRI basemaps available at version 3.16 of JavaScript API. --- viewer/js/config/basemaps.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 28bd4bd92..c7c36fa5d 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -27,6 +27,15 @@ define([ streets: { title: 'Streets' }, + 'streets-night-vector': { + title: 'Streets (Night)' + }, + 'streets-navigation-vector': { + title: 'Streets (Navigation)' + }, + 'streets-relief-vector': { + title: 'Street (Relief)' + }, satellite: { title: 'Satellite' }, @@ -36,9 +45,15 @@ define([ topo: { title: 'Topo' }, - gray: { + 'terrain': { + title: 'Terrain' + }, + 'gray-vector': { title: 'Gray' }, + 'dark-gray-vector': { + title: 'Dark Gray' + }, oceans: { title: 'Oceans' }, From 2660f1bf94036cdcceeb211c3d245d1d41db1bc2 Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Mon, 7 Mar 2016 20:12:15 -0600 Subject: [PATCH 048/216] Move layerInfo mixin into the LayerControl widget This change caught some layers at a point where they were already loaded. As a result, we'll need to explicitly set the visibleLayers on the layer --- viewer/js/gis/dijit/LayerControl.js | 74 ++++++++++++++++++++++++++++- viewer/js/viewer/_MapMixin.js | 58 ---------------------- 2 files changed, 73 insertions(+), 59 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 994b4aa44..2c44eb93e 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -200,9 +200,17 @@ define([ }, // create layer control and add to appropriate _container _addControl: function (layerInfo, Control) { + var layer = (typeof layerInfo.layer === 'string') ? this.map.getLayer(layerInfo.layer) : layerInfo.layer; + if (layerInfo.controlOptions && (layerInfo.type === 'dynamic' || layerInfo.type === 'feature')) { + if (layer.loaded) { + this._applyLayerControlOptions(layerInfo.controlOptions, layer); + } else { + layer.on('load', lang.hitch(this, '_applyLayerControlOptions', layer.controlOptions)); + } + } var layerControl = new Control({ controller: this, - layer: (typeof layerInfo.layer === 'string') ? this.map.getLayer(layerInfo.layer) : layerInfo.layer, // check if we have a layer or just a layer id + layer: layer, layerTitle: layerInfo.title, controlOptions: lang.mixin({ noLegend: null, @@ -226,6 +234,70 @@ define([ this.addChild(layerControl, position); } }, + _applyLayerControlOptions: function (controlOptions, layer) { + if (typeof controlOptions.includeUnspecifiedLayers === 'undefined' && typeof controlOptions.subLayerInfos === 'undefined' && typeof controlOptions.excludedLayers === 'undefined') { + return; + } + var esriLayerInfos = []; + // Case 1: only show the layers that are explicitly listed + if (!controlOptions.includeUnspecifiedLayers && controlOptions.subLayerInfos && controlOptions.subLayerInfos.length !== 0) { + var subLayerInfos = array.map(controlOptions.subLayerInfos, function (sli) { + return sli.id; + }); + array.forEach(layer.layerInfos, function (li) { + if (array.indexOf(subLayerInfos, li.id) !== -1) { + esriLayerInfos.push(li); + } + }); + // Case 2: show ALL layers except those in the excluded list + } else if (controlOptions.excludedLayers) { + array.forEach(layer.layerInfos, function (li) { + if (array.indexOf(controlOptions.excludedLayers, li.id) === -1) { + esriLayerInfos.push(li); + } + }); + // Case 3: just override the values found in the subLayerInfos + } else if (controlOptions.subLayerInfos) { + // show ALL layers that are in the map service's layerInfos, but take care to override the properties of each subLayerInfo as configured + this._mixinLayerInfos(layer.layerInfos, controlOptions.subLayerInfos); + this._setSublayerVisibilities(layer); + return; + } + // Finally, if we made use of the esriLayerInfos, make sure to apply all the subLayerInfos that were defined to our new array of esri layer infos + if (controlOptions.subLayerInfos) { + this._mixinLayerInfos(esriLayerInfos, controlOptions.subLayerInfos); + } + layer.layerInfos = esriLayerInfos; + this._setSublayerVisibilities(layer); + }, + _setSublayerVisibilities: function (layer) { + var visibleIds = array.map(array.filter(layer.layerInfos, function (li) { + return li.defaultVisibility; + }), function (l) { + return l.id; + }); + layer.setVisibleLayers(visibleIds); + }, + _mixinLayerInfos: function (esriLayerInfos, subLayerInfos) { + // for each of the sublayers, go through the subLayerInfos from the controlOptions and see if defaultVisiblity is set to true or false + // then set each of the layer.layerInfos defaultVisibility appropriately + // assume defaultVisibility is true if it's not defined + if (subLayerInfos && subLayerInfos.length !== 0) { + array.forEach(subLayerInfos, function (sli) { + if (typeof sli.defaultVisibility === 'undefined') { + sli.defaultVisibility = true; + } + }); + array.forEach(esriLayerInfos, function (li) { + var sli = array.filter(subLayerInfos, function (s) { + return s.id === li.id; + }).shift(); + if (sli) { + lang.mixin(li, sli); + } + }); + } + }, // move control up in controller and layer up in map _moveUp: function (control) { var id = control.layer.id, diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index 396db7094..f265319dd 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -159,64 +159,6 @@ define([ if (idOptions.exclude !== true) { this.identifyLayerInfos.push(idOptions); } - if (layer.layerControlLayerInfos) { - l.on('load', lang.hitch(this, '_applyLayerControlOptions', layer.layerControlLayerInfos)); - } - } - }, - _applyLayerControlOptions: function (controlOptions, args) { - if (typeof controlOptions.includeUnspecifiedLayers === 'undefined' && typeof controlOptions.subLayerInfos === 'undefined' && typeof controlOptions.excludedLayers === 'undefined') { - return; - } - var esriLayerInfos = [], - layer = args.layer; - // Case 1: only show the layers that are explicitly listed - if (!controlOptions.includeUnspecifiedLayers && controlOptions.subLayerInfos && controlOptions.subLayerInfos.length !== 0) { - var subLayerInfos = array.map(controlOptions.subLayerInfos, function (sli) { - return sli.id; - }); - array.forEach(layer.layerInfos, function (li) { - if (array.indexOf(subLayerInfos, li.id) !== -1) { - esriLayerInfos.push(li); - } - }); - // Case 2: show ALL layers except those in the excluded list - } else if (controlOptions.excludedLayers) { - array.forEach(layer.layerInfos, function (li) { - if (array.indexOf(controlOptions.excludedLayers, li.id) === -1) { - esriLayerInfos.push(li); - } - }); - // Case 3: just override the values found in the subLayerInfos - } else if (controlOptions.subLayerInfos) { - // show ALL layers that are in the map service's layerInfos, but take care to override the properties of each subLayerInfo as configured - this._mixinLayerInfos(layer.layerInfos, controlOptions.subLayerInfos); - return; - } - // Finally, if we made use of the esriLayerInfos, make sure to apply all the subLayerInfos that were defined to our new array of esri layer infos - if (controlOptions.subLayerInfos) { - this._mixinLayerInfos(esriLayerInfos, controlOptions.subLayerInfos); - } - layer.layerInfos = esriLayerInfos; - }, - _mixinLayerInfos: function (esriLayerInfos, subLayerInfos) { - // for each of the sublayers, go through the subLayerInfos from the controlOptions and see if defaultVisiblity is set to true or false - // then set each of the layer.layerInfos defaultVisibility appropriately - // assume defaultVisibility is true if it's not defined - if (subLayerInfos && subLayerInfos.length !== 0) { - array.forEach(subLayerInfos, function (sli) { - if (typeof sli.defaultVisibility === 'undefined') { - sli.defaultVisibility = true; - } - }); - array.forEach(esriLayerInfos, function (li) { - var sli = array.filter(subLayerInfos, function (s) { - return s.id === li.id; - }).shift(); - if (sli) { - lang.mixin(li, sli); - } - }); } }, initMapComplete: function (warnings) { From edfac16cb9fba5e8e283f58c36d1787fd0194bb2 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 16 Mar 2016 17:46:23 -0700 Subject: [PATCH 049/216] The ESRI Bookmarks widget in version 3.16 now requires a unique id. Otherwise it fails. --- viewer/js/gis/dijit/Bookmarks.js | 1 + 1 file changed, 1 insertion(+) diff --git a/viewer/js/gis/dijit/Bookmarks.js b/viewer/js/gis/dijit/Bookmarks.js index 3f6572934..3224674e0 100644 --- a/viewer/js/gis/dijit/Bookmarks.js +++ b/viewer/js/gis/dijit/Bookmarks.js @@ -23,6 +23,7 @@ define([ this.bookmarks = new Bookmarks({ map: this.map, + id: this.id + '_esri', editable: this.editable, bookmarks: lang.mixin(this.bookmarkItems, bookmarks) }, this.domNode); From ac12c93e4845854f09ec87b6d4c16df1bf36b4c0 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 20 Mar 2016 12:09:07 -0700 Subject: [PATCH 050/216] combined arcgis online (agol) and custom basemaps using `esri/basemaps` maintained support for existing agol and custom configurations removed BasemapGallery widget custom basemaps allowing for more custom map types --- viewer/js/gis/dijit/Basemaps.js | 80 ++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index 7ce37ddb4..ff655a1d4 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -4,28 +4,48 @@ define([ 'dijit/_WidgetBase', 'dijit/_TemplatedMixin', 'dijit/_WidgetsInTemplateMixin', + 'dojo/_base/lang', - 'dijit/DropDownMenu', - 'dijit/MenuItem', 'dojo/_base/array', 'dojo/topic', - 'dojox/lang/functional', + + 'dijit/DropDownMenu', + 'dijit/MenuItem', + + 'esri/basemaps', + 'dojo/text!./Basemaps/templates/Basemaps.html', - 'esri/dijit/BasemapGallery', 'dojo/i18n!./Basemaps/nls/resource', 'dijit/form/DropDownButton', 'xstyle/css!./Basemaps/css/Basemaps.css' -], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, DropDownMenu, MenuItem, array, topic, functional, template, BasemapGallery, i18n) { +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + _WidgetsInTemplateMixin, + + lang, + array, + topic, + + DropDownMenu, + MenuItem, + + esriBasemaps, + + template, + i18n +) { - // main basemap widget return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { templateString: template, widgetsInTemplate: true, i18n: i18n, - mode: 'agol', title: i18n.title, + basemaps: {}, + currentBasemap: null, mapStartBasemap: null, basemapsToShow: null, @@ -50,25 +70,22 @@ define([ this.mapStartBasemap = this.basemapsToShow[0]; } - this.currentBasemap = this.mapStartBasemap || null; - - if (this.mode === 'custom') { - this.gallery = new BasemapGallery({ - map: this.map, - showArcGISBasemaps: false, - basemaps: functional.map(this.basemaps, function (map) { - return map.basemap; - }) - }); - this.gallery.startup(); - } - this.menu = new DropDownMenu({ style: 'display: none;' }); array.forEach(this.basemapsToShow, function (basemap) { if (this.basemaps.hasOwnProperty(basemap)) { + // add any custom to the esri basemaps + var basemapObj = this.basemaps[basemap]; + if (basemapObj.basemap) { + if (!esriBasemaps[basemap]) { + if (!basemapObj.basemap.title) { + basemapObj.basemap.title = basemapObj.title || basemap; + } + esriBasemaps[basemap] = basemapObj.basemap; + } + } var menuItem = new MenuItem({ id: basemap, label: this.basemaps[basemap].title, @@ -81,14 +98,15 @@ define([ topic.subscribe('basemaps/updateBasemap', lang.hitch(this, 'updateBasemap')); this.dropDownButton.set('dropDown', this.menu); }, + updateBasemap: function (basemap) { if (basemap !== this.currentBasemap && (array.indexOf(this.basemapsToShow, basemap) !== -1)) { - this.currentBasemap = basemap; - if (this.mode === 'custom') { - this.gallery.select(basemap); - } else { - this.map.setBasemap(basemap); + if (!this.basemaps.hasOwnProperty(basemap)) { + return; } + this.currentBasemap = basemap; + this.map.setBasemap(basemap); + var ch = this.menu.getChildren(); array.forEach(ch, function (c) { if (c.id === basemap) { @@ -99,15 +117,13 @@ define([ }); } }, + startup: function () { this.inherited(arguments); - if (this.mode === 'custom') { - if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the title of custom basemaps in viewer.js config - this.gallery.select(this.mapStartBasemap); - } - } else if (this.mapStartBasemap) { - if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the agol basemap name - this.map.setBasemap(this.mapStartBasemap); + if (this.mapStartBasemap) { + this.currentBasemap = this.mapStartBasemap; + if (this.map.getBasemap() !== this.mapStartBasemap) { + this.updateBasemap(this.mapStartBasemap); } } } From 25a3893c2af2a394affa2e1d92bf59a0ec2ade15 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 20 Mar 2016 12:18:21 -0700 Subject: [PATCH 051/216] updated configuration with examples of combined agol and custom basemaps Basemap and BasemapLayer dijits no longer needed for custom basemaps some of the examples required v 3.16 or higher of the ESRI JavaScript API --- viewer/js/config/basemaps.js | 381 +++++++++++++++++------------------ 1 file changed, 186 insertions(+), 195 deletions(-) diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 28bd4bd92..c01c99988 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -1,204 +1,195 @@ -define([ - //'esri/dijit/Basemap', - //'esri/dijit/BasemapLayer', - //'esri/layers/osm' -], function (/* Basemap, BasemapLayer, osm */) { - 'use strict'; +define({ + map: true, // needs a refrence to the map + title: 'Basemaps', // title for widget - return { - map: true, // needs a refrence to the map - mode: 'agol', //must be either 'agol' or 'custom' - title: 'Basemaps', // title for widget + /* optional starting basemap + / otherwise uses the basemap from the map + / must match one of the keys in basemaps object below + */ + //mapStartBasemap: 'streets', - /* optional starting basemap - / otherwise uses the basemap from the map - / must match one of the keys in basemaps object below - */ - //mapStartBasemap: 'streets', - - /* optional array of basemaps to show in menu. - / otherwise uses keys in basemaps object below - / values in array must match keys in basemaps object - */ - //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'national-geographic', 'osm', 'oceans'], + /* optional array of basemaps to show in menu. + / otherwise uses keys in basemaps object below + / values in array must match keys in basemaps object + */ + //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'national-geographic', 'osm', 'oceans'], - // define all valid custom basemaps here. Object of Basemap objects. For custom basemaps, the key name and basemap id must match. - basemaps: { // agol basemaps - streets: { - title: 'Streets' - }, - satellite: { - title: 'Satellite' - }, - hybrid: { - title: 'Hybrid' - }, - topo: { - title: 'Topo' - }, - gray: { - title: 'Gray' - }, - oceans: { - title: 'Oceans' - }, - 'national-geographic': { - title: 'Nat Geo' - }, - osm: { - title: 'Open Street Map' + // define all valid basemaps here. + basemaps: { + streets: { + title: 'Streets' + }, + 'streets-night-vector': { // requires v3.16 or higher + title: 'Streets (Night)' + }, + 'streets-navigation-vector': { // requires v3.16 or higher + title: 'Streets (Navigation)' + }, + 'streets-relief-vector': { // requires v3.16 or higher + title: 'Street (Relief)' + }, + satellite: { + title: 'Satellite' + }, + hybrid: { + title: 'Hybrid' + }, + topo: { + title: 'Topo' + }, + 'terrain': { + title: 'Terrain' + }, + 'gray-vector': { // requires v3.16 or higher + title: 'Gray' + }, + 'dark-gray-vector': { // requires v3.16 or higher + title: 'Dark Gray' + }, + oceans: { + title: 'Oceans' + }, + 'national-geographic': { + title: 'Nat Geo' + }, + osm: { + title: 'Open Street Map' + }, + LandsatShaded: { + title: 'Landsat Shaded', + basemap: { + baseMapLayers: [ + { + url: 'https://imagery.arcgisonline.com/arcgis/rest/services/LandsatGLS/LandsatShadedBasemap/ImageServer' + } + ] } + }, + EarthAtNight: { + title: 'Earth at Night', + basemap: { + baseMapLayers: [ + { + url: 'https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Earth_at_Night_WM/MapServer' + } + ] + } + }, + DavidRumseyMap1812: { + title: 'David Rumsey 1812', + basemap: { + baseMapLayers: [ + { + url: 'http://tiles.arcgis.com/tiles/IEuSomXfi6iB7a25/arcgis/rest/services/World_Globe_1812/MapServer' + } + ] + } + } - // examples of custom basemaps - - /*streets: { - title: 'Streets', - basemap: new Basemap({ - id: 'streets', - layers: [new BasemapLayer({ - url: 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer' - })] - }) - }, - satellite: { - title: 'Satellite', - basemap: new Basemap({ - id: 'satellite', - layers: [new BasemapLayer({ - url: 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' - })] - }) - }, - hybrid: { - title: 'Hybrid', - basemap: new Basemap({ - id: 'hybrid', - layers: [new BasemapLayer({ - url: 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' - }), new BasemapLayer({ - url: 'http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer', - isReference: true, - displayLevels: [0, 1, 2, 3, 4, 5, 6, 7] - }), new BasemapLayer({ - url: 'http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer', - isReference: true, - displayLevels: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] - })] - }) - }, - lightGray: { - title: 'Light Gray Canvas', - basemap: new Basemap({ - id: 'lightGray', - layers: [new BasemapLayer({ - url: 'http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer' - }), new BasemapLayer({ - url: 'http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer', + // additional examples of vector tile basemaps (requires v3.16 or higher) + /* + streetsVector: { + title: 'Streets', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/3b8814f6ddbd485cae67e8018992246e/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + satelliteVector: { + title: 'Satellite', + basemap: { + baseMapLayers: [ + { + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' + } + ] + } + }, + hybridVector: { + title: 'Hybrid', + basemap: { + baseMapLayers: [ + { + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' + }, + { + url: 'https://www.arcgis.com/sharing/rest/content/items/1854498c7e35420b963a514a32689c80/resources/styles/root.json', + type: 'VectorTile', isReference: true - })] - }) - }*/ - - // example using vector tile basemaps (beta in v3.15) - - /* - streets: { - title: 'Streets', - basemap: new Basemap({ - id: 'streets', - layers: [new BasemapLayer({ - 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/3b8814f6ddbd485cae67e8018992246e/resources/styles/root.json', - 'type': 'VectorTileLayer' - })] - }) - }, - satellite: { - title: 'Satellite', - basemap: new Basemap({ - id: 'satellite', - layers: [new BasemapLayer({ - url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' - })] - }) - }, - hybrid: { - title: 'Hybrid', - basemap: new Basemap({ - id: 'hybrid', - layers: [ - new BasemapLayer({ - url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' - }), - new BasemapLayer({ - 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/1854498c7e35420b963a514a32689c80/resources/styles/root.json', - 'type': 'VectorTileLayer', - isReference: true - }) - ] - }) - }, - lightGray: { - title: 'Light Gray Canvas', - basemap: new Basemap({ - id: 'lightGray', - layers: [new BasemapLayer({ - 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', - 'type': 'VectorTileLayer' - })] - }) - }, - darkGray: { - title: 'Dark Gray Canvas', - basemap: new Basemap({ - id: 'darkGray', - layers: [new BasemapLayer({ - 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/3e3099d7302f4d99bc6f916dcc07ed59/resources/styles/root.json', - 'type': 'VectorTileLayer' - })] - }) - }, - navigation: { - title: 'Navigation', - basemap: new Basemap({ - id: 'navigation', - layers: [new BasemapLayer({ - 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/styles/root.json', - 'type': 'VectorTileLayer' - })] - }) - }, - streetsNight: { - title: 'Streets Night', - basemap: new Basemap({ - id: 'streetsNight', - layers: [new BasemapLayer({ - 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/f96366254a564adda1dc468b447ed956/resources/styles/root.json', - 'type': 'VectorTileLayer' - })] - }) - }, - streetsRelief: { - title: 'Streets w/ Relief', - basemap: new Basemap({ - id: 'streetsRelief', - layers: [new BasemapLayer({ - 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/ad06088bd1174866aad2dddbf5ec9642/resources/styles/root.json', - 'type': 'VectorTileLayer' - })] - }) - }, - topo: { - title: 'Topographic', - basemap: new Basemap({ - id: 'topo', - layers: [new BasemapLayer({ - 'styleUrl': '//www.arcgis.com/sharing/rest/content/items/be44936bcdd24db588a1ae5076e36f34/resources/styles/root.json', - 'type': 'VectorTileLayer' - })] - }) + } + ] + } + }, + lightGrayVector: { + title: 'Light Gray Canvas', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + darkGrayVector: { + title: 'Dark Gray Canvas', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/3e3099d7302f4d99bc6f916dcc07ed59/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + navigationVector: { + title: 'Navigation', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + streetsNightVector: { + title: 'Streets Night', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/f96366254a564adda1dc468b447ed956/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + streetsReliefVector: { + title: 'Streets w/ Relief', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/ad06088bd1174866aad2dddbf5ec9642/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + topoVector: { + title: 'Topographic', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/be44936bcdd24db588a1ae5076e36f34/resources/styles/root.json', + type: 'VectorTile' + } + ] } - */ - } - }; + */ + } }); \ No newline at end of file From 68e9b768799067856ce97445e38080ad6b7ea2c5 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 26 Mar 2016 12:14:55 -0700 Subject: [PATCH 052/216] restored `custom` mode for basemaps widget. Custom basemaps are also supported in agol mode for those types of basemaps which are supported by `esri/basemaps` Added additional examples of custom basemaps using WebMapTiled layers --- viewer/js/config/basemaps.js | 474 ++++++++++++++++++++------------ viewer/js/gis/dijit/Basemaps.js | 37 ++- 2 files changed, 320 insertions(+), 191 deletions(-) diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index c01c99988..f30896ff1 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -1,195 +1,303 @@ -define({ - map: true, // needs a refrence to the map - title: 'Basemaps', // title for widget +define([ + //'esri/dijit/Basemap', + //'esri/dijit/BasemapLayer' +], function (/* Basemap, BasemapLayer */) { + 'use strict'; - /* optional starting basemap - / otherwise uses the basemap from the map - / must match one of the keys in basemaps object below - */ - //mapStartBasemap: 'streets', + return { + map: true, // needs a reference to the map + mode: 'agol', // mut be either 'agol' or 'custom' + title: 'Basemaps', // title for widget - /* optional array of basemaps to show in menu. - / otherwise uses keys in basemaps object below - / values in array must match keys in basemaps object - */ - //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'national-geographic', 'osm', 'oceans'], + /* optional starting basemap + / otherwise uses the basemap from the map + / must match one of the keys in basemaps object below + */ + //mapStartBasemap: 'streets', - // define all valid basemaps here. - basemaps: { - streets: { - title: 'Streets' - }, - 'streets-night-vector': { // requires v3.16 or higher - title: 'Streets (Night)' - }, - 'streets-navigation-vector': { // requires v3.16 or higher - title: 'Streets (Navigation)' - }, - 'streets-relief-vector': { // requires v3.16 or higher - title: 'Street (Relief)' - }, - satellite: { - title: 'Satellite' - }, - hybrid: { - title: 'Hybrid' - }, - topo: { - title: 'Topo' - }, - 'terrain': { - title: 'Terrain' - }, - 'gray-vector': { // requires v3.16 or higher - title: 'Gray' - }, - 'dark-gray-vector': { // requires v3.16 or higher - title: 'Dark Gray' - }, - oceans: { - title: 'Oceans' - }, - 'national-geographic': { - title: 'Nat Geo' - }, - osm: { - title: 'Open Street Map' - }, - LandsatShaded: { - title: 'Landsat Shaded', - basemap: { - baseMapLayers: [ - { - url: 'https://imagery.arcgisonline.com/arcgis/rest/services/LandsatGLS/LandsatShadedBasemap/ImageServer' - } - ] - } - }, - EarthAtNight: { - title: 'Earth at Night', - basemap: { - baseMapLayers: [ - { - url: 'https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Earth_at_Night_WM/MapServer' - } - ] - } - }, - DavidRumseyMap1812: { - title: 'David Rumsey 1812', - basemap: { - baseMapLayers: [ - { - url: 'http://tiles.arcgis.com/tiles/IEuSomXfi6iB7a25/arcgis/rest/services/World_Globe_1812/MapServer' - } - ] + /* optional array of basemaps to show in menu. + / otherwise uses keys in basemaps object below + / values in array must match keys in basemaps object + */ + //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'national-geographic', 'osm', 'oceans'], + + // define all valid basemaps here. + basemaps: { + streets: { + title: 'Streets' + }, + 'streets-night-vector': { // requires v3.16 or higher + title: 'Streets (Night)' + }, + 'streets-navigation-vector': { // requires v3.16 or higher + title: 'Streets (Navigation)' + }, + 'streets-relief-vector': { // requires v3.16 or higher + title: 'Street (Relief)' + }, + satellite: { + title: 'Satellite' + }, + hybrid: { + title: 'Hybrid' + }, + topo: { + title: 'Topo' + }, + 'terrain': { + title: 'Terrain' + }, + 'gray-vector': { // requires v3.16 or higher + title: 'Gray' + }, + 'dark-gray-vector': { // requires v3.16 or higher + title: 'Dark Gray' + }, + oceans: { + title: 'Oceans' + }, + 'national-geographic': { + title: 'Nat Geo' + }, + osm: { + title: 'Open Street Map' + }, + LandsatShaded: { + title: 'Landsat Shaded', + basemap: { + baseMapLayers: [ + { + url: 'https://imagery.arcgisonline.com/arcgis/rest/services/LandsatGLS/LandsatShadedBasemap/ImageServer' + } + ] + } + }, + EarthAtNight: { + title: 'Earth at Night', + basemap: { + baseMapLayers: [ + { + url: 'https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Earth_at_Night_WM/MapServer' + } + ] + } + }, + DavidRumseyMap1812: { + title: 'David Rumsey 1812', + basemap: { + baseMapLayers: [ + { + url: 'http://tiles.arcgis.com/tiles/IEuSomXfi6iB7a25/arcgis/rest/services/World_Globe_1812/MapServer' + } + ] + } } - } - // additional examples of vector tile basemaps (requires v3.16 or higher) - /* - streetsVector: { - title: 'Streets', - basemap: { - baseMapLayers: [ - { - url: 'https://www.arcgis.com/sharing/rest/content/items/3b8814f6ddbd485cae67e8018992246e/resources/styles/root.json', - type: 'VectorTile' - } - ] + // additional examples of vector tile basemaps (requires v3.16 or higher) + /* + streetsVector: { + title: 'Streets', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/3b8814f6ddbd485cae67e8018992246e/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + satelliteVector: { + title: 'Satellite', + basemap: { + baseMapLayers: [ + { + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' + } + ] + } + }, + hybridVector: { + title: 'Hybrid', + basemap: { + baseMapLayers: [ + { + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' + }, + { + url: 'https://www.arcgis.com/sharing/rest/content/items/1854498c7e35420b963a514a32689c80/resources/styles/root.json', + type: 'VectorTile', + isReference: true + } + ] + } + }, + lightGrayVector: { + title: 'Light Gray Canvas', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + darkGrayVector: { + title: 'Dark Gray Canvas', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/3e3099d7302f4d99bc6f916dcc07ed59/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + navigationVector: { + title: 'Navigation', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + streetsNightVector: { + title: 'Streets Night', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/f96366254a564adda1dc468b447ed956/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + streetsReliefVector: { + title: 'Streets w/ Relief', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/ad06088bd1174866aad2dddbf5ec9642/resources/styles/root.json', + type: 'VectorTile' + } + ] + } + }, + topoVector: { + title: 'Topographic', + basemap: { + baseMapLayers: [ + { + url: 'https://www.arcgis.com/sharing/rest/content/items/be44936bcdd24db588a1ae5076e36f34/resources/styles/root.json', + type: 'VectorTile' + } + ] + } } - }, - satelliteVector: { - title: 'Satellite', - basemap: { - baseMapLayers: [ - { + */ + + //examples of custom basemaps + /* + streets: { + title: 'Streets', + basemap: new Basemap({ + id: 'streets', + layers: [new BasemapLayer({ + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer' + })] + }) + }, + satellite: { + title: 'Satellite', + basemap: new Basemap({ + id: 'satellite', + layers: [new BasemapLayer({ url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' - } - ] - } - }, - hybridVector: { - title: 'Hybrid', - basemap: { - baseMapLayers: [ - { + })] + }) + }, + hybrid: { + title: 'Hybrid', + basemap: new Basemap({ + id: 'hybrid', + layers: [new BasemapLayer({ url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' - }, - { - url: 'https://www.arcgis.com/sharing/rest/content/items/1854498c7e35420b963a514a32689c80/resources/styles/root.json', - type: 'VectorTile', + }), new BasemapLayer({ + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer', + isReference: true, + displayLevels: [0, 1, 2, 3, 4, 5, 6, 7] + }), new BasemapLayer({ + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer', + isReference: true, + displayLevels: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] + })] + }) + }, + lightGray: { + title: 'Light Gray Canvas', + basemap: new Basemap({ + id: 'lightGray', + layers: [new BasemapLayer({ + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer' + }), new BasemapLayer({ + url: 'https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer', isReference: true - } - ] - } - }, - lightGrayVector: { - title: 'Light Gray Canvas', - basemap: { - baseMapLayers: [ - { - url: 'https://www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', - type: 'VectorTile' - } - ] - } - }, - darkGrayVector: { - title: 'Dark Gray Canvas', - basemap: { - baseMapLayers: [ - { - url: 'https://www.arcgis.com/sharing/rest/content/items/3e3099d7302f4d99bc6f916dcc07ed59/resources/styles/root.json', - type: 'VectorTile' - } - ] - } - }, - navigationVector: { - title: 'Navigation', - basemap: { - baseMapLayers: [ - { - url: 'https://www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/styles/root.json', - type: 'VectorTile' - } - ] - } - }, - streetsNightVector: { - title: 'Streets Night', - basemap: { - baseMapLayers: [ - { - url: 'https://www.arcgis.com/sharing/rest/content/items/f96366254a564adda1dc468b447ed956/resources/styles/root.json', - type: 'VectorTile' - } - ] - } - }, - streetsReliefVector: { - title: 'Streets w/ Relief', - basemap: { - baseMapLayers: [ - { - url: 'https://www.arcgis.com/sharing/rest/content/items/ad06088bd1174866aad2dddbf5ec9642/resources/styles/root.json', - type: 'VectorTile' - } - ] - } - }, - topoVector: { - title: 'Topographic', - basemap: { - baseMapLayers: [ - { - url: 'https://www.arcgis.com/sharing/rest/content/items/be44936bcdd24db588a1ae5076e36f34/resources/styles/root.json', - type: 'VectorTile' - } - ] + })] + }) + }, + stamenToner: { + title: 'Toner (maps.stamen.com)', + basemap: new Basemap({ + id: 'stamenToner', + layers: [new BasemapLayer({ + url: 'http://tile.stamen.com/toner/${level}/${col}/${row}.png', + copyright: 'stamen, 2016', + id: 'stamenToner', + type: 'WebTiledLayer' + })] + }) + }, + stamenTerrain: { + title: 'Terrain (stamen.com)', + basemap: new Basemap({ + id: 'stamenTerrain', + layers: [new BasemapLayer({ + url: 'http://tile.stamen.com/terrain/${level}/${col}/${row}.png', + copyright: 'stamen, 2016', + id: 'stamenTerrain', + type: 'WebTiledLayer' + })] + }) + }, + stamenWatercolor: { + title: 'Watercolor (stamen.com)', + basemap: new Basemap({ + id: 'stamenWatercolor', + layers: [new BasemapLayer({ + url: 'http://tile.stamen.com/watercolor/${level}/${col}/${row}.png', + copyright: 'stamen, 2016', + id: 'stamenWatercolor', + type: 'WebTiledLayer' + })] + }) + }, + mapboxPirates: { + title: 'Pirates (mapbox.com)', + basemap: new Basemap({ + id: 'mapboxPirates', + layers: [new BasemapLayer({ + url: 'https://${subDomain}.tiles.mapbox.com/v3/aj.Sketchy2/${level}/${col}/${row}.png', + copyright: 'mapbox, 2016', + id: 'mapboxPirates', + subDomains: ['a', 'b', 'c', 'd'], + type: 'WebTiledLayer' + })] + }) } + */ } - */ - } + }; }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index ff655a1d4..3939f845b 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -8,11 +8,13 @@ define([ 'dojo/_base/lang', 'dojo/_base/array', 'dojo/topic', + 'dojox/lang/functional', 'dijit/DropDownMenu', 'dijit/MenuItem', 'esri/basemaps', + 'esri/dijit/BasemapGallery', 'dojo/text!./Basemaps/templates/Basemaps.html', 'dojo/i18n!./Basemaps/nls/resource', @@ -28,11 +30,13 @@ define([ lang, array, topic, + functional, DropDownMenu, MenuItem, esriBasemaps, + BasemapGallery, template, i18n @@ -43,6 +47,7 @@ define([ widgetsInTemplate: true, i18n: i18n, title: i18n.title, + mode: 'agol', basemaps: {}, currentBasemap: null, @@ -70,20 +75,32 @@ define([ this.mapStartBasemap = this.basemapsToShow[0]; } + if (this.mode === 'custom') { + this.gallery = new BasemapGallery({ + map: this.map, + showArcGISBasemaps: false, + basemaps: functional.map(this.basemaps, function (map) { + return map.basemap; + }) + }); + this.gallery.startup(); + } this.menu = new DropDownMenu({ style: 'display: none;' }); array.forEach(this.basemapsToShow, function (basemap) { if (this.basemaps.hasOwnProperty(basemap)) { - // add any custom to the esri basemaps - var basemapObj = this.basemaps[basemap]; - if (basemapObj.basemap) { - if (!esriBasemaps[basemap]) { - if (!basemapObj.basemap.title) { - basemapObj.basemap.title = basemapObj.title || basemap; + if (this.mode !== 'custom') { + // add any custom to the esri basemaps + var basemapObj = this.basemaps[basemap]; + if (basemapObj.basemap) { + if (!esriBasemaps[basemap]) { + if (!basemapObj.basemap.title) { + basemapObj.basemap.title = basemapObj.title || basemap; + } + esriBasemaps[basemap] = basemapObj.basemap; } - esriBasemaps[basemap] = basemapObj.basemap; } } var menuItem = new MenuItem({ @@ -105,7 +122,11 @@ define([ return; } this.currentBasemap = basemap; - this.map.setBasemap(basemap); + if (this.mode === 'custom') { + this.gallery.select(basemap); + } else { + this.map.setBasemap(basemap); + } var ch = this.menu.getChildren(); array.forEach(ch, function (c) { From 81f653e8aee43b6d1ad0bc970ba8cddfd1398df5 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 2 Apr 2016 11:49:36 -0700 Subject: [PATCH 053/216] Adds the ability to resize a floating titlePane widget. Fixes #379 - mouse does not release after dragging a floating widge when using IE. The delay before a titlePane starts dragging from the side pane is now configurable. --- viewer/js/gis/dijit/FloatingTitlePane.js | 123 ++++++++++++++++++----- 1 file changed, 97 insertions(+), 26 deletions(-) diff --git a/viewer/js/gis/dijit/FloatingTitlePane.js b/viewer/js/gis/dijit/FloatingTitlePane.js index 414d1241a..e73e0d062 100644 --- a/viewer/js/gis/dijit/FloatingTitlePane.js +++ b/viewer/js/gis/dijit/FloatingTitlePane.js @@ -14,11 +14,23 @@ define([ 'dojo/dom-construct', 'dojo/dom-attr', 'dojo/dom-class', + 'dojox/layout/ResizeHandle', + 'xstyle/css!dojox/layout/resources/ResizeHandle.css', 'xstyle/css!./FloatingTitlePane/css/FloatingTitlePane.css' -], function (declare, TitlePane, on, lang, Moveable, aspect, topic, win, winUtils, domGeom, domStyle, domConstruct, domAttr, domClass) { +], function (declare, TitlePane, on, lang, Moveable, aspect, topic, win, winUtils, domGeom, domStyle, domConstruct, domAttr, domClass, ResizeHandle) { return declare([TitlePane], { sidebarPosition: null, + + canFloat: false, + isFloating: false, + isDragging: false, + dragDelay: 3, + + resizable: false, + resizeOptions: {}, + isResizing: false, + postCreate: function () { if (this.canFloat) { this.createDomNodes(); @@ -31,9 +43,9 @@ define([ startup: function () { if (this.titleBarNode && this.canFloat) { this._moveable = new Moveable(this.domNode, { - delay: 5, handle: this.titleBarNode }); + this._titleBarHeight = domStyle.get(this.titleBarNode, 'height'); aspect.after(this._moveable, 'onMove', lang.hitch(this, '_dragging'), true); aspect.after(this._moveable, 'onMoveStop', lang.hitch(this, '_endDrag'), true); aspect.after(this._moveable, 'onMoveStart', lang.hitch(this, '_startDrag'), true); @@ -59,36 +71,47 @@ define([ this._dockWidget(); evt.stopImmediatePropagation(); }))); + + if (this.resizable) { + var resOptions = lang.mixin({ + targetId: this.id, + activeResize: true, + intermediateChanges: true, + startTopic: this.id + '/resize/start', + endTopic: this.id + '/resize/end' + }, this.resizeOptions); + this._resizer = new ResizeHandle(resOptions).placeAt(this.id); + domStyle.set(this._resizer.resizeHandle, 'display', 'none'); + on(this._resizer, 'resize', lang.hitch(this, '_resizing'), true); + this.own(topic.subscribe(this.id + '/resize/start', lang.hitch(this, '_startResize'))); + this.own(topic.subscribe(this.id + '/resize/end', lang.hitch(this, '_endResize'))); + } }, + + /* Methods related to Toggling the TitleBar */ toggle: function () { - if (this.isFloating && this.isDragging) { + if ((this.isFloating && this.isDragging) || this.resizing) { return; } this.inherited(arguments); }, - _dockWidget: function () { - if (!this.isDragging) { - domAttr.remove(this.domNode, 'style'); - domStyle.set(this.dockHandleNode, 'display', 'none'); - domStyle.set(this.moveHandleNode, 'display', 'inline'); - var dockedWidgets = this.sidebar.getChildren(); - if (this.sidebarPosition > dockedWidgets.length || this.sidebarPosition < 0) { - this.sidebarPosition = dockedWidgets.length; - } - this.placeAt(this.sidebar, this.sidebarPosition); - this.isFloating = false; - this._updateTopic('dock'); - } + _afterToggle: function () { + var evt = this.open ? 'open' : 'close'; + this._updateTopic(evt); }, - _dragging: function () { + + /* Methods for Dragging */ + _dragging: function (mover) { + // add our own delay since the movable delay + // property breaks in all versions of Internet Explorer + if (Math.abs(mover.marginBox.l - this._moverBox.l) <= this.dragDelay || Math.abs(mover.marginBox.t - this._moverBox.t) <= this.dragDelay) { + return; + } this.isDragging = true; - }, - _startDrag: function (mover) { if (!this.titleCursor) { this.titleCursor = domStyle.get(this.titleBarNode, 'cursor'); } domStyle.set(this.titleBarNode, 'cursor', 'move'); - if (!this.isFloating) { this._checkSidebarPosition(); domStyle.set(this.dockHandleNode, 'display', 'inline'); @@ -101,13 +124,19 @@ define([ }, computedStyle); this.isFloating = true; this.placeAt(win.body()); - var titleHeight = domStyle.get(this.titleBarNode, 'height'); domStyle.set(this.domNode, { - top: (mover.marginBox.t - titleHeight) + 'px' + top: (this._moverBox.t - this._titleBarHeight) + 'px' }); + + if (this.resizable && this._resizer && this._resizer.resizeHandle) { + domStyle.set(this._resizer.resizeHandle, 'display', 'block'); + } this._updateTopic('undock'); } }, + _startDrag: function (mover) { + this._moverBox = mover.marginBox; + }, _endDrag: function () { // summary: // Called after dragging the Dialog. Saves the position of the dialog in the viewport, @@ -144,6 +173,28 @@ define([ }); } }, + + /* Methods for Docking and Undocking */ + _dockWidget: function () { + if (!this.isDragging) { + domAttr.remove(this.domNode, 'style'); + domStyle.set(this.dockHandleNode, 'display', 'none'); + domStyle.set(this.moveHandleNode, 'display', 'inline'); + var dockedWidgets = this.sidebar.getChildren(); + if (this.sidebarPosition > dockedWidgets.length || this.sidebarPosition < 0) { + this.sidebarPosition = dockedWidgets.length; + } + this.placeAt(this.sidebar, this.sidebarPosition); + this.isFloating = false; + this._updateTopic('dock'); + } + if (this.resizable && this._resizer && this._resizer.resizeHandle) { + domStyle.set(this._resizer.resizeHandle, 'display', 'none'); + if (this._initialDimensions) { + topic.publish(this.id + '/resize/resize', this._initialDimensions); + } + } + }, _updateWidgetSidebarPosition: function (msg) { var id = msg.widgetID, pos = msg.sidebarPosition, action = msg.action; @@ -187,6 +238,30 @@ define([ } } }, + + /* Methods for Resizing */ + _resizing: function (evt) { + this.isResizing = true; + var newDim = this._resizer._getNewCoords(evt, this, 'margin'); + if (newDim) { + topic.publish(this.id + '/resize/resize', { + h: this._resizeDimensions.h + (newDim.h - this._resizer.startSize.h), + w: this._resizeDimensions.w + (newDim.w - this._resizer.startSize.w) + }); + } + }, + _startResize: function () { + this.isResizing = true; + this._resizeDimensions = domGeom.getContentBox(this.containerNode); + if (!this._initialDimensions) { + this._initialDimensions = this._resizeDimensions; + } + }, + _endResize: function () { + this.isResizing = false; + domStyle.set(this.domNode, 'height', 'auto'); + }, + _updateTopic: function (msg) { topic.publish('titlePane/event', { category: 'Titlepane Event', @@ -196,10 +271,6 @@ define([ sidebarPosition: this.sidebarPosition, value: msg }); - }, - _afterToggle: function () { - var evt = this.open ? 'open' : 'close'; - this._updateTopic(evt); } }); }); \ No newline at end of file From 8e78bfb1e72f73645281480cc943e2d285966f48 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 2 Apr 2016 12:37:31 -0700 Subject: [PATCH 054/216] move titlePane background-color to dijitTitlePane so there is no gap at the bottom. --- viewer/css/main.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/viewer/css/main.css b/viewer/css/main.css index 8d605b40a..a88b52722 100644 --- a/viewer/css/main.css +++ b/viewer/css/main.css @@ -219,6 +219,7 @@ body, html { margin-bottom: 2px; -webkit-border-radius: 4px; border-radius: 4px; + background-color: #FFFFFF; } .dbootstrap .dijitTitlePaneTitle { color: #666666 !important; @@ -229,9 +230,6 @@ body, html { .dijitSliderBarContainerH { z-index: 0 !important; } -.dbootstrap .dijitTitlePaneContentInner { - background-color: #FFFFFF; -} .dijitBorderContainerNoGutterPane { z-index: auto; } From d8b51832a3a4575f1b28fb77cb55db57b148d872 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 2 Apr 2016 12:43:00 -0700 Subject: [PATCH 055/216] make StreetView widget resizable. move StreetView button to increase size of Panorama div. add StreetView instructions to background div that is initially visible. make StreetView button a toggle so you can untoggle (disconnect). change the StreetView button icon to use the FontAwesome fa-street-view class. --- viewer/js/gis/dijit/StreetView.js | 36 +++++++----- .../gis/dijit/StreetView/css/StreetView.css | 56 ++++++++----------- .../js/gis/dijit/StreetView/nls/resource.js | 8 +-- .../StreetView/templates/StreetView.html | 16 +++--- 4 files changed, 57 insertions(+), 59 deletions(-) diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index dde884fdb..77cd0a354 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -14,16 +14,17 @@ define([ 'dojo/text!./StreetView/templates/StreetView.html', 'esri/symbols/PictureMarkerSymbol', 'dojo/dom-style', + 'dojo/dom-geometry', 'esri/geometry/Point', 'esri/SpatialReference', 'dijit/MenuItem', '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12/proj4.js', 'dojo/i18n!./StreetView/nls/resource', - 'dijit/form/Button', + 'dijit/form/ToggleButton', 'xstyle/css!./StreetView/css/StreetView.css', 'gis/plugins/async!//maps.google.com/maps/api/js?v=3' -], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, aspect, topic, GraphicsLayer, Graphic, SimpleRenderer, template, PictureMarkerSymbol, domStyle, Point, SpatialReference, MenuItem, proj4, i18n) { +], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, aspect, topic, GraphicsLayer, Graphic, SimpleRenderer, template, PictureMarkerSymbol, domStyle, domGeom, Point, SpatialReference, MenuItem, proj4, i18n) { return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { widgetsInTemplate: true, @@ -68,11 +69,8 @@ define([ this.onLayoutChange(this.parentWidget.open); }))); } - this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, function () { - if (this.panorama) { - google.maps.event.trigger(this.panorama, 'resize'); - } - }))); + this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, 'resize'))); + this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); } // spatialreference.org uses the old @@ -111,9 +109,6 @@ define([ this.panorama = new google.maps.StreetViewPanorama(this.panoNode, this.panoOptions); this.panoramaService = new google.maps.StreetViewService(); } - if (this.panorama) { - google.maps.event.trigger(this.panorama, 'resize'); - } }, onClose: function () { // end streetview on close of title pane @@ -130,14 +125,20 @@ define([ } }, placePoint: function () { - this.disconnectMapClick(); + if (this.streetViewButtonDijit.get('checked')) { + this.disconnectMapClick(); + } else { + this.connectMapClick(); + } //get map click, set up listener in post create }, disconnectMapClick: function () { + this.streetViewButtonDijit.set('checked', true); this.map.setMapCursor('crosshair'); topic.publish('mapClickMode/setCurrent', 'streetview'); }, connectMapClick: function () { + this.streetViewButtonDijit.set('checked', false); this.map.setMapCursor('auto'); topic.publish('mapClickMode/setDefault'); }, @@ -184,9 +185,9 @@ define([ }; } + domStyle.set(this.streetViewInstructions, 'display', 'none'); if (geometry) { domStyle.set(this.noStreetViewResults, 'display', 'none'); - domStyle.set(this.loadingStreetView, 'display', 'inline-block'); this.getPanoramaLocation(geometry); } else { this.setPanoPlace = null; @@ -205,7 +206,6 @@ define([ google.maps.event.addListener(this.panorama, 'pov_changed', lang.hitch(this, 'setPlaceMarkerRotation')); }, getPanoramaByLocationComplete: function (geoPoint, StreetViewPanoramaData, StreetViewStatus) { - domStyle.set(this.loadingStreetView, 'display', 'none'); if (StreetViewStatus === 'OK') { this.disableStreetViewClick(); var place = new google.maps.LatLng(geoPoint.y, geoPoint.x); @@ -227,6 +227,16 @@ define([ }); } }, + resize: function (options) { + if (options && options.h) { + domGeom.setContentSize(this.containerNode, { + h: (options.h - 2) + }); + } + if (this.panorama) { + google.maps.event.trigger(this.panorama, 'resize'); + } + }, setPlaceMarkerPosition: function () { if (!this.placeMarker || this.pointGraphics.graphics.length === 0) { this.placeMarker = new Graphic(); diff --git a/viewer/js/gis/dijit/StreetView/css/StreetView.css b/viewer/js/gis/dijit/StreetView/css/StreetView.css index 1f943023f..f3d57b21f 100644 --- a/viewer/js/gis/dijit/StreetView/css/StreetView.css +++ b/viewer/js/gis/dijit/StreetView/css/StreetView.css @@ -1,60 +1,50 @@ .gis_StreetView { - padding: 5px; + width: 100%; + height: 250px; + padding-bottom: 5px; } -.gis_StreetView .buttonActionBar { - padding: 3px 0px 2px 0px; - text-align: right; - width: 100%; +.gis_StreetView .streetViewButton { + position: absolute; + left: 4px; + top: 4px; + z-index: 9; } -.gis_StreetView .buttonActionBar .loadingStreetView { - display: none; - width: 18px; - position: relative; - top: 5px; - margin-right: 10px; - background-image: url('../images/loading.gif'); +.gis_StreetView .streetViewButton .dijitButtonNode { + padding: 6px; } -.gis_StreetView .streetViewNode { - border: 1px solid #999999; +.gis_StreetView .streetViewPano { + border: 1px solid #CCC; width: 100%; - height: 275px; + height: 100%; } -.floatingWidget .gis_StreetView .streetViewNode { +.floatingWidget .gis_StreetView .streetViewPano { width: 400px; height: 275px; } -.gis_StreetView .pegmanIcon { - background-image: url(../images/googleIcon.png); - background-size: contain; - background-repeat: no-repeat; - width: 16px; - height: 20px; - vertical-align: middle; - margin-top: -4px; - margin-bottom: -4px; -} - +.gis_StreetView .streetViewInstructions, .gis_StreetView .noStreetViewResults { - display: none; background-color: black; width: 100%; height: 100%; z-index: 2; - position: relative; + position: absolute; +} +.gis_StreetView .noStreetViewResults { + display: none; } +.gis_StreetView .streetViewInstructionsText, .gis_StreetView .noStreetViewResultsText { - color: white; background-color: black; + color: white; z-index: 2; - position: relative; - top: 40%; + position: absolute; + top: 25%; text-align: center; - font-size: 12pt; padding: 10px; } \ No newline at end of file diff --git a/viewer/js/gis/dijit/StreetView/nls/resource.js b/viewer/js/gis/dijit/StreetView/nls/resource.js index 8dbb2fa92..d417ab380 100644 --- a/viewer/js/gis/dijit/StreetView/nls/resource.js +++ b/viewer/js/gis/dijit/StreetView/nls/resource.js @@ -1,14 +1,12 @@ // http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ root: { - activateButton: { - label: 'Activate with map click' - }, messages: { - notAvailable: 'Street View not available at this location.' + instructions: 'Click the StreetView button then click the map at your desired location.', + notAvailable: 'Unfortunately, Google StreetView imagery is not yet available at that location.' }, rightClickMenuItem: { - label: 'Street View here' + label: 'Google StreetView here' } } }); diff --git a/viewer/js/gis/dijit/StreetView/templates/StreetView.html b/viewer/js/gis/dijit/StreetView/templates/StreetView.html index 108785294..30ba826b6 100644 --- a/viewer/js/gis/dijit/StreetView/templates/StreetView.html +++ b/viewer/js/gis/dijit/StreetView/templates/StreetView.html @@ -1,15 +1,15 @@ -
-
+
+
+ + +
+ ${i18n.messages.instructions} +
+
${i18n.messages.notAvailable}
-
- - -
From 463a1b54857dd7a961f08830de9497db6d67b12f Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 2 Apr 2016 12:44:51 -0700 Subject: [PATCH 056/216] remove unused StreetView icons. --- .../gis/dijit/StreetView/images/googleIcon.png | Bin 1712 -> 0 bytes .../js/gis/dijit/StreetView/images/loading.gif | Bin 1787 -> 0 bytes viewer/js/gis/dijit/StreetView/images/svicon.png | Bin 717 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 viewer/js/gis/dijit/StreetView/images/googleIcon.png delete mode 100644 viewer/js/gis/dijit/StreetView/images/loading.gif delete mode 100644 viewer/js/gis/dijit/StreetView/images/svicon.png diff --git a/viewer/js/gis/dijit/StreetView/images/googleIcon.png b/viewer/js/gis/dijit/StreetView/images/googleIcon.png deleted file mode 100644 index c0984aae58971900639f2d80336c65a2b296a514..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1712 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 From e5fa2bd385453355deb88a50b5fe83878871d797 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 2 Apr 2016 13:13:55 -0700 Subject: [PATCH 057/216] reposition the instructions and no street view messages. --- viewer/js/gis/dijit/StreetView/css/StreetView.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/viewer/js/gis/dijit/StreetView/css/StreetView.css b/viewer/js/gis/dijit/StreetView/css/StreetView.css index f3d57b21f..d0ba18386 100644 --- a/viewer/js/gis/dijit/StreetView/css/StreetView.css +++ b/viewer/js/gis/dijit/StreetView/css/StreetView.css @@ -44,7 +44,6 @@ color: white; z-index: 2; position: absolute; - top: 25%; - text-align: center; + top: 50px; padding: 10px; } \ No newline at end of file From d64d4e8659f0a8ab5f6324d48ef925f0a432e366 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 2 Apr 2016 13:18:37 -0700 Subject: [PATCH 058/216] Add new 'resizable: true/false' option for widget configs. Add new 'paneOptions` for widget configs to pass along to the widget's parent. Mixed in with existing options for backwards compatability. consistent arguments passed to `_createTitlePaneWidget`, `_createFloatingWidget` and `_createContentPaneWidget` methods. --- viewer/js/viewer/_WidgetsMixin.js | 49 ++++++++++++++++++------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index 18884f6c0..c9733d135 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -90,15 +90,19 @@ define([ return; } + if (position) { + widgetConfig.position = position; + } + // build a titlePane or floating widget as the parent if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating') && (widgetConfig.id && widgetConfig.id.length > 0)) { parentId = widgetConfig.id + '_parent'; if (widgetConfig.type === 'titlePane') { - pnl = this._createTitlePaneWidget(parentId, widgetConfig.title, position, widgetConfig.open, widgetConfig.canFloat, widgetConfig.placeAt); + pnl = this._createTitlePaneWidget(parentId, widgetConfig); } else if (widgetConfig.type === 'contentPane') { - pnl = this._createContentPaneWidget(parentId, widgetConfig.title, widgetConfig.className, widgetConfig.region, widgetConfig.placeAt); + pnl = this._createContentPaneWidget(parentId, widgetConfig); } else if (widgetConfig.type === 'floating') { - pnl = this._createFloatingWidget(parentId, widgetConfig.title); + pnl = this._createFloatingWidget(parentId, widgetConfig); } widgetConfig.parentWidget = pnl; } @@ -165,16 +169,18 @@ define([ } }, - _createTitlePaneWidget: function (parentId, title, position, open, canFloat, placeAt) { + _createTitlePaneWidget: function (parentId, widgetConfig) { var tp, - options = { - title: title || 'Widget', - open: open || false, - canFloat: canFloat || false - }; + options = lang.mixin({ + title: widgetConfig.title || 'Widget', + open: widgetConfig.open || false, + canFloat: widgetConfig.canFloat || false, + resizable: widgetConfig.resizable || false + }, widgetConfig.paneOptions || {}); if (parentId) { options.id = parentId; } + var placeAt = widgetConfig.placeAt; if (typeof (placeAt) === 'string') { placeAt = this.panes[placeAt]; } @@ -183,16 +189,16 @@ define([ } if (placeAt) { options.sidebar = placeAt; - tp = new FloatingTitlePane(options).placeAt(placeAt, position); + tp = new FloatingTitlePane(options).placeAt(placeAt, widgetConfig.position); tp.startup(); } return tp; }, - _createFloatingWidget: function (parentId, title) { - var options = { - title: title - }; + _createFloatingWidget: function (parentId, widgetConfig) { + var options = lang.mixin({ + title: widgetConfig.title + }, widgetConfig.paneOptions || {}); if (parentId) { options.id = parentId; } @@ -201,18 +207,19 @@ define([ return fw; }, - _createContentPaneWidget: function (parentId, title, className, region, placeAt) { + _createContentPaneWidget: function (parentId, widgetConfig) { var cp, - options = { - title: title, - region: region || 'center' - }; - if (className) { - options.className = className; + options = lang.mixin({ + title: widgetConfig.title, + region: widgetConfig.region || 'center' + }, widgetConfig.paneOptions || {}); + if (widgetConfig.className) { + options.className = widgetConfig.className; } if (parentId) { options.id = parentId; } + var placeAt = widgetConfig.placeAt; if (!placeAt) { placeAt = this.panes.sidebar; } else if (typeof (placeAt) === 'string') { From 958cc57c45b1c8eed5dd4f56515030b17da690ac Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 2 Apr 2016 13:19:20 -0700 Subject: [PATCH 059/216] demonstrate use of new `paneOptions` for resizable StreetView widget. --- viewer/js/config/viewer.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index c0ee61064..2d71212f7 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -493,6 +493,15 @@ define([ position: 9, path: 'gis/dijit/StreetView', title: 'Google Street View', + paneOptions: { + resizable: true, + resizeOptions: { + minSize: { + w: 250, + h: 250 + } + } + }, options: { map: true, mapClickMode: true, From ff21f6f6fc188bd85d4cc85eaf75e8db852f6c57 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 2 Apr 2016 13:37:14 -0700 Subject: [PATCH 060/216] Fixes broken right-click menu due to CSS selector change in the ESRI API as of version 3.15 --- viewer/js/viewer/_WidgetsMixin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index c9733d135..e7de474ab 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -131,7 +131,7 @@ define([ if (!this.mapRightClickMenu) { this.mapRightClickMenu = new Menu({ targetNodeIds: [this.map.root], - selector: '.layersDiv' // restrict to map only + selector: '.esriMapLayers' // restrict to map only }); this.mapRightClickMenu.startup(); } From 71874e42adc0c8cef9aab33399a2757c0ab98d25 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 3 Apr 2016 10:20:48 -0700 Subject: [PATCH 061/216] Fixes #455 --- viewer/js/gis/dijit/Geocoder.js | 1 + 1 file changed, 1 insertion(+) diff --git a/viewer/js/gis/dijit/Geocoder.js b/viewer/js/gis/dijit/Geocoder.js index fcdd1e29c..95d7d6461 100644 --- a/viewer/js/gis/dijit/Geocoder.js +++ b/viewer/js/gis/dijit/Geocoder.js @@ -129,6 +129,7 @@ define([ this.map.infoWindow.clearFeatures(); this.map.infoWindow.setTitle(graphic.getTitle()); this.map.infoWindow.setContent(graphic.getContent()); + this.map.infoWindow.setFeatures([graphic]); var screenPnt = this.map.toScreen(res.location); this.map.infoWindow.show(screenPnt, this.map.getInfoWindowAnchor(screenPnt)); From c6acc17ead460b66effb437dd0783c58151a8cb1 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 4 Apr 2016 17:49:20 -0700 Subject: [PATCH 062/216] update package.json for 1.4.0 release. update the grunt packages to most recent. --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 2b71ed472..e33245645 100644 --- a/package.json +++ b/package.json @@ -1,29 +1,29 @@ { "name": "ConfigurableMapViewerCMV", - "version": "1.3.4", + "version": "1.4.0", "author": "cmv.io - https://github.com/cmv/", "license": "MIT", - "year": "2015", + "year": "2016", "homepage": "http://cmv.io/", "repository": "https://github.com/cmv/cmv-app/", "dependencies": { - "babel-eslint": "4.1.x", + "babel-eslint": "6.0.x", "csslint": "0.10.x", - "eslint": "1.7.3", + "eslint": "2.5.x", "grunt": "0.4.x", - "grunt-autoprefixer": "0.7.x", - "grunt-contrib-clean": "0.5.x", - "grunt-contrib-connect": "0.7.x", - "grunt-contrib-copy": "0.5.x", - "grunt-contrib-cssmin": "0.9.x", - "grunt-contrib-csslint": "0.5.x", - "grunt-eslint": "17.3.x", - "grunt-contrib-uglify": "0.4.x", - "grunt-contrib-watch": "0.6.x", - "grunt-newer": "0.7.x", + "grunt-postcss": "0.8.x", + "grunt-contrib-clean": "1.0.x", + "grunt-contrib-connect": "1.0.x", + "grunt-contrib-copy": "1.0.x", + "grunt-contrib-csslint": "1.0.x", + "grunt-contrib-cssmin": "1.0.x", + "grunt-eslint": "18.0.x", + "grunt-contrib-uglify": "1.0.x", + "grunt-contrib-watch": "1.0.x", + "grunt-newer": "1.1.x", "grunt-open": "0.2.x", - "grunt-contrib-compress": "0.10.x", + "grunt-contrib-compress": "1.2.x", "proxypage": "*" }, - "engine": "node >= 0.10" + "engine": "node >= 0.12" } \ No newline at end of file From 4ab37f7129cfa171d1e3f38f8f70ddb3971ad72e Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 4 Apr 2016 17:52:26 -0700 Subject: [PATCH 063/216] update `.eslincrc` ruls for new version of eslint. also add warning for `max-statements` --- .eslintrc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.eslintrc b/.eslintrc index c7653194b..c5271f002 100644 --- a/.eslintrc +++ b/.eslintrc @@ -57,10 +57,10 @@ "dot-notation": 2, "eqeqeq": 2, "guard-for-in": 2, + "max-statements": [1, 30, {"ignoreTopLevelFunctions": true}], "no-alert": 2, "no-caller": 2, "no-div-regex": 2, - "no-empty-label": 2, "no-empty-pattern": 2, "no-eq-null": 2, "no-eval": 2, @@ -158,6 +158,7 @@ "afterColon": true, "mode": "strict" }], + "keyword-spacing": [2, {"before": true, "after": true, "overrides": {}}], "max-nested-callbacks": [2, 4], "new-cap": 2, "new-parens": 2, @@ -175,13 +176,10 @@ "after": true }], "semi": [2, "always"], - "space-after-keywords": [2, "always"], "space-before-blocks": [2, "always"], "space-before-function-paren": [2, "always"], - "space-before-keywords": [2, "always"], "space-in-parens": [2, "never"], "space-infix-ops": 2, - "space-return-throw-case": 2, "wrap-regex": 2, // ignored stylistic rules @@ -240,8 +238,8 @@ "browser": true }, "globals": { - "define": false, - "require": false + "define": true, + "require": true }, "parser": "babel-eslint", "extends": "eslint:recommended" From b12588846005f6b685d46898c6b9c8cb3b8afe62 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 4 Apr 2016 18:06:22 -0700 Subject: [PATCH 064/216] eslint rule for `use strict` in modules has changed so we don't need it any more. also a few cases of enforcing consistent returns. --- viewer/js/config/app.js | 1 - viewer/js/config/basemaps.js | 1 - viewer/js/config/find.js | 2 +- viewer/js/config/viewer.js | 1 - viewer/js/gis/dijit/Basemaps.js | 1 - viewer/js/gis/dijit/Bookmarks.js | 1 - viewer/js/gis/dijit/Directions.js | 1 - viewer/js/gis/dijit/Draw.js | 2 -- viewer/js/gis/dijit/Editor.js | 1 - viewer/js/gis/dijit/Find.js | 1 - viewer/js/gis/dijit/FloatingTitlePane.js | 1 - viewer/js/gis/dijit/FloatingWidgetDialog.js | 1 - viewer/js/gis/dijit/Geocoder.js | 1 - viewer/js/gis/dijit/Growler.js | 1 - viewer/js/gis/dijit/Help.js | 1 - viewer/js/gis/dijit/Identify.js | 1 - viewer/js/gis/dijit/LayerControl.js | 9 ++++----- viewer/js/gis/dijit/LayerControl/controls/CSV.js | 1 - viewer/js/gis/dijit/LayerControl/controls/Dynamic.js | 7 +++---- viewer/js/gis/dijit/LayerControl/controls/Feature.js | 1 - viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js | 1 - viewer/js/gis/dijit/LayerControl/controls/Image.js | 1 - viewer/js/gis/dijit/LayerControl/controls/ImageVector.js | 1 - viewer/js/gis/dijit/LayerControl/controls/KML.js | 1 - viewer/js/gis/dijit/LayerControl/controls/Raster.js | 1 - viewer/js/gis/dijit/LayerControl/controls/Stream.js | 1 - viewer/js/gis/dijit/LayerControl/controls/Tiled.js | 1 - viewer/js/gis/dijit/LayerControl/controls/VectorTile.js | 1 - viewer/js/gis/dijit/LayerControl/controls/WFS.js | 1 - viewer/js/gis/dijit/LayerControl/controls/WMS.js | 1 - viewer/js/gis/dijit/LayerControl/controls/WebTiled.js | 1 - viewer/js/gis/dijit/LayerControl/controls/_Control.js | 1 - .../js/gis/dijit/LayerControl/controls/_DynamicFolder.js | 5 ++--- .../gis/dijit/LayerControl/controls/_DynamicSublayer.js | 1 - viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js | 1 - viewer/js/gis/dijit/LayerControl/plugins/Transparency.js | 1 - viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js | 5 +++-- viewer/js/gis/dijit/LocateButton.js | 1 - viewer/js/gis/dijit/MapInfo.js | 2 +- viewer/js/gis/dijit/Measurement.js | 1 - viewer/js/gis/dijit/Print.js | 2 +- viewer/js/gis/dijit/StreetView.js | 1 - viewer/js/gis/dijit/Vim.js | 1 - viewer/js/gis/dijit/_FloatingWidgetMixin.js | 1 - viewer/js/gis/plugins/async.js | 1 - viewer/js/viewer/_ConfigMixin.js | 1 - viewer/js/viewer/_ControllerBase.js | 2 +- viewer/js/viewer/_LayoutMixin.js | 2 +- viewer/js/viewer/_MapMixin.js | 2 +- viewer/js/viewer/_WidgetsMixin.js | 1 - 50 files changed, 18 insertions(+), 61 deletions(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index fbd746e44..f2f2f0139 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -1,5 +1,4 @@ (function () { - 'use strict'; var path = location.pathname.replace(/[^\/]+$/, ''); window.dojoConfig = { async: true, diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index f30896ff1..2949e10a0 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -2,7 +2,6 @@ define([ //'esri/dijit/Basemap', //'esri/dijit/BasemapLayer' ], function (/* Basemap, BasemapLayer */) { - 'use strict'; return { map: true, // needs a reference to the map diff --git a/viewer/js/config/find.js b/viewer/js/config/find.js index 760c7b0bb..5e9cb84c7 100644 --- a/viewer/js/config/find.js +++ b/viewer/js/config/find.js @@ -1,4 +1,4 @@ -/*eslint strict: 0, no-console: 0, no-alert: 0*/ +/*eslint no-console: 0, no-alert: 0*/ define({ map: true, zoomExtentFactor: 2, diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 2d71212f7..9569a7007 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -6,7 +6,6 @@ define([ 'esri/tasks/GeometryService', 'esri/layers/ImageParameters' ], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters) { - 'use strict'; // url to your proxy page, must be on same machine hosting you app. See proxy folder for readme. esriConfig.defaults.io.proxyUrl = 'proxy/proxy.ashx'; diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index 3939f845b..440800c41 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Bookmarks.js b/viewer/js/gis/dijit/Bookmarks.js index 3224674e0..0082d887f 100644 --- a/viewer/js/gis/dijit/Bookmarks.js +++ b/viewer/js/gis/dijit/Bookmarks.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Directions.js b/viewer/js/gis/dijit/Directions.js index a0b031b80..524c9cf37 100644 --- a/viewer/js/gis/dijit/Directions.js +++ b/viewer/js/gis/dijit/Directions.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Draw.js b/viewer/js/gis/dijit/Draw.js index 2d5b11219..c7934f1b3 100644 --- a/viewer/js/gis/dijit/Draw.js +++ b/viewer/js/gis/dijit/Draw.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', @@ -216,7 +215,6 @@ define([ } else { return false; } - return false; }, onLayoutChange: function (open) { diff --git a/viewer/js/gis/dijit/Editor.js b/viewer/js/gis/dijit/Editor.js index 4e50d0a59..094377bec 100644 --- a/viewer/js/gis/dijit/Editor.js +++ b/viewer/js/gis/dijit/Editor.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Find.js b/viewer/js/gis/dijit/Find.js index dfa737b3b..71d7d5242 100644 --- a/viewer/js/gis/dijit/Find.js +++ b/viewer/js/gis/dijit/Find.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/FloatingTitlePane.js b/viewer/js/gis/dijit/FloatingTitlePane.js index e73e0d062..81a6c4820 100644 --- a/viewer/js/gis/dijit/FloatingTitlePane.js +++ b/viewer/js/gis/dijit/FloatingTitlePane.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/TitlePane', diff --git a/viewer/js/gis/dijit/FloatingWidgetDialog.js b/viewer/js/gis/dijit/FloatingWidgetDialog.js index 87e781c04..42a0170fa 100644 --- a/viewer/js/gis/dijit/FloatingWidgetDialog.js +++ b/viewer/js/gis/dijit/FloatingWidgetDialog.js @@ -2,7 +2,6 @@ define([ 'dojo/_base/declare', 'dijit/Dialog' ], function (declare, Dialog) { - 'use strict'; return declare([Dialog], { declaredClass: 'gis.dijit.FloatingWidget', diff --git a/viewer/js/gis/dijit/Geocoder.js b/viewer/js/gis/dijit/Geocoder.js index 95d7d6461..b21a9d8fb 100644 --- a/viewer/js/gis/dijit/Geocoder.js +++ b/viewer/js/gis/dijit/Geocoder.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ // adapted from https://github.com/esri/arcgis-dijit-geocoder-button-js/ define([ 'dojo/_base/declare', diff --git a/viewer/js/gis/dijit/Growler.js b/viewer/js/gis/dijit/Growler.js index 89ac59df0..8c5b948b4 100644 --- a/viewer/js/gis/dijit/Growler.js +++ b/viewer/js/gis/dijit/Growler.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Help.js b/viewer/js/gis/dijit/Help.js index 1c0d8fa0a..2594baf0c 100644 --- a/viewer/js/gis/dijit/Help.js +++ b/viewer/js/gis/dijit/Help.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Identify.js b/viewer/js/gis/dijit/Identify.js index 0bd7793a9..dc91afac5 100644 --- a/viewer/js/gis/dijit/Identify.js +++ b/viewer/js/gis/dijit/Identify.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 2c44eb93e..a47cb8c5b 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/array', @@ -181,7 +180,7 @@ define([ this._vectorContainer.getChildren().filter(function (c) { return _filterList(c); })).concat( - this.getChildren().filter(function (c) { + this.getChildren().filter(function (c) { return _filterList(c); })); // follow the same logic as when the layers were added @@ -237,10 +236,10 @@ define([ _applyLayerControlOptions: function (controlOptions, layer) { if (typeof controlOptions.includeUnspecifiedLayers === 'undefined' && typeof controlOptions.subLayerInfos === 'undefined' && typeof controlOptions.excludedLayers === 'undefined') { return; - } + } var esriLayerInfos = []; // Case 1: only show the layers that are explicitly listed - if (!controlOptions.includeUnspecifiedLayers && controlOptions.subLayerInfos && controlOptions.subLayerInfos.length !== 0) { + if (!controlOptions.includeUnspecifiedLayers && controlOptions.subLayerInfos && controlOptions.subLayerInfos.length !== 0) { var subLayerInfos = array.map(controlOptions.subLayerInfos, function (sli) { return sli.id; }); @@ -276,7 +275,7 @@ define([ }), function (l) { return l.id; }); - layer.setVisibleLayers(visibleIds); + layer.setVisibleLayers(visibleIds); }, _mixinLayerInfos: function (esriLayerInfos, subLayerInfos) { // for each of the sublayers, go through the subLayerInfos from the controlOptions and see if defaultVisiblity is set to true or false diff --git a/viewer/js/gis/dijit/LayerControl/controls/CSV.js b/viewer/js/gis/dijit/LayerControl/controls/CSV.js index cd9687c80..e34b5db92 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/CSV.js +++ b/viewer/js/gis/dijit/LayerControl/controls/CSV.js @@ -13,7 +13,6 @@ define([ _Control, legendUtil ) { - 'use strict'; var CSVControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js index 974139148..bc6e8c453 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js @@ -39,7 +39,6 @@ define([ legendUtil, i18n ) { - 'use strict'; var DynamicControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant @@ -100,8 +99,8 @@ define([ _createSublayers: function (layer) { // check for single sublayer - if so no sublayer/folder controls if (layer.layerInfos.length > 1) { - var allLayers = array.map(layer.layerInfos, function (l) { - return l.id; + var allLayers = array.map(layer.layerInfos, function (l) { + return l.id; }); array.forEach(layer.layerInfos, lang.hitch(this, function (info) { // see if there was any override needed from the subLayerInfos array in the controlOptions @@ -113,7 +112,7 @@ define([ slids = info.subLayerIds, controlId = layer.id + '-' + info.id + '-sublayer-control', control; - // it's a top level + // it's a top level if (pid === -1 || allLayers.indexOf(pid) === -1) { if (slids === null) { // it's a top level sublayer diff --git a/viewer/js/gis/dijit/LayerControl/controls/Feature.js b/viewer/js/gis/dijit/LayerControl/controls/Feature.js index 6722e36ae..4ac2061a5 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Feature.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Feature.js @@ -13,7 +13,6 @@ define([ _Control, legendUtil ) { - 'use strict'; var FeatureControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js b/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js index 119d18aaa..86e99a560 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js +++ b/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js @@ -11,7 +11,6 @@ define([ _Contained, _Control ) { - 'use strict'; var GeoRSSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Image.js b/viewer/js/gis/dijit/LayerControl/controls/Image.js index d7b2253a1..6b845d01c 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Image.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Image.js @@ -13,7 +13,6 @@ define([ _Control, legendUtil ) { - 'use strict'; var ImageControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js b/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js index decdb0aca..512b19ac4 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js +++ b/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js @@ -13,7 +13,6 @@ define([ _Control, legendUtil ) { - 'use strict'; var ImageVectorControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/KML.js b/viewer/js/gis/dijit/LayerControl/controls/KML.js index f7fd04c7d..5042c8df2 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/KML.js +++ b/viewer/js/gis/dijit/LayerControl/controls/KML.js @@ -13,7 +13,6 @@ define([ _Control, legendUtil ) { - 'use strict'; var KMLControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Raster.js b/viewer/js/gis/dijit/LayerControl/controls/Raster.js index 2dfb5e508..1ab1bf896 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Raster.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Raster.js @@ -11,7 +11,6 @@ define([ _Contained, _Control ) { - 'use strict'; var RasterControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Stream.js b/viewer/js/gis/dijit/LayerControl/controls/Stream.js index e77b88d92..385cae7a8 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Stream.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Stream.js @@ -13,7 +13,6 @@ define([ _Control, legendUtil ) { - 'use strict'; var StreamControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/Tiled.js b/viewer/js/gis/dijit/LayerControl/controls/Tiled.js index f1cd9106a..242fe3acb 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Tiled.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Tiled.js @@ -13,7 +13,6 @@ define([ _Control, legendUtil ) { - 'use strict'; var TiledControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js b/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js index 189bca3bb..f6901ad4a 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js +++ b/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js @@ -11,7 +11,6 @@ define([ _Contained, _Control ) { - 'use strict'; var VectorTileControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/WFS.js b/viewer/js/gis/dijit/LayerControl/controls/WFS.js index 51e3415e7..848e41d99 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/WFS.js +++ b/viewer/js/gis/dijit/LayerControl/controls/WFS.js @@ -12,7 +12,6 @@ define([ _Contained, _Control ) { - 'use strict'; var WFSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'vector', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/WMS.js b/viewer/js/gis/dijit/LayerControl/controls/WMS.js index db7ff9949..21817901b 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/WMS.js +++ b/viewer/js/gis/dijit/LayerControl/controls/WMS.js @@ -11,7 +11,6 @@ define([ _Contained, _Control ) { - 'use strict'; var WMSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js b/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js index f29e56a3b..3287bcbb8 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js +++ b/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js @@ -11,7 +11,6 @@ define([ _Contained, _Control ) { - 'use strict'; var WebTiledControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { _layerType: 'overlay', // constant diff --git a/viewer/js/gis/dijit/LayerControl/controls/_Control.js b/viewer/js/gis/dijit/LayerControl/controls/_Control.js index 6dd6a8b08..aff0d2166 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_Control.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_Control.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/lang', diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js index f70c9ca65..584a3c9a4 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/lang', @@ -119,8 +118,8 @@ define([ }, destroy: function () { this.inherited(arguments); - this._handlers.forEach(function (h) { - h.remove(); + this._handlers.forEach(function (h) { + h.remove(); }); } }); diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js index e9a7d0fbd..3cce73151 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/lang', diff --git a/viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js b/viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js index c5767ff95..32869d74d 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/LayerMenu.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/Menu', diff --git a/viewer/js/gis/dijit/LayerControl/plugins/Transparency.js b/viewer/js/gis/dijit/LayerControl/plugins/Transparency.js index 54f4344e7..fcabf5e8b 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/Transparency.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/Transparency.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ /* transparency component */ define([ 'dojo/_base/declare', diff --git a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js index a77212ed6..eeef8b35e 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js @@ -31,7 +31,6 @@ define([ esriBundle, i18n ) { - 'use strict'; esriBundle.widgets.legend.NLS_noLegend = i18n.noLegend; @@ -55,6 +54,7 @@ define([ return false; } } + return false; }, // request legend json _legendRequest: function (layer, expandNode, callback, errback) { @@ -335,8 +335,9 @@ define([ param.push(e); } }, this); - return JSON.stringify(param); + return JSON.stringify(param); } + return null; } }; }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LocateButton.js b/viewer/js/gis/dijit/LocateButton.js index 1c7d9e3ab..aeb725496 100644 --- a/viewer/js/gis/dijit/LocateButton.js +++ b/viewer/js/gis/dijit/LocateButton.js @@ -8,7 +8,6 @@ define([ 'esri/InfoTemplate', 'dojo/topic' ], function (declare, lang, LocateButton, SimpleRenderer, PictureMarkerSymbol, GraphicsLayer, InfoTemplate, topic) { - 'use strict'; return declare(null, { growlTemplate: 'latitude: {latitude}
longitude: {longitude}
accuracy: {accuracy}
altitude: {altitude}
altitude accuracy: {altitudeAccuracy}
heading: {heading}
speed: {speed}', diff --git a/viewer/js/gis/dijit/MapInfo.js b/viewer/js/gis/dijit/MapInfo.js index d9c772784..07c238bea 100644 --- a/viewer/js/gis/dijit/MapInfo.js +++ b/viewer/js/gis/dijit/MapInfo.js @@ -23,7 +23,7 @@ define([ topic, proj4 ) { - 'use strict'; + return declare([WidgetBase, TemplatedMixin], { map: null, mode: 'map', diff --git a/viewer/js/gis/dijit/Measurement.js b/viewer/js/gis/dijit/Measurement.js index 1d7ad28a6..d1bf38917 100644 --- a/viewer/js/gis/dijit/Measurement.js +++ b/viewer/js/gis/dijit/Measurement.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Print.js b/viewer/js/gis/dijit/Print.js index df22c0e1f..5c7383255 100644 --- a/viewer/js/gis/dijit/Print.js +++ b/viewer/js/gis/dijit/Print.js @@ -1,4 +1,4 @@ -/*eslint strict: 0, no-eval: 0 */ +/*eslint no-eval: 0 */ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index 77cd0a354..057332415 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -1,5 +1,4 @@ /*global google */ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', diff --git a/viewer/js/gis/dijit/Vim.js b/viewer/js/gis/dijit/Vim.js index 8ad012dc1..22988ed98 100644 --- a/viewer/js/gis/dijit/Vim.js +++ b/viewer/js/gis/dijit/Vim.js @@ -13,7 +13,6 @@ define([ 'dojo/_base/unload', 'dojo/_base/lang' ], function (declare, kernel, cookie, JSON, baseUnload, lang) { - 'use strict'; return declare(null, { constructor: function (idStateName) { diff --git a/viewer/js/gis/dijit/_FloatingWidgetMixin.js b/viewer/js/gis/dijit/_FloatingWidgetMixin.js index 3163d78d7..c3dc7f5d6 100644 --- a/viewer/js/gis/dijit/_FloatingWidgetMixin.js +++ b/viewer/js/gis/dijit/_FloatingWidgetMixin.js @@ -1,4 +1,3 @@ -/*eslint strict: 0*/ define([ 'dojo/_base/declare', 'dojo/on', diff --git a/viewer/js/gis/plugins/async.js b/viewer/js/gis/plugins/async.js index 4e63ab811..bf56f173d 100644 --- a/viewer/js/gis/plugins/async.js +++ b/viewer/js/gis/plugins/async.js @@ -1,5 +1,4 @@ define(function () { - 'use strict'; var cb = '_asyncApiLoaderCallback'; return { diff --git a/viewer/js/viewer/_ConfigMixin.js b/viewer/js/viewer/_ConfigMixin.js index 62e0115a1..0113fc381 100644 --- a/viewer/js/viewer/_ConfigMixin.js +++ b/viewer/js/viewer/_ConfigMixin.js @@ -7,7 +7,6 @@ define([ lang, Deferred ) { - 'use strict'; return declare(null, { diff --git a/viewer/js/viewer/_ControllerBase.js b/viewer/js/viewer/_ControllerBase.js index 4fc35620d..08ae67ed6 100644 --- a/viewer/js/viewer/_ControllerBase.js +++ b/viewer/js/viewer/_ControllerBase.js @@ -1,4 +1,4 @@ -/*eslint strict: 0, no-console: 0*/ +/*eslint no-console: 0*/ define([ 'dojo/_base/declare', 'dojo/_base/lang' diff --git a/viewer/js/viewer/_LayoutMixin.js b/viewer/js/viewer/_LayoutMixin.js index 8bd2eef67..9ba077ae5 100644 --- a/viewer/js/viewer/_LayoutMixin.js +++ b/viewer/js/viewer/_LayoutMixin.js @@ -43,7 +43,7 @@ define([ mapOverlay ) { - 'use strict'; + return declare(null, { panes: { diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index f265319dd..2c30c7bfe 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -20,7 +20,7 @@ define([ Map ) { - 'use strict'; + return declare(null, { initMapAsync: function () { diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index e7de474ab..78dc52f41 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -25,7 +25,6 @@ define([ FloatingWidgetDialog ) { - 'use strict'; return declare(null, { legendLayerInfos: [], From 4eaebbffa734163bfbdd34acb7452f4d153ea79a Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 4 Apr 2016 18:48:52 -0700 Subject: [PATCH 065/216] switch from deprecated `grunt-autoprefixer` to `grunt-postcss` --- Gruntfile.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 76dd07503..55c15596a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -51,7 +51,7 @@ module.exports = function (grunt) { src: ['dist'] } }, - autoprefixer: { + postcss: { build: { expand: true, cwd: 'dist/viewer', @@ -161,7 +161,7 @@ module.exports = function (grunt) { // load the tasks grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-autoprefixer'); + grunt.loadNpmTasks('grunt-postcss'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-uglify'); @@ -177,6 +177,6 @@ module.exports = function (grunt) { grunt.registerTask('build', 'Compiles all of the assets and copies the files to the build directory.', ['clean', 'copy', 'scripts', 'stylesheets', 'compress:build']); grunt.registerTask('build-view', 'Compiles all of the assets and copies the files to the build directory starts a web server and opens browser to preview app.', ['clean', 'copy', 'scripts', 'stylesheets', 'compress:build', 'connect:build', 'open:build_browser', 'watch:build']); grunt.registerTask('scripts', 'Compiles the JavaScript files.', ['eslint', 'uglify']); - grunt.registerTask('stylesheets', 'Auto prefixes css and compiles the stylesheets.', ['csslint:lax', 'autoprefixer', 'cssmin']); + grunt.registerTask('stylesheets', 'Auto prefixes css and compiles the stylesheets.', ['csslint:lax', 'postcss', 'cssmin']); grunt.registerTask('lint', 'Run eslint and csslint.', ['eslint', 'csslint:strict']); }; \ No newline at end of file From 991234ee6ffdc613d9d870868694d9ed67f00bca Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 4 Apr 2016 19:04:52 -0700 Subject: [PATCH 066/216] updating node versions. postcss fails on travis-ci because of our old version of node. --- .travis.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cec756b2c..88a5a983b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: -- '0.10' +- '5' sudo: false before_install: npm install -g grunt-cli before_script: grunt build --verbose diff --git a/package.json b/package.json index e33245645..58ad7b674 100644 --- a/package.json +++ b/package.json @@ -25,5 +25,5 @@ "grunt-contrib-compress": "1.2.x", "proxypage": "*" }, - "engine": "node >= 0.12" + "engine": "node >= 4" } \ No newline at end of file From 1420dad8e1f32c94a7a1db58ad489682bddeaf8b Mon Sep 17 00:00:00 2001 From: AlexThomasEOG Date: Thu, 7 Apr 2016 18:42:34 -0500 Subject: [PATCH 067/216] Track Scale Range Handler for final destroy() The scaleRangeHandler was being tracked outside of the _handlers list. In some scenarios this handler would never be released. This fix confirms that this handler is tracked for a final destroy --- .../dijit/LayerControl/controls/_Control.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl/controls/_Control.js b/viewer/js/gis/dijit/LayerControl/controls/_Control.js index 6dd6a8b08..9ee4cf867 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_Control.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_Control.js @@ -2,7 +2,7 @@ define([ 'dojo/_base/declare', 'dojo/_base/lang', - //'dojo/_base/array', + 'dojo/_base/array', 'dojo/on', 'dojo/topic', 'dojo/dom-construct', @@ -16,7 +16,7 @@ define([ ], function ( declare, lang, - //array, + array, on, topic, domConst, @@ -194,11 +194,23 @@ define([ _scaleRangeChange: function () { if (this.layer.minScale !== 0 || this.layer.maxScale !== 0) { this._checkboxScaleRange(); + if (this._scaleRangeHandler) { + var handlerIndex = array.indexOf(this._handlers, this._scaleRangeHandler); + if (handlerIndex !== -1) { + this._handlers[handlerIndex].remove(); + this._handlers.splice(handlerIndex, 1); + } + } this._scaleRangeHandler = this.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')); + this._handlers.push(this._scaleRangeHandler); } else { this._checkboxScaleRange(); if (this._scaleRangeHandler) { - this._scaleRangeHandler.remove(); + var handlerIndex2 = array.indexOf(this._handlers, this._scaleRangeHandler); + if (handlerIndex2 !== -1) { + this._handlers[handlerIndex2].remove(); + this._handlers.splice(handlerIndex2, 1); + } this._scaleRangeHandler = null; } } From 7d1c51f702747e4349205446f4a60f7d3b254039 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 10 Apr 2016 20:14:29 -0700 Subject: [PATCH 068/216] including panes config in viewer.js breaks application. this was introduced when Controller was split into separate mixins. --- viewer/js/viewer/_LayoutMixin.js | 16 +++++++++++----- viewer/js/viewer/_MapMixin.js | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/viewer/js/viewer/_LayoutMixin.js b/viewer/js/viewer/_LayoutMixin.js index 8bd2eef67..69273aa5f 100644 --- a/viewer/js/viewer/_LayoutMixin.js +++ b/viewer/js/viewer/_LayoutMixin.js @@ -75,7 +75,7 @@ define([ addTopics: function () { // toggle a sidebar pane topic.subscribe('viewer/togglePane', lang.hitch(this, function (args) { - this.toggleSidebar(args.pane, args.show); + this.togglePane(args.pane, args.show); })); // load a widget @@ -160,12 +160,17 @@ define([ } } this.panes.outer.startup(); - this.createPanes(panes); }, - createPanes: function (panes) { - var key; - // where to place the buttons + createPanes: function () { + var key, + panes = this.config.panes || {}; + for (key in this.panes) { + if (this.panes.hasOwnProperty(key)) { + panes[key] = lang.mixin(this.panes[key], panes[key]); + } + } + // where to place the buttons // either the center map pane or the outer pane? this.collapseButtonsPane = this.config.collapseButtonsPane || 'outer'; @@ -204,6 +209,7 @@ define([ } } + this.resizeLayout(); }, togglePane: function (id, show) { diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index f265319dd..75a1314d3 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -177,7 +177,7 @@ define([ }); // in _LayoutsMixin - this.resizeLayout(); + this.createPanes(); // in _WidgetsMixin this.initWidgets(); From 4f6a94b959e755a1d7cc156122ecccd16ac014ce Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 11 Apr 2016 10:19:58 -0700 Subject: [PATCH 069/216] `currentBasemap` should not be set prior to updating the basemap. --- viewer/js/gis/dijit/Basemaps.js | 1 - 1 file changed, 1 deletion(-) diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index 3939f845b..18415f7e2 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -142,7 +142,6 @@ define([ startup: function () { this.inherited(arguments); if (this.mapStartBasemap) { - this.currentBasemap = this.mapStartBasemap; if (this.map.getBasemap() !== this.mapStartBasemap) { this.updateBasemap(this.mapStartBasemap); } From df3f889d2a9832476ef2986f644a173683c74611 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 18 Apr 2016 16:09:05 -0700 Subject: [PATCH 070/216] remove unused css and html from Draw widget. A little clean up for better compatibility with themes other than dbootstrap. --- viewer/js/gis/dijit/Draw/css/Draw.css | 76 +------- viewer/js/gis/dijit/Draw/templates/Draw.html | 175 +++++++++---------- 2 files changed, 84 insertions(+), 167 deletions(-) diff --git a/viewer/js/gis/dijit/Draw/css/Draw.css b/viewer/js/gis/dijit/Draw/css/Draw.css index d1943125f..cd2618c97 100644 --- a/viewer/js/gis/dijit/Draw/css/Draw.css +++ b/viewer/js/gis/dijit/Draw/css/Draw.css @@ -1,18 +1,15 @@ -.gis_DrawDijit { -} - .gis_DrawDijit .outerList>li { margin-bottom: 1em; } .gis_DrawDijit .list-unstyled { - padding-left: 0px; + padding-left: 0; list-style-type: none; list-style-position: outside; list-style-image: none; } .gis_DrawDijit .list-inline { - padding-left: 0px; + padding-left: 0; margin-left: -5px; list-style-type: none; list-style-position: outside; @@ -23,75 +20,10 @@ display: inline-block; } -.gis_DrawDijit .drawButton { - width: 50px; -} - -.gis_DrawDijit .stopIcon { - color: red; -} - -.gis_DrawDijit .drawButton .dijitButtonText { - /*display: none;*/ -} -.gis_DrawDijit .polyIcon { - background-image: url(../images/toolbar_icons.png); - background-position: -68px 0; - width: 16px; - height: 16px; -} - -.gis_DrawDijit .pointIcon { - background-image: url(../images/toolbar_icons.png); - background-position: 0px 0; - width: 16px; - height: 16px; -} - -.gis_DrawDijit .circleDrawIcon { - background-image: url(../images/toolbar_icons.png); - background-position: -390px 0; - width: 16px; - height: 16px; -} - -.gis_DrawDijit .lineIcon { - background-image: url(../images/toolbar_icons.png); - background-position: -34px 0; - width: 16px; - height: 16px; -} - -.gis_DrawDijit .freehandDrawIcon { - background-image: url(../images/toolbar_icons.png); - background-position: -102px 0; - width: 16px; - height: 16px; -} - -.gis_DrawDijit .freehandPolygonDrawIcon { - background-image: url(../images/toolbar_icons_2.png); - background-position: -473px 0; - width: 16px; - height: 16px; -} - -.gis_DrawDijit .clearIcon { - background-image: url(../images/clear.png); - width: 16px; - height: 16px; -} - .gis_DrawDijit .formContainer { - /*border: 1px solid #bbb;*/ - margin-bottom: -1px; width: 100%; } -.gis_DrawDijit .buttonActionBar { - /*background-color: #F2F2F2; - border: 1px solid #CDCDCD;*/ - padding: 3px 0px 2px 0px; - text-align: right; - width: 100%; +.gis_DrawDijit .dijitButtonNode .dijitIcon { + margin-right: 0; } \ No newline at end of file diff --git a/viewer/js/gis/dijit/Draw/templates/Draw.html b/viewer/js/gis/dijit/Draw/templates/Draw.html index 2fe283f7a..eabb9e1c0 100644 --- a/viewer/js/gis/dijit/Draw/templates/Draw.html +++ b/viewer/js/gis/dijit/Draw/templates/Draw.html @@ -1,100 +1,85 @@
-
-
    +
      +
    • +
        +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      +
    • +
    • +
      + ${i18n.labels.currentDrawMode} + ${i18n.labels.currentDrawModeNone} +
      +
    • -
    • -
        - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      • - -
      -
    • - -
    • -
      - ${i18n.labels.currentDrawMode} - ${i18n.labels.currentDrawModeNone} -
      -
    • - -
    - -
+
-
From 2c6623dca07b9bd11c678176d6d7892ced30a282 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Tue, 19 Apr 2016 12:48:22 -0500 Subject: [PATCH 071/216] Removes unused images --- viewer/js/gis/dijit/Draw/images/clear.png | Bin 648 -> 0 bytes .../js/gis/dijit/Draw/images/toolbar_icons.png | Bin 6603 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 viewer/js/gis/dijit/Draw/images/clear.png delete mode 100644 viewer/js/gis/dijit/Draw/images/toolbar_icons.png diff --git a/viewer/js/gis/dijit/Draw/images/clear.png b/viewer/js/gis/dijit/Draw/images/clear.png deleted file mode 100644 index 0b82e3f886f77eb748c0baba9f868a4d4c7263c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 648 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 JPDHLkV1ircy} Date: Tue, 19 Apr 2016 16:14:37 -0700 Subject: [PATCH 072/216] add user-defined layers --- viewer/js/viewer/_MapMixin.js | 46 ++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index 57cd22244..4806d7e75 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -60,34 +60,36 @@ define([ _initLayers: function (returnWarnings) { this.layers = []; var layerTypes = { - csv: 'CSV', - dataadapter: 'DataAdapterFeature', //untested - dynamic: 'ArcGISDynamicMapService', - feature: 'Feature', - georss: 'GeoRSS', - image: 'ArcGISImageService', - imagevector: 'ArcGISImageServiceVector', - kml: 'KML', - label: 'Label', //untested - mapimage: 'MapImage', //untested - osm: 'OpenStreetMap', - raster: 'Raster', - stream: 'Stream', - tiled: 'ArcGISTiledMapService', - vectortile: 'VectorTile', - webtiled: 'WebTiled', - wfs: 'WFS', - wms: 'WMS', - wmts: 'WMTS' //untested + csv: 'esri/layers/CSVLayer', + dataadapter: 'esri/layers/DataAdapterFeatureLayer', //untested + dynamic: 'esri/layers/ArcGISDynamicMapServiceLayer', + feature: 'esri/layers/FeatureLayer', + georss: 'esri/layers/GeoRSSLayer', + image: 'esri/layers/ArcGISImageServiceLayer', + imagevector: 'esri/layers/ArcGISImageServiceVectorLayer', + kml: 'esri/layers/KMLLayer', + label: 'esri/layers/LabelLayer', //untested + mapimage: 'esri/layers/MapImageLayer', //untested + osm: 'esri/layers/OpenStreetMapLayer', + raster: 'esri/layers/RasterLayer', + stream: 'esri/layers/StreamLayer', + tiled: 'esri/layers/ArcGISTiledMapServiceLayer', + vectortile: 'esri/layers/VectorTileLayer', + webtiled: 'esri/layers/WebTiledLayer', + wfs: 'esri/layers/WFSLayer', + wms: 'esri/layers/WMSLayer', + wmts: 'esri/layers/WMTSLayer' //untested }; + // add any user-defined layer types such as https://github.com/Esri/geojson-layer-js + layerTypes = lang.mixin(layerTypes, this.config.layerTypes || {}); // loading all the required modules first ensures the layer order is maintained var modules = []; array.forEach(this.config.operationalLayers, function (layer) { var type = layerTypes[layer.type]; if (type) { - modules.push('esri/layers/' + type + 'Layer'); + modules.push(type); } else { - returnWarnings.push('Layer type "' + layer.type + '"" isnot supported: '); + returnWarnings.push('Layer type "' + layer.type + '" is not supported: '); } }, this); @@ -95,7 +97,7 @@ define([ array.forEach(this.config.operationalLayers, function (layer) { var type = layerTypes[layer.type]; if (type) { - require(['esri/layers/' + type + 'Layer'], lang.hitch(this, '_initLayer', layer)); + require([type], lang.hitch(this, '_initLayer', layer)); } }, this); this.map.addLayers(this.layers); From b9b367a678f423ed0ecb2b531c37a4d63e76ec05 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Tue, 19 Apr 2016 16:14:55 -0700 Subject: [PATCH 073/216] add user-defined widgets --- viewer/js/viewer/_WidgetsMixin.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index 78dc52f41..22624d9a3 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -79,8 +79,10 @@ define([ widgetLoader: function (widgetConfig, position) { var parentId, pnl; - // only proceed for valid widget types var widgetTypes = ['titlePane', 'contentPane', 'floating', 'domNode', 'invisible', 'map']; + // add any user-defined widget types + widgetTypes = widgetTypes.concat(this.config.widgetTypes || []); + // only proceed for valid widget types if (array.indexOf(widgetTypes, widgetConfig.type) < 0) { this.handleError({ source: 'Controller', From 357d924ff1a5c04dedf531c83c592778a6120b73 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Tue, 19 Apr 2016 16:15:23 -0700 Subject: [PATCH 074/216] add user-defined controls for layerControl widget --- viewer/js/gis/dijit/LayerControl.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index a47cb8c5b..c1158b1f0 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -85,6 +85,8 @@ define([ }); return; } + // add any user-defined controls - possibly for user-defined layers + this._controls = lang.mixin(this._controls, options.controls || {}); }, postCreate: function () { this.inherited(arguments); From 3bba918626859950fbde5fa8a7fa7389ff33b9e9 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Tue, 19 Apr 2016 16:15:58 -0700 Subject: [PATCH 075/216] add examples of custom titles, layerTypes and widgetTypes --- viewer/js/config/viewer.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 9569a7007..39b0194b2 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -53,6 +53,7 @@ define([ zoom: 5, sliderStyle: 'small' }, + // panes: { // left: { // splitter: true @@ -81,6 +82,29 @@ define([ // }, // collapseButtonsPane: 'center', //center or outer + // custom titles + /* + titles: { + header: 'My App', + subHeader: 'My GIS App is the best!', + pageTitle: 'My App' + }, + */ + + // user-defined layer types + /* + layerTypes: { + myCustomLayer: 'widgets/MyCustomLayer' + }, + */ + + // user-defined widget types + /* + widgetTypes: [ + 'myWidgetType' + ], + */ + // operationalLayers: Array of Layers to load on top of the basemap: valid 'type' options: 'dynamic', 'tiled', 'feature'. // The 'options' object is passed as the layers options for constructor. Title will be used in the legend only. id's must be unique and have no spaces. // 3 'mode' options: MODE_SNAPSHOT = 0, MODE_ONDEMAND = 1, MODE_SELECTION = 2 From 6e1122f3ac9a25e664dc1ef87d3e89316ebfd3e5 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 25 Apr 2016 15:56:55 -0700 Subject: [PATCH 076/216] Add a TimeExtent to the Identify Parameters when appropriate. --- viewer/js/gis/dijit/Identify.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/viewer/js/gis/dijit/Identify.js b/viewer/js/gis/dijit/Identify.js index dc91afac5..dff75e193 100644 --- a/viewer/js/gis/dijit/Identify.js +++ b/viewer/js/gis/dijit/Identify.js @@ -16,13 +16,14 @@ define([ 'esri/tasks/IdentifyTask', 'esri/tasks/IdentifyParameters', 'esri/dijit/PopupTemplate', + 'esri/TimeExtent', 'dojo/text!./Identify/templates/Identify.html', 'dojo/i18n!./Identify/nls/resource', 'dijit/form/Form', 'dijit/form/FilteringSelect', 'xstyle/css!./Identify/css/Identify.css' -], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, MenuItem, lang, array, all, topic, query, domStyle, domClass, Moveable, Memory, IdentifyTask, IdentifyParameters, PopupTemplate, IdentifyTemplate, i18n) { +], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, MenuItem, lang, array, all, topic, query, domStyle, domClass, Moveable, Memory, IdentifyTask, IdentifyParameters, PopupTemplate, TimeExtent, IdentifyTemplate, i18n) { return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { widgetsInTemplate: true, @@ -181,6 +182,9 @@ define([ var params = lang.clone(identifyParams); params.layerDefinitions = layer.ref.layerDefinitions; params.layerIds = layerIds; + if (layer.ref.timeInfo && layer.ref.timeInfo.timeExtent && this.map.timeExtent) { + params.timeExtent = new TimeExtent(this.map.timeExtent.startTime, this.map.timeExtent.endTime); + } identifies.push(layer.identifyTask.execute(params)); identifiedlayers.push(layer); } From f55eb49c8818fde59395bfad9e082cde37e9baaf Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 30 Apr 2016 09:39:24 -0700 Subject: [PATCH 077/216] Fixes #552 --- viewer/js/config/app.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index f2f2f0139..9f1730767 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -12,6 +12,14 @@ }, { name: 'config', location: path + 'js/config' + }, { + name: 'put-selector', + main: 'put', + location: 'https://cdn.rawgit.com/kriszyp/put-selector/v0.3.6' + }, { + name: 'xstyle', + main: 'css', + location: 'https://cdn.rawgit.com/kriszyp/xstyle/master' } ] }; From 0696a28eef3b45defa3fb7927a8597e36172b26c Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 2 May 2016 20:52:00 -0700 Subject: [PATCH 078/216] swtich to the newly tagged release of xstyle. --- viewer/js/config/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 9f1730767..e8084d7c7 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -19,7 +19,7 @@ }, { name: 'xstyle', main: 'css', - location: 'https://cdn.rawgit.com/kriszyp/xstyle/master' + location: 'https://cdn.rawgit.com/kriszyp/xstyle/v0.3.2' } ] }; From e8ef1830c8aa1a8de8f15ee6028f8e8e20a034aa Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Tue, 19 Apr 2016 15:21:00 -0500 Subject: [PATCH 079/216] Move proj4 to the app config to allow developers to use offline version of proj4. --- viewer/js/config/app.js | 4 +++- viewer/js/gis/dijit/MapInfo.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index e8084d7c7..7a4a11cc4 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -15,6 +15,8 @@ }, { name: 'put-selector', main: 'put', + name: 'proj4js', + location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' location: 'https://cdn.rawgit.com/kriszyp/put-selector/v0.3.6' }, { name: 'xstyle', @@ -61,4 +63,4 @@ ]))(); controller.startup(); }); -})(); \ No newline at end of file +})(); diff --git a/viewer/js/gis/dijit/MapInfo.js b/viewer/js/gis/dijit/MapInfo.js index 07c238bea..6f674e665 100644 --- a/viewer/js/gis/dijit/MapInfo.js +++ b/viewer/js/gis/dijit/MapInfo.js @@ -10,7 +10,7 @@ define([ 'dojo/dom-style', 'dojo/number', 'dojo/topic', - '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12/proj4.js', + 'proj4js/proj4', 'xstyle/css!./MapInfo/css/MapInfo.css' ], function ( declare, @@ -217,4 +217,4 @@ define([ return deg + '°' + minIntTxt + '\'' + secTxt + '" ' + dir; } }); -}); \ No newline at end of file +}); From c5eeb40796cd0e10f65fc17307c6646f16d5d38f Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Tue, 19 Apr 2016 15:26:53 -0500 Subject: [PATCH 080/216] Remove proj4 cdn path from streetview --- viewer/js/gis/dijit/StreetView.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index 057332415..51cb49719 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -17,9 +17,8 @@ define([ 'esri/geometry/Point', 'esri/SpatialReference', 'dijit/MenuItem', - '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12/proj4.js', + 'proj4js/proj4', 'dojo/i18n!./StreetView/nls/resource', - 'dijit/form/ToggleButton', 'xstyle/css!./StreetView/css/StreetView.css', 'gis/plugins/async!//maps.google.com/maps/api/js?v=3' @@ -302,4 +301,4 @@ define([ this.mapClickMode = mode; } }); -}); \ No newline at end of file +}); From 35e8d8db7f5c51be1aed5ef90cb7956d6a5cb47f Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Wed, 20 Apr 2016 07:54:41 -0500 Subject: [PATCH 081/216] Add a package.js build descriptor file --- package.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 package.js diff --git a/package.js b/package.js new file mode 100644 index 000000000..e24076f02 --- /dev/null +++ b/package.js @@ -0,0 +1,43 @@ +/** + * This file is referenced by the `dojoBuild` key in `package.json` and provides extra hinting specific to the Dojo + * build system about how certain files in the package need to be handled at build time. Build profiles for the + * application itself are stored in the `profiles` directory. + */ + +var profile = { + // Resource tags are functions that provide hints to the build system about the way files should be processed. + // Each of these functions is called once for every file in the package directory. The first argument passed to + // the function is the filename of the file, and the second argument is the computed AMD module ID of the file. + resourceTags: { + // Files that contain test code and should be excluded when the `copyTests` build flag exists and is `false`. + // It is strongly recommended that the `mini` build flag be used instead of `copyTests`. Therefore, no files + // are marked with the `test` tag here. + test: function (filename, mid) { + return false; + }, + + // Files that should be copied as-is without being modified by the build system. + // All files in the `app/resources` directory that are not CSS files are marked as copy-only, since these files + // are typically binaries (images, etc.) and may be corrupted by the build system if it attempts to process + // them and naively assumes they are scripts. + copyOnly: function (filename, mid) { + return (/^app\/resources\//.test(mid) && !/\.css$/.test(filename)); + }, + + // Files that are AMD modules. + // All JavaScript in this package should be AMD modules if you are starting a new project. If you are copying + // any legacy scripts from an existing project, those legacy scripts should not be given the `amd` tag. + amd: function (filename, mid) { + return !this.copyOnly(filename, mid) && /\.js$/.test(filename); + }, + + // Files that should not be copied when the `mini` build flag is set to true. + // In this case, we are excluding this package configuration file which is not necessary in a built copy of + // the application. + miniExclude: function (filename, mid) { + return mid in { + 'cmv/package': 1 + }; + } + } +}; From becb23c4accd7f4481924b9505e4c99bc370c06c Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 21 Apr 2016 11:17:19 -0500 Subject: [PATCH 082/216] Switch to the bower version of google maps loader. --- viewer/js/gis/dijit/StreetView.js | 77 ++++++----- viewer/js/gis/plugins/Google.js | 219 ++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+), 34 deletions(-) create mode 100644 viewer/js/gis/plugins/Google.js diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index 51cb49719..403b526e2 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -19,28 +19,19 @@ define([ 'dijit/MenuItem', 'proj4js/proj4', 'dojo/i18n!./StreetView/nls/resource', + 'gis/plugins/Google', 'dijit/form/ToggleButton', - 'xstyle/css!./StreetView/css/StreetView.css', - 'gis/plugins/async!//maps.google.com/maps/api/js?v=3' -], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, aspect, topic, GraphicsLayer, Graphic, SimpleRenderer, template, PictureMarkerSymbol, domStyle, domGeom, Point, SpatialReference, MenuItem, proj4, i18n) { - + 'xstyle/css!./StreetView/css/StreetView.css' + // 'gis/plugins/async!//maps.google.com/maps/api/js?v=3' +], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, aspect, topic, GraphicsLayer, Graphic, SimpleRenderer, template, PictureMarkerSymbol, domStyle, domGeom, Point, SpatialReference, MenuItem, proj4, i18n, Google) { + var google; return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { widgetsInTemplate: true, templateString: template, i18n: i18n, mapClickMode: null, - panoOptions: { - addressControlOptions: { - position: google.maps.ControlPosition.TOP_RIGHT - }, - linksControl: false, - panControl: false, - zoomControlOptions: { - style: google.maps.ZoomControlStyle.SMALL - }, - enableCloseButton: false - }, + panoOptions: null, // in case this changes some day proj4BaseURL: 'http://spatialreference.org/', @@ -56,29 +47,47 @@ define([ postCreate: function () { this.inherited(arguments); - this.createGraphicsLayer(); - this.map.on('click', lang.hitch(this, 'getStreetView')); + //load the google api asynchronously + Google.load(lang.hitch(this, function(g){ + //store a reference to google + google = g; - this.own(topic.subscribe('mapClickMode/currentSet', lang.hitch(this, 'setMapClickMode'))); + //init our panoOptions since they depend on google + this.panoOptions = { + addressControlOptions: { + position: google.maps.ControlPosition.TOP_RIGHT + }, + linksControl: false, + panControl: false, + zoomControlOptions: { + style: google.maps.ZoomControlStyle.SMALL + }, + enableCloseButton: false + }; + this.createGraphicsLayer(); + this.map.on('click', lang.hitch(this, 'getStreetView')); - if (this.parentWidget) { - if (this.parentWidget.toggleable) { - this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { - this.onLayoutChange(this.parentWidget.open); - }))); - } - this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, 'resize'))); - this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); - } + this.own(topic.subscribe('mapClickMode/currentSet', lang.hitch(this, 'setMapClickMode'))); - // spatialreference.org uses the old - // Proj4js style so we need an alias - // https://github.com/proj4js/proj4js/issues/23 - window.Proj4js = proj4; + if (this.parentWidget) { + if (this.parentWidget.toggleable) { + this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { + this.onLayoutChange(this.parentWidget.open); + }))); + } + this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, 'resize'))); + this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); + } - if (this.mapRightClickMenu) { - this.addRightClickMenu(); - } + // spatialreference.org uses the old + // Proj4js style so we need an alias + // https://github.com/proj4js/proj4js/issues/23 + window.Proj4js = proj4; + + if (this.mapRightClickMenu) { + this.addRightClickMenu(); + } + })); }, createGraphicsLayer: function () { this.pointSymbol = new PictureMarkerSymbol(require.toUrl('gis/dijit/StreetView/images/blueArrow.png'), 30, 30); diff --git a/viewer/js/gis/plugins/Google.js b/viewer/js/gis/plugins/Google.js new file mode 100644 index 000000000..3d9435c82 --- /dev/null +++ b/viewer/js/gis/plugins/Google.js @@ -0,0 +1,219 @@ +(function(root, factory) { + + if (root === null) { + throw new Error('Google-maps package can be used only in browser'); + } + + if (typeof define === 'function' && define.amd) { + define(factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.GoogleMapsLoader = factory(); + } + +})(typeof window !== 'undefined' ? window : null, function() { + + + 'use strict'; + + + var googleVersion = '3.18'; + + var script = null; + + var google = null; + + var loading = false; + + var callbacks = []; + + var onLoadEvents = []; + + var originalCreateLoaderMethod = null; + + + var GoogleMapsLoader = {}; + + + GoogleMapsLoader.URL = 'https://maps.googleapis.com/maps/api/js'; + + GoogleMapsLoader.KEY = null; + + GoogleMapsLoader.LIBRARIES = []; + + GoogleMapsLoader.CLIENT = null; + + GoogleMapsLoader.CHANNEL = null; + + GoogleMapsLoader.LANGUAGE = null; + + GoogleMapsLoader.REGION = null; + + GoogleMapsLoader.VERSION = googleVersion; + + GoogleMapsLoader.WINDOW_CALLBACK_NAME = '__google_maps_api_provider_initializator__'; + + + GoogleMapsLoader._googleMockApiObject = {}; + + + GoogleMapsLoader.load = function(fn) { + if (google === null) { + if (loading === true) { + if (fn) { + callbacks.push(fn); + } + } else { + loading = true; + + window[GoogleMapsLoader.WINDOW_CALLBACK_NAME] = function() { + ready(fn); + }; + + GoogleMapsLoader.createLoader(); + } + } else if (fn) { + fn(google); + } + }; + + + GoogleMapsLoader.createLoader = function() { + script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = GoogleMapsLoader.createUrl(); + + document.body.appendChild(script); + }; + + + GoogleMapsLoader.isLoaded = function() { + return google !== null; + }; + + + GoogleMapsLoader.createUrl = function() { + var url = GoogleMapsLoader.URL; + + url += '?callback=' + GoogleMapsLoader.WINDOW_CALLBACK_NAME; + + if (GoogleMapsLoader.KEY) { + url += '&key=' + GoogleMapsLoader.KEY; + } + + if (GoogleMapsLoader.LIBRARIES.length > 0) { + url += '&libraries=' + GoogleMapsLoader.LIBRARIES.join(','); + } + + if (GoogleMapsLoader.CLIENT) { + url += '&client=' + GoogleMapsLoader.CLIENT + '&v=' + GoogleMapsLoader.VERSION; + } + + if (GoogleMapsLoader.CHANNEL) { + url += '&channel=' + GoogleMapsLoader.CHANNEL; + } + + if (GoogleMapsLoader.LANGUAGE) { + url += '&language=' + GoogleMapsLoader.LANGUAGE; + } + + if (GoogleMapsLoader.REGION) { + url += '®ion=' + GoogleMapsLoader.REGION; + } + + return url; + }; + + + GoogleMapsLoader.release = function(fn) { + var release = function() { + GoogleMapsLoader.KEY = null; + GoogleMapsLoader.LIBRARIES = []; + GoogleMapsLoader.CLIENT = null; + GoogleMapsLoader.CHANNEL = null; + GoogleMapsLoader.LANGUAGE = null; + GoogleMapsLoader.REGION = null; + GoogleMapsLoader.VERSION = googleVersion; + + google = null; + loading = false; + callbacks = []; + onLoadEvents = []; + + if (typeof window.google !== 'undefined') { + delete window.google; + } + + if (typeof window[GoogleMapsLoader.WINDOW_CALLBACK_NAME] !== 'undefined') { + delete window[GoogleMapsLoader.WINDOW_CALLBACK_NAME]; + } + + if (originalCreateLoaderMethod !== null) { + GoogleMapsLoader.createLoader = originalCreateLoaderMethod; + originalCreateLoaderMethod = null; + } + + if (script !== null) { + script.parentElement.removeChild(script); + script = null; + } + + if (fn) { + fn(); + } + }; + + if (loading) { + GoogleMapsLoader.load(function() { + release(); + }); + } else { + release(); + } + }; + + + GoogleMapsLoader.onLoad = function(fn) { + onLoadEvents.push(fn); + }; + + + GoogleMapsLoader.makeMock = function() { + originalCreateLoaderMethod = GoogleMapsLoader.createLoader; + + GoogleMapsLoader.createLoader = function() { + window.google = GoogleMapsLoader._googleMockApiObject; + window[GoogleMapsLoader.WINDOW_CALLBACK_NAME](); + }; + }; + + + var ready = function(fn) { + var i; + + loading = false; + + if (google === null) { + google = window.google; + } + + for (i = 0; i < onLoadEvents.length; i++) { + onLoadEvents[i](google); + } + + if (fn) { + fn(google); + } + + for (i = 0; i < callbacks.length; i++) { + callbacks[i](google); + } + + callbacks = []; + }; + + + return GoogleMapsLoader; + +}); From ec2b69105ce55ba8cbffa7a33efa17769dff157d Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 21 Apr 2016 11:17:48 -0500 Subject: [PATCH 083/216] Use quotes around reserved property 'float' --- viewer/js/gis/dijit/Directions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/viewer/js/gis/dijit/Directions.js b/viewer/js/gis/dijit/Directions.js index 524c9cf37..9ae0f36fe 100644 --- a/viewer/js/gis/dijit/Directions.js +++ b/viewer/js/gis/dijit/Directions.js @@ -30,8 +30,8 @@ define([ this.directions._activateButton.style.display = 'none'; } else if (this.directions._activateButtonNode) { this.directions._activateButtonNode.style.display = 'none'; - this.directions._addDestinationNode.style.float = 'inherit'; - this.directions._optionsButtonNode.style.float = 'inherit'; + this.directions._addDestinationNode.style['float'] = 'inherit'; + this.directions._optionsButtonNode.style['float'] = 'inherit'; this.directions._optionsButtonNode.style.marginRight = '5px'; } @@ -130,4 +130,4 @@ define([ }); } }); -}); \ No newline at end of file +}); From 2e74d2174019e919c26b95758001b54b6d4a985c Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 21 Apr 2016 13:00:34 -0500 Subject: [PATCH 084/216] Update package descriptor to only copy the image files --- package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.js b/package.js index e24076f02..765d02464 100644 --- a/package.js +++ b/package.js @@ -21,7 +21,7 @@ var profile = { // are typically binaries (images, etc.) and may be corrupted by the build system if it attempts to process // them and naively assumes they are scripts. copyOnly: function (filename, mid) { - return (/^app\/resources\//.test(mid) && !/\.css$/.test(filename)); + return (/^cmv\/(images)\//.test(mid) && !/\.css$/.test(filename)); }, // Files that are AMD modules. From 683f5debe5ca39e4fbc4c3e21114d59990dcb9e9 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 21 Apr 2016 13:17:31 -0500 Subject: [PATCH 085/216] Remove old plugin import --- viewer/js/gis/dijit/StreetView.js | 1 - 1 file changed, 1 deletion(-) diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index 403b526e2..9edce2e4d 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -22,7 +22,6 @@ define([ 'gis/plugins/Google', 'dijit/form/ToggleButton', 'xstyle/css!./StreetView/css/StreetView.css' - // 'gis/plugins/async!//maps.google.com/maps/api/js?v=3' ], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, aspect, topic, GraphicsLayer, Graphic, SimpleRenderer, template, PictureMarkerSymbol, domStyle, domGeom, Point, SpatialReference, MenuItem, proj4, i18n, Google) { var google; return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { From 66a73bdd516b87b02335984f1e0964e1026bf6f5 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 25 Apr 2016 08:44:57 -0500 Subject: [PATCH 086/216] Fix indentation --- viewer/js/config/app.js | 4 +- viewer/js/gis/dijit/StreetView.js | 74 +++++++++++++++---------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 7a4a11cc4..f8183b401 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -15,8 +15,8 @@ }, { name: 'put-selector', main: 'put', - name: 'proj4js', - location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' + name: 'proj4js', + location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' location: 'https://cdn.rawgit.com/kriszyp/put-selector/v0.3.6' }, { name: 'xstyle', diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index 9edce2e4d..9dba0c8ec 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -1,4 +1,3 @@ -/*global google */ define([ 'dojo/_base/declare', 'dijit/_WidgetBase', @@ -23,6 +22,7 @@ define([ 'dijit/form/ToggleButton', 'xstyle/css!./StreetView/css/StreetView.css' ], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, aspect, topic, GraphicsLayer, Graphic, SimpleRenderer, template, PictureMarkerSymbol, domStyle, domGeom, Point, SpatialReference, MenuItem, proj4, i18n, Google) { + //cache google so var google; return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { widgetsInTemplate: true, @@ -47,46 +47,46 @@ define([ postCreate: function () { this.inherited(arguments); //load the google api asynchronously - Google.load(lang.hitch(this, function(g){ - //store a reference to google - google = g; + Google.load(lang.hitch(this, function (g) { + //store a reference to google + google = g; - //init our panoOptions since they depend on google - this.panoOptions = { - addressControlOptions: { - position: google.maps.ControlPosition.TOP_RIGHT - }, - linksControl: false, - panControl: false, - zoomControlOptions: { - style: google.maps.ZoomControlStyle.SMALL - }, - enableCloseButton: false - }; - this.createGraphicsLayer(); - this.map.on('click', lang.hitch(this, 'getStreetView')); + //init our panoOptions since they depend on google + this.panoOptions = { + addressControlOptions: { + position: google.maps.ControlPosition.TOP_RIGHT + }, + linksControl: false, + panControl: false, + zoomControlOptions: { + style: google.maps.ZoomControlStyle.SMALL + }, + enableCloseButton: false + }; + this.createGraphicsLayer(); + this.map.on('click', lang.hitch(this, 'getStreetView')); - this.own(topic.subscribe('mapClickMode/currentSet', lang.hitch(this, 'setMapClickMode'))); + this.own(topic.subscribe('mapClickMode/currentSet', lang.hitch(this, 'setMapClickMode'))); - if (this.parentWidget) { - if (this.parentWidget.toggleable) { - this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { - this.onLayoutChange(this.parentWidget.open); - }))); - } - this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, 'resize'))); - this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); - } + if (this.parentWidget) { + if (this.parentWidget.toggleable) { + this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { + this.onLayoutChange(this.parentWidget.open); + }))); + } + this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, 'resize'))); + this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); + } - // spatialreference.org uses the old - // Proj4js style so we need an alias - // https://github.com/proj4js/proj4js/issues/23 - window.Proj4js = proj4; + // spatialreference.org uses the old + // Proj4js style so we need an alias + // https://github.com/proj4js/proj4js/issues/23 + window.Proj4js = proj4; - if (this.mapRightClickMenu) { - this.addRightClickMenu(); - } - })); + if (this.mapRightClickMenu) { + this.addRightClickMenu(); + } + })); }, createGraphicsLayer: function () { this.pointSymbol = new PictureMarkerSymbol(require.toUrl('gis/dijit/StreetView/images/blueArrow.png'), 30, 30); @@ -136,7 +136,7 @@ define([ } else { this.connectMapClick(); } - //get map click, set up listener in post create + //get map click, set up listener in post create }, disconnectMapClick: function () { this.streetViewButtonDijit.set('checked', true); From 580347d26f09472b67b88b84f3b29ed2df0b8745 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 25 Apr 2016 08:46:02 -0500 Subject: [PATCH 087/216] Disable eslint on vendor google-maps loader --- viewer/js/gis/plugins/Google.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/viewer/js/gis/plugins/Google.js b/viewer/js/gis/plugins/Google.js index 3d9435c82..c6ebf3190 100644 --- a/viewer/js/gis/plugins/Google.js +++ b/viewer/js/gis/plugins/Google.js @@ -1,3 +1,5 @@ +//https://www.npmjs.com/package/google-maps +/* eslint-disable */ (function(root, factory) { if (root === null) { From 6a83281e2a2bcd96814635fa11971e82f14ae0d4 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 25 Apr 2016 08:46:27 -0500 Subject: [PATCH 088/216] Switch style setter to use dojo/dom-style --- viewer/js/gis/dijit/Directions.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/viewer/js/gis/dijit/Directions.js b/viewer/js/gis/dijit/Directions.js index 9ae0f36fe..88fcbac5d 100644 --- a/viewer/js/gis/dijit/Directions.js +++ b/viewer/js/gis/dijit/Directions.js @@ -12,8 +12,9 @@ define([ 'esri/geometry/Point', 'esri/SpatialReference', 'dojo/topic', - 'dojo/i18n!./Directions/nls/resource' -], function (declare, _WidgetBase, _TemplatedMixin, Directions, template, lang, Menu, MenuItem, PopupMenuItem, MenuSeparator, Point, SpatialReference, topic, i18n) { + 'dojo/i18n!./Directions/nls/resource', + 'dojo/dom-style' +], function (declare, _WidgetBase, _TemplatedMixin, Directions, template, lang, Menu, MenuItem, PopupMenuItem, MenuSeparator, Point, SpatialReference, topic, i18n, domStyle) { return declare([_WidgetBase, _TemplatedMixin], { templateString: template, @@ -27,12 +28,14 @@ define([ //temp fix for 3.12 and 3.13 map click button. if (this.directions._activateButton) { - this.directions._activateButton.style.display = 'none'; + domStyle.set(this.directions._activateButton, 'display', 'none'); } else if (this.directions._activateButtonNode) { - this.directions._activateButtonNode.style.display = 'none'; - this.directions._addDestinationNode.style['float'] = 'inherit'; - this.directions._optionsButtonNode.style['float'] = 'inherit'; - this.directions._optionsButtonNode.style.marginRight = '5px'; + domStyle.set(this.directions._activateButtonNode, 'display', 'none'); + domStyle.set(this.directions._addDestinationNode, 'float', 'inherit'); + domStyle.set(this.directions._optionsButtonNode, { + 'float': 'inherit', + marginRight: '5px' + }); } if (this.mapRightClickMenu) { From 8ced6d28d7e25d344066091e083c32ee4cc90785 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 29 Apr 2016 12:45:50 -0500 Subject: [PATCH 089/216] Exclude node_modules from amd search --- package.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.js b/package.js index 765d02464..61756af6e 100644 --- a/package.js +++ b/package.js @@ -21,7 +21,8 @@ var profile = { // are typically binaries (images, etc.) and may be corrupted by the build system if it attempts to process // them and naively assumes they are scripts. copyOnly: function (filename, mid) { - return (/^cmv\/(images)\//.test(mid) && !/\.css$/.test(filename)); + return (/^cmv\/(images)\//.test(mid) && !/\.css$/.test(filename)) || + /\/node_modules\//.test(mid); }, // Files that are AMD modules. From 0e1ba877217266e7e51c7f9dea6db32abaa28d39 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 29 Apr 2016 13:17:45 -0500 Subject: [PATCH 090/216] Tell dojo to use the package.js build file --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 58ad7b674..5e060cb08 100644 --- a/package.json +++ b/package.json @@ -25,5 +25,6 @@ "grunt-contrib-compress": "1.2.x", "proxypage": "*" }, - "engine": "node >= 4" -} \ No newline at end of file + "engine": "node >= 4", + "dojoBuild": "package.js" +} From 1cf77500aaa9539f2fff87968a11ad26cc2285d1 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 29 Apr 2016 13:18:18 -0500 Subject: [PATCH 091/216] Exclude node_modules and other non-amd files from being tagged as amd --- package.js | 75 +++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/package.js b/package.js index 61756af6e..03a9a6abf 100644 --- a/package.js +++ b/package.js @@ -4,41 +4,46 @@ * application itself are stored in the `profiles` directory. */ -var profile = { - // Resource tags are functions that provide hints to the build system about the way files should be processed. - // Each of these functions is called once for every file in the package directory. The first argument passed to - // the function is the filename of the file, and the second argument is the computed AMD module ID of the file. - resourceTags: { - // Files that contain test code and should be excluded when the `copyTests` build flag exists and is `false`. - // It is strongly recommended that the `mini` build flag be used instead of `copyTests`. Therefore, no files - // are marked with the `test` tag here. - test: function (filename, mid) { - return false; - }, +var profile = (function() { + var excludes = { + 'Gruntfile': 1, + 'package': 1 + }; + return { + // Resource tags are functions that provide hints to the build system about the way files should be processed. + // Each of these functions is called once for every file in the package directory. The first argument passed to + // the function is the filename of the file, and the second argument is the computed AMD module ID of the file. + resourceTags: { + // Files that contain test code and should be excluded when the `copyTests` build flag exists and is `false`. + // It is strongly recommended that the `mini` build flag be used instead of `copyTests`. Therefore, no files + // are marked with the `test` tag here. + test: function(filename, mid) { + return false; + }, - // Files that should be copied as-is without being modified by the build system. - // All files in the `app/resources` directory that are not CSS files are marked as copy-only, since these files - // are typically binaries (images, etc.) and may be corrupted by the build system if it attempts to process - // them and naively assumes they are scripts. - copyOnly: function (filename, mid) { - return (/^cmv\/(images)\//.test(mid) && !/\.css$/.test(filename)) || - /\/node_modules\//.test(mid); - }, + // Files that should be copied as-is without being modified by the build system. + // All files in the `app/resources` directory that are not CSS files are marked as copy-only, since these files + // are typically binaries (images, etc.) and may be corrupted by the build system if it attempts to process + // them and naively assumes they are scripts. + copyOnly: function(filename, mid) { + return (/\/(images)\//.test(mid) && !/\.css$/.test(filename)) || + /\/node_modules\//.test(mid) || + filename in excludes; + }, - // Files that are AMD modules. - // All JavaScript in this package should be AMD modules if you are starting a new project. If you are copying - // any legacy scripts from an existing project, those legacy scripts should not be given the `amd` tag. - amd: function (filename, mid) { - return !this.copyOnly(filename, mid) && /\.js$/.test(filename); - }, + // Files that are AMD modules. + // All JavaScript in this package should be AMD modules if you are starting a new project. If you are copying + // any legacy scripts from an existing project, those legacy scripts should not be given the `amd` tag. + amd: function(filename, mid) { + return !this.copyOnly(filename, mid) && /\.js$/.test(filename); + }, - // Files that should not be copied when the `mini` build flag is set to true. - // In this case, we are excluding this package configuration file which is not necessary in a built copy of - // the application. - miniExclude: function (filename, mid) { - return mid in { - 'cmv/package': 1 - }; - } - } -}; + // Files that should not be copied when the `mini` build flag is set to true. + // In this case, we are excluding this package configuration file which is not necessary in a built copy of + // the application. + miniExclude: function(filename, mid) { + return filename in excludes; + } + } + }; +})(); From 059b3aca789102c00755a2a17290626725f5ad87 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 2 May 2016 10:35:37 -0500 Subject: [PATCH 092/216] Remove troublesome error from Google Loader --- viewer/js/gis/plugins/Google.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/gis/plugins/Google.js b/viewer/js/gis/plugins/Google.js index c6ebf3190..4155ef7c4 100644 --- a/viewer/js/gis/plugins/Google.js +++ b/viewer/js/gis/plugins/Google.js @@ -3,7 +3,7 @@ (function(root, factory) { if (root === null) { - throw new Error('Google-maps package can be used only in browser'); + //throw new Error('Google-maps package can be used only in browser'); } if (typeof define === 'function' && define.amd) { From a62df6af544006027aca1d6cf09a8712f66a25e4 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 2 May 2016 12:27:56 -0500 Subject: [PATCH 093/216] Add more rules to the package.js --- package.js | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/package.js b/package.js index 03a9a6abf..2e973bdb7 100644 --- a/package.js +++ b/package.js @@ -5,10 +5,21 @@ */ var profile = (function() { - var excludes = { - 'Gruntfile': 1, - 'package': 1 - }; + //only copy files matching these expressions + //this prevents them from being evaluated as amd modules + var reCopyOnly = [ + /Gruntfile/, + /package/ + ]; + //exclude from builds completely + var reMiniExclude = [ + /Gruntfile/, + /package/ + ]; + //non-amd modules + var reNonAmd = [ + /plugins\/Google/ + ]; return { // Resource tags are functions that provide hints to the build system about the way files should be processed. // Each of these functions is called once for every file in the package directory. The first argument passed to @@ -26,15 +37,24 @@ var profile = (function() { // are typically binaries (images, etc.) and may be corrupted by the build system if it attempts to process // them and naively assumes they are scripts. copyOnly: function(filename, mid) { + for (var i = 0; i < reCopyOnly.length; i++) { + if (reCopyOnly[i].test(filename)) { + return true; + } + } return (/\/(images)\//.test(mid) && !/\.css$/.test(filename)) || - /\/node_modules\//.test(mid) || - filename in excludes; + /\/node_modules\//.test(mid); }, // Files that are AMD modules. // All JavaScript in this package should be AMD modules if you are starting a new project. If you are copying // any legacy scripts from an existing project, those legacy scripts should not be given the `amd` tag. amd: function(filename, mid) { + for (var i = 0; i < reNonAmd.length; i++) { + if (reNonAmd[i].test(filename)) { + return false; + } + } return !this.copyOnly(filename, mid) && /\.js$/.test(filename); }, @@ -42,7 +62,12 @@ var profile = (function() { // In this case, we are excluding this package configuration file which is not necessary in a built copy of // the application. miniExclude: function(filename, mid) { - return filename in excludes; + for (var i = 0; i < reMiniExclude.length; i++) { + if (reMiniExclude[i].test(filename)) { + return true; + } + } + return false; } } }; From 95ed51ceb4bcdac23e8df4edcd64bcf105fb6be8 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 12 May 2016 11:00:29 -0500 Subject: [PATCH 094/216] Makes config/app dojo-build friendly --- viewer/js/config/app.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index f8183b401..aca56e23c 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -1,6 +1,7 @@ -(function () { - var path = location.pathname.replace(/[^\/]+$/, ''); - window.dojoConfig = { +define(['dojo/_base/window'], function(window){ + + var path = window.global.location.pathname.replace(/[^\/]+$/, ''); + var dojoConfig = window.global.dojoConfig = { async: true, packages: [ { @@ -26,7 +27,7 @@ ] }; - require(window.dojoConfig, [ + require(dojoConfig, [ 'dojo/_base/declare', // minimal Base Controller @@ -63,4 +64,6 @@ ]))(); controller.startup(); }); -})(); + //we have to return something + return dojoConfig; +}); From 1e916e6c17a2c22db3e4b9187e1fc0e9daecc30a Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 12 May 2016 11:14:35 -0500 Subject: [PATCH 095/216] Fix proj4js path merge --- viewer/js/config/app.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index aca56e23c..22de0cc3a 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -13,11 +13,12 @@ define(['dojo/_base/window'], function(window){ }, { name: 'config', location: path + 'js/config' + }, { + name: 'proj4js', + location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' }, { name: 'put-selector', main: 'put', - name: 'proj4js', - location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' location: 'https://cdn.rawgit.com/kriszyp/put-selector/v0.3.6' }, { name: 'xstyle', From 3f89efc35e5afcf21301dc8b611b9af658831a14 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 12 May 2016 11:57:56 -0500 Subject: [PATCH 096/216] Fix eslint errors (again) --- package.js | 56 ++++++++++++++++++++--------------------- viewer/js/config/app.js | 6 ++--- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/package.js b/package.js index 2e973bdb7..3aed5bf83 100644 --- a/package.js +++ b/package.js @@ -4,70 +4,70 @@ * application itself are stored in the `profiles` directory. */ -var profile = (function() { +var profile = (function () { //only copy files matching these expressions //this prevents them from being evaluated as amd modules - var reCopyOnly = [ - /Gruntfile/, - /package/ + var reCopyOnly = [ + /Gruntfile/, + /package/ ]; //exclude from builds completely - var reMiniExclude = [ - /Gruntfile/, - /package/ + var reMiniExclude = [ + /Gruntfile/, + /package/ ]; //non-amd modules - var reNonAmd = [ - /plugins\/Google/ + var reNonAmd = [ + /plugins\/Google/ ]; - return { + return { // Resource tags are functions that provide hints to the build system about the way files should be processed. // Each of these functions is called once for every file in the package directory. The first argument passed to // the function is the filename of the file, and the second argument is the computed AMD module ID of the file. - resourceTags: { + resourceTags: { // Files that contain test code and should be excluded when the `copyTests` build flag exists and is `false`. // It is strongly recommended that the `mini` build flag be used instead of `copyTests`. Therefore, no files // are marked with the `test` tag here. - test: function(filename, mid) { - return false; + test: function (filename, mid) { + return false; }, // Files that should be copied as-is without being modified by the build system. // All files in the `app/resources` directory that are not CSS files are marked as copy-only, since these files // are typically binaries (images, etc.) and may be corrupted by the build system if it attempts to process // them and naively assumes they are scripts. - copyOnly: function(filename, mid) { - for (var i = 0; i < reCopyOnly.length; i++) { - if (reCopyOnly[i].test(filename)) { - return true; + copyOnly: function (filename, mid) { + for (var i = 0; i < reCopyOnly.length; i++) { + if (reCopyOnly[i].test(filename)) { + return true; } } - return (/\/(images)\//.test(mid) && !/\.css$/.test(filename)) || + return (/\/(images)\//.test(mid) && !/\.css$/.test(filename)) || /\/node_modules\//.test(mid); }, // Files that are AMD modules. // All JavaScript in this package should be AMD modules if you are starting a new project. If you are copying // any legacy scripts from an existing project, those legacy scripts should not be given the `amd` tag. - amd: function(filename, mid) { - for (var i = 0; i < reNonAmd.length; i++) { - if (reNonAmd[i].test(filename)) { - return false; + amd: function (filename, mid) { + for (var i = 0; i < reNonAmd.length; i++) { + if (reNonAmd[i].test(filename)) { + return false; } } - return !this.copyOnly(filename, mid) && /\.js$/.test(filename); + return !this.copyOnly(filename, mid) && /\.js$/.test(filename); }, // Files that should not be copied when the `mini` build flag is set to true. // In this case, we are excluding this package configuration file which is not necessary in a built copy of // the application. - miniExclude: function(filename, mid) { - for (var i = 0; i < reMiniExclude.length; i++) { - if (reMiniExclude[i].test(filename)) { - return true; + miniExclude: function (filename, mid) { + for (var i = 0; i < reMiniExclude.length; i++) { + if (reMiniExclude[i].test(filename)) { + return true; } } - return false; + return false; } } }; diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 22de0cc3a..62171b609 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -1,4 +1,4 @@ -define(['dojo/_base/window'], function(window){ +define(['dojo/_base/window'], function (window) { var path = window.global.location.pathname.replace(/[^\/]+$/, ''); var dojoConfig = window.global.dojoConfig = { @@ -14,8 +14,8 @@ define(['dojo/_base/window'], function(window){ name: 'config', location: path + 'js/config' }, { - name: 'proj4js', - location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' + name: 'proj4js', + location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' }, { name: 'put-selector', main: 'put', From 0e5224f739bee6f8c6c591d98591c156dd382823 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 12 May 2016 15:17:59 -0500 Subject: [PATCH 097/216] Revert app.js back to cmv default and ignore app.js via the profile. --- package.js | 67 +++++++++++++++++++++-------------------- viewer/js/config/app.js | 19 +++++------- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/package.js b/package.js index 3aed5bf83..ca310ab6a 100644 --- a/package.js +++ b/package.js @@ -8,67 +8,68 @@ var profile = (function () { //only copy files matching these expressions //this prevents them from being evaluated as amd modules var reCopyOnly = [ - /Gruntfile/, - /package/ - ]; + /Gruntfile/, + /package/, + /app\.js/ + ]; //exclude from builds completely - var reMiniExclude = [ - /Gruntfile/, - /package/ + var reMiniExclude = [ + /Gruntfile/, + /package/ ]; //non-amd modules var reNonAmd = [ - /plugins\/Google/ - ]; + /plugins\/Google/ + ]; return { // Resource tags are functions that provide hints to the build system about the way files should be processed. // Each of these functions is called once for every file in the package directory. The first argument passed to // the function is the filename of the file, and the second argument is the computed AMD module ID of the file. - resourceTags: { + resourceTags: { // Files that contain test code and should be excluded when the `copyTests` build flag exists and is `false`. // It is strongly recommended that the `mini` build flag be used instead of `copyTests`. Therefore, no files // are marked with the `test` tag here. - test: function (filename, mid) { - return false; - }, + test: function (filename, mid) { + return false; + }, // Files that should be copied as-is without being modified by the build system. // All files in the `app/resources` directory that are not CSS files are marked as copy-only, since these files // are typically binaries (images, etc.) and may be corrupted by the build system if it attempts to process // them and naively assumes they are scripts. - copyOnly: function (filename, mid) { - for (var i = 0; i < reCopyOnly.length; i++) { - if (reCopyOnly[i].test(filename)) { - return true; + copyOnly: function (filename, mid) { + for (var i = 0; i < reCopyOnly.length; i++) { + if (reCopyOnly[i].test(filename)) { + return true; + } } - } - return (/\/(images)\//.test(mid) && !/\.css$/.test(filename)) || + return (/\/(images)\//.test(mid) && !/\.css$/.test(filename)) || /\/node_modules\//.test(mid); - }, + }, // Files that are AMD modules. // All JavaScript in this package should be AMD modules if you are starting a new project. If you are copying // any legacy scripts from an existing project, those legacy scripts should not be given the `amd` tag. - amd: function (filename, mid) { - for (var i = 0; i < reNonAmd.length; i++) { - if (reNonAmd[i].test(filename)) { - return false; + amd: function (filename, mid) { + for (var i = 0; i < reNonAmd.length; i++) { + if (reNonAmd[i].test(filename)) { + return false; + } } - } - return !this.copyOnly(filename, mid) && /\.js$/.test(filename); - }, + return !this.copyOnly(filename, mid) && /\.js$/.test(filename); + }, // Files that should not be copied when the `mini` build flag is set to true. // In this case, we are excluding this package configuration file which is not necessary in a built copy of // the application. - miniExclude: function (filename, mid) { - for (var i = 0; i < reMiniExclude.length; i++) { - if (reMiniExclude[i].test(filename)) { - return true; + miniExclude: function (filename, mid) { + for (var i = 0; i < reMiniExclude.length; i++) { + if (reMiniExclude[i].test(filename)) { + return true; } } - return false; + return false; + } } - } - }; + }; })(); diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 62171b609..b2b71c050 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -1,7 +1,6 @@ -define(['dojo/_base/window'], function (window) { - - var path = window.global.location.pathname.replace(/[^\/]+$/, ''); - var dojoConfig = window.global.dojoConfig = { +(function () { + var path = location.pathname.replace(/[^\/]+$/, ''); + window.dojoConfig = { async: true, packages: [ { @@ -13,9 +12,6 @@ define(['dojo/_base/window'], function (window) { }, { name: 'config', location: path + 'js/config' - }, { - name: 'proj4js', - location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' }, { name: 'put-selector', main: 'put', @@ -24,11 +20,14 @@ define(['dojo/_base/window'], function (window) { name: 'xstyle', main: 'css', location: 'https://cdn.rawgit.com/kriszyp/xstyle/v0.3.2' + }, { + name: 'proj4js', + location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12' } ] }; - require(dojoConfig, [ + require(window.dojoConfig, [ 'dojo/_base/declare', // minimal Base Controller @@ -65,6 +64,4 @@ define(['dojo/_base/window'], function (window) { ]))(); controller.startup(); }); - //we have to return something - return dojoConfig; -}); +})(); From a3f9771f9ca949195c5fe02fb33034ede4b00816 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Thu, 16 Jun 2016 11:42:48 -0700 Subject: [PATCH 098/216] Update to JS API 3.17 --- viewer/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/index.html b/viewer/index.html index ca69ab38d..a5c4b41d5 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -11,7 +11,7 @@ Configurable Map Viewer - + @@ -41,7 +41,7 @@ - + From b9a98a9dff40c9fc7b53aa159c37fe71b752292e Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 18 Jun 2016 18:20:39 -0700 Subject: [PATCH 099/216] Remove outdated resource proxy files. Add link to Esri resource proxy in README. Add note about proxy not available in GitHub demo. --- README.md | 5 +- resource-proxy.zip | Bin 54459 -> 0 bytes viewer/proxy/PROXY_README.md | 96 ---- viewer/proxy/Web.config | 18 - viewer/proxy/proxy.ashx | 834 ----------------------------------- viewer/proxy/proxy.config | 9 - viewer/proxy/proxy.xsd | 31 -- viewer/proxy/readme.md | 7 - 8 files changed, 4 insertions(+), 996 deletions(-) delete mode 100644 resource-proxy.zip delete mode 100755 viewer/proxy/PROXY_README.md delete mode 100755 viewer/proxy/Web.config delete mode 100755 viewer/proxy/proxy.ashx delete mode 100755 viewer/proxy/proxy.config delete mode 100755 viewer/proxy/proxy.xsd delete mode 100644 viewer/proxy/readme.md diff --git a/README.md b/README.md index efb59a017..3244f9377 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # CMV - The Configurable Map Viewer -[![Read The Docs](https://img.shields.io/badge/docs-1.3.4-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) +[![Read The Docs](https://img.shields.io/badge/docs-1.3.4-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) ## Introduction [CMV](http://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](http://docs.cmv.io/en/latest/developers.arcgis.com/javascript/jsapi/), [ArcGIS Server](http://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. @@ -39,6 +39,9 @@ This JavaScript web app can be easily configured or used as a boilerplate/starti Read more about the [core widgets](http://docs.cmv.io/en/latest/widgets/). In addition, there is a growing number of [widgets contributed by the CMV developer community](https://github.com/cmv/cmv-contrib-widgets). +## Resource Proxy: +A [resource proxy](https://github.com/Esri/resource-proxy) may be required to access some MapServices and other content that reside on a different domain. A proxy is not available for the Github demo. + ## Documentation: Use the [documentation](http://docs.cmv.io/) for getting started and guidance on configuring your application. The initial documentation is sparse. Please help make it better by contributing over at the [cmv documentation repo](https://github.com/cmv/cmv-docs). diff --git a/resource-proxy.zip b/resource-proxy.zip deleted file mode 100644 index 4e127987674fecd73011da88c6b01a23f421843b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54459 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 entry for each service that will use the proxy. The proxy.config allows you to use the serverUrl tag to specify one or more ArcGIS Server services that the proxy will forward requests to. The serverUrl tag has the following attributes: - * **url**: Location of the ArcGIS Server service (or other URL) to proxy. Specify either the specific URL or the root (in which case you should set matchAll="false"). - * **matchAll="true"**: When true all requests that begin with the specified URL are forwarded. Otherwise, the URL requested must match exactly. - * **username**: Username to use when requesting a token - if needed for ArcGIS Server token based authentication. - * **password**: Password to use when requesting a token - if needed for ArcGIS Server token based authentication. - * **clientId**. Used with clientSecret for OAuth authentication to obtain a token - if needed for OAuth 2.0 authentication. **NOTE**: If used to access hosted services, the service(s) must be owned by the user accessing it, (with the exception of credit-based esri services, e.g. routing, geoenrichment, etc.) - * **clientSecret**: Used with clientId for OAuth authentication to obtain a token - if needed for OAuth 2.0 authentication. - * **oauth2Endpoint**: When using OAuth 2.0 authentication specify the portal specific OAuth 2.0 authentication endpoint. The default value is https://www.arcgis.com/sharing/oauth2/. - * **accessToken**: OAuth2 access token to use instead of on-demand access-token generation using clientId & clientSecret. - * **rateLimit**: The maximum number of requests with a particular referer over the specified **rateLimitPeriod**. - * **rateLimitPeriod**: The time period (in minutes) within which the specified number of requests (rate_limit) sent with a particular referer will be tracked. The default value is 60 (one hour). - -Note: Refresh the proxy application after updates to the proxy.config have been made. - -Example of proxy using application credentials and limiting requests to 10/minute -``` - - -``` -Example of a tag for a resource which does not require authentication -``` - - -``` -Note: You may have to refresh the proxy application after updates to the proxy.config have been made. - -##Folders and Files - -The proxy consists of the following files: -* proxy.config: This file contains the configuration settings for the proxy. This is where you will define all the resources that will use the proxy. After updating this file you might need to refresh the proxy application using IIS tools in order for the changes to take effect. -* **Important note:** In order to keep your credentials safe, ensure that your web server will not display the text inside your proxy.config in the browser (ie: http://[yourmachine]/proxy/proxy.config). -* proxy.ashx: The actual proxy application. In most cases you will not need to modify this file. -* web.config: An XML file that stores ASP.NET configuration data. Use this file to configure logging for the proxy. By default the proxy will write log messages to a file named auth_proxy.log located in 'C:\Temp\Shared\proxy_logs'. Note that the folder location needs to exist in order for the log file to be successfully created. -##Requirements - -* ASP.NET 4.0 or greater (4.5 is required on Windows 8/Server 2012, see [this article] (http://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-using-aspnet-35-and-aspnet-45) for more information) - -##Issues - -Found a bug or want to request a new feature? Let us know by submitting an issue. - -##Contributing - -All contributions are welcome. - -##Licensing - -Copyright 2014 Esri - -Licensed under the Apache License, Version 2.0 (the "License"); -You may not use this file except in compliance with the License. -You may obtain a copy of the License at -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for specific language governing permissions and limitations under the license. diff --git a/viewer/proxy/Web.config b/viewer/proxy/Web.config deleted file mode 100755 index 8d1a40128..000000000 --- a/viewer/proxy/Web.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/viewer/proxy/proxy.ashx b/viewer/proxy/proxy.ashx deleted file mode 100755 index 6446e630d..000000000 --- a/viewer/proxy/proxy.ashx +++ /dev/null @@ -1,834 +0,0 @@ -<%@ WebHandler Language="C#" Class="proxy" %> - -/* - * DotNet proxy client. - * - * Version 1.1 beta - * See https://github.com/Esri/resource-proxy for more information. - * - */ - -#define TRACE -using System; -using System.IO; -using System.Web; -using System.Xml.Serialization; -using System.Web.Caching; -using System.Collections.Concurrent; -using System.Diagnostics; - -public class proxy : IHttpHandler { - - class RateMeter { - double _rate; //internal rate is stored in requests per second - int _countCap; - double _count = 0; - DateTime _lastUpdate = DateTime.Now; - - public RateMeter(int rate_limit, int rate_limit_period) { - _rate = (double) rate_limit / rate_limit_period / 60; - _countCap = rate_limit; - } - - //called when rate-limited endpoint is invoked - public bool click() { - TimeSpan ts = DateTime.Now - _lastUpdate; - _lastUpdate = DateTime.Now; - //assuming uniform distribution of requests over time, - //reducing the counter according to # of seconds passed - //since last invocation - _count = Math.Max(0, _count - ts.TotalSeconds * _rate); - if (_count <= _countCap) { - //good to proceed - _count++; - return true; - } - return false; - } - - public bool canBeCleaned() { - TimeSpan ts = DateTime.Now - _lastUpdate; - return _count - ts.TotalSeconds * _rate <= 0; - } - } - - private static string PROXY_REFERER = "http://localhost/proxy/proxy.ashx"; - private static string DEFAULT_OAUTH = "https://www.arcgis.com/sharing/oauth2/"; - private static int CLEAN_RATEMAP_AFTER = 10000; //clean the rateMap every xxxx requests - - private static Object _rateMapLock = new Object(); - - public void ProcessRequest(HttpContext context) { - HttpResponse response = context.Response; - if (context.Request.Url.Query.Length < 1) - { - string errorMsg = "No URL specified"; - log(TraceLevel.Error, errorMsg); - sendErrorResponse(context.Response, null, errorMsg, System.Net.HttpStatusCode.BadRequest); - return; - } - - string uri = context.Request.Url.Query.Substring(1); - - //if url is encoded, decode it. - if (uri.StartsWith("http%3a%2f%2f", StringComparison.InvariantCultureIgnoreCase) || uri.StartsWith("https%3a%2f%2f", StringComparison.InvariantCultureIgnoreCase)) - uri = HttpUtility.UrlDecode(uri); - - log(TraceLevel.Info, uri); - ServerUrl serverUrl; - bool passThrough = false; - try { - serverUrl = getConfig().GetConfigServerUrl(uri); - passThrough = serverUrl == null; - } - //if XML couldn't be parsed - catch (InvalidOperationException ex) { - - string errorMsg = ex.InnerException.Message + " " + uri; - log(TraceLevel.Error, errorMsg); - sendErrorResponse(context.Response, null, errorMsg, System.Net.HttpStatusCode.InternalServerError); - return; - } - //if mustMatch was set to true and URL wasn't in the list - catch (ArgumentException ex) { - string errorMsg = ex.Message + " " + uri; - log(TraceLevel.Error, errorMsg); - sendErrorResponse(context.Response, null, errorMsg, System.Net.HttpStatusCode.Forbidden); - return; - } - //use actual request header instead of a placeholder, if present - if (context.Request.Headers["referer"] != null) - PROXY_REFERER = context.Request.Headers["referer"]; - - //referer - //check against the list of referers if they have been specified in the proxy.config - String[] allowedReferersArray = ProxyConfig.GetAllowedReferersArray(); - if (allowedReferersArray != null && allowedReferersArray.Length > 0) - { - bool allowed = false; - string requestReferer = context.Request.Headers["referer"]; - - foreach (var referer in allowedReferersArray) - { - if ((allowedReferersArray.Length == 1) && referer == String.Empty) - break; - - if (requestReferer != null && requestReferer != String.Empty && (ProxyConfig.isUrlPrefixMatch(referer, requestReferer)) || referer == "*") - { - allowed = true; - break; - } - } - - if (!allowed) - { - string errorMsg = "Proxy is being used from an unsupported referer: " + context.Request.Headers["referer"]; - log(TraceLevel.Error, errorMsg); - sendErrorResponse(context.Response, null, errorMsg, System.Net.HttpStatusCode.Forbidden); - return; - } - } - - //Throttling: checking the rate limit coming from particular client IP - if (!passThrough && serverUrl.RateLimit > -1) { - lock (_rateMapLock) - { - ConcurrentDictionary ratemap = (ConcurrentDictionary)context.Application["rateMap"]; - if (ratemap == null) - { - ratemap = new ConcurrentDictionary(); - context.Application["rateMap"] = ratemap; - context.Application["rateMap_cleanup_counter"] = 0; - } - string key = "[" + serverUrl.Url + "]x[" + context.Request.UserHostAddress + "]"; - RateMeter rate; - if (!ratemap.TryGetValue(key, out rate)) - { - rate = new RateMeter(serverUrl.RateLimit, serverUrl.RateLimitPeriod); - ratemap.TryAdd(key, rate); - } - if (!rate.click()) - { - log(TraceLevel.Warning, " Pair " + key + " is throttled to " + serverUrl.RateLimit + " requests per " + serverUrl.RateLimitPeriod + " minute(s). Come back later."); - sendErrorResponse(context.Response, "This is a metered resource, number of requests have exceeded the rate limit interval.", "Unable to proxy request for requested resource", System.Net.HttpStatusCode.PaymentRequired); - return; - } - - //making sure the rateMap gets periodically cleaned up so it does not grow uncontrollably - int cnt = (int)context.Application["rateMap_cleanup_counter"]; - cnt++; - if (cnt >= CLEAN_RATEMAP_AFTER) - { - cnt = 0; - cleanUpRatemap(ratemap); - } - context.Application["rateMap_cleanup_counter"] = cnt; - } - } - - //readying body (if any) of POST request - byte[] postBody = readRequestPostBody(context); - string post = System.Text.Encoding.UTF8.GetString(postBody); - - System.Net.NetworkCredential credentials = null; - string requestUri = uri; - bool hasClientToken = false; - string token = string.Empty; - string tokenParamName = null; - - if (!passThrough && serverUrl.Domain != null) - { - credentials = new System.Net.NetworkCredential(serverUrl.Username, serverUrl.Password, serverUrl.Domain); - } - else - { - //if token comes with client request, it takes precedence over token or credentials stored in configuration - hasClientToken = uri.Contains("?token=") || uri.Contains("&token=") || post.Contains("?token=") || post.Contains("&token="); - - if (!passThrough && !hasClientToken) - { - // Get new token and append to the request. - // But first, look up in the application scope, maybe it's already there: - token = (String)context.Application["token_for_" + serverUrl.Url]; - bool tokenIsInApplicationScope = !String.IsNullOrEmpty(token); - - //if still no token, let's see if there is an access token or if are credentials stored in configuration which we can use to obtain new token - if (!tokenIsInApplicationScope) - { - token = serverUrl.AccessToken; - if (String.IsNullOrEmpty(token)) - token = getNewTokenIfCredentialsAreSpecified(serverUrl, uri); - } - - if (!String.IsNullOrEmpty(token) && !tokenIsInApplicationScope) - { - //storing the token in Application scope, to do not waste time on requesting new one untill it expires or the app is restarted. - context.Application.Lock(); - context.Application["token_for_" + serverUrl.Url] = token; - context.Application.UnLock(); - } - } - - //name by which token parameter is passed (if url actually came from the list) - tokenParamName = serverUrl != null ? serverUrl.TokenParamName : null; - - if (String.IsNullOrEmpty(tokenParamName)) - tokenParamName = "token"; - - requestUri = addTokenToUri(uri, token, tokenParamName); - } - - - - //forwarding original request - System.Net.WebResponse serverResponse = null; - try { - serverResponse = forwardToServer(context, requestUri, postBody, credentials); - } catch (System.Net.WebException webExc) { - - string errorMsg = webExc.Message + " " + uri; - log(TraceLevel.Error, errorMsg); - - if (webExc.Response != null) - { - copyHeaders(webExc.Response as System.Net.HttpWebResponse, context.Response); - - using (Stream responseStream = webExc.Response.GetResponseStream()) - { - byte[] bytes = new byte[32768]; - int bytesRead = 0; - - while ((bytesRead = responseStream.Read(bytes, 0, bytes.Length)) > 0) - { - responseStream.Write(bytes, 0, bytesRead); - } - - context.Response.StatusCode = (int)(webExc.Response as System.Net.HttpWebResponse).StatusCode; - context.Response.OutputStream.Write(bytes, 0, bytes.Length); - } - } - else - { - System.Net.HttpStatusCode statusCode = System.Net.HttpStatusCode.InternalServerError; - sendErrorResponse(context.Response, null, errorMsg, statusCode); - } - return; - } - - if (passThrough || string.IsNullOrEmpty(token) || hasClientToken) - //if token is not required or provided by the client, just fetch the response as is: - fetchAndPassBackToClient(serverResponse, response, true); - else { - //credentials for secured service have come from configuration file: - //it means that the proxy is responsible for making sure they were properly applied: - - //first attempt to send the request: - bool tokenRequired = fetchAndPassBackToClient(serverResponse, response, false); - - - //checking if previously used token has expired and needs to be renewed - if (tokenRequired) { - log(TraceLevel.Info, "Renewing token and trying again."); - //server returned error - potential cause: token has expired. - //we'll do second attempt to call the server with renewed token: - token = getNewTokenIfCredentialsAreSpecified(serverUrl, uri); - serverResponse = forwardToServer(context, addTokenToUri(uri, token, tokenParamName), postBody); - - //storing the token in Application scope, to do not waste time on requesting new one untill it expires or the app is restarted. - context.Application.Lock(); - context.Application["token_for_" + serverUrl.Url] = token; - context.Application.UnLock(); - - fetchAndPassBackToClient(serverResponse, response, true); - } - } - response.End(); - } - - public bool IsReusable { - get { return true; } - } - -/** -* Private -*/ - private byte[] readRequestPostBody(HttpContext context) { - if (context.Request.InputStream.Length > 0) { - byte[] bytes = new byte[context.Request.InputStream.Length]; - context.Request.InputStream.Read(bytes, 0, (int)context.Request.InputStream.Length); - return bytes; - } - return new byte[0]; - } - - private System.Net.WebResponse forwardToServer(HttpContext context, string uri, byte[] postBody, System.Net.NetworkCredential credentials = null) - { - return - postBody.Length > 0? - doHTTPRequest(uri, postBody, "POST", context.Request.Headers["referer"], context.Request.ContentType, credentials): - doHTTPRequest(uri, context.Request.HttpMethod, credentials); - } - - /// - /// Attempts to copy all headers from the fromResponse to the the toResponse. - /// - /// The response that we are copying the headers from - /// The response that we are copying the headers to - private void copyHeaders(System.Net.WebResponse fromResponse, HttpResponse toResponse) - { - foreach (var headerKey in fromResponse.Headers.AllKeys) - { - switch (headerKey.ToLower()) - { - case "content-type": - case "transfer-encoding": - continue; - default: - toResponse.AddHeader(headerKey, fromResponse.Headers[headerKey]); - break; - } - } - toResponse.ContentType = fromResponse.ContentType; - } - - private bool fetchAndPassBackToClient(System.Net.WebResponse serverResponse, HttpResponse clientResponse, bool ignoreAuthenticationErrors) { - if (serverResponse != null) { - copyHeaders(serverResponse, clientResponse); - using (Stream byteStream = serverResponse.GetResponseStream()) { - // Text response - if (serverResponse.ContentType.Contains("text") || - serverResponse.ContentType.Contains("json") || - serverResponse.ContentType.Contains("xml")) { - using (StreamReader sr = new StreamReader(byteStream)) { - string strResponse = sr.ReadToEnd(); - if ( - !ignoreAuthenticationErrors - && strResponse.IndexOf("{\"error\":{") > -1 - && (strResponse.IndexOf("\"code\":498") > -1 || strResponse.IndexOf("\"code\":499") > -1) - ) - return true; - clientResponse.Write(strResponse); - } - } else { - // Binary response (image, lyr file, other binary file) - - // Tell client not to cache the image since it's dynamic - clientResponse.CacheControl = "no-cache"; - byte[] buffer = new byte[32768]; - int read; - while ((read = byteStream.Read(buffer, 0, buffer.Length)) > 0) - { - clientResponse.OutputStream.Write(buffer, 0, read); - } - clientResponse.OutputStream.Close(); - } - serverResponse.Close(); - } - } - return false; - } - - private System.Net.WebResponse doHTTPRequest(string uri, string method, System.Net.NetworkCredential credentials = null) - { - byte[] bytes = null; - String contentType = null; - log(TraceLevel.Info, "Sending request!"); - - if (method.Equals("POST")) - { - String[] uriArray = uri.Split('?'); - - if (uriArray.Length > 1) - { - contentType = "application/x-www-form-urlencoded"; - String queryString = uriArray[1]; - - bytes = System.Text.Encoding.UTF8.GetBytes(queryString); - } - } - - return doHTTPRequest(uri, bytes, method, PROXY_REFERER, contentType, credentials); - } - - private System.Net.WebResponse doHTTPRequest(string uri, byte[] bytes, string method, string referer, string contentType, System.Net.NetworkCredential credentials = null) - { - System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(uri); - req.ServicePoint.Expect100Continue = false; - req.Referer = referer; - req.Method = method; - - if (credentials != null) - req.Credentials = credentials; - - if (bytes != null && bytes.Length > 0 || method == "POST") { - req.Method = "POST"; - req.ContentType = string.IsNullOrEmpty(contentType) ? "application/x-www-form-urlencoded" : contentType; - if (bytes != null && bytes.Length > 0) - req.ContentLength = bytes.Length; - using (Stream outputStream = req.GetRequestStream()) { - outputStream.Write(bytes, 0, bytes.Length); - } - } - return req.GetResponse(); - } - - private string webResponseToString(System.Net.WebResponse serverResponse) { - using (Stream byteStream = serverResponse.GetResponseStream()) { - using (StreamReader sr = new StreamReader(byteStream)) { - string strResponse = sr.ReadToEnd(); - return strResponse; - } - } - } - - private string getNewTokenIfCredentialsAreSpecified(ServerUrl su, string reqUrl) { - string token = ""; - string infoUrl = ""; - - bool isUserLogin = !String.IsNullOrEmpty(su.Username) && !String.IsNullOrEmpty(su.Password); - bool isAppLogin = !String.IsNullOrEmpty(su.ClientId) && !String.IsNullOrEmpty(su.ClientSecret); - if (isUserLogin || isAppLogin) { - log(TraceLevel.Info, "Matching credentials found in configuration file. OAuth 2.0 mode: " + isAppLogin); - if (isAppLogin) { - //OAuth 2.0 mode authentication - //"App Login" - authenticating using client_id and client_secret stored in config - su.OAuth2Endpoint = string.IsNullOrEmpty(su.OAuth2Endpoint) ? DEFAULT_OAUTH : su.OAuth2Endpoint; - if (su.OAuth2Endpoint[su.OAuth2Endpoint.Length - 1] != '/') - su.OAuth2Endpoint += "/"; - log(TraceLevel.Info, "Service is secured by " + su.OAuth2Endpoint + ": getting new token..."); - string uri = su.OAuth2Endpoint + "token?client_id=" + su.ClientId + "&client_secret=" + su.ClientSecret + "&grant_type=client_credentials&f=json"; - string tokenResponse = webResponseToString(doHTTPRequest(uri, "POST")); - token = extractToken(tokenResponse, "token"); - if (!string.IsNullOrEmpty(token)) - token = exchangePortalTokenForServerToken(token, su); - } else { - //standalone ArcGIS Server/ArcGIS Online token-based authentication - - //if a request is already being made to generate a token, just let it go - if (reqUrl.ToLower().Contains("/generatetoken")) { - string tokenResponse = webResponseToString(doHTTPRequest(reqUrl, "POST")); - token = extractToken(tokenResponse, "token"); - return token; - } - - //lets look for '/rest/' in the requested URL (could be 'rest/services', 'rest/community'...) - if (reqUrl.ToLower().Contains("/rest/")) - infoUrl = reqUrl.Substring(0, reqUrl.IndexOf("/rest/", StringComparison.OrdinalIgnoreCase)); - - //if we don't find 'rest', lets look for the portal specific 'sharing' instead - else if (reqUrl.ToLower().Contains("/sharing/")) { - infoUrl = reqUrl.Substring(0, reqUrl.IndexOf("/sharing/", StringComparison.OrdinalIgnoreCase)); - infoUrl = infoUrl + "/sharing"; - } - else - throw new ApplicationException("Unable to determine the correct URL to request a token to access private resources"); - - if (infoUrl != "") { - log(TraceLevel.Info," Querying security endpoint..."); - infoUrl += "/rest/info?f=json"; - //lets send a request to try and determine the URL of a token generator - string infoResponse = webResponseToString(doHTTPRequest(infoUrl, "GET")); - String tokenServiceUri = getJsonValue(infoResponse, "tokenServicesUrl"); - if (string.IsNullOrEmpty(tokenServiceUri)) - tokenServiceUri = getJsonValue(infoResponse, "tokenServiceUrl"); - if (tokenServiceUri != "") { - log(TraceLevel.Info," Service is secured by " + tokenServiceUri + ": getting new token..."); - string uri = tokenServiceUri + "?f=json&request=getToken&referer=" + PROXY_REFERER + "&expiration=60&username=" + su.Username + "&password=" + su.Password; - string tokenResponse = webResponseToString(doHTTPRequest(uri, "POST")); - token = extractToken(tokenResponse, "token"); - } - } - - - } - } - return token; - } - - private string exchangePortalTokenForServerToken(string portalToken, ServerUrl su) { - //ideally, we should POST the token request - log(TraceLevel.Info," Exchanging Portal token for Server-specific token for " + su.Url + "..."); - string uri = su.OAuth2Endpoint.Substring(0, su.OAuth2Endpoint.IndexOf("/oauth2/", StringComparison.OrdinalIgnoreCase)) + - "/generateToken?token=" + portalToken + "&serverURL=" + su.Url + "&f=json"; - string tokenResponse = webResponseToString(doHTTPRequest(uri, "GET")); - return extractToken(tokenResponse, "token"); - } - - private static void sendErrorResponse(HttpResponse response, String errorDetails, String errorMessage, System.Net.HttpStatusCode errorCode) - { - String message = string.Format("{{error: {{code: {0},message:\"{1}\"", (int)errorCode, errorMessage); - if (!string.IsNullOrEmpty(errorDetails)) - message += string.Format(",details:[message:\"{0}\"]", errorDetails); - message += "}}"; - response.StatusCode = (int)errorCode; - //this displays our customized error messages instead of IIS's custom errors - response.TrySkipIisCustomErrors = true; - response.Write(message); - response.Flush(); - } - - private static string getClientIp(HttpRequest request) - { - if (request == null) - return null; - string remoteAddr = request.ServerVariables["HTTP_X_FORWARDED_FOR"]; - if (string.IsNullOrWhiteSpace(remoteAddr)) - { - remoteAddr = request.ServerVariables["REMOTE_ADDR"]; - } - else - { - // the HTTP_X_FORWARDED_FOR may contain an array of IP, this can happen if you connect through a proxy. - string[] ipRange = remoteAddr.Split(','); - remoteAddr = ipRange[ipRange.Length - 1]; - } - return remoteAddr; - } - - private string addTokenToUri(string uri, string token, string tokenParamName) { - if (!String.IsNullOrEmpty(token)) - uri += uri.Contains("?")? "&" + tokenParamName + "=" + token : "?" + tokenParamName + "=" + token; - return uri; - } - - private string extractToken(string tokenResponse, string key) { - string token = getJsonValue(tokenResponse, key); - if (string.IsNullOrEmpty(token)) - log(TraceLevel.Error," Token cannot be obtained: " + tokenResponse); - else - log(TraceLevel.Info," Token obtained: " + token); - return token; - } - - private string getJsonValue(string text, string key) { - int i = text.IndexOf(key); - String value = ""; - if (i > -1) { - value = text.Substring(text.IndexOf(':', i) + 1).Trim(); - value = value.Length > 0 && value[0] == '"' ? - value.Substring(1, value.IndexOf('"', 1) - 1): - value = value.Substring(0, Math.Max(0, Math.Min(Math.Min(value.IndexOf(","), value.IndexOf("]")), value.IndexOf("}")))); - } - return value; - } - - private void cleanUpRatemap(ConcurrentDictionary ratemap) { - foreach (string key in ratemap.Keys){ - RateMeter rate = ratemap[key]; - if (rate.canBeCleaned()) - ratemap.TryRemove(key, out rate); - } - } - -/** -* Static -*/ - private static ProxyConfig getConfig() { - ProxyConfig config = ProxyConfig.GetCurrentConfig(); - if (config != null) - return config; - else - throw new ApplicationException("The proxy configuration file cannot be found, or is not readable."); - } - - //writing Log file - private static void log(TraceLevel logLevel, string msg) { - string logMessage = string.Format("{0} {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msg); - if (TraceLevel.Error == logLevel) - { - Trace.TraceError(logMessage); - logMessageToFile(logMessage); - } - else if (TraceLevel.Warning == logLevel) - { - Trace.TraceWarning(logMessage); - logMessageToFile(logMessage); - } - else - { - Trace.TraceInformation(logMessage); - logMessageToFile(logMessage); - } - } - - private static object _lockobject = new object(); - - private static void logMessageToFile(String message) - { - //Only log messages to disk if logFile has value in configuration, otherwise log nothing. - ProxyConfig config = ProxyConfig.GetCurrentConfig(); - if (config.LogFile != null) - { - string log = config.LogFile; - if (!log.Contains("\\") || log.Contains(".\\")) - { - if (log.Contains(".\\")) //If this type of relative pathing .\log.txt - { - log = log.Replace(".\\", ""); - } - string configDirectory = HttpContext.Current.Server.MapPath("proxy.config"); //Cannot use System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath b/ config may be in a child directory - string path = configDirectory.Replace("proxy.config",""); - log = path + log; - } - - lock(_lockobject) { - using (StreamWriter sw = File.AppendText(log)) - { - sw.WriteLine(message); - } - } - } - } -} - - -[XmlRoot("ProxyConfig")] -public class ProxyConfig -{ - private static object _lockobject = new object(); - public static ProxyConfig LoadProxyConfig(string fileName) { - ProxyConfig config = null; - lock (_lockobject) { - if (System.IO.File.Exists(fileName)) { - XmlSerializer reader = new XmlSerializer(typeof(ProxyConfig)); - using (System.IO.StreamReader file = new System.IO.StreamReader(fileName)) { - try { - config = (ProxyConfig)reader.Deserialize(file); - } - catch (Exception ex) { - throw ex; - } - } - } - } - return config; - } - - public static ProxyConfig GetCurrentConfig() { - ProxyConfig config = HttpRuntime.Cache["proxyConfig"] as ProxyConfig; - if (config == null) { - string fileName = HttpContext.Current.Server.MapPath("proxy.config"); - config = LoadProxyConfig(fileName); - if (config != null) { - CacheDependency dep = new CacheDependency(fileName); - HttpRuntime.Cache.Insert("proxyConfig", config, dep); - } - } - return config; - } - - //referer - //create an array with valid referers using the allowedReferers String that is defined in the proxy.config - public static String[] GetAllowedReferersArray() - { - if (allowedReferers == null) - return null; - - return allowedReferers.Split(','); - } - - //referer - //check if URL starts with prefix... - public static bool isUrlPrefixMatch(String prefix, String uri) - { - - return uri.ToLower().StartsWith(prefix.ToLower()) || - uri.ToLower().Replace("https://", "http://").StartsWith(prefix.ToLower()) || - uri.ToLower().Substring(uri.IndexOf("//")).StartsWith(prefix.ToLower()); - } - - ServerUrl[] serverUrls; - public String logFile; - bool mustMatch; - //referer - static String allowedReferers; - - [XmlArray("serverUrls")] - [XmlArrayItem("serverUrl")] - public ServerUrl[] ServerUrls { - get { return this.serverUrls; } - set - { - this.serverUrls = value; - } - } - [XmlAttribute("mustMatch")] - public bool MustMatch { - get { return mustMatch; } - set - { mustMatch = value; } - } - - //logFile - [XmlAttribute("logFile")] - public String LogFile - { - get { return logFile; } - set - { logFile = value; } - } - - - //referer - [XmlAttribute("allowedReferers")] - public string AllowedReferers - { - get { return allowedReferers; } - set - { - allowedReferers = value; - } - } - - public ServerUrl GetConfigServerUrl(string uri) { - //split both request and proxy.config urls and compare them - string[] uriParts = uri.Split(new char[] {'/','?'}, StringSplitOptions.RemoveEmptyEntries); - string[] configUriParts = new string[] {}; - - foreach (ServerUrl su in serverUrls) { - //if a relative path is specified in the proxy.config, append what's in the request itself - if (!su.Url.StartsWith("http")) - su.Url = su.Url.Insert(0, uriParts[0]); - - configUriParts = su.Url.Split(new char[] { '/','?' }, StringSplitOptions.RemoveEmptyEntries); - - //if the request has less parts than the config, don't allow - if (configUriParts.Length > uriParts.Length) continue; - - int i = 0; - for (i = 0; i < configUriParts.Length; i++) { - - if (!configUriParts[i].ToLower().Equals(uriParts[i].ToLower())) break; - } - if (i == configUriParts.Length) { - //if the urls don't match exactly, and the individual matchAll tag is 'false', don't allow - if (configUriParts.Length == uriParts.Length || su.MatchAll) - return su; - } - } - - if (mustMatch) - throw new ArgumentException("Proxy is being used for an unsupported service:"); - - return null; - } - - -} - -public class ServerUrl { - string url; - bool matchAll; - string oauth2Endpoint; - string domain; - string username; - string password; - string clientId; - string clientSecret; - string accessToken; - string tokenParamName; - string rateLimit; - string rateLimitPeriod; - - [XmlAttribute("url")] - public string Url { - get { return url; } - set { url = value; } - } - [XmlAttribute("matchAll")] - public bool MatchAll { - get { return matchAll; } - set { matchAll = value; } - } - [XmlAttribute("oauth2Endpoint")] - public string OAuth2Endpoint { - get { return oauth2Endpoint; } - set { oauth2Endpoint = value; } - } - [XmlAttribute("domain")] - public string Domain - { - get { return domain; } - set { domain = value; } - } - [XmlAttribute("username")] - public string Username { - get { return username; } - set { username = value; } - } - [XmlAttribute("password")] - public string Password { - get { return password; } - set { password = value; } - } - [XmlAttribute("clientId")] - public string ClientId { - get { return clientId; } - set { clientId = value; } - } - [XmlAttribute("clientSecret")] - public string ClientSecret { - get { return clientSecret; } - set { clientSecret = value; } - } - [XmlAttribute("accessToken")] - public string AccessToken { - get { return accessToken; } - set { accessToken = value; } - } - [XmlAttribute("tokenParamName")] - public string TokenParamName { - get { return tokenParamName; } - set { tokenParamName = value; } - } - [XmlAttribute("rateLimit")] - public int RateLimit { - get { return string.IsNullOrEmpty(rateLimit)? -1 : int.Parse(rateLimit); } - set { rateLimit = value.ToString(); } - } - [XmlAttribute("rateLimitPeriod")] - public int RateLimitPeriod { - get { return string.IsNullOrEmpty(rateLimitPeriod)? 60 : int.Parse(rateLimitPeriod); } - set { rateLimitPeriod = value.ToString(); } - } -} diff --git a/viewer/proxy/proxy.config b/viewer/proxy/proxy.config deleted file mode 100755 index ef689f898..000000000 --- a/viewer/proxy/proxy.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/viewer/proxy/proxy.xsd b/viewer/proxy/proxy.xsd deleted file mode 100755 index d6c057fa8..000000000 --- a/viewer/proxy/proxy.xsd +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/viewer/proxy/readme.md b/viewer/proxy/readme.md deleted file mode 100644 index 630a8993d..000000000 --- a/viewer/proxy/readme.md +++ /dev/null @@ -1,7 +0,0 @@ -# AGS Proxy page help - -For full info please read here: -[https://developers.arcgis.com/javascript/jshelp/ags_proxy.html](https://developers.arcgis.com/javascript/jshelp/ags_proxy.html) - -You will more than likely need a proxy page for printing and other large cross domain requests. -There are diffrent flavors (.net, jsp, php) of the proxy page depending on your server side technology. See the above link for full details. \ No newline at end of file From b189f5c80ae347fa7fa6ecebd24a347c7bf40a5e Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 8 Jul 2016 12:13:06 -0700 Subject: [PATCH 100/216] fixed typo. --- viewer/js/gis/dijit/LayerControl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index c1158b1f0..4dbf4b07f 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -206,7 +206,7 @@ define([ if (layer.loaded) { this._applyLayerControlOptions(layerInfo.controlOptions, layer); } else { - layer.on('load', lang.hitch(this, '_applyLayerControlOptions', layer.controlOptions)); + layer.on('load', lang.hitch(this, '_applyLayerControlOptions', layerInfo.controlOptions)); } } var layerControl = new Control({ From a3f09e355314f509f385625915b380799f71e9ae Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 8 Jul 2016 12:15:29 -0700 Subject: [PATCH 101/216] ensure that `_reorderUp` and `_reoderDown` dom nodes exist before calling set methods. --- viewer/js/gis/dijit/LayerControl.js | 40 +++++++++++++++++------------ 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 4dbf4b07f..bffc5b586 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -346,29 +346,37 @@ define([ if (this.separated) { if (this.vectorReorder) { array.forEach(this._vectorContainer.getChildren(), function (child) { - if (!child.getPreviousSibling()) { - child._reorderUp.set('disabled', true); - } else { - child._reorderUp.set('disabled', false); + if (child._reorderUp) { + if (!child.getPreviousSibling()) { + child._reorderUp.set('disabled', true); + } else { + child._reorderUp.set('disabled', false); + } } - if (!child.getNextSibling()) { - child._reorderDown.set('disabled', true); - } else { - child._reorderDown.set('disabled', false); + if (child._reorderDown) { + if (!child.getNextSibling()) { + child._reorderDown.set('disabled', true); + } else { + child._reorderDown.set('disabled', false); + } } }, this); } if (this.overlayReorder) { array.forEach(this._overlayContainer.getChildren(), function (child) { - if (!child.getPreviousSibling()) { - child._reorderUp.set('disabled', true); - } else { - child._reorderUp.set('disabled', false); + if (child._reorderUp) { + if (!child.getPreviousSibling()) { + child._reorderUp.set('disabled', true); + } else { + child._reorderUp.set('disabled', false); + } } - if (!child.getNextSibling()) { - child._reorderDown.set('disabled', true); - } else { - child._reorderDown.set('disabled', false); + if (child._reorderDown) { + if (!child.getNextSibling()) { + child._reorderDown.set('disabled', true); + } else { + child._reorderDown.set('disabled', false); + } } }, this); } From c4e3958e7295029b57fad7d5dc6ffb668cf0ded2 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 13 Jul 2016 13:38:21 -0700 Subject: [PATCH 102/216] use HTTPS whereever possible because it is the right thing to do. --- README.md | 2 +- viewer/css/main.css | 2 +- viewer/index.html | 8 ++++---- viewer/js/config/basemaps.js | 8 ++++---- viewer/js/config/find.js | 4 ++-- viewer/js/config/viewer.js | 20 +++++++++---------- viewer/js/gis/dijit/Find/nls/resource.js | 2 +- .../js/gis/dijit/LayerControl/nls/resource.js | 2 +- .../dijit/LayerControl/plugins/legendUtil.js | 2 +- viewer/js/gis/dijit/Print/nls/resource.js | 2 +- .../js/gis/dijit/StreetView/nls/resource.js | 2 +- 11 files changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 3244f9377..50c57c03e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Read The Docs](https://img.shields.io/badge/docs-1.3.4-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) ## Introduction -[CMV](http://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](http://docs.cmv.io/en/latest/developers.arcgis.com/javascript/jsapi/), [ArcGIS Server](http://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. +[CMV](http://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](http://developers.arcgis.com/javascript/jsapi/3/), [ArcGIS Server](https://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. ## Make It Your Own! This JavaScript web app can be easily configured or used as a boilerplate/starting point for basic viewers. It also demonstrates best practices for modular design and OOP via classes in JS using dojo's great [declare](http://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html) system. diff --git a/viewer/css/main.css b/viewer/css/main.css index a88b52722..f351cc5be 100644 --- a/viewer/css/main.css +++ b/viewer/css/main.css @@ -312,7 +312,7 @@ body, html { /* media queries bootstrap style - http://getbootstrap.com/css/#grid-media-queries + https://getbootstrap.com/css/#grid-media-queries */ @media screen and (max-width: 991px) { diff --git a/viewer/index.html b/viewer/index.html index a5c4b41d5..8edd538da 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -11,8 +11,8 @@ Configurable Map Viewer - - + + @@ -39,9 +39,9 @@
- + diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 2949e10a0..92e4ba169 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -86,7 +86,7 @@ define([ basemap: { baseMapLayers: [ { - url: 'http://tiles.arcgis.com/tiles/IEuSomXfi6iB7a25/arcgis/rest/services/World_Globe_1812/MapServer' + url: 'https://tiles.arcgis.com/tiles/IEuSomXfi6iB7a25/arcgis/rest/services/World_Globe_1812/MapServer' } ] } @@ -252,7 +252,7 @@ define([ basemap: new Basemap({ id: 'stamenToner', layers: [new BasemapLayer({ - url: 'http://tile.stamen.com/toner/${level}/${col}/${row}.png', + url: 'https://tile.stamen.com/toner/${level}/${col}/${row}.png', copyright: 'stamen, 2016', id: 'stamenToner', type: 'WebTiledLayer' @@ -264,7 +264,7 @@ define([ basemap: new Basemap({ id: 'stamenTerrain', layers: [new BasemapLayer({ - url: 'http://tile.stamen.com/terrain/${level}/${col}/${row}.png', + url: 'https://tile.stamen.com/terrain/${level}/${col}/${row}.png', copyright: 'stamen, 2016', id: 'stamenTerrain', type: 'WebTiledLayer' @@ -276,7 +276,7 @@ define([ basemap: new Basemap({ id: 'stamenWatercolor', layers: [new BasemapLayer({ - url: 'http://tile.stamen.com/watercolor/${level}/${col}/${row}.png', + url: 'https://tile.stamen.com/watercolor/${level}/${col}/${row}.png', copyright: 'stamen, 2016', id: 'stamenWatercolor', type: 'WebTiledLayer' diff --git a/viewer/js/config/find.js b/viewer/js/config/find.js index 5e9cb84c7..aa323416a 100644 --- a/viewer/js/config/find.js +++ b/viewer/js/config/find.js @@ -5,7 +5,7 @@ define({ queries: [ { description: 'Find A Public Safety Location By Name', - url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', + url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', layerIds: [1, 2, 3, 4, 5, 6, 7], searchFields: ['FDNAME, PDNAME', 'NAME', 'RESNAME'], minChars: 2, @@ -33,7 +33,7 @@ define({ }, { description: 'Find Incident By Code/Description', - url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', + url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', layerIds: [15, 17, 18], searchFields: ['FCODE', 'DESCRIPTION'], minChars: 4, diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 39b0194b2..89d2eb3ac 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -19,7 +19,7 @@ define([ });*/ // url to your geometry server. - esriConfig.defaults.geometryService = new GeometryService('http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'); + esriConfig.defaults.geometryService = new GeometryService('https://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'); // helper function returning ImageParameters for dynamic layers // example: @@ -110,7 +110,7 @@ define([ // 3 'mode' options: MODE_SNAPSHOT = 0, MODE_ONDEMAND = 1, MODE_SELECTION = 2 operationalLayers: [{ type: 'feature', - url: 'http://services1.arcgis.com/6bXbLtkf4y11TosO/arcgis/rest/services/Restaurants/FeatureServer/0', + url: 'https://services1.arcgis.com/6bXbLtkf4y11TosO/arcgis/rest/services/Restaurants/FeatureServer/0', title: 'Restaurants', options: { id: 'restaurants', @@ -130,7 +130,7 @@ define([ } }, { type: 'feature', - url: 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', + url: 'https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', title: 'San Francisco 311 Incidents', options: { id: 'sf311Incidents', @@ -141,7 +141,7 @@ define([ } }, { type: 'dynamic', - url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', + url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', title: 'Louisville Public Safety', options: { id: 'louisvillePubSafety', @@ -165,7 +165,7 @@ define([ } }, { type: 'dynamic', - url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/MapServer', + url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/MapServer', title: 'Damage Assessment', options: { id: 'DamageAssessment', @@ -186,7 +186,7 @@ define([ }, { type: 'vectortile', title: 'Light Gray Canvas Vector', - url: '//www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', + url: 'https://www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', options: { id: 'vectortile1', opacity: 0.8, @@ -200,12 +200,12 @@ define([ id: 'vectortile2', opacity: 1.0, visible: true, - 'glyphs': '//www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/fonts/{fontstack}/{range}.pbf', - 'sprite': '//www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/sprites/sprite', + 'glyphs': 'https://www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/fonts/{fontstack}/{range}.pbf', + 'sprite': 'https://www.arcgis.com/sharing/rest/content/items/00cd8e843bae49b3a040423e5d65416b/resources/sprites/sprite', 'version': 8, 'sources': { 'esri': { - 'url': '//basemapsdev.arcgis.com/arcgis/rest/services/World_Basemap/VectorTileServer', + 'url': 'https://basemapsdev.arcgis.com/arcgis/rest/services/World_Basemap/VectorTileServer', 'type': 'vector' } }, @@ -472,7 +472,7 @@ define([ map: true, mapRightClickMenu: true, options: { - routeTaskUrl: 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Network/USA/NAServer/Route', + routeTaskUrl: 'https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Network/USA/NAServer/Route', routeParams: { directionsLanguage: 'en-US', directionsLengthUnits: units.MILES diff --git a/viewer/js/gis/dijit/Find/nls/resource.js b/viewer/js/gis/dijit/Find/nls/resource.js index 0d5c82f74..3564a898e 100644 --- a/viewer/js/gis/dijit/Find/nls/resource.js +++ b/viewer/js/gis/dijit/Find/nls/resource.js @@ -1,4 +1,4 @@ -// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +// https://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ root: { selectQuery: 'Select query', diff --git a/viewer/js/gis/dijit/LayerControl/nls/resource.js b/viewer/js/gis/dijit/LayerControl/nls/resource.js index 3910c23cb..98a9848cb 100644 --- a/viewer/js/gis/dijit/LayerControl/nls/resource.js +++ b/viewer/js/gis/dijit/LayerControl/nls/resource.js @@ -1,6 +1,6 @@ // internationalization for LayerControl // -// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +// https://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html // // if you would like to add a locale please create an issue at // https://github.com/cmv/cmv-app/issues and someone will assist diff --git a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js index eeef8b35e..830a71792 100644 --- a/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js +++ b/viewer/js/gis/dijit/LayerControl/plugins/legendUtil.js @@ -82,7 +82,7 @@ define([ _arcgisLegendRequest: function (layer, expandNode, callback, errback) { var index = layer.url.toLowerCase().indexOf('/rest/'); var soap = layer.url.substring(0, index) + layer.url.substring(index + 5, layer.url.length); - var url = 'http://utility.arcgis.com/sharing/tools/legend?soapUrl=' + window.escape(soap); + var url = 'https://utility.arcgis.com/sharing/tools/legend?soapUrl=' + window.escape(soap); if (!has('ie') || has('ie') > 8) { url += '&returnbytes=true'; } diff --git a/viewer/js/gis/dijit/Print/nls/resource.js b/viewer/js/gis/dijit/Print/nls/resource.js index 3c250c54d..fab5aaa97 100644 --- a/viewer/js/gis/dijit/Print/nls/resource.js +++ b/viewer/js/gis/dijit/Print/nls/resource.js @@ -1,4 +1,4 @@ -// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +// https://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ root: { title: 'Title', diff --git a/viewer/js/gis/dijit/StreetView/nls/resource.js b/viewer/js/gis/dijit/StreetView/nls/resource.js index d417ab380..9645bd886 100644 --- a/viewer/js/gis/dijit/StreetView/nls/resource.js +++ b/viewer/js/gis/dijit/StreetView/nls/resource.js @@ -1,4 +1,4 @@ -// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +// https://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ root: { messages: { From c2462ce0921a0a9b9c9f6bd7a65769731cc243ce Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 13 Jul 2016 15:05:07 -0700 Subject: [PATCH 103/216] restore `async: true` to dojoConfig in index.html By default, ESRI uses `async: false` applications load much faster if set to true. This is also the place to add custom locale(s), if desired. --- viewer/index.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/viewer/index.html b/viewer/index.html index 8edd538da..2b2020236 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -38,6 +38,11 @@ + From 27cae907b2f01e853247cfcc86118fef50202892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Wed, 13 Jul 2016 00:38:46 +0100 Subject: [PATCH 104/216] trying to add i18n support to viewer --- viewer/js/config/nls/main.js | 23 ++++++++++++++++++++++ viewer/js/config/nls/pt-pt/main.js | 22 +++++++++++++++++++++ viewer/js/config/viewer.js | 31 +++++++++++++++--------------- 3 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 viewer/js/config/nls/main.js create mode 100644 viewer/js/config/nls/pt-pt/main.js diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js new file mode 100644 index 000000000..29a31d349 --- /dev/null +++ b/viewer/js/config/nls/main.js @@ -0,0 +1,23 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + root: { + operationalLayers: { + sf311Incidents: 'San Francisco 311 Incidents' + }, + widgetTitles: { + bookmarks: 'Bookmarks', + directions: 'Directions', + draw: 'Draw', + editor: 'Editor', + find: 'Find', + help: 'Help', + identify: 'Identify', + measure: 'Measurement', + layerControl: 'Layers', + legend: 'Legend', + print: 'Print', + streetview: 'Google Street View' + } + }, + 'pt-pt': true +}) diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js new file mode 100644 index 000000000..e60ee3ed3 --- /dev/null +++ b/viewer/js/config/nls/pt-pt/main.js @@ -0,0 +1,22 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + root: { + operationalLayers: { + sf311Incidents: 'San Francisco 311 Incidents' + }, + widgetTitles: { + bookmarks: 'Marcadores', + directions: 'Direcções', + draw: 'Desenhar', + editor: 'Editor', + find: 'Procurar', + help: 'Ajuda', + identify: 'Identificar', + measure: 'Medir', + layerControl: 'Camadas', + legend: 'Legendas', + print: 'Imprimir', + streetview: 'Google Street View' + } + } +}) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 89d2eb3ac..08859995a 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -4,8 +4,9 @@ define([ 'esri/config', /*'esri/urlUtils',*/ 'esri/tasks/GeometryService', - 'esri/layers/ImageParameters' -], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters) { + 'esri/layers/ImageParameters', + 'dojo/i18n!./nls/main' +], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters, i18n) { // url to your proxy page, must be on same machine hosting you app. See proxy folder for readme. esriConfig.defaults.io.proxyUrl = 'proxy/proxy.ashx'; @@ -131,7 +132,7 @@ define([ }, { type: 'feature', url: 'https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', - title: 'San Francisco 311 Incidents', + title: i18n.operationalLayers.sf311Incidents, options: { id: 'sf311Incidents', opacity: 1.0, @@ -267,7 +268,7 @@ define([ id: 'identify', type: 'titlePane', path: 'gis/dijit/Identify', - title: 'Identify', + title: i18n.widgetTitles.identify, open: false, position: 3, options: 'config/identify' @@ -366,7 +367,7 @@ define([ id: 'legend', type: 'titlePane', path: 'esri/dijit/Legend', - title: 'Legend', + title: i18n.widgetTitles.legend, open: false, position: 0, options: { @@ -379,7 +380,7 @@ define([ id: 'layerControl', type: 'titlePane', path: 'gis/dijit/LayerControl', - title: 'Layers', + title: i18n.widgetTitles.layerControl, open: false, position: 0, options: { @@ -395,7 +396,7 @@ define([ id: 'bookmarks', type: 'titlePane', path: 'gis/dijit/Bookmarks', - title: 'Bookmarks', + title: i18n.widgetTitles.bookmarks, open: false, position: 2, options: 'config/bookmarks' @@ -406,7 +407,7 @@ define([ type: 'titlePane', canFloat: true, path: 'gis/dijit/Find', - title: 'Find', + title: i18n.widgetTitles.find, open: false, position: 3, options: 'config/find' @@ -417,7 +418,7 @@ define([ type: 'titlePane', canFloat: true, path: 'gis/dijit/Draw', - title: 'Draw', + title: i18n.widgetTitles.draw, open: false, position: 4, options: { @@ -431,7 +432,7 @@ define([ type: 'titlePane', canFloat: true, path: 'gis/dijit/Measurement', - title: 'Measurement', + title: i18n.widgetTitles.measure, open: false, position: 5, options: { @@ -447,7 +448,7 @@ define([ type: 'titlePane', canFloat: true, path: 'gis/dijit/Print', - title: 'Print', + title: i18n.widgetTitles.print, open: false, position: 6, options: { @@ -465,7 +466,7 @@ define([ id: 'directions', type: 'titlePane', path: 'gis/dijit/Directions', - title: 'Directions', + title: i18n.widgetTitles.directions, open: false, position: 7, options: { @@ -486,7 +487,7 @@ define([ id: 'editor', type: 'titlePane', path: 'gis/dijit/Editor', - title: 'Editor', + title: i18n.widgetTitles.editor, open: false, position: 8, options: { @@ -515,7 +516,7 @@ define([ canFloat: true, position: 9, path: 'gis/dijit/StreetView', - title: 'Google Street View', + title: i18n.widgetTitles.streetview, paneOptions: { resizable: true, resizeOptions: { @@ -536,7 +537,7 @@ define([ id: 'help', type: 'floating', path: 'gis/dijit/Help', - title: 'Help', + title: i18n.widgetTitles.help, options: {} } From 38660d44466446379386e7597100ea8a05278948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Thu, 14 Jul 2016 16:43:14 +0100 Subject: [PATCH 105/216] complete viewer, add nls support in basemaps and bookmarks uniformize keys names to camelCase. --- viewer/js/config/basemaps.js | 59 +++++++++++------------ viewer/js/config/bookmarks.js | 39 +++++++++------- viewer/js/config/nls/main.js | 75 ++++++++++++++++++++++-------- viewer/js/config/nls/pt-pt/main.js | 48 +++++++++++-------- viewer/js/config/viewer.js | 46 +++++++++--------- 5 files changed, 159 insertions(+), 108 deletions(-) diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 92e4ba169..745b50911 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -1,12 +1,13 @@ define([ //'esri/dijit/Basemap', //'esri/dijit/BasemapLayer' -], function (/* Basemap, BasemapLayer */) { + 'dojo/i18n!./nls/main' +], function (/* Basemap, BasemapLayer, */i18n) { return { map: true, // needs a reference to the map mode: 'agol', // mut be either 'agol' or 'custom' - title: 'Basemaps', // title for widget + title: i18n.basemaps.title, // title for widget /* optional starting basemap / otherwise uses the basemap from the map @@ -18,51 +19,51 @@ define([ / otherwise uses keys in basemaps object below / values in array must match keys in basemaps object */ - //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'national-geographic', 'osm', 'oceans'], + //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'nationalGeographic', 'osm', 'oceans'], // define all valid basemaps here. basemaps: { streets: { - title: 'Streets' + title: i18n.basemaps.streets }, - 'streets-night-vector': { // requires v3.16 or higher - title: 'Streets (Night)' + streetsNightVector: { // requires v3.16 or higher + title: i18n.basemaps.streetsNightVector }, - 'streets-navigation-vector': { // requires v3.16 or higher - title: 'Streets (Navigation)' + streetsNavigationVector: { // requires v3.16 or higher + title: i18n.basemaps.streetsNavigationVector }, - 'streets-relief-vector': { // requires v3.16 or higher - title: 'Street (Relief)' + streetsReliefVector: { // requires v3.16 or higher + title: i18n.basemaps.streetsReliefVector }, satellite: { - title: 'Satellite' + title: i18n.basemaps.satellite }, hybrid: { - title: 'Hybrid' + title: i18n.basemaps.hybrid }, topo: { - title: 'Topo' + title: i18n.basemaps.topo }, - 'terrain': { - title: 'Terrain' + terrain: { + title: i18n.basemaps.terrain }, - 'gray-vector': { // requires v3.16 or higher - title: 'Gray' + grayVector: { // requires v3.16 or higher + title: i18n.basemaps.grayVector }, - 'dark-gray-vector': { // requires v3.16 or higher - title: 'Dark Gray' + darkGrayVector: { // requires v3.16 or higher + title: i18n.basemaps.darkGrayVector }, oceans: { - title: 'Oceans' + title: i18n.basemaps.oceans }, - 'national-geographic': { - title: 'Nat Geo' + nationalGeographic: { + title: i18n.basemaps.nationalGeographic }, osm: { - title: 'Open Street Map' + title: i18n.basemaps.osm }, - LandsatShaded: { - title: 'Landsat Shaded', + landsatShaded: { + title: i18n.basemaps.landsatShaded, basemap: { baseMapLayers: [ { @@ -71,8 +72,8 @@ define([ ] } }, - EarthAtNight: { - title: 'Earth at Night', + earthAtNight: { + title: i18n.basemaps.earthAtNight, basemap: { baseMapLayers: [ { @@ -81,8 +82,8 @@ define([ ] } }, - DavidRumseyMap1812: { - title: 'David Rumsey 1812', + davidRumseyMap1812: { + title: i18n.basemaps.davidRumseyMap1812, basemap: { baseMapLayers: [ { diff --git a/viewer/js/config/bookmarks.js b/viewer/js/config/bookmarks.js index cf89998e3..e0f7552ea 100644 --- a/viewer/js/config/bookmarks.js +++ b/viewer/js/config/bookmarks.js @@ -1,18 +1,23 @@ -define({ - map: true, - editable: true, - bookmarks: [ - { - extent: { - xmin: -15489130.48708616, - ymin: 398794.4860580916, - xmax: -5891085.7193757, - ymax: 8509680.431452557, - spatialReference: { - wkid: 102100 - } - }, - name: 'USA' - } - ] +define([ + 'dojo/i18n!./nls/main' +], function (i18n) { + + return { + map: true, + editable: true, + bookmarks: [ + { + extent: { + xmin: -15489130.48708616, + ymin: 398794.4860580916, + xmax: -5891085.7193757, + ymax: 8509680.431452557, + spatialReference: { + wkid: 102100 + } + }, + name: i18n.bookmarks.usa + } + ] + } }); \ No newline at end of file diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index 29a31d349..75da4bc62 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -1,23 +1,58 @@ // http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ - root: { - operationalLayers: { - sf311Incidents: 'San Francisco 311 Incidents' + root: { + basemaps: { + davidRumseyMap1812: 'David Rumsey 1812', + darkGrayVector: 'Dark Gray', + earthAtNight: 'Earth at Night', + grayVector: 'Gray', + hybrid: 'Hybrid', + landsatShaded: 'Landsat Shaded', + nationalGeographic: 'Nat Geo', + oceans: 'Oceans', + osm: 'Open Street Map', + satellite: 'Satellite', + streets: 'Streets', + streetsNavigationVector: 'Streets (Navigation)', + streetsNightVector: 'Streets (Night)', + streetsReliefVector: 'Street (Relief)', + terrain: 'Terrain', + title: 'Basemaps', + topo: 'Topographic' + }, + bookmarks: { + usa: 'USA' + }, + viewer: { + operationalLayers: { + damageAssessment: 'Damage Assessment', + louisvillePubSafety: 'Louisville Public Safety', + restaurants: 'Restaurants', + sf311Incidents: 'San Francisco 311 Incidents', + vectortile1: 'Light Gray Canvas Vector', + vectortile2: 'Custom Vector Style' + }, + titles: { + header: 'Configurable Map Viewer', + pageTitle: 'Configurable Map Viewer' + subHeader: 'make it your own', + }, + widgets: { + bookmarks: 'Bookmarks', + directions: 'Directions', + draw: 'Draw', + editor: 'Editor', + find: 'Find', + help: 'Help', + identify: 'Identify', + measure: 'Measurement', + layerControl: 'Layers', + legend: 'Legend', + print: 'Print', + streetview: 'Google Street View' + } + + }, }, - widgetTitles: { - bookmarks: 'Bookmarks', - directions: 'Directions', - draw: 'Draw', - editor: 'Editor', - find: 'Find', - help: 'Help', - identify: 'Identify', - measure: 'Measurement', - layerControl: 'Layers', - legend: 'Legend', - print: 'Print', - streetview: 'Google Street View' - } - }, - 'pt-pt': true -}) + 'pt-pt': true +}); diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index e60ee3ed3..276478f0a 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -1,22 +1,32 @@ // http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ - root: { - operationalLayers: { - sf311Incidents: 'San Francisco 311 Incidents' - }, - widgetTitles: { - bookmarks: 'Marcadores', - directions: 'Direcções', - draw: 'Desenhar', - editor: 'Editor', - find: 'Procurar', - help: 'Ajuda', - identify: 'Identificar', - measure: 'Medir', - layerControl: 'Camadas', - legend: 'Legendas', - print: 'Imprimir', - streetview: 'Google Street View' + viewer: { + operationalLayers: { + damageAssessment: 'Avaliação de dano', + louisvillePubSafety: 'Segurança Pública de Louisville', + restaurants: 'Restaurantes', + sf311Incidents: 'Incidentes do 311 de São Francisco', + vectortile1: 'Tela vectorial cinzento claro', + vectortile2: 'Estilo vectorial personalizado' + }, + titles: { + header: 'Configurable Map Viewer', + pageTitle: 'Configurable Map Viewer' + subHeader: 'make it your own', + }, + widgets: { + bookmarks: 'Marcadores', + directions: 'Direcções', + draw: 'Desenhar', + editor: 'Editor', + find: 'Procurar', + help: 'Ajuda', + identify: 'Identificar', + measure: 'Medir', + layerControl: 'Camadas', + legend: 'Legendas', + print: 'Imprimir', + streetview: 'Google Street View' + } } - } -}) +}); diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 08859995a..1a2673dcc 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -86,9 +86,9 @@ define([ // custom titles /* titles: { - header: 'My App', - subHeader: 'My GIS App is the best!', - pageTitle: 'My App' + header: i18n.viewer.titles.header, + subHeader: i18n.viewer.titles.subHeader, + pageTitle: i18n.viewer.titles.pageTitle }, */ @@ -112,7 +112,7 @@ define([ operationalLayers: [{ type: 'feature', url: 'https://services1.arcgis.com/6bXbLtkf4y11TosO/arcgis/rest/services/Restaurants/FeatureServer/0', - title: 'Restaurants', + title: i18n.viewer.operationalLayers.restaurants, options: { id: 'restaurants', opacity: 1.0, @@ -126,13 +126,13 @@ define([ legendLayerInfos: { exclude: false, layerInfo: { - title: 'Restaurants' + title: i18n.viewer.operationalLayers.restaurants } } }, { type: 'feature', url: 'https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', - title: i18n.operationalLayers.sf311Incidents, + title: i18n.viewer.operationalLayers.sf311Incidents, options: { id: 'sf311Incidents', opacity: 1.0, @@ -143,7 +143,7 @@ define([ }, { type: 'dynamic', url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', - title: 'Louisville Public Safety', + title: i18n.viewer.operationalLayers.louisvillePubSafety, options: { id: 'louisvillePubSafety', opacity: 1.0, @@ -167,9 +167,9 @@ define([ }, { type: 'dynamic', url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/MapServer', - title: 'Damage Assessment', + title: i18n.viewer.operationalLayers.damageAssessment, options: { - id: 'DamageAssessment', + id: 'damageAssessment', opacity: 1.0, visible: true, imageParameters: buildImageParameters() @@ -186,7 +186,7 @@ define([ //examples of vector tile layers (beta in v3.15) }, { type: 'vectortile', - title: 'Light Gray Canvas Vector', + title: i18n.viewer.operationalLayers.vectortile1, url: 'https://www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', options: { id: 'vectortile1', @@ -196,7 +196,7 @@ define([ }, { // taken from this demo: https://github.com/ycabon/presentations/blob/gh-pages/2015-berlin-plenary/demos/3.15-vectortile/create-by-style-object.html type: 'vectortile', - title: 'Custom Vector Style', + title: i18n.viewer.operationalLayers.vectortile2, options: { id: 'vectortile2', opacity: 1.0, @@ -268,7 +268,7 @@ define([ id: 'identify', type: 'titlePane', path: 'gis/dijit/Identify', - title: i18n.widgetTitles.identify, + title: i18n.viewer.widgets.identify, open: false, position: 3, options: 'config/identify' @@ -367,7 +367,7 @@ define([ id: 'legend', type: 'titlePane', path: 'esri/dijit/Legend', - title: i18n.widgetTitles.legend, + title: i18n.viewer.widgets.legend, open: false, position: 0, options: { @@ -380,7 +380,7 @@ define([ id: 'layerControl', type: 'titlePane', path: 'gis/dijit/LayerControl', - title: i18n.widgetTitles.layerControl, + title: i18n.viewer.widgets.layerControl, open: false, position: 0, options: { @@ -396,7 +396,7 @@ define([ id: 'bookmarks', type: 'titlePane', path: 'gis/dijit/Bookmarks', - title: i18n.widgetTitles.bookmarks, + title: i18n.viewer.widgets.bookmarks, open: false, position: 2, options: 'config/bookmarks' @@ -407,7 +407,7 @@ define([ type: 'titlePane', canFloat: true, path: 'gis/dijit/Find', - title: i18n.widgetTitles.find, + title: i18n.viewer.widgets.find, open: false, position: 3, options: 'config/find' @@ -418,7 +418,7 @@ define([ type: 'titlePane', canFloat: true, path: 'gis/dijit/Draw', - title: i18n.widgetTitles.draw, + title: i18n.viewer.widgets.draw, open: false, position: 4, options: { @@ -432,7 +432,7 @@ define([ type: 'titlePane', canFloat: true, path: 'gis/dijit/Measurement', - title: i18n.widgetTitles.measure, + title: i18n.viewer.widgets.measure, open: false, position: 5, options: { @@ -448,7 +448,7 @@ define([ type: 'titlePane', canFloat: true, path: 'gis/dijit/Print', - title: i18n.widgetTitles.print, + title: i18n.viewer.widgets.print, open: false, position: 6, options: { @@ -466,7 +466,7 @@ define([ id: 'directions', type: 'titlePane', path: 'gis/dijit/Directions', - title: i18n.widgetTitles.directions, + title: i18n.viewer.widgets.directions, open: false, position: 7, options: { @@ -487,7 +487,7 @@ define([ id: 'editor', type: 'titlePane', path: 'gis/dijit/Editor', - title: i18n.widgetTitles.editor, + title: i18n.viewer.widgets.editor, open: false, position: 8, options: { @@ -516,7 +516,7 @@ define([ canFloat: true, position: 9, path: 'gis/dijit/StreetView', - title: i18n.widgetTitles.streetview, + title: i18n.viewer.widgets.streetview, paneOptions: { resizable: true, resizeOptions: { @@ -537,7 +537,7 @@ define([ id: 'help', type: 'floating', path: 'gis/dijit/Help', - title: i18n.widgetTitles.help, + title: i18n.viewer.widgets.help, options: {} } From ce893307b2a7aafe25dedf35091ac820692624d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Thu, 14 Jul 2016 18:18:20 +0100 Subject: [PATCH 106/216] translate page titles --- viewer/js/config/nls/main.js | 7 +++---- viewer/js/config/nls/pt-pt/main.js | 4 ++-- viewer/js/config/viewer.js | 2 -- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index 75da4bc62..04fc35fd1 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -34,8 +34,8 @@ define({ }, titles: { header: 'Configurable Map Viewer', - pageTitle: 'Configurable Map Viewer' - subHeader: 'make it your own', + pageTitle: 'Configurable Map Viewer', + subHeader: 'make it your own' }, widgets: { bookmarks: 'Bookmarks', @@ -51,8 +51,7 @@ define({ print: 'Print', streetview: 'Google Street View' } - - }, + } }, 'pt-pt': true }); diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index 276478f0a..1cc146a82 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -11,8 +11,8 @@ define({ }, titles: { header: 'Configurable Map Viewer', - pageTitle: 'Configurable Map Viewer' - subHeader: 'make it your own', + pageTitle: 'Configurable Map Viewer — Um visualizador de mapas configurável', // One configurable map viewer + subHeader: 'personaliza-o ao teu gosto' // customize it at your will (the literal translation doesn’t sound good) }, widgets: { bookmarks: 'Marcadores', diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 1a2673dcc..ca518d6f3 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -84,13 +84,11 @@ define([ // collapseButtonsPane: 'center', //center or outer // custom titles - /* titles: { header: i18n.viewer.titles.header, subHeader: i18n.viewer.titles.subHeader, pageTitle: i18n.viewer.titles.pageTitle }, - */ // user-defined layer types /* From 11116e77631a9e2b09db04b71167f2eab28d00f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Thu, 14 Jul 2016 22:01:01 +0100 Subject: [PATCH 107/216] translate basemaps and bookmark --- viewer/js/config/nls/main.js | 2 +- viewer/js/config/nls/pt-pt/main.js | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index 04fc35fd1..c5ada65eb 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -15,7 +15,7 @@ define({ streets: 'Streets', streetsNavigationVector: 'Streets (Navigation)', streetsNightVector: 'Streets (Night)', - streetsReliefVector: 'Street (Relief)', + streetsReliefVector: 'Streets (Relief)', terrain: 'Terrain', title: 'Basemaps', topo: 'Topographic' diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index 1cc146a82..2193a033e 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -1,5 +1,27 @@ // http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ + basemaps: { + davidRumseyMap1812: 'David Rumsey 1812', + darkGrayVector: 'Cinzento escuro', + earthAtNight: 'Terra à noite', + grayVector: 'Cinzento', + hybrid: 'Híbrido', + landsatShaded: 'Landsat sombreado', + nationalGeographic: 'National Geographic', + oceans: 'Oceanos', + osm: 'Open Street Map', + satellite: 'Satélite', + streets: 'Ruas', + streetsNavigationVector: 'Ruas (Navegação)', + streetsNightVector: 'Ruas (Nocturno)', + streetsReliefVector: 'Ruas (Relevo)', + terrain: 'Terreno', + title: 'Mapas base', + topo: 'Topográfico' + }, + bookmarks: { + usa: 'EUA' + }, viewer: { operationalLayers: { damageAssessment: 'Avaliação de dano', From e5e951db74255ab96c390b975d9b8b2bf2163800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Thu, 14 Jul 2016 22:14:27 +0100 Subject: [PATCH 108/216] drop translation of commented operationalLayers examples --- viewer/js/config/nls/main.js | 2 -- viewer/js/config/nls/pt-pt/main.js | 2 -- viewer/js/config/viewer.js | 6 +++--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index c5ada65eb..e478f7c1f 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -29,8 +29,6 @@ define({ louisvillePubSafety: 'Louisville Public Safety', restaurants: 'Restaurants', sf311Incidents: 'San Francisco 311 Incidents', - vectortile1: 'Light Gray Canvas Vector', - vectortile2: 'Custom Vector Style' }, titles: { header: 'Configurable Map Viewer', diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index 2193a033e..24a260efc 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -28,8 +28,6 @@ define({ louisvillePubSafety: 'Segurança Pública de Louisville', restaurants: 'Restaurantes', sf311Incidents: 'Incidentes do 311 de São Francisco', - vectortile1: 'Tela vectorial cinzento claro', - vectortile2: 'Estilo vectorial personalizado' }, titles: { header: 'Configurable Map Viewer', diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index ca518d6f3..5e22c8fcf 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -184,8 +184,8 @@ define([ //examples of vector tile layers (beta in v3.15) }, { type: 'vectortile', - title: i18n.viewer.operationalLayers.vectortile1, - url: 'https://www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', + title: 'Light Gray Canvas Vector', + url: 'https//www.arcgis.com/sharing/rest/content/items/bdf1eec3fa79456c8c7c2bb62f86dade/resources/styles/root.json', options: { id: 'vectortile1', opacity: 0.8, @@ -194,7 +194,7 @@ define([ }, { // taken from this demo: https://github.com/ycabon/presentations/blob/gh-pages/2015-berlin-plenary/demos/3.15-vectortile/create-by-style-object.html type: 'vectortile', - title: i18n.viewer.operationalLayers.vectortile2, + title: 'Custom Vector Style', options: { id: 'vectortile2', opacity: 1.0, From 89b38011ab06064729bae9543c83a2d74aeb6daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Thu, 14 Jul 2016 22:48:52 +0100 Subject: [PATCH 109/216] add widgets translation --- .../gis/dijit/Basemaps/nls/pt-pt/resource.js | 3 ++ viewer/js/gis/dijit/Basemaps/nls/resource.js | 3 +- .../dijit/Directions/nls/pt-pt/resource.js | 23 +++++++++++ .../js/gis/dijit/Directions/nls/resource.js | 3 +- .../js/gis/dijit/Draw/nls/pt-pt/resource.js | 14 +++++++ viewer/js/gis/dijit/Draw/nls/resource.js | 3 +- .../js/gis/dijit/Editor/nls/pt-pt/resource.js | 6 +++ viewer/js/gis/dijit/Editor/nls/resource.js | 3 +- .../js/gis/dijit/Find/nls/pt-pt/resource.js | 26 ++++++++++++ viewer/js/gis/dijit/Find/nls/resource.js | 3 +- .../gis/dijit/Geocoder/nls/pt-pt/resource.js | 14 +++++++ viewer/js/gis/dijit/Geocoder/nls/resource.js | 3 +- .../gis/dijit/Identify/nls/pt-pt/resource.js | 12 ++++++ viewer/js/gis/dijit/Identify/nls/resource.js | 3 +- .../dijit/LayerControl/nls/pt-pt/resource.js | 21 ++++++++++ .../js/gis/dijit/LayerControl/nls/resource.js | 3 +- .../js/gis/dijit/Print/nls/pt-pt/resource.js | 40 +++++++++++++++++++ viewer/js/gis/dijit/Print/nls/resource.js | 3 +- .../dijit/StreetView/nls/pt-pt/resource.js | 10 +++++ .../js/gis/dijit/StreetView/nls/resource.js | 3 +- 20 files changed, 189 insertions(+), 10 deletions(-) create mode 100644 viewer/js/gis/dijit/Basemaps/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Directions/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Editor/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Find/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Geocoder/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/LayerControl/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Print/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/StreetView/nls/pt-pt/resource.js diff --git a/viewer/js/gis/dijit/Basemaps/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Basemaps/nls/pt-pt/resource.js new file mode 100644 index 000000000..0407ae701 --- /dev/null +++ b/viewer/js/gis/dijit/Basemaps/nls/pt-pt/resource.js @@ -0,0 +1,3 @@ +define ({ + title: 'Mapas base' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Basemaps/nls/resource.js b/viewer/js/gis/dijit/Basemaps/nls/resource.js index b7dace410..d9d66ace7 100644 --- a/viewer/js/gis/dijit/Basemaps/nls/resource.js +++ b/viewer/js/gis/dijit/Basemaps/nls/resource.js @@ -1,5 +1,6 @@ define ({ root: { title: 'Basemaps' - } + }, + 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Directions/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Directions/nls/pt-pt/resource.js new file mode 100644 index 000000000..38de61d1d --- /dev/null +++ b/viewer/js/gis/dijit/Directions/nls/pt-pt/resource.js @@ -0,0 +1,23 @@ +define ({ + labels: { + startAtMyLocation: 'iniciar na minha localização', + endAtMyLocation: 'terminar na minha localização', + clearStops: 'limpar paragens', + addStop: 'Adicionar paragem', + directionsToHere: 'Direcções para aqui', + directionsFromHere: 'Direcções a partir daqui', + useMyLocationAsStart: 'Usar a minha localização como ponto inicial', + useMyLocationAsEnd: 'Usar a minha localização como ponto final', + directions: 'Direcções' + }, + errors: { + geoLocation: { + title: 'Erro', + message: 'GeoLocalização não suportada no seu navegador.' + }, + location: { + title: 'Erro', + message: 'Ocorreu um problema ao obter a sua localização: ' + } + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Directions/nls/resource.js b/viewer/js/gis/dijit/Directions/nls/resource.js index 125b2e678..16dcbd567 100644 --- a/viewer/js/gis/dijit/Directions/nls/resource.js +++ b/viewer/js/gis/dijit/Directions/nls/resource.js @@ -21,5 +21,6 @@ define ({ message: 'There was a problem getting your location: ' } } - } + }, + 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js new file mode 100644 index 000000000..7b1eb8663 --- /dev/null +++ b/viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js @@ -0,0 +1,14 @@ +define ({ + labels: { + point: 'Ponto', + circle: 'Círculo', + polyline: 'Polilinha', + freehandPolyline: 'Polilinha à mão livre', + polygon: 'Polígono', + freehandPolygon: 'Polígono à mão livre', + stopDrawing: 'Parar de desenhar', + clearDrawing: 'Limpar desenhos', + currentDrawMode: 'Modo de desenho actual:', + currentDrawModeNone: 'Nenhum' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Draw/nls/resource.js b/viewer/js/gis/dijit/Draw/nls/resource.js index 29c6ab534..f571404d0 100644 --- a/viewer/js/gis/dijit/Draw/nls/resource.js +++ b/viewer/js/gis/dijit/Draw/nls/resource.js @@ -12,5 +12,6 @@ define ({ currentDrawMode: 'Current draw mode:', currentDrawModeNone: 'None' } - } + }, + 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Editor/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Editor/nls/pt-pt/resource.js new file mode 100644 index 000000000..065f070fd --- /dev/null +++ b/viewer/js/gis/dijit/Editor/nls/pt-pt/resource.js @@ -0,0 +1,6 @@ +define ({ + labels: { + startEditing: 'Iniciar edição', + stopEditing: 'Parar edição' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Editor/nls/resource.js b/viewer/js/gis/dijit/Editor/nls/resource.js index e24f161fb..d9212d380 100644 --- a/viewer/js/gis/dijit/Editor/nls/resource.js +++ b/viewer/js/gis/dijit/Editor/nls/resource.js @@ -4,5 +4,6 @@ define ({ startEditing: 'Start editing', stopEditing: 'Stop editing' } - } + }, + 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Find/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Find/nls/pt-pt/resource.js new file mode 100644 index 000000000..7538316be --- /dev/null +++ b/viewer/js/gis/dijit/Find/nls/pt-pt/resource.js @@ -0,0 +1,26 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + selectQuery: 'Seleccionar consulta', + searchText: { + label: 'Procurar por', + placeholder: 'Introduza o texto que pretende procurar.' + }, + exactMatches: 'Apenas correspondências exactas', + searchButton: { + label: 'Procurar', + busyLabel: 'a procurar' + }, + clearButton: { + label: 'Limpar' + }, + searching: 'A procurar...', + resultsLabel: { + multipleResultsSuffix: 's', + labelPrefix: 'Resultado', + labelSuffix: 'encontrado' + }, + noResultsLabel: 'Nenhum resultado encontrado.', + optionsLabel: 'Opções', + zoomOnSelect: 'Aproximar ao seleccionar', + zoomOnDeselect: 'Aproximar ao desseleccionar' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Find/nls/resource.js b/viewer/js/gis/dijit/Find/nls/resource.js index 3564a898e..c5d1ed505 100644 --- a/viewer/js/gis/dijit/Find/nls/resource.js +++ b/viewer/js/gis/dijit/Find/nls/resource.js @@ -24,6 +24,7 @@ define({ optionsLabel: 'Options', zoomOnSelect: 'Zoom on select', zoomOnDeselect: 'Zoom on deselect' - } + }, + 'pt-pt': true }); diff --git a/viewer/js/gis/dijit/Geocoder/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Geocoder/nls/pt-pt/resource.js new file mode 100644 index 000000000..302069814 --- /dev/null +++ b/viewer/js/gis/dijit/Geocoder/nls/pt-pt/resource.js @@ -0,0 +1,14 @@ +define ({ + title: 'Alternar barra de pesquisa', + labels: { + address: 'Endereço', + neighborhood: 'Bairro', + city: 'Cidade', + subregion: 'Subregião', + region: 'Região', + postalCode: 'Código postal', + countryCode: 'Código do país', + locatorName: 'Nome do localizador', + getAddressHere: 'Obter o endereço daqui' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Geocoder/nls/resource.js b/viewer/js/gis/dijit/Geocoder/nls/resource.js index 5f02f504a..b917a3046 100644 --- a/viewer/js/gis/dijit/Geocoder/nls/resource.js +++ b/viewer/js/gis/dijit/Geocoder/nls/resource.js @@ -12,5 +12,6 @@ define ({ locatorName: 'Locator name', getAddressHere: 'Get address here' } - } + }, + 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js new file mode 100644 index 000000000..23d428855 --- /dev/null +++ b/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js @@ -0,0 +1,12 @@ +define ({ + labels: { + selectLayer: 'Escolher "Todas as camadas visíveis" ou uma única camada para identificar:', + allVisibleLayers: '*** Todas as camadas visíveis ***' + }, + rightClickMenuItem: { + label: 'Identificar aqui' + }, + mapInfoWindow: { + identifyingTitle: 'A identificar...' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Identify/nls/resource.js b/viewer/js/gis/dijit/Identify/nls/resource.js index 54093328c..769ecc9e0 100644 --- a/viewer/js/gis/dijit/Identify/nls/resource.js +++ b/viewer/js/gis/dijit/Identify/nls/resource.js @@ -10,5 +10,6 @@ define ({ mapInfoWindow: { identifyingTitle: 'Identifying...' } - } + }, + 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/nls/pt-pt/resource.js b/viewer/js/gis/dijit/LayerControl/nls/pt-pt/resource.js new file mode 100644 index 000000000..bbb63ba4d --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/nls/pt-pt/resource.js @@ -0,0 +1,21 @@ +// internationalization for LayerControl +// +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +// +// if you would like to add a locale please create an issue at +// https://github.com/cmv/cmv-app/issues and someone will assist +// if need be or checkout the link above and submit a PR +define({ + noLegend: 'Sem legenda', + moveUp: 'Mover para cima', + moveDown: 'Mover para baixo', + zoomTo: 'Aproximar à Camada', + transparency: 'Transparência', + metadata: 'Metadados', + layerSwipe: 'Deslizar camada', + layerSwipeVertical: 'Vertical', + layerSwipeHorizontal: 'Horizontal', + layerSwipeScope: 'Janela', + dynamicSublayersOn: 'Activar todas as subcamadas', + dynamicSublayersOff: 'Desligar todas as subcamadas' +}); diff --git a/viewer/js/gis/dijit/LayerControl/nls/resource.js b/viewer/js/gis/dijit/LayerControl/nls/resource.js index 98a9848cb..cc3ee742b 100644 --- a/viewer/js/gis/dijit/LayerControl/nls/resource.js +++ b/viewer/js/gis/dijit/LayerControl/nls/resource.js @@ -19,5 +19,6 @@ define({ layerSwipeScope: 'Scope', dynamicSublayersOn: 'Turn On All Sublayers', dynamicSublayersOff: 'Turn Off All Sublayers' - } + }, + 'pt-pt': true }); diff --git a/viewer/js/gis/dijit/Print/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Print/nls/pt-pt/resource.js new file mode 100644 index 000000000..d95dcadc1 --- /dev/null +++ b/viewer/js/gis/dijit/Print/nls/pt-pt/resource.js @@ -0,0 +1,40 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + title: 'Título', + format: 'Formato', + layout: 'Modelo', + settings: 'Configurações', + mapScaleExtent: 'Escala/Extensão do mapa', + preserve: 'Preservar', + mapScale: 'Escala do mapa', + mapExtent: 'Extensão do mapa', + fullLayoutOptions: 'Todas as opções do modelo', + scaleBarUnits: 'Unidades da escala gráfica', + miles: 'Milhas', + kilometers: 'Quilómetros', + meters: 'Metros', + feet: 'Pés', + includeLegend: 'Incluir legenda', + printQualityOptions: 'Opções da qualidade de impressão', + dpiInput: { + label: 'DPI', + invalidMessage: 'Por favor introduza um valor numérico.', + rangeMessage: 'Por favor introduza um valor entre 100 e 300.' + }, + mapOnlyOptions: 'Opções do mapa', + width: 'Largura', + height: 'Altura', + printButton: { + busyLabel: 'a imprimir', + label: 'Imprimir' + }, + clearHistoryButton: { + label: 'Limpar o histórico de impressão' + }, + printResults: { + progressBar: { + label: 'A criar a impressão' + }, + errorMessage: 'Erro, tente novamente' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Print/nls/resource.js b/viewer/js/gis/dijit/Print/nls/resource.js index fab5aaa97..10662266c 100644 --- a/viewer/js/gis/dijit/Print/nls/resource.js +++ b/viewer/js/gis/dijit/Print/nls/resource.js @@ -38,6 +38,7 @@ define({ }, errorMessage: 'Error, try again' } - } + }, + 'pt-pt': true }); diff --git a/viewer/js/gis/dijit/StreetView/nls/pt-pt/resource.js b/viewer/js/gis/dijit/StreetView/nls/pt-pt/resource.js new file mode 100644 index 000000000..6e9f7e049 --- /dev/null +++ b/viewer/js/gis/dijit/StreetView/nls/pt-pt/resource.js @@ -0,0 +1,10 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + messages: { + instructions: 'Clique no botão do StreetView e depois clique na localização desejada no mapa.', + notAvailable: 'Infelizmente, o Google Street View não está disponível nesta localização.' + }, + rightClickMenuItem: { + label: 'Street View aqui' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/StreetView/nls/resource.js b/viewer/js/gis/dijit/StreetView/nls/resource.js index 9645bd886..600588984 100644 --- a/viewer/js/gis/dijit/StreetView/nls/resource.js +++ b/viewer/js/gis/dijit/StreetView/nls/resource.js @@ -8,6 +8,7 @@ define({ rightClickMenuItem: { label: 'Google StreetView here' } - } + }, + 'pt-pt': true }); From 8c3b11aa481bb9deab7ee81d4d688db42b20b324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Thu, 14 Jul 2016 23:19:56 +0100 Subject: [PATCH 110/216] add nls support to find and identify widgets and drop meetupHometowns layer reference, it isn't being used anymore --- viewer/js/config/find.js | 215 +++++++++++++++-------------- viewer/js/config/identify.js | 119 ++++++++-------- viewer/js/config/nls/main.js | 12 +- viewer/js/config/nls/pt-pt/main.js | 12 +- 4 files changed, 190 insertions(+), 168 deletions(-) diff --git a/viewer/js/config/find.js b/viewer/js/config/find.js index aa323416a..d0324aa15 100644 --- a/viewer/js/config/find.js +++ b/viewer/js/config/find.js @@ -1,112 +1,117 @@ /*eslint no-console: 0, no-alert: 0*/ -define({ - map: true, - zoomExtentFactor: 2, - queries: [ - { - description: 'Find A Public Safety Location By Name', - url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', - layerIds: [1, 2, 3, 4, 5, 6, 7], - searchFields: ['FDNAME, PDNAME', 'NAME', 'RESNAME'], - minChars: 2, - gridColumns: [ - { - field: 'Name', - label: 'Name' - }, - { - field: 'layerName', - label: 'Layer', - width: 100, - sortable: false, - resizable: false - } - ], - sort: [ - { - attribute: 'Name', - descending: false - } - ], - prompt: 'fdname, pdname, name or resname', - selectionMode: 'single' - }, - { - description: 'Find Incident By Code/Description', - url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', - layerIds: [15, 17, 18], - searchFields: ['FCODE', 'DESCRIPTION'], - minChars: 4, - gridColumns: [ - { - field: 'layerName', - label: 'Layer', - width: 100, - sortable: false, - resizable: false - }, - { - field: 'Fcode', - label: 'Fcode', - width: 100 - }, - { - field: 'Description', - label: 'Descr' - }, - { - field: 'SORT_VALUE', - visible: false, - get: function (findResult) { - return findResult.layerName + ' ' + findResult.feature.attributes.Fcode; //seems better to use attributes[ 'Fcode' ] but fails build. Attribute names will be aliases and may contain spaces and mixed cases. +define([ + 'dojo/i18n!./nls/main' +], function (i18n) { + + return { + map: true, + zoomExtentFactor: 2, + queries: [ + { + description: i18n.find.louisvillePubSafety, + url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', + layerIds: [1, 2, 3, 4, 5, 6, 7], + searchFields: ['FDNAME, PDNAME', 'NAME', 'RESNAME'], + minChars: 2, + gridColumns: [ + { + field: 'Name', + label: 'Name' + }, + { + field: 'layerName', + label: 'Layer', + width: 100, + sortable: false, + resizable: false } - } - ], - sort: [ - { - attribute: 'SORT_VALUE', - descending: false - } - ], - prompt: 'fdname, pdname, name or resname', - customGridEventHandlers: [ - { - event: '.dgrid-row:click', - handler: function (event) { - alert('You clicked a row!'); - console.log(event); + ], + sort: [ + { + attribute: 'Name', + descending: false + } + ], + prompt: 'fdname, pdname, name or resname', + selectionMode: 'single' + }, + { + description: i18n.find.sf311Incidents, + url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', + layerIds: [15, 17, 18], + searchFields: ['FCODE', 'DESCRIPTION'], + minChars: 4, + gridColumns: [ + { + field: 'layerName', + label: 'Layer', + width: 100, + sortable: false, + resizable: false + }, + { + field: 'Fcode', + label: 'Fcode', + width: 100 + }, + { + field: 'Description', + label: 'Descr' + }, + { + field: 'SORT_VALUE', + visible: false, + get: function (findResult) { + return findResult.layerName + ' ' + findResult.feature.attributes.Fcode; //seems better to use attributes[ 'Fcode' ] but fails build. Attribute names will be aliases and may contain spaces and mixed cases. + } } + ], + sort: [ + { + attribute: 'SORT_VALUE', + descending: false + } + ], + prompt: 'fdname, pdname, name or resname', + customGridEventHandlers: [ + { + event: '.dgrid-row:click', + handler: function (event) { + alert('You clicked a row!'); + console.log(event); + } + } + ] + } + ], + selectionSymbols: { + polygon: { + type: 'esriSFS', + style: 'esriSFSSolid', + color: [255, 0, 0, 62], + outline: { + type: 'esriSLS', + style: 'esriSLSSolid', + color: [255, 0, 0, 255], + width: 3 + } + }, + point: { + type: 'esriSMS', + style: 'esriSMSCircle', + size: 25, + color: [255, 0, 0, 62], + angle: 0, + xoffset: 0, + yoffset: 0, + outline: { + type: 'esriSLS', + style: 'esriSLSSolid', + color: [255, 0, 0, 255], + width: 2 } - ] - } - ], - selectionSymbols: { - polygon: { - type: 'esriSFS', - style: 'esriSFSSolid', - color: [255, 0, 0, 62], - outline: { - type: 'esriSLS', - style: 'esriSLSSolid', - color: [255, 0, 0, 255], - width: 3 } }, - point: { - type: 'esriSMS', - style: 'esriSMSCircle', - size: 25, - color: [255, 0, 0, 62], - angle: 0, - xoffset: 0, - yoffset: 0, - outline: { - type: 'esriSLS', - style: 'esriSLSSolid', - color: [255, 0, 0, 255], - width: 2 - } - } - }, - selectionMode: 'extended' + selectionMode: 'extended' + } }); \ No newline at end of file diff --git a/viewer/js/config/identify.js b/viewer/js/config/identify.js index ba781edda..5f6f36dbf 100644 --- a/viewer/js/config/identify.js +++ b/viewer/js/config/identify.js @@ -1,67 +1,64 @@ -define({ - map: true, - mapClickMode: true, - mapRightClickMenu: true, - identifyLayerInfos: true, - identifyTolerance: 5, +define([ + 'dojo/i18n!./nls/main' +], function (i18n) { - // config object definition: - // {:{ - // :{ - // - // } - // }, - // :{ - // :{ - // - // } - // } - // } + return { + map: true, + mapClickMode: true, + mapRightClickMenu: true, + identifyLayerInfos: true, + identifyTolerance: 5, + draggable: false, - // for details on pop-up definition see: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html + // config object definition: + // {:{ + // :{ + // + // } + // }, + // :{ + // :{ + // + // } + // } + // } - identifies: { - meetupHometowns: { - 0: { - title: 'Hometowns', - fieldInfos: [{ - fieldName: 'Location', - visible: true - }] - } - }, - louisvillePubSafety: { - 2: { - title: 'Police Station', - fieldInfos: [{ - fieldName: 'Name', - visible: true - }, { - fieldName: 'Address', - visible: true - }, { - fieldName: 'Type', - visible: true - }, { - fieldName: 'Police Function', - visible: true - }, { - fieldName: 'Last Update Date', - visible: true - }] - }, - 8: { - title: 'Traffic Camera', - description: '{Description} lasted updated: {Last Update Date}', - mediaInfos: [{ - title: '', - caption: '', - type: 'image', - value: { - sourceURL: '{Location URL}', - linkURL: '{Location URL}' - } - }] + // for details on pop-up definition see: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html + + identifies: { + louisvillePubSafety: { + 2: { + title: i18n.identify.louisvillePubSafety.policeStation, + fieldInfos: [{ + fieldName: 'Name', + visible: true + }, { + fieldName: 'Address', + visible: true + }, { + fieldName: 'Type', + visible: true + }, { + fieldName: 'Police Function', + visible: true + }, { + fieldName: 'Last Update Date', + visible: true + }] + }, + 8: { + title: i18n.identify.louisvillePubSafety.trafficCamera, + description: '{Description} lasted updated: {Last Update Date}', + mediaInfos: [{ + title: '', + caption: '', + type: 'image', + value: { + sourceURL: '{Location URL}', + linkURL: '{Location URL}' + } + }] + } } } } diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index e478f7c1f..23d7dc432 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -23,12 +23,22 @@ define({ bookmarks: { usa: 'USA' }, + find: { + louisvillePubSafety: 'Find A Public Safety Location By Name', + sf311Incidents: 'Find Incident By Code/Description' + }, + identify: { + louisvillePubSafety: { + policeStation: 'Police Station', + trafficCamera: 'Traffic Camera' + } + }, viewer: { operationalLayers: { damageAssessment: 'Damage Assessment', louisvillePubSafety: 'Louisville Public Safety', restaurants: 'Restaurants', - sf311Incidents: 'San Francisco 311 Incidents', + sf311Incidents: 'San Francisco 311 Incidents' }, titles: { header: 'Configurable Map Viewer', diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index 24a260efc..2b2f92d5c 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -22,12 +22,22 @@ define({ bookmarks: { usa: 'EUA' }, + find: { + louisvillePubSafety: 'Encontrar um local de Segurança Pública pelo nome', + sf311Incidents: 'Encontrar incidente por código/descrição' + }, + identify: { + louisvillePubSafety: { + policeStation: 'Esquadra da Polícia', + trafficCamera: 'Câmara de trânsito' + } + }, viewer: { operationalLayers: { damageAssessment: 'Avaliação de dano', louisvillePubSafety: 'Segurança Pública de Louisville', restaurants: 'Restaurantes', - sf311Incidents: 'Incidentes do 311 de São Francisco', + sf311Incidents: 'Incidentes do 311 de São Francisco' }, titles: { header: 'Configurable Map Viewer', From f7dc97e49c73528c555225f2c25ac36deef7a609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Thu, 14 Jul 2016 23:32:31 +0100 Subject: [PATCH 111/216] Null Island! as suggested by @tmcgee see: http://www.wsj.com/articles/if-you-cant-follow-directions-youll-end-up-on-null-island-1468422251 http://www.nullisland.com/ --- viewer/js/config/bookmarks.js | 12 ++++++++++++ viewer/js/config/nls/main.js | 3 ++- viewer/js/config/nls/pt-pt/main.js | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/viewer/js/config/bookmarks.js b/viewer/js/config/bookmarks.js index e0f7552ea..56cc070a1 100644 --- a/viewer/js/config/bookmarks.js +++ b/viewer/js/config/bookmarks.js @@ -17,6 +17,18 @@ define([ } }, name: i18n.bookmarks.usa + }, + { + extent: { + xmin: 0, + ymin: 0, + xmax: 0, + ymax: 0, + spatialReference: { + wkid: 102100 + } + }, + name: i18n.bookmarks.nullIsland } ] } diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index 23d7dc432..3c61ae143 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -21,7 +21,8 @@ define({ topo: 'Topographic' }, bookmarks: { - usa: 'USA' + nullIsland: 'Null Island', + usa: 'USA' }, find: { louisvillePubSafety: 'Find A Public Safety Location By Name', diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index 2b2f92d5c..a309b1e34 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -20,6 +20,7 @@ define({ topo: 'Topográfico' }, bookmarks: { + nullIsland: 'Ilha Nula', usa: 'EUA' }, find: { From 131ed064134421e7a4cdbf4cfdc830e5c72bc840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Fri, 15 Jul 2016 02:18:40 +0100 Subject: [PATCH 112/216] lint free --- viewer/js/config/basemaps.js | 18 +++++++++--------- viewer/js/config/bookmarks.js | 2 +- viewer/js/config/find.js | 2 +- viewer/js/config/identify.js | 2 +- .../gis/dijit/Basemaps/nls/pt-pt/resource.js | 4 ++-- .../gis/dijit/Directions/nls/pt-pt/resource.js | 4 ++-- viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js | 4 ++-- .../js/gis/dijit/Editor/nls/pt-pt/resource.js | 4 ++-- viewer/js/gis/dijit/Find/nls/pt-pt/resource.js | 2 +- .../gis/dijit/Geocoder/nls/pt-pt/resource.js | 4 ++-- .../gis/dijit/Identify/nls/pt-pt/resource.js | 4 ++-- .../dijit/LayerControl/nls/pt-pt/resource.js | 2 +- .../js/gis/dijit/Print/nls/pt-pt/resource.js | 2 +- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 745b50911..32cefd31c 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -19,20 +19,20 @@ define([ / otherwise uses keys in basemaps object below / values in array must match keys in basemaps object */ - //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'nationalGeographic', 'osm', 'oceans'], + //basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'lightGray', 'gray', 'national-geographic', 'osm', 'oceans'], // define all valid basemaps here. basemaps: { streets: { title: i18n.basemaps.streets }, - streetsNightVector: { // requires v3.16 or higher + 'streets-night-vector': { // requires v3.16 or higher title: i18n.basemaps.streetsNightVector }, - streetsNavigationVector: { // requires v3.16 or higher + 'streets-navigation-vector': { // requires v3.16 or higher title: i18n.basemaps.streetsNavigationVector }, - streetsReliefVector: { // requires v3.16 or higher + 'streets-relief-vector': { // requires v3.16 or higher title: i18n.basemaps.streetsReliefVector }, satellite: { @@ -47,16 +47,16 @@ define([ terrain: { title: i18n.basemaps.terrain }, - grayVector: { // requires v3.16 or higher + 'gray-vector': { // requires v3.16 or higher title: i18n.basemaps.grayVector }, - darkGrayVector: { // requires v3.16 or higher + 'dark-gray-vector': { // requires v3.16 or higher title: i18n.basemaps.darkGrayVector }, oceans: { title: i18n.basemaps.oceans }, - nationalGeographic: { + 'national-geographic': { title: i18n.basemaps.nationalGeographic }, osm: { @@ -142,7 +142,7 @@ define([ ] } }, - darkGrayVector: { + 'dark-gray-vector': { title: 'Dark Gray Canvas', basemap: { baseMapLayers: [ @@ -164,7 +164,7 @@ define([ ] } }, - streetsNightVector: { + 'streets-night-vector': { title: 'Streets Night', basemap: { baseMapLayers: [ diff --git a/viewer/js/config/bookmarks.js b/viewer/js/config/bookmarks.js index 56cc070a1..90beb5de4 100644 --- a/viewer/js/config/bookmarks.js +++ b/viewer/js/config/bookmarks.js @@ -31,5 +31,5 @@ define([ name: i18n.bookmarks.nullIsland } ] - } + }; }); \ No newline at end of file diff --git a/viewer/js/config/find.js b/viewer/js/config/find.js index d0324aa15..ad6bfb877 100644 --- a/viewer/js/config/find.js +++ b/viewer/js/config/find.js @@ -113,5 +113,5 @@ define([ } }, selectionMode: 'extended' - } + }; }); \ No newline at end of file diff --git a/viewer/js/config/identify.js b/viewer/js/config/identify.js index 5f6f36dbf..32958beac 100644 --- a/viewer/js/config/identify.js +++ b/viewer/js/config/identify.js @@ -61,5 +61,5 @@ define([ } } } - } + }; }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Basemaps/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Basemaps/nls/pt-pt/resource.js index 0407ae701..d67f99c97 100644 --- a/viewer/js/gis/dijit/Basemaps/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Basemaps/nls/pt-pt/resource.js @@ -1,3 +1,3 @@ -define ({ - title: 'Mapas base' +define({ + title: 'Mapas base' }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Directions/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Directions/nls/pt-pt/resource.js index 38de61d1d..e1ccff40e 100644 --- a/viewer/js/gis/dijit/Directions/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Directions/nls/pt-pt/resource.js @@ -1,5 +1,5 @@ -define ({ - labels: { +define({ + labels: { startAtMyLocation: 'iniciar na minha localização', endAtMyLocation: 'terminar na minha localização', clearStops: 'limpar paragens', diff --git a/viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js index 7b1eb8663..9dc6144bb 100644 --- a/viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Draw/nls/pt-pt/resource.js @@ -1,5 +1,5 @@ -define ({ - labels: { +define({ + labels: { point: 'Ponto', circle: 'Círculo', polyline: 'Polilinha', diff --git a/viewer/js/gis/dijit/Editor/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Editor/nls/pt-pt/resource.js index 065f070fd..5c499062e 100644 --- a/viewer/js/gis/dijit/Editor/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Editor/nls/pt-pt/resource.js @@ -1,5 +1,5 @@ -define ({ - labels: { +define({ + labels: { startEditing: 'Iniciar edição', stopEditing: 'Parar edição' } diff --git a/viewer/js/gis/dijit/Find/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Find/nls/pt-pt/resource.js index 7538316be..e38f69d21 100644 --- a/viewer/js/gis/dijit/Find/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Find/nls/pt-pt/resource.js @@ -1,6 +1,6 @@ // http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ - selectQuery: 'Seleccionar consulta', + selectQuery: 'Seleccionar consulta', searchText: { label: 'Procurar por', placeholder: 'Introduza o texto que pretende procurar.' diff --git a/viewer/js/gis/dijit/Geocoder/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Geocoder/nls/pt-pt/resource.js index 302069814..7667ddf08 100644 --- a/viewer/js/gis/dijit/Geocoder/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Geocoder/nls/pt-pt/resource.js @@ -1,5 +1,5 @@ -define ({ - title: 'Alternar barra de pesquisa', +define({ + title: 'Alternar barra de pesquisa', labels: { address: 'Endereço', neighborhood: 'Bairro', diff --git a/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js index 23d428855..ab2998ff7 100644 --- a/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js @@ -1,5 +1,5 @@ -define ({ - labels: { +define({ + labels: { selectLayer: 'Escolher "Todas as camadas visíveis" ou uma única camada para identificar:', allVisibleLayers: '*** Todas as camadas visíveis ***' }, diff --git a/viewer/js/gis/dijit/LayerControl/nls/pt-pt/resource.js b/viewer/js/gis/dijit/LayerControl/nls/pt-pt/resource.js index bbb63ba4d..e66ea4143 100644 --- a/viewer/js/gis/dijit/LayerControl/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/LayerControl/nls/pt-pt/resource.js @@ -6,7 +6,7 @@ // https://github.com/cmv/cmv-app/issues and someone will assist // if need be or checkout the link above and submit a PR define({ - noLegend: 'Sem legenda', + noLegend: 'Sem legenda', moveUp: 'Mover para cima', moveDown: 'Mover para baixo', zoomTo: 'Aproximar à Camada', diff --git a/viewer/js/gis/dijit/Print/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Print/nls/pt-pt/resource.js index d95dcadc1..2f9ac62fa 100644 --- a/viewer/js/gis/dijit/Print/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Print/nls/pt-pt/resource.js @@ -1,6 +1,6 @@ // http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html define({ - title: 'Título', + title: 'Título', format: 'Formato', layout: 'Modelo', settings: 'Configurações', From 8f19570c7910603c07f383fa5ac305a908b54d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=81lio?= Date: Thu, 21 Jul 2016 14:04:45 +0100 Subject: [PATCH 113/216] add nls support to the help widget --- viewer/js/gis/dijit/Help.js | 7 +-- .../js/gis/dijit/Help/nls/pt-pt/resource.js | 36 ++++++++++++++ viewer/js/gis/dijit/Help/nls/resource.js | 39 +++++++++++++++ .../gis/dijit/Help/templates/HelpDialog.html | 47 +++++++++---------- 4 files changed, 102 insertions(+), 27 deletions(-) create mode 100644 viewer/js/gis/dijit/Help/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Help/nls/resource.js diff --git a/viewer/js/gis/dijit/Help.js b/viewer/js/gis/dijit/Help.js index 2594baf0c..461a374d1 100644 --- a/viewer/js/gis/dijit/Help.js +++ b/viewer/js/gis/dijit/Help.js @@ -9,17 +9,18 @@ define([ 'dojo/_base/lang', 'dojo/aspect', 'dojo/text!./Help/templates/HelpDialog.html', + 'dojo/i18n!./Help/nls/resource', 'dijit/form/Button', 'dijit/layout/TabContainer', 'dijit/layout/ContentPane', 'xstyle/css!./Help/css/Help.css' -], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, domConstruct, on, lang, aspect, template) { +], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, domConstruct, on, lang, aspect, template, i18n) { return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin], { widgetsInTemplate: true, templateString: template, - title: 'Help', - html: 'Help', + i18n: i18n, + html: 'link'.replace('link', i18n.link), domTarget: 'helpDijit', draggable: false, baseClass: 'helpDijit', diff --git a/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js new file mode 100644 index 000000000..2793d85a8 --- /dev/null +++ b/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js @@ -0,0 +1,36 @@ +define({ + link: 'Ajuda', + navigation: { + title: 'Navegação', + description: 'Navegação no mapa usando o rato e o teclado', + pan1: 'Arrastar para mover', + recenter: 'SHIFT + Clique para centrar', + zoomIn1: 'SHIFT + Arrastar para aproximar à área', + zoomOut1: 'SHIFT + CTRL + Arrastar para afastar', + zoomIn2: 'Mover roda de deslocação do rato para a frente para aproximar', + zoomOut2: 'Mover roda de deslocação do rato para trás para afastar', + pan2: 'Teclas de seta para mover', + zoomInLevel: 'Tecla + para aproximar um nível', + zoomOutLevel: 'Tecla - para afastar um nível', + zoomCenter: 'Duplo clique para centrar e aproximar' + }, + search: { + title: 'Pesquisa', + description: 'A caixa de pesquisa suporta vários tipos de pesquisa:', + address: 'Pesquisar por endereço', + place: 'Pesquisar por nome do local', + etc: 'Pesquisar por código postal, região, etc.' + }, + tools: { + title: 'Ferramentas', + description: 'Além das funcionalidades de pesquisa, são incluídas as seguintes ferramentas:', + measure: { + title: 'Medir', + description: 'A ferramenta de medição permite desenhar um ponto, linha, ou polígono, no mapa e especificar a unidade de medida.' + }, + print: { + title: 'Imprimir', + description: 'Este mapa pode ser exportado para diferentes formatos e modelos.' + } + } +}); diff --git a/viewer/js/gis/dijit/Help/nls/resource.js b/viewer/js/gis/dijit/Help/nls/resource.js new file mode 100644 index 000000000..058b58576 --- /dev/null +++ b/viewer/js/gis/dijit/Help/nls/resource.js @@ -0,0 +1,39 @@ +define({ + root: { + link: 'Help', + navigation: { + title: 'Navigation', + description: 'Map navigation using mouse and keyboard:', + pan1: 'Drag to pan', + recenter: 'SHIFT + Click to recenter', + zoomIn1: 'SHIFT + Drag to zoom in', + zoomOut1: 'SHIFT + CTRL + Drag to zoom out', + zoomIn2: 'Mouse Scroll Forward to zoom in', + zoomOut2: 'Mouse Scroll Backward to zoom out', + pan2: 'Use Arrow keys to pan', + zoomInLevel: '+ key to zoom in a level', + zoomOutLevel: '- key to zoom out a level', + zoomCenter: 'Double Click to Center and Zoom in' + }, + search: { + title: 'Search', + description: 'A variety of searches can be performed in the search box:', + address: 'Search by Address', + place: 'Search by Place Name', + etc: 'Search By Zip Code, County, etc.' + }, + tools: { + title: 'Tools', + description: 'In addition to Search capabilities, the following tools are provided:', + measure: { + title: 'Measure', + description: 'The measure tool provides the capabilities to draw a point, line, or polygon on the map and specify the unit of measurement.' + }, + print: { + title: 'Print', + description: 'This map can be exported to various formats and layouts.' + } + } + }, + 'pt-pt': true +}); diff --git a/viewer/js/gis/dijit/Help/templates/HelpDialog.html b/viewer/js/gis/dijit/Help/templates/HelpDialog.html index 82a31e5b9..da701f42f 100644 --- a/viewer/js/gis/dijit/Help/templates/HelpDialog.html +++ b/viewer/js/gis/dijit/Help/templates/HelpDialog.html @@ -2,42 +2,42 @@
-
+
@@ -45,35 +45,34 @@
- Map navigation using mouse and keyboard: + ${i18n.navigation.description}
  • - Drag to pan + ${i18n.navigation.pan1}
  • - SHIFT + Click to recenter + ${i18n.navigation.recenter}
  • - SHIFT + Drag to zoom in + ${i18n.navigation.zoomIn1}
  • - SHIFT + CTRL + Drag to zoom out + ${i18n.navigation.zoomOut1}
  • - Mouse Scroll Forward to zoom in + ${i18n.navigation.zoomIn2}
  • - Mouse Scroll Backward to zoom out + ${i18n.navigation.zoomOut2}
  • - Use Arrow keys to pan + ${i18n.navigation.pan2}
  • - + key to zoom in a level + ${i18n.navigation.zoomInLevel}
  • - - key to zoom out a level + ${i18n.navigation.zoomOutLevel}
  • - Double Click to Center and Zoom in + ${i18n.navigation.zoomCenter}
-
- A variety of searches can be performed in the search box: +
+ ${i18n.search.description}
  • - Search by Address + ${i18n.search.address}
  • - Search by Place Name + ${i18n.search.place}
  • - Search By Zip Code, County, etc. + ${i18n.search.etc}
-
- In addition to Search capabilities, the following tools are provided: +
+ ${i18n.tools.description}
  • - Measure + ${i18n.tools.measure.title}
  • - The measure tool provides the capabilities to draw a point, line, or polygon - on the map and specify the unit of measurement. + ${i18n.tools.measure.description}
  • - Print + ${i18n.tools.print.title}
  • - This map can be exported to varouis formats and layouts + ${i18n.tools.print.description}
From 16ed6cd5ec557e27f0f5918a2fb548e96bfbc54b Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Thu, 4 Aug 2016 18:19:53 -0700 Subject: [PATCH 114/216] Replace spatialreference.org with epsg.io to support https scheme. --- viewer/js/gis/dijit/MapInfo.js | 28 ++++++++++++++-------------- viewer/js/gis/dijit/StreetView.js | 21 ++++++++++----------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/viewer/js/gis/dijit/MapInfo.js b/viewer/js/gis/dijit/MapInfo.js index 6f674e665..a6d414ba2 100644 --- a/viewer/js/gis/dijit/MapInfo.js +++ b/viewer/js/gis/dijit/MapInfo.js @@ -36,6 +36,7 @@ define([ scaleLabel: '1:', zoomLabel: 'Z:', minWidth: 0, + proj4BaseURL: 'https://epsg.io/', proj4Catalog: null, proj4Wkid: null, proj4CustomURL: null, @@ -99,27 +100,26 @@ define([ this._mode = 3; } else { this._mode = 4; - // spatialreference.org uses the old - // Proj4js style so we need an alias - // https://github.com/proj4js/proj4js/issues/23 - window.Proj4js = proj4; - //load custom projection file or default to spatialreference.org - if (!this.proj4Catalog && !this.proj4Wkid && !this.proj4CustomURL) { + if (!window.proj4) { + window.proj4 = proj4; + } + if (this.proj4Wkid) { + wkid = this.proj4Wkid; + } + //load custom projection file or default to epsg.io + if (!this.proj4Catalog && !wkid && !this.proj4CustomURL) { topic.publish('viewer/handleError', { source: 'MapInfo', error: 'MapInfo error::a proj4Catalog/proj4Wkid or custom URL must be defined' }); return; } - if (this.proj4CustomURL) { - require([this.proj4CustomURL], lang.hitch(this, function () { - this._projectionLoaded = true; - this._projection = this.proj4Catalog + ':' + this.proj4Wkid; - })); - } else { - require(['http://spatialreference.org/ref/' + this.proj4Catalog.toLowerCase() + '/' + this.proj4Wkid + '/proj4js/'], lang.hitch(this, function () { + var key = this.proj4Catalog + ':' + String(wkid); + this._projection = key; + if (!proj4.defs[key]) { + var url = this.proj4CustomURL || this.proj4BaseURL + String(wkid) + '.js'; + require([url], lang.hitch(this, function () { this._projectionLoaded = true; - this._projection = this.proj4Catalog + ':' + this.proj4Wkid; })); } } diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index 9dba0c8ec..e628e0271 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -33,14 +33,14 @@ define([ panoOptions: null, // in case this changes some day - proj4BaseURL: 'http://spatialreference.org/', + proj4BaseURL: 'https://epsg.io/', // options are ESRI, EPSG and SR-ORG - // See http://spatialreference.org/ for more information + // See http://sepsg.io/ for more information proj4Catalog: 'EPSG', // if desired, you can load a projection file from your server - // instead of using one from spatialreference.org + // instead of using one from epsg.io // i.e., http://server/projections/102642.js projCustomURL: null, @@ -78,10 +78,9 @@ define([ this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); } - // spatialreference.org uses the old - // Proj4js style so we need an alias - // https://github.com/proj4js/proj4js/issues/23 - window.Proj4js = proj4; + if (!window.proj4) { + window.proj4 = proj4; + } if (this.mapRightClickMenu) { this.addRightClickMenu(); @@ -175,9 +174,9 @@ define([ if (wkid === 102100) { wkid = 3857; } - var key = this.proj4Catalog + ':' + wkid; + var key = this.proj4Catalog + ':' + String(wkid); if (!proj4.defs[key]) { - var url = this.proj4CustomURL || this.proj4BaseURL + 'ref/' + this.proj4Catalog.toLowerCase() + '/' + wkid + '/proj4js/'; + var url = this.proj4CustomURL || this.proj4BaseURL + String(wkid) + '.js'; require([url], lang.hitch(this, 'getStreetView', evt, true)); return; } @@ -261,9 +260,9 @@ define([ if (wkid === 102100) { wkid = 3857; } - var key = this.proj4Catalog + ':' + wkid; + var key = this.proj4Catalog + ':' + String(wkid); if (!proj4.defs[key]) { - var url = this.proj4CustomURL || this.proj4BaseURL + 'ref/' + this.proj4Catalog.toLowerCase() + '/' + wkid + '/proj4js/'; + var url = this.proj4CustomURL || this.proj4BaseURL + String(wkid) + '.js'; require([url], lang.hitch(this, 'setPlaceMarkerPosition')); return; } From 273dc54b3b021a9562a9b741837c55336cd05745 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 5 Aug 2016 15:59:53 -0700 Subject: [PATCH 115/216] fix a typo that's been around for awhile. --- viewer/js/gis/dijit/StreetView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index e628e0271..a9dc90a0f 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -42,7 +42,7 @@ define([ // if desired, you can load a projection file from your server // instead of using one from epsg.io // i.e., http://server/projections/102642.js - projCustomURL: null, + proj4CustomURL: null, postCreate: function () { this.inherited(arguments); From 1da70c7552c0ec52c2c02145dede3ced3d371bd2 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 6 Aug 2016 17:05:12 -0700 Subject: [PATCH 116/216] Add translations for Spanish, French and Portuguese (Brazil). Spanish and French are quick and dirty translations and need review by native speakers. --- viewer/js/config/basemaps.js | 1 - viewer/js/config/nls/es/main.js | 63 +++++++++++++++++++ viewer/js/config/nls/fr/main.js | 62 ++++++++++++++++++ viewer/js/config/nls/main.js | 4 +- viewer/js/config/nls/pt-br/main.js | 62 ++++++++++++++++++ viewer/js/config/nls/pt-pt/main.js | 1 - .../js/gis/dijit/Basemaps/nls/es/resource.js | 3 + .../js/gis/dijit/Basemaps/nls/fr/resource.js | 3 + .../gis/dijit/Basemaps/nls/pt-br/resource.js | 3 + viewer/js/gis/dijit/Basemaps/nls/resource.js | 3 + .../gis/dijit/Directions/nls/es/resource.js | 23 +++++++ .../gis/dijit/Directions/nls/fr/resource.js | 23 +++++++ .../dijit/Directions/nls/pt-br/resource.js | 23 +++++++ .../js/gis/dijit/Directions/nls/resource.js | 3 + viewer/js/gis/dijit/Draw/nls/es/resource.js | 14 +++++ viewer/js/gis/dijit/Draw/nls/fr/resource.js | 14 +++++ .../js/gis/dijit/Draw/nls/pt-br/resource.js | 14 +++++ viewer/js/gis/dijit/Draw/nls/resource.js | 3 + viewer/js/gis/dijit/Editor/nls/es/resource.js | 6 ++ viewer/js/gis/dijit/Editor/nls/fr/resource.js | 6 ++ .../js/gis/dijit/Editor/nls/pt-br/resource.js | 6 ++ viewer/js/gis/dijit/Editor/nls/resource.js | 3 + viewer/js/gis/dijit/Find/nls/es/resource.js | 25 ++++++++ viewer/js/gis/dijit/Find/nls/fr/resource.js | 25 ++++++++ .../js/gis/dijit/Find/nls/pt-br/resource.js | 26 ++++++++ viewer/js/gis/dijit/Find/nls/resource.js | 3 + .../js/gis/dijit/Geocoder/nls/es/resource.js | 14 +++++ .../js/gis/dijit/Geocoder/nls/fr/resource.js | 14 +++++ .../gis/dijit/Geocoder/nls/pt-br/resource.js | 14 +++++ viewer/js/gis/dijit/Geocoder/nls/resource.js | 3 + viewer/js/gis/dijit/Help/nls/es/resource.js | 36 +++++++++++ viewer/js/gis/dijit/Help/nls/fr/resource.js | 36 +++++++++++ .../js/gis/dijit/Help/nls/pt-br/resource.js | 36 +++++++++++ viewer/js/gis/dijit/Help/nls/resource.js | 3 + .../js/gis/dijit/Identify/nls/es/resource.js | 12 ++++ .../js/gis/dijit/Identify/nls/fr/resource.js | 12 ++++ .../gis/dijit/Identify/nls/pt-br/resource.js | 12 ++++ viewer/js/gis/dijit/Identify/nls/resource.js | 3 + .../gis/dijit/LayerControl/nls/es/resource.js | 14 +++++ .../gis/dijit/LayerControl/nls/fr/resource.js | 14 +++++ .../dijit/LayerControl/nls/pt-br/resource.js | 21 +++++++ .../js/gis/dijit/LayerControl/nls/resource.js | 3 + viewer/js/gis/dijit/Print/nls/es/resource.js | 39 ++++++++++++ viewer/js/gis/dijit/Print/nls/fr/resource.js | 39 ++++++++++++ .../js/gis/dijit/Print/nls/pt-br/resource.js | 40 ++++++++++++ viewer/js/gis/dijit/Print/nls/resource.js | 3 + .../gis/dijit/StreetView/nls/es/resource.js | 9 +++ .../gis/dijit/StreetView/nls/fr/resource.js | 9 +++ .../dijit/StreetView/nls/pt-br/resource.js | 10 +++ .../js/gis/dijit/StreetView/nls/resource.js | 3 + 50 files changed, 818 insertions(+), 3 deletions(-) create mode 100644 viewer/js/config/nls/es/main.js create mode 100644 viewer/js/config/nls/fr/main.js create mode 100644 viewer/js/config/nls/pt-br/main.js create mode 100644 viewer/js/gis/dijit/Basemaps/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Basemaps/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Basemaps/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Directions/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Directions/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Directions/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Draw/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Draw/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Draw/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Editor/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Editor/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Editor/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Find/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Find/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Find/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Geocoder/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Geocoder/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Geocoder/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Help/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Help/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Help/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Identify/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Identify/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Identify/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/LayerControl/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/LayerControl/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/LayerControl/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Print/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Print/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Print/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/StreetView/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/StreetView/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/StreetView/nls/pt-br/resource.js diff --git a/viewer/js/config/basemaps.js b/viewer/js/config/basemaps.js index 32cefd31c..b8949f657 100644 --- a/viewer/js/config/basemaps.js +++ b/viewer/js/config/basemaps.js @@ -7,7 +7,6 @@ define([ return { map: true, // needs a reference to the map mode: 'agol', // mut be either 'agol' or 'custom' - title: i18n.basemaps.title, // title for widget /* optional starting basemap / otherwise uses the basemap from the map diff --git a/viewer/js/config/nls/es/main.js b/viewer/js/config/nls/es/main.js new file mode 100644 index 000000000..75d390710 --- /dev/null +++ b/viewer/js/config/nls/es/main.js @@ -0,0 +1,63 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + basemaps: { + davidRumseyMap1812: 'David Rumsey 1812', + darkGrayVector: 'Gris oscuro', + earthAtNight: 'Tierra en la noche', + grayVector: 'Gris', + hybrid: 'Híbrido', + landsatShaded: 'Landsat sombreada', + nationalGeographic: 'Nat Geo', + oceans: 'Oceános', + osm: 'Open Street Map', + satellite: 'Satélite', + streets: 'Calle', + streetsNavigationVector: 'Calle (Navegación)', + streetsNightVector: 'Calle (Noche)', + streetsReliefVector: 'Calle (Relieve)', + terrain: 'Terreno', + title: 'Mapas base', + topo: 'Topográfico' + }, + bookmarks: { + nullIsland: 'Isla nula', + usa: 'EE.UU.' + }, + find: { + louisvillePubSafety: 'Encontrar un local de Seguridad Pública por su nombre', + sf311Incidents: 'Encuentra incidente por código/descripción' + }, + identify: { + louisvillePubSafety: { + policeStation: 'Comisaría de Policía', + trafficCamera: 'Cámara de Tráfico' + } + }, + viewer: { + operationalLayers: { + damageAssessment: 'Valoración de daño', + louisvillePubSafety: 'Seguridad Pública de Louisville', + restaurants: 'Restaurantes', + sf311Incidents: '311 Incidentes de San Francisco' + }, + titles: { + header: 'Configurable Map Viewer', + pageTitle: 'Configurable Map Viewer — Un visor de mapas configurables', // One configurable map viewer + subHeader: 'personalizarlo a su gusto' // customize it at your will (the literal translation doesn’t sound good) + }, + widgets: { + bookmarks: 'Marcadores', + directions: 'Direcciones', + draw: 'Dibujar', + editor: 'Editor', + find: 'Encontrar', + help: 'Ayuda', + identify: 'Identificar', + measure: 'Medición', + layerControl: 'Capas', + legend: 'Leyenda', + print: 'Imprimir', + streetview: 'Google Street View' + } + } +}); \ No newline at end of file diff --git a/viewer/js/config/nls/fr/main.js b/viewer/js/config/nls/fr/main.js new file mode 100644 index 000000000..3dab3a222 --- /dev/null +++ b/viewer/js/config/nls/fr/main.js @@ -0,0 +1,62 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + basemaps: { + davidRumseyMap1812: 'David Rumsey 1812', + darkGrayVector: 'Gris Foncé', + earthAtNight: 'Terre la nuit', + grayVector: 'Gris', + hybrid: 'Hybride', + landsatShaded: 'Landsat Ombragée', + nationalGeographic: 'National Geographic', + oceans: 'Oceans', + osm: 'Open Street Map', + satellite: 'Photos aériennes', + streets: 'Rues', + streetsNavigationVector: 'Rues (Navigation)', + streetsNightVector: 'Rues (Nuit)', + streetsReliefVector: 'Rues (Relief)', + terrain: 'Sol', + topo: 'Topographique' + }, + bookmarks: { + nullIsland: 'Île Null', + usa: 'USA' + }, + find: { + louisvillePubSafety: 'Trouvez une Sécurité Publique locale par nom', + sf311Incidents: 'Trouver incident en code/description' + }, + identify: { + louisvillePubSafety: { + policeStation: 'Poste de police', + trafficCamera: 'Caméra de circulation' + } + }, + viewer: { + operationalLayers: { + damageAssessment: 'Évaluation des Dommages', + louisvillePubSafety: 'Louisville Sécurité Publique', + restaurants: 'Restaurants', + sf311Incidents: '311 Incidents de San Francisco' + }, + titles: { + header: 'Configurable Map Viewer', + pageTitle: 'Configurable Map Viewer - Un visualiseur de cartes configurables', + subHeader: 'personalizarlo su gusto' + }, + widgets: { + bookmarks: 'Géosignets', + directions: 'Directions', + draw: 'Annotations', + editor: 'Éditeur', + find: 'Rechercher', + help: 'Aide', + identify: 'Identifier', + measure: 'Mesures', + layerControl: 'Couches d\'information', + legend: 'Légende', + print: 'Impression', + streetview: 'Google Street View' + } + } +}); diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index 3c61ae143..0e3df38df 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -17,7 +17,6 @@ define({ streetsNightVector: 'Streets (Night)', streetsReliefVector: 'Streets (Relief)', terrain: 'Terrain', - title: 'Basemaps', topo: 'Topographic' }, bookmarks: { @@ -62,5 +61,8 @@ define({ } } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); diff --git a/viewer/js/config/nls/pt-br/main.js b/viewer/js/config/nls/pt-br/main.js new file mode 100644 index 000000000..27b6d6ffb --- /dev/null +++ b/viewer/js/config/nls/pt-br/main.js @@ -0,0 +1,62 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + basemaps: { + davidRumseyMap1812: 'David Rumsey 1812', + darkGrayVector: 'Cinzento escuro', + earthAtNight: 'Terra à noite', + grayVector: 'Cinzento', + hybrid: 'Híbrido', + landsatShaded: 'Landsat sombreado', + nationalGeographic: 'National Geographic', + oceans: 'Oceanos', + osm: 'Open Street Map', + satellite: 'Satélite', + streets: 'Ruas', + streetsNavigationVector: 'Ruas (Navegação)', + streetsNightVector: 'Ruas (Nocturno)', + streetsReliefVector: 'Ruas (Relevo)', + terrain: 'Terreno', + topo: 'Topográfico' + }, + bookmarks: { + nullIsland: 'Ilha Nula', + usa: 'EUA' + }, + find: { + louisvillePubSafety: 'Encontrar um local de Segurança Pública pelo nome', + sf311Incidents: 'Encontrar incidente por código/descrição' + }, + identify: { + louisvillePubSafety: { + policeStation: 'Esquadra da Polícia', + trafficCamera: 'Câmara de trânsito' + } + }, + viewer: { + operationalLayers: { + damageAssessment: 'Avaliação de dano', + louisvillePubSafety: 'Segurança Pública de Louisville', + restaurants: 'Restaurantes', + sf311Incidents: 'Incidentes do 311 de São Francisco' + }, + titles: { + header: 'Configurable Map Viewer', + pageTitle: 'Configurable Map Viewer — Um visualizador de mapas configurável', // One configurable map viewer + subHeader: 'personaliza-o ao teu gosto' // customize it at your will (the literal translation doesn’t sound good) + }, + widgets: { + bookmarks: 'Marcadores', + directions: 'Direcções', + draw: 'Desenhar', + editor: 'Editor', + find: 'Procurar', + help: 'Ajuda', + identify: 'Identificar', + measure: 'Medir', + layerControl: 'Camadas', + legend: 'Legendas', + print: 'Imprimir', + streetview: 'Google Street View' + } + } +}); diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index a309b1e34..27b6d6ffb 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -16,7 +16,6 @@ define({ streetsNightVector: 'Ruas (Nocturno)', streetsReliefVector: 'Ruas (Relevo)', terrain: 'Terreno', - title: 'Mapas base', topo: 'Topográfico' }, bookmarks: { diff --git a/viewer/js/gis/dijit/Basemaps/nls/es/resource.js b/viewer/js/gis/dijit/Basemaps/nls/es/resource.js new file mode 100644 index 000000000..48f8546d9 --- /dev/null +++ b/viewer/js/gis/dijit/Basemaps/nls/es/resource.js @@ -0,0 +1,3 @@ +define ({ + title: 'Mapas base' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Basemaps/nls/fr/resource.js b/viewer/js/gis/dijit/Basemaps/nls/fr/resource.js new file mode 100644 index 000000000..1717b565f --- /dev/null +++ b/viewer/js/gis/dijit/Basemaps/nls/fr/resource.js @@ -0,0 +1,3 @@ +define ({ + title: 'Fond de carte' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Basemaps/nls/pt-br/resource.js b/viewer/js/gis/dijit/Basemaps/nls/pt-br/resource.js new file mode 100644 index 000000000..48f8546d9 --- /dev/null +++ b/viewer/js/gis/dijit/Basemaps/nls/pt-br/resource.js @@ -0,0 +1,3 @@ +define ({ + title: 'Mapas base' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Basemaps/nls/resource.js b/viewer/js/gis/dijit/Basemaps/nls/resource.js index d9d66ace7..99c7c0fae 100644 --- a/viewer/js/gis/dijit/Basemaps/nls/resource.js +++ b/viewer/js/gis/dijit/Basemaps/nls/resource.js @@ -2,5 +2,8 @@ define ({ root: { title: 'Basemaps' }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Directions/nls/es/resource.js b/viewer/js/gis/dijit/Directions/nls/es/resource.js new file mode 100644 index 000000000..0f1f0d9e0 --- /dev/null +++ b/viewer/js/gis/dijit/Directions/nls/es/resource.js @@ -0,0 +1,23 @@ +define ({ + labels: { + startAtMyLocation: 'comenzará a mi ubicación', + endAtMyLocation: 'terminar en mi ubicación', + clearStops: 'paradas claras', + addStop: 'Añadir parada', + directionsToHere: 'Direcciones a aquí', + directionsFromHere: 'Direcciones de aquí', + useMyLocationAsStart: 'Usar mi ubicación como punto de inicio', + useMyLocationAsEnd: 'Usar mi ubicación como punto final', + directions: 'Direcciones' + }, + errors: { + geoLocation: { + title: 'Error', + message: 'No geolocalización apoyado por su hojeanr.' + }, + location: { + title: 'Error', + message: 'Hubo un problema con su ubicación: ' + } + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Directions/nls/fr/resource.js b/viewer/js/gis/dijit/Directions/nls/fr/resource.js new file mode 100644 index 000000000..fd33b5437 --- /dev/null +++ b/viewer/js/gis/dijit/Directions/nls/fr/resource.js @@ -0,0 +1,23 @@ +define ({ + labels: { + startAtMyLocation: 'commencer à mon endroit', + endAtMyLocation: 'fin à mon endroit', + clearStops: 'arrêts clairs', + addStop: 'Ajouter arrêt', + directionsToHere: 'Directions vers ici', + directionsFromHere: 'Directions d\'ici', + useMyLocationAsStart: 'Utiliser ma position comme point de départ', + useMyLocationAsEnd: 'Utiliser ma position comme point final', + directions: 'Directions' + }, + errors: { + geoLocation: { + title: 'Erreur', + message: 'Géolocalisation non supporté par votre navigateur.' + }, + location: { + title: 'Erreur', + message: 'Il y avait un problème pour obtenir votre position: ' + } + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Directions/nls/pt-br/resource.js b/viewer/js/gis/dijit/Directions/nls/pt-br/resource.js new file mode 100644 index 000000000..51bf9d23f --- /dev/null +++ b/viewer/js/gis/dijit/Directions/nls/pt-br/resource.js @@ -0,0 +1,23 @@ +define({ + labels: { + startAtMyLocation: 'Inicie na minha Localização', + endAtMyLocation: 'Termine na minha Localização', + clearStops: 'Limpar paradas', + addStop: 'Adicionar parada', + directionsToHere: 'Direções para aqui', + directionsFromHere: 'Direções daqui', + useMyLocationAsStart: 'Use minha Localização como ponto de início', + useMyLocationAsEnd: 'Use minha Localização como ponto final', + directions: 'Direções' + }, + errors: { + geoLocation: { + title: 'Erro', + message: 'GeoLocalização não suportada no seu navegador.' + }, + location: { + title: 'Erro', + message: 'Houve um problema ao buscar sua Localização: ' + } + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Directions/nls/resource.js b/viewer/js/gis/dijit/Directions/nls/resource.js index 16dcbd567..b1db86f01 100644 --- a/viewer/js/gis/dijit/Directions/nls/resource.js +++ b/viewer/js/gis/dijit/Directions/nls/resource.js @@ -22,5 +22,8 @@ define ({ } } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Draw/nls/es/resource.js b/viewer/js/gis/dijit/Draw/nls/es/resource.js new file mode 100644 index 000000000..32e5d4098 --- /dev/null +++ b/viewer/js/gis/dijit/Draw/nls/es/resource.js @@ -0,0 +1,14 @@ +define ({ + labels: { + point: 'Punto', + circle: 'Circulo', + polyline: 'Polilínea', + freehandPolyline: 'Polilínea a mano alzada', + polygon: 'Polígono', + freehandPolygon: 'Polígono a mano alzada', + stopDrawing: 'Comienzo dibujo', + clearDrawing: 'Despejar dibujo', + currentDrawMode: 'El modo de dibujo:', + currentDrawModeNone: 'Nada' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Draw/nls/fr/resource.js b/viewer/js/gis/dijit/Draw/nls/fr/resource.js new file mode 100644 index 000000000..eb3810ca0 --- /dev/null +++ b/viewer/js/gis/dijit/Draw/nls/fr/resource.js @@ -0,0 +1,14 @@ +define ({ + labels: { + point: 'Point', + circle: 'Cercle', + polyline: 'Polyline', + freehandPolyline: 'À main levée polyline', + polygon: 'Polygone', + freehandPolygon: 'À main levée polygone', + stopDrawing: 'Arrêtez le dessin', + clearDrawing: 'Effacer dessin', + currentDrawMode: 'Mode de dessin:', + currentDrawModeNone: 'Aucun' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Draw/nls/pt-br/resource.js b/viewer/js/gis/dijit/Draw/nls/pt-br/resource.js new file mode 100644 index 000000000..4192728c6 --- /dev/null +++ b/viewer/js/gis/dijit/Draw/nls/pt-br/resource.js @@ -0,0 +1,14 @@ +define({ + labels: { + point: 'Ponto', + circle: 'Círculo', + polyline: 'Polilinha', + freehandPolyline: 'Polilinha a Mão Livre', + polygon: 'Polígono', + freehandPolygon: 'Polígono a Mão Livre', + stopDrawing: 'Parar de Desenhar', + clearDrawing: 'Limpar Desenhos', + currentDrawMode: 'Modo de desenho atual:', + currentDrawModeNone: 'Nenhum' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Draw/nls/resource.js b/viewer/js/gis/dijit/Draw/nls/resource.js index f571404d0..b55a4fd3c 100644 --- a/viewer/js/gis/dijit/Draw/nls/resource.js +++ b/viewer/js/gis/dijit/Draw/nls/resource.js @@ -13,5 +13,8 @@ define ({ currentDrawModeNone: 'None' } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Editor/nls/es/resource.js b/viewer/js/gis/dijit/Editor/nls/es/resource.js new file mode 100644 index 000000000..445721fa7 --- /dev/null +++ b/viewer/js/gis/dijit/Editor/nls/es/resource.js @@ -0,0 +1,6 @@ +define ({ + labels: { + startEditing: 'Comenzar a editar', + stopEditing: 'Detener la edición' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Editor/nls/fr/resource.js b/viewer/js/gis/dijit/Editor/nls/fr/resource.js new file mode 100644 index 000000000..237f02020 --- /dev/null +++ b/viewer/js/gis/dijit/Editor/nls/fr/resource.js @@ -0,0 +1,6 @@ +define ({ + labels: { + startEditing: 'Commencez à éditer', + stopEditing: 'Arrêter l\'édition' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Editor/nls/pt-br/resource.js b/viewer/js/gis/dijit/Editor/nls/pt-br/resource.js new file mode 100644 index 000000000..79974dfec --- /dev/null +++ b/viewer/js/gis/dijit/Editor/nls/pt-br/resource.js @@ -0,0 +1,6 @@ +define({ + labels: { + startEditing: 'Iniciar Edição', + stopEditing: 'Parar Edição' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Editor/nls/resource.js b/viewer/js/gis/dijit/Editor/nls/resource.js index d9212d380..5320f6518 100644 --- a/viewer/js/gis/dijit/Editor/nls/resource.js +++ b/viewer/js/gis/dijit/Editor/nls/resource.js @@ -5,5 +5,8 @@ define ({ stopEditing: 'Stop editing' } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Find/nls/es/resource.js b/viewer/js/gis/dijit/Find/nls/es/resource.js new file mode 100644 index 000000000..0efc73504 --- /dev/null +++ b/viewer/js/gis/dijit/Find/nls/es/resource.js @@ -0,0 +1,25 @@ +define ({ + selectQuery: 'Consulta de selección', + searchText: { + label: 'Buscar', + placeholder: 'Introduzca el texto que desea buscar.' + }, + exactMatches: 'Buscar sólo coincidencias exactas', + searchButton: { + label: 'Buscar', + busyLabel: 'buscando' + }, + clearButton: { + label: 'Despejar' + }, + searching: 'Buscando...', + resultsLabel: { + multipleResultsSuffix: 's', + labelPrefix: 'Resultado', + labelSuffix: 'encontró' + }, + noResultsLabel: 'No se han encontrado resultados.', + optionsLabel: 'Opciones', + zoomOnSelect: 'Ampliar en seleccione', + zoomOnDeselect: 'Ampliar en no seleccione' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Find/nls/fr/resource.js b/viewer/js/gis/dijit/Find/nls/fr/resource.js new file mode 100644 index 000000000..b0ce0408b --- /dev/null +++ b/viewer/js/gis/dijit/Find/nls/fr/resource.js @@ -0,0 +1,25 @@ +define ({ + selectQuery: 'Sélectionnez requête', + searchText: { + label: 'Rechercher', + placeholder: 'Entrez le texte que vous souhaitez rechercher.' + }, + exactMatches: 'Trouver seulement les correspondances exactes', + searchButton: { + label: 'Rechercher', + busyLabel: 'recherche' + }, + clearButton: { + label: 'Effacer' + }, + searching: 'Recherche...', + resultsLabel: { + multipleResultsSuffix: 's', + labelPrefix: 'Résultat', + labelSuffix: 'trouvé' + }, + noResultsLabel: 'Aucun résultat trouvé.', + optionsLabel: 'Options', + zoomOnSelect: 'Zoom sur select', + zoomOnDeselect: 'Zoom sur deselect' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Find/nls/pt-br/resource.js b/viewer/js/gis/dijit/Find/nls/pt-br/resource.js new file mode 100644 index 000000000..fa350b994 --- /dev/null +++ b/viewer/js/gis/dijit/Find/nls/pt-br/resource.js @@ -0,0 +1,26 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + selectQuery: 'Selecionar Procura', + searchText: { + label: 'Procurar por', + placeholder: 'Digite o texto que você quer procurar.' + }, + exactMatches: 'Apenas buscas exatas', + searchButton: { + label: 'Procurar', + busyLabel: 'procurando' + }, + clearButton: { + label: 'Limpar' + }, + searching: 'Procurando...', + resultsLabel: { + multipleResultsSuffix: 's', + labelPrefix: 'Resultado', + labelSuffix: 'encontrado' + }, + noResultsLabel: 'Nenhum Resultado Encontrado.', + optionsLabel: 'Opções', + zoomOnSelect: 'Zoom para selecionar', + zoomOnDeselect: 'Zoom para deselecionar' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Find/nls/resource.js b/viewer/js/gis/dijit/Find/nls/resource.js index c5d1ed505..4e0a71f8d 100644 --- a/viewer/js/gis/dijit/Find/nls/resource.js +++ b/viewer/js/gis/dijit/Find/nls/resource.js @@ -25,6 +25,9 @@ define({ zoomOnSelect: 'Zoom on select', zoomOnDeselect: 'Zoom on deselect' }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); diff --git a/viewer/js/gis/dijit/Geocoder/nls/es/resource.js b/viewer/js/gis/dijit/Geocoder/nls/es/resource.js new file mode 100644 index 000000000..edd0ec207 --- /dev/null +++ b/viewer/js/gis/dijit/Geocoder/nls/es/resource.js @@ -0,0 +1,14 @@ +define ({ + title: 'Alternar barra de búsqueda', + labels: { + address: 'Dirección', + neighborhood: 'Barrio', + city: 'Ciudad', + subregion: 'Subregión', + region: 'Región', + postalCode: 'Código postal', + countryCode: 'Código de país', + locatorName: 'Nombre del localizador', + getAddressHere: 'Obtener dirección aquí' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Geocoder/nls/fr/resource.js b/viewer/js/gis/dijit/Geocoder/nls/fr/resource.js new file mode 100644 index 000000000..08e9c28b3 --- /dev/null +++ b/viewer/js/gis/dijit/Geocoder/nls/fr/resource.js @@ -0,0 +1,14 @@ +define ({ + title: 'Basculer barre de recherche', + labels: { + address: 'Adresse', + neighborhood: 'Quartier', + city: 'Ville', + subregion: 'Sous-région', + region: 'Région', + postalCode: 'Code postal', + countryCode: 'Code de pays', + locatorName: 'Nom du localisateur', + getAddressHere: 'Obtenir l\'adresse ici' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Geocoder/nls/pt-br/resource.js b/viewer/js/gis/dijit/Geocoder/nls/pt-br/resource.js new file mode 100644 index 000000000..8f79694a2 --- /dev/null +++ b/viewer/js/gis/dijit/Geocoder/nls/pt-br/resource.js @@ -0,0 +1,14 @@ +define ({ + title: 'Alternar barra de Pesquisa', + labels: { + address: 'Endereço', + neighborhood: 'Bairro', + city: 'Cidade', + subregion: 'Subregião', + region: 'Região', + postalCode: 'Código Postal (CEP)', + countryCode: 'Código do País', + locatorName: 'Nome do Localizador', + getAddressHere: 'Obtenha o Endereço daqui' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Geocoder/nls/resource.js b/viewer/js/gis/dijit/Geocoder/nls/resource.js index b917a3046..a93722458 100644 --- a/viewer/js/gis/dijit/Geocoder/nls/resource.js +++ b/viewer/js/gis/dijit/Geocoder/nls/resource.js @@ -13,5 +13,8 @@ define ({ getAddressHere: 'Get address here' } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Help/nls/es/resource.js b/viewer/js/gis/dijit/Help/nls/es/resource.js new file mode 100644 index 000000000..6c4cea412 --- /dev/null +++ b/viewer/js/gis/dijit/Help/nls/es/resource.js @@ -0,0 +1,36 @@ +define ({ + link: 'Ayuda', + navigation: { + title: 'Navegación', + description: 'Mapa de navegación a través del ratón y el teclado:', + pan1: 'Arrastre a la sartén', + recenter: 'SHIFT + Clic para volver a centrar', + zoomIn1: 'SHIFT + Arrastre para ampliar la imagen', + zoomOut1: 'SHIFT + CTRL + arrastrar para alejarla', + zoomIn2: 'De desplazamiento del ratón hacia adelante para hacer un zoom', + zoomOut2: 'De desplazamiento del ratón hacia atrás para reducir', + pan2: 'Utilice las teclas de flecha para desplazarse', + zoomInLevel: '+ clave para hacer un zoom un nivel', + zoomOutLevel: '- clave para alejar un nivel', + zoomCenter: 'Doble click para Centro y hacer zoom in' + }, + search: { + title: 'Buscar', + description: 'Una variedad de búsquedas se pueden realizar en el buscador:', + address: 'Buscar por Dirección', + place: 'Búsqueda Territorial', + etc: 'Buscar por código postal, condado, etc.' + }, + tools: { + title: 'Herramientas', + description: 'Además de las capacidades de búsqueda, se proporcionan las siguientes herramientas:', + measure: { + title: 'Medición', + description: 'La herramienta de medida proporciona la capacidad para dibujar un punto, una línea o un polígono en el mapa y especificar la unidad de medida.' + }, + print: { + title: 'Impresión', + description: 'Este mapa se puede exportar a diversos formatos y diseños.' + } + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Help/nls/fr/resource.js b/viewer/js/gis/dijit/Help/nls/fr/resource.js new file mode 100644 index 000000000..0bae87a2a --- /dev/null +++ b/viewer/js/gis/dijit/Help/nls/fr/resource.js @@ -0,0 +1,36 @@ +define ({ + link: 'Aidez-moi', + navigation: { + title: 'La navigation', + description: 'Navigation de la carte en utilisant la souris et le clavier:', + pan1: 'Faites glisser la casserole', + recenter: 'SHIFT + Cliquez pour recentrer', + zoomIn1: 'SHIFT + Drag to zoom in', + zoomOut1: 'SHIFT + CTRL + glisser pour effectuer un zoom arrière', + zoomIn2: 'Défilement de la souris vers l\'avant pour agrandir', + zoomOut2: 'Défilement de la souris vers l\'avant pour rétrécir', + pan2: 'Utilisez les touches fléchées pour vous déplacer', + zoomInLevel: '+ clé pour zoomer un niveau', + zoomOutLevel: '- clé pour rétrécir un niveau', + zoomCenter: 'Double cliquez pour centre et zoom' + }, + search: { + title: 'Chercher', + description: 'Une variété de recherches peuvent être effectuées dans la zone de recherche:', + address: 'Recherche par adresse', + place: 'Search by Place Name', + etc: 'Recherche par code postal, comté, etc.' + }, + tools: { + title: 'Outils', + description: 'En plus de capacités de recherche, les outils suivants sont fournis:', + measure: { + title: 'Mesurer', + description: 'L\'outil de mesure fournit les capacités pour dessiner un point, une ligne ou un polygone sur la carte et indiquer l\'unité de mesure.' + }, + print: { + title: 'Impression', + description: 'Cette carte peut être exportée vers différents formats et présentations.' + } + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Help/nls/pt-br/resource.js b/viewer/js/gis/dijit/Help/nls/pt-br/resource.js new file mode 100644 index 000000000..2793d85a8 --- /dev/null +++ b/viewer/js/gis/dijit/Help/nls/pt-br/resource.js @@ -0,0 +1,36 @@ +define({ + link: 'Ajuda', + navigation: { + title: 'Navegação', + description: 'Navegação no mapa usando o rato e o teclado', + pan1: 'Arrastar para mover', + recenter: 'SHIFT + Clique para centrar', + zoomIn1: 'SHIFT + Arrastar para aproximar à área', + zoomOut1: 'SHIFT + CTRL + Arrastar para afastar', + zoomIn2: 'Mover roda de deslocação do rato para a frente para aproximar', + zoomOut2: 'Mover roda de deslocação do rato para trás para afastar', + pan2: 'Teclas de seta para mover', + zoomInLevel: 'Tecla + para aproximar um nível', + zoomOutLevel: 'Tecla - para afastar um nível', + zoomCenter: 'Duplo clique para centrar e aproximar' + }, + search: { + title: 'Pesquisa', + description: 'A caixa de pesquisa suporta vários tipos de pesquisa:', + address: 'Pesquisar por endereço', + place: 'Pesquisar por nome do local', + etc: 'Pesquisar por código postal, região, etc.' + }, + tools: { + title: 'Ferramentas', + description: 'Além das funcionalidades de pesquisa, são incluídas as seguintes ferramentas:', + measure: { + title: 'Medir', + description: 'A ferramenta de medição permite desenhar um ponto, linha, ou polígono, no mapa e especificar a unidade de medida.' + }, + print: { + title: 'Imprimir', + description: 'Este mapa pode ser exportado para diferentes formatos e modelos.' + } + } +}); diff --git a/viewer/js/gis/dijit/Help/nls/resource.js b/viewer/js/gis/dijit/Help/nls/resource.js index 058b58576..137c491ff 100644 --- a/viewer/js/gis/dijit/Help/nls/resource.js +++ b/viewer/js/gis/dijit/Help/nls/resource.js @@ -35,5 +35,8 @@ define({ } } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); diff --git a/viewer/js/gis/dijit/Identify/nls/es/resource.js b/viewer/js/gis/dijit/Identify/nls/es/resource.js new file mode 100644 index 000000000..fda941704 --- /dev/null +++ b/viewer/js/gis/dijit/Identify/nls/es/resource.js @@ -0,0 +1,12 @@ +define ({ + labels: { + selectLayer: 'Seleccione la opción "Todas las capas visibles" o una sola capa para identificar:', + allVisibleLayers: '*** Todas las capas visibles ***' + }, + rightClickMenuItem: { + label: 'Identificar aquí' + }, + mapInfoWindow: { + identifyingTitle: 'Identificando...' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Identify/nls/fr/resource.js b/viewer/js/gis/dijit/Identify/nls/fr/resource.js new file mode 100644 index 000000000..e67fcc89e --- /dev/null +++ b/viewer/js/gis/dijit/Identify/nls/fr/resource.js @@ -0,0 +1,12 @@ +define ({ + labels: { + selectLayer: 'Choisissez "Tous les calques visibles" ou une seule couche pour identifier:', + allVisibleLayers: '*** Tous les calques visibles ***' + }, + rightClickMenuItem: { + label: 'Identifier ici' + }, + mapInfoWindow: { + identifyingTitle: 'Identifier...' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Identify/nls/pt-br/resource.js b/viewer/js/gis/dijit/Identify/nls/pt-br/resource.js new file mode 100644 index 000000000..1a4d3327b --- /dev/null +++ b/viewer/js/gis/dijit/Identify/nls/pt-br/resource.js @@ -0,0 +1,12 @@ +define({ + labels: { + selectLayer: 'Escolha "Todas Camadas Visíveis" ou uma camada única para Identificar:', + allVisibleLayers: '*** Todas Camadas Visíveis ***' + }, + rightClickMenuItem: { + label: 'Identifique aqui' + }, + mapInfoWindow: { + identifyingTitle: 'Identificando...' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Identify/nls/resource.js b/viewer/js/gis/dijit/Identify/nls/resource.js index 769ecc9e0..f46111906 100644 --- a/viewer/js/gis/dijit/Identify/nls/resource.js +++ b/viewer/js/gis/dijit/Identify/nls/resource.js @@ -11,5 +11,8 @@ define ({ identifyingTitle: 'Identifying...' } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/nls/es/resource.js b/viewer/js/gis/dijit/LayerControl/nls/es/resource.js new file mode 100644 index 000000000..f877b51f5 --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/nls/es/resource.js @@ -0,0 +1,14 @@ +define ({ + noLegend: 'Sin Leyenda', + moveUp: 'Ascender', + moveDown: 'Mover hacia abajo', + zoomTo: 'Amplía a Capa', + transparency: 'Transparencia', + metadata: 'Metadatos', + layerSwipe: 'Flagelo capa', + layerSwipeVertical: 'Vertical', + layerSwipeHorizontal: 'Horizontal', + layerSwipeScope: 'Alcance', + dynamicSublayersOn: 'Abra todas las subcapas', + dynamicSublayersOff: 'Apagar todas las subcapas' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/nls/fr/resource.js b/viewer/js/gis/dijit/LayerControl/nls/fr/resource.js new file mode 100644 index 000000000..fa134d775 --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/nls/fr/resource.js @@ -0,0 +1,14 @@ +define ({ + noLegend: 'No Légende', + moveUp: 'Déplacer vers le haut', + moveDown: 'Descendre', + zoomTo: 'Zoom sur la couche', + transparency: 'Transparence', + metadata: 'Métadonnées', + layerSwipe: 'Couche swipe', + layerSwipeVertical: 'Verticale', + layerSwipeHorizontal: 'Horizontal', + layerSwipeScope: 'Microscope', + dynamicSublayersOn: 'Activer tous les sous-couches', + dynamicSublayersOff: 'Éteignez tous les sous-couches' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/nls/pt-br/resource.js b/viewer/js/gis/dijit/LayerControl/nls/pt-br/resource.js new file mode 100644 index 000000000..612db0653 --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/nls/pt-br/resource.js @@ -0,0 +1,21 @@ +// internationalization for LayerControl +// +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +// +// if you would like to add a locale please create an issue at +// https://github.com/cmv/cmv-app/issues and someone will assist +// if need be or checkout the link above and submit a PR +define({ + noLegend: 'Sem Legenda', + moveUp: 'Mover para Cima', + moveDown: 'Mover para Baixo', + zoomTo: 'Zoom para a Camada', + transparency: 'Transparência', + metadata: 'Metadados', + layerSwipe: 'Cortina de Camada', + layerSwipeVertical: 'Vertical', + layerSwipeHorizontal: 'Horizontal', + layerSwipeScope: 'Escopo', + dynamicSublayersOn: 'Liga todas Subcamadas', + dynamicSublayersOff: 'Desliga todas Subcamadas' +}); diff --git a/viewer/js/gis/dijit/LayerControl/nls/resource.js b/viewer/js/gis/dijit/LayerControl/nls/resource.js index cc3ee742b..c371d3507 100644 --- a/viewer/js/gis/dijit/LayerControl/nls/resource.js +++ b/viewer/js/gis/dijit/LayerControl/nls/resource.js @@ -20,5 +20,8 @@ define({ dynamicSublayersOn: 'Turn On All Sublayers', dynamicSublayersOff: 'Turn Off All Sublayers' }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); diff --git a/viewer/js/gis/dijit/Print/nls/es/resource.js b/viewer/js/gis/dijit/Print/nls/es/resource.js new file mode 100644 index 000000000..a11fa0e2b --- /dev/null +++ b/viewer/js/gis/dijit/Print/nls/es/resource.js @@ -0,0 +1,39 @@ +define ({ + title: 'Título', + format: 'Formato', + layout: 'Diseño', + settings: 'Ajustes', + mapScaleExtent: 'Escala/Extensión de mapa', + preserve: 'Preservar', + mapScale: 'escala del mapa', + mapExtent: 'extensión de mapa', + fullLayoutOptions: 'Opciones de diseño completos', + scaleBarUnits: 'Unidades barra de escala', + miles: 'Millas', + kilometers: 'Kilómetros', + meters: 'Metros', + feet: 'Pies', + includeLegend: 'Incluir la leyenda', + printQualityOptions: 'Opciones de calidad de impresión', + dpiInput: { + label: 'DPI', + invalidMessage: 'Por favor, introduzca un valor numérico.', + rangeMessage: 'Por favor, introduzca un valor entre 100 y 300.' + }, + mapOnlyOptions: 'Opciones MAP_ONLY', + width: 'Anchura', + height: 'Altura', + printButton: { + busyLabel: 'imprenta', + label: 'Impresión' + }, + clearHistoryButton: { + label: 'Despejar el historial de impresión' + }, + printResults: { + progressBar: { + label: 'Creación de impresión' + }, + errorMessage: 'Error, inténtalo de nuevo' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Print/nls/fr/resource.js b/viewer/js/gis/dijit/Print/nls/fr/resource.js new file mode 100644 index 000000000..6749eacd2 --- /dev/null +++ b/viewer/js/gis/dijit/Print/nls/fr/resource.js @@ -0,0 +1,39 @@ +define ({ + title: 'Titre', + format: 'Format', + layout: 'Disposition', + settings: 'Paramètres', + mapScaleExtent: 'échelle/mesure de la carte', + preserve: 'Préserver', + mapScale: 'échelle de la carte', + mapExtent: 'étendue de la carte', + fullLayoutOptions: 'Full options de mise en page', + scaleBarUnits: 'unités de barre d\'échelle', + miles: 'Miles', + kilometers: 'Kilomètres', + meters: 'Mètres', + feet: 'Pieds', + includeLegend: 'Inclure la légende', + printQualityOptions: 'les options de qualité d`impression', + dpiInput: { + label: 'DPI', + invalidMessage: 'S'il vous plaît entrer une valeur numérique.', + rangeMessage: 'S'il vous plaît entrer une valeur entre 100 et 300.' + }, + mapOnlyOptions: 'Options MAP_ONLY', + width: 'Largeur', + height: 'La taille', + printButton: { + busyLabel: 'impression', + label: 'Imprimer' + }, + clearHistoryButton: { + label: 'Effacer l\'historique d`impression' + }, + printResults: { + progressBar: { + label: 'Création Imprimer' + }, + errorMessage: 'Erreur, réessayez' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Print/nls/pt-br/resource.js b/viewer/js/gis/dijit/Print/nls/pt-br/resource.js new file mode 100644 index 000000000..dbb30c663 --- /dev/null +++ b/viewer/js/gis/dijit/Print/nls/pt-br/resource.js @@ -0,0 +1,40 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + title: 'Título', + format: 'Formato', + layout: 'Modelo', + settings: 'Configurações', + mapScaleExtent: 'Escala/Extensão do Mapa', + preserve: 'Preservar', + mapScale: 'Escala do mapa', + mapExtent: 'Extensão do mapa', + fullLayoutOptions: 'Opções de Modelo Completa', + scaleBarUnits: 'Unidades da barra de escala', + miles: 'Milhas', + kilometers: 'Quilômetros', + meters: 'Metros', + feet: 'Pés', + includeLegend: 'Incluir Legenda', + printQualityOptions: 'Opções da qualidade de Impressão', + dpiInput: { + label: 'DPI', + invalidMessage: 'Por favor entre um valor numérico.', + rangeMessage: 'Por favor entre um valor entre 100 e 300.' + }, + mapOnlyOptions: 'opções MAP_ONLY', + width: 'Largura', + height: 'Altura', + printButton: { + busyLabel: 'imprimindo', + label: 'Imprimir' + }, + clearHistoryButton: { + label: 'Limpar histórico de impressão' + }, + printResults: { + progressBar: { + label: 'Criando impressão' + }, + errorMessage: 'Erro, tente novamente' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Print/nls/resource.js b/viewer/js/gis/dijit/Print/nls/resource.js index 10662266c..3af6b5a74 100644 --- a/viewer/js/gis/dijit/Print/nls/resource.js +++ b/viewer/js/gis/dijit/Print/nls/resource.js @@ -39,6 +39,9 @@ define({ errorMessage: 'Error, try again' } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); diff --git a/viewer/js/gis/dijit/StreetView/nls/es/resource.js b/viewer/js/gis/dijit/StreetView/nls/es/resource.js new file mode 100644 index 000000000..2318abc5e --- /dev/null +++ b/viewer/js/gis/dijit/StreetView/nls/es/resource.js @@ -0,0 +1,9 @@ +define ({ + messages: { + instructions: 'Haga clic en el botón de StreetView a continuación, haga clic en el mapa en su posición deseada.', + notAvailable: 'Desafortunadamente, Google StreetView todavía no está disponible en ese lugar.' + }, + rightClickMenuItem: { + label: 'Google StreetView aquí' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/StreetView/nls/fr/resource.js b/viewer/js/gis/dijit/StreetView/nls/fr/resource.js new file mode 100644 index 000000000..5ff15ec7c --- /dev/null +++ b/viewer/js/gis/dijit/StreetView/nls/fr/resource.js @@ -0,0 +1,9 @@ +define ({ + messages: { + instructions: 'Cliquez sur le bouton StreetView puis cliquez sur la carte à l\'endroit désiré.', + notAvailable: 'Malheureusement, les images de Google StreetView est pas encore disponible à cet endroit.' + }, + rightClickMenuItem: { + label: 'Google StreetView ici' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/StreetView/nls/pt-br/resource.js b/viewer/js/gis/dijit/StreetView/nls/pt-br/resource.js new file mode 100644 index 000000000..6e9f7e049 --- /dev/null +++ b/viewer/js/gis/dijit/StreetView/nls/pt-br/resource.js @@ -0,0 +1,10 @@ +// http://dojotoolkit.org/reference-guide/1.10/dojo/i18n.html +define({ + messages: { + instructions: 'Clique no botão do StreetView e depois clique na localização desejada no mapa.', + notAvailable: 'Infelizmente, o Google Street View não está disponível nesta localização.' + }, + rightClickMenuItem: { + label: 'Street View aqui' + } +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/StreetView/nls/resource.js b/viewer/js/gis/dijit/StreetView/nls/resource.js index 600588984..6e80605ca 100644 --- a/viewer/js/gis/dijit/StreetView/nls/resource.js +++ b/viewer/js/gis/dijit/StreetView/nls/resource.js @@ -9,6 +9,9 @@ define({ label: 'Google StreetView here' } }, + 'es': true, + 'fr': true, + 'pt-br': true, 'pt-pt': true }); From ea1d486324207f5cd62a36268bcc81452062be0d Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 6 Aug 2016 17:06:26 -0700 Subject: [PATCH 117/216] fix formatting issue in Print widget settings popup. --- viewer/js/gis/dijit/Print/templates/Print.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/js/gis/dijit/Print/templates/Print.html b/viewer/js/gis/dijit/Print/templates/Print.html index 28d754273..c8ed5cdab 100644 --- a/viewer/js/gis/dijit/Print/templates/Print.html +++ b/viewer/js/gis/dijit/Print/templates/Print.html @@ -42,12 +42,12 @@
- From 6ee0cc67bea165dc7fd7c1010b07560cc6c4fb6f Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 6 Aug 2016 17:40:50 -0700 Subject: [PATCH 118/216] Add new `Locale` widget which enables switching locales within an application. --- README.md | 1 + viewer/index.html | 3 + viewer/js/config/nls/es/main.js | 1 + viewer/js/config/nls/fr/main.js | 1 + viewer/js/config/nls/main.js | 1 + viewer/js/config/nls/pt-br/main.js | 1 + viewer/js/config/nls/pt-pt/main.js | 1 + viewer/js/config/viewer.js | 14 + viewer/js/gis/dijit/Locale.js | 187 +++++++++++++ viewer/js/gis/dijit/Locale/countries.js | 247 ++++++++++++++++++ viewer/js/gis/dijit/Locale/css/Locale.css | 14 + viewer/js/gis/dijit/Locale/nls/es/resource.js | 3 + viewer/js/gis/dijit/Locale/nls/fr/resource.js | 3 + .../js/gis/dijit/Locale/nls/pt-br/resource.js | 3 + .../js/gis/dijit/Locale/nls/pt-pt/resource.js | 3 + viewer/js/gis/dijit/Locale/nls/resource.js | 9 + .../js/gis/dijit/Locale/templates/Locale.html | 6 + 17 files changed, 498 insertions(+) create mode 100644 viewer/js/gis/dijit/Locale.js create mode 100644 viewer/js/gis/dijit/Locale/countries.js create mode 100644 viewer/js/gis/dijit/Locale/css/Locale.css create mode 100644 viewer/js/gis/dijit/Locale/nls/es/resource.js create mode 100644 viewer/js/gis/dijit/Locale/nls/fr/resource.js create mode 100644 viewer/js/gis/dijit/Locale/nls/pt-br/resource.js create mode 100644 viewer/js/gis/dijit/Locale/nls/pt-pt/resource.js create mode 100644 viewer/js/gis/dijit/Locale/nls/resource.js create mode 100644 viewer/js/gis/dijit/Locale/templates/Locale.html diff --git a/README.md b/README.md index 50c57c03e..d3b1fb678 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ This JavaScript web app can be easily configured or used as a boilerplate/starti - Identify - Layer Control (Table of Contents) - Legend +- Locale (Change the Country + Language) - Locate Button (Geolocation) - MapInfo - Measure diff --git a/viewer/index.html b/viewer/index.html index 2b2020236..0aa25b974 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -39,7 +39,10 @@ diff --git a/viewer/js/config/nls/es/main.js b/viewer/js/config/nls/es/main.js index 75d390710..67aff1d08 100644 --- a/viewer/js/config/nls/es/main.js +++ b/viewer/js/config/nls/es/main.js @@ -56,6 +56,7 @@ define({ measure: 'Medición', layerControl: 'Capas', legend: 'Leyenda', + locale: 'Lugar', print: 'Imprimir', streetview: 'Google Street View' } diff --git a/viewer/js/config/nls/fr/main.js b/viewer/js/config/nls/fr/main.js index 3dab3a222..1126dc252 100644 --- a/viewer/js/config/nls/fr/main.js +++ b/viewer/js/config/nls/fr/main.js @@ -55,6 +55,7 @@ define({ measure: 'Mesures', layerControl: 'Couches d\'information', legend: 'Légende', + locale: 'Lieu', print: 'Impression', streetview: 'Google Street View' } diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index 0e3df38df..d2f8d304f 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -56,6 +56,7 @@ define({ measure: 'Measurement', layerControl: 'Layers', legend: 'Legend', + locale: 'Locale', print: 'Print', streetview: 'Google Street View' } diff --git a/viewer/js/config/nls/pt-br/main.js b/viewer/js/config/nls/pt-br/main.js index 27b6d6ffb..35d3e4682 100644 --- a/viewer/js/config/nls/pt-br/main.js +++ b/viewer/js/config/nls/pt-br/main.js @@ -55,6 +55,7 @@ define({ measure: 'Medir', layerControl: 'Camadas', legend: 'Legendas', + locale: 'Localidade', print: 'Imprimir', streetview: 'Google Street View' } diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index 27b6d6ffb..35d3e4682 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -55,6 +55,7 @@ define({ measure: 'Medir', layerControl: 'Camadas', legend: 'Legendas', + locale: 'Localidade', print: 'Imprimir', streetview: 'Google Street View' } diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 5e22c8fcf..6cde92d8b 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -530,6 +530,20 @@ define([ mapRightClickMenu: true } }, + locale: { + include: true, + id: 'locale', + //type: 'titlePane', + //position: 0, + //open: true, + type: 'domNode', + srcNodeRef: 'geocodeDijit', + path: 'gis/dijit/Locale', + title: i18n.viewer.widgets.locale, + options: { + style: 'margin-left: 30px;' + } + }, help: { include: true, id: 'help', diff --git a/viewer/js/gis/dijit/Locale.js b/viewer/js/gis/dijit/Locale.js new file mode 100644 index 000000000..a7b532b9b --- /dev/null +++ b/viewer/js/gis/dijit/Locale.js @@ -0,0 +1,187 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + + 'dojo/_base/lang', + 'dojo/on', + 'dojo/dom-style', + 'dojo/_base/array', + 'dojo/_base/kernel', + 'dojo/io-query', + + 'dijit/form/DropDownButton', + 'dijit/DropDownMenu', + 'dijit/MenuItem', + + './Locale/countries', + + 'dojo/text!./Locale/templates/Locale.html', + 'dojo/i18n!./Locale/nls/resource', + + 'xstyle/css!https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1/css/flag-icon.min.css', + 'xstyle/css!./Locale/css/Locale.css' +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + + lang, + on, + domStyle, + array, + kernel, + ioQuery, + + DropDownButton, + DropDownMenu, + MenuItem, + + countries, + + template, + i18n +) { + + return declare([_WidgetBase, _TemplatedMixin], { + templateString: template, + i18n: i18n, + baseClass: 'cmvLocaleDijit', + + currentLocale: null, + + includeFlag: true, + includeCountry: true, + includeLanguage: true, + + languages: { + 'en': 'English', + 'es': 'Español', + 'fr': 'Français', + 'pt': 'Português' + }, + + locales: [ + 'es-ar', + 'es-bo', + 'pt-br', + 'en-ca', + 'fr-ca', + 'es-cl', + 'es-co', + 'es-cr', + 'es-do', + 'es-ec', + 'es-sv', + 'fr-FR', + 'es-gt', + 'fr-ht', + 'es-hn', + 'en-in', + 'es-mx', + 'es-pa', + 'es-pe', + 'es-pr', + 'pt-pt', + 'es-py', + 'es-es', + 'en-gb', + 'en-us', + 'es-us', + 'es-uy', + 'es-ve' + ], + + postCreate: function () { + this.inherited(arguments); + + this.currentLocale = kernel.locale; + + if (this.parentWidget) { + if (this.parentWidget.toggleable) { + domStyle.set(this.localeLabelContainer, 'display', 'block'); + } + } + + var menu = new DropDownMenu({ + baseClass: 'localeMenu' + }); + + array.forEach(this.locales, lang.hitch(this, function (locale) { + var vals = locale.split('-'); + + // only include supported languages + var language = this.languages[vals[0]]; + if (language) { + var label = '', country = null, icon = null; + if (vals[1]) { + if (this.includeFlag) { + icon = 'flag-icon flag-icon-' + vals[1].toLowerCase(); + } + country = countries[vals[1].toUpperCase()]; + if (country && this.includeCountry) { + label = country; + } + } + if (this.includeLanguage) { + if (label.length > 0) { + label += ' - '; + } + label += language; + } + var menuItem = new MenuItem({ + id: locale, + label: label, + iconClass: icon, + onClick: lang.hitch(this, 'switchLocale', locale) + }); + menu.addChild(menuItem); + } + })); + menu.startup(); + + var vals = this.currentLocale.split('-'); + var language = this.languages[vals[0]]; + var label = '', country = null; + if (vals[1]) { + if (this.includeFlag) { + label = '
'; + } + country = countries[vals[1].toUpperCase()]; + if (country && this.includeCountry) { + label += country; + } + if (this.includeLanguage) { + if (country && this.includeCountry) { + label += ' - '; + } + label += language; + } + } + + var button = new DropDownButton({ + label: label, + dropDown: menu + }); + + this.localeDropDownContainer.appendChild(button.domNode); + }, + + switchLocale: function (newLocale) { + if (newLocale !== this.currentLocale) { + var uri = window.location.href, qsObj = {}; + if (uri.indexOf('?') > -1) { + var qs = uri.substring(uri.indexOf('?') + 1, uri.length); + qsObj = ioQuery.queryToObject(qs); + } + + // set the new locale + qsObj.locale = newLocale; + + // reload the page + window.location = window.location.pathname + '?' + ioQuery.objectToQuery(qsObj); + + } + } + }); +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Locale/countries.js b/viewer/js/gis/dijit/Locale/countries.js new file mode 100644 index 000000000..2313b1ee2 --- /dev/null +++ b/viewer/js/gis/dijit/Locale/countries.js @@ -0,0 +1,247 @@ +define ({ + 'AF': 'Afghanistan', + 'AX': 'Åland Islands', + 'AL': 'Albania', + 'DZ': 'Algeria', + 'AS': 'American Samoa', + 'AD': 'Andorra', + 'AO': 'Angola', + 'AI': 'Anguilla', + 'AQ': 'Antarctica', + 'AG': 'Antigua and Barbuda', + 'AR': 'Argentina', + 'AM': 'Armenia', + 'AW': 'Aruba', + 'AU': 'Australia', + 'AT': 'Austria', + 'AZ': 'Azerbaijan', + 'BS': 'Bahamas', + 'BH': 'Bahrain', + 'BD': 'Bangladesh', + 'BB': 'Barbados', + 'BY': 'Belarus', + 'BE': 'Belgium', + 'BZ': 'Belize', + 'BJ': 'Benin', + 'BM': 'Bermuda', + 'BT': 'Bhutan', + 'BO': 'Bolivia', + 'BA': 'Bosnia and Herzegovina', + 'BW': 'Botswana', + 'BV': 'Bouvet Island', + 'BR': 'Brazil', + 'IO': 'British Indian Ocean Territory', + 'BN': 'Brunei Darussalam', + 'BG': 'Bulgaria', + 'BF': 'Burkina Faso', + 'BI': 'Burundi', + 'KH': 'Cambodia', + 'CM': 'Cameroon', + 'CA': 'Canada', + 'CV': 'Cape Verde', + 'KY': 'Cayman Islands', + 'CF': 'Central African Republic', + 'TD': 'Chad', + 'CL': 'Chile', + 'CN': 'China', + 'CX': 'Christmas Island', + 'CC': 'Cocos (Keeling) Islands', + 'CO': 'Colombia', + 'KM': 'Comoros', + 'CG': 'Congo', + 'CD': 'Congo, The Democratic Republic of the', + 'CK': 'Cook Islands', + 'CR': 'Costa Rica', + 'CI': 'Cote D\'Ivoire', + 'HR': 'Croatia', + 'CU': 'Cuba', + 'CY': 'Cyprus', + 'CZ': 'Czech Republic', + 'DK': 'Denmark', + 'DJ': 'Djibouti', + 'DM': 'Dominica', + 'DO': 'Dominican Republic', + 'EC': 'Ecuador', + 'EG': 'Egypt', + 'SV': 'El Salvador', + 'GQ': 'Equatorial Guinea', + 'ER': 'Eritrea', + 'EE': 'Estonia', + 'ET': 'Ethiopia', + 'FK': 'Falkland Islands (Malvinas)', + 'FO': 'Faroe Islands', + 'FJ': 'Fiji', + 'FI': 'Finland', + 'FR': 'France', + 'GF': 'French Guiana', + 'PF': 'French Polynesia', + 'TF': 'French Southern Territories', + 'GA': 'Gabon', + 'GM': 'Gambia', + 'GE': 'Georgia', + 'DE': 'Germany', + 'GH': 'Ghana', + 'GI': 'Gibraltar', + 'GR': 'Greece', + 'GL': 'Greenland', + 'GD': 'Grenada', + 'GP': 'Guadeloupe', + 'GU': 'Guam', + 'GT': 'Guatemala', + 'GG': 'Guernsey', + 'GN': 'Guinea', + 'GW': 'Guinea-Bissau', + 'GY': 'Guyana', + 'HT': 'Haiti', + 'HM': 'Heard Island and Mcdonald Islands', + 'VA': 'Holy See (Vatican City State)', + 'HN': 'Honduras', + 'HK': 'Hong Kong', + 'HU': 'Hungary', + 'IS': 'Iceland', + 'IN': 'India', + 'ID': 'Indonesia', + 'IR': 'Iran, Islamic Republic Of', + 'IQ': 'Iraq', + 'IE': 'Ireland', + 'IM': 'Isle of Man', + 'IL': 'Israel', + 'IT': 'Italy', + 'JM': 'Jamaica', + 'JP': 'Japan', + 'JE': 'Jersey', + 'JO': 'Jordan', + 'KZ': 'Kazakhstan', + 'KE': 'Kenya', + 'KI': 'Kiribati', + 'KP': 'Democratic People\'s Republic of Korea', + 'KR': 'Korea, Republic of', + 'XK': 'Kosovo', + 'KW': 'Kuwait', + 'KG': 'Kyrgyzstan', + 'LA': 'Lao People\'s Democratic Republic', + 'LV': 'Latvia', + 'LB': 'Lebanon', + 'LS': 'Lesotho', + 'LR': 'Liberia', + 'LY': 'Libyan Arab Jamahiriya', + 'LI': 'Liechtenstein', + 'LT': 'Lithuania', + 'LU': 'Luxembourg', + 'MO': 'Macao', + 'MK': 'Macedonia, The Former Yugoslav Republic of', + 'MG': 'Madagascar', + 'MW': 'Malawi', + 'MY': 'Malaysia', + 'MV': 'Maldives', + 'ML': 'Mali', + 'MT': 'Malta', + 'MH': 'Marshall Islands', + 'MQ': 'Martinique', + 'MR': 'Mauritania', + 'MU': 'Mauritius', + 'YT': 'Mayotte', + 'MX': 'Mexico', + 'FM': 'Micronesia, Federated States of', + 'MD': 'Moldova, Republic of', + 'MC': 'Monaco', + 'MN': 'Mongolia', + 'ME': 'Montenegro', + 'MS': 'Montserrat', + 'MA': 'Morocco', + 'MZ': 'Mozambique', + 'MM': 'Myanmar', + 'NA': 'Namibia', + 'NR': 'Nauru', + 'NP': 'Nepal', + 'NL': 'Netherlands', + 'AN': 'Netherlands Antilles', + 'NC': 'New Caledonia', + 'NZ': 'New Zealand', + 'NI': 'Nicaragua', + 'NE': 'Niger', + 'NG': 'Nigeria', + 'NU': 'Niue', + 'NF': 'Norfolk Island', + 'MP': 'Northern Mariana Islands', + 'NO': 'Norway', + 'OM': 'Oman', + 'PK': 'Pakistan', + 'PW': 'Palau', + 'PS': 'Palestinian Territory, Occupied', + 'PA': 'Panama', + 'PG': 'Papua New Guinea', + 'PY': 'Paraguay', + 'PE': 'Peru', + 'PH': 'Philippines', + 'PN': 'Pitcairn', + 'PL': 'Poland', + 'PT': 'Portugal', + 'PR': 'Puerto Rico', + 'QA': 'Qatar', + 'RE': 'Reunion', + 'RO': 'Romania', + 'RU': 'Russian Federation', + 'RW': 'Rwanda', + 'SH': 'Saint Helena', + 'KN': 'Saint Kitts and Nevis', + 'LC': 'Saint Lucia', + 'PM': 'Saint Pierre and Miquelon', + 'VC': 'Saint Vincent and the Grenadines', + 'WS': 'Samoa', + 'SM': 'San Marino', + 'ST': 'Sao Tome and Principe', + 'SA': 'Saudi Arabia', + 'SN': 'Senegal', + 'RS': 'Serbia', + 'SC': 'Seychelles', + 'SL': 'Sierra Leone', + 'SG': 'Singapore', + 'SK': 'Slovakia', + 'SI': 'Slovenia', + 'SB': 'Solomon Islands', + 'SO': 'Somalia', + 'ZA': 'South Africa', + 'GS': 'South Georgia and the South Sandwich Islands', + 'ES': 'Spain', + 'LK': 'Sri Lanka', + 'SD': 'Sudan', + 'SR': 'Suriname', + 'SJ': 'Svalbard and Jan Mayen', + 'SZ': 'Swaziland', + 'SE': 'Sweden', + 'CH': 'Switzerland', + 'SY': 'Syrian Arab Republic', + 'TW': 'Taiwan', + 'TJ': 'Tajikistan', + 'TZ': 'Tanzania, United Republic of', + 'TH': 'Thailand', + 'TL': 'Timor-Leste', + 'TG': 'Togo', + 'TK': 'Tokelau', + 'TO': 'Tonga', + 'TT': 'Trinidad and Tobago', + 'TN': 'Tunisia', + 'TR': 'Turkey', + 'TM': 'Turkmenistan', + 'TC': 'Turks and Caicos Islands', + 'TV': 'Tuvalu', + 'UG': 'Uganda', + 'UA': 'Ukraine', + 'AE': 'United Arab Emirates', + 'GB': 'United Kingdom', + 'US': 'United States', + 'UM': 'United States Minor Outlying Islands', + 'UY': 'Uruguay', + 'UZ': 'Uzbekistan', + 'VU': 'Vanuatu', + 'VE': 'Venezuela', + 'VN': 'Viet Nam', + 'VG': 'Virgin Islands, British', + 'VI': 'Virgin Islands, U.S.', + 'WF': 'Wallis and Futuna', + 'EH': 'Western Sahara', + 'YE': 'Yemen', + 'ZM': 'Zambia', + 'ZW': 'Zimbabwe' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Locale/css/Locale.css b/viewer/js/gis/dijit/Locale/css/Locale.css new file mode 100644 index 000000000..295d669fc --- /dev/null +++ b/viewer/js/gis/dijit/Locale/css/Locale.css @@ -0,0 +1,14 @@ +.cmvLocaleDijit label { + font-weight: bold; +} +.flag-icon { + width: 20px; + height: 15px; + margin-right: 5px; + margin-top: -1px; + border: 1px solid #DDD; +} + +.localeMenuPopup { + max-height: 300px; +} \ No newline at end of file diff --git a/viewer/js/gis/dijit/Locale/nls/es/resource.js b/viewer/js/gis/dijit/Locale/nls/es/resource.js new file mode 100644 index 000000000..ca3c987cb --- /dev/null +++ b/viewer/js/gis/dijit/Locale/nls/es/resource.js @@ -0,0 +1,3 @@ +define ({ + selectLocale: 'Seleccione su Lugar:' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Locale/nls/fr/resource.js b/viewer/js/gis/dijit/Locale/nls/fr/resource.js new file mode 100644 index 000000000..5689537fb --- /dev/null +++ b/viewer/js/gis/dijit/Locale/nls/fr/resource.js @@ -0,0 +1,3 @@ +define ({ + selectLocale: 'Sélectionnez votre lieu:' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Locale/nls/pt-br/resource.js b/viewer/js/gis/dijit/Locale/nls/pt-br/resource.js new file mode 100644 index 000000000..eac84670c --- /dev/null +++ b/viewer/js/gis/dijit/Locale/nls/pt-br/resource.js @@ -0,0 +1,3 @@ +define ({ + selectLocale: 'Escolha a sua localidade:' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Locale/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Locale/nls/pt-pt/resource.js new file mode 100644 index 000000000..eac84670c --- /dev/null +++ b/viewer/js/gis/dijit/Locale/nls/pt-pt/resource.js @@ -0,0 +1,3 @@ +define ({ + selectLocale: 'Escolha a sua localidade:' +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Locale/nls/resource.js b/viewer/js/gis/dijit/Locale/nls/resource.js new file mode 100644 index 000000000..239076ecf --- /dev/null +++ b/viewer/js/gis/dijit/Locale/nls/resource.js @@ -0,0 +1,9 @@ +define ({ + root: { + selectLocale: 'Select Your Locale:' + }, + 'es': true, + 'fr': true, + 'pt-br': true, + 'pt-pt': true +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/Locale/templates/Locale.html b/viewer/js/gis/dijit/Locale/templates/Locale.html new file mode 100644 index 000000000..e07a68851 --- /dev/null +++ b/viewer/js/gis/dijit/Locale/templates/Locale.html @@ -0,0 +1,6 @@ +
+
+ +
+
+
\ No newline at end of file From a5d77aac543ec34265906d67a5f69ac211c64947 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 9 Sep 2016 19:34:54 -0700 Subject: [PATCH 119/216] add flat theme --- viewer/css/theme/flat/flat.css | 1 + viewer/css/theme/flat/fonts/flat-icon.eot | Bin 0 -> 13608 bytes viewer/css/theme/flat/fonts/flat-icon.svg | 122 ++++++++++++++++++ viewer/css/theme/flat/fonts/flat-icon.ttf | Bin 0 -> 13436 bytes viewer/css/theme/flat/fonts/flat-icon.woff | Bin 0 -> 13512 bytes .../theme/flat/images/loadingAnimation.gif | Bin 0 -> 631 bytes .../theme/flat/images/progressBarStrips.png | Bin 0 -> 1280 bytes 7 files changed, 123 insertions(+) create mode 100644 viewer/css/theme/flat/flat.css create mode 100644 viewer/css/theme/flat/fonts/flat-icon.eot create mode 100644 viewer/css/theme/flat/fonts/flat-icon.svg create mode 100644 viewer/css/theme/flat/fonts/flat-icon.ttf create mode 100644 viewer/css/theme/flat/fonts/flat-icon.woff create mode 100644 viewer/css/theme/flat/images/loadingAnimation.gif create mode 100644 viewer/css/theme/flat/images/progressBarStrips.png diff --git a/viewer/css/theme/flat/flat.css b/viewer/css/theme/flat/flat.css new file mode 100644 index 000000000..99e67f488 --- /dev/null +++ b/viewer/css/theme/flat/flat.css @@ -0,0 +1 @@ +.dj_ie .dijitButtonNode,.dj_ie .dijitSliderRtl .dijitRuleLabelH,.dj_ie6 .dijitTabContainerLeft-tabs .dijitTabRtl,.dj_ie6 .dijitTabContainerRight-tabs .dijitTabRtl,.dj_ie6 .dijitTabRtl .tabLabel,.dj_ie6 .dijitTitlePane .dijitTitlePaneTitle,.dj_ie6 .dijitTitlePaneContentOuter,.dj_ie7 .dijitTabContainerLeft-tabs .dijitTabRtl,.dj_ie7 .dijitTabContainerRight-tabs .dijitTabRtl{zoom:1}.dijitBorderContainer>.dijitTextArea,.dijitExpandingTextArea{resize:none}.dijitReset{margin:0;border:0;padding:0;font:inherit;color:inherit}.dj_a11y .dijitReset{-moz-appearance:none}.dijitInline{display:inline-block;#zoom:1;#display:inline;border:0;padding:0;vertical-align:middle;#vertical-align:auto}table.dijitInline{display:inline-table;box-sizing:content-box;-moz-box-sizing:content-box}.dijitHidden{display:none!important}.dijitVisible{display:block!important;position:relative}.dijitInputContainer,.dj_ie6 .dijitComboBox .dijitInputContainer{#zoom:1;overflow:hidden;float:none!important;position:relative}.dj_ie7 .dijitInputContainer{float:left!important;clear:left;display:inline-block!important}.dj_ie .dijitSelect input,.dj_ie .dijitTextBox input,.dj_ie input.dijitTextBox{font-size:100%}.dijitSelect .dijitButtonText{float:left;vertical-align:top}TABLE.dijitSelect{padding:0!important}.dijitTextBox .dijitArrowButtonContainer,.dijitTextBox .dijitSpinnerButtonContainer,.dijitValidationTextBox .dijitValidationContainer{float:right;text-align:center}.dijitSelect input.dijitInputField,.dijitTextBox input.dijitInputField{padding-left:0!important;padding-right:0!important}.dijitValidationTextBox .dijitValidationContainer{display:none}.dijitTeeny{font-size:1px;line-height:1px}.dijitOffScreen{position:absolute!important;left:50%!important;top:-10000px!important}.dijitPopup{position:absolute;background-color:transparent;margin:0;border:0;padding:0}.dijitPositionOnly{padding:0!important;border:0!important;background-color:transparent!important;background-image:none!important;height:auto!important;width:auto!important}.dijitNonPositionOnly{float:none!important;position:static!important;margin:0!important;vertical-align:middle!important}.dijitButtonNode,.dijitButtonNode *,.dijitButtonNode img,.dijitTextBox,.dj_ie .dijitToolbar .dijitComboBox{vertical-align:middle}.dijitBackgroundIframe{position:absolute;left:0;top:0;width:100%;height:100%;z-index:-1;border:0;padding:0;margin:0}.dijitDisplayNone{display:none!important}.dijitContainer{overflow:hidden}.dj_a11y .dijitCalendarIncrementControl,.dj_a11y .dijitIcon,.dj_a11y .dijitTreeExpando,.dj_a11y div.dijitArrowButtonInner,.dj_a11y img.dijitArrowButtonInner,.dj_a11y span.dijitArrowButtonInner{display:none}.dijitSpinner div.dijitArrowButtonInner{display:block}.dj_a11y .dijitA11ySideArrow{display:inline!important;cursor:pointer}.dj_a11y .dijitCalendarDateLabel{padding:1px;border:0!important}.dj_a11y .dijitCalendarSelectedDate .dijitCalendarDateLabel{border-style:solid!important;border-width:1px!important;padding:0}.dj_a11y .dijitCalendarDateTemplate{padding-bottom:.1em!important;border:0!important}.dj_a11y .dijitButtonNode{border:outset #000!important;padding:0!important}.dj_a11y .dijitArrowButton{padding:0!important}.dj_a11y .dijitButtonContents{margin:.15em}.dj_a11y .dijitTextBoxReadOnly .dijitButtonNode,.dj_a11y .dijitTextBoxReadOnly .dijitInputField{border-style:outset!important;border-width:medium!important;border-color:#999!important;color:#999!important}.dijitButtonNode,.dijitSelect{border:1px solid gray}.dijitButtonNode .dijitArrowButtonInner,.dijitSelect .dijitArrowButtonInner{background:center no-repeat;direction:ltr}.dijitLeft{background-position:left top;background-repeat:no-repeat}.dijitStretch{white-space:nowrap;background-repeat:repeat-x}.dijitRight{#display:inline;background-position:right top;background-repeat:no-repeat}.dj_gecko .dj_a11y .dijitButtonDisabled .dijitButtonNode{opacity:.5}.dijitButton,.dijitComboButton,.dijitDropDownButton,.dijitToggleButton{margin:.2em;vertical-align:middle}.dijitButtonContents{display:block}td.dijitButtonContents{display:table-cell}.dijitToolbar .dijitComboButton{border-collapse:separate}.dijitToolbar .dijitButton,.dijitToolbar .dijitComboButton,.dijitToolbar .dijitDropDownButton,.dijitToolbar .dijitToggleButton{margin:0}.dijitToolbar .dijitButtonContents{padding:1px 2px}.dj_gecko .dijitToolbar .dijitButtonNode::-moz-focus-inner{padding:0}.dijitButtonNode{margin:0;line-height:20px;#vertical-align:auto;text-align:center;white-space:nowrap}.dj_webkit .dijitSpinner .dijitSpinnerButtonContainer{line-height:inherit}.dijitTextBox .dijitButtonNode{border-width:0}.dijitButtonNode,.dijitButtonNode *,.dijitSelect,.dijitSelect *{cursor:pointer}.dj_ie .dijitButtonNode button{overflow:visible}div.dijitArrowButton{float:right}.dijitTextBox{border:1px solid #000;#overflow:hidden;width:15em}.dijitTextBoxDisabled,.dijitTextBoxReadOnly{color:gray}.dj_safari .dijitTextBoxDisabled input{color:#B0B0B0}.dj_safari textarea.dijitTextAreaDisabled{color:#333}.dj_gecko .dijitTextBoxDisabled input,.dj_gecko .dijitTextBoxReadOnly input.dijitInputField{-moz-user-input:none}.dijitPlaceHolder{color:#999;position:absolute;top:0;left:0;#filter:""}.dijitTimeTextBox{width:8em}.dijitTextBox input:focus{outline:0}.dijitTextBoxFocused{outline:-webkit-focus-ring-color 5px}.dijitSelect input,.dijitTextBox input{float:left}.dj_ie6 .dijitTextBox input,.dj_ie6 input.dijitTextBox{float:none}.dijitInputInner{border:0!important;background-color:transparent!important;width:100%!important;box-shadow:none!important;padding-left:0!important;padding-right:0!important;margin-left:0!important;margin-right:0!important}.dj_a11y .dijitTextBox input{margin:0!important}.dijitSelect input,.dijitTextBox input.dijitArrowButtonInner,.dijitValidationTextBoxError input.dijitValidationInner{text-indent:-2em!important;direction:ltr!important;text-align:left!important;#text-indent:0!important;#letter-spacing:-5em!important;#text-align:right!important}.dj_ie .dijitSelect input,.dj_ie .dijitTextBox input,.dj_ie input.dijitTextBox{overflow-y:visible;line-height:20px;height:20px}.dijitSelect .dijitSelectLabel span{line-height:100%}.dj_ie .dijitSelect .dijitSelectLabel{line-height:normal}.dijitSelect td,.dj_ie6 .dijitSelect .dijitSelectLabel,.dj_ie6 .dijitSelect .dijitValidationContainer,.dj_ie6 .dijitSelect input,.dj_ie6 .dijitTextBox input,.dj_ie6 input.dijitTextBox,.dj_ie7 .dijitSelect .dijitSelectLabel,.dj_ie8 .dijitSelect .dijitSelectLabel,.dj_iequirks .dijitSelect .dijitSelectLabel,.dj_iequirks .dijitSelect input,.dj_iequirks .dijitTextBox input.dijitArrowButtonInner,.dj_iequirks .dijitTextBox input.dijitInputInner,.dj_iequirks .dijitTextBox input.dijitSpinnerButtonInner,.dj_iequirks .dijitTextBox input.dijitValidationInner,.dj_iequirks input.dijitTextBox{line-height:100%}.dj_a11y input.dijitArrowButtonInner,.dj_a11y input.dijitValidationInner{text-indent:0!important;width:1em!important;text-align:left!important;color:#000!important}.dijitValidationTextBoxError .dijitValidationContainer{display:inline;cursor:default}.bootstrap .dijitSelect .dijitArrowButton,.dijitComboBox .dijitArrowButtonContainer,.dijitSpinner .dijitSpinnerButtonContainer{border-width:0 0 0 1px!important}.dijitToolbar .dijitComboBox .dijitArrowButtonContainer,.dj_a11y .dijitSelect .dijitArrowButtonContainer{border-width:0!important}.dijitComboBox .dijitButtonNode,.dijitSpinner .dijitSpinnerButtonContainer .dijitButtonNode,.dijitSpinnerButtonContainer .dijitButtonNode{border-width:0}.dijitComboBoxMenu{list-style-type:none}.dj_ie .dj_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitButtonNode{clear:both}.dijitTextBox .dijitSpinnerButtonContainer{width:1em;position:relative!important;overflow:hidden}.dijitSpinner .dijitSpinnerButtonInner{width:1em;visibility:hidden!important;overflow-x:hidden}.dj_a11y .dijitSpinnerButtonContainer .dijitButtonNode{border-width:0!important;border-style:solid!important}.dj_a11y .dijitSpinner .dijitArrowButtonInner,.dj_a11y .dijitSpinnerButtonContainer input,.dj_a11y .dijitTextBox .dijitSpinnerButtonContainer{width:1em!important}.dj_a11y .dijitSpinner .dijitArrowButtonInner{margin:0 auto!important}.dj_ie .dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField{padding-left:.3em!important;padding-right:.3em!important;margin-left:.3em!important;margin-right:.3em!important;width:1.4em!important}.dj_ie7 .dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField{padding-left:0!important;padding-right:0!important;width:1em!important}.dj_ie6 .dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField{margin-left:.1em!important;margin-right:.1em!important;width:1em!important}.dj_iequirks .dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField{margin-left:0!important;margin-right:0!important;width:2em!important}.dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton{padding:0;position:absolute!important;float:none;height:50%;width:100%;bottom:auto;left:0;right:auto}.dj_iequirks .dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton{width:auto}.dj_a11y .dijitSpinnerButtonContainer .dijitArrowButton{overflow:visible!important}.dijitSpinner .dijitSpinnerButtonContainer .dijitDownArrowButton{top:50%;border-top-width:1px!important}.dijitSpinner .dijitSpinnerButtonContainer .dijitUpArrowButton{#bottom:50%;top:0}.dijitSpinner .dijitArrowButtonInner{margin:auto;overflow-x:hidden}.dj_iequirks .dijitSpinner .dijitArrowButtonInner{height:auto!important}.dijitSpinner .dijitArrowButtonInner .dijitInputField{-moz-transform:scale(.5);-moz-transform-origin:center top;-webkit-transform:scale(.5);-webkit-transform-origin:center top;-o-transform:scale(.5);-o-transform-origin:center top;transform:scale(.5);transform-origin:left top;padding-top:0;padding-bottom:0;padding-left:0!important;padding-right:0!important;width:100%;visibility:hidden}.dj_ie .dijitSpinner .dijitArrowButtonInner .dijitInputField{display:none}.dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButtonInner{overflow:hidden}.dj_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton{width:100%}.dj_a11y .dijitSpinnerButtonContainer,.dj_iequirks .dj_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton{width:1em}.dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField{vertical-align:top;visibility:visible}.dijitCalendarIncrementControl,.dijitCheckedMenuItemIconChar,.dijitColorPalette .dijitPaletteCell,.dijitMenuItemLabel,.dijitSliderMoveable,.dijitTab *,.dijitTitlePaneTitle *,.dijitTreeRow img{vertical-align:middle}.dijitCheckBox,.dijitCheckBoxInput,.dijitRadio{padding:0;border:0;width:20px;height:20px;background-position:center center;background-repeat:no-repeat;overflow:hidden;cursor:pointer}.dijitCheckBox input,.dijitRadio input{margin:0;padding:0;display:block}.dijitCheckBoxInput{opacity:.01}.dj_ie .dijitCheckBoxInput{filter:alpha(opacity=0)}.dj_a11y .dijitCheckBox,.dj_a11y .dijitRadio{width:auto!important;height:auto!important}.dj_a11y .dijitCheckBoxInput{opacity:1;filter:none;width:auto;height:auto}.dj_a11y .dijitFocusedLabel{border:1px dotted;outline:0!important}.dijitProgressBar{z-index:0}.dijitProgressBarEmpty{position:relative;overflow:hidden;border:1px solid #000;z-index:0}.dijitProgressBarFull,.dijitProgressBarTile{position:absolute;overflow:hidden;top:0;width:100%}.dijitProgressBarFull{z-index:-1}.dj_ie6 .dijitProgressBarFull{height:1.6em}.dijitProgressBarTile{left:0;bottom:0;right:0;margin:0;padding:0;height:auto;background-color:#aaa}.dj_a11y .dijitProgressBarTile{border-width:2px;border-style:solid;background-color:transparent!important}.dj_ie6 .dijitProgressBarTile{position:static;height:1.6em}.dijitProgressBarIndeterminateHighContrastImage{display:none}.dj_a11y .dijitProgressBarIndeterminate .dijitProgressBarIndeterminateHighContrastImage{display:block;position:absolute;top:0;bottom:0;margin:0;padding:0;width:100%;height:auto}.dijitProgressBarLabel{display:block;position:static;width:100%;text-align:center;background-color:transparent!important}.dijitTooltip,.dijitTooltipConnector{position:absolute}.dijitTooltip{z-index:2000;display:block;left:0;top:-10000px;overflow:visible}.dijitTooltipContainer{border:2px solid #000;background:#b8b5b5;color:#000;font-size:small}.dijitTooltipFocusNode{padding:2px}.dijitTooltipData,.dj_a11y .dijitTooltipConnector{display:none}.dijitLayoutContainer{position:relative;display:block;overflow:hidden}.dijitAlignBottom,.dijitAlignLeft,.dijitAlignRight,.dijitAlignTop{position:absolute;overflow:hidden}body .dijitAlignClient{position:absolute}.dijitBorderContainer,.dijitBorderContainerNoGutter{position:relative;overflow:hidden;z-index:0}.dijitBorderContainerNoGutterPane,.dijitBorderContainerPane{position:absolute!important;z-index:2}.dijitGutter{position:absolute;font-size:1px}.dijitSplitter{position:absolute;overflow:hidden;z-index:10;background-color:#fff;border-color:gray;border-style:solid;border-width:0}.dj_ie .dijitSplitter{z-index:1}.dijitSplitterActive{z-index:11!important}.dijitSplitterCover{position:absolute;z-index:-1;top:0;left:0;width:100%;height:100%}.dijitSplitterCoverActive{z-index:3!important}.dj_ie .dijitSplitterCover{background:#fff;filter:alpha(opacity=0)}.dijitSplitterH{height:7px;border-top:1px;border-bottom:1px;cursor:row-resize}.dijitSplitContainerSizerH,.dijitSplitContainerVirtualSizerH,.dijitSplitterV{cursor:col-resize}.dijitSplitterV{width:7px;border-left:1px;border-right:1px}.dijitSplitContainer{position:relative;overflow:hidden;display:block}.dijitSplitPane{position:absolute}.dijitSplitContainerSizerH,.dijitSplitContainerSizerV{position:absolute;font-size:1px;background-color:ThreeDFace;border:1px solid;border-color:ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight;margin:0}.dijitSplitContainerSizerH .thumb,.dijitSplitterV .dijitSplitterThumb{overflow:hidden;position:absolute;top:49%}.dijitSplitContainerSizerV .thumb,.dijitSplitterH .dijitSplitterThumb{position:absolute;left:49%}.dijitSplitContainerVirtualSizerH,.dijitSplitContainerVirtualSizerV,.dijitSplitterShadow{font-size:1px;background-color:ThreeDShadow;-moz-opacity:.5;opacity:.5;filter:Alpha(Opacity=50);margin:0}.dijitSplitContainerSizerV,.dijitSplitContainerVirtualSizerV{cursor:row-resize}.dj_a11y .dijitSplitterH{border-top:1px solid #d3d3d3!important;border-bottom:1px solid #d3d3d3!important}.dj_a11y .dijitSplitterV{border-left:1px solid #d3d3d3!important;border-right:1px solid #d3d3d3!important}.dijitContentPane{display:block;overflow:auto}.dijitAccordionChildWrapper,.dijitContentPaneSingleChild,.dijitSpacer,.dijitTitlePane{overflow:hidden}.dijitContentPaneError .dijitIconError,.dijitContentPaneLoading .dijitIconLoading{margin-right:9px}.dijitTitlePane{display:block}.dijitFixedClosed .dijitArrowNode,.dijitFixedClosed .dijitArrowNodeInner,.dijitFixedOpen .dijitArrowNode,.dijitFixedOpen .dijitArrowNodeInner,.dijitTitlePane .dijitArrowNodeInner{display:none}.dijitTitlePaneTitle{cursor:pointer}.dijitFixedClosed,.dijitFixedOpen{cursor:default}.dj_a11y .dijitTitlePane .dijitArrowNodeInner{display:inline!important;font-family:monospace}.dijitAccordionTitle .arrowTextDown,.dijitAccordionTitle .arrowTextUp,.dj_a11y .dijitTitlePane .dijitArrowNode{display:none}.dijitColorPalette{border:1px solid #999;background:#fff;position:relative}.dijitColorPalette .dijitPaletteTable{padding:2px 3px 3px;position:relative;overflow:hidden;outline:0;border-collapse:separate}.dj_ie6 .dijitColorPalette .dijitPaletteTable,.dj_ie7 .dijitColorPalette .dijitPaletteTable,.dj_iequirks .dijitColorPalette .dijitPaletteTable{padding:0;margin:2px 3px 3px}.dijitColorPalette .dijitPaletteCell{font-size:1px;text-align:center;background:0 0}.dijitColorPalette .dijitPaletteImg{padding:1px;border:1px solid #999;margin:2px 1px;cursor:default;font-size:1px}.dj_gecko .dijitColorPalette .dijitPaletteImg{padding-bottom:0}.dijitColorPalette .dijitColorPaletteSwatch{width:14px;height:12px}.dijitPaletteTable td{padding:0}.dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg{border:1px solid #000}.dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg,.dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg{border:2px solid #000;margin:1px 0}.dj_a11y .dijitColorPalette .dijitPaletteTable,.dj_a11y .dijitColorPalette .dijitPaletteTable *{background-color:transparent!important}.dijitAccordionContainer{border:1px solid #b7b7b7;border-top:0!important}.dijitAccordionTitle{cursor:pointer}.dijitAccordionTitleSelected{cursor:default}.dj_a11y .dijitAccordionTitle .arrowTextUp,.dj_a11y .dijitAccordionTitleSelected .arrowTextDown{display:inline}.dijitMenuExpandA11y,.dj_a11y .dijitAccordionTitleSelected .arrowTextUp{display:none}.dijitCalendarContainer{width:auto}.dijitCalendarContainer td,.dijitCalendarContainer th{padding:1px 2px 2px;vertical-align:middle}.dijitCalendarYearLabel{white-space:nowrap}.dijitCalendarNextYear{margin:0 0 0 .55em}.dijitCalendarPreviousYear{margin:0 .55em 0 0}.dijitCalendarDateTemplate,.dijitCalendarIncrementControl,.dijitCalendarMonthLabel,.dijitCalendarNextYear,.dijitCalendarPreviousYear{cursor:pointer}.dijitCalendarDisabledDate{color:gray;text-decoration:line-through;cursor:default}.dijitSpacer{position:relative;height:1px;visibility:hidden}.dijitCalendarMonthMenu .dijitCalendarMonthLabel{text-align:center}.dijitMenu{border:1px solid #000;background-color:#fff}.dijitMenuTable{border-collapse:collapse;border-width:0;background-color:#fff}.dj_webkit .dijitMenuTable td[colspan="2"]{border-right:hidden}.dijitMenuItem{text-align:left;white-space:nowrap;padding:.1em .2em;cursor:pointer}.dijitMenuItemDisabled *,.dijitStackController .dijitToggleButtonChecked *{cursor:default}.dijitMenuItem:focus{outline:0}.dijitMenuItemSelected,.dijitMenuPassive .dijitMenuItemHover{background-color:#000;color:#fff}.dijitMenuExpand,.dijitMenuItemIcon{background-repeat:no-repeat}.dj_ie .dijitMenuItemDisabled *,.dj_ie .dj_a11y .dijitMenuItemDisabled,.dj_ie .dj_a11y .dijitMenuItemDisabled *{color:gray;filter:alpha(opacity=35)}.dijitMenuItemLabel{position:relative}.dj_a11y .dijitMenuItemSelected{border:1px dotted #000!important}.dj_a11y .dijitMenuItemSelected .dijitMenuItemLabel{border-width:1px;border-style:solid}.dj_ie8 .dj_a11y .dijitMenuItemLabel{position:static}.dj_a11y .dijitMenuExpandA11y{display:inline}.dijitMenuSeparator td{border:0;padding:0}.dijitMenuSeparatorTop{height:50%;margin:3px 0 0;font-size:1px}.dijitMenuSeparatorBottom{height:50%;margin:0 0 3px;font-size:1px}.dijitCheckedMenuItemIconChar{visibility:hidden}.dijitCheckedMenuItemChecked .dijitCheckedMenuItemIconChar{visibility:visible}.dj_a11y .dijitCheckedMenuItemIconChar{display:inline!important}.dj_a11y .dijitCheckedMenuItemIcon{display:none}.dj_ie .dj_a11y .dijitMenuBar .dijitMenuItem{margin:0}.dijitTabContainer{z-index:0;overflow:visible}.dj_ie6 .dijitTabContainer{overflow:hidden}.dijitTabContainerNoLayout{width:100%}.dijitTabContainerBottom-tabs,.dijitTabContainerLeft-tabs,.dijitTabContainerRight-tabs,.dijitTabContainerTop-tabs{z-index:1;overflow:visible!important}.dijitTabController{z-index:1}.dijitTabContainerBottom-container,.dijitTabContainerLeft-container,.dijitTabContainerRight-container,.dijitTabContainerTop-container{z-index:0;overflow:hidden;border:1px solid #000}.nowrapTabStrip{width:50000px;display:block;position:relative;text-align:left;z-index:1}.dijitTabListWrapper{overflow:hidden;z-index:1}.dj_a11y .tabStripButton img{display:none}.dijitTabContainerTop-tabs{border-bottom:1px solid #000}.dijitTabContainerTop-container{border-top:0}.dijitTabContainerLeft-tabs{border-right:1px solid #000;float:left}.dijitTabContainerLeft-container{border-left:0}.dijitTabContainerBottom-tabs{border-top:1px solid #000}.dijitTabContainerBottom-container{border-bottom:0}.dijitTabContainerRight-tabs{border-left:1px solid #000;float:left}.dijitTabContainerRight-container{border-right:0}.dj_ie div.dijitTabDisabled,div.dijitTabDisabled{cursor:auto}.dijitTab{position:relative;cursor:pointer;white-space:nowrap;z-index:3}.dijitTabChecked{cursor:default}.dijitTabContainerTop-tabs .dijitTab{top:1px}.dijitTabContainerBottom-tabs .dijitTab{top:-1px}.dijitTabContainerLeft-tabs .dijitTab{left:1px}.dijitTabContainerRight-tabs .dijitTab{left:-1px}.dijitTabContainerBottom-tabs .dijitTab,.dijitTabContainerTop-tabs .dijitTab{display:inline-block;#zoom:1;#display:inline}.dijitTabButtonDisabled .tabStripButton,.dijitTabCloseText{display:none}.tabStripButton{z-index:12}.dijitTabCloseButton{margin-left:1em}.dijitTab .tabLabel{display:inline-block}.dijitNoIcon{display:none}.dj_ie6 .dijitTab .dijitNoIcon{display:inline;height:15px;width:1px}.dj_a11y .dijitTabCloseButton{background-image:none!important;width:auto!important;height:auto!important}.dj_a11y .dijitTabCloseText{display:inline}.dijitAccordionContainer-child,.dijitStackContainer-child,.dijitTabPane{border:none!important}.dijitInlineEditBoxDisplayMode{border:1px solid transparent;cursor:text}.dijitInlineEditBoxDisplayModeDisabled,.dijitTreeContent{cursor:default}.dj_a11y .dijitInlineEditBoxDisplayMode,.dj_ie6 .dijitInlineEditBoxDisplayMode{border:none}.dijitInlineEditBoxDisplayModeHover,.dj_a11y .dijitInlineEditBoxDisplayModeHover,.dj_ie6 .dijitInlineEditBoxDisplayModeHover{background-color:#e2ebf2;border:1px solid #000}.dijitTree{overflow:auto}.dijitTreeContainer{float:left}.dijitTreeIndent{width:19px}.dijitTreeContent,.dijitTreeRow{white-space:nowrap}.dj_ie .dijitTreeLabel:focus{outline:#000 dotted 1px}.dijitExpandoText{display:none}.dj_a11y .dijitExpandoText{display:inline;padding-left:10px;padding-right:10px;font-family:monospace;border-style:solid;border-width:thin;cursor:pointer}.dijitSlider .dijitButtonNode,.dijitSliderButton{padding:0;display:block}.dijitTreeLabel{margin:0 4px}.dijitDialog{position:absolute;z-index:999;overflow:hidden}.dijitDialogTitleBar{cursor:move}.dijitDialogFixed .dijitDialogTitleBar{cursor:default}.dijitDialogCloseIcon,.dijitSliderBar,.dijitSliderButtonContainer *,.dijitTimePickerItemHover{cursor:pointer}.dijitDialogPaneContent{-webkit-overflow-scrolling:touch}.dijitDialogUnderlayWrapper{position:absolute;left:0;top:0;z-index:998;display:none;background:0 0!important}.dijitDialogUnderlay{background:#eee;opacity:.5}.dj_ie .dijitDialogUnderlay{filter:alpha(opacity=50)}.dj_a11y .dijitDialog,.dj_a11y .dijitSpinnerButtonContainer{opacity:1!important;background-color:#fff!important}.dijitDialog .closeText{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;display:block;color:#000;text-shadow:0 1px 0 #FFF;position:absolute}.dj_a11y .dijitDialog .closeText{display:inline}.dijitSliderMoveable{z-index:99;position:absolute!important;display:block}.dijitSliderMoveableH{right:0}.dijitSliderMoveableV{right:50%}.dijitSliderImageHandle,.dj_a11y div.dijitSliderImageHandle{margin:0;padding:0;position:relative!important;border:8px solid gray;width:0;height:0;cursor:pointer}.dijitSliderBarContainerH,.dijitSliderBarContainerV{position:relative;z-index:1}.dj_iequirks .dj_a11y .dijitSliderImageHandle{font-size:0}.dj_ie7 .dijitSliderImageHandle{overflow:hidden}.dj_ie7 .dj_a11y .dijitSliderImageHandle{overflow:visible}.dj_a11y .dijitSliderFocused .dijitSliderImageHandle{border:4px solid #000;height:8px;width:8px}.dijitSliderImageHandleV{top:-8px;right:-50%}.dijitSliderImageHandleH{left:50%;top:-5px;vertical-align:top}.dijitSliderBar{border-style:solid;border-color:#000}.dijitSliderBarContainerV{height:100%}.dijitSliderBarH{height:4px;border-width:1px 0}.dijitSliderBarV{width:4px;border-width:0 1px}.dijitSliderProgressBar{background-color:red;z-index:1}.dijitSliderProgressBarV{position:static!important;height:0;vertical-align:top;text-align:left}.dijitSliderProgressBarH{position:absolute!important;width:0;vertical-align:middle;overflow:visible}.dijitSliderBumper,.dijitSliderRemainingBar{overflow:hidden;z-index:1}.dijitSliderRemainingBar{background-color:transparent}.dijitSliderRemainingBarV{height:100%;text-align:left}.dijitSliderRemainingBarH{width:100%!important}.dijitSliderBumperV{width:4px;height:8px;border-width:0 1px}.dijitSliderBumperH{width:8px;height:4px;border-width:1px 0}.dijitSliderBottomBumper,.dijitSliderLeftBumper{background-color:red}.dijitSliderRightBumper,.dijitSliderTopBumper{background-color:transparent}.dijitSliderDecoration{text-align:center}.dijitSliderDecorationC,.dijitSliderDecorationV{position:relative}.dijitSliderDecorationH{width:100%}.dijitSliderDecorationV{height:100%;white-space:nowrap}.dijitSliderButton{font-family:monospace;margin:0}.dj_a11y .dijitSliderButtonInner{visibility:visible!important}.dijitSliderButtonContainer{text-align:center;height:0}.dijitRuleContainer{position:relative;overflow:visible}.dijitRuleLabelContainer,.dijitRuleMark{position:absolute}.dijitRuleContainerV{height:100%;line-height:0;float:left;text-align:left}.dj_opera .dijitRuleContainerV{line-height:2%}.dj_ie .dijitRuleContainerV{line-height:normal}.dj_gecko .dijitRuleContainerV{margin:0 0 1px}.dijitRuleMark{border:1px solid #000;line-height:0;height:100%}.dijitRuleMarkH{width:0;border-top-width:0!important;border-bottom-width:0!important}.dijitRuleLabelContainerH{text-align:center;display:inline-block}.dijitRuleLabelH{position:relative;left:-50%}.dijitRuleLabelV{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.dijitRuleMarkV{height:0;border-right-width:0!important;border-left-width:0!important;width:100%;left:0}.dj_ie .dijitRuleLabelContainerV{margin-top:-.55em}.dj_a11y .dijitSliderDisabled,.dj_a11y .dijitSliderReadOnly{opacity:.6}.dj_ie .dj_a11y .dijitSliderDisabled .dijitSliderBar,.dj_ie .dj_a11y .dijitSliderReadOnly .dijitSliderBar{filter:alpha(opacity=40)}.dj_a11y .dijitSlider .dijitSliderButtonContainer div{font-family:monospace;font-size:1em;line-height:1em;height:auto;width:auto;margin:0 4px}.dj_a11y .dijitButtonContents .dijitButtonText,.dj_a11y .dijitTab .tabLabel{display:inline!important}.dj_a11y .dijitSelect .dijitButtonText{display:inline-block!important}.dijitSelectError .dijitButtonContents .dijitButtonText{display:none!important}.dijitTextArea{width:100%;overflow-y:auto}.dijitTextArea[cols],.dj_ie .dijitTextAreaCols{width:auto}.dijitToolbarSeparator{height:18px;width:5px;padding:0 1px;margin:0}.dijitIEFixedToolbar{position:absolute;top:expression(eval((document.documentElement||document.body).scrollTop))}.dijitEditor{display:block}.dijitEditorDisabled,.dijitEditorReadOnly{color:gray}.dijitTimePickerItemInner{text-align:center;border:0;padding:2px 8px}.dijitTimePicker .dijitDownArrowButton{border-top:none!important}.dijitTimePickerMarker{color:#000}.dijitTimePickerItemSelected{font-weight:700;color:#333;background-color:#b7cdee}.dijitTimePickerItemHover{background-color:gray;color:#fff}.dijitTimePickerItemDisabled{color:gray;text-decoration:line-through}.dj_a11y .dijitTimePickerItemSelected .dijitTimePickerItemInner{border:4px solid #000}.dj_a11y .dijitTimePickerItemHover .dijitTimePickerItemInner{border:4px dashed #000}.dijitToggleButtonIconChar{display:none!important}.dj_a11y .dijitToggleButton .dijitToggleButtonIconChar{display:inline!important;visibility:hidden}.dj_ie6 .dijitToggleButtonIconChar,.dj_ie6 .tabStripButton .dijitButtonText{font-family:"Arial Unicode MS"}.dojoDndAvatarHeader:before,.flat .dijitCalendarIncrementControl{font-family:flat-icon;speak:none;font-style:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.dj_a11y .dijitToggleButtonChecked .dijitToggleButtonIconChar{display:inline!important;visibility:visible!important}.dijitArrowButtonChar{display:none!important}.dj_a11y .dijitArrowButtonChar{display:inline!important}.dj_a11y .dijitComboButton .dijitArrowButtonInner,.dj_a11y .dijitDropDownButton .dijitArrowButtonInner{display:none!important}.dijitSelectMenu .dijitMenuItemIcon,.flat .dijitA11ySideArrow{display:none}.dj_a11y .dijitSelect{border-collapse:separate!important;border-width:1px;border-style:solid}.flat .dijitCalendar,.flat .dijitMenuTable,.flat table.dijitComboButton{border-collapse:separate}.dj_ie .dijitSelect{vertical-align:middle}.dj_ie6 .dijitSelect .dijitValidationContainer,.dj_ie8 .dijitSelect .dijitButtonText{vertical-align:top}.dijitSelect .dijitSelectLabel,.dijitSelectLabel *,.dj_ie6 .dijitSpinner .dijitSpinnerButtonInner,.dj_ie6 .dijitTextBox .dijitArrowButtonInner,.dj_ie6 .dijitTextBox .dijitInputContainer,.dj_iequirks .dijitTextBox .dijitInputContainer{vertical-align:baseline}.dijitNumberTextBox{text-align:left;direction:ltr}.dijitNumberTextBox .dijitInputInner{text-align:inherit}.dijitToolbar .dijitSelect{margin:0}.dj_webkit .dijitToolbar .dijitSelect{padding-left:.3em}.dijitSelect .dijitButtonContents{padding:0;white-space:nowrap;text-align:left;border-style:none solid none none;border-width:0}.dijitSelectFixedWidth .dijitButtonContents{width:100%}.dj_ie6 .dijitSelectMenu .dijitMenuItemLabel,.dj_ie7 .dijitSelectMenu .dijitMenuItemLabel{position:static}.flat .dijitCalendarYearContainer,.flat .dijitCalendarYearLabel span{vertical-align:middle}.dijitSelectSelectedOption *{font-weight:400}.dijitSelectMenu{border-width:1px}.dijitSelectMenu .dijitMenuTable{margin:0;background-color:transparent}.dijitForceStatic{position:static!important}.dijitDisabled,.dijitDisabled *,.dijitReadOnly,.dijitReadOnly *{cursor:default}.dojoDndItem{padding:2px;-webkit-touch-callout:none;-webkit-user-select:none}.dojoDndHorizontal .dojoDndItem{#display:inline;display:inline-block}.dojoDndItemAfter,.dojoDndItemBefore{border:0 solid #369}.dojoDndItemBefore{border-width:2px 0 0;padding:0 2px 2px}.dojoDndItemAfter{border-width:0 0 2px;padding:2px 2px 0}.dojoDndHorizontal .dojoDndItemBefore{border-width:0 0 0 2px;padding:2px 2px 2px 0}.dojoDndHorizontal .dojoDndItemAfter{border-width:0 2px 0 0;padding:2px 0 2px 2px}.dj_gecko .dijitArrowButtonInner INPUT,.dj_gecko INPUT.dijitArrowButtonInner{-moz-user-focus:ignore}.dijitFocused .dijitMenuItemShortcutKey{text-decoration:underline}.flat .dijitCalendar{background-color:#fff;text-align:center;padding:4px;border:1px solid #9e9e9e;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2);box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2)}.flat .dijitCalendarMonthContainer th{text-align:center;line-height:20px;vertical-align:middle;margin:4px 0}.flat .dijitCalendarIncrementControl{font-weight:400;line-height:1;font-size:24px;border:1px solid transparent;padding:4px}.flat .dijitCalendarDecrease:before{content:"\f000"}.flat .dijitCalendarIncrease:before{content:"\f001"}.flat .dijitCalendarArrow:hover .dijitCalendarIncrementControl,.flat .dijitCalendarArrowHover .dijitCalendarIncrementControl,.flat .dijitCalendarNextYear:hover,.flat .dijitCalendarNextYearHover,.flat .dijitCalendarPreviousYear:hover,.flat .dijitCalendarPreviousYearHover{border-style:solid;border-width:1px;border-color:#9e9e9e;-webkit-border-radius:3px;border-radius:3px;line-height:20px;cursor:pointer;-webkit-transition:all 50ms linear;-moz-transition:all 50ms linear;-o-transition:all 50ms linear;-ms-transition:all 50ms linear;transition:all 50ms linear;background:#fff;padding:4px}.flat .dijitCalendarArrow:active .dijitCalendarIncrementControl,.flat .dijitCalendarArrowActive .dijitCalendarIncrementControl,.flat .dijitCalendarNextYear:active,.flat .dijitCalendarNextYearActive,.flat .dijitCalendarPreviousYear:active,.flat .dijitCalendarPreviousYearActive{-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none;transition:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.05);box-shadow:inset 0 3px 5px rgba(0,0,0,.05);background:#e0e0e0;border-color:#b3b3b3}.flat .dijitCalendarContainer td,.flat .dijitCalendarContainer th{padding:4px}.flat .dijitCalendarDayLabelTemplate{text-align:center;border-bottom:#9e9e9e}.flat .dijitCalendarDayLabel{font-weight:700;text-align:center}.flat .dijitCalendarDateTemplate{font-size:.9em;letter-spacing:.05em;text-align:center}.flat .dijitCalendarDateTemplate .dijitCalendarDateLabel{text-decoration:none;display:block;padding:2px 4px;border:0;-webkit-border-radius:50%;border-radius:50%}.flat .dijitCalendarNextMonth .dijitCalendarDateLabel,.flat .dijitCalendarPreviousMonth .dijitCalendarDateLabel{color:#c2c2c2}.flat .dijitCalendarCurrentDate .dijitCalendarDateLabel{border-color:#2196f3}.flat .dijitCalendarEnabledDate:hover .dijitCalendarDateLabel,.flat .dijitCalendarHoveredDate .dijitCalendarDateLabel{background-color:#f2f2f2}.flat .dijitCalendarActiveDate .dijitCalendarDateLabel,.flat .dijitCalendarEnabledDate:active .dijitCalendarDateLabel{background-color:#e6e6e6}.flat .dijitCalendarSelectedDate .dijitCalendarDateLabel,.flat .dijitCalendarSelectedDate.dijitCalendarHoveredDate .dijitCalendarDateLabel{color:#fff;background-color:#2196f3}.flat .dijitCalendarDisabledDate .dijitCalendarDateLabel{opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitCalendarYearLabel{padding:4px 0 0;margin:0;font-size:1.15em}.flat .dijitCalendarNextYear,.flat .dijitCalendarPreviousYear,.flat .dijitCalendarSelectedYear{padding:4px}.flat .dijitCalendarSelectedYear{color:#2196f3;padding:0 4px}.flat .dijitCalendarNextYear,.flat .dijitCalendarPreviousYear{color:#2196f3;font-size:.9em;line-height:20px;border:1px solid transparent}.flat .dijitCalendar .dijitDropDownButton{margin:0}.flat .dijitCalendarMonthMenu{padding:8px 0}.flat .dijitCalendarMonthMenu .dijitCalendarMonthLabel,.flat .dijitColorPalette .dijitPaletteTable{padding:4px}.flat .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover{color:#fff;background-color:#2196f3}.flat .dijitColorPalette{border:1px solid #9e9e9e;background-color:#fff;-webkit-border-radius:3px;border-radius:3px}.flat .dijitColorPalette .dijitColorPaletteSwatch{height:15px;width:15px;-webkit-border-radius:2px;border-radius:2px}.flat .dijitColorPalette .dijitPaletteImg{border:1px solid transparent;line-height:normal}.flat .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg{border-color:#9e9e9e;-webkit-box-shadow:none;box-shadow:none;-webkit-border-radius:2px;border-radius:2px;-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-o-transform:scale(1.2);-ms-transform:scale(1.2);transform:scale(1.2)}.flat .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg,.flat .dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg{border:1px solid #2196f3;-webkit-box-shadow:0 1px .5px rgba(0,0,0,.3),0 2px 2px rgba(0,0,0,.2);box-shadow:0 1px .5px rgba(0,0,0,.3),0 2px 2px rgba(0,0,0,.2);-webkit-border-radius:2px;border-radius:2px;-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-o-transform:scale(1.2);-ms-transform:scale(1.2);transform:scale(1.2)}.dojoDndAvatarItem td>*,.flat .dijitDialog{-webkit-box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2)}.dijitPopup{-webkit-border-radius:3px;border-radius:3px}.dojoDndItem{border:1px solid transparent;cursor:pointer;-webkit-transition-duration:.25s;-moz-transition-duration:.25s;-o-transition-duration:.25s;-ms-transition-duration:.25s;transition-duration:.25s;-webkit-transition-property:background-color,border-color,opacity;-moz-transition-property:background-color,border-color,opacity;-o-transition-property:background-color,border-color,opacity;-ms-transition-property:background-color,border-color,opacity;transition-property:background-color,border-color,opacity}.dojoDndItemOver{cursor:pointer;background-color:#f5f5f5;-webkit-border-radius:3px;border-radius:3px}.dojoDndItemAnchor{background-color:transparent;border:1px dashed #2196f3;-webkit-border-radius:3px;border-radius:3px}.dojoDndItemBefore{background:0 0;padding-top:2px;border-top:1px solid #2196f3}.dojoDndItemAfter{background:0 0;padding-bottom:2px;border-bottom:1px solid #2196f3}table.dojoDndAvatar{display:block}.dojoDndAvatarHeader td{display:none}.dojoDndAvatarHeader:before{font-weight:400;line-height:1;font-size:16px;display:table-cell}.flat .dijitCheckedMenuItemIconChar,.flat .dijitDialogCloseIcon .closeText{display:none}.dojoDndCopy .dojoDndAvatarHeader:before,.dojoDndMove .dojoDndAvatarHeader:before{color:#dd2c00;content:"\f01c"}.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader:before,.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader:before{color:#43a047;content:"\f008"}.dojoDndAvatarItem{-webkit-border-radius:3px;border-radius:3px}.dojoDndAvatarItem td>*{padding:4px 8px;list-style-type:none;background-color:#fff;box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2)}.flat .dijitDialog{background-color:#fff;border:1px solid #9e9e9e;-webkit-border-radius:3px;border-radius:3px;box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2)}.flat .dijitMenu,.flat .dijitTooltipDialog .dijitTooltipContainer{-webkit-box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2)}.flat .dijitDialogPaneContent{background-color:#fff;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;padding:8px;position:relative}.flat .dijitDialogPaneActionBar{padding-top:8px;text-align:right;position:relative}.flat .dijitDialogPaneActionBar .dijitButton{float:none}.flat .dijitTooltipDialog .dijitDialogPaneActionBar{-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;margin:8px 0 0}.flat .dijitDialogTitleBar{line-height:20px;border-bottom:1px solid #e0e0e0;padding:8px 12px;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.flat .dijitDialogTitle{font-size:1.1em;font-weight:700}.flat .dijitDialogCloseIcon,.flat .dijitMenuExpand{font-family:flat-icon;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.flat .dijitDialogCloseIcon{width:20px;height:20px;text-align:center;position:absolute;top:8px;right:12px;line-height:1;font-size:16px;opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitDialogCloseIcon:before{content:"\f00e";font-size:20px}.flat .dijitDialogCloseIconActive,.flat .dijitDialogCloseIconHover{opacity:1;-ms-filter:none;filter:none}.flat .dijitDialogUnderlay{background:#000;opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitTooltip,.flat .dijitTooltipDialog{background:0 0}.flat .dijitTooltipContainer{background-color:#424242;opacity:1;-ms-filter:none;filter:none;padding:4px 8px;-webkit-border-radius:3px;border-radius:3px}.flat .dijitTooltip .dijitTooltipContainer{color:#fff;border:0}.flat .dijitTooltipConnector{z-index:2;width:auto;height:auto;opacity:1;-ms-filter:none;filter:none}.flat .dijitTooltipABRight .dijitTooltipConnector{left:auto!important;right:8px}.flat .dijitTooltipBelow{padding-top:4px}.flat .dijitTooltipBelow .dijitTooltipConnector{top:0;left:8px;border-bottom:4px solid #424242;border-left:4px solid transparent;border-right:4px solid transparent;border-top:0}.flat .dijitTooltipAbove{padding-bottom:4px}.flat .dijitTooltipAbove .dijitTooltipConnector{bottom:0;left:8px;border-top:4px solid #424242;border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:0}.flat .dijitTooltipLeft{padding-right:4px}.flat .dijitTooltipLeft .dijitTooltipConnector{right:0;border-left:4px solid #424242;border-bottom:4px solid transparent;border-top:4px solid transparent;border-right:0}.flat .dijitTooltipRight{padding-left:4px}.flat .dijitTooltipRight .dijitTooltipConnector{left:0;border-bottom:4px solid transparent;border-top:4px solid transparent;border-right:4px solid #424242}.flat .dijitTooltipDialog .dijitTooltipContainer{background:#fff;border:1px solid #9e9e9e;-webkit-border-radius:3px;border-radius:3px;box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2);opacity:1;-ms-filter:none;filter:none}.flat .dijitTooltipDialog.dijitTooltipBelow{padding-top:6px}.flat .dijitTooltipDialog.dijitTooltipAbove{padding-bottom:6px}.flat .dijitTooltipDialog.dijitTooltipLeft{padding-right:6px}.flat .dijitTooltipDialog.dijitTooltipRight{padding-left:6px}.flat .dijitTooltipDialog .dijitTooltipConnector{height:0;width:0;position:absolute;z-index:2;opacity:1;-ms-filter:none;filter:none}.flat .dijitTooltipDialog .dijitTooltipConnector:after{content:"";height:0;width:0;position:absolute}.flat .dijitTooltipDialog.dijitTooltipAbove .dijitTooltipConnector{border-color:#9e9e9e transparent transparent;border-width:7px 7px 0;border-style:solid}.flat .dijitTooltipDialog.dijitTooltipAbove .dijitTooltipConnector:after{border-color:#fff transparent transparent;border-width:6px 6px 0;border-style:solid;left:-6px;top:-7px}.flat .dijitTooltipDialog.dijitTooltipBelow .dijitTooltipConnector{border-color:transparent transparent #9e9e9e;border-width:0 7px 7px;border-style:solid}.flat .dijitTooltipDialog.dijitTooltipBelow .dijitTooltipConnector:after{border-color:transparent transparent #fff;border-width:0 6px 6px;border-style:solid;left:-6px;bottom:-7px}.flat .dijitTooltipDialog.dijitTooltipLeft .dijitTooltipConnector{border-color:transparent transparent transparent #9e9e9e;border-width:7px 0 7px 7px;border-style:solid}.flat .dijitTooltipDialog.dijitTooltipLeft .dijitTooltipConnector:after{border-color:transparent transparent transparent #fff;border-width:6px 0 6px 6px;border-style:solid;top:-6px;left:-7px}.flat .dijitTooltipDialog.dijitTooltipRight .dijitTooltipConnector{border-color:transparent #9e9e9e transparent transparent;border-width:7px 7px 7px 0;border-style:solid}.flat .dijitTooltipDialog.dijitTooltipRight .dijitTooltipConnector:after{border-color:transparent #fff transparent transparent;border-width:6px 6px 6px 0;border-style:solid;top:-6px;right:-7px}.flat .dijitEditor{background-color:#fff;border:1px solid #9e9e9e;-webkit-border-radius:3px;border-radius:3px}.flat .dijitEditor .dijitEditorIFrameContainer{border:1px solid transparent;border-top:1px solid #9e9e9e;padding:4px 8px;-webkit-transition:border .2s linear 0s;-moz-transition:border .2s linear 0s;-o-transition:border .2s linear 0s;-ms-transition:border .2s linear 0s;transition:border .2s linear 0s}.flat .dijitAccordionTitle,.flat .dijitTitlePaneTitle{-webkit-transition:all 50ms linear;-moz-transition:all 50ms linear;-ms-transition:all 50ms linear;cursor:pointer}.flat .dijitEditorFocused .dijitEditorIFrameContainer,.flat .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame,.flat .dijitEditorHover .dijitEditorIFrameContainer,.flat .dijitEditorHover .dijitEditorIFrameContainer .dijitEditorIFrame{border:1px solid #2196f3}.flat .dijitEditorDisabled{border:1px solid #9e9e9e;opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitEditorDisabled .dijitEditorIFrame,.flat .dijitEditorDisabled .dijitEditorIFrameContainer,.flat .dijitEditorDisabled .dijitEditorIFrameContainer .dijitEditorIFrame{background-color:#f5f5f5;border:1px solid transparent}.flat .dijitInlineEditBoxDisplayMode{border:1px dashed transparent;padding:4px 6px}.flat .dijitInlineEditBoxDisplayModeHover{background-color:transparent;border:1px dashed #2196f3}.flat .dijitInlineEditBoxDisplayModeDisabled{opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitMenu{background:#fff;border:1px solid #9e9e9e;-webkit-border-radius:3px;border-radius:3px;margin:0;box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2)}.flat .dijitComboBoxMenu,.flat .dijitMenuTable{padding:8px 0}.flat .dijitComboBoxMenu{margin-left:0;background-image:none}.flat .dijitMenuTable{border-spacing:0 0}.flat .dijitMenuItem,.flat .dijitMenuItem td{line-height:20px;padding:8px;white-space:nowrap}.flat .dijitMenuItemActive,.flat .dijitMenuItemActive td,.flat .dijitMenuItemHover,.flat .dijitMenuItemHover td,.flat .dijitMenuItemSelected,.flat .dijitMenuItemSelected td{color:#fff;background-color:#2196f3}.flat .dijitMenuItemDisabled{color:#9e9e9e}.flat .dijitMenuItemDisabled.dijitMenuItemSelected,.flat .dijitMenuItemDisabled.dijitMenuItemSelected td{color:#f2f2f2;background:#6fbbf7}.flat .dijitMenuSeparatorTop{height:auto;margin-top:1px;border-bottom:1px solid #9e9e9e}.flat .dijitMenuSeparatorBottom{height:auto;margin-bottom:1px;border-top:1px solid transparent}.flat td.dijitMenuItemIconCell{padding:4px;margin:0 0 0 4px;text-align:center}.flat .dijitMenuExpand{line-height:1;font-size:16px}.flat .dijitMenuExpand:before{content:"\f001"}.flat .dijitMenuNextButton,.flat .dijitMenuPreviousButton{font-style:italic}.flat .dijitAccordionTitle .arrowTextDown,.flat .dijitAccordionTitle .arrowTextUp,.flat .dijitTabCloseButton,.flat .dijitTitlePane .dijitArrowNode,.flat .dijitTreeExpando{font-family:flat-icon;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.flat .dijitMenuBar{margin:0;padding:0;background-color:#f5f5f5}.flat .dijitMenuBar .dijitMenuItem{padding:8px 12px;margin:0}.flat .dijitMenuBar .dijitMenuItemActive,.flat .dijitMenuBar .dijitMenuItemActive.dijitMenuItemSelected,.flat .dijitMenuBar .dijitMenuItemHover,.flat .dijitMenuBar .dijitMenuItemHover.dijitMenuItemSelected,.flat .dijitMenuBar .dijitMenuItemSelected{color:#fff;background-color:#2196f3}.flat .dijitMenuBar .dijitMenuItemDisabled.dijitMenuItemSelected{color:#f2f2f2;background:#6fbbf7}.flat .dijitMenuPopup,.flat .dijitMenuPopup .dijitMenu{border-top-left-radius:0;border-top-right-radius:0}.flat .dijitMenuPopup .dijitMenuItem,.flat .dijitMenuPopup .dijitMenuItem td{padding:8px}.flat .dijitProgressBar{background-color:#e0e0e0;border:0;-webkit-border-radius:3px;border-radius:3px}.flat .dijitProgressBarTile{background:url(images/progressBarStrips.png) top repeat-x;-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.flat .dijitProgressBarFull{background-color:#2196f3;-webkit-transition-property:width;-moz-transition-property:width;-o-transition-property:width;-ms-transition-property:width;transition-property:width;-webkit-transition-duration:.25s;-moz-transition-duration:.25s;-o-transition-duration:.25s;-ms-transition-duration:.25s;transition-duration:.25s;height:100%}.flat .dijitProgressBar.alt-primary .dijitProgressBarFull{background-color:#1e88e5}.flat .dijitProgressBar.alt-success .dijitProgressBarFull{background-color:#43a047}.flat .dijitProgressBar.alt-info .dijitProgressBarFull{background-color:#03a9f4}.flat .dijitProgressBar.alt-warning .dijitProgressBarFull{background-color:#fb8c00}.flat .dijitProgressBar.alt-danger .dijitProgressBarFull{background-color:#e53935}.flat .dijitProgressBar.alt-inverse .dijitProgressBarFull{background-color:#616161}.flat .dijitProgressBarLabel{margin-top:.2em;margin-bottom:.2em;color:#fff;font-size:1em;text-shadow:.1em .1em 1px #424242}@-moz-keyframes progress-bar-stripes{from{background-position:75px 0}to{background-position:0 0}}@-webkit-keyframes progress-bar-stripes{from{background-position:75px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:75px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:75px 0}to{background-position:0 0}}.dijitTimePickerPopup{-webkit-box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2);box-shadow:0 7px 3px -4px rgba(0,0,0,.3),0 8px 8px rgba(0,0,0,.2);height:200px}.dijitTimePicker{background-color:#fff;padding:4px 0;border:1px solid #9e9e9e;-webkit-border-radius:3px;border-radius:3px}.dijitTimePickerItem{margin:0}.dijitTimePickerTick{color:#9e9e9e;border:0}.dijitTimePickerMarker{background-color:transparent;white-space:nowrap;border:0}.dijitTimePickerMarkerHover,.dijitTimePickerMarkerSelected,.dijitTimePickerTickHover,.dijitTimePickerTickSelected{background:#f2f2f2;color:#424242}.dijitTimePickerMarker .dijitTimePickerItemInner,.dijitTimePickerTick .dijitTimePickerItemInner{padding:8px;margin:0}.flat .dijitTitlePaneTitle{border-style:solid;border-width:1px;border-color:#9e9e9e;padding:4px;line-height:20px;-o-transition:all 50ms linear;transition:all 50ms linear;background:#fff;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.flat .dijitTitlePaneTitleHover{-webkit-transition:all .1s;-moz-transition:all .1s;-o-transition:all .1s;-ms-transition:all .1s;transition:all .1s;background:#f2f2f2;border-color:#d9d9d9}.flat .dijitTitlePaneTitleActive{-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none;transition:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.05);box-shadow:inset 0 3px 5px rgba(0,0,0,.05);background:#e0e0e0;border-color:#b3b3b3}.flat .dijitTitlePane .dijitArrowNode{line-height:1;font-size:18px;text-align:center}.flat .dijitTitlePane .dijitArrowNode:before{content:"\f007"}.flat .dijitTitlePane .dijitClosed{-webkit-border-radius:3px;border-radius:3px}.flat .dijitTitlePane .dijitClosed .dijitArrowNode:before{content:"\f006"}.flat .dijitTitlePaneContentOuter{background-color:#fff;border:1px solid #9e9e9e;border-top:none;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.flat .dijitTitlePaneContentInner{padding:8px}.flat .dijitTitlePaneTextNode{margin-left:8px;margin-right:8px;vertical-align:text-top}.flat .dijitToolbar{background-color:#f5f5f5;padding:4px;zoom:1}.flat .dijitToolbar label{padding:8px}.flat .dijitToolbar .dijitButton,.flat .dijitToolbar .dijitComboButton,.flat .dijitToolbar .dijitDropDownButton,.flat .dijitToolbar .dijitToggleButton{margin-right:4px}.flat .dijitToolbar .dijitButton .dijitButtonNode,.flat .dijitToolbar .dijitComboBox .dijitButtonNode,.flat .dijitToolbar .dijitComboButton .dijitButtonNode,.flat .dijitToolbar .dijitDropDownButton .dijitButtonNode,.flat .dijitToolbar .dijitToggleButton .dijitButtonNode{border-color:transparent;padding:4px;background-color:transparent;-webkit-border-radius:3px;border-radius:3px;-webkit-transition-property:background-color;-moz-transition-property:background-color;-o-transition-property:background-color;-ms-transition-property:background-color;transition-property:background-color;-webkit-transition-duration:.3s;-moz-transition-duration:.3s;-o-transition-duration:.3s;-ms-transition-duration:.3s;transition-duration:.3s}.flat .dijitToolbar .dijitComboButton .dijitStretch{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.flat .dijitToolbar .dijitComboButton .dijitArrowButton{-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.flat .dijitToolbar .dijitComboBox .dijitButtonNode{padding:0 8px}.flat .dijitToolbar .dijitComboBox .dijitInputInner{padding:0}.flat .dijitToolbar .dijitDropDownButton .dijitArrowButtonInner{margin-left:4px}.flat .dijitToolbar .dijitButtonHover .dijitButtonNode,.flat .dijitToolbar .dijitComboButtonHover .dijitButtonNode,.flat .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,.flat .dijitToolbar .dijitToggleButtonHover .dijitButtonNode{-webkit-transition:all .1s;-moz-transition:all .1s;-o-transition:all .1s;-ms-transition:all .1s;transition:all .1s;background:#f2f2f2;border:1px solid #9e9e9e}.flat .dijitToolbar .dijitButtonActive .dijitButtonNode,.flat .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,.flat .dijitToolbar .dijitToggleButtonActive .dijitButtonNode,.flat .dijitToolbar .dijitToggleButtonChecked .dijitButtonNode{-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none;transition:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.05);box-shadow:inset 0 3px 5px rgba(0,0,0,.05);background:#e0e0e0;border:1px solid #9e9e9e}.flat .dijitToolbarSeparator{width:1px;height:20px;background-color:#9e9e9e;padding:0;margin:0 4px}.flat .dijitDisabled .dijitToolbar{background-color:#f5f5f5;border-bottom:1px solid #9e9e9e}.flat .dijitTreeIsRoot{background-color:transparent}.flat .dijitTreeRowActive,.flat .dijitTreeRowHover{background-color:#f2f2f2;border-color:transparent}.flat .dijitTreeNode .dojoDndItemAfter,.flat .dijitTreeNode .dojoDndItemBefore,.flat .dijitTreeRow{padding:8px 0;border:0 transparent;line-height:20px;-webkit-transition-property:background-color;-moz-transition-property:background-color;-o-transition-property:background-color;-ms-transition-property:background-color;transition-property:background-color;-webkit-transition-duration:.15s;-moz-transition-duration:.15s;-o-transition-duration:.15s;-ms-transition-duration:.15s;transition-duration:.15s;-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;transition-timing-function:ease-out}.flat .dijitTreeRowHover{-webkit-transition-duration:.15s;-moz-transition-duration:.15s;-o-transition-duration:.15s;-ms-transition-duration:.15s;transition-duration:.15s}.flat .dijitTreeRowActive.dijitTreeRowSelected,.flat .dijitTreeRowHover.dijitTreeRowSelected,.flat .dijitTreeRowSelected{color:#fff;background-color:#2196f3;border-color:transparent}.flat .dijitTreeRowActive.dijitTreeRowSelected .dijitTreeExpando,.flat .dijitTreeRowHover.dijitTreeRowSelected .dijitTreeExpando,.flat .dijitTreeRowSelected .dijitTreeExpando{color:#fff}.flat .dijitTreeExpando{font-size:16px;width:16px;height:16px;line-height:16px;text-align:center;margin-left:4px;margin-right:4px;color:#2196f3;vertical-align:middle}.flat .dijitTreeExpandoOpened:before{content:"\e60d";cursor:pointer}.flat .dijitTreeExpandoClosed:before{content:"\e60a";cursor:pointer}.flat .dijitTreeExpandoLoading:before{content:"\e60e";-webkit-animation:spinning 2s linear infinite;-moz-animation:spinning 2s linear infinite;-o-animation:spinning 2s linear infinite;-ms-animation:spinning 2s linear infinite;animation:spinning 2s linear infinite}.dj_ie8 .dijitTreeExpandoLoading:before,.dj_ie9 .dijitTreeExpandoLoading:before,.flat .dijitTab:before{content:""}.dj_ie8 .dijitTreeExpandoLoading,.dj_ie9 .dijitTreeExpandoLoading{background:url(images/loadingAnimation.gif) no-repeat}@-moz-keyframes spinning{from{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes spinning{from{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes spinning{from{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinning{from{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}.flat .dijitAccordionContainer{border:0;-webkit-border-radius:3px;border-radius:3px}.flat .dijitAccordionInnerContainer{background-color:#fff;border:1px solid #9e9e9e;-webkit-transition-property:background-color,border;-moz-transition-property:background-color,border;-o-transition-property:background-color,border;-ms-transition-property:background-color,border;transition-property:background-color,border;-webkit-transition-duration:.3s;-moz-transition-duration:.3s;-o-transition-duration:.3s;-ms-transition-duration:.3s;transition-duration:.3s;-webkit-transition-timing-function:linear;-moz-transition-timing-function:linear;-o-transition-timing-function:linear;-ms-transition-timing-function:linear;transition-timing-function:linear}.flat .dijitAccordionTitle{padding:4px;line-height:20px;-o-transition:all 50ms linear;transition:all 50ms linear;background:#fff;border:0;-webkit-border-radius:3px;border-radius:3px}.flat .dijitAccordionTitle .arrowTextDown,.flat .dijitAccordionTitle .arrowTextUp{display:none;line-height:1;text-align:center;font-size:0}.flat .dijitAccordionTitle .arrowTextDown:before,.flat .dijitAccordionTitle .arrowTextUp:before{content:"\f007";font-size:18px}.flat .dijitAccordionTitle .arrowTextUp{display:block}.flat .dijitAccordionTitle .arrowTextUp:before{content:"\f006"}.flat .dijitAccordionInnerContainerHover .dijitAccordionTitle{-webkit-transition:all .1s;-moz-transition:all .1s;-o-transition:all .1s;-ms-transition:all .1s;transition:all .1s;background:#f2f2f2;border-color:#d9d9d9}.flat .dijitAccordionInnerContainerActive .dijitAccordionTitle{-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none;transition:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.05);box-shadow:inset 0 3px 5px rgba(0,0,0,.05);background:#e0e0e0;border-color:#b3b3b3}.flat .dijitAccordionInnerContainerSelected{border:0}.flat .dijitAccordionInnerContainerSelected .dijitAccordionTitle{color:#fff;background-color:#2196f3;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.flat .dijitAccordionInnerContainerSelected .dijitAccordionTitle .arrowTextUp{display:none}.flat .dijitAccordionInnerContainerSelected .dijitAccordionTitle .arrowTextDown{display:block}.flat .dijitAccordionContainer .dijitAccordionChildWrapper{background-color:#fff;border:1px solid #9e9e9e;border-top:0 none;position:relative;z-index:1;clear:both;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.flat .dijitAccordionInnerContainer,.flat .dijitAccordionInnerContainer .dijitAccordionTitle,.flat .dijitAccordionInnerContainer:not(:last-child) .dijitAccordionChildWrapper{-webkit-border-radius:0;border-radius:0}.flat .dijitAccordionInnerContainer+.dijitAccordionInnerContainer{margin-top:0;position:relative;border-top:0 none}.flat .dijitAccordionInnerContainer+.dijitAccordionInnerContainerSelected:last-child .dijitAccordionTitle{-webkit-border-radius:0;border-radius:0}.flat .dijitAccordionInnerContainer:first-child,.flat .dijitAccordionInnerContainer:first-child .dijitAccordionTitle{-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.flat .dijitAccordionInnerContainer:last-child,.flat .dijitAccordionInnerContainer:last-child .dijitAccordionTitle{-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.flat .dijitBorderContainer{padding:5px}.flat .dijitBorderContainer-child,.flat .dijitSplitContainer-child{border:1px solid #9e9e9e}.flat .dijitBorderContainer-dijitAccordionContainer,.flat .dijitBorderContainer-dijitTabContainerBottom,.flat .dijitBorderContainer-dijitTabContainerLeft,.flat .dijitBorderContainer-dijitTabContainerRight,.flat .dijitBorderContainer-dijitTabContainerTop{border:none}.flat .dijitBorderContainer-dijitBorderContainer{border:0;padding:0}.flat .dijitGutterH,.flat .dijitSplitterH{background:0 0;border:0;height:5px}.flat .dijitSplitterH .dijitSplitterThumb{background:#9e9e9e;height:1px;top:2px;width:19px}.flat .dijitGutterV,.flat .dijitSplitterV{background:0 0;border:0;width:5px;margin:0}.flat .dijitSplitterV .dijitSplitterThumb{background:#9e9e9e;height:19px;left:2px;width:1px;margin:0}.flat .dijitSplitterHHover,.flat .dijitSplitterVHover{font-size:1px;background:#f2f2f2}.flat .dijitSplitterHHover .dijitSplitterThumb,.flat .dijitSplitterVHover .dijitSplitterThumb{background:#767676}.flat .dijitSplitterHActive,.flat .dijitSplitterVActive{font-size:1px;background:#f2f2f2}.flat .dijitSplitterHActive .dijitSplitterThumb,.flat .dijitSplitterVActive .dijitSplitterThumb{background:#767676}.flat .dijitContentPane{background-color:#fff;padding:8px}.flat .dijitAccordionContainer-dijitContentPane,.flat .dijitTabContainerBottom-dijitContentPane,.flat .dijitTabContainerLeft-dijitContentPane,.flat .dijitTabContainerRight-dijitContentPane,.flat .dijitTabContainerTop-dijitContentPane{background-color:#fff;padding:8px;left:0!important;top:0!important}.flat .dijitTabContainer{-webkit-border-radius:3px;border-radius:3px}.flat .dijitTabPaneWrapper{background:#fff;border:1px solid #9e9e9e;margin:0;padding:0;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.flat .dijitTabContainerBottom-tabs,.flat .dijitTabContainerLeft-tabs,.flat .dijitTabContainerRight-tabs,.flat .dijitTabContainerTop-tabs{border:none}.flat .dijitTabSpacer{display:none}.flat .dijitTab{border:1px solid transparent;background-color:#fff;text-align:center;-webkit-transition-property:background,padding,margin;-moz-transition-property:background,padding,margin;-o-transition-property:background,padding,margin;-ms-transition-property:background,padding,margin;transition-property:background,padding,margin;-webkit-transition-duration:.2s;-moz-transition-duration:.2s;-o-transition-duration:.2s;-ms-transition-duration:.2s;transition-duration:.2s;-webkit-transition-timing-function:ease;-moz-transition-timing-function:ease;-o-transition-timing-function:ease;-ms-transition-timing-function:ease;transition-timing-function:ease;position:relative;z-index:0}.flat .dijitTab:before{display:block;position:absolute}.flat .dijitTabContainerTabListNested .dijitTabChecked.dijitTabActive:before,.flat .dijitTabContainerTabListNested .dijitTabChecked.dijitTabHover:before,.flat .dijitTabContainerTabListNested .dijitTabChecked:before,.flat .dijitToggleButton .dijitCheckBoxIcon{display:none}.flat .dijitTabHover{background-color:#f2f2f2}.flat .dijitTabActive{background-color:#e6e6e6}.flat .dijitTabChecked{border:1px solid #9e9e9e;z-index:1}.flat .dijitTabChecked.dijitTabActive,.flat .dijitTabChecked.dijitTabHover{border:1px solid #9e9e9e;background-color:#fff;color:#424242}.flat .dijitTabDisabled{opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitTabCloseButton{line-height:1;font-size:1em;vertical-align:middle;margin-left:4px;opacity:.35;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=35)";filter:alpha(opacity=35)}.flat .dijitArrowButton,.flat .dijitDropDownButton .dijitArrowButtonInner,.flat .dijitTabStripIcon{font-family:flat-icon;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:16px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.flat .dijitTabCloseButton:before{content:"\f00e"}.flat .dijitTabCloseButtonHover{opacity:.75;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=75)";filter:alpha(opacity=75)}.flat .dijitTabCloseButtonActive{opacity:1;-ms-filter:none;filter:none}.flat .dijitTabContainerTop-tabs .dijitTab{margin-right:0;padding:6px 16px;border-bottom-color:#9e9e9e;border-left:none;border-right:none}.flat .dijitTabContainerTop-tabs .dijitTabChecked{border-bottom:1px solid #fff;border-left:1px solid #9e9e9e;border-right:1px solid #9e9e9e}.flat .dijitTabContainerTop-tabs .dijitTabChecked:before{height:3px;background:#2196f3;top:-1px;left:-1px;right:-1px}.flat .dijitTabListContainer-bottom .dijitTab,.flat .dijitTabListContainer-top .dijitTab{top:0}.flat .dijitTabListContainer-top{margin-top:1px}.flat .dijitTabPaneWrapper.dijitTabContainerBottom-container{-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.flat .dijitTabContainerBottom-tabs .dijitTab{margin-right:0;padding:6px 16px;border-top-color:#9e9e9e;border-left:none;border-right:none}.flat .dijitTabContainerBottom-tabs .dijitTabChecked{border-top:1px solid #fff;border-left:1px solid #9e9e9e;border-right:1px solid #9e9e9e}.flat .dijitTabContainerBottom-tabs .dijitTabChecked:before{height:3px;background:#2196f3;bottom:-1px;left:-1px;right:-1px}.flat .dijitTabListContainer-bottom{margin-top:-1px}.flat .dijitTabPaneWrapper.dijitTabContainerLeft-container{-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.flat .dijitTabContainerLeft-tabs .dijitTab{margin-bottom:0;padding:8px 12px;border-right-color:#9e9e9e;border-top:none;border-bottom:none}.flat .dijitTabContainerLeft-tabs .dijitTabChecked{border-right:1px solid #fff;border-top:1px solid #9e9e9e;border-bottom:1px solid #9e9e9e}.flat .dijitTabContainerLeft-tabs .dijitTabChecked:before{width:3px;background:#2196f3;bottom:-1px;left:-1px;top:-1px}.flat .dijitTabPaneWrapper.dijitTabContainerRight-container{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.flat .dijitTabContainerRight-tabs .dijitTab{margin-bottom:0;padding:8px 12px;border-left-color:#9e9e9e;border-top:none;border-bottom:none}.flat .dijitTabContainerRight-tabs .dijitTabChecked{border-left:1px solid #fff;border-top:1px solid #9e9e9e;border-bottom:1px solid #9e9e9e}.flat .dijitTabContainerRight-tabs .dijitTabChecked:before{width:3px;background:#2196f3;bottom:-1px;right:-1px;top:-1px}.flat .tabStripButton{background-color:#fff;border:1px solid transparent;-webkit-transition-property:background-color;-moz-transition-property:background-color;-o-transition-property:background-color;-ms-transition-property:background-color;transition-property:background-color}.flat .dijitTabListContainer-bottom .tabStripButton,.flat .dijitTabListContainer-top .tabStripButton{padding:4px 8px;margin-left:0;margin-right:0}.flat .dijitTabListContainer-top .tabStripButton{margin-bottom:1px}.flat .dijitTabListContainer-bottom .tabStripButton{margin-top:1px}.flat .tabStripButtonHover{background-color:#f2f2f2}.flat .tabStripButtonActive{background-color:#e6e6e6}.flat .dijitTabStripIcon{line-height:1;color:#2196f3;vertical-align:middle}.flat .dijitTabStripIcon:before{content:"\f004"}.flat .dijitTabStripSlideRightIcon:before{content:"\f005"}.flat .dijitTabStripMenuIcon:before{content:"\f006"}.flat .dijitTabListContainer-bottom .tabStripButtonDisabled,.flat .dijitTabListContainer-top .tabStripButtonDisabled{opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitTabContainerNested .dijitTabListWrapper{height:auto}.flat .dijitTabContainerTabListNested .dijitTab{color:#2196f3;margin:4px;padding:4px 8px;border:1px solid transparent;-webkit-border-radius:3px;border-radius:3px;-webkit-transition-property:background-color,border-color;-moz-transition-property:background-color,border-color;-o-transition-property:background-color,border-color;-ms-transition-property:background-color,border-color;transition-property:background-color,border-color;-webkit-transition-duration:.3s;-moz-transition-duration:.3s;-o-transition-duration:.3s;-ms-transition-duration:.3s;transition-duration:.3s}.flat .dijitTabContainerTabListNested .dijitTabHover{background-color:#f2f2f2}.flat .dijitTabContainerTabListNested .dijitTabActive{color:#2196f3;background-color:#e6e6e6}.flat .dijitTabContainerTabListNested .dijitTabChecked,.flat .dijitTabContainerTabListNested .dijitTabChecked.dijitTabActive,.flat .dijitTabContainerTabListNested .dijitTabChecked.dijitTabHover{color:#fff;background-color:#2196f3}.flat .dijitTabContainerTabListNested.dijitTabContainerBottom-tabs .dijitTab,.flat .dijitTabContainerTabListNested.dijitTabContainerTop-tabs .dijitTab{margin-right:4px}.flat .dijitTabContainerTabListNested.dijitTabContainerLeft-tabs .dijitTab,.flat .dijitTabContainerTabListNested.dijitTabContainerRight-tabs .dijitTab{margin-bottom:4px}.flat .dijitTabPaneWrapperNested{border:none;-webkit-box-shadow:none;box-shadow:none}.flat .dijitButtonText{padding:0 4px;text-align:center}.flat .dijitButton .dijitButtonNode,.flat .dijitComboButton .dijitButtonNode,.flat .dijitDropDownButton .dijitButtonNode,.flat .dijitToggleButton .dijitButtonNode{border-style:solid;border-width:1px;border-color:#9e9e9e;padding:4px;-webkit-border-radius:3px;border-radius:3px;line-height:20px;cursor:pointer;-webkit-transition:all 50ms linear;-moz-transition:all 50ms linear;-o-transition:all 50ms linear;-ms-transition:all 50ms linear;transition:all 50ms linear;background:#fff}.flat .dijitButton.alt-primary .dijitButtonNode,.flat .dijitComboBox.alt-primary .dijitButtonNode,.flat .dijitComboButton.alt-primary .dijitButtonNode,.flat .dijitDropDownButton.alt-primary .dijitButtonNode,.flat .dijitSelect.alt-primary .dijitButtonContents,.flat .dijitSelect.alt-primary .dijitButtonNode,.flat .dijitSpinner.alt-primary .dijitArrowButton,.flat .dijitToggleButton.alt-primary .dijitButtonNode{background:#1e88e5;color:#fff;border-color:#166fbd}.flat .dijitComboButton.alt-primary .dijitStretch{border-right-color:#166fbd}.flat .dijitComboButtonRtl.alt-primary .dijitStretch{border-left-color:#166fbd}.flat .dijitButton.alt-success .dijitButtonNode,.flat .dijitComboBox.alt-success .dijitButtonNode,.flat .dijitComboButton.alt-success .dijitButtonNode,.flat .dijitDropDownButton.alt-success .dijitButtonNode,.flat .dijitSelect.alt-success .dijitButtonContents,.flat .dijitSelect.alt-success .dijitButtonNode,.flat .dijitSpinner.alt-success .dijitArrowButton,.flat .dijitToggleButton.alt-success .dijitButtonNode{background:#43a047;color:#fff;border-color:#37823a}.flat .dijitComboButton.alt-success .dijitStretch{border-right-color:#37823a}.flat .dijitComboButtonRtl.alt-success .dijitStretch{border-left-color:#37823a}.flat .dijitButton.alt-info .dijitButtonNode,.flat .dijitComboBox.alt-info .dijitButtonNode,.flat .dijitComboButton.alt-info .dijitButtonNode,.flat .dijitDropDownButton.alt-info .dijitButtonNode,.flat .dijitSelect.alt-info .dijitButtonContents,.flat .dijitSelect.alt-info .dijitButtonNode,.flat .dijitSpinner.alt-info .dijitArrowButton,.flat .dijitToggleButton.alt-info .dijitButtonNode{background:#03a9f4;color:#fff;border-color:#028ac7}.flat .dijitComboButton.alt-info .dijitStretch{border-right-color:#028ac7}.flat .dijitComboButtonRtl.alt-info .dijitStretch{border-left-color:#028ac7}.flat .dijitButton.alt-warning .dijitButtonNode,.flat .dijitComboBox.alt-warning .dijitButtonNode,.flat .dijitComboButton.alt-warning .dijitButtonNode,.flat .dijitDropDownButton.alt-warning .dijitButtonNode,.flat .dijitSelect.alt-warning .dijitButtonContents,.flat .dijitSelect.alt-warning .dijitButtonNode,.flat .dijitSpinner.alt-warning .dijitArrowButton,.flat .dijitToggleButton.alt-warning .dijitButtonNode{background:#fb8c00;color:#fff;border-color:#cd7200}.flat .dijitComboButton.alt-warning .dijitStretch{border-right-color:#cd7200}.flat .dijitComboButtonRtl.alt-warning .dijitStretch{border-left-color:#cd7200}.flat .dijitButton.alt-danger .dijitButtonNode,.flat .dijitComboBox.alt-danger .dijitButtonNode,.flat .dijitComboButton.alt-danger .dijitButtonNode,.flat .dijitDropDownButton.alt-danger .dijitButtonNode,.flat .dijitSelect.alt-danger .dijitButtonContents,.flat .dijitSelect.alt-danger .dijitButtonNode,.flat .dijitSpinner.alt-danger .dijitArrowButton,.flat .dijitToggleButton.alt-danger .dijitButtonNode{background:#e53935;color:#fff;border-color:#cc1e1a}.flat .dijitComboButton.alt-danger .dijitStretch{border-right-color:#cc1e1a}.flat .dijitComboButtonRtl.alt-danger .dijitStretch{border-left-color:#cc1e1a}.flat .dijitButton.alt-inverse .dijitButtonNode,.flat .dijitComboBox.alt-inverse .dijitButtonNode,.flat .dijitComboButton.alt-inverse .dijitButtonNode,.flat .dijitDropDownButton.alt-inverse .dijitButtonNode,.flat .dijitSelect.alt-inverse .dijitButtonContents,.flat .dijitSelect.alt-inverse .dijitButtonNode,.flat .dijitSpinner.alt-inverse .dijitArrowButton,.flat .dijitToggleButton.alt-inverse .dijitButtonNode{background:#616161;color:#fff;border-color:#4f4f4f}.flat .dijitComboButton.alt-inverse .dijitStretch{border-right-color:#4f4f4f}.flat .dijitComboBoxRtlDisabled.alt-primary .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-primary .dijitStretch,.flat .dijitDateTextBoxRtlDisabled.alt-primary .dijitButtonNode,.flat .dijitTimeTextBoxRtlDisabled.alt-primary .dijitButtonNode{border-right-color:#50a2eb}.flat .dijitComboButtonRtl.alt-inverse .dijitStretch{border-left-color:#4f4f4f}.flat .dijitComboBoxDisabled.alt-primary .dijitButtonNode,.flat .dijitComboButtonRtlDisabled.alt-primary .dijitStretch,.flat .dijitDateTextBoxDisabled.alt-primary .dijitButtonNode,.flat .dijitTimeTextBoxDisabled.alt-primary .dijitButtonNode{border-left-color:#50a2eb}.flat .dijitButtonHover .dijitButtonNode,.flat .dijitComboButton .dijitButtonNodeHover,.flat .dijitComboButton .dijitDownArrowButtonHover,.flat .dijitDropDownButtonHover .dijitButtonNode,.flat .dijitToggleButtonHover .dijitButtonNode{-webkit-transition:all .1s;-moz-transition:all .1s;-o-transition:all .1s;-ms-transition:all .1s;transition:all .1s;background:#f2f2f2;border-color:#d9d9d9}.flat .dijitButtonHover.alt-primary .dijitButtonNode,.flat .dijitComboBoxHover.alt-primary .dijitButtonNode,.flat .dijitComboButton.alt-primary .dijitButtonNodeHover,.flat .dijitComboButton.alt-primary .dijitDownArrowButtonHover,.flat .dijitDropDownButtonHover.alt-primary .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-primary .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-primary .dijitButtonContents,.flat .dijitSelectHover.alt-primary .dijitButtonContents,.flat .dijitSelectHover.alt-primary .dijitButtonNode,.flat .dijitSpinner.alt-primary .dijitDownArrowButtonHover,.flat .dijitSpinner.alt-primary .dijitUpArrowButtonHover,.flat .dijitToggleButtonHover.alt-primary .dijitButtonNode{background:#1981dd;border-color:#1774c5}.flat .dijitButtonHover.alt-success .dijitButtonNode,.flat .dijitComboBoxHover.alt-success .dijitButtonNode,.flat .dijitComboButton.alt-success .dijitButtonNodeHover,.flat .dijitComboButton.alt-success .dijitDownArrowButtonHover,.flat .dijitDropDownButtonHover.alt-success .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-success .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-success .dijitButtonContents,.flat .dijitSelectHover.alt-success .dijitButtonContents,.flat .dijitSelectHover.alt-success .dijitButtonNode,.flat .dijitSpinner.alt-success .dijitDownArrowButtonHover,.flat .dijitSpinner.alt-success .dijitUpArrowButtonHover,.flat .dijitToggleButtonHover.alt-success .dijitButtonNode{background:#409843;border-color:#39883c}.flat .dijitButtonHover.alt-info .dijitButtonNode,.flat .dijitComboBoxHover.alt-info .dijitButtonNode,.flat .dijitComboButton.alt-info .dijitButtonNodeHover,.flat .dijitComboButton.alt-info .dijitDownArrowButtonHover,.flat .dijitDropDownButtonHover.alt-info .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-info .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-info .dijitButtonContents,.flat .dijitSelectHover.alt-info .dijitButtonContents,.flat .dijitSelectHover.alt-info .dijitButtonNode,.flat .dijitSpinner.alt-info .dijitDownArrowButtonHover,.flat .dijitSpinner.alt-info .dijitUpArrowButtonHover,.flat .dijitToggleButtonHover.alt-info .dijitButtonNode{background:#03a1e8;border-color:#0390cf}.flat .dijitButtonHover.alt-warning .dijitButtonNode,.flat .dijitComboBoxHover.alt-warning .dijitButtonNode,.flat .dijitComboButton.alt-warning .dijitButtonNodeHover,.flat .dijitComboButton.alt-warning .dijitDownArrowButtonHover,.flat .dijitDropDownButtonHover.alt-warning .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-warning .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-warning .dijitButtonContents,.flat .dijitSelectHover.alt-warning .dijitButtonContents,.flat .dijitSelectHover.alt-warning .dijitButtonNode,.flat .dijitSpinner.alt-warning .dijitDownArrowButtonHover,.flat .dijitSpinner.alt-warning .dijitUpArrowButtonHover,.flat .dijitToggleButtonHover.alt-warning .dijitButtonNode{background:#ee8500;border-color:#d57700}.flat .dijitButtonHover.alt-danger .dijitButtonNode,.flat .dijitComboBoxHover.alt-danger .dijitButtonNode,.flat .dijitComboButton.alt-danger .dijitButtonNodeHover,.flat .dijitComboButton.alt-danger .dijitDownArrowButtonHover,.flat .dijitDropDownButtonHover.alt-danger .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-danger .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-danger .dijitButtonContents,.flat .dijitSelectHover.alt-danger .dijitButtonContents,.flat .dijitSelectHover.alt-danger .dijitButtonNode,.flat .dijitSpinner.alt-danger .dijitDownArrowButtonHover,.flat .dijitSpinner.alt-danger .dijitUpArrowButtonHover,.flat .dijitToggleButtonHover.alt-danger .dijitButtonNode{background:#e32d29;border-color:#d4201b}.flat .dijitButtonHover.alt-inverse .dijitButtonNode,.flat .dijitComboBoxHover.alt-inverse .dijitButtonNode,.flat .dijitComboButton.alt-inverse .dijitButtonNodeHover,.flat .dijitComboButton.alt-inverse .dijitDownArrowButtonHover,.flat .dijitDropDownButtonHover.alt-inverse .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-inverse .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-inverse .dijitButtonContents,.flat .dijitSelectHover.alt-inverse .dijitButtonContents,.flat .dijitSelectHover.alt-inverse .dijitButtonNode,.flat .dijitSpinner.alt-inverse .dijitDownArrowButtonHover,.flat .dijitSpinner.alt-inverse .dijitUpArrowButtonHover,.flat .dijitToggleButtonHover.alt-inverse .dijitButtonNode{background:#5c5c5c;border-color:#525252}.flat .dijitButtonActive .dijitButtonNode,.flat .dijitComboButton .dijitButtonNodeActive,.flat .dijitComboButton .dijitDownArrowButtonActive,.flat .dijitDropDownButtonActive .dijitButtonNode,.flat .dijitToggleButtonActive .dijitButtonNode,.flat .dijitToggleButtonChecked .dijitButtonNode{-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none;transition:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.05);box-shadow:inset 0 3px 5px rgba(0,0,0,.05);background:#e0e0e0;border-color:#b3b3b3}.flat .dijitButtonActive.alt-primary .dijitButtonNode,.flat .dijitComboBox.alt-primary .dijitButtonNode.dijitHasDropDownOpen,.flat .dijitComboBoxActive.alt-primary .dijitButtonNode,.flat .dijitComboButton.alt-primary .dijitButtonNodeActive,.flat .dijitDropDownButtonActive.alt-primary .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-primary .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-primary .dijitButtonContents,.flat .dijitSelectActive.alt-primary .dijitArrowButton,.flat .dijitSelectActive.alt-primary .dijitButtonContents,.flat .dijitSpinner.alt-primary .dijitDownArrowButtonActive,.flat .dijitSpinner.alt-primary .dijitUpArrowButtonActive,.flat .dijitToggleButtonActive.alt-primary .dijitButtonNode{background:#1878cc;border-color:#135fa3}.flat .dijitButtonActive.alt-success .dijitButtonNode,.flat .dijitComboBox.alt-success .dijitButtonNode.dijitHasDropDownOpen,.flat .dijitComboBoxActive.alt-success .dijitButtonNode,.flat .dijitComboButton.alt-success .dijitButtonNodeActive,.flat .dijitDropDownButtonActive.alt-success .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-success .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-success .dijitButtonContents,.flat .dijitSelectActive.alt-success .dijitArrowButton,.flat .dijitSelectActive.alt-success .dijitButtonContents,.flat .dijitSpinner.alt-success .dijitDownArrowButtonActive,.flat .dijitSpinner.alt-success .dijitUpArrowButtonActive,.flat .dijitToggleButtonActive.alt-success .dijitButtonNode{background:#3b8d3e;border-color:#2f7032}.flat .dijitButtonActive.alt-info .dijitButtonNode,.flat .dijitComboBox.alt-info .dijitButtonNode.dijitHasDropDownOpen,.flat .dijitComboBoxActive.alt-info .dijitButtonNode,.flat .dijitComboButton.alt-info .dijitButtonNodeActive,.flat .dijitDropDownButtonActive.alt-info .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-info .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-info .dijitButtonContents,.flat .dijitSelectActive.alt-info .dijitArrowButton,.flat .dijitSelectActive.alt-info .dijitButtonContents,.flat .dijitSpinner.alt-info .dijitDownArrowButtonActive,.flat .dijitSpinner.alt-info .dijitUpArrowButtonActive,.flat .dijitToggleButtonActive.alt-info .dijitButtonNode{background:#0395d7;border-color:#0276ab}.flat .dijitButtonActive.alt-warning .dijitButtonNode,.flat .dijitComboBox.alt-warning .dijitButtonNode.dijitHasDropDownOpen,.flat .dijitComboBoxActive.alt-warning .dijitButtonNode,.flat .dijitComboButton.alt-warning .dijitButtonNodeActive,.flat .dijitDropDownButtonActive.alt-warning .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-warning .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-warning .dijitButtonContents,.flat .dijitSelectActive.alt-warning .dijitArrowButton,.flat .dijitSelectActive.alt-warning .dijitButtonContents,.flat .dijitSpinner.alt-warning .dijitDownArrowButtonActive,.flat .dijitSpinner.alt-warning .dijitUpArrowButtonActive,.flat .dijitToggleButtonActive.alt-warning .dijitButtonNode{background:#dd7b00;border-color:#b06200}.flat .dijitButtonActive.alt-danger .dijitButtonNode,.flat .dijitComboBox.alt-danger .dijitButtonNode.dijitHasDropDownOpen,.flat .dijitComboBoxActive.alt-danger .dijitButtonNode,.flat .dijitComboButton.alt-danger .dijitButtonNodeActive,.flat .dijitDropDownButtonActive.alt-danger .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-danger .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-danger .dijitButtonContents,.flat .dijitSelectActive.alt-danger .dijitArrowButton,.flat .dijitSelectActive.alt-danger .dijitButtonContents,.flat .dijitSpinner.alt-danger .dijitDownArrowButtonActive,.flat .dijitSpinner.alt-danger .dijitUpArrowButtonActive,.flat .dijitToggleButtonActive.alt-danger .dijitButtonNode{background:#dc211c;border-color:#af1a17}.flat .dijitButtonActive.alt-inverse .dijitButtonNode,.flat .dijitComboBox.alt-inverse .dijitButtonNode.dijitHasDropDownOpen,.flat .dijitComboBoxActive.alt-inverse .dijitButtonNode,.flat .dijitComboButton.alt-inverse .dijitButtonNodeActive,.flat .dijitDropDownButtonActive.alt-inverse .dijitButtonNode,.flat .dijitSelect.dijitSelectOpened.alt-inverse .dijitArrowButton,.flat .dijitSelect.dijitSelectOpened.alt-inverse .dijitButtonContents,.flat .dijitSelectActive.alt-inverse .dijitArrowButton,.flat .dijitSelectActive.alt-inverse .dijitButtonContents,.flat .dijitSpinner.alt-inverse .dijitDownArrowButtonActive,.flat .dijitSpinner.alt-inverse .dijitUpArrowButtonActive,.flat .dijitToggleButtonActive.alt-inverse .dijitButtonNode{background:#555;border-color:#444}.flat .dijitButtonDisabled,.flat .dijitComboButtonDisabled,.flat .dijitDropDownButtonDisabled,.flat .dijitToggleButtonDisabled{outline:0}.flat .dijitButtonDisabled .dijitButtonNode,.flat .dijitComboButtonDisabled .dijitButtonNode,.flat .dijitDropDownButtonDisabled .dijitButtonNode,.flat .dijitToggleButtonDisabled .dijitButtonNode{cursor:default;color:#9e9e9e;background-color:#f5f5f5;border-color:#e3e3e3}.flat .dijitButtonDisabled.alt-primary .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-primary .dijitButtonNode,.flat .dijitDropDownButtonDisabled.alt-primary .dijitButtonNode,.flat .dijitToggleButtonDisabled.alt-primary .dijitButtonNode{background:#6db2ee;border-color:#50a2eb;color:#f2f2f2}.flat .dijitComboBoxDisabled.alt-success .dijitButtonNode,.flat .dijitComboButtonRtlDisabled.alt-success .dijitStretch,.flat .dijitDateTextBoxDisabled.alt-success .dijitButtonNode,.flat .dijitTimeTextBoxDisabled.alt-success .dijitButtonNode{border-left-color:#63be67}.flat .dijitComboBoxRtlDisabled.alt-success .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-success .dijitStretch,.flat .dijitDateTextBoxRtlDisabled.alt-success .dijitButtonNode,.flat .dijitTimeTextBoxRtlDisabled.alt-success .dijitButtonNode{border-right-color:#63be67}.flat .dijitButtonDisabled.alt-success .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-success .dijitButtonNode,.flat .dijitDropDownButtonDisabled.alt-success .dijitButtonNode,.flat .dijitToggleButtonDisabled.alt-success .dijitButtonNode{background:#7dc981;border-color:#63be67;color:#f2f2f2}.flat .dijitComboBoxDisabled.alt-info .dijitButtonNode,.flat .dijitComboButtonRtlDisabled.alt-info .dijitStretch,.flat .dijitDateTextBoxDisabled.alt-info .dijitButtonNode,.flat .dijitTimeTextBoxDisabled.alt-info .dijitButtonNode{border-left-color:#34befd}.flat .dijitComboBoxRtlDisabled.alt-info .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-info .dijitStretch,.flat .dijitDateTextBoxRtlDisabled.alt-info .dijitButtonNode,.flat .dijitTimeTextBoxRtlDisabled.alt-info .dijitButtonNode{border-right-color:#34befd}.flat .dijitButtonDisabled.alt-info .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-info .dijitButtonNode,.flat .dijitDropDownButtonDisabled.alt-info .dijitButtonNode,.flat .dijitToggleButtonDisabled.alt-info .dijitButtonNode{background:#56c9fd;border-color:#34befd;color:#f2f2f2}.flat .dijitComboBoxDisabled.alt-warning .dijitButtonNode,.flat .dijitComboButtonRtlDisabled.alt-warning .dijitStretch,.flat .dijitDateTextBoxDisabled.alt-warning .dijitButtonNode,.flat .dijitTimeTextBoxDisabled.alt-warning .dijitButtonNode{border-left-color:#ffa635}.flat .dijitComboBoxRtlDisabled.alt-warning .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-warning .dijitStretch,.flat .dijitDateTextBoxRtlDisabled.alt-warning .dijitButtonNode,.flat .dijitTimeTextBoxRtlDisabled.alt-warning .dijitButtonNode{border-right-color:#ffa635}.flat .dijitButtonDisabled.alt-warning .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-warning .dijitButtonNode,.flat .dijitDropDownButtonDisabled.alt-warning .dijitButtonNode,.flat .dijitToggleButtonDisabled.alt-warning .dijitButtonNode{background:#ffb557;border-color:#ffa635;color:#f2f2f2}.flat .dijitComboBoxDisabled.alt-danger .dijitButtonNode,.flat .dijitComboButtonRtlDisabled.alt-danger .dijitStretch,.flat .dijitDateTextBoxDisabled.alt-danger .dijitButtonNode,.flat .dijitTimeTextBoxDisabled.alt-danger .dijitButtonNode{border-left-color:#eb6561}.flat .dijitComboBoxRtlDisabled.alt-danger .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-danger .dijitStretch,.flat .dijitDateTextBoxRtlDisabled.alt-danger .dijitButtonNode,.flat .dijitTimeTextBoxRtlDisabled.alt-danger .dijitButtonNode{border-right-color:#eb6561}.flat .dijitButtonDisabled.alt-danger .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-danger .dijitButtonNode,.flat .dijitDropDownButtonDisabled.alt-danger .dijitButtonNode,.flat .dijitToggleButtonDisabled.alt-danger .dijitButtonNode{background:#ee7e7c;border-color:#eb6561;color:#f2f2f2}.flat .dijitComboBoxDisabled.alt-inverse .dijitButtonNode,.flat .dijitComboButtonRtlDisabled.alt-inverse .dijitStretch,.flat .dijitDateTextBoxDisabled.alt-inverse .dijitButtonNode,.flat .dijitTimeTextBoxDisabled.alt-inverse .dijitButtonNode{border-left-color:#848484}.flat .dijitComboBoxRtlDisabled.alt-inverse .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-inverse .dijitStretch,.flat .dijitDateTextBoxRtlDisabled.alt-inverse .dijitButtonNode,.flat .dijitTimeTextBoxRtlDisabled.alt-inverse .dijitButtonNode{border-right-color:#848484}.flat .dijitButtonDisabled.alt-inverse .dijitButtonNode,.flat .dijitComboButtonDisabled.alt-inverse .dijitButtonNode,.flat .dijitDropDownButtonDisabled.alt-inverse .dijitButtonNode,.flat .dijitToggleButtonDisabled.alt-inverse .dijitButtonNode{background:#989898;border-color:#848484;color:#f2f2f2}.flat .dijitComboButtonDisabled .dijitArrowButton{border-left-width:0}.flat .dijitDropDownButton .dijitButtonNode{padding-right:8px}.flat table.dijitComboButton .dijitStretch{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.flat table.dijitComboButton .dijitArrowButton{padding:4px;width:20px;-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;border-left-width:0}.flat .dijitCheckBox,.flat .dijitCheckedMenuItem .dijitCheckedMenuItemIcon{border:1px solid #9e9e9e;width:16px;text-align:center;overflow:visible;height:16px}.flat .dijitToggleButtonChecked .dijitIcon{display:inline-block}.flat .dijitDropDownButton .dijitArrowButtonInner{margin-left:3px}.flat .dijitArrowButton,.flat .dijitDropDownButton .dijitArrowButtonInner{line-height:1}.flat .dijitArrowButton:before,.flat .dijitDropDownButton .dijitArrowButtonInner:before{content:"\f002"}.flat .dijitLeftArrowButton:before{content:"\f000"}.flat .dijitRightArrowButton:before{content:"\f001"}.flat .dijitUpArrowButton:before{content:"\f003"}.flat .dijitCheckBoxChecked:before,.flat .dijitCheckBoxCheckedDisabled:before,.flat .dijitCheckBoxIcon:before,.flat .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon:before{line-height:1;font-size:16px;content:"\f00c";speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:flat-icon}.flat .dijitCheckBox{background-color:#fff;line-height:1;padding:0;-webkit-border-radius:2px;border-radius:2px;position:relative;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;-o-transition:all .1s linear;-ms-transition:all .1s linear;transition:all .1s linear}.flat .dijitCheckBox input{position:absolute;top:0}.flat .dijitCheckBoxChecked:before,.flat .dijitCheckBoxCheckedDisabled:before,.flat .dijitCheckBoxIcon:before{color:#fff}.flat .dijitCheckBoxIcon{padding:0}.flat .dijitCheckBoxIcon:before{color:#2196f3}.flat .alt-danger .dijitCheckBoxIcon:before,.flat .alt-info .dijitCheckBoxIcon:before,.flat .alt-inverse .dijitCheckBoxIcon:before,.flat .alt-primary .dijitCheckBoxIcon:before,.flat .alt-success .dijitCheckBoxIcon:before,.flat .alt-warning .dijitCheckBoxIcon:before{color:#fff}.flat .dijitCheckBoxChecked{background-color:#2196f3;border-color:#2196f3}.flat .dijitCheckBoxHover{background-color:#fff;border:1px solid #2196f3}.flat .dijitCheckBoxCheckedHover{background-color:#42a6f5;border:1px solid #2196f3}.flat .dijitCheckBoxDisabled{color:#9e9e9e;background-color:#f5f5f5;border-color:#e3e3e3}.flat .dijitCheckBoxCheckedDisabled{color:#a6a6a6;background-color:#6fbbf7;border-color:#6fbbf7}.flat .dijitCheckedMenuItem .dijitCheckedMenuItemIcon{background-color:#fff;line-height:1;padding:0;-webkit-border-radius:2px;border-radius:2px;position:relative;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;-o-transition:all .1s linear;-ms-transition:all .1s linear;transition:all .1s linear}.dijitMenuItemRtl,.dj_ie .dijitSliderRtl .dijitRuleContainerV,div.dijitNumberTextBoxRtl{text-align:right}.flat .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon:before{color:#2196f3}.flat .dijitSpinner .dijitSpinnerButtonContainer{overflow:hidden;position:relative;width:auto;padding:0;border:1px solid #9e9e9e}.flat .dijitSpinner .dijitSpinnerButtonInner{width:30px;padding:4px 0!important;margin:0}.flat .dijitSpinner .dijitArrowButton{line-height:20px;cursor:pointer;-webkit-transition:all 50ms linear;-moz-transition:all 50ms linear;-o-transition:all 50ms linear;-ms-transition:all 50ms linear;transition:all 50ms linear;background:#fff;-webkit-border-radius:0;border-radius:0;border:0;width:auto;overflow:hidden;left:0;right:0;padding:0}.flat .dijitSpinner .dijitArrowButton:before{content:none}.flat .dijitSpinner .dijitUpArrowButton{border-top-right-radius:2px}.flat .dijitSpinner .dijitDownArrowButton{border-bottom-right-radius:2px}.flat .dijitSpinner .dijitDownArrowButtonHover,.flat .dijitSpinner .dijitUpArrowButtonHover{-webkit-transition:all .1s;-moz-transition:all .1s;-o-transition:all .1s;-ms-transition:all .1s;transition:all .1s;background:#f2f2f2;border-color:#d9d9d9}.flat .dijitSpinner .dijitDownArrowButtonActive,.flat .dijitSpinner .dijitUpArrowButtonActive{-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none;transition:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.05);box-shadow:inset 0 3px 5px rgba(0,0,0,.05);background:#e0e0e0;border-color:#b3b3b3}.flat .dijitSpinner .dijitArrowButtonInner{line-height:16px;display:block}.flat .dijitSpinner .dijitArrowButtonInner .dijitInputField{padding:0}.flat .dijitSpinner .dijitArrowButtonInner:before{content:"\f003"}.flat .dijitSpinner .dijitDownArrowButton .dijitArrowButtonInner:before{content:"\f002"}.flat .dijitSpinnerDisabled .dijitDownArrowButton,.flat .dijitSpinnerDisabled .dijitUpArrowButton{cursor:default;color:#9e9e9e;background-color:#f5f5f5;border-color:#e3e3e3}.flat .alt-primary .dijitSpinnerButtonContainer{border-color:#1e88e5}.flat .alt-success .dijitSpinnerButtonContainer{border-color:#43a047}.flat .alt-info .dijitSpinnerButtonContainer{border-color:#03a9f4}.flat .alt-warning .dijitSpinnerButtonContainer{border-color:#fb8c00}.flat .alt-danger .dijitSpinnerButtonContainer{border-color:#e53935}.flat .alt-inverse .dijitSpinnerButtonContainer{border-color:#616161}.flat .dijitRadio,.flat .dijitRadioIcon{width:16px;height:16px;background:#fff;border:1px solid #2196f3;-webkit-border-radius:50%;border-radius:50%;position:relative;overflow:visible;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.flat .dijitRadio:after,.flat .dijitRadioIcon:after{content:" ";display:block;width:0;height:0;background-color:#2196f3;-webkit-border-radius:50%;border-radius:50%;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);margin:8px;position:absolute;top:0;left:0;-webkit-transition:all .15s ease-in-out;-moz-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;-ms-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.flat .alt-danger .dijitRadioIcon:after,.flat .alt-info .dijitRadioIcon:after,.flat .alt-inverse .dijitRadioIcon:after,.flat .alt-primary .dijitRadioIcon:after,.flat .alt-success .dijitRadioIcon:after,.flat .alt-warning .dijitRadioIcon:after{background-color:#fff}.flat .dijitRadioHover{border-color:#59b0f6}.flat .alt-danger .dijitRadioIcon,.flat .alt-info .dijitRadioIcon,.flat .alt-inverse .dijitRadioIcon,.flat .alt-primary .dijitRadioIcon,.flat .alt-success .dijitRadioIcon,.flat .alt-warning .dijitRadioIcon{border-color:#fff}.flat .dijitChecked .dijitRadioIcon:after,.flat .dijitRadioChecked:after{width:8px;height:8px;margin:3px;opacity:1;-ms-filter:none;filter:none}.flat .dijitRadioDisabled{background-color:#f5f5f5;border-color:#e3e3e3}.flat .dijitRadioCheckedDisabled{background-color:#f5f5f5;border-color:#6fbbf7}.flat .dijitRadioCheckedDisabled:after{background-color:#6fbbf7}.flat .dijitRadioMenuItem .dijitCheckedMenuItemIcon{width:16px;height:16px;background:#fff;border:1px solid #9e9e9e;-webkit-border-radius:50%;border-radius:50%;position:relative;overflow:visible;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.flat .dijitRadioMenuItemChecked .dijitCheckedMenuItemIcon,.flat .dijitSelect{border-color:#9e9e9e}.flat .dijitRadioMenuItem .dijitCheckedMenuItemIcon:after{content:" ";display:block;width:0;height:0;background-color:#2196f3;-webkit-border-radius:50%;border-radius:50%;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);margin:8px;position:absolute;top:0;left:0;-webkit-transition:all .15s ease-in-out;-moz-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;-ms-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.flat .dijitRadioMenuItemChecked .dijitCheckedMenuItemIcon:after{width:8px;height:8px;margin:3px;opacity:1;-ms-filter:none;filter:none}.flat .dijitComboBox .dijitArrowButtonInner,.flat .dijitSelect .dijitArrowButtonInner{margin:0;width:0;height:0}.flat .dijitComboBox .dijitArrowButton,.flat .dijitSelect .dijitArrowButton{width:20px;padding:4px}.flat .dijitSelect{border-style:solid;border-width:1px;padding:4px;-webkit-border-radius:3px;border-radius:3px;line-height:20px;cursor:pointer;-webkit-transition:all 50ms linear;-moz-transition:all 50ms linear;-o-transition:all 50ms linear;-ms-transition:all 50ms linear;transition:all 50ms linear;background:#fff;table-layout:fixed}.flat .dijitSelect .dijitArrowButton,.flat .dijitSelect .dijitButtonContents{line-height:20px;padding:4px 12px;border:0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.flat .dijitSelect .dijitButtonContents{padding:0;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.flat .dijitSelect .dijitInputField{padding:0 0 0 12px}.flat .dijitSelectHover{-webkit-transition:all .1s;-moz-transition:all .1s;-o-transition:all .1s;-ms-transition:all .1s;transition:all .1s;background:#f2f2f2;border-color:#d9d9d9}.flat .dijitSelectActive{-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none;transition:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.05);box-shadow:inset 0 3px 5px rgba(0,0,0,.05);background:#e0e0e0;border-color:#b3b3b3}.flat .dijitSelectFocused{border:1px solid #9e9e9e}.flat .dijitSelectDisabled{cursor:default;color:#9e9e9e;background-color:#f5f5f5;border-color:#e3e3e3}.flat .dijitComboBox .dijitButtonNode{border-style:solid;border-width:1px;border-color:#9e9e9e;padding:4px;line-height:20px;cursor:pointer;-webkit-transition:all 50ms linear;-moz-transition:all 50ms linear;-o-transition:all 50ms linear;-ms-transition:all 50ms linear;transition:all 50ms linear;background:#fff;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.flat .dijitComboBox .dijitDownArrowButtonHover,.flat .dijitComboBoxOpenHover .dijitButtonNode{-webkit-transition:all .1s;-moz-transition:all .1s;-o-transition:all .1s;-ms-transition:all .1s;transition:all .1s;background:#f2f2f2;border-color:#d9d9d9;-webkit-box-shadow:none;box-shadow:none}.flat .dijitComboBoxDisabled .dijitButtonNode{cursor:default;color:#9e9e9e;background-color:#f5f5f5;border-color:#e3e3e3}.flat .dijitToolbar .dijitComboBox .dijitArrowButtonInner{border:none}.flat .dijitDateTextBox .dijitArrowButton:before{content:"\f01e"}.flat .dijitTimeTextBox .dijitArrowButton:before{content:"\f01f"}.flat select{padding:4px 0;border:1px solid #9e9e9e;-webkit-box-shadow:0 1px .5px rgba(0,0,0,.3),0 2px 2px rgba(0,0,0,.2);box-shadow:0 1px .5px rgba(0,0,0,.3),0 2px 2px rgba(0,0,0,.2)}.flat select option{padding:4px 8px}.flat .dijitRuleLabelsContainerH,.flat .dijitRuleLabelsContainerV{padding:0}.flat .dijitSelectMenu td.dijitMenuArrowCell,.flat .dijitSelectMenu td.dijitMenuItemIconCell{display:none}.flat .dijitSliderBar{border-style:solid;outline:1px}.flat .dijitRuleLabelsContainer{color:#424242;font-size:smaller}.flat .dijitSliderDisabled{opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitSliderBarH,.flat .dijitSliderBumperH{height:3px}.flat .dijitSlider .dijitSliderLeftBumper{-webkit-border-radius:1.5px 0 0 1.5px;border-radius:1.5px 0 0 1.5px;margin-left:4px}.flat .dijitSlider .dijitSliderRightBumper{-webkit-border-radius:0 1.5px 1.5px 0;border-radius:0 1.5px 1.5px 0;margin-left:-2px;margin-right:4px}.flat .dijitSlider .dijitSliderLeftBumper,.flat .dijitSlider .dijitSliderProgressBarH{border:0;background-color:#2196f3;background-image:none}.flat .dijitSlider .dijitSliderRemainingBarH,.flat .dijitSlider .dijitSliderRightBumper{border:0;background-color:#9e9e9e}.flat .dijitSliderHover .dijitSliderLeftBumper,.flat .dijitSliderHover .dijitSliderProgressBarH{background-color:#0d8cf1;background-image:none}.flat .dijitSliderFocused .dijitSliderLeftBumper,.flat .dijitSliderFocused .dijitSliderProgressBarH,.flat .dijitSliderFocused .dijitSliderRemainingBarH,.flat .dijitSliderFocused .dijitSliderRightBumper{-webkit-box-shadow:none;box-shadow:none}.flat .dijitSliderBarV,.flat .dijitSliderBumperV{width:3px}.flat .dijitSlider .dijitSliderTopBumper{-webkit-border-radius:1.5px 1.5px 0 0;border-radius:1.5px 1.5px 0 0;margin-top:4px;margin-bottom:-2px}.flat .dijitSlider .dijitSliderBottomBumper{-webkit-border-radius:0 0 1.5px 1.5px;border-radius:0 0 1.5px 1.5px;margin-bottom:4px}.flat .dijitSlider .dijitSliderBottomBumper,.flat .dijitSlider .dijitSliderProgressBarV{border:0;background-color:#2196f3;background-image:none}.flat .dijitSlider .dijitSliderRemainingBarV,.flat .dijitSlider .dijitSliderTopBumper{border:0;background-color:#9e9e9e}.flat .dijitSliderHover .dijitSliderBottomBumper,.flat .dijitSliderHover .dijitSliderProgressBarV{background-color:#0d8cf1;background-image:none}.flat .dijitSliderFocused .dijitSliderBottomBumper,.flat .dijitSliderFocused .dijitSliderProgressBarV,.flat .dijitSliderFocused .dijitSliderRemainingBarV,.flat .dijitSliderFocused .dijitSliderTopBumper{-webkit-box-shadow:none;box-shadow:none}.flat .dijitSliderImageHandle{background:#fff;-webkit-box-shadow:0 1px .5px rgba(0,0,0,.3),0 2px 2px rgba(0,0,0,.2);box-shadow:0 1px .5px rgba(0,0,0,.3),0 2px 2px rgba(0,0,0,.2);-webkit-border-radius:50%;border-radius:50%;border:1px solid #2196f3;width:16px;height:16px;margin-top:-2px;position:absolute;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.flat .dijitSliderImageHandle:after{content:"";display:block;background:#2196f3;-webkit-border-radius:50%;border-radius:50%;height:10px;width:10px;left:2px;top:2px;position:absolute}.flat .dijitSliderDecrementIconH .dijitSliderButtonInner,.flat .dijitSliderDecrementIconV .dijitSliderButtonInner,.flat .dijitSliderDisabled.dijitSliderFocused .dijitSliderImageHandle:after,.flat .dijitSliderIncrementIconH .dijitSliderButtonInner,.flat .dijitSliderIncrementIconV .dijitSliderButtonInner,.flat .dijitValidationTextBoxError .dijitValidationIcon{display:none}.flat .dijitSliderImageHandleV{margin-top:0}.flat .dijitSliderFocused .dijitSliderImageHandle,.flat .dijitSliderHover .dijitSliderImageHandle{-webkit-box-shadow:0 4px 2px -2px rgba(0,0,0,.3),0 4px 6px rgba(0,0,0,.2);box-shadow:0 4px 2px -2px rgba(0,0,0,.3),0 4px 6px rgba(0,0,0,.2)}.flat .dijitSliderDecrementIconH,.flat .dijitSliderDecrementIconV,.flat .dijitSliderIncrementIconH,.flat .dijitSliderIncrementIconV{border-style:solid;border-width:1px;border-color:#9e9e9e;-webkit-border-radius:3px;border-radius:3px;-webkit-transition:all 50ms linear;-moz-transition:all 50ms linear;-o-transition:all 50ms linear;-ms-transition:all 50ms linear;transition:all 50ms linear;background:#fff;height:20px;width:20px;cursor:pointer;color:#2196f3;padding:0;font-family:flat-icon;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;font-size:16px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.flat .dijitSliderDecrementIconH:hover,.flat .dijitSliderDecrementIconV:hover,.flat .dijitSliderIncrementIconH:hover,.flat .dijitSliderIncrementIconV:hover{-webkit-transition:all .1s;-moz-transition:all .1s;-o-transition:all .1s;-ms-transition:all .1s;transition:all .1s;background:#f2f2f2;border-color:#d9d9d9}.flat .dijitSliderDecrementIconH:active,.flat .dijitSliderDecrementIconV:active,.flat .dijitSliderIncrementIconH:active,.flat .dijitSliderIncrementIconV:active{-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none;transition:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.05);box-shadow:inset 0 3px 5px rgba(0,0,0,.05);background:#e0e0e0;border-color:#b3b3b3}.flat .dijitSliderDisabled .dijitSliderDecrementIconH,.flat .dijitSliderDisabled .dijitSliderDecrementIconV,.flat .dijitSliderDisabled .dijitSliderIncrementIconH,.flat .dijitSliderDisabled .dijitSliderIncrementIconV,.flat .dijitSliderReadOnly .dijitSliderDecrementIconH,.flat .dijitSliderReadOnly .dijitSliderDecrementIconV,.flat .dijitSliderReadOnly .dijitSliderIncrementIconH,.flat .dijitSliderReadOnly .dijitSliderIncrementIconV{opacity:.65;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=65)";filter:alpha(opacity=65)}.flat .dijitSliderDecrementIconH:before,.flat .dijitSliderDecrementIconV:before,.flat .dijitSliderIncrementIconH:before,.flat .dijitSliderIncrementIconV:before{content:"\f011";top:0;line-height:20px}.flat .dijitSliderDecrementIconH:before,.flat .dijitSliderDecrementIconV:before{content:"\f012"}.flat .dijitRuleMark{border:0}.flat .dijitRuleMarkH{border-right:1px solid #e0e0e0}.flat .dijitRuleMarkV{border-bottom:1px solid #e0e0e0}.flat .dijitRuleLabelContainerH{margin-top:2px;margin-bottom:2px}.flat .dijitRuleLabelContainerV{margin-left:2px;margin-right:2px}.flat .dijitInputInner,.flat .dijitTextBox{line-height:20px}.dijitEditorIcon,.dijitIcon,.flat .dijitValidationTextBoxError .dijitValidationContainer,[class*=" flat-"],[class^=flat-]{speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.flat .dijitTextBox{background:#fff;border:1px solid #9e9e9e;-webkit-border-radius:3px;border-radius:3px;-webkit-transition:border .2s linear 0s,box-shadow .2s linear 0s;-moz-transition:border .2s linear 0s,box-shadow .2s linear 0s;-o-transition:border .2s linear 0s,box-shadow .2s linear 0s;-ms-transition:border .2s linear 0s,box-shadow .2s linear 0s;transition:border .2s linear 0s,box-shadow .2s linear 0s}.flat .dijitTextArea{padding:4px 6px}.flat .dijitTextBox .dijitInputField{padding:0 4px;margin:0 2px}.flat .dijitComboBox.alt-primary,.flat .dijitSelect.alt-primary,.flat .dijitSpinner.alt-primary{border-color:#1e88e5}.flat .dijitComboBox.alt-success,.flat .dijitSelect.alt-success,.flat .dijitSpinner.alt-success{border-color:#43a047}.flat .dijitComboBox.alt-info,.flat .dijitSelect.alt-info,.flat .dijitSpinner.alt-info{border-color:#03a9f4}.flat .dijitComboBox.alt-warning,.flat .dijitSelect.alt-warning,.flat .dijitSpinner.alt-warning{border-color:#fb8c00}.flat .dijitComboBox.alt-danger,.flat .dijitSelect.alt-danger,.flat .dijitSpinner.alt-danger{border-color:#e53935}.flat .dijitComboBox.alt-inverse,.flat .dijitSelect.alt-inverse,.flat .dijitSpinner.alt-inverse{border-color:#616161}.flat .dijitTextBox .dijitInputField .dijitPlaceHolder,.flat .dijitTextBox .dijitInputInner,.flat .dijitValidationTextBox .dijitValidationContainer{padding:4px}.flat .dijitTextBoxHover{border-color:#2196f3;-webkit-transition-duration:.25s;-moz-transition-duration:.25s;-o-transition-duration:.25s;-ms-transition-duration:.25s;transition-duration:.25s}.flat .dijitTextBoxFocused{border-color:#2196f3;-webkit-transition-duration:.1s;-moz-transition-duration:.1s;-o-transition-duration:.1s;-ms-transition-duration:.1s;transition-duration:.1s}.flat .dijitTextBoxDisabled{color:#9e9e9e;background-color:#f5f5f5;border-color:#e3e3e3}.flat .dijitComboBoxDisabled.alt-primary,.flat .dijitSpinnerDisabled.alt-primary{background:#f5f5f5;color:#9e9e9e;border:1px solid #6db2ee}.flat .dijitComboBoxDisabled.alt-primary .dijitButtonNode,.flat .dijitSelectDisabled.alt-primary .dijitButtonNode,.flat .dijitSelectDisabled.alt-primary .dijitStretch,.flat .dijitSpinnerDisabled.alt-primary .dijitButtonNode{background:#6db2ee;color:#f2f2f2}.flat .dijitSpinnerDisabled.alt-primary .dijitSpinnerButtonContainer{border-left-color:#6db2ee}.flat .dijitSpinnerRtlDisabled.alt-primary .dijitSpinnerButtonContainer{border-right-color:#6db2ee}.flat .dijitSelectDisabled.alt-primary{border-color:#6db2ee}.flat .dijitComboBoxDisabled.alt-success,.flat .dijitSpinnerDisabled.alt-success{background:#f5f5f5;color:#9e9e9e;border:1px solid #7dc981}.flat .dijitComboBoxDisabled.alt-success .dijitButtonNode,.flat .dijitSelectDisabled.alt-success .dijitButtonNode,.flat .dijitSelectDisabled.alt-success .dijitStretch,.flat .dijitSpinnerDisabled.alt-success .dijitButtonNode{background:#7dc981;color:#f2f2f2}.flat .dijitSpinnerDisabled.alt-success .dijitSpinnerButtonContainer{border-left-color:#7dc981}.flat .dijitSpinnerRtlDisabled.alt-success .dijitSpinnerButtonContainer{border-right-color:#7dc981}.flat .dijitSelectDisabled.alt-success{border-color:#7dc981}.flat .dijitComboBoxDisabled.alt-info,.flat .dijitSpinnerDisabled.alt-info{background:#f5f5f5;color:#9e9e9e;border:1px solid #56c9fd}.flat .dijitComboBoxDisabled.alt-info .dijitButtonNode,.flat .dijitSelectDisabled.alt-info .dijitButtonNode,.flat .dijitSelectDisabled.alt-info .dijitStretch,.flat .dijitSpinnerDisabled.alt-info .dijitButtonNode{background:#56c9fd;color:#f2f2f2}.flat .dijitSpinnerDisabled.alt-info .dijitSpinnerButtonContainer{border-left-color:#56c9fd}.flat .dijitSpinnerRtlDisabled.alt-info .dijitSpinnerButtonContainer{border-right-color:#56c9fd}.flat .dijitSelectDisabled.alt-info{border-color:#56c9fd}.flat .dijitComboBoxDisabled.alt-warning,.flat .dijitSpinnerDisabled.alt-warning{background:#f5f5f5;color:#9e9e9e;border:1px solid #ffb557}.flat .dijitComboBoxDisabled.alt-warning .dijitButtonNode,.flat .dijitSelectDisabled.alt-warning .dijitButtonNode,.flat .dijitSelectDisabled.alt-warning .dijitStretch,.flat .dijitSpinnerDisabled.alt-warning .dijitButtonNode{background:#ffb557;color:#f2f2f2}.flat .dijitSpinnerDisabled.alt-warning .dijitSpinnerButtonContainer{border-left-color:#ffb557}.flat .dijitSpinnerRtlDisabled.alt-warning .dijitSpinnerButtonContainer{border-right-color:#ffb557}.flat .dijitSelectDisabled.alt-warning{border-color:#ffb557}.flat .dijitComboBoxDisabled.alt-danger,.flat .dijitSpinnerDisabled.alt-danger{background:#f5f5f5;color:#9e9e9e;border:1px solid #ee7e7c}.flat .dijitComboBoxDisabled.alt-danger .dijitButtonNode,.flat .dijitSelectDisabled.alt-danger .dijitButtonNode,.flat .dijitSelectDisabled.alt-danger .dijitStretch,.flat .dijitSpinnerDisabled.alt-danger .dijitButtonNode{background:#ee7e7c;color:#f2f2f2}.flat .dijitSpinnerDisabled.alt-danger .dijitSpinnerButtonContainer{border-left-color:#ee7e7c}.flat .dijitSpinnerRtlDisabled.alt-danger .dijitSpinnerButtonContainer{border-right-color:#ee7e7c}.flat .dijitSelectDisabled.alt-danger{border-color:#ee7e7c}.flat .dijitComboBoxDisabled.alt-inverse,.flat .dijitSpinnerDisabled.alt-inverse{background:#f5f5f5;color:#9e9e9e;border:1px solid #989898}.flat .dijitComboBoxDisabled.alt-inverse .dijitButtonNode,.flat .dijitSelectDisabled.alt-inverse .dijitButtonNode,.flat .dijitSelectDisabled.alt-inverse .dijitStretch,.flat .dijitSpinnerDisabled.alt-inverse .dijitButtonNode{background:#989898;color:#f2f2f2}.flat .dijitSpinnerDisabled.alt-inverse .dijitSpinnerButtonContainer{border-left-color:#989898}.flat .dijitSpinnerRtlDisabled.alt-inverse .dijitSpinnerButtonContainer{border-right-color:#989898}.flat .dijitSelectDisabled.alt-inverse{border-color:#989898}.flat .dijitTextBoxError,.flat .dijitTextBoxError .dijitButtonNode{border-color:#dd2c00}.flat .dijitTextBoxErrorFocused,.flat .dijitTextBoxErrorFocused .dijitButtonNode{border:1px solid #bc2500}.flat .dijitValidationTextBoxError .dijitValidationContainer{color:#dd2c00;width:18px;font-family:flat-icon;font-size:18px}.flat .dijitValidationTextBoxError .dijitValidationContainer:before{content:"\f017"}@font-face{font-family:flat-icon;src:url(fonts/flat-icon.eot?90nq1s);src:url(fonts/flat-icon.eot?#iefix90nq1s) format('embedded-opentype'),url(fonts/flat-icon.ttf?90nq1s) format('truetype'),url(fonts/flat-icon.woff?90nq1s) format('woff'),url(fonts/flat-icon.svg?90nq1s#flat-icon) format('svg');font-weight:400;font-style:normal}[class*=" flat-"],[class^=flat-]{font-family:flat-icon}.dijitEditorIcon,.dijitIcon{font-family:flat-icon;font-size:16px;width:16px;height:16px}.flat-drop-left:before{content:"\f000"}.flat-drop-right:before{content:"\f001"}.flat-drop-down:before{content:"\f002"}.flat-drop-up:before{content:"\f003"}.flat-chevron-left:before{content:"\f004"}.flat-chevron-right:before{content:"\f005"}.flat-chevron-down:before{content:"\f006"}.flat-chevron-up:before{content:"\f007"}.flat-arrow-left:before{content:"\f008"}.flat-arrow-right:before{content:"\f009"}.flat-arrow-down:before{content:"\f00a"}.flat-arrow-up:before{content:"\f00b"}.flat-check:before{content:"\f00c"}.flat-check-circle:before{content:"\f00d"}.flat-close:before{content:"\f00e"}.dijitIconClear:before,.flat-close-circle:before{content:"\f00f"}.dijitEditorIconCancel:before,.flat-close-circle-o:before{content:"\f010"}.flat-add:before{content:"\f011"}.flat-remove:before{content:"\f012"}.flat-add-circle:before{content:"\f013"}.flat-remove-circle:before{content:"\f014"}.flat-add-circle-o:before{content:"\f015"}.flat-remove-circle-o:before{content:"\f016"}.dijitIconError:before,.flat-error:before{content:"\f017"}.flat-error-o:before{content:"\f018"}.flat-warning:before{content:"\f019"}.flat-report:before{content:"\f01a"}.flat-help:before{content:"\f01b"}.flat-no-symbol:before{content:"\f01c"}.flat-update:before{content:"\f01d"}.flat-calendar:before{content:"\f01e"}.flat-clock:before{content:"\f01f"}.dijitFolderClosed:before,.dijitIconFolderClosed:before,.flat-folder:before{content:"\f020"}.dijitFolderOpened:before,.dijitIconFolderOpen:before,.flat-folder-open:before{content:"\f021"}.dijitIconEdit:before,.flat-edit:before{content:"\f022"}.dijitEditorIconSave:before,.dijitIconSave:before,.flat-save:before{content:"\f023"}.dijitEditorIconPrint:before,.dijitIconPrint:before,.flat-print:before{content:"\f024"}.dijitEditorIconDelete:before,.dijitIconDelete:before,.flat-delete:before{content:"\f025"}.dijitLeaf:before,.flat-page:before{content:"\f026"}.flat-page-o:before{content:"\f027"}.flat-page-add:before{content:"\f028"}.flat-page-remove:before{content:"\f029"}.flat-page-add-o:before{content:"\f02a"}.flat-page-remove-o:before{content:"\f02b"}.dijitIconFile:before,.flat-file:before{content:"\f02c"}.dijitIconMail:before,.flat-mail:before{content:"\f02d"}.dijitIconDatabase:before,.flat-storage:before{content:"\f02e"}.dijitIconConfigure:before,.flat-settings:before{content:"\f02f"}.dijitIconSearch:before,.flat-search:before{content:"\f030"}.dijitIconBookmark:before,.flat-bookmark:before{content:"\f031"}.flat-menu:before{content:"\f032"}.dijitIconApplication:before,.flat-application:before{content:"\f033"}.dijitIconKey:before,.flat-key:before{content:"\f034"}.dijitEditorIconInsertTable:before,.dijitIconTable:before,.flat-table:before{content:"\f035"}.flat-grid:before{content:"\f036"}.dijitIconChart:before,.flat-chart:before{content:"\f037"}.dijitIconFilter:before,.flat-filter:before{content:"\f038"}.dijitIconFunction:before,.flat-function:before{content:"\f039"}.flat-user:before{content:"\f03a"}.dijitIconUsers:before,.flat-users:before{content:"\f03b"}.dijitIconConnector:before,.flat-connector:before{content:"\f03c"}.dijitIconDocuments:before,.flat-documents:before{content:"\f03d"}.dijitIconEditProperty:before,.flat-edit-property:before{content:"\f03e"}.dijitIconTask:before,.flat-task:before{content:"\f03f"}.dijitIconNewTask:before,.flat-task-new:before{content:"\f040"}.dijitIconEditTask:before,.flat-task-edit:before{content:"\f041"}.dijitIconSample:before,.flat-sample:before{content:"\f042"}.dijitIconPackage:before,.flat-package:before{content:"\f043"}.dijitEditorIconUndo:before,.flat-undo:before{content:"\f044"}.dijitEditorIconRedo:before,.flat-redo:before{content:"\f045"}.dijitEditorIconCopy:before,.dijitIconCopy:before,.flat-copy:before{content:"\f046"}.dijitEditorIconCut:before,.dijitIconCut:before,.flat-cut:before{content:"\f047"}.dijitEditorIconPaste:before,.flat-paste:before{content:"\f048"}.dijitEditorIconBold:before,.flat-bold:before{content:"\f049"}.dijitEditorIconItalic:before,.flat-italic:before{content:"\f04a"}.dijitEditorIconUnderline:before,.flat-underline:before{content:"\f04b"}.dijitEditorIconStrikethrough:before,.flat-strikethrough:before{content:"\f04c"}.dijitEditorIconRemoveFormat:before,.flat-clear-format:before{content:"\f04d"}.flat-quote:before{content:"\f04e"}.dijitEditorIconSuperscript:before,.flat-superscript:before{content:"\f04f"}.dijitEditorIconSubscript:before,.flat-subscript:before{content:"\f050"}.dijitEditorIconForeColor:before,.flat-color-text:before{content:"\f051"}.dijitEditorIconBackColor:before,.flat-color-fill:before{content:"\f052"}.dijitEditorIconHiliteColor:before,.flat-color-highlight:before{content:"\f053"}.flat-font-size:before{content:"\f054"}.dijitEditorIconJustifyCenter:before,.flat-align-center:before{content:"\f055"}.dijitEditorIconJustifyFull:before,.flat-align-justify:before{content:"\f056"}.dijitEditorIconJustifyLeft:before,.flat-align-left:before{content:"\f057"}.dijitEditorIconJustifyRight:before,.flat-align-right:before{content:"\f058"}.dijitEditorIconIndent:before,.flat-indent:before{content:"\f059"}.dijitEditorIconOutdent:before,.flat-outdent:before{content:"\f05a"}.flat-sort:before{content:"\f05b"}.dijitEditorIconSpace:before,.flat-keyboard-space:before{content:"\f05c"}.dijitEditorIconTabIndent:before,.flat-keyboard-tab:before{content:"\f05d"}.dijitEditorIconInsertUnorderedList:before,.flat-list-bullet:before{content:"\f05e"}.dijitEditorIconInsertOrderedList:before,.flat-list-number:before{content:"\f05f"}.dijitEditorIconListBulletIndent:before,.flat-list-bullet-indent:before{content:"\f060"}.dijitEditorIconListBulletOutdent:before,.flat-list-bullet-outdent:before{content:"\f061"}.dijitEditorIconListNumIndent:before,.flat-list-number-indent:before{content:"\f062"}.dijitEditorIconListNumOutdent:before,.flat-list-number-outdent:before{content:"\f063"}.dijitEditorIconViewSource:before,.flat-code:before{content:"\f064"}.dijitEditorIconCreateLink:before,.flat-link:before{content:"\f065"}.dijitEditorIconUnlink:before,.flat-unlink:before{content:"\f066"}.dijitEditorIconFullScreen:before,.flat-fullscreen:before{content:"\f067"}.flat-fullscreen-exit:before{content:"\f068"}.dijitEditorIconInsertImage:before,.flat-image:before{content:"\f069"}.dijitEditorIconNewPage:before,.flat-page-new:before{content:"\f06a"}.dijitEditorIconToggleDir:before,.flat-toggle-dir:before{content:"\f06b"}.dijitEditorIconLeftToRight:before,.flat-left-to-right:before{content:"\f06c"}.dijitEditorIconRightToLeft:before,.flat-right-to-left:before{content:"\f06d"}.dijitEditorIconSelectAll:before,.flat-select-all:before{content:"\f06e"}.dijitEditorIconWikiword:before,.flat-wikiword:before{content:"\f06f"}.icon-spin{-webkit-animation:spin-right 2s infinite linear;-moz-animation:spin-right 2s infinite linear;-o-animation:spin-right 2s infinite linear;-ms-animation:spin-right 2s infinite linear;animation:spin-right 2s infinite linear}.dijitIconLoading{font-size:24px}.dijitIconLoading:before{content:"\f01d";-webkit-animation:spin-left 2s linear infinite;-moz-animation:spin-left 2s linear infinite;-o-animation:spin-left 2s linear infinite;-ms-animation:spin-left 2s linear infinite;animation:spin-left 2s linear infinite}.dj_ie8 .dijitIconLoading,.dj_ie9 .dijitIconLoading{background:url(images/loadingAnimation.gif) no-repeat;height:20px;width:20px}.dj_ie8 .dijitIconLoading:before,.dj_ie9 .dijitIconLoading:before{content:""}.dijitRtl .dijitEditorIconRedo:before,.dijitRtl .dijitEditorIconUndo:before{content:"\f044"}.dijitRtl .dijitEditorIconTabIndent:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.dijitRtl .dijitEditorIconInsertOrderedList,.dijitRtl .dijitEditorIconInsertUnorderedList{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);-o-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}:root .dijitRtl .dijitEditorIconInsertOrderedList,:root .dijitRtl .dijitEditorIconInsertUnorderedList{filter:none}@-moz-keyframes spin-right{from{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes spin-right{from{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes spin-right{from{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spin-right{from{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes spin-left{from{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}to{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}}@-webkit-keyframes spin-left{from{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}to{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}}@-o-keyframes spin-left{from{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}to{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}}@keyframes spin-left{from{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}to{-webkit-transform:rotate(0);-moz-transform:rotate(0);-o-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}}.dijitRtl .dijitOffScreen{left:auto!important;right:-10000px!important}.dijitRtl .dijitPlaceHolder,.dijitSpinnerRtl .dijitSpinnerButtonContainer .dijitArrowButton{right:0;left:auto}.dj_iequirks .dijitComboButtonRtl button{float:left}.dj_ie .dijitTextBoxRtl .dijitInputContainer{clear:right}.dijitComboBoxRtl .dijitArrowButtonContainer,.dijitTextBoxRtl .dijitSpinnerButtonContainer,.dijitTextBoxRtl .dijitValidationContainer{border-right-width:1px!important;border-left-width:0!important}.dijitSelectRtl .dijitButtonText{float:right}.dijitTextBoxRtl .dijitArrowButtonContainer,.dijitTextBoxRtl .dijitSpinnerButtonContainer,.dijitValidationTextBoxRtl .dijitValidationContainer{float:left}.dijitSliderRtl .dijitRuleContainerV,.dijitTreeRtl .dijitTreeContainer,.flat .dijitTreeRtl .dijitTreeContainer{float:right}.dijitCalendarRtl .dijitCalendarNextYear{margin:0 .55em 0 0}.dijitCalendarRtl .dijitCalendarPreviousYear{margin:0 0 0 .55em}.dijitSliderRtl .dijitSliderImageHandleV{left:auto}.dijitSliderRtl .dijitSliderImageHandleH{left:-50%}.dijitSliderRtl .dijitSliderMoveableH{right:auto;left:0}.dj_ie .dijitSliderRtl .dijitRuleLabelV{text-align:left}.dijitSliderRtl .dijitSliderProgressBarH{float:right;right:0;left:auto}.dijitRtl .dijitContentPaneError .dijitIconError,.dijitRtl .dijitContentPaneLoading .dijitIconLoading{margin-right:0;margin-left:9px}.dijitTabControllerRtl .nowrapTabStrip{text-align:right}.dijitTabRtl .dijitTabCloseButton{margin-left:0;margin-right:1em}.dj_ie6 .dijitTabContainerRight-tabs .dijitTabRtl,.dj_ie7 .dijitTabContainerRight-tabs .dijitTabRtl{left:0}.dijitColorPaletteRtl .dijitColorPaletteUnder,.flat .dijitColorPaletteRtl .dijitColorPaletteUnder{left:auto;right:0}.dj_ie6 .dijitTabContainerLeftRtl .dijitTabContainerLeft-tabs,.dj_ie6 .dijitTabContainerRightRtl .dijitTabContainerRight-tabs{width:1%}.dj_ie .dijitTimePickerRtl .dijitTimePickerItem{width:100%}.dijitSelectRtl .dijitButtonContents{border-style:none none none solid;text-align:right}.dijitRtl .dojoDndHorizontal .dojoDndItemBefore{border-width:0 2px 0 0;padding:2px 0 2px 2px}.dijitRtl .dojoDndHorizontal .dojoDndItemAfter{border-width:0 0 0 2px;padding:2px 2px 2px 0}.flat .dijitCalendarRtl .dijitCalendarDecrease:before{content:"\f001"}.flat .dijitCalendarRtl .dijitCalendarIncrease:before,.flat .dijitMenuItemRtl .dijitMenuExpand:before{content:"\f000"}.flat .dijitDialogRtl .dijitDialogCloseIcon{right:auto;left:12px}.flat .dijitDialogRtl .dijitDialogPaneActionBar,.flat .dijitTooltipDialogRtl .dijitDialogPaneActionBar{text-align:left}.flat .dijitMenuBarRtl,.flat .dijitMenuItemRtl,.flat .dijitTabControllerRtl,.flat .dijitTabControllerRtl .nowrapTabStrip,.flat .dijitTitlePaneRtl .dijitTitlePaneTitle,.flat .dijitTreeRtl,.flat div.dijitNumberTextBoxRtl{text-align:right}.flat .dijitTitlePaneRtl .dijitClosed .dijitArrowNode:before{content:"\f006"}.flat .dijitToolbar .dijitButtonRtl,.flat .dijitToolbar .dijitComboButtonRtl,.flat .dijitToolbar .dijitDropDownButtonRtl,.flat .dijitToolbar .dijitToggleButtonRtl{margin-left:4px;margin-right:auto}.flat .dijitToolbar .dijitDropDownButtonRtl .dijitArrowButtonInner{margin-left:auto;margin-right:4px}.flat .dijitTreeRtl .dijitTreeExpandoClosed:before{content:"\e60b"}.flat .dijitAccordionTitle .arrowTextDown,.flat .dijitAccordionTitle .arrowTextUp{float:left}.flat .dijitTabContainerBottom-tabs .dijitTabRtl,.flat .dijitTabContainerTop-tabs .dijitTabRtl{margin-right:0;margin-left:-1px}.flat .dijitTabRtl .dijitTabCloseButton{margin-left:0;margin-right:4px}.flat table.dijitComboButtonRtl .dijitStretch{-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.flat table.dijitComboButtonRtl .dijitArrowButton{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;border-left-width:1px;border-right-width:0}.flat .dijitDropDownButtonRtl .dijitButtonNode{padding-left:8px}.flat .dijitDropDownButtonRtl .dijitArrowButtonInner{margin-left:0;margin-right:12px}.flat .dijitSpinnerRtl .dijitSpinnerButtonContainer .dijitArrowButton{right:0;left:auto}.flat .dijitSelectRtl .dijitButtonText{float:right;padding:0 12px 0 0}.flat .dijitSelectRtl .dijitButtonContents{border-style:none none none solid;text-align:right}.flat .dijitComboBoxRtl .dijitButtonNode.dijitArrowButtonContainer{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.flat .dijitComboBoxRtl .dijitArrowButtonContainer{border-right-width:1px!important;border-left-width:0!important}.flat .dijitSliderRtl .dijitSliderProgressBarH{float:right;right:0;left:auto}.flat .dijitSliderRtl .dijitSliderLeftBumper{border-left-width:0;border-right-width:1px;margin-left:0;margin-right:4px;-webkit-border-radius:0 1.5px 1.5px 0;border-radius:0 1.5px 1.5px 0}.flat .dijitSliderRtl .dijitSliderRightBumper{border-left-width:1px;border-right-width:0;margin-left:4px;margin-right:-2px;-webkit-border-radius:1.5px 0 0 1.5px;border-radius:1.5px 0 0 1.5px}.flat .dijitSliderRtl .dijitSliderMoveableH{right:auto;left:0}.flat .dijitSliderRtl .dijitSliderImageHandleV{left:auto}.flat .dijitSliderRtl .dijitSliderImageHandleH{left:-50%}.flat .dijitSliderRtl .dijitRuleContainerV{float:right}.flat .dijitTextBoxRtl .dijitSpinnerButtonContainer,.flat .dijitTextBoxRtl .dijitValidationContainer{border-right-width:1px!important;border-left-width:0!important}.flat .dijitTextBoxRtlError .dijitValidationContainer{border-left-width:0;border-right-width:1px}.flat .dijitRtl .dijitPlaceHolder{left:auto;right:0}.flat .dijitTextBoxRtl .dijitArrowButtonContainer,.flat .dijitTextBoxRtl .dijitSpinnerButtonContainer,.flat .dijitValidationTextBoxRtl .dijitValidationContainer{float:left} \ No newline at end of file diff --git a/viewer/css/theme/flat/fonts/flat-icon.eot b/viewer/css/theme/flat/fonts/flat-icon.eot new file mode 100644 index 0000000000000000000000000000000000000000..803a042203e0699ba4597eefd83196dceff23189 GIT binary patch literal 13608 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 + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/viewer/css/theme/flat/fonts/flat-icon.ttf b/viewer/css/theme/flat/fonts/flat-icon.ttf new file mode 100644 index 0000000000000000000000000000000000000000..96d0c500ace639093b386ffb4e1a4822e9a2dbcc GIT binary patch literal 13436 zcmeHOe`s7sexI4Q(n_+t-d$;T6`kW~wU$=ARU})h)#}Jbwnb`uXP@i3PwyO)rgkFR zit0$lk&9E(^eL1!+#NmFxF#peVRHSWJUtF`9HkuTVTuVQ4WWe9<9ZyyP)dT&7!j@^ zy?USe`Odtz+LdI*l>X5_G}0`-4L};@hvG zf*}dQW{*REq%-BHd)S1(h;k@%H zV}pN=`jIIVg#Rg2K%VgJo_cle^84)TZy|pdZT|KA?8~Q*?>RWh*xp;HzxV3t%NN)@ zJIUD44dlCKPQQBQ4?aDA7J@uS<|sxUVSV7F!agm`Bfy$Fjn7#k^;@ z)H&xi>MT{)6H9U1UE+?5a-HXdE4XZv4kPOz=eN=M1nP1$M_x>&x$e52!6#g5XR<|c zRV)&nc{mkr=Hlv|JEaxOK+Gb638{W(0B0+>W|1vsxy{)ME8V#x7FSe4!2zYl#Iq7# zsu|r0!bXtdS&6oEN6v%sCjd7=aLqiN4QGkWKvxnI5^V`tn@wn@#u-+dC(<;yR5-1f zl`kKZJe!-P2cn5D8OtSZBC{;}ueNCdUW_wcNE2q$vr7*uUy7y&8ux5umW_?zi>X*X zR@4BkK=@+N5Bgk(zl{bS%f!MM3k|?n=8H8wDfp{wUbDnM(mZ>3if4=5;&)0Odr z|4nd$nT%_;M)XJ$WR_>cd?=Mnw1*or-Pzv4aB(CLnp-9By?07nzxAgGw^Y2utua|@ zSBp>q`nl*^7fX-;a&1B6Vz!tnYWjl*rQj!i5TsC4GmdTG3WnjL5w=CDn9|mcMz{+L zrQo+vJ0Knlicv4Dx=|6w1#^wEGwGJ(bMI)^^o~5zro?;S2V? zGYH>Pac#FVrJ3q)q6z^xjnxhT+iMjLv|puDD>7*;C^ilDK{}!7E6gBPFu(@$egZ|Z z4F_%c5+nuM6bQEB2!qcXsI6VkR`w(y3YkJCkxAqe`9gjJLOO}&9xgmRJXr-S?+OW z6wae_^q$#dT5=4V5tMeQXPYL?O=mgHg*>6TZI?R`>qc{HXy$1lQF)BJ+93CBSz zOVc0HfuS)AZ7nT_wh6Y&r%QM(leVQ|;dC}ul*sgC3?ZrFn|JSex9{HN`xS})fhwX1 zR4rce>+aUje<$R?5c*k_0(la5QVQ(gjZbo9wT;*1t-hh5g9nF(jLy#P?#|B6;UNQ= zH7oTmeWL&YAVCn^$jEqde8l_2Fho6jt?r2?7H1i(Trj4#p(1~TbkZV+AZ;$6{P^-o zuZxnkeEe@GFGB(ys@yol@5*GoFp{#uURlC9H_u|S$3iMxP!c~?*I`x-C6O&A1hZ{m z9U0qo`0#W!VcUzA?N}JVMR{`7lQ5r7kz3RV{WFj=WLK<8ZFqqow8jY(>E=>ji8QO&Tw8lJ;LyvDq zz`PLRmgjJT#)ZCY^ezmI24bPA3g)@xGB2ZY1^mJpfE8U`j77&-n&kP3Zt}%^D$l_N z)!EZ#zt&&wzgBV8^3a~fMlf}~VhIdK%}?R8p}U!owVK42&n9@9ucB(BDG2@keb0rS zDA$@=3+yqGyLXR6$pAXJ=j0wCoU3vukd2BwM6OI#CEUkHp5@54L9NKN1zMsMn_y!8 z=Htl5?`|v`dADIy`s-AWtubwIhHTMk%~|{S`zZulE#R9b=qOJ?CV+QRBmojqJgsFS zs2cb0OU5VWhf+>*GvFm|5;wV~2~|ee8}QVsyl#-%UZJ5U(I9QCRbKVQjWhtssH+#* z!Vwdu>zZY51wE6DqY;2-8*9#kW)@*>tb=ra$(&&+)<}iPlIprzhQS(|@sRW{o8E?> zhh1w}(Ej`7t5TLPIuj;Avm1~#Q3lTmUn@R)Qb{OGgS-)Oj&~38-fS4z-hG@b$SmF? zPw^4N&u}_PQblCZf{qly#`+P)RLsXtMq13K__V$&8j3o2db_9NO=e5vq!61_@kA8` z5S>5R62BH{)OWRBh{rEPJN3rMwRp?H$j+USN7pEsYOw>_G-PyCY6@%T31>jIkX^Nm zmCS<-zkX~K;h2g!EAKD29+{f^J%qWrW5>o@yZJ=58bGM;ZXG{%Y)*kp9U&7CcC$Jk zNN<)$QBQ-~7{bMd@LbP@?B-^7PF`I3=X0W5QBq9)O>CDCQSGy$UY%nsiBr6*|QwfvxP&7Q_TamSYaTYV;Eo= z)(V=>YjzDD;<;{?W&La~8)46oOo8$mgBqKG4qF@bP!?)$rVyr7s=oGFYNtVO0R0@N ztf*)OnQ~AB(k|I{1yfW36&z3qXhi|U$Ap0h>r1{YHD8Ph%gf2I{bNJGz%-_K)mhjCcm75T}N2J8n z;_rCYjZ<%2c>ekB$^J{1uG(+%PZvCE;n;x#Q(bSHCgH%ohF{BqUn|6(V7oW-kYp3& zc2}mp?)CGsQXag1_2y;EV+PsFEGNv0Eo{-6T>S_QMnaj1stuV02z#dRvDrdytC>PdtZU%gVps*P`m z2%sh-%2kQDZ`b7HuD~W>RgUgj*rW^Rbp5bbFlPNg+3=iH>!*i9pMa6;Y7kK!766xyF^{%eS zPbP$8SrtQL&J zuYDKVNWYVsohgj6Qzi`){K`RZP#h28Alo)4_338mD@0?s3p3e5CPkO4nIa}F%rBoi zx$ErZxmGbX^7*(m<^4h|SvOA{y4=)KxjypwjW0NyvTCkNxHp_ulwJYg?DAoTler995F6qqn!? zUJ5!^a|uE9&4WQV3^HGR@40hcpk!)&L2q4ih-*jk)vB& zavCWA41IG$=K?`yVhzP+a4(iv!y0<{5QM(0S*W}#UKES8%q8`$%>p?M8rd{^4gRQK zqdoapo??600pO_)Qj#GX*w4ZB!Mcwx))jDFDq&LPf-vf!tKW_ey5a3mNAmhuz;8o7 z8)BE20H>f4izXcA>PSbt!fJDJ4&)b8XCuww3CI_GF(TJfts>1v!x0(ADOo6HiUsNA zp%Nr0Q^?ehw`?6fY8^SE>xQmd79#o41`SN$ihqUm_npAcvicnlPk(!VJI1kfrakVN z7U$Pe7a%=_<4zV<#--^;!Ksr(=hj4r>%li$zL zeq56F8Ob+z)TEyp>Sqq_z^d|G$V*1aLPLFqCxXw&WD;Lm3HQVp!U@M2$s&xv18H$^ z=`ESAsT1@2_MJGfZ{KlL0Q5NVicX2uVz9{nOCAYTzkzFn3~iTZ0ZE38QmctT$in%X zkn%#9WdkyS%+0ceE0?k%mXLsFwQTTy)H$f6xjqVSJ|QI!Y)2)4lpKO@5(t2nKMCv@pS~uH+t;|di&rX|ylm%xbepr= z(={b@N#OwZmJHjHVgHwYrmg+-c>4+N255Bbulr{H;}3U~{*!GBp@6ZETZX^6`j(d9 zBJ%Xbxe90_zh8&2p@5h$)rL7$ql&0mh;a*#jYsz%6Ym*3R7W^aSNB{+9x%-H-$A-I zPi3_aa5MB%EhC(@d4i>UP)4{2rWQw#t}UPR+Yo%vmih|t`|s*Js4l>>*?YVO4tOPP z7|Lq

%+Q>gb`o^%W0|iN-OFCuskuw+k402#0_|^*7tcwx8Pm*7l!AN|7s(k0PJ#NbVTj@#2m*cl>iS9vzDQarDR0 zkD?D_eK9lk7qRzZ%kfCOJ3b!&+xTZ~Lv3%gz26>f-_!ml?RVOj6FU>%Ok7KRlI%-f zOum7&#@D9D~S;7dYSQ~2>Y?W=jHzZ_-O&Z)I~q7!Lp(M6rey>&R_az(yG4Z zryEiJZ9m s1K4LYnmLT;9FWb(G13&yut}7?1j=-=Z^+4f3y=g$j#T_N$!6hy03#`QegFUf literal 0 HcmV?d00001 diff --git a/viewer/css/theme/flat/fonts/flat-icon.woff b/viewer/css/theme/flat/fonts/flat-icon.woff new file mode 100644 index 0000000000000000000000000000000000000000..a62cb0b77bed040d61c91c1030d6baccc2a10a53 GIT binary patch literal 13512 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 literal 0 HcmV?d00001 diff --git a/viewer/css/theme/flat/images/loadingAnimation.gif b/viewer/css/theme/flat/images/loadingAnimation.gif new file mode 100644 index 0000000000000000000000000000000000000000..694e2cb3fa30eb15e5cbd1aa17c8864f0a4b43bc GIT binary patch literal 631 zcmZ?wbhEHb6k!ly_{_$z=5kPS3cgn@zC zIAhnHIDuU&7cDveNTz&q>+yz1PScJ>u2OovQ@TggNp{iE1^2Zde%5Ue_`xO7X~>&( z(gS7=D}xRb0|x^$11HcNP7Ny`K7$jU*-TJdm_V{jKv^yZ1{U6clg^V}B{B{-|6d@^ z2vxxVQ^5jM!9L-n+uT?Sm~NmPBLgD?D}xYFPV~b`&Q)t3+-fg<7R_FlBsovzm2WT$ z!Z++NmCS+>yYBom@KRqT6)|ybL%8D$6{sqpTRHH$m4l#LAu6!D748CpZsjG)t$cXh T%16+x5Eai6w^{=LCAG3? literal 0 HcmV?d00001 diff --git a/viewer/css/theme/flat/images/progressBarStrips.png b/viewer/css/theme/flat/images/progressBarStrips.png new file mode 100644 index 0000000000000000000000000000000000000000..50644f98c61d833022ec4f208526182e91954f97 GIT binary patch literal 1280 zcmaJ>eM}p57(TMCYnIgo2N{qM&%Zq#x3h`(n*X?GBII7ri;pq#;qCAgcxHC{>obBAGk~IejjZMOH zRERpTR%?I^C~goFj`XRZxvw!4>FbWLQLO$TT9@Qt01@asniS)b#w8utMqCc=bJqlh zZb0;I2X;?XTc8Pb%PK&vxYZmXX$rNmIAvv6imE|rlClsKNzkmBqBzFJQMG9P!C*Eu z+Q|hyzI-lta$qrCS2%)5BocVSg3D?bL9r}LkTgNlW{5CrDM{y(W=X3mMDPGDq6&&G z$P${1$al!Sx&wns@0B1bfxu>9Ny{4rEhCb=LQptKh+?j;4YZ~Q!F?H9qP0*;0YngJ za<3YJ{phSJkfC=EPLu;eHJnF|^ol^z{T>GfZ}6xP$|G7DRojETS9UaKaY(y*8VVak4hMleI(bwB1AcoEFAsakEa=>#fD|+~^i{ z=ehR(AihFM?OA!?wIkX)bR7!6{hF> z-miZzIX8B()^$kqy49D2OnMD!7QUAljK-KRc5`NqILL}AeJ>%)VzA2^unOwtCbI2%FO)w3|IH2a>u^ Date: Fri, 9 Sep 2016 19:37:45 -0700 Subject: [PATCH 120/216] migrate dbootstrap and esri css overrides to separate file. add font awesome icons to titlePanes. --- viewer/css/cmv-theme-overrides.css | 257 +++++++++++++++++++++++++++++ viewer/css/main.css | 107 +----------- 2 files changed, 261 insertions(+), 103 deletions(-) create mode 100644 viewer/css/cmv-theme-overrides.css diff --git a/viewer/css/cmv-theme-overrides.css b/viewer/css/cmv-theme-overrides.css new file mode 100644 index 000000000..5cb63f9fb --- /dev/null +++ b/viewer/css/cmv-theme-overrides.css @@ -0,0 +1,257 @@ +.cmv .dijitToolbar .dijitButtonContents { + padding: 1px !important; +} + +.cmv .dijitTitlePane { + margin-bottom: 2px; +} + +.cmv .dijitTitlePaneTitle { + color: #666; + background-color: #F5F5F5; +} + +.cmv label { + font-weight: bold; +} + +.cmv :focus { + outline: none !important; +} + +/* icons for the sidebar */ + +.cmv .dijitTitlePane .dijitTitlePaneTextNode:before, +.cmv .dijitDialogTitleBar:before { + font-family:'FontAwesome'; + margin-right: 8px; +} + +.cmv #bookmarks_parent .dijitTitlePaneTextNode:before { + content: '\f02e' +} +.cmv #directions_parent .dijitTitlePaneTextNode:before { + content: '\f277' +} +.cmv #draw_parent .dijitTitlePaneTextNode:before { + content: '\f1fc' +} +.cmv #editor_parent .dijitTitlePaneTextNode:before { + content: '\f040' +} +.cmv #find_parent .dijitTitlePaneTextNode:before { + content: '\f002'; +} +.cmv #help_parent .dijitTitlePaneTextNode:before { + content: '\f059' +} +.cmv #identify_parent .dijitTitlePaneTextNode:before { + content: '\f05a' +} +.cmv #layerControl_parent .dijitTitlePaneTextNode:before{ + content: '\f00b'; +} +.cmv #legend_parent .dijitTitlePaneTextNode:before { + content: '\f03e' +} +.cmv #measurement_parent .dijitTitlePaneTextNode:before { + content: '\f065' +} +.cmv #print_parent .dijitTitlePaneTextNode:before { + content: '\f02f'; +} +.cmv #streetview_parent .dijitTitlePaneTextNode:before { + content: '\f21d'; +} +/* end custom icons */ + +/* esri popup window overrides */ + +.cmv .esriPopup .sizer { + width: 325px; +} + +.cmv .esriPopup .esriPopupWrapper { + background-color: #FFFFFF; +} +.cmv .esriPopup .attachmentsSection div { + font-weight: bold; +} +.cmv .esriPopup .contentPane table.attrTable { + width: 100%; + border-collapse: collapse; +} +.cmv .esriPopup .contentPane table.attrTable td { + padding: 2px; +} +.cmv .esriPopup .contentPane table.attrTable td.attrName { + text-align: right; + font-weight: bold; + color: #333333; + width: 40%; + padding-right: 5px; +} +.cmv .esriPopup .contentPane table.attrTable td.attrValue { + width: 60%; +} +.cmv .esriPopup .contentPane table.attrTable tr { + vertical-align: top; + border-bottom: 1px solid rgb(221, 221, 221); +} +.cmv .esriPopup .contentPane table.attrTable tr:nth-child(odd) { + background-color: none; +} +.cmv .esriPopup .contentPane table.attrTable tr:nth-child(even) { + background-color: rgb(238, 238, 238); +} + +/* end esri popup window overrides */ + +/* esri mobile popup overrides */ + +.cmv .esriPopupMobile { + z-index: 999; +} +.cmv .esriMobileNavigationBar { + background-color: #666666; + background: url("../images/linen.jpg") repeat-x scroll left top transparent; + color: #FFFFFF; +} +.cmv .esriPopupMobile .titlePane { + background-color: #666666; + background: url("../images/linen.jpg") repeat-x scroll left top transparent; + color: #FFFFFF; +} +.cmv .esriPopupMobile .pointer.bottom{ + background:url("../images/pointertop.png"); + -webkit-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -o-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.cmv .esriPopupMobile .pointer.top { + background:url("../images/pointertop.png"); +} + +/* end esri mobile popup overrides */ + +/* esri directions widget overrides */ +.cmv .simpleDirections .esriDirectionsButton { + background-color: #E6E6E6; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #e6e6e6)); + background-image: -webkit-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -moz-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -ms-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-repeat: repeat-x; + border: 1px solid #BBB; + border-bottom: 1px solid #A8A8A8; + padding: 0px 12px; + color: #000; + letter-spacing: 0; + text-transform: none; +} +.cmv .simpleDirections .esriDirectionsButton:before { + font-family:'FontAwesome'; + margin-right: 8px; + content: '\f277' +} + +.cmv .simpleDirections .esriLinkButton { + color: #000; + letter-spacing: 0; + text-transform: none; +} +/* end esri directions widget overrides */ + +/* flat theme */ +/* makes the flat theme more like dbootstrap */ +.flat { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +.flat a, +.flat a:hover { + text-decoration: none; +} + +.flat .dijitTitlePane { + border-color: #E0E0E0; +} + +.flat .dijitTabContainerTop-tabs .dijitTabChecked:before { + height: 3px; + background-color: #666; + top: -1px; + left: -1px; + right: -1px; +} + +.flat .dijitTitlePaneTitle { + border: 1px solid #DDD; + border-bottom: none; + -webkit-border-radius: 4px; + border-radius: 4px; + padding: 8px 15px; +} + +.flat .dijitDialogTitleBar { + background-color: #F5F5F5; + color: #666; +} + +.flat .dijitTitlePaneContentOuter { + border: 1px solid #DDD; + border-top: none; +} + +.flat .dijitButton .dijitButtonNode, +.flat .dijitDropDownButton .dijitButtonNode, +.flat .dijitComboButton .dijitButtonNode, +.flat .dijitToggleButton .dijitButtonNode, +.flat .dijitComboBox .dijitButtonNode, +.flat .dijitSpinnerButtonContainer.dijitButtonNode, +.flat .dijitSelect .dijitButtonNode { + background-color: #E6E6E6; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #e6e6e6)); + background-image: -webkit-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -moz-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -ms-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-repeat: repeat-x; + border-color: #BBB; + border-bottom-color: #A8A8A8; + padding: 4px 12px; +} + +.flat .success .dijitButtonNode { + background: #409843; + color: #FFF; + border-color: #39883c; +} +.flat .danger .dijitButtonNode { + background: #e32d29; + color: #FFF; + border-color: #d4201b; +} + +.flat .dijitTextBoxHover, +.flat .dijitTextBoxFocused, +.flat .dijitCheckBoxChecked, +.flat .dijitCheckBoxHover, +.flat .dijitCheckBoxCheckedHover, +.flat .dijitRadio, +.flat .dijitRadioIcon, +.flat .dijitRadioHover { + border-color: #666; +} +.flat .dijitCheckBoxChecked, +.flat .dijitRadio:after, +.flat .dijitRadioIcon:after { + background-color: #999; +} + +/* end flat theme */ diff --git a/viewer/css/main.css b/viewer/css/main.css index f351cc5be..ce00bb911 100644 --- a/viewer/css/main.css +++ b/viewer/css/main.css @@ -4,7 +4,6 @@ body, html { margin: 0; padding: 0; overflow: hidden; - /*font-family: Tahoma;*/ font-size: 14px; } .appHeader { @@ -59,7 +58,7 @@ body, html { right: 0; border: none; padding: 0; - background-color: #FFFFFF + background-color: #FFFFFF; } #sidebarLeft { width: 334px; @@ -170,6 +169,9 @@ body, html { border-radius: 0 0 5px 5px; border-bottom: 1px solid #B5BCC7; } +.sidebarCollapseButton .open:before, .sidebarCollapseButton .close:before { + font-family: FontAwesome; +} .sidebarCollapseButtonHorz .button { padding-top: 4px; padding-left: 2px; @@ -209,107 +211,6 @@ body, html { display: block; } -/* dbootstrap overrides*/ - -.dbootstrap .dijitToolbar .dijitButtonContents { - padding: 1px !important; -} -.dbootstrap .dijitTitlePane { - border: 1px solid #DDDDDD; - margin-bottom: 2px; - -webkit-border-radius: 4px; - border-radius: 4px; - background-color: #FFFFFF; -} -.dbootstrap .dijitTitlePaneTitle { - color: #666666 !important; - border-bottom: none; - padding: 8px 15px; - background-color: #F5F5F5; -} -.dijitSliderBarContainerH { - z-index: 0 !important; -} -.dijitBorderContainerNoGutterPane { - z-index: auto; -} -.dbootstrap :focus { - outline: none !important; -} - -/* end dbootstrap overrides*/ - -/* esri popup window overrides */ - -.esriPopup .sizer { - width: 325px; -} - -.esriPopup .esriPopupWrapper { - background-color: #FFFFFF; -} -.esriPopup .attachmentsSection div { - font-weight: bold; -} -.esriPopup .contentPane table.attrTable { - width: 100%; - border-collapse: collapse; -} -.esriPopup .contentPane table.attrTable td { - padding: 2px; -} -.esriPopup .contentPane table.attrTable td.attrName { - text-align: right; - font-weight: bold; - color: #333333; - width: 40%; - padding-right: 5px; -} -.esriPopup .contentPane table.attrTable td.attrValue { - width: 60%; -} -.esriPopup .contentPane table.attrTable tr { - vertical-align: top; - border-bottom: 1px solid rgb(221, 221, 221); -} -.esriPopup .contentPane table.attrTable tr:nth-child(odd) { - background-color: none; -} -.esriPopup .contentPane table.attrTable tr:nth-child(even) { - background-color: rgb(238, 238, 238); -} - -/* end esri popup window overrides */ - -/* esri mobile popup overrides */ - -.esriPopupMobile { - z-index: 999; -} -.esriMobileNavigationBar { - background-color: #666666; - background: url("../images/linen.jpg") repeat-x scroll left top transparent; - color: #FFFFFF; -} -.esriPopupMobile .titlePane { - background-color: #666666; - background: url("../images/linen.jpg") repeat-x scroll left top transparent; - color: #FFFFFF; -} -.esriPopupMobile .pointer.bottom{ - background:url("../images/pointertop.png"); - -webkit-transform: rotate(180deg); - -moz-transform: rotate(180deg); - -o-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} -.esriPopupMobile .pointer.top { - background:url("../images/pointertop.png"); -} - -/* end esri mobile popup overrides */ - /* media queries bootstrap style https://getbootstrap.com/css/#grid-media-queries From 2a38ceb641a1dc356caacfaa6a663bb8847d3ac1 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 9 Sep 2016 19:39:32 -0700 Subject: [PATCH 121/216] add flat theme and cmv overrides to index.html. update Esri JS API to upcoming version 3.18. update Font-Awesome to version 4.6.3 --- viewer/index.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/viewer/index.html b/viewer/index.html index 0aa25b974..8de7add0b 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -11,12 +11,13 @@ Configurable Map Viewer - - + + + - +

+ ${i18n.preserve}: - ${i18n.mapScale}   + ${i18n.mapScale}
${i18n.mapExtent}
- - +
+
diff --git a/viewer/js/gis/dijit/LayerControl/controls/templates/Folder.html b/viewer/js/gis/dijit/LayerControl/controls/templates/Folder.html index 628438952..c62a97f34 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/templates/Folder.html +++ b/viewer/js/gis/dijit/LayerControl/controls/templates/Folder.html @@ -1,7 +1,7 @@ -
- - -
+
+ + +
diff --git a/viewer/js/gis/dijit/LayerControl/controls/templates/Sublayer.html b/viewer/js/gis/dijit/LayerControl/controls/templates/Sublayer.html index 8e5b82ea6..6d2a2b464 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/templates/Sublayer.html +++ b/viewer/js/gis/dijit/LayerControl/controls/templates/Sublayer.html @@ -1,7 +1,7 @@ -
- - -
+
+ + + +
@@ -9,9 +9,14 @@ - + + + + +
- +
From 2d346f8ce2f918ddad70147ff388d70e13871a98 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 27 Feb 2017 14:53:44 -0600 Subject: [PATCH 197/216] Add cursor style mouse to various parts of the layer control --- .../dijit/LayerControl/css/LayerControl.css | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl/css/LayerControl.css b/viewer/js/gis/dijit/LayerControl/css/LayerControl.css index 2a09ad53e..c3fa09b4e 100644 --- a/viewer/js/gis/dijit/LayerControl/css/LayerControl.css +++ b/viewer/js/gis/dijit/LayerControl/css/LayerControl.css @@ -45,8 +45,7 @@ line-height: 15px; } -.layerControlDijit .layerControlTableCheck, -.layerControlDijit .layerControlTableMenu { +.layerControlDijit .layerControlTableCheck, .layerControlDijit .layerControlTableMenu { cursor: pointer; width: 19px; height: 16px; @@ -54,10 +53,14 @@ } .layerControlDijit .layerControlTableLabel { + cursor: pointer; font-size: 15px; height: 16px; line-height: 16px; - cursor: default; +} + +.layerControlDijit .layerControlTableMenu { + cursor: pointer; } .layerControlDijit .layerControlTableUpdate { @@ -70,6 +73,7 @@ .layerControlDijit .layerControlHidden { display: none; } + .layerControlDijit .layerControlVisible { display: block; } @@ -99,7 +103,9 @@ color: #BBB; } + /* not in use - retain for links */ + .layerControlDijit .layerControlClick { cursor: pointer; color: #1f78af; @@ -118,7 +124,7 @@ vertical-align: middle; } -.layerControlDijit .layerControlLegendImage > img { +.layerControlDijit .layerControlLegendImage>img { border: none; padding: 0; } @@ -127,7 +133,9 @@ padding: 0 0 0 4px; } + /* temp esri/Legend overrides */ + .layerControlDijit .esriLegendService td { padding: 0; } @@ -140,13 +148,12 @@ display: none; } -.layerControlDijit .menuLink { - color: #369; - text-decoration: none; +/* sublayer menu */ + +.layerControlDijit .layerControlSublayer .layerControlTable td.layerControlTableMenu { + padding-right: 20px; } -.layerControlDijit .menuLink:hover { - color: #5196DB; - text-decoration: underline; - cursor: pointer; +.layerControlDijit .menuClickNode.hidden { + display: none; } From 5f1f817f65a5da7eabc433d85a4ffe69e861d429 Mon Sep 17 00:00:00 2001 From: Gregg Roemhildt Date: Sat, 11 Feb 2017 17:03:50 -0600 Subject: [PATCH 198/216] move custom layer menu logic to _Control - all layer types now support `layerControlLayerInfos.menu` property --- .../dijit/LayerControl/controls/Dynamic.js | 18 +++-------------- .../dijit/LayerControl/controls/_Control.js | 20 ++++++++++++++++++- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js index d474d6eda..705a557f4 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js @@ -87,25 +87,13 @@ define([ })); menu.addChild(new MenuSeparator()); } - + }, + _initCustomMenu: function () { // add custom sublayer menu items if we only have one sublayer if (!this._hasSublayers) { - array.forEach(this.controlOptions.menu, lang.hitch(this, '_addMenuItem', menu)); + array.forEach(this.controlOptions.menu, lang.hitch(this, '_addMenuItem', this.layerMenu)); } }, - _addMenuItem: function (menu, menuItem) { - //create the menu item - var item = new MenuItem(menuItem); - item.set('onClick', lang.hitch(this, function () { - topic.publish('layerControl/' + menuItem.topic, { - layer: this.layer, - subLayer: this.layer.layerInfos[0], - iconNode: this.iconNode, - menuItem: item - }); - })); - menu.addChild(item); - }, // toggle all sublayers on/off _toggleAllSublayers: function (state) { array.forEach(this._sublayerControls, function (control) { diff --git a/viewer/js/gis/dijit/LayerControl/controls/_Control.js b/viewer/js/gis/dijit/LayerControl/controls/_Control.js index 4975b12d3..58e7f6179 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_Control.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_Control.js @@ -10,6 +10,7 @@ define([ 'dojo/dom-attr', 'dojo/fx', 'dojo/html', + 'dijit/MenuItem', './../plugins/LayerMenu', 'dojo/text!./templates/Control.html' ], function ( @@ -24,6 +25,7 @@ define([ domAttr, fx, html, + MenuItem, LayerMenu, template ) { @@ -91,6 +93,7 @@ define([ leftClickToOpen: true }); this.layerMenu.startup(); + this._initCustomMenu(); } else { domClass.remove(this.menuNode, 'fa, layerControlMenuIcon, ' + this.icons.menu); domStyle.set(this.menuClickNode, 'cursor', 'default'); @@ -117,6 +120,21 @@ define([ layer.on('visibility-change', lang.hitch(this, '_visibilityChange')) ); }, + _initCustomMenu: function () { + array.forEach(this.controlOptions.menu, lang.hitch(this, '_addCustomMenuItem', this.layerMenu)); + }, + _addCustomMenuItem: function (menu, menuItem) { + //create the menu item + var item = new MenuItem(menuItem); + item.set('onClick', lang.hitch(this, function () { + topic.publish('layerControl/' + menuItem.topic, { + layer: this.layer, + iconNode: this.iconNode, + menuItem: item + }); + })); + menu.addChild(item); + }, // add on event to expandClickNode _expandClick: function () { this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, '_expandClicked')); @@ -259,4 +277,4 @@ define([ } }); return _Control; -}); \ No newline at end of file +}); From 2848aad644caf7ba116a2fb2cc080dc7fe51c77e Mon Sep 17 00:00:00 2001 From: Gregg Roemhildt Date: Sat, 11 Feb 2017 17:05:55 -0600 Subject: [PATCH 199/216] add examples of feature layer custom menu --- viewer/js/config/viewer.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index f7c7a8c34..d680090d1 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -54,13 +54,17 @@ define([ topic.subscribe('layerControl/hello', function (event) { topic.publish('growler/growl', { title: 'Hello!', - message: event.layer._titleForLegend + ' ' + event.subLayer.name + ' says hello' + message: event.layer._titleForLegend + ' ' + + (event.subLayer ? event.subLayer.name : '') + + ' says hello' }); }); topic.subscribe('layerControl/goodbye', function (event) { topic.publish('growler/growl', { title: 'Goodbye!', - message: event.layer._titleForLegend + ' ' + event.subLayer.name + ' says goodbye' + message: event.layer._titleForLegend + ' ' + + (event.subLayer ? event.subLayer.name : '') + + ' says goodbye' }); }); @@ -163,6 +167,13 @@ define([ visible: true, outFields: ['req_type', 'req_date', 'req_time', 'address', 'district'], mode: 0 + }, + layerControlLayerInfos: { + menu: [{ + topic: 'hello', + label: 'Say Hello Custom', + iconClass: 'fa fa-smile-o' + }] } }, { type: 'dynamic', @@ -431,6 +442,11 @@ define([ topic: 'goodbye', iconClass: 'fa fa-frown-o', label: 'Say goodbye' + }], + feature: [{ + topic: 'hello', + iconClass: 'fa fa-smile-o', + label: 'Say Hello' }] } } From a8978a21405e1f10b5d3eb71723ab957477b4556 Mon Sep 17 00:00:00 2001 From: Gregg Roemhildt Date: Sat, 11 Feb 2017 17:37:03 -0600 Subject: [PATCH 200/216] separate menus into `subLayerMenu` and `menu` properties --- viewer/js/config/viewer.js | 25 +++++++++++-------- viewer/js/gis/dijit/LayerControl.js | 6 +++-- .../dijit/LayerControl/controls/Dynamic.js | 3 ++- .../dijit/LayerControl/controls/Feature.js | 2 +- .../LayerControl/controls/_DynamicSublayer.js | 6 ++--- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index d680090d1..d11dc7490 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -55,16 +55,16 @@ define([ topic.publish('growler/growl', { title: 'Hello!', message: event.layer._titleForLegend + ' ' + - (event.subLayer ? event.subLayer.name : '') + - ' says hello' + (event.subLayer ? event.subLayer.name : '') + + ' says hello' }); }); topic.subscribe('layerControl/goodbye', function (event) { topic.publish('growler/growl', { title: 'Goodbye!', message: event.layer._titleForLegend + ' ' + - (event.subLayer ? event.subLayer.name : '') + - ' says goodbye' + (event.subLayer ? event.subLayer.name : '') + + ' says goodbye' }); }); @@ -218,7 +218,7 @@ define([ expanded: true, //override the menu on this particular layer - menu: [{ + subLayerMenu: [{ topic: 'hello', label: 'Say Hello', iconClass: 'fa fa-smile-o' @@ -434,7 +434,15 @@ define([ separated: true, vectorReorder: true, overlayReorder: true, - + // create a custom menu entry in all of these feature types + // the custom menu item will publish a topic when clicked + menu: { + feature: [{ + topic: 'hello', + iconClass: 'fa fa-smile-o', + label: 'Say Hello' + }] + }, //create a example sub layer menu that will //apply to all layers of type 'dynamic' subLayerMenu: { @@ -442,11 +450,6 @@ define([ topic: 'goodbye', iconClass: 'fa fa-frown-o', label: 'Say goodbye' - }], - feature: [{ - topic: 'hello', - iconClass: 'fa fa-smile-o', - label: 'Say Hello' }] } } diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index ec176f00d..4a8f14098 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -51,6 +51,7 @@ define([ noLegend: null, noZoom: null, noTransparency: null, + menu: {}, subLayerMenu: {}, swipe: null, swiperButtonStyle: 'position:absolute;top:20px;left:120px;z-index:50;', @@ -220,7 +221,8 @@ define([ swipe: null, expanded: false, sublayers: true, - menu: this.subLayerMenu[layerInfo.type] + menu: this.menu[layerInfo.type], + subLayerMenu: this.subLayerMenu[layerInfo.type] }, layerInfo.controlOptions) }); layerControl.startup(); @@ -487,4 +489,4 @@ define([ } }); return LayerControl; -}); \ No newline at end of file +}); diff --git a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js index 705a557f4..c4ce2a847 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js @@ -91,7 +91,8 @@ define([ _initCustomMenu: function () { // add custom sublayer menu items if we only have one sublayer if (!this._hasSublayers) { - array.forEach(this.controlOptions.menu, lang.hitch(this, '_addMenuItem', this.layerMenu)); + array.forEach(this.controlOptions.subLayerMenu, lang.hitch(this, '_addCustomMenuItem', this.layerMenu)); + this.layerMenu.addChild(new MenuSeparator()); } }, // toggle all sublayers on/off diff --git a/viewer/js/gis/dijit/LayerControl/controls/Feature.js b/viewer/js/gis/dijit/LayerControl/controls/Feature.js index 4ac2061a5..8706f5e29 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Feature.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Feature.js @@ -28,4 +28,4 @@ define([ } }); return FeatureControl; -}); \ No newline at end of file +}); diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js index c8f3880b0..51c9dd271 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js @@ -88,14 +88,14 @@ define([ this._handlers.push(this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange'))); } //set up menu - if (this.control.controlOptions.menu && - this.control.controlOptions.menu.length) { + if (this.control.controlOptions.subLayerMenu && + this.control.controlOptions.subLayerMenu.length) { this.menu = new Menu({ contextMenuForWindow: false, targetNodeIds: [this.menuClickNode], leftClickToOpen: true }); - array.forEach(this.control.controlOptions.menu, lang.hitch(this, '_addMenuItem')); + array.forEach(this.control.controlOptions.subLayerMenu, lang.hitch(this, '_addMenuItem')); this.menu.startup(); } else { domClass.add(this.menuClickNode, 'hidden'); From b9d22a04e51a55951c9505c8dab193994507ff67 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 2 Mar 2017 16:08:58 -0600 Subject: [PATCH 201/216] move flag icon css to dojo config for package location configuration --- viewer/js/config/app.js | 3 +++ viewer/js/gis/dijit/Locale.js | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 486259e58..322a54645 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -15,6 +15,9 @@ }, { name: 'proj4js', location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15' + }, { + name: 'flag-icon-css', + location: '//cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1' } ] }; diff --git a/viewer/js/gis/dijit/Locale.js b/viewer/js/gis/dijit/Locale.js index a7b532b9b..32322fc58 100644 --- a/viewer/js/gis/dijit/Locale.js +++ b/viewer/js/gis/dijit/Locale.js @@ -19,7 +19,7 @@ define([ 'dojo/text!./Locale/templates/Locale.html', 'dojo/i18n!./Locale/nls/resource', - 'xstyle/css!https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1/css/flag-icon.min.css', + 'xstyle/css!flag-icon-css/css/flag-icon.min.css', 'xstyle/css!./Locale/css/Locale.css' ], function ( declare, @@ -184,4 +184,4 @@ define([ } } }); -}); \ No newline at end of file +}); From 34c448bf0fc00401447a27c2f2dbc3d5e9f42fac Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Thu, 2 Mar 2017 16:09:34 -0600 Subject: [PATCH 202/216] use relative url for i18n path --- viewer/js/viewer/_WebMapMixin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/viewer/_WebMapMixin.js b/viewer/js/viewer/_WebMapMixin.js index 9a4fcd1d4..c1d2be293 100644 --- a/viewer/js/viewer/_WebMapMixin.js +++ b/viewer/js/viewer/_WebMapMixin.js @@ -7,7 +7,7 @@ define([ 'esri/arcgis/utils', 'esri/units', - 'dojo/i18n!config/nls/main' + 'dojo/i18n!../config/nls/main' ], function ( declare, From 4fbf86a94e8c9363ffb341ff56cec59d9e05c084 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Thu, 2 Mar 2017 16:58:15 -0800 Subject: [PATCH 203/216] remove dependency on nls for 2 words. To override the title, include a config for the widget in viewer.js. --- viewer/js/viewer/_WebMapMixin.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/viewer/js/viewer/_WebMapMixin.js b/viewer/js/viewer/_WebMapMixin.js index c1d2be293..106a302b2 100644 --- a/viewer/js/viewer/_WebMapMixin.js +++ b/viewer/js/viewer/_WebMapMixin.js @@ -5,9 +5,7 @@ define([ 'dojo/dom', 'esri/arcgis/utils', - 'esri/units', - - 'dojo/i18n!../config/nls/main' + 'esri/units' ], function ( declare, @@ -16,9 +14,7 @@ define([ dom, arcgisUtils, - units, - - i18n + units ) { return declare(null, { startup: function () { @@ -162,7 +158,7 @@ define([ id: 'directions', type: 'titlePane', path: 'gis/dijit/Directions', - title: i18n.viewer.widgets.directions, + title: 'Directions', open: false, position: 999, options: { @@ -186,7 +182,7 @@ define([ id: 'measurement', type: 'titlePane', path: 'gis/dijit/Measurement', - title: i18n.viewer.widgets.measure, + title: 'Measurement', open: false, position: 999, options: { From 9bab91be0f933310c5540d438d7c4b5b606c995e Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 3 Mar 2017 09:08:58 -0800 Subject: [PATCH 204/216] update flag-icon-css version to most recent. --- viewer/js/config/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 322a54645..f83155e22 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -17,7 +17,7 @@ location: '//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15' }, { name: 'flag-icon-css', - location: '//cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1' + location: '//cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.8.0' } ] }; From 1ee3e7fc04a7df5820dbcdd61e1bae3dbb378391 Mon Sep 17 00:00:00 2001 From: Gregg Roemhildt Date: Thu, 2 Mar 2017 19:58:19 -0600 Subject: [PATCH 205/216] make default config file configureable --- viewer/js/viewer/_ConfigMixin.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/viewer/js/viewer/_ConfigMixin.js b/viewer/js/viewer/_ConfigMixin.js index 10a7929fe..999f8ab14 100644 --- a/viewer/js/viewer/_ConfigMixin.js +++ b/viewer/js/viewer/_ConfigMixin.js @@ -9,6 +9,10 @@ define([ ) { return declare(null, { + + // the default name of the config file to load if ?config=configName + // is not specified + defaultConfig: 'viewer', loadConfig: function (wait) { // this will be used to make any inherited methods 'wait' @@ -49,7 +53,7 @@ define([ initConfigAsync: function () { var returnDeferred = new Deferred(); // get the config file from the url if present - var file = 'config/viewer', + var file = 'config/' + this.defaultConfig, s = window.location.search, q = s.match(/config=([^&]*)/i); if (q && q.length > 0) { From 36a3727e43a9246ae6a7709b033e24a8c68337cb Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 3 Mar 2017 13:08:41 -0600 Subject: [PATCH 206/216] mix-in parameters passed to app constructor --- viewer/js/viewer/_ControllerBase.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/viewer/js/viewer/_ControllerBase.js b/viewer/js/viewer/_ControllerBase.js index 20958b0d8..4ae03c5f7 100644 --- a/viewer/js/viewer/_ControllerBase.js +++ b/viewer/js/viewer/_ControllerBase.js @@ -8,6 +8,15 @@ define([ ) { return declare(null, { + /** + * Mixes in this apps properties with the passed arguments + * @param {Object} args The properties to mixin + * @return {undefined} + */ + constructor: function (args) { + lang.mixin(this, args); + }, + /** * A method run before anything else, can be inherited by mixins to * load and process the config sync or async From ea567b02714b405ab9d091afd6b77bcecf57827a Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 3 Mar 2017 14:05:32 -0600 Subject: [PATCH 207/216] add ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..413eaa59d --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,49 @@ + + +__How often can you reproduce it?__ + +- [ ] Always +- [ ] Sometimes +- [ ] Rarely +- [ ] Unable +- [ ] I didn’t try + + + +__Description:__ + + + + + +__Steps to reproduce:__ + +1. Include a JS Bin (or equivalent) link if possible. [You can use this as a starting point](http://jsbin.com/guresequba/edit?js,output) +2. Detail the exact steps taken to produce the problem +3. Include a gif if possible; you can use LICEcap to make a gif: http://www.cockos.com/licecap/ +4. Check the browser console for errors (Use F12 to access the console) + + + +__Expected results:__ + + + + + +__Actual results:__ + + + + + +__Environment:__ + +| Software | Version +| ------------------ | ------- +| CMV Version | +| Browser | +| Operating system | From cc810b70bb1c3eafc3906bd578c2a4293bef431c Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 3 Mar 2017 14:14:36 -0600 Subject: [PATCH 208/216] add pull request template --- .github/PULL_REQUEST_TEMPLATE.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..3fd7ca439 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ + + +# Description + + +# Use case + +```javascript +// how the code can be used +``` + +# Checklist + + + - [ ] `grunt lint` produces no error messages From c255512fb910bc24d6905fcc3817bbc11465faf1 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Fri, 3 Mar 2017 13:43:45 -0800 Subject: [PATCH 209/216] Updated badge for documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b2f9d9514..7757eb9b0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # CMV - The Configurable Map Viewer -[![Read The Docs](https://img.shields.io/badge/docs-1.3.4-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) ## Introduction [CMV](http://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](http://developers.arcgis.com/javascript/jsapi/3/), [ArcGIS Server](https://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. From e777cf338e82319857b580ab837f8795f2f17b9d Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Sat, 4 Mar 2017 00:33:06 +0000 Subject: [PATCH 210/216] chore(package): update dependencies https://greenkeeper.io/ --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 905f125b3..a83a5b61f 100644 --- a/package.json +++ b/package.json @@ -9,21 +9,21 @@ "dependencies": { "babel-eslint": "~7.1.1", "csslint": "1.0.x", - "eslint": "3.5.x", + "eslint": "~3.17.0", "grunt": "1.0.x", "grunt-contrib-clean": "1.0.x", "grunt-contrib-compress": "~1.4.1", "grunt-contrib-connect": "1.0.x", "grunt-contrib-copy": "1.0.x", "grunt-contrib-csslint": "~2.0.x", - "grunt-contrib-cssmin": "1.0.x", - "grunt-contrib-uglify": "2.1.x", + "grunt-contrib-cssmin": "~2.0.0", + "grunt-contrib-uglify": "~2.2.0", "grunt-contrib-watch": "1.0.x", "grunt-eslint": "19.0.x", "grunt-newer": "1.2.x", "grunt-open": "0.2.x", "grunt-postcss": "0.8.x", - "body-parser": "1.16.x", + "body-parser": "~1.17.0", "proxypage": "*" }, "engine": "node >= 4", From bb06971464313ece9b42439ff0078c454f3e4e1a Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Sat, 4 Mar 2017 00:44:30 +0000 Subject: [PATCH 211/216] docs(readme): add Greenkeeper badge https://greenkeeper.io/ --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b2f9d9514..7404eb130 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # CMV - The Configurable Map Viewer +[![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) + [![Read The Docs](https://img.shields.io/badge/docs-1.3.4-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) ## Introduction From 1de756639ca9de45da15f9ef3c5d7659d0bfde40 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 4 Mar 2017 08:25:28 -0800 Subject: [PATCH 212/216] Updated badge (again) for documentation after addition of Greenkeeper badge. missed second docs badge in README. --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7404eb130..e9f58ed32 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # CMV - The Configurable Map Viewer -[![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) - -[![Read The Docs](https://img.shields.io/badge/docs-1.3.4-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) ## Introduction [CMV](http://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](http://developers.arcgis.com/javascript/jsapi/3/), [ArcGIS Server](https://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. @@ -49,7 +47,7 @@ A [resource proxy](https://github.com/Esri/resource-proxy) may be required to ac ## Documentation: Use the [documentation](http://docs.cmv.io/) for getting started and guidance on configuring your application. The initial documentation is sparse. Please help make it better by contributing over at the [cmv documentation repo](https://github.com/cmv/cmv-docs). -[![Read The Docs](https://img.shields.io/badge/docs-1.3.4-brightgreen.svg?style=flat)](http://docs.cmv.io/) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](http://docs.cmv.io/) ## Community We have a gitter.im chat room. Come on by if you have questions. The community is very helpful. [https://gitter.im/cmv/cmv-app](https://gitter.im/cmv/cmv-app) From 74b1511833c4fc2520fa1d1da161225d192a2819 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 4 Mar 2017 15:50:08 -0800 Subject: [PATCH 213/216] HTTPS everywhere --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e9f58ed32..673261f21 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # CMV - The Configurable Map Viewer -[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](http://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://travis-ci.org/cmv/cmv-app.svg?branch=master)](http://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](https://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/cmv/cmv-app.svg?branch=master)](https://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) ## Introduction -[CMV](http://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](http://developers.arcgis.com/javascript/jsapi/3/), [ArcGIS Server](https://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. +[CMV](https://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](https://developers.arcgis.com/javascript/jsapi/3/), [ArcGIS Server](https://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. ## Make It Your Own! -This JavaScript web app can be easily configured or used as a boilerplate/starting point for basic viewers. It also demonstrates best practices for modular design and OOP via classes in JS using dojo's great [declare](http://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html) system. +This JavaScript web app can be easily configured or used as a boilerplate/starting point for basic viewers. It also demonstrates best practices for modular design and OOP via classes in JS using dojo's great [declare](https://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html) system. ## Try The Demo: -[http://demo.cmv.io/viewer/](http://demo.cmv.io/viewer/) +[https://demo.cmv.io/](https://demo.cmv.io/) ![screen shot 2014-08-20 at 9 59 48 pm](https://cloud.githubusercontent.com/assets/661156/3991302/5aa2e0f2-28df-11e4-94d0-9c813937d933.png) @@ -39,18 +39,18 @@ This JavaScript web app can be easily configured or used as a boilerplate/starti - Map Right click menu with various widget functions. - Highly configurable UI, right or left sidebars with widgets in both, top and bottom regions for other content. -Read more about the [core widgets](http://docs.cmv.io/en/latest/widgets/). In addition, there is a growing number of [widgets contributed by the CMV developer community](https://github.com/cmv/cmv-contrib-widgets). +Read more about the [core widgets](https://docs.cmv.io/en/latest/widgets/). In addition, there is a growing number of [widgets contributed by the CMV developer community](https://github.com/cmv/cmv-contrib-widgets). ## Resource Proxy: A [resource proxy](https://github.com/Esri/resource-proxy) may be required to access some MapServices and other content that reside on a different domain. A proxy is not available for the Github demo. ## Documentation: -Use the [documentation](http://docs.cmv.io/) for getting started and guidance on configuring your application. The initial documentation is sparse. Please help make it better by contributing over at the [cmv documentation repo](https://github.com/cmv/cmv-docs). +Use the [documentation](https://docs.cmv.io/) for getting started and guidance on configuring your application. The initial documentation is sparse. Please help make it better by contributing over at the [cmv documentation repo](https://github.com/cmv/cmv-docs). -[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](http://docs.cmv.io/) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](https://docs.cmv.io/) ## Community -We have a gitter.im chat room. Come on by if you have questions. The community is very helpful. [https://gitter.im/cmv/cmv-app](https://gitter.im/cmv/cmv-app) +We have a [gitter.im chat room](https://gitter.im/cmv/cmv-app). Come on by if you have questions. The community is very active and helpful. [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) @@ -69,7 +69,7 @@ There are many ways to contribute to CMV: 4. __Join the Chat Room__ - Lots of us in CMV community hang out in the chat room on [Gitter](https://gitter.im/cmv/cmv-app/). Feel free to hangout with us, answer questions and throw out ideas. -5. __Submit a Pull Request__ - If you are developer and have an enhancement or bug fix you would like to submit, pull requests are welcome. Please review the [Contributing on GitHub](http://docs.cmv.io/en/latest/contribute/ContributingOnGitHub) documentation before submitting any Pull Requests. +5. __Submit a Pull Request__ - If you are developer and have an enhancement or bug fix you would like to submit, pull requests are welcome. Please review the [Contributing on GitHub](https://docs.cmv.io/en/latest/contribute/ContributingOnGitHub) documentation before submitting any Pull Requests. 6. __User contributed widgets__ - For general information on how to build a CMV widget [read the docs](https://docs.cmv.io/en/latest). Users can submit widgets to the [cmv-contrib-widgets](https://github.com/cmv/cmv-contrib-widgets) repo. These widgets are created and submitted by users. Head on over and read the details. From cefe3cefaa0f9d09a0cfafab4f7abbad6488be39 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 4 Mar 2017 15:50:30 -0800 Subject: [PATCH 214/216] updated screenshot --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 673261f21..e393463c6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ This JavaScript web app can be easily configured or used as a boilerplate/starti ## Try The Demo: [https://demo.cmv.io/](https://demo.cmv.io/) -![screen shot 2014-08-20 at 9 59 48 pm](https://cloud.githubusercontent.com/assets/661156/3991302/5aa2e0f2-28df-11e4-94d0-9c813937d933.png) +[![Screenshot](https://cloud.githubusercontent.com/assets/200780/23583081/e38becbc-00ee-11e7-86da-13b0bf91ad8d.png)](https://demo.cmv.io/) ## Widgets Included: - Basemaps From 17e360fe2c614bb59d65f0ea7b9c9ab9c120dd71 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 4 Mar 2017 16:09:03 -0800 Subject: [PATCH 215/216] Add CMV rocket logo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e393463c6..98a184156 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# CMV - The Configurable Map Viewer +# CMV The Configurable Map Viewer [![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](https://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/cmv/cmv-app.svg?branch=master)](https://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) From 874b326b362a208632e8e8ba443023dae0a407c3 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 4 Mar 2017 16:21:42 -0800 Subject: [PATCH 216/216] use relative link for logo image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 98a184156..4e1417eb2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# CMV The Configurable Map Viewer +# CMV The Configurable Map Viewer [![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](https://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/cmv/cmv-app.svg?branch=master)](https://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/)