diff --git a/.gitattributes b/.gitattributes index 1151fa3f24e..6acaaad4ed5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,3 +8,4 @@ Makefile* text whitespace=indent-with-non-tab,tabwidth=2 eol=lf *.gif binary *.ico binary *.enc binary +*.cur binary diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index d63da101a70..52706362ed3 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -3,7 +3,7 @@ To check before create a new issue: * I am using the latest minor version of the major version (`x.y.last`). * I create one issue per subject (do not put more than one thing in the same issue). -For commiters: +For committers: * I have assigned a blue and a green label. * I have assigned a milestone. diff --git a/.gitignore b/.gitignore index ab1d060bd55..7f327c11f47 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ /contribs/gmf/fonts/gmf-icons.woff /contribs/gmf/fonts/FontAwesome* /contribs/gmf/fonts/fontawesome* -/contribs/gmf/cursors/*.cur /contribs/gmf/examples/https.js /test/spec/templatecache.js /test/spec/gmftemplatecache.js diff --git a/Makefile b/Makefile index fa5be0aa8f4..560edd5d72e 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ NGEO_EXAMPLES_JS_FILES := $(NGEO_EXAMPLES_HTML_FILES:.html=.js) GMF_PARTIALS_FILES := $(shell find contribs/gmf/src/ -name *.html) GMF_JS_FILES := $(shell find contribs/gmf/src/ -type f -name '*.js') -GMF_ALL_SRC_FILES := $(shell find contribs/gmf/src/ -type f) $(NGEO_ALL_SRC_FILES) +GMF_ALL_SRC_FILES := $(shell find contribs/gmf/src/ -type f) $(shell find contribs/gmf/cursors/ -type f) $(NGEO_ALL_SRC_FILES) GMF_TEST_JS_FILES := $(shell find contribs/gmf/test/ -type f -name '*.js') GMF_EXAMPLES_HTML_FILES := $(shell ls -1 contribs/gmf/examples/*.html) GMF_EXAMPLES_JS_FILES := $(GMF_EXAMPLES_HTML_FILES:.html=.js) @@ -110,8 +110,8 @@ help: @echo "- test Run the test suite" @echo "- test-debug Run the test suite in the browser" @echo "- clean Remove generated files" - @echo "- cleanall Remove all the build artefacts" - @echo "- cleanallcache Remove all the build artefacts and the extra caches (npm and pip)" + @echo "- cleanall Remove all the build artifacts" + @echo "- cleanallcache Remove all the build artifacts and the extra caches (npm and pip)" @echo @echo "Secondary targets:" @echo @@ -124,7 +124,7 @@ help: apidoc: .build/apidoc .PHONY: check -check: lint check-examples-checker check-examples test examples-hosted-apps +check: lint spell check-examples-checker check-examples test examples-hosted-apps .PHONY: check-examples-checker check-example-checker: $(CHECK_EXAMPLE_CHECKER) @@ -140,6 +140,14 @@ lint-extra: if [ "`git grep @fileoverview src contribs`" != "" ]; then echo "Using @fileoverview breaks the documentation main page"; false; fi if [ "`git grep @example src contribs`" != "" ]; then echo "We don't use @example to have the example in the description"; false; fi +.PHONY: spell +spell: .build/python-venv.timestamp + $(PY_VENV_BIN)/codespell --quiet-level=2 --ignore-words=spell-ignore-words.txt \ + $(shell find -name 'node_modules' -prune -or -name '.build' -prune -or -name '.git' -prune \ + -or -name '__pycache__' -prune -or -name 'build' -prune \ + -or \( -type f -and -not -name '*.png' -and -not -name '*.mo' -and -not -name '*.po*' -and -not -name '*_translation' \ + -and -not -name 'themescapabilities.js' -and -not -name 'themes.js' -and -not -name 'prettify.js' \) -print) + .PHONY: eslint eslint: .build/eslint.timestamp @@ -153,7 +161,7 @@ eof-newline: .PHONY: test test: .build/node_modules.timestamp - ./node_modules/karma/bin/karma start karma-conf.js --single-run + THEME=mobile ./node_modules/karma/bin/karma start karma-conf.js --single-run @echo "\nFull coverage report in: .build/coverage/lcov-report" .PHONY: test-debug @@ -171,7 +179,7 @@ serve-ngeo: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCAL .PHONY: serve-gmf serve-gmf: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - npm run serve-gmf-examples + THEME=mobile npm run serve-gmf-examples .PHONY: serve-gmf-apps-desktop serve-gmf-apps-desktop: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) @@ -183,11 +191,11 @@ serve-gmf-apps-desktopalt: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) .PHONY: serve-gmf-apps-mobile serve-gmf-apps-mobile: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - APP=mobile npm run serve-gmf-apps + APP=mobile npm THEME=mobile run serve-gmf-apps .PHONY: serve-gmf-apps-mobilealt serve-gmf-apps-mobilealt: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - APP=mobile_alt npm run serve-gmf-apps + APP=mobile_alt THEME=mobile npm run serve-gmf-apps .PHONY: serve-gmf-apps-oeedit serve-gmf-apps-oeedit: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) @@ -214,7 +222,7 @@ examples-hosted-ngeo: .build/examples-ngeo.timestamp .build/examples-hosted/inde examples-hosted-gmf: .build/examples-gmf.timestamp .build/examples-hosted/contribs/gmf/index.html .build/examples-gmf.timestamp: $(GMF_ALL_SRC_FILES) $(WEBPACK_CONFIG_FILES) .build/node_modules.timestamp - npm run build-gmf-examples + THEME=mobile npm run build-gmf-examples touch $@ .PHONY: examples-hosted-apps @@ -223,8 +231,8 @@ examples-hosted-apps: .build/gmf-apps.timestamp .build/examples-hosted-gmf-apps- .build/gmf-apps.timestamp: $(GMF_APPS_ALL_SRC_FILES) $(WEBPACK_CONFIG_FILES) .build/node_modules.timestamp APP=desktop THEME=desktop npm run build-gmf-apps APP=desktop_alt THEME=desktop_alt npm run build-gmf-apps - APP=mobile npm run build-gmf-apps - APP=mobile_alt npm run build-gmf-apps + APP=mobile THEME=mobile npm run build-gmf-apps + APP=mobile_alt THEME=mobile npm run build-gmf-apps APP=oeedit THEME=desktop npm run build-gmf-apps APP=oeview THEME=desktop npm run build-gmf-apps touch $@ @@ -246,8 +254,7 @@ gh-pages: .build/python-venv.timestamp .build/examples-hosted-gmf-apps-deps.timestamp: \ $(addprefix contribs/gmf/build/gmf-, $(addsuffix .json, $(LANGUAGES))) \ - $(addprefix contribs/gmf/build/angular-locale_, $(addsuffix .js, $(LANGUAGES))) \ - $(addprefix contribs/gmf/cursors/,grab.cur grabbing.cur) + $(addprefix contribs/gmf/build/angular-locale_, $(addsuffix .js, $(LANGUAGES))) mkdir -p .build/examples-hosted/contribs/gmf # We need the files for each app # To simplify processing, we first copy them in gmfappsdeps directory, then from there to each app @@ -338,10 +345,6 @@ contribs/gmf/build/angular-locale_%.js: package.json rm -rf $@ ./node_modules/.bin/jsdoc -c $< --destination $@ -.PRECIOUS: contribs/gmf/cursors/%.cur -contribs/gmf/cursors/%.cur: contribs/gmf/cursors/%.png - convert $< $@ - # i18n diff --git a/buildtools/check-example.js b/buildtools/check-example.js index 2a16ce1f443..ef2d75d2bb6 100644 --- a/buildtools/check-example.js +++ b/buildtools/check-example.js @@ -37,12 +37,12 @@ page.onAlert = function(msg) { }; page.onResourceError = function(resourceError) { if (resourceError.url.includes('tile.openstreetmap.org')) { - console.warn('Ignoring ressource error from OpenStreetMap'); + console.warn('Ignoring resource error from OpenStreetMap'); } else if (resourceError.url.includes('https://maps.googleapis.com/maps/api/js')) { - console.warn('Ignoring ressource error from Google'); + console.warn('Ignoring resource error from Google'); } else if (resourceError.url.includes('https://csi.gstatic.com/')) { - console.warn('Ignoring ressource error from Google static'); - } else if (resourceError.errorCode >= 300) { + console.warn('Ignoring resource error from Google static'); + } else if (resourceError.errorCode >= 400) { console.log('Resource error: ' + resourceError.errorCode + ', ' + resourceError.url); exitCode = 2; } diff --git a/buildtools/webpack.commons.js b/buildtools/webpack.commons.js index c994f4bba32..fdf185f8c34 100644 --- a/buildtools/webpack.commons.js +++ b/buildtools/webpack.commons.js @@ -7,6 +7,7 @@ const LessPluginAutoprefix = require('less-plugin-autoprefix'); const devMode = process.env.NODE_ENV !== 'production' const themes = { + 'mobile': '"~gmf/controllers/mobile-theme.less"', 'desktop': '"~gmf/controllers/desktop-theme.less"', 'desktop_alt': '"' + path.resolve('contribs/gmf/apps/desktop_alt/less/theme.less') + '"', } @@ -127,7 +128,7 @@ const cssLessLoaderConfigs = [ new LessPluginAutoprefix() ], modifyVars: { - 'THEME': themes[theme], + 'THEME': themes[theme] ? themes[theme] : theme, } } } diff --git a/contribs/gmf/apps/desktop/Controller.js b/contribs/gmf/apps/desktop/Controller.js index be91a5bb194..5eccaf3c7c0 100644 --- a/contribs/gmf/apps/desktop/Controller.js +++ b/contribs/gmf/apps/desktop/Controller.js @@ -14,6 +14,8 @@ import appBase from '../appmodule.js'; import ngeoProjEPSG2056 from 'ngeo/proj/EPSG2056.js'; import ngeoProjEPSG21781 from 'ngeo/proj/EPSG21781.js'; import * as olBase from 'ol/index.js'; +import Raven from 'raven-js/src/raven.js'; +import RavenPluginsAngular from 'raven-js/plugins/angular.js'; if (!window.requestAnimationFrame) { alert('Your browser is not supported, please update it or use another one. You will be redirected.\n\n' @@ -97,6 +99,14 @@ const exports = function($scope, $injector) { gettextCatalog.getString('Add a theme'); gettextCatalog.getString('Add a sub theme'); gettextCatalog.getString('Add a layer'); + + if ($injector.has('sentryUrl')) { + const options = $injector.has('sentryOptions') ? $injector.get('sentryOptions') : undefined; + const raven = new Raven(); + raven.config($injector.get('sentryUrl'), options) + .addPlugin(RavenPluginsAngular) + .install(); + } }; olBase.inherits(exports, gmfControllersAbstractDesktopController); diff --git a/contribs/gmf/apps/desktop_alt/Controller.js b/contribs/gmf/apps/desktop_alt/Controller.js index 5a628ce4ae1..229ed8284b0 100644 --- a/contribs/gmf/apps/desktop_alt/Controller.js +++ b/contribs/gmf/apps/desktop_alt/Controller.js @@ -17,6 +17,8 @@ import ngeoRoutingModule from 'ngeo/routing/module.js'; import ngeoProjEPSG2056 from 'ngeo/proj/EPSG2056.js'; import ngeoProjEPSG21781 from 'ngeo/proj/EPSG21781.js'; import * as olBase from 'ol/index.js'; +import Raven from 'raven-js/src/raven.js'; +import RavenPluginsAngular from 'raven-js/plugins/angular.js'; if (!window.requestAnimationFrame) { alert('Your browser is not supported, please update it or use another one. You will be redirected.\n\n' @@ -127,6 +129,14 @@ const exports = function($scope, $injector, ngeoFile, gettext, $q) { * @export */ this.bgOpacityOptions = 'Test aus Olten'; + + if ($injector.has('sentryUrl')) { + const options = $injector.has('sentryOptions') ? $injector.get('sentryOptions') : undefined; + const raven = new Raven(); + raven.config($injector.get('sentryUrl'), options) + .addPlugin(RavenPluginsAngular) + .install(); + } }; olBase.inherits(exports, gmfControllersAbstractDesktopController); diff --git a/contribs/gmf/apps/mobile/Controller.js b/contribs/gmf/apps/mobile/Controller.js index 1de8986c665..f5a88f356f0 100644 --- a/contribs/gmf/apps/mobile/Controller.js +++ b/contribs/gmf/apps/mobile/Controller.js @@ -14,6 +14,8 @@ import appBase from '../appmodule.js'; import ngeoProjEPSG2056 from 'ngeo/proj/EPSG2056.js'; import ngeoProjEPSG21781 from 'ngeo/proj/EPSG21781.js'; import * as olBase from 'ol/index.js'; +import Raven from 'raven-js/src/raven.js'; +import RavenPluginsAngular from 'raven-js/plugins/angular.js'; if (!window.requestAnimationFrame) { alert('Your browser is not supported, please update it or use another one. You will be redirected.\n\n' @@ -56,6 +58,13 @@ const exports = function($scope, $injector) { */ this.searchCoordinatesProjections = [ngeoProjEPSG21781, ngeoProjEPSG2056, 'EPSG:4326']; + if ($injector.has('sentryUrl')) { + const options = $injector.has('sentryOptions') ? $injector.get('sentryOptions') : undefined; + const raven = new Raven(); + raven.config($injector.get('sentryUrl'), options) + .addPlugin(RavenPluginsAngular) + .install(); + } }; olBase.inherits(exports, gmfControllersAbstractMobileController); diff --git a/contribs/gmf/apps/mobile_alt/Controller.js b/contribs/gmf/apps/mobile_alt/Controller.js index bc8e27d567e..09069360277 100644 --- a/contribs/gmf/apps/mobile_alt/Controller.js +++ b/contribs/gmf/apps/mobile_alt/Controller.js @@ -18,6 +18,8 @@ import olStyleFill from 'ol/style/Fill.js'; import olStyleRegularShape from 'ol/style/RegularShape.js'; import olStyleStroke from 'ol/style/Stroke.js'; import olStyleStyle from 'ol/style/Style.js'; +import Raven from 'raven-js/src/raven.js'; +import RavenPluginsAngular from 'raven-js/plugins/angular.js'; if (!window.requestAnimationFrame) { alert('Your browser is not supported, please update it or use another one. You will be redirected.\n\n' @@ -93,6 +95,13 @@ const exports = function($scope, $injector) { }) }); + if ($injector.has('sentryUrl')) { + const options = $injector.has('sentryOptions') ? $injector.get('sentryOptions') : undefined; + const raven = new Raven(); + raven.config($injector.get('sentryUrl'), options) + .addPlugin(RavenPluginsAngular) + .install(); + } }; olBase.inherits(exports, gmfControllersAbstractMobileController); diff --git a/contribs/gmf/apps/oeedit/Controller.js b/contribs/gmf/apps/oeedit/Controller.js index 0be987890ef..fa1cbcceea3 100644 --- a/contribs/gmf/apps/oeedit/Controller.js +++ b/contribs/gmf/apps/oeedit/Controller.js @@ -19,6 +19,8 @@ import * as olBase from 'ol/index.js'; import olCollection from 'ol/Collection.js'; import olLayerVector from 'ol/layer/Vector.js'; import olSourceVector from 'ol/source/Vector.js'; +import Raven from 'raven-js/src/raven.js'; +import RavenPluginsAngular from 'raven-js/plugins/angular.js'; if (!window.requestAnimationFrame) { alert('Your browser is not supported, please update it or use another one. You will be redirected.\n\n' @@ -206,6 +208,14 @@ const exports = function($scope, $injector, $timeout) { gettextCatalog.getString('Add a theme'); gettextCatalog.getString('Add a sub theme'); gettextCatalog.getString('Add a layer'); + + if ($injector.has('sentryUrl')) { + const options = $injector.has('sentryOptions') ? $injector.get('sentryOptions') : undefined; + const raven = new Raven(); + raven.config($injector.get('sentryUrl'), options) + .addPlugin(RavenPluginsAngular) + .install(); + } }; olBase.inherits(exports, gmfControllersAbstractDesktopController); diff --git a/contribs/gmf/apps/oeview/Controller.js b/contribs/gmf/apps/oeview/Controller.js index bf4c18a6161..b0697747bc0 100644 --- a/contribs/gmf/apps/oeview/Controller.js +++ b/contribs/gmf/apps/oeview/Controller.js @@ -14,6 +14,8 @@ import appBase from '../appmodule.js'; import ngeoProjEPSG2056 from 'ngeo/proj/EPSG2056.js'; import ngeoProjEPSG21781 from 'ngeo/proj/EPSG21781.js'; import * as olBase from 'ol/index.js'; +import Raven from 'raven-js/src/raven.js'; +import RavenPluginsAngular from 'raven-js/plugins/angular.js'; if (!window.requestAnimationFrame) { alert('Your browser is not supported, please update it or use another one. You will be redirected.\n\n' @@ -97,6 +99,14 @@ const exports = function($scope, $injector) { gettextCatalog.getString('Add a theme'); gettextCatalog.getString('Add a sub theme'); gettextCatalog.getString('Add a layer'); + + if ($injector.has('sentryUrl')) { + const options = $injector.has('sentryOptions') ? $injector.get('sentryOptions') : undefined; + const raven = new Raven(); + raven.config($injector.get('sentryUrl'), options) + .addPlugin(RavenPluginsAngular) + .install(); + } }; olBase.inherits(exports, gmfControllersAbstractDesktopController); diff --git a/contribs/gmf/cursors/Grab_hand_animation_2sec.gif b/contribs/gmf/cursors/Grab_hand_animation_2sec.gif deleted file mode 100644 index 17002971bce..00000000000 Binary files a/contribs/gmf/cursors/Grab_hand_animation_2sec.gif and /dev/null differ diff --git a/contribs/gmf/cursors/grab.cur b/contribs/gmf/cursors/grab.cur new file mode 100644 index 00000000000..c72cd91a05f Binary files /dev/null and b/contribs/gmf/cursors/grab.cur differ diff --git a/contribs/gmf/cursors/grab.png b/contribs/gmf/cursors/grab.png deleted file mode 100644 index 2555f931f74..00000000000 Binary files a/contribs/gmf/cursors/grab.png and /dev/null differ diff --git a/contribs/gmf/cursors/grabbing.cur b/contribs/gmf/cursors/grabbing.cur new file mode 100644 index 00000000000..123dc2d3400 Binary files /dev/null and b/contribs/gmf/cursors/grabbing.cur differ diff --git a/contribs/gmf/cursors/grabbing.png b/contribs/gmf/cursors/grabbing.png deleted file mode 100644 index a2843dd716d..00000000000 Binary files a/contribs/gmf/cursors/grabbing.png and /dev/null differ diff --git a/contribs/gmf/examples/datepicker.html b/contribs/gmf/examples/datepicker.html index b09000735ea..c9d9f748f51 100644 --- a/contribs/gmf/examples/datepicker.html +++ b/contribs/gmf/examples/datepicker.html @@ -14,7 +14,7 @@
  • - Date formated for a WMS request (resolution set on 'day'): + Date formatted for a WMS request (resolution set on 'day'):
               {{ctrl.rangeValue}}
             
    @@ -23,7 +23,7 @@
  • - Date formated for a WMS request (resolution set on 'month'): + Date formatted for a WMS request (resolution set on 'month'):
               {{ctrl.value}}
             
    diff --git a/contribs/gmf/examples/profile.html b/contribs/gmf/examples/profile.html index 7b41197a334..92ed1cfcf30 100644 --- a/contribs/gmf/examples/profile.html +++ b/contribs/gmf/examples/profile.html @@ -13,7 +13,7 @@

    This example shows how to use the gmf-profile. - The draw tool and hover feedback on the map are completely independant of + The draw tool and hover feedback on the map are completely independent of the gmf-profile components. This profile relies on the ngeo.profile (d3) and ngeo.ProfileDirective. It passes a custom css through the optional gmf-profile-options attribute

    diff --git a/contribs/gmf/examples/timeslider.html b/contribs/gmf/examples/timeslider.html index 1d4c43fe8eb..ab17777aae7 100644 --- a/contribs/gmf/examples/timeslider.html +++ b/contribs/gmf/examples/timeslider.html @@ -17,7 +17,7 @@
  • - Date formated for a WMS request (resolution set on 'day'): + Date formatted for a WMS request (resolution set on 'day'):
               {{ctrl.sliderRangeValue}}
             
    @@ -29,7 +29,7 @@
  • - Date formated for a WMS request (resolution set on 'year'): + Date formatted for a WMS request (resolution set on 'year'):
               {{ctrl.sliderValue}}
             
    diff --git a/contribs/gmf/externs/gmf-themes.js b/contribs/gmf/externs/gmf-themes.js index 73c14d792c9..45248b1259f 100644 --- a/contribs/gmf/externs/gmf-themes.js +++ b/contribs/gmf/externs/gmf-themes.js @@ -146,7 +146,7 @@ gmfThemes.GmfGroup.prototype.ogcServer; /** - * On non mixed first level group with more then one time layer, it is the time informations. + * On non mixed first level group with more then one time layer, it is the time information. * @type {ngeox.TimeProperty|undefined} */ gmfThemes.GmfGroup.prototype.time; @@ -232,7 +232,7 @@ gmfThemes.GmfLayerWMS.prototype.ogcServer; /** - * The time informations if the layer directly manage it, see + * The time information if the layer directly manage it, see * also {gmfThemes.GmfGroup.time}. * @type {ngeox.TimeProperty|undefined} */ @@ -378,7 +378,7 @@ gmfThemes.GmfFunctionalities.prototype.default_basemap; /** * When set, contains the name of the panel to open upon loading an application. - * Note: altough this is a list, only one can be defined. + * Note: although this is a list, only one can be defined. * @type {Array.|undefined} */ gmfThemes.GmfFunctionalities.prototype.open_panel; @@ -387,7 +387,7 @@ gmfThemes.GmfFunctionalities.prototype.open_panel; /** * Name of the layer (data source) that should be toggled in the filter tool * upon loading an application. - * Note: altough this is a list, only one can be defined. + * Note: although this is a list, only one can be defined. * @type {Array.|undefined} */ gmfThemes.GmfFunctionalities.prototype.preset_layer_filter; @@ -561,7 +561,7 @@ gmfThemes.GmfMetaData.prototype.maxResolution; /** - * The URL to the informations on this layer. + * The URL to the information on this layer. * For WMS and WMTS layers. * @type {string|undefined} */ diff --git a/contribs/gmf/options/gmfx.js b/contribs/gmf/options/gmfx.js index db6a39c941c..5368dc58967 100644 --- a/contribs/gmf/options/gmfx.js +++ b/contribs/gmf/options/gmfx.js @@ -178,7 +178,7 @@ gmfx.MousePositionProjection.prototype.code; /** - * The label to diplay with this projection. + * The label to display with this projection. * @type {string} */ gmfx.MousePositionProjection.prototype.label; @@ -753,7 +753,7 @@ gmfx.datasource.OGCOptions; /** * A reference to the GMF layer node that was used to create the data source. - * It may contains additionnal information, such as metadata, about the data + * It may contains additional information, such as metadata, about the data * source. * @type {gmfThemes.GmfLayer} */ diff --git a/contribs/gmf/src/contextualdata/component.js b/contribs/gmf/src/contextualdata/component.js index b2cc6a289dc..eee802a13f0 100644 --- a/contribs/gmf/src/contextualdata/component.js +++ b/contribs/gmf/src/contextualdata/component.js @@ -80,6 +80,7 @@ exports.directive('gmfContextualdata', /** * * @param {angular.$compile} $compile Angular compile service. + * @param {angular.$timeout} $timeout Angular timeout service. * @param {!angular.Scope} $scope Scope. * @param {gmf.raster.RasterService} gmfRaster Gmf Raster service * @@ -88,7 +89,7 @@ exports.directive('gmfContextualdata', * @ngdoc controller * @ngInject */ -exports.Controller_ = function($compile, $scope, gmfRaster) { +exports.Controller_ = function($compile, $timeout, $scope, gmfRaster) { /** * @type {ol.Map} @@ -120,6 +121,12 @@ exports.Controller_ = function($compile, $scope, gmfRaster) { */ this.$compile_ = $compile; + /** + * @type {angular.$timeout} + * @private + */ + this.timeout_ = $timeout; + /** * @type {angular.Scope} * @private @@ -160,7 +167,11 @@ exports.Controller_.prototype.handleMapContextMenu_ = function(event) { event.preventDefault(); this.hidePopover(); this.showPopover(); - this.overlay_.setPosition(coordinate); + + // Use timeout to let the popover content to be rendered before displaying it. + this.timeout_(() => { + this.overlay_.setPosition(coordinate); + }); }); }; diff --git a/contribs/gmf/src/controllers/mobile-theme.less b/contribs/gmf/src/controllers/mobile-theme.less new file mode 100644 index 00000000000..e69de29bb2d diff --git a/contribs/gmf/src/filters/filterselectorComponent.js b/contribs/gmf/src/filters/filterselectorComponent.js index fa79ce57b89..a68c7cab817 100644 --- a/contribs/gmf/src/filters/filterselectorComponent.js +++ b/contribs/gmf/src/filters/filterselectorComponent.js @@ -354,7 +354,7 @@ exports.Controller_ = class { /** * Called when the active property changes. Toggle data source registration. - * Also, when deactivated, unselect data source. + * Also, when deactivated, deselect data source. * @param {boolean} active Active. * @private */ @@ -454,7 +454,7 @@ exports.Controller_ = class { /** * Unregister a data source if it's filtrable. Also, if it's the one - * that was currently selected, unselect it. + * that was currently selected, deselect it. * @param {gmf.datasource.OGC} dataSource Data source * @private */ diff --git a/contribs/gmf/src/layertree/TreeManager.js b/contribs/gmf/src/layertree/TreeManager.js index c78ef1c7d5e..7f95422ff4a 100644 --- a/contribs/gmf/src/layertree/TreeManager.js +++ b/contribs/gmf/src/layertree/TreeManager.js @@ -88,7 +88,7 @@ const exports = function($timeout, $injector, gettextCatalog, ngeoLayerHelper, /** * The controller of the (unique) root layer tree. - * The array of top level layer trees is avaible through `rootCtrl.children`. + * The array of top level layer trees is available through `rootCtrl.children`. * The order doesn't match with the ordre of the displayed layertree. * @type {ngeo.layertree.Controller} * @export @@ -576,7 +576,7 @@ exports.prototype.setNodeMetadataFromFullState_ = function(node, fullState) { }); } - // Set the metadata with the fullState object informations. + // Set the metadata with the fullState object information. const metadata = node.metadata; metadata.isChecked = fullState.isChecked; metadata.isExpanded = fullState.isExpanded; diff --git a/contribs/gmf/src/layertree/component.js b/contribs/gmf/src/layertree/component.js index 759c12d7f13..8ff442a3062 100644 --- a/contribs/gmf/src/layertree/component.js +++ b/contribs/gmf/src/layertree/component.js @@ -98,7 +98,7 @@ function gmfLayertreeTemplate($element, $attrs, gmfLayertreeTemplate) { * This component creates a layertree based on the c2cgeoportal JSON themes * source and a {@link ngeo.layertreeComponent}. The controller used by this * component defines some functions for each node that are created by a default - * template. This default template can be overrided by setting the value + * template. This default template can be overridden by setting the value * 'gmf.layertreeTemplateUrl' but you will have to adapt the * ngeoLayertreeTemplateUrl value too (to define the children's nodes template * path). @@ -532,7 +532,7 @@ exports.Controller_.prototype.getLegendsObject = function(treeCtrl) { let layersNames = gmfLayerWMS.layers; const gmfOgcServer = this.gmfTreeManager_.getOgcServer(treeCtrl); const scale = this.getScale_(); - // QGIS can handle multiple layers natively. Use Mutliple urls for other map + // QGIS can handle multiple layers natively. Use Multiple URLs for other map // servers if (gmfOgcServer.type === ngeoDatasourceOGC.ServerType.QGISSERVER) { layersNames = [layersNames]; diff --git a/contribs/gmf/src/less/vars.less b/contribs/gmf/src/less/vars.less index f1d0bc006a9..ec30fcd16ae 100644 --- a/contribs/gmf/src/less/vars.less +++ b/contribs/gmf/src/less/vars.less @@ -1,5 +1,7 @@ @import "~bootstrap/less/variables.less"; +@search-width: 6 * @map-tools-size; + @app-margin: 1rem; @half-app-margin: 0.5rem; @micro-app-margin: 0.2rem; @@ -36,4 +38,4 @@ @brand-secondary: #d3e5d7; @font-size-small: 0.9em; -@import (optional) "@{THEME}"; +@import "@{THEME}"; diff --git a/contribs/gmf/src/lidarprofile/Manager.js b/contribs/gmf/src/lidarprofile/Manager.js index 5ad0bcf1d0f..43deb5dd4d0 100644 --- a/contribs/gmf/src/lidarprofile/Manager.js +++ b/contribs/gmf/src/lidarprofile/Manager.js @@ -83,7 +83,7 @@ const exports = class { this.map_ = null; /** - * The hovered point attributes in d3 profile highlighted on the 2D map + * The hovered point attributes in D3 profile highlighted on the 2D map * @type {ol.Overlay} */ this.cartoHighlight = new olOverlay({ @@ -92,7 +92,7 @@ const exports = class { }); /** - * The hovered point geometry (point) in d3 profile highlighted on the 2D map + * The hovered point geometry (point) in D3 profile highlighted on the 2D map * @type {ol.layer.Vector} */ this.lidarPointHighlight = new olLayerVector({ @@ -201,11 +201,11 @@ const exports = class { /** - * Load profile data (lidar points) by succesive Levels Of Details using asynchronous requests + * Load profile data (lidar points) by successive Levels Of Details using asynchronous requests * @param {Array} clippedLine an array of the clipped line coordinates - * @param {number} distanceOffset the left side of d3 profile domain at current zoom and pan configuration - * @param {boolean} resetPlot wether to reset d3 plot or not - * @param {number} minLOD minimum level of detail + * @param {number} distanceOffset the left side of D3 profile domain at current zoom and pan configuration + * @param {boolean} resetPlot whether to reset D3 plot or not + * @param {number} minLOD minimum Level Of Detail * @export */ getProfileByLOD(clippedLine, distanceOffset, resetPlot, minLOD) { @@ -265,14 +265,14 @@ const exports = class { /** * Request to Pytree service for a range of Level Of Detail (LOD) - * @param {number} minLOD minimum level of detail of the request - * @param {number} maxLOD maximum level of detail of the request + * @param {number} minLOD minimum Level Of Detail of the request + * @param {number} maxLOD maximum Level Of Detail of the request * @param {number} iter the iteration in profile requests cycle * @param {string} coordinates linestring in cPotree format - * @param {number} distanceOffset the left side of d3 profile domain at current zoom and pan configuration + * @param {number} distanceOffset the left side of D3 profile domain at current zoom and pan configuration * @param {boolean} lastLOD the deepest level to retrieve for this profile * @param {number} width the width of the profile - * @param {boolean} resetPlot wether to reset d3 plot or not, used for first LOD + * @param {boolean} resetPlot whether to reset D3 plot or not, used for first LOD * @private */ queryPytree_(minLOD, maxLOD, iter, coordinates, distanceOffset, lastLOD, width, resetPlot) { @@ -312,9 +312,9 @@ const exports = class { * Process the binary array return by Pytree (cPotree) * @param {ArrayBuffer} profile binary array returned by cPotree executable called by Pytree * @param {number} iter the iteration in profile requests cycle - * @param {number} distanceOffset the left side of d3 profile domain at current zoom and pan configuration + * @param {number} distanceOffset the left side of D3 profile domain at current zoom and pan configuration * @param {boolean} lastLOD the deepest level to retrieve for this profile - * @param {boolean} resetPlot wether to reset d3 plot or not + * @param {boolean} resetPlot whether to reset D3 plot or not * @private */ processBuffer_(profile, iter, distanceOffset, lastLOD, resetPlot) { @@ -449,7 +449,7 @@ const exports = class { } /** - * Update the profile data according to d3 chart zoom and pan level + * Update the profile data according to D3 chart zoom and pan level * The update will wait on a 200ms pause on the actions of users before to do the update. * @export */ diff --git a/contribs/gmf/src/lidarprofile/Plot.js b/contribs/gmf/src/lidarprofile/Plot.js index 0fc671052c8..4e25f80404d 100644 --- a/contribs/gmf/src/lidarprofile/Plot.js +++ b/contribs/gmf/src/lidarprofile/Plot.js @@ -24,7 +24,7 @@ const exports = class { /** * Provides a service to create an SVG element with defined axis and a LIDAR - * point drawing mecanism. + * point drawing mechanism. * * @struct * @param {gmf.lidarprofile.Manager} gmfLidarprofileManagerInstance gmf lidar profile manager instance @@ -137,7 +137,7 @@ const exports = class { /** - * Setup the SVG components of the d3 chart + * Setup the SVG components of the D3 chart * @param {Array.} rangeX range of the x scale * @param {Array.} rangeY range of the y scale * @export diff --git a/contribs/gmf/src/lidarprofile/Utils.js b/contribs/gmf/src/lidarprofile/Utils.js index 3ae5033c7c2..e0547e8c449 100644 --- a/contribs/gmf/src/lidarprofile/Utils.js +++ b/contribs/gmf/src/lidarprofile/Utils.js @@ -18,7 +18,7 @@ const d3 = { const exports = class { /** - * Clip a linstring with start and end measure givent by d3 Chart domain + * Clip a linstring with start and end measure given by D3 Chart domain * @param {gmf.lidarprofile.Config} config the LIDAR profile config instance * @param {number} map_resolution the current resolution of the map * @param {ol.geom.LineString} linestring an OpenLayer Linestring @@ -154,11 +154,11 @@ const exports = class { /** - * Get a LOD and with for a given chart span + * Get a Level Of Details and with for a given chart span * Configuration is set up in Pytree configuration * @param {number} span domain extent * @param {lidarprofileServer.ConfigLevels} max_levels levels defined by a LIDAR server - * @return {{maxLOD: number, width: number}} Object with optimized LOD and width for this profile span + * @return {{maxLOD: number, width: number}} Object with optimized Level Of Details and width for this profile span */ getNiceLOD(span, max_levels) { let maxLOD = 0; @@ -227,7 +227,7 @@ const exports = class { /** - * Transforms a lidarprofile into mutliple single points sorted by distance. + * Transforms a lidarprofile into multiple single points sorted by distance. * @param {gmfx.LidarprofilePoints} profilePoints in the profile * @return {Array.} An array of Lidar Points. */ diff --git a/contribs/gmf/src/print/component.js b/contribs/gmf/src/print/component.js index 579bbffb884..b296d8763a3 100644 --- a/contribs/gmf/src/print/component.js +++ b/contribs/gmf/src/print/component.js @@ -154,7 +154,7 @@ function gmfPrintTemplateUrl($element, $attrs, gmfPrintTemplateUrl) { * value in each of your print panel field. The key refers to the * property's name of the field. * Example: {'comments': 'demo', 'legend': false}. Doesn't work for the dpi - * and the scale. Server's values are used in priorty. + * and the scale. Server's values are used in priority. * @htmlAttribute {Array.} gmf-print-hiddenattributes The list of attributes that should be hidden. * @ngdoc component * @ngname gmfPrint @@ -533,7 +533,7 @@ exports.Controller_ = class { * @return {number} Scale of the map to print. */ getScaleFn(frameState) { - // Don't compute an optimal scale if the user manualy choose a value not in + // Don't compute an optimal scale if the user manually choose a value not in // the pre-defined scales. (`scaleInput` in `gmfPrintOptions`). googAsserts.assert(this.layoutInfo.scales); googAsserts.assert(this.layoutInfo.scale !== undefined); @@ -780,7 +780,7 @@ exports.Controller_ = class { if (this.active && originalEvent.altKey && originalEvent.shiftKey && mapCenter) { const center = this.map.getPixelFromCoordinate(mapCenter); const pixel = e.pixel; - // Reset previous position between two differents sessions of drags events. + // Reset previous position between two different sessions of drags events. if (this.rotationTimeoutPromise_ === null) { this.onDragPreviousMousePosition_ = null; } else { @@ -830,14 +830,10 @@ exports.Controller_ = class { const mapSize = this.map.getSize(); const viewResolution = this.map.getView().getResolution() || 0; const scale = this.layoutInfo.scale || this.getOptimalScale_(mapSize, viewResolution); - const rotation = this.rotateMask ? -this.rotation : this.rotation; const datasource = this.getDataSource_(); const customAttributes = { - 'datasource': datasource, - 'lang': this.gettextCatalog_.currentLanguage, - 'rotation': rotation, - 'scale': scale + 'datasource': datasource }; if (this.layoutInfo.simpleAttributes) { diff --git a/contribs/gmf/src/query/gridComponent.js b/contribs/gmf/src/query/gridComponent.js index 037ac25f66b..8b14aaede97 100644 --- a/contribs/gmf/src/query/gridComponent.js +++ b/contribs/gmf/src/query/gridComponent.js @@ -867,7 +867,7 @@ exports.Controller_.prototype.selectAll = function() { /** - * Unselect all rows of the currently active grid. + * Deselect all rows of the currently active grid. * @export */ exports.Controller_.prototype.unselectAll = function() { diff --git a/contribs/gmf/src/search/search.less b/contribs/gmf/src/search/search.less index e1cba972325..78708fc2a6e 100644 --- a/contribs/gmf/src/search/search.less +++ b/contribs/gmf/src/search/search.less @@ -108,8 +108,6 @@ gmf-search { } } -@search-width: 6 * @map-tools-size; - // Overrides for tablet devices and up @media (min-width: @screen-sm-min) { gmf-search { diff --git a/contribs/gmf/test/spec/controllers/gmfprintcontroller.spec.js b/contribs/gmf/test/spec/controllers/gmfprintcontroller.spec.js index 43c743ad033..e10718d93f5 100644 --- a/contribs/gmf/test/spec/controllers/gmfprintcontroller.spec.js +++ b/contribs/gmf/test/spec/controllers/gmfprintcontroller.spec.js @@ -37,7 +37,7 @@ describe('GmfPrintController', () => { expect(gmfPrintCtrl.rotation).toBe(-180); }); - it('Set layout and test depending layout informations changes', () => { + it('Set layout and test depending layout information changes', () => { const title = 'title'; gmfPrintCtrl.layoutInfo.title = title; diff --git a/contribs/gmf/test/spec/services/permalinkservice.spec.js b/contribs/gmf/test/spec/services/permalinkservice.spec.js index 1c1d419c17e..1108af0b4d4 100644 --- a/contribs/gmf/test/spec/services/permalinkservice.spec.js +++ b/contribs/gmf/test/spec/services/permalinkservice.spec.js @@ -126,7 +126,7 @@ describe('Permalink service', () => { expect(PermalinkService.getWfsPermalinkData_()).toEqual(expectedQueryParams); }); - it('works with multipe filter groups', () => { + it('works with multiple filter groups', () => { // ?wfs_layer=osm_scale&wfs_ngroups=2&wfs_0_ele=380&wfs_0_highway=bus_stop& // wfs_0_operator=TL&wfs_1_highway=bus_stop&wfs_1_name=Grand-Pont&wfs_1_operator=TL ngeoLocation.updateParams({ diff --git a/docs/guidelines.md b/docs/guidelines.md index c45a70a38f0..1e0adb7c239 100644 --- a/docs/guidelines.md +++ b/docs/guidelines.md @@ -1,12 +1,12 @@ # Development guidelines -The purpose of this guideline is to help the developper to contribute in the +The purpose of this guideline is to help the developer to contribute in the best way to `ngeo` and `gmf` cores. It describe the golbal philosophy of `ngeo` design, and set base rules to apply when you want to add a new feature. You are free to read and fork this library. But you must know that we have currently no time to handle issues -or PR from persons outside of Camptocamp customers or developpers. +or PR from persons outside of Camptocamp customers or developers. ## Table of content @@ -66,7 +66,7 @@ We also use ES6 coding standards. With Webpack, some things have changed between the current ngeo 2.3 version, and the last ones. - Functions from the goog library are no more allowed. -- We export only one object per file. (That also means that we have splitted some files in multiple files). +- We export only one object per file. (That also means that we have split some files in multiple files). - We must have no more global value in the attached to the window (except in some very rare cases). - All AngularJS elements are now in a small module (see below in this documentation). - All modules import only what they need to work. No less, no more. @@ -77,12 +77,12 @@ With Webpack, some things have changed between the current ngeo 2.3 version, and Be as logical as possble. In the previous example, the AngularJS name should be `ngeoExampleSearch`. For a service in `contribs/gmf/src/sample/MyService.js`, the name must be `GmfSampleMyservice`. -Don't change a name after it's choosed. Because that change the html in the code of all user of ngeo ! +Don't change a name after it's chosen. Because that change the html in the code of all user of ngeo ! ## Module management -Since ngeo 2.3, every elements are grouped by functionnality (there is no more gloables `directive`, +Since ngeo 2.3, every elements are grouped by functionality (there is no more gloables `directive`, nor `service` directories). That also means that every element provide it's own AngularJS module; we no more link all elements to a global `ngeo` or `gmf` module. @@ -264,7 +264,7 @@ property and the `$parent` scope property whose name is given in `foo` HTML attr It's important to note that they don't share the same reference, but both are watched and updated concurrently. AngularJs adds `$watchers` each time you -have a two-way bindings pattern in your application. As mentionned before, this +have a two-way bindings pattern in your application. As mentioned before, this should be avoided when not needed. In angularJs, `$scope` values are mapped to HTML view through expressions. @@ -394,7 +394,7 @@ the controller instance (`this`) or on the `$scope`. These properties are then referenced by their names in HTML pages and templates. So it is required to prevent the compiler from renaming these properties. -The way to do that is to add the right tag on each variable, function and classe. +The way to do that is to add the right tag on each variable, function and class. - `@export`: this tell the compiler to not rename the element (and so it is usable in the html). - `@private`: With a final underscore (`this.my_private_variable_`) tell the compilier to rename it with a name not understainable outside of the current file. diff --git a/npm.mk b/npm.mk index b32917976ce..b65e73b5795 100644 --- a/npm.mk +++ b/npm.mk @@ -1,15 +1,5 @@ -OS := $(shell uname) -ifneq (, $(findstring CYGWIN_NT, $(OS))) - CONVERT_CMD := magick convert -else ifeq ($(OS),Windows_NT) - CONVERT_CMD := magick convert -else - CONVERT_CMD := convert -endif - .PHONY: install -install: $(addprefix contribs/gmf/fonts/gmf-icons.,ttf eot woff) \ - $(addprefix contribs/gmf/cursors/,grab.cur grabbing.cur) +install: $(addprefix contribs/gmf/fonts/gmf-icons.,ttf eot woff) contribs/gmf/fonts/gmf-icons.ttf: contribs/gmf/fonts/gmf-icons.svg svg2ttf $< $@ @@ -19,6 +9,3 @@ contribs/gmf/fonts/gmf-icons.eot: contribs/gmf/fonts/gmf-icons.ttf contribs/gmf/fonts/gmf-icons.woff: contribs/gmf/fonts/gmf-icons.ttf ttf2woff $< $@ - -contribs/gmf/cursors/%.cur: contribs/gmf/cursors/%.png - $(CONVERT_CMD) $< $@ diff --git a/options/ngeox.js b/options/ngeox.js index 864b581bc76..fb932048046 100644 --- a/options/ngeox.js +++ b/options/ngeox.js @@ -228,7 +228,7 @@ ngeox.IssueGetFeaturesOptions.prototype.extent; /** - * A filter to additionnally use with the query. Only used by WFS requests. + * A filter to additionally use with the query. Only used by WFS requests. * If a filter is defined, then it is used instead of the data source's * filter rules. * @type {ol.format.filter.Filter|undefined} diff --git a/package.json b/package.json index 57045f9961b..c0f48282f0f 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "phantomjs-polyfill-string-includes": "1.0.0", "phantomjs-prebuilt": "2.1.16", "proj4": "2.4.4", + "raven-js": "3.24.2", "svg2ttf": "4.1.0", "ttf2eot": "2.0.0", "ttf2woff": "2.0.1", diff --git a/requirements.txt b/requirements.txt index c423ad75b1c..0857b31c92f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ beautifulsoup4==4.6.0 +codespell==1.12.0 glob2==0.6 htmlmin==0.1.12 Mako==1.0.7 diff --git a/spell-ignore-words.txt b/spell-ignore-words.txt new file mode 100644 index 00000000000..24ba0a6a941 --- /dev/null +++ b/spell-ignore-words.txt @@ -0,0 +1,2 @@ +lod +oder diff --git a/src/filter/ruleComponent.js b/src/filter/ruleComponent.js index b320932897a..16384ec783a 100644 --- a/src/filter/ruleComponent.js +++ b/src/filter/ruleComponent.js @@ -176,31 +176,31 @@ exports.RuleController_ = class { */ this.clone; - const ot = ngeoRuleRule.OperatorType; - const sot = ngeoRuleRule.SpatialOperatorType; - const tot = ngeoRuleRule.TemporalOperatorType; + const operatorType = ngeoRuleRule.OperatorType; + const spatialOperatorType = ngeoRuleRule.SpatialOperatorType; + const temporalOperatorType = ngeoRuleRule.TemporalOperatorType; /** * @type {Object.} * @export */ this.operators = { - [ot.EQUAL_TO]: gettextCatalog.getString('Is equal to'), - [ot.GREATER_THAN]: gettextCatalog.getString('Is greater than'), - [ot.GREATER_THAN_OR_EQUAL_TO]: gettextCatalog.getString( + [operatorType.EQUAL_TO]: gettextCatalog.getString('Is equal to'), + [operatorType.GREATER_THAN]: gettextCatalog.getString('Is greater than'), + [operatorType.GREATER_THAN_OR_EQUAL_TO]: gettextCatalog.getString( 'Is greater than or equal to'), - [ot.LESSER_THAN]: gettextCatalog.getString('Is lesser than'), - [ot.LESSER_THAN_OR_EQUAL_TO]: gettextCatalog.getString( + [operatorType.LESSER_THAN]: gettextCatalog.getString('Is lesser than'), + [operatorType.LESSER_THAN_OR_EQUAL_TO]: gettextCatalog.getString( 'Is lesser than or equal to'), - [ot.NOT_EQUAL_TO]: gettextCatalog.getString('Is not equal to'), - [ot.LIKE]: gettextCatalog.getString('Contains'), - [sot.CONTAINS]: gettextCatalog.getString('Contains'), - [sot.INTERSECTS]: gettextCatalog.getString('Intersects'), - [sot.WITHIN]: gettextCatalog.getString('Is inside of'), - [tot.BEGINS]: gettextCatalog.getString('Begins at'), - [tot.DURING]: gettextCatalog.getString('During'), - [tot.ENDS]: gettextCatalog.getString('Ends at'), - [tot.EQUALS]: gettextCatalog.getString('Is equal to') + [operatorType.NOT_EQUAL_TO]: gettextCatalog.getString('Is not equal to'), + [operatorType.LIKE]: gettextCatalog.getString('Contains'), + [spatialOperatorType.CONTAINS]: gettextCatalog.getString('Contains'), + [spatialOperatorType.INTERSECTS]: gettextCatalog.getString('Intersects'), + [spatialOperatorType.WITHIN]: gettextCatalog.getString('Is inside of'), + [temporalOperatorType.BEGINS]: gettextCatalog.getString('Begins at'), + [temporalOperatorType.DURING]: gettextCatalog.getString('During'), + [temporalOperatorType.ENDS]: gettextCatalog.getString('Ends at'), + [temporalOperatorType.EQUALS]: gettextCatalog.getString('Is equal to') }; /** @@ -208,16 +208,16 @@ exports.RuleController_ = class { * @export */ this.operatorsShortFormat = { - [ot.EQUAL_TO]: '=', - [ot.GREATER_THAN]: '>', - [ot.GREATER_THAN_OR_EQUAL_TO]: '>=', - [ot.LESSER_THAN]: '<', - [ot.LESSER_THAN_OR_EQUAL_TO]: '<=', - [ot.NOT_EQUAL_TO]: '!=', - [ot.LIKE]: '~', - [tot.BEGINS]: '>=', - [tot.ENDS]: '<=', - [tot.EQUALS]: '=' + [operatorType.EQUAL_TO]: '=', + [operatorType.GREATER_THAN]: '>', + [operatorType.GREATER_THAN_OR_EQUAL_TO]: '>=', + [operatorType.LESSER_THAN]: '<', + [operatorType.LESSER_THAN_OR_EQUAL_TO]: '<=', + [operatorType.NOT_EQUAL_TO]: '!=', + [operatorType.LIKE]: '~', + [temporalOperatorType.BEGINS]: '>=', + [temporalOperatorType.ENDS]: '<=', + [temporalOperatorType.EQUALS]: '=' }; /** @@ -228,10 +228,10 @@ exports.RuleController_ = class { */ this.timeRangeMode = { widget: 'datepicker', - maxValue: this.createDate_(), - minValue: this.createWeekAgoDate_(), - maxDefValue: null, - minDefValue: null, + maxValue: null, + minValue: null, + maxDefValue: this.createDate_(), + minDefValue: this.createWeekAgoDate_(), mode: 'range', interval: [0, 1, 0, 0] }; @@ -244,10 +244,10 @@ exports.RuleController_ = class { */ this.timeValueMode = { widget: 'datepicker', - maxValue: this.createDate_(), - minValue: this.createDate_(), - maxDefValue: null, - minDefValue: null, + maxValue: null, + minValue: null, + maxDefValue: this.createDate_(), + minDefValue: this.createDate_(), mode: 'value', interval: [0, 1, 0, 0] }; @@ -424,24 +424,21 @@ exports.RuleController_ = class { this.unlisteners_.push(this.scope_.$watch( () => this.clone.getExpression(), (newVal) => { - const value = newVal === null ? this.createDate_() : newVal; - this.timeValueMode.minValue = value; + this.timeValueMode.minValue = newVal; } )); // Watch 'lowerBoundary' this.unlisteners_.push(this.scope_.$watch( () => this.clone.lowerBoundary, (newVal) => { - const value = newVal === null ? this.createWeekAgoDate_() : newVal; - this.timeRangeMode.minValue = value; + this.timeRangeMode.minValue = newVal; } )); // Watch 'upperBoundary' this.unlisteners_.push(this.scope_.$watch( () => this.clone.upperBoundary, (newVal) => { - const value = newVal === null ? this.createDate_() : newVal; - this.timeRangeMode.maxValue = value; + this.timeRangeMode.maxValue = newVal; } )); } else if (this.clone.type === ngeoFormatAttributeType.GEOMETRY) { diff --git a/src/format/FeatureHash.js b/src/format/FeatureHash.js index d8b7e25fcce..f52c56fcaa1 100644 --- a/src/format/FeatureHash.js +++ b/src/format/FeatureHash.js @@ -929,7 +929,7 @@ exports.GEOMETRY_WRITERS_ = { /** - * Read a logical sequence of characters and return (or complet then return) + * Read a logical sequence of characters and return (or complete then return) * an array of numbers. The coordinates are assumed to be in * two dimensions and in latitude, longitude order. * corresponding to a geometry's coordinates. diff --git a/src/grid/Config.js b/src/grid/Config.js index 9163898f8ec..1d6e309b5a7 100644 --- a/src/grid/Config.js +++ b/src/grid/Config.js @@ -110,7 +110,7 @@ exports.prototype.selectAll = function() { /** - * Unselect all rows. + * Deselect all rows. * @export */ exports.prototype.unselectAll = function() { diff --git a/src/message/displaywindowComponent.js b/src/message/displaywindowComponent.js index 4483a4c4451..5fa2037fcaa 100644 --- a/src/message/displaywindowComponent.js +++ b/src/message/displaywindowComponent.js @@ -287,13 +287,13 @@ exports.Controller_ = class { * @htmlAttribute {angular.Scope=} ngeo-displaywindow-content-scope Scope used for ngeo-displaywindow-content-template. * @htmlAttribute {boolean=} ngeo-displaywindow-desktop If true, the window is draggable and resizable. If * not set, you must set manually both parameter. - * @htmlAttribute {boolean=} ngeo-displaywindow-draggable Wheter the window is draggable or not. - * @htmlAttribute {string=} ngeo-displaywindow-draggable-containment The zone (css selector) where the window + * @htmlAttribute {boolean=} ngeo-displaywindow-draggable Whether the window is draggable or not. + * @htmlAttribute {string=} ngeo-displaywindow-draggable-containment The zone (CSS selector) where the window * is authorized to be dragged. * @htmlAttribute {string=} ngeo-displaywindow-height The default height of the window. - * @htmlAttribute {boolean=} ngeo-displaywindow-open Wheter the window is open or not. + * @htmlAttribute {boolean=} ngeo-displaywindow-open Whether the window is open or not. * @htmlAttribute {string=} ngeo-displaywindow-title The html title of the window. - * @htmlAttribute {string=} ngeo-displaywindow-url The url to open in an iframe, in the window. The content + * @htmlAttribute {string=} ngeo-displaywindow-url The URL to open in an iframe, in the window. The content * attribute must not be provided. * @htmlAttribute {string=} ngeo-displaywindow-width The default width of the window. * @ngdoc component diff --git a/src/message/popupComponent.js b/src/message/popupComponent.js index 5a0b11ce3ed..7581c4c5587 100644 --- a/src/message/popupComponent.js +++ b/src/message/popupComponent.js @@ -34,7 +34,7 @@ exports.run(/* @ngInject */ ($templateCache) => { * * Things to know about this directive: * - * - This directive is intented to be used along with the popup service. + * - This directive is intended to be used along with the popup service. * * - By default the directive uses "popup.html" as its templateUrl. This can be * changed by redefining the "ngeoPopupTemplateUrl" value. diff --git a/src/misc/Time.js b/src/misc/Time.js index 42338a38031..b8aa0c20f1b 100644 --- a/src/misc/Time.js +++ b/src/misc/Time.js @@ -11,6 +11,23 @@ */ const exports = function() {}; +/** + * @param {number|string|null} value The value + * @param {Date} defaultValue The default value + * @return {Date} the date + */ +exports.prototype.createDate = function(value, defaultValue = null) { + return value !== null ? new Date(value) : defaultValue; +}; + +/** + * @param {Date} date The date + * @param {number|null=} defaultValue The default value + * @return {number|null} the time + */ +exports.prototype.getTime = function(date, defaultValue = null) { + return date ? date.getTime() : defaultValue; +}; /** * Get options regarding the time property of a node; @@ -25,21 +42,19 @@ const exports = function() {}; */ exports.prototype.getOptions = function(time) { - const minDate = new Date(time.minValue); - const maxDate = new Date(time.maxValue); + const minDate = this.createDate(time.minValue); + const maxDate = this.createDate(time.maxValue); - const minDefaultDate = (time.minDefValue) ? - new Date(time.minDefValue) : minDate; - const maxDefaultDate = (time.maxDefValue) ? - new Date(time.maxDefValue) : maxDate; + const minDefaultDate = this.createDate(time.minDefValue, minDate); + const maxDefaultDate = this.createDate(time.maxDefValue, maxDate); const defaultValues = (time.mode === 'range') ? - [minDefaultDate.getTime(), maxDefaultDate.getTime()] : - minDefaultDate.getTime(); + [this.getTime(minDefaultDate), this.getTime(maxDefaultDate)] : + this.getTime(minDefaultDate); return { - minDate: minDate.getTime(), - maxDate: maxDate.getTime(), + minDate: this.getTime(minDate), + maxDate: this.getTime(maxDate), values: defaultValues }; }; diff --git a/src/misc/datepickerComponent.js b/src/misc/datepickerComponent.js index 933558f11be..1fad68a0d1f 100644 --- a/src/misc/datepickerComponent.js +++ b/src/misc/datepickerComponent.js @@ -212,8 +212,8 @@ exports.Controller_ = function($scope, $injector, if (angular.isDate(sDate) && (!this.isModeRange || angular.isDate(eDate))) { this.onDateSelected({ time: { - start: sDate.getTime(), - end: eDate ? eDate.getTime() : null + start: this.ngeoTime_.getTime(sDate), + end: this.ngeoTime_.getTime(eDate) } }); } @@ -226,17 +226,17 @@ exports.Controller_ = function($scope, $injector, exports.Controller_.prototype.init = function() { //fetch the initial options for the component const initialOptions_ = this.ngeoTime_.getOptions(this.time); - this.initialMinDate = new Date(initialOptions_.minDate); - this.initialMaxDate = new Date(initialOptions_.maxDate); + this.initialMinDate = this.ngeoTime_.createDate(initialOptions_.minDate); + this.initialMaxDate = this.ngeoTime_.createDate(initialOptions_.maxDate); this.isModeRange = this.time.mode === 'range'; if (this.isModeRange) { googAsserts.assertArray(initialOptions_.values); - this.sdate = new Date(initialOptions_.values[0]); - this.edate = new Date(initialOptions_.values[1]); + this.sdate = this.ngeoTime_.createDate(initialOptions_.values[0]); + this.edate = this.ngeoTime_.createDate(initialOptions_.values[1]); } else { googAsserts.assertNumber(initialOptions_.values); - this.sdate = new Date(initialOptions_.values); + this.sdate = this.ngeoTime_.createDate(initialOptions_.values); } }; diff --git a/src/print/Service.js b/src/print/Service.js index 881711edcee..82230664572 100644 --- a/src/print/Service.js +++ b/src/print/Service.js @@ -57,9 +57,10 @@ import olTilegridWMTS from 'ol/tilegrid/WMTS.js'; * @struct * @param {string} url URL to MapFish print web service. * @param {angular.$http} $http Angular $http service. + * @param {!angularGettext.Catalog} gettextCatalog Gettext service. * @param {ngeo.map.LayerHelper} ngeoLayerHelper Ngeo Layer Helper service. */ -const exports = function(url, $http, ngeoLayerHelper) { +const exports = function(url, $http, gettextCatalog, ngeoLayerHelper) { /** * @type {string} * @private @@ -72,6 +73,12 @@ const exports = function(url, $http, ngeoLayerHelper) { */ this.$http_ = $http; + /** + * @type {!angularGettext.Catalog} + * @private + */ + this.gettextCatalog_ = gettextCatalog; + /** * @type {ngeo.map.LayerHelper} * @private @@ -134,9 +141,12 @@ exports.prototype.createSpec = function( }); olObj.assign(attributes, customAttributes); + const lang = this.gettextCatalog_.currentLanguage; + const spec = /** @type {MapFishPrintSpec} */ ({ attributes, format, + lang, layout }); @@ -454,19 +464,20 @@ exports.prototype.getCapabilities = function(opt_httpConfig) { /** * @param {angular.$http} $http Angular $http service. + * @param {!angularGettext.Catalog} gettextCatalog Gettext service. * @param {ngeo.map.LayerHelper} ngeoLayerHelper Ngeo Layer Helper. * @return {ngeox.CreatePrint} The function to create a print service. * @ngInject * @ngdoc service * @ngname ngeoCreatePrint */ -exports.createPrintServiceFactory = function($http, ngeoLayerHelper) { +exports.createPrintServiceFactory = function($http, gettextCatalog, ngeoLayerHelper) { return ( /** * @param {string} url URL to MapFish print service. */ function(url) { - return new exports(url, $http, ngeoLayerHelper); + return new exports(url, $http, gettextCatalog, ngeoLayerHelper); } ); }; diff --git a/src/profile/d3Elevation.js b/src/profile/d3Elevation.js index f60cd3f8a48..333e55d8995 100644 --- a/src/profile/d3Elevation.js +++ b/src/profile/d3Elevation.js @@ -115,7 +115,7 @@ const exports = function(options) { const linesConfiguration = options.linesConfiguration; /** - * Number of differents configurations for the line. + * Number of different configurations for the line. */ const numberOfLines = Object.keys(linesConfiguration).length; diff --git a/test/spec/data/msGMLOutputBusStopAndInformation.js b/test/spec/data/msGMLOutputBusStopAndInformation.js index 18d09e12c6a..c9bca9adca4 100644 --- a/test/spec/data/msGMLOutputBusStopAndInformation.js +++ b/test/spec/data/msGMLOutputBusStopAndInformation.js @@ -7,7 +7,7 @@ const exports = '' + ' xmlns:xlink="http://www.w3.org/1999/xlink"' + ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + ' ' + -' Informations' + +' Information' + ' ' + ' ' + ' ' + diff --git a/test/spec/directives/grid.spec.js b/test/spec/directives/grid.spec.js index a8bd71649f1..6a64da65fe7 100644 --- a/test/spec/directives/grid.spec.js +++ b/test/spec/directives/grid.spec.js @@ -122,7 +122,7 @@ describe('ngeo.grid.component', () => { expect(gridController.configuration.isRowSelected(firstRow)).toBe(true); expect(gridController.configuration.isRowSelected(sndRow)).toBe(true); - // unselect the 2nd row + // deselect the 2nd row gridController.clickRow_(sndRow, false, true); expect(gridController.configuration.isRowSelected(firstRow)).toBe(true); expect(gridController.configuration.isRowSelected(sndRow)).toBe(false); diff --git a/test/spec/services/print.spec.js b/test/spec/services/print.spec.js index efe848bb515..92b286ca763 100644 --- a/test/spec/services/print.spec.js +++ b/test/spec/services/print.spec.js @@ -123,6 +123,7 @@ describe('ngeo.print.Service', () => { foo: 'fooval', bar: 'barval' }, + lang: 'en', format: 'pdf', layout: 'foo layout' }); @@ -181,6 +182,7 @@ describe('ngeo.print.Service', () => { foo: 'fooval', bar: 'barval' }, + lang: 'en', format: 'pdf', layout: 'foo layout' }); @@ -277,6 +279,7 @@ describe('ngeo.print.Service', () => { foo: 'fooval', bar: 'barval' }, + lang: 'en', format: 'pdf', layout: 'foo layout' }); @@ -553,6 +556,7 @@ describe('ngeo.print.Service', () => { foo: 'fooval', bar: 'barval' }, + lang: 'en', format: 'pdf', layout: 'foo layout' }); diff --git a/webpack.config.js b/webpack.config.js index 69bea7cbbf1..c4d5ae77ece 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -12,7 +12,7 @@ switch (nodeEnv) { config = webpackMerge(config, require('./buildtools/webpack.prod')); break; default: - console.log(`The 'NODE_ENV' environement variable is set to an invalide value: ${process.env.NODE_ENV}.` ) + console.log(`The 'NODE_ENV' environment variable is set to an invalid value: ${process.env.NODE_ENV}.` ) process.exit(2); } @@ -27,7 +27,7 @@ switch (process.env.TARGET) { config = webpackMerge(config, require('./buildtools/webpack.gmfapps')); break; default: - console.log(`The 'TARGET' environement variable is set to an invalide value: ${process.env.TARGET}.` ) + console.log(`The 'TARGET' environment variable is set to an invalid value: ${process.env.TARGET}.` ) process.exit(2); }