diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 00000000..8d2f2cbf --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,6 @@ +trailingComma: "es5" +tabWidth: 2 +semi: false +singleQuote: true +printWidth: 88 +quoteProps: "consistent" diff --git a/Makefile b/Makefile index e0fc00c5..13907259 100644 --- a/Makefile +++ b/Makefile @@ -52,3 +52,9 @@ tx_push: tx push -s tx_pull: tx pull + +jsdir = umap/static/umap/js/ +filepath = "${jsdir}*.js" +pretty: ## Apply PrettierJS to all JS files (or specified `filepath`) + ./node_modules/prettier/bin-prettier.js --write ${filepath} + diff --git a/package-lock.json b/package-lock.json index 31a046ea..12bf20b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "mocha-phantomjs": "^4.0.1", "optimist": "~0.4.0", "phantomjs": "^1.9.18", + "prettier": "^2.8.8", "sinon": "^1.10.3", "uglify-js": "~3.17.4" } @@ -1920,6 +1921,21 @@ "node": ">=0.10.0" } }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", @@ -4071,6 +4087,12 @@ "pinkie": "^2.0.0" } }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true + }, "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", diff --git a/package.json b/package.json index 46fc25cb..8302ef3a 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "mocha-phantomjs": "^4.0.1", "optimist": "~0.4.0", "phantomjs": "^1.9.18", + "prettier": "^2.8.8", "sinon": "^1.10.3", "uglify-js": "~3.17.4" }, diff --git a/umap/static/umap/js/umap.autocomplete.js b/umap/static/umap/js/umap.autocomplete.js index efd9bf03..df7966ab 100644 --- a/umap/static/umap/js/umap.autocomplete.js +++ b/umap/static/umap/js/umap.autocomplete.js @@ -1,314 +1,341 @@ L.U.AutoComplete = L.Class.extend({ + options: { + placeholder: 'Start typing...', + emptyMessage: 'No result', + allowFree: true, + minChar: 2, + maxResults: 5, + }, - options: { - placeholder: 'Start typing...', - emptyMessage: 'No result', - allowFree: true, - minChar: 2, - maxResults: 5 - }, + CACHE: '', + RESULTS: [], - CACHE: '', - RESULTS: [], - - initialize: function (el, options) { - this.el = el; - var ui = new L.U.UI(document.querySelector('header')); - this.xhr = new L.U.Xhr(ui); - L.setOptions(this, options); - var CURRENT = null; - try { - Object.defineProperty(this, 'CURRENT', { - get: function () { - return CURRENT; - }, - set: function (index) { - if (typeof index === 'object') { - index = this.resultToIndex(index); - } - CURRENT = index; - } - }); - } catch (e) { - // Hello IE8 - } - return this; - }, - - createInput: function () { - this.input = L.DomUtil.element('input', { - type: 'text', - placeholder: this.options.placeholder, - autocomplete: 'off', - className: this.options.className - }, this.el); - L.DomEvent.on(this.input, 'keydown', this.onKeyDown, this); - L.DomEvent.on(this.input, 'keyup', this.onKeyUp, this); - L.DomEvent.on(this.input, 'blur', this.onBlur, this); - }, - - createContainer: function () { - this.container = L.DomUtil.element('ul', {className: 'umap-autocomplete'}, document.body); - }, - - resizeContainer: function() - { - var l = this.getLeft(this.input); - var t = this.getTop(this.input) + this.input.offsetHeight; - this.container.style.left = l + 'px'; - this.container.style.top = t + 'px'; - var width = this.options.width ? this.options.width : this.input.offsetWidth - 2; - this.container.style.width = width + 'px'; - }, - - - onKeyDown: function (e) { - switch (e.keyCode) { - case L.U.Keys.TAB: - if(this.CURRENT !== null) this.setChoice(); - L.DomEvent.stop(e); - break; - case L.U.Keys.ENTER: - L.DomEvent.stop(e); - this.setChoice(); - break; - case L.U.Keys.ESC: - L.DomEvent.stop(e); - this.hide(); - break; - case L.U.Keys.DOWN: - if(this.RESULTS.length > 0) { - if(this.CURRENT !== null && this.CURRENT < this.RESULTS.length - 1) { // what if one result? - this.CURRENT++; - this.highlight(); - } - else if(this.CURRENT === null) { - this.CURRENT = 0; - this.highlight(); - } - } - break; - case L.U.Keys.UP: - if(this.CURRENT !== null) { - L.DomEvent.stop(e); - } - if(this.RESULTS.length > 0) { - if(this.CURRENT > 0) { - this.CURRENT--; - this.highlight(); - } - else if(this.CURRENT === 0) { - this.CURRENT = null; - this.highlight(); - } - } - break; - } - }, - - onKeyUp: function (e) { - var special = [ - L.U.Keys.TAB, - L.U.Keys.ENTER, - L.U.Keys.LEFT, - L.U.Keys.RIGHT, - L.U.Keys.DOWN, - L.U.Keys.UP, - L.U.Keys.APPLE, - L.U.Keys.SHIFT, - L.U.Keys.ALT, - L.U.Keys.CTRL - ]; - if (special.indexOf(e.keyCode) === -1) - { - this.search(); - } - }, - - onBlur: function () { - var self = this; - setTimeout(function () { - self.hide(); - }, 100); - }, - - clear: function () { - this.RESULTS = []; - this.CURRENT = null; - this.CACHE = ''; - this.container.innerHTML = ''; - }, - - hide: function() { - this.clear(); - this.container.style.display = 'none'; - this.input.value = ''; - }, - - setChoice: function (choice) { - choice = choice || this.RESULTS[this.CURRENT]; - if (choice) { - this.input.value = choice.item.label; - this.options.on_select(choice); - this.displaySelected(choice); - this.hide(); - if (this.options.callback) { - L.Util.bind(this.options.callback, this)(choice); - } - } - }, - - search: function() { - var val = this.input.value; - if (val.length < this.options.minChar) { - this.clear(); - return; - } - if( val + '' === this.CACHE + '') return; - else this.CACHE = val; - this._do_search(val, function (data) { - this.handleResults(data.data); - }, this); - }, - - createResult: function (item) { - var el = L.DomUtil.element('li', {}, this.container); - el.textContent = item.label; - var result = { - item: item, - el: el - }; - L.DomEvent.on(el, 'mouseover', function () { - this.CURRENT = result; - this.highlight(); - }, this); - L.DomEvent.on(el, 'mousedown', function () { - this.setChoice(); - }, this); - return result; - }, - - resultToIndex: function (result) { - var out = null; - this.forEach(this.RESULTS, function (item, index) { - if (item.item.value == result.item.value) { - out = index; - return; - } - }); - return out; - }, - - handleResults: function(data) { - var self = this; - this.clear(); - this.container.style.display = 'block'; - this.resizeContainer(); - this.forEach(data, function (item) { - self.RESULTS.push(self.createResult(item)); - }); - this.CURRENT = 0; - this.highlight(); - //TODO manage no results - }, - - highlight: function () { - var self = this; - this.forEach(this.RESULTS, function (result, index) { - if (index === self.CURRENT) L.DomUtil.addClass(result.el, 'on'); - else L.DomUtil.removeClass(result.el, 'on'); - }); - }, - - getLeft: function (el) { - var tmp = el.offsetLeft; - el = el.offsetParent; - while(el) { - tmp += el.offsetLeft; - el = el.offsetParent; - } - return tmp; - }, - - getTop: function (el) { - var tmp = el.offsetTop; - el = el.offsetParent; - while(el) { - tmp += el.offsetTop; - el = el.offsetParent; - } - return tmp; - }, - - forEach: function (els, callback) { - Array.prototype.forEach.call(els, callback); + initialize: function (el, options) { + this.el = el + var ui = new L.U.UI(document.querySelector('header')) + this.xhr = new L.U.Xhr(ui) + L.setOptions(this, options) + var CURRENT = null + try { + Object.defineProperty(this, 'CURRENT', { + get: function () { + return CURRENT + }, + set: function (index) { + if (typeof index === 'object') { + index = this.resultToIndex(index) + } + CURRENT = index + }, + }) + } catch (e) { + // Hello IE8 } + return this + }, -}); + createInput: function () { + this.input = L.DomUtil.element( + 'input', + { + type: 'text', + placeholder: this.options.placeholder, + autocomplete: 'off', + className: this.options.className, + }, + this.el + ) + L.DomEvent.on(this.input, 'keydown', this.onKeyDown, this) + L.DomEvent.on(this.input, 'keyup', this.onKeyUp, this) + L.DomEvent.on(this.input, 'blur', this.onBlur, this) + }, + createContainer: function () { + this.container = L.DomUtil.element( + 'ul', + { className: 'umap-autocomplete' }, + document.body + ) + }, + + resizeContainer: function () { + var l = this.getLeft(this.input) + var t = this.getTop(this.input) + this.input.offsetHeight + this.container.style.left = l + 'px' + this.container.style.top = t + 'px' + var width = this.options.width ? this.options.width : this.input.offsetWidth - 2 + this.container.style.width = width + 'px' + }, + + onKeyDown: function (e) { + switch (e.keyCode) { + case L.U.Keys.TAB: + if (this.CURRENT !== null) this.setChoice() + L.DomEvent.stop(e) + break + case L.U.Keys.ENTER: + L.DomEvent.stop(e) + this.setChoice() + break + case L.U.Keys.ESC: + L.DomEvent.stop(e) + this.hide() + break + case L.U.Keys.DOWN: + if (this.RESULTS.length > 0) { + if (this.CURRENT !== null && this.CURRENT < this.RESULTS.length - 1) { + // what if one result? + this.CURRENT++ + this.highlight() + } else if (this.CURRENT === null) { + this.CURRENT = 0 + this.highlight() + } + } + break + case L.U.Keys.UP: + if (this.CURRENT !== null) { + L.DomEvent.stop(e) + } + if (this.RESULTS.length > 0) { + if (this.CURRENT > 0) { + this.CURRENT-- + this.highlight() + } else if (this.CURRENT === 0) { + this.CURRENT = null + this.highlight() + } + } + break + } + }, + + onKeyUp: function (e) { + var special = [ + L.U.Keys.TAB, + L.U.Keys.ENTER, + L.U.Keys.LEFT, + L.U.Keys.RIGHT, + L.U.Keys.DOWN, + L.U.Keys.UP, + L.U.Keys.APPLE, + L.U.Keys.SHIFT, + L.U.Keys.ALT, + L.U.Keys.CTRL, + ] + if (special.indexOf(e.keyCode) === -1) { + this.search() + } + }, + + onBlur: function () { + var self = this + setTimeout(function () { + self.hide() + }, 100) + }, + + clear: function () { + this.RESULTS = [] + this.CURRENT = null + this.CACHE = '' + this.container.innerHTML = '' + }, + + hide: function () { + this.clear() + this.container.style.display = 'none' + this.input.value = '' + }, + + setChoice: function (choice) { + choice = choice || this.RESULTS[this.CURRENT] + if (choice) { + this.input.value = choice.item.label + this.options.on_select(choice) + this.displaySelected(choice) + this.hide() + if (this.options.callback) { + L.Util.bind(this.options.callback, this)(choice) + } + } + }, + + search: function () { + var val = this.input.value + if (val.length < this.options.minChar) { + this.clear() + return + } + if (val + '' === this.CACHE + '') return + else this.CACHE = val + this._do_search( + val, + function (data) { + this.handleResults(data.data) + }, + this + ) + }, + + createResult: function (item) { + var el = L.DomUtil.element('li', {}, this.container) + el.textContent = item.label + var result = { + item: item, + el: el, + } + L.DomEvent.on( + el, + 'mouseover', + function () { + this.CURRENT = result + this.highlight() + }, + this + ) + L.DomEvent.on( + el, + 'mousedown', + function () { + this.setChoice() + }, + this + ) + return result + }, + + resultToIndex: function (result) { + var out = null + this.forEach(this.RESULTS, function (item, index) { + if (item.item.value == result.item.value) { + out = index + return + } + }) + return out + }, + + handleResults: function (data) { + var self = this + this.clear() + this.container.style.display = 'block' + this.resizeContainer() + this.forEach(data, function (item) { + self.RESULTS.push(self.createResult(item)) + }) + this.CURRENT = 0 + this.highlight() + //TODO manage no results + }, + + highlight: function () { + var self = this + this.forEach(this.RESULTS, function (result, index) { + if (index === self.CURRENT) L.DomUtil.addClass(result.el, 'on') + else L.DomUtil.removeClass(result.el, 'on') + }) + }, + + getLeft: function (el) { + var tmp = el.offsetLeft + el = el.offsetParent + while (el) { + tmp += el.offsetLeft + el = el.offsetParent + } + return tmp + }, + + getTop: function (el) { + var tmp = el.offsetTop + el = el.offsetParent + while (el) { + tmp += el.offsetTop + el = el.offsetParent + } + return tmp + }, + + forEach: function (els, callback) { + Array.prototype.forEach.call(els, callback) + }, +}) L.U.AutoComplete.Ajax = L.U.AutoComplete.extend({ + initialize: function (el, options) { + L.U.AutoComplete.prototype.initialize.call(this, el, options) + if (!this.el) return this + this.createInput() + this.createContainer() + this.selected_container = this.initSelectedContainer() + }, - initialize: function (el, options) { - L.U.AutoComplete.prototype.initialize.call(this, el, options); - if (!this.el) return this; - this.createInput(); - this.createContainer(); - this.selected_container = this.initSelectedContainer(); - }, - - optionToResult: function (option) { - return { - value: option.value, - label: option.innerHTML - }; - }, - - _do_search: function (val, callback, context) { - val = val.toLowerCase(); - this.xhr.get('/agnocomplete/AutocompleteUser/?q=' + encodeURIComponent(val), {callback: callback, context: context || this}); + optionToResult: function (option) { + return { + value: option.value, + label: option.innerHTML, } + }, -}); + _do_search: function (val, callback, context) { + val = val.toLowerCase() + this.xhr.get('/agnocomplete/AutocompleteUser/?q=' + encodeURIComponent(val), { + callback: callback, + context: context || this, + }) + }, +}) L.U.AutoComplete.Ajax.SelectMultiple = L.U.AutoComplete.Ajax.extend({ + initSelectedContainer: function () { + return L.DomUtil.after( + this.input, + L.DomUtil.element('ul', { className: 'umap-multiresult' }) + ) + }, - initSelectedContainer: function () { - return L.DomUtil.after(this.input, L.DomUtil.element('ul', {className: 'umap-multiresult'})); - }, - - displaySelected: function (result) { - var result_el = L.DomUtil.element('li', {}, this.selected_container); - result_el.textContent = result.item.label; - var close = L.DomUtil.element('span', {className: 'close'}, result_el); - close.textContent = '×'; - L.DomEvent.on(close, 'click', function () { - this.selected_container.removeChild(result_el); - this.options.on_unselect(result); - }, this); - this.hide(); - } - -}); - + displaySelected: function (result) { + var result_el = L.DomUtil.element('li', {}, this.selected_container) + result_el.textContent = result.item.label + var close = L.DomUtil.element('span', { className: 'close' }, result_el) + close.textContent = '×' + L.DomEvent.on( + close, + 'click', + function () { + this.selected_container.removeChild(result_el) + this.options.on_unselect(result) + }, + this + ) + this.hide() + }, +}) L.U.AutoComplete.Ajax.Select = L.U.AutoComplete.Ajax.extend({ + initSelectedContainer: function () { + return L.DomUtil.after( + this.input, + L.DomUtil.element('div', { className: 'umap-singleresult' }) + ) + }, - initSelectedContainer: function () { - return L.DomUtil.after(this.input, L.DomUtil.element('div', {className: 'umap-singleresult'})); - }, - - displaySelected: function (result) { - var result_el = L.DomUtil.element('div', {}, this.selected_container); - result_el.textContent = result.item.label; - var close = L.DomUtil.element('span', {className: 'close'}, result_el); - close.textContent = '×'; - this.input.style.display = 'none'; - L.DomEvent.on(close, 'click', function () { - this.selected_container.innerHTML = ''; - this.input.style.display = 'block'; - }, this); - this.hide(); - } - -}); + displaySelected: function (result) { + var result_el = L.DomUtil.element('div', {}, this.selected_container) + result_el.textContent = result.item.label + var close = L.DomUtil.element('span', { className: 'close' }, result_el) + close.textContent = '×' + this.input.style.display = 'none' + L.DomEvent.on( + close, + 'click', + function () { + this.selected_container.innerHTML = '' + this.input.style.display = 'block' + }, + this + ) + this.hide() + }, +}) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 66d4647e..17e431dc 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -1,1310 +1,1360 @@ L.U.BaseAction = L.ToolbarAction.extend({ - - initialize: function (map) { - this.map = map; - this.options.toolbarIcon = { - className: this.options.className, - tooltip: this.options.tooltip - }; - L.ToolbarAction.prototype.initialize.call(this); - if (this.options.helpMenu && !this.map.helpMenuActions[this.options.className]) this.map.helpMenuActions[this.options.className] = this; + initialize: function (map) { + this.map = map + this.options.toolbarIcon = { + className: this.options.className, + tooltip: this.options.tooltip, } - -}); + L.ToolbarAction.prototype.initialize.call(this) + if (this.options.helpMenu && !this.map.helpMenuActions[this.options.className]) + this.map.helpMenuActions[this.options.className] = this + }, +}) L.U.ImportAction = L.U.BaseAction.extend({ + options: { + helpMenu: true, + className: 'upload-data dark', + tooltip: L._('Import data') + ' (Ctrl+I)', + }, - options: { - helpMenu: true, - className: 'upload-data dark', - tooltip: L._('Import data') + ' (Ctrl+I)' - }, - - addHooks: function () { - this.map.importPanel(); - } - -}); + addHooks: function () { + this.map.importPanel() + }, +}) L.U.EditPropertiesAction = L.U.BaseAction.extend({ + options: { + helpMenu: true, + className: 'update-map-settings dark', + tooltip: L._('Edit map settings'), + }, - options: { - helpMenu: true, - className: 'update-map-settings dark', - tooltip: L._('Edit map settings') - }, - - addHooks: function () { - this.map.edit(); - } - -}); + addHooks: function () { + this.map.edit() + }, +}) L.U.ChangeTileLayerAction = L.U.BaseAction.extend({ + options: { + helpMenu: true, + className: 'dark update-map-tilelayers', + tooltip: L._('Change tilelayers'), + }, - options: { - helpMenu: true, - className: 'dark update-map-tilelayers', - tooltip: L._('Change tilelayers') - }, - - addHooks: function () { - this.map.updateTileLayers(); - } - -}); + addHooks: function () { + this.map.updateTileLayers() + }, +}) L.U.ManageDatalayersAction = L.U.BaseAction.extend({ + options: { + className: 'dark manage-datalayers', + tooltip: L._('Manage layers'), + }, - options: { - className: 'dark manage-datalayers', - tooltip: L._('Manage layers') - }, - - addHooks: function () { - this.map.manageDatalayers(); - } - -}); + addHooks: function () { + this.map.manageDatalayers() + }, +}) L.U.UpdateExtentAction = L.U.BaseAction.extend({ + options: { + className: 'update-map-extent dark', + tooltip: L._('Save this center and zoom'), + }, - options: { - className: 'update-map-extent dark', - tooltip: L._('Save this center and zoom') - }, - - addHooks: function () { - this.map.updateExtent(); - } - -}); + addHooks: function () { + this.map.updateExtent() + }, +}) L.U.UpdatePermsAction = L.U.BaseAction.extend({ + options: { + className: 'update-map-permissions dark', + tooltip: L._('Update permissions and editors'), + }, - options: { - className: 'update-map-permissions dark', - tooltip: L._('Update permissions and editors') - }, - - addHooks: function () { - this.map.permissions.edit(); - } - -}); + addHooks: function () { + this.map.permissions.edit() + }, +}) L.U.DrawMarkerAction = L.U.BaseAction.extend({ + options: { + helpMenu: true, + className: 'umap-draw-marker dark', + tooltip: L._('Draw a marker'), + }, - options: { - helpMenu: true, - className: 'umap-draw-marker dark', - tooltip: L._('Draw a marker') - }, - - addHooks: function () { - this.map.startMarker(); - } - -}); + addHooks: function () { + this.map.startMarker() + }, +}) L.U.DrawPolylineAction = L.U.BaseAction.extend({ + options: { + helpMenu: true, + className: 'umap-draw-polyline dark', + tooltip: L._('Draw a polyline'), + }, - options: { - helpMenu: true, - className: 'umap-draw-polyline dark', - tooltip: L._('Draw a polyline') - }, - - addHooks: function () { - this.map.startPolyline(); - } - -}); + addHooks: function () { + this.map.startPolyline() + }, +}) L.U.DrawPolygonAction = L.U.BaseAction.extend({ + options: { + helpMenu: true, + className: 'umap-draw-polygon dark', + tooltip: L._('Draw a polygon'), + }, - options: { - helpMenu: true, - className: 'umap-draw-polygon dark', - tooltip: L._('Draw a polygon') - }, - - addHooks: function () { - this.map.startPolygon(); - } - -}); + addHooks: function () { + this.map.startPolygon() + }, +}) L.U.AddPolylineShapeAction = L.U.BaseAction.extend({ + options: { + className: 'umap-draw-polyline-multi dark', + tooltip: L._('Add a line to the current multi'), + }, - options: { - className: 'umap-draw-polyline-multi dark', - tooltip: L._('Add a line to the current multi') - }, - - addHooks: function () { - this.map.editedFeature.editor.newShape(); - } - -}); + addHooks: function () { + this.map.editedFeature.editor.newShape() + }, +}) L.U.AddPolygonShapeAction = L.U.AddPolylineShapeAction.extend({ - - options: { - className: 'umap-draw-polygon-multi dark', - tooltip: L._('Add a polygon to the current multi') - } - -}); + options: { + className: 'umap-draw-polygon-multi dark', + tooltip: L._('Add a polygon to the current multi'), + }, +}) L.U.BaseFeatureAction = L.ToolbarAction.extend({ + initialize: function (map, feature, latlng) { + this.map = map + this.feature = feature + this.latlng = latlng + L.ToolbarAction.prototype.initialize.call(this) + this.postInit() + }, - initialize: function (map, feature, latlng) { - this.map = map; - this.feature = feature; - this.latlng = latlng; - L.ToolbarAction.prototype.initialize.call(this); - this.postInit(); - }, + postInit: function () {}, - postInit: function () {}, + hideToolbar: function () { + this.map.removeLayer(this.toolbar) + }, - hideToolbar: function () { - this.map.removeLayer(this.toolbar); - }, - - addHooks: function () { - this.onClick({latlng: this.latlng}); - this.hideToolbar(); - } - -}); + addHooks: function () { + this.onClick({ latlng: this.latlng }) + this.hideToolbar() + }, +}) L.U.CreateHoleAction = L.U.BaseFeatureAction.extend({ - - options: { - toolbarIcon: { - className: 'umap-new-hole', - tooltip: L._('Start a hole here') - } + options: { + toolbarIcon: { + className: 'umap-new-hole', + tooltip: L._('Start a hole here'), }, + }, - onClick: function (e) { - this.feature.startHole(e); - } - -}); + onClick: function (e) { + this.feature.startHole(e) + }, +}) L.U.ToggleEditAction = L.U.BaseFeatureAction.extend({ - - options: { - toolbarIcon: { - className: 'umap-toggle-edit', - tooltip: L._('Toggle edit mode (Shift+Click)') - } + options: { + toolbarIcon: { + className: 'umap-toggle-edit', + tooltip: L._('Toggle edit mode (Shift+Click)'), }, + }, - onClick: function (e) { - if (this.feature._toggleEditing) this.feature._toggleEditing(e); // Path - else this.feature.edit(e); // Marker - } - -}); + onClick: function (e) { + if (this.feature._toggleEditing) this.feature._toggleEditing(e) // Path + else this.feature.edit(e) // Marker + }, +}) L.U.DeleteFeatureAction = L.U.BaseFeatureAction.extend({ - - options: { - toolbarIcon: { - className: 'umap-delete-all', - tooltip: L._('Delete this feature') - } + options: { + toolbarIcon: { + className: 'umap-delete-all', + tooltip: L._('Delete this feature'), }, + }, - postInit: function () { - if (!this.feature.isMulti()) this.options.toolbarIcon.className = 'umap-delete-one-of-one'; - }, + postInit: function () { + if (!this.feature.isMulti()) + this.options.toolbarIcon.className = 'umap-delete-one-of-one' + }, - onClick: function (e) { - this.feature.confirmDelete(e); - } - -}); + onClick: function (e) { + this.feature.confirmDelete(e) + }, +}) L.U.DeleteShapeAction = L.U.BaseFeatureAction.extend({ - - options: { - toolbarIcon: { - className: 'umap-delete-one-of-multi', - tooltip: L._('Delete this shape') - } + options: { + toolbarIcon: { + className: 'umap-delete-one-of-multi', + tooltip: L._('Delete this shape'), }, + }, - onClick: function (e) { - this.feature.enableEdit().deleteShapeAt(e.latlng); - } - -}); + onClick: function (e) { + this.feature.enableEdit().deleteShapeAt(e.latlng) + }, +}) L.U.ExtractShapeFromMultiAction = L.U.BaseFeatureAction.extend({ - - options: { - toolbarIcon: { - className: 'umap-extract-shape-from-multi', - tooltip: L._('Extract shape to separate feature') - } + options: { + toolbarIcon: { + className: 'umap-extract-shape-from-multi', + tooltip: L._('Extract shape to separate feature'), }, + }, - onClick: function (e) { - this.feature.isolateShape(e.latlng); - } - -}); + onClick: function (e) { + this.feature.isolateShape(e.latlng) + }, +}) L.U.BaseVertexAction = L.U.BaseFeatureAction.extend({ - - initialize: function (map, feature, latlng, vertex) { - this.vertex = vertex; - L.U.BaseFeatureAction.prototype.initialize.call(this, map, feature, latlng); - } - -}); + initialize: function (map, feature, latlng, vertex) { + this.vertex = vertex + L.U.BaseFeatureAction.prototype.initialize.call(this, map, feature, latlng) + }, +}) L.U.DeleteVertexAction = L.U.BaseVertexAction.extend({ - - options: { - toolbarIcon: { - className: 'umap-delete-vertex', - tooltip: L._('Delete this vertex (Alt+Click)') - } + options: { + toolbarIcon: { + className: 'umap-delete-vertex', + tooltip: L._('Delete this vertex (Alt+Click)'), }, + }, - onClick: function () { - this.vertex.delete(); - } - -}); + onClick: function () { + this.vertex.delete() + }, +}) L.U.SplitLineAction = L.U.BaseVertexAction.extend({ - - options: { - toolbarIcon: { - className: 'umap-split-line', - tooltip: L._('Split line') - } + options: { + toolbarIcon: { + className: 'umap-split-line', + tooltip: L._('Split line'), }, + }, - onClick: function () { - this.vertex.split(); - } - -}); + onClick: function () { + this.vertex.split() + }, +}) L.U.ContinueLineAction = L.U.BaseVertexAction.extend({ - - options: { - toolbarIcon: { - className: 'umap-continue-line', - tooltip: L._('Continue line') - } + options: { + toolbarIcon: { + className: 'umap-continue-line', + tooltip: L._('Continue line'), }, + }, - onClick: function () { - this.vertex.continue(); - } - -}); + onClick: function () { + this.vertex.continue() + }, +}) // Leaflet.Toolbar doesn't allow twice same toolbar class… -L.U.SettingsToolbar = L.Toolbar.Control.extend({}); +L.U.SettingsToolbar = L.Toolbar.Control.extend({}) L.U.DrawToolbar = L.Toolbar.Control.extend({ + initialize: function (options) { + L.Toolbar.Control.prototype.initialize.call(this, options) + this.map = this.options.map + this.map.on('seteditedfeature', this.redraw, this) + }, - initialize: function (options) { - L.Toolbar.Control.prototype.initialize.call(this, options); - this.map = this.options.map; - this.map.on('seteditedfeature', this.redraw, this); - }, - - appendToContainer: function (container) { - this.options.actions = []; - if (this.map.options.enableMarkerDraw) { - this.options.actions.push(L.U.DrawMarkerAction); - } - if (this.map.options.enablePolylineDraw) { - this.options.actions.push(L.U.DrawPolylineAction); - if (this.map.editedFeature && this.map.editedFeature instanceof L.U.Polyline) { - this.options.actions.push(L.U.AddPolylineShapeAction); - } - } - if (this.map.options.enablePolygonDraw) { - this.options.actions.push(L.U.DrawPolygonAction); - if (this.map.editedFeature && this.map.editedFeature instanceof L.U.Polygon) { - this.options.actions.push(L.U.AddPolygonShapeAction); - } - } - L.Toolbar.Control.prototype.appendToContainer.call(this, container); - }, - - redraw: function () { - var container = this._control.getContainer(); - container.innerHTML = ''; - this.appendToContainer(container); + appendToContainer: function (container) { + this.options.actions = [] + if (this.map.options.enableMarkerDraw) { + this.options.actions.push(L.U.DrawMarkerAction) } + if (this.map.options.enablePolylineDraw) { + this.options.actions.push(L.U.DrawPolylineAction) + if (this.map.editedFeature && this.map.editedFeature instanceof L.U.Polyline) { + this.options.actions.push(L.U.AddPolylineShapeAction) + } + } + if (this.map.options.enablePolygonDraw) { + this.options.actions.push(L.U.DrawPolygonAction) + if (this.map.editedFeature && this.map.editedFeature instanceof L.U.Polygon) { + this.options.actions.push(L.U.AddPolygonShapeAction) + } + } + L.Toolbar.Control.prototype.appendToContainer.call(this, container) + }, -}); - + redraw: function () { + var container = this._control.getContainer() + container.innerHTML = '' + this.appendToContainer(container) + }, +}) L.U.EditControl = L.Control.extend({ + options: { + position: 'topright', + }, - options: { - position: 'topright' - }, + onAdd: function (map) { + var container = L.DomUtil.create('div', 'leaflet-control-edit-enable umap-control'), + edit = L.DomUtil.create('a', '', container) + edit.href = '#' + edit.title = L._('Enable editing') + ' (Ctrl+E)' - onAdd: function (map) { - var container = L.DomUtil.create('div', 'leaflet-control-edit-enable umap-control'), - edit = L.DomUtil.create('a', '', container); - edit.href = '#'; - edit.title = L._('Enable editing') + ' (Ctrl+E)'; - - L.DomEvent - .addListener(edit, 'click', L.DomEvent.stop) - .addListener(edit, 'click', map.enableEdit, map); - return container; - } - -}); + L.DomEvent.addListener(edit, 'click', L.DomEvent.stop).addListener( + edit, + 'click', + map.enableEdit, + map + ) + return container + }, +}) /* Share control */ L.Control.Embed = L.Control.extend({ + options: { + position: 'topleft', + }, - options: { - position: 'topleft' - }, + onAdd: function (map) { + var container = L.DomUtil.create('div', 'leaflet-control-embed umap-control') - onAdd: function (map) { - var container = L.DomUtil.create('div', 'leaflet-control-embed umap-control'); + var link = L.DomUtil.create('a', '', container) + link.href = '#' + link.title = L._('Embed and share this map') - var link = L.DomUtil.create('a', '', container); - link.href = '#'; - link.title = L._('Embed and share this map'); + L.DomEvent.on(link, 'click', L.DomEvent.stop) + .on(link, 'click', map.renderShareBox, map) + .on(link, 'dblclick', L.DomEvent.stopPropagation) - L.DomEvent - .on(link, 'click', L.DomEvent.stop) - .on(link, 'click', map.renderShareBox, map) - .on(link, 'dblclick', L.DomEvent.stopPropagation); - - return container; - } -}); + return container + }, +}) L.U.MoreControls = L.Control.extend({ + options: { + position: 'topleft', + }, - options: { - position: 'topleft' - }, + onAdd: function () { + var container = L.DomUtil.create('div', ''), + more = L.DomUtil.create('a', 'umap-control-more umap-control-text', container), + less = L.DomUtil.create('a', 'umap-control-less umap-control-text', container) + more.href = '#' + more.title = L._('More controls') - onAdd: function () { - var container = L.DomUtil.create('div', ''), - more = L.DomUtil.create('a', 'umap-control-more umap-control-text', container), - less = L.DomUtil.create('a', 'umap-control-less umap-control-text', container); - more.href = '#'; - more.title = L._('More controls'); + L.DomEvent.on(more, 'click', L.DomEvent.stop).on(more, 'click', this.toggle, this) - L.DomEvent - .on(more, 'click', L.DomEvent.stop) - .on(more, 'click', this.toggle, this); + less.href = '#' + less.title = L._('Hide controls') - less.href = '#'; - less.title = L._('Hide controls'); + L.DomEvent.on(less, 'click', L.DomEvent.stop).on(less, 'click', this.toggle, this) - L.DomEvent - .on(less, 'click', L.DomEvent.stop) - .on(less, 'click', this.toggle, this); - - return container; - }, - - toggle: function () { - var pos = this.getPosition(), - corner = this._map._controlCorners[pos], - className = 'umap-more-controls'; - if (L.DomUtil.hasClass(corner, className)) L.DomUtil.removeClass(corner, className); - else L.DomUtil.addClass(corner, className); - } - -}); + return container + }, + toggle: function () { + var pos = this.getPosition(), + corner = this._map._controlCorners[pos], + className = 'umap-more-controls' + if (L.DomUtil.hasClass(corner, className)) L.DomUtil.removeClass(corner, className) + else L.DomUtil.addClass(corner, className) + }, +}) L.U.PermanentCreditsControl = L.Control.extend({ + options: { + position: 'bottomleft', + }, - options: { - position: 'bottomleft' - }, + initialize: function (map, options) { + this.map = map + L.Control.prototype.initialize.call(this, options) + }, - initialize: function (map, options) { - this.map = map; - L.Control.prototype.initialize.call(this, options); - }, + onAdd: function () { + var paragraphContainer = L.DomUtil.create( + 'div', + 'umap-permanent-credits-container' + ), + creditsParagraph = L.DomUtil.create('p', '', paragraphContainer) - onAdd: function () { - var paragraphContainer = L.DomUtil.create('div', 'umap-permanent-credits-container'), - creditsParagraph = L.DomUtil.create('p', '', paragraphContainer); + this.paragraphContainer = paragraphContainer + this.setCredits() + this.setBackground() - this.paragraphContainer = paragraphContainer; - this.setCredits(); - this.setBackground(); + return paragraphContainer + }, - return paragraphContainer; - }, + setCredits: function () { + this.paragraphContainer.innerHTML = L.Util.toHTML(this.map.options.permanentCredit) + }, - setCredits: function () { - this.paragraphContainer.innerHTML = L.Util.toHTML(this.map.options.permanentCredit); - }, - - setBackground: function () { - if (this.map.options.permanentCreditBackground) { - this.paragraphContainer.style.backgroundColor = '#FFFFFFB0'; - } else { - this.paragraphContainer.style.backgroundColor = ''; - } + setBackground: function () { + if (this.map.options.permanentCreditBackground) { + this.paragraphContainer.style.backgroundColor = '#FFFFFFB0' + } else { + this.paragraphContainer.style.backgroundColor = '' } - -}); - + }, +}) L.U.DataLayersControl = L.Control.extend({ + options: { + position: 'topleft', + }, - options: { - position: 'topleft' - }, + labels: { + zoomToLayer: L._('Zoom to layer extent'), + toggleLayer: L._('Show/hide layer'), + editLayer: L._('Edit'), + }, - labels: { - zoomToLayer: L._('Zoom to layer extent'), - toggleLayer: L._('Show/hide layer'), - editLayer: L._('Edit') - }, + initialize: function (map, options) { + this.map = map + L.Control.prototype.initialize.call(this, options) + }, - initialize: function (map, options) { - this.map = map; - L.Control.prototype.initialize.call(this, options); - }, + _initLayout: function (map) { + var container = (this._container = L.DomUtil.create( + 'div', + 'leaflet-control-browse umap-control' + )), + actions = L.DomUtil.create('div', 'umap-browse-actions', container) + this._datalayers_container = L.DomUtil.create( + 'ul', + 'umap-browse-datalayers', + actions + ) - _initLayout: function (map) { - var container = this._container = L.DomUtil.create('div', 'leaflet-control-browse umap-control'), - actions = L.DomUtil.create('div', 'umap-browse-actions', container); - this._datalayers_container = L.DomUtil.create('ul', 'umap-browse-datalayers', actions); + var link = L.DomUtil.create('a', 'umap-browse-link', actions) + link.href = '#' + link.title = link.textContent = L._('Browse data') - var link = L.DomUtil.create('a', 'umap-browse-link', actions); - link.href = '#'; - link.title = link.textContent = L._('Browse data'); + var toggle = L.DomUtil.create('a', 'umap-browse-toggle', container) + toggle.href = '#' + toggle.title = L._('See data layers') - var toggle = L.DomUtil.create('a', 'umap-browse-toggle', container); - toggle.href = '#'; - toggle.title = L._('See data layers') + L.DomEvent.on(toggle, 'click', L.DomEvent.stop) - L.DomEvent - .on(toggle, 'click', L.DomEvent.stop); + L.DomEvent.on(link, 'click', L.DomEvent.stop).on( + link, + 'click', + map.openBrowser, + map + ) - L.DomEvent - .on(link, 'click', L.DomEvent.stop) - .on(link, 'click', map.openBrowser, map); + map.whenReady(function () { + this.update() + }, this) - map.whenReady(function () { - this.update(); - }, this); - - if (L.Browser.pointer) { - L.DomEvent.disableClickPropagation(container); - L.DomEvent.on(container, 'mousewheel', L.DomEvent.stopPropagation); - L.DomEvent.on(container, 'MozMousePixelScroll', L.DomEvent.stopPropagation); - } - if (!L.Browser.touch) { - L.DomEvent.on(container, { - mouseenter: this.expand, - mouseleave: this.collapse - }, this); - } else { - L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation); - L.DomEvent.on(toggle, 'click', L.DomEvent.stop) - .on(toggle, 'click', this.expand, this); - map.on('click', this.collapse, this); - } - - return container; - }, - - onAdd: function (map) { - if (!this._container) this._initLayout(map); - if (map.options.datalayersControl === 'expanded') this.expand(); - return this._container; - }, - - onRemove: function (map) { - this.collapse(); - }, - - update: function () { - if (this._datalayers_container && this._map) { - this._datalayers_container.innerHTML = ''; - this._map.eachDataLayerReverse(function (datalayer) { - this.addDataLayer(this._datalayers_container, datalayer); - }, this) - } - }, - - expand: function () { - L.DomUtil.addClass(this._container, 'expanded'); - }, - - collapse: function () { - if (this._map.options.datalayersControl === 'expanded') return; - L.DomUtil.removeClass(this._container, 'expanded'); - }, - - addDataLayer: function (container, datalayer, draggable) { - var datalayerLi = L.DomUtil.create('li', '', container); - if (draggable) L.DomUtil.element('i', {className: 'drag-handle', title: L._('Drag to reorder')}, datalayerLi); - datalayer.renderToolbox(datalayerLi); - var title = L.DomUtil.add('span', 'layer-title', datalayerLi, datalayer.options.name); - - datalayerLi.id = 'browse_data_toggle_' + L.stamp(datalayer); - L.DomUtil.classIf(datalayerLi, 'off', !datalayer.isVisible()); - - title.textContent = datalayer.options.name; - }, - - newDataLayer: function () { - var datalayer = this.map.createDataLayer({}); - datalayer.edit(); - }, - - openPanel: function () { - if (!this.map.editEnabled) return; - var container = L.DomUtil.create('ul', 'umap-browse-datalayers'); - this.map.eachDataLayerReverse(function (datalayer) { - this.addDataLayer(container, datalayer, true); - }, this); - var orderable = new L.U.Orderable(container); - orderable.on('drop', function (e) { - var layer = this.map.datalayers[e.src.dataset.id], - other = this.map.datalayers[e.dst.dataset.id], - minIndex = Math.min(e.initialIndex, e.finalIndex); - if (e.finalIndex === 0) layer.bringToTop(); - else if (e.finalIndex > e.initialIndex) layer.insertBefore(other); - else layer.insertAfter(other); - this.map.eachDataLayerReverse(function (datalayer) { - if (datalayer.getRank() >= minIndex) datalayer.isDirty = true; - }); - this.map.indexDatalayers(); - }, this); - - var bar = L.DomUtil.create('div', 'button-bar', container), - add = L.DomUtil.create('a', 'show-on-edit block add-datalayer button', bar); - add.href = '#'; - add.textContent = add.title = L._('Add a layer'); - - L.DomEvent - .on(add, 'click', L.DomEvent.stop) - .on(add, 'click', this.newDataLayer, this); - - this.map.ui.openPanel({data: {html: container}, className: 'dark'}); + if (L.Browser.pointer) { + L.DomEvent.disableClickPropagation(container) + L.DomEvent.on(container, 'mousewheel', L.DomEvent.stopPropagation) + L.DomEvent.on(container, 'MozMousePixelScroll', L.DomEvent.stopPropagation) + } + if (!L.Browser.touch) { + L.DomEvent.on( + container, + { + mouseenter: this.expand, + mouseleave: this.collapse, + }, + this + ) + } else { + L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation) + L.DomEvent.on(toggle, 'click', L.DomEvent.stop).on( + toggle, + 'click', + this.expand, + this + ) + map.on('click', this.collapse, this) } -}); + return container + }, + + onAdd: function (map) { + if (!this._container) this._initLayout(map) + if (map.options.datalayersControl === 'expanded') this.expand() + return this._container + }, + + onRemove: function (map) { + this.collapse() + }, + + update: function () { + if (this._datalayers_container && this._map) { + this._datalayers_container.innerHTML = '' + this._map.eachDataLayerReverse(function (datalayer) { + this.addDataLayer(this._datalayers_container, datalayer) + }, this) + } + }, + + expand: function () { + L.DomUtil.addClass(this._container, 'expanded') + }, + + collapse: function () { + if (this._map.options.datalayersControl === 'expanded') return + L.DomUtil.removeClass(this._container, 'expanded') + }, + + addDataLayer: function (container, datalayer, draggable) { + var datalayerLi = L.DomUtil.create('li', '', container) + if (draggable) + L.DomUtil.element( + 'i', + { className: 'drag-handle', title: L._('Drag to reorder') }, + datalayerLi + ) + datalayer.renderToolbox(datalayerLi) + var title = L.DomUtil.add( + 'span', + 'layer-title', + datalayerLi, + datalayer.options.name + ) + + datalayerLi.id = 'browse_data_toggle_' + L.stamp(datalayer) + L.DomUtil.classIf(datalayerLi, 'off', !datalayer.isVisible()) + + title.textContent = datalayer.options.name + }, + + newDataLayer: function () { + var datalayer = this.map.createDataLayer({}) + datalayer.edit() + }, + + openPanel: function () { + if (!this.map.editEnabled) return + var container = L.DomUtil.create('ul', 'umap-browse-datalayers') + this.map.eachDataLayerReverse(function (datalayer) { + this.addDataLayer(container, datalayer, true) + }, this) + var orderable = new L.U.Orderable(container) + orderable.on( + 'drop', + function (e) { + var layer = this.map.datalayers[e.src.dataset.id], + other = this.map.datalayers[e.dst.dataset.id], + minIndex = Math.min(e.initialIndex, e.finalIndex) + if (e.finalIndex === 0) layer.bringToTop() + else if (e.finalIndex > e.initialIndex) layer.insertBefore(other) + else layer.insertAfter(other) + this.map.eachDataLayerReverse(function (datalayer) { + if (datalayer.getRank() >= minIndex) datalayer.isDirty = true + }) + this.map.indexDatalayers() + }, + this + ) + + var bar = L.DomUtil.create('div', 'button-bar', container), + add = L.DomUtil.create('a', 'show-on-edit block add-datalayer button', bar) + add.href = '#' + add.textContent = add.title = L._('Add a layer') + + L.DomEvent.on(add, 'click', L.DomEvent.stop).on( + add, + 'click', + this.newDataLayer, + this + ) + + this.map.ui.openPanel({ data: { html: container }, className: 'dark' }) + }, +}) L.U.DataLayer.include({ + renderToolbox: function (container) { + var toggle = L.DomUtil.create('i', 'layer-toggle', container), + zoomTo = L.DomUtil.create('i', 'layer-zoom_to', container), + edit = L.DomUtil.create('i', 'layer-edit show-on-edit', container), + table = L.DomUtil.create('i', 'layer-table-edit show-on-edit', container), + remove = L.DomUtil.create('i', 'layer-delete show-on-edit', container) + zoomTo.title = L._('Zoom to layer extent') + toggle.title = L._('Show/hide layer') + edit.title = L._('Edit') + table.title = L._('Edit properties in a table') + remove.title = L._('Delete layer') + L.DomEvent.on(toggle, 'click', this.toggle, this) + L.DomEvent.on(zoomTo, 'click', this.zoomTo, this) + L.DomEvent.on(edit, 'click', this.edit, this) + L.DomEvent.on(table, 'click', this.tableEdit, this) + L.DomEvent.on( + remove, + 'click', + function () { + if (!this.isVisible()) return + if (!confirm(L._('Are you sure you want to delete this layer?'))) return + this._delete() + this.map.ui.closePanel() + }, + this + ) + L.DomUtil.addClass(container, this.getHidableClass()) + L.DomUtil.classIf(container, 'off', !this.isVisible()) + container.dataset.id = L.stamp(this) + }, - renderToolbox: function (container) { - var toggle = L.DomUtil.create('i', 'layer-toggle', container), - zoomTo = L.DomUtil.create('i', 'layer-zoom_to', container), - edit = L.DomUtil.create('i', 'layer-edit show-on-edit', container), - table = L.DomUtil.create('i', 'layer-table-edit show-on-edit', container), - remove = L.DomUtil.create('i', 'layer-delete show-on-edit', container); - zoomTo.title = L._('Zoom to layer extent'); - toggle.title = L._('Show/hide layer'); - edit.title = L._('Edit'); - table.title = L._('Edit properties in a table'); - remove.title = L._('Delete layer'); - L.DomEvent.on(toggle, 'click', this.toggle, this); - L.DomEvent.on(zoomTo, 'click', this.zoomTo, this); - L.DomEvent.on(edit, 'click', this.edit, this); - L.DomEvent.on(table, 'click', this.tableEdit, this); - L.DomEvent.on(remove, 'click', function () { - if (!this.isVisible()) return; - if (!confirm(L._('Are you sure you want to delete this layer?'))) return; - this._delete(); - this.map.ui.closePanel(); - }, this); - L.DomUtil.addClass(container, this.getHidableClass()); - L.DomUtil.classIf(container, 'off', !this.isVisible()); - container.dataset.id = L.stamp(this); - }, + getHidableElements: function () { + return document.querySelectorAll('.' + this.getHidableClass()) + }, - getHidableElements: function () { - return document.querySelectorAll('.' + this.getHidableClass()); - }, + getHidableClass: function () { + return 'show_with_datalayer_' + L.stamp(this) + }, - getHidableClass: function () { - return 'show_with_datalayer_' + L.stamp(this); - }, - - propagateRemote: function () { - var els = this.getHidableElements(); - for (var i = 0; i < els.length; i++) { - L.DomUtil.classIf(els[i], 'remotelayer', this.isRemoteLayer()); - } - }, - - propagateHide: function () { - var els = this.getHidableElements(); - for (var i = 0; i < els.length; i++) { - L.DomUtil.addClass(els[i], 'off'); - } - }, - - propagateShow: function () { - this.onceLoaded(function () { - var els = this.getHidableElements(); - for (var i = 0; i < els.length; i++) { - L.DomUtil.removeClass(els[i], 'off'); - } - }, this); + propagateRemote: function () { + var els = this.getHidableElements() + for (var i = 0; i < els.length; i++) { + L.DomUtil.classIf(els[i], 'remotelayer', this.isRemoteLayer()) } + }, -}); + propagateHide: function () { + var els = this.getHidableElements() + for (var i = 0; i < els.length; i++) { + L.DomUtil.addClass(els[i], 'off') + } + }, + + propagateShow: function () { + this.onceLoaded(function () { + var els = this.getHidableElements() + for (var i = 0; i < els.length; i++) { + L.DomUtil.removeClass(els[i], 'off') + } + }, this) + }, +}) L.U.DataLayer.addInitHook(function () { - this.on('hide', this.propagateHide); - this.on('show', this.propagateShow); - this.propagateShow(); -}); - + this.on('hide', this.propagateHide) + this.on('show', this.propagateShow) + this.propagateShow() +}) L.U.Map.include({ + _openBrowser: function () { + var browserContainer = L.DomUtil.create('div', 'umap-browse-data'), + title = L.DomUtil.add( + 'h3', + 'umap-browse-title', + browserContainer, + this.options.name + ), + filter = L.DomUtil.create('input', '', browserContainer), + filterValue = '', + featuresContainer = L.DomUtil.create( + 'div', + 'umap-browse-features', + browserContainer + ), + filterKeys = this.getFilterKeys() + filter.type = 'text' + filter.placeholder = L._('Filter…') + filter.value = this.options.filter || '' - _openBrowser: function () { - var browserContainer = L.DomUtil.create('div', 'umap-browse-data'), - title = L.DomUtil.add('h3', 'umap-browse-title', browserContainer, this.options.name), - filter = L.DomUtil.create('input', '', browserContainer), - filterValue = '', - featuresContainer = L.DomUtil.create('div', 'umap-browse-features', browserContainer), - filterKeys = this.getFilterKeys(); - filter.type = 'text'; - filter.placeholder = L._('Filter…'); - filter.value = this.options.filter || ''; - - var addFeature = function (feature) { - var feature_li = L.DomUtil.create('li', feature.getClassName() + ' feature'), - zoom_to = L.DomUtil.create('i', 'feature-zoom_to', feature_li), - edit = L.DomUtil.create('i', 'show-on-edit feature-edit', feature_li), - color = L.DomUtil.create('i', 'feature-color', feature_li), - title = L.DomUtil.create('span', 'feature-title', feature_li), - symbol = feature._getIconUrl ? L.U.Icon.prototype.formatUrl(feature._getIconUrl(), feature): null; - zoom_to.title = L._('Bring feature to center'); - edit.title = L._('Edit this feature'); - title.textContent = feature.getDisplayName() || '—'; - color.style.backgroundColor = feature.getOption('color'); - if (symbol) { - color.style.backgroundImage = 'url(' + symbol + ')'; - } - L.DomEvent.on(zoom_to, 'click', function (e) { - e.callback = L.bind(this.view, this); - this.zoomTo(e); - }, feature); - L.DomEvent.on(title, 'click', function (e) { - e.callback = L.bind(this.view, this) - this.zoomTo(e); - }, feature); - L.DomEvent.on(edit, 'click', function () { - this.edit(); - }, feature); - return feature_li; - }; - - var append = function (datalayer) { - var container = L.DomUtil.create('div', datalayer.getHidableClass(), featuresContainer), - headline = L.DomUtil.create('h5', '', container); - container.id = 'browse_data_datalayer_' + datalayer.umap_id; - datalayer.renderToolbox(headline); - L.DomUtil.add('span', '', headline, datalayer.options.name); - var ul = L.DomUtil.create('ul', '', container); - L.DomUtil.classIf(container, 'off', !datalayer.isVisible()); - - var build = function () { - ul.innerHTML = ''; - datalayer.eachFeature(function (feature) { - if ((filterValue && !feature.matchFilter(filterValue, filterKeys)) || feature.properties.isVisible === false) return; - ul.appendChild(addFeature(feature)); - }); - }; - build(); - datalayer.on('datachanged', build); - datalayer.map.ui.once('panel:closed', function () { - datalayer.off('datachanged', build); - }); - datalayer.map.ui.once('panel:ready', function () { - datalayer.map.ui.once('panel:ready', function () { - datalayer.off('datachanged', build); - }); - }); - }; - - var appendAll = function () { - this.options.filter = filterValue = filter.value; - featuresContainer.innerHTML = ''; - this.eachBrowsableDataLayer(function (datalayer) { - append(datalayer); - }); - }; - var resetLayers = function () { - this.eachBrowsableDataLayer(function (datalayer) { - datalayer.resetLayer(true); - }); - } - L.bind(appendAll, this)(); - L.DomEvent.on(filter, 'input', appendAll, this); - L.DomEvent.on(filter, 'input', resetLayers, this); - var link = L.DomUtil.create('li', ''); - L.DomUtil.create('i', 'umap-icon-16 umap-caption', link); - var label = L.DomUtil.create('span', '', link); - label.textContent = label.title = L._('About'); - L.DomEvent.on(link, 'click', this.displayCaption, this); - this.ui.openPanel({data: {html: browserContainer}, actions: [link]}); - }, - - _openFilter: function () { - var filterContainer = L.DomUtil.create('div', 'umap-filter-data'), - title = L.DomUtil.add('h3', 'umap-filter-title', filterContainer, this.options.name), - propertiesContainer = L.DomUtil.create('div', 'umap-filter-properties', filterContainer), - advancedFilterKeys = this.getAdvancedFilterKeys(); - - var advancedFiltersFull = {}; - var filtersAlreadyLoaded = true; - if (!this.getMap().options.advancedFilters) { - this.getMap().options.advancedFilters = {}; - filtersAlreadyLoaded = false; - } - advancedFilterKeys.forEach(property => { - advancedFiltersFull[property] = []; - if (!filtersAlreadyLoaded || !this.getMap().options.advancedFilters[property]) { - this.getMap().options.advancedFilters[property] = []; - } - }); - this.eachDataLayer(function (datalayer) { - datalayer.eachFeature(function (feature) { - advancedFilterKeys.forEach(property => { - if (feature.properties[property]) { - if (!advancedFiltersFull[property].includes(feature.properties[property])) { - advancedFiltersFull[property].push(feature.properties[property]); - } - } - }); - }); - }); - - var addPropertyValue = function (property, value) { - var property_li = L.DomUtil.create('li', ''), - filter_check = L.DomUtil.create('input', '', property_li), - filter_label = L.DomUtil.create('label', '', property_li); - filter_check.type = 'checkbox'; - filter_check.id = `checkbox_${property}_${value}`; - filter_check.checked = this.getMap().options.advancedFilters[property] && this.getMap().options.advancedFilters[property].includes(value); - filter_check.setAttribute('data-property', property); - filter_check.setAttribute('data-value', value); - filter_label.htmlFor = `checkbox_${property}_${value}`; - filter_label.innerHTML = value; - L.DomEvent.on(filter_check, 'change', function (e) { - var property = e.srcElement.dataset.property; - var value = e.srcElement.dataset.value; - if (e.srcElement.checked) { - this.getMap().options.advancedFilters[property].push(value); - } else { - this.getMap().options.advancedFilters[property].splice(this.getMap().options.advancedFilters[property].indexOf(value), 1); - } - L.bind(filterFeatures, this)(); - }, this); - return property_li - }; - - var addProperty = function (property) { - var container = L.DomUtil.create('div', 'property-container', propertiesContainer), - headline = L.DomUtil.add('h5', '', container, property); - var ul = L.DomUtil.create('ul', '', container); - var orderedValues = advancedFiltersFull[property]; - orderedValues.sort(); - orderedValues.forEach(value => { - ul.appendChild(L.bind(addPropertyValue, this)(property, value)); - }); - }; - - var filterFeatures = function () { - var noResults = true; - this.eachDataLayer(function (datalayer) { - datalayer.eachFeature(function (feature) { - feature.properties.isVisible = true; - for (const [property, values] of Object.entries(this.map.options.advancedFilters)) { - if (values.length > 0) { - if (!feature.properties[property] || !values.includes(feature.properties[property])) { - feature.properties.isVisible = false; - } - } - } - if (feature.properties.isVisible) { - noResults = false; - if (!this.isLoaded()) this.fetchData(); - this.map.addLayer(feature); - this.fire('show'); - } else { - this.map.removeLayer(feature); - this.fire('hide'); - } - }); - }); - if (noResults) { - this.help.show('advancedFiltersNoResults'); - } else { - this.help.hide(); - } - }; - - propertiesContainer.innerHTML = ''; - advancedFilterKeys.forEach(property => { - L.bind(addProperty, this)(property); - }); - - var link = L.DomUtil.create('li', ''); - L.DomUtil.create('i', 'umap-icon-16 umap-caption', link); - var label = L.DomUtil.create('span', '', link); - label.textContent = label.title = L._('About'); - L.DomEvent.on(link, 'click', this.displayCaption, this); - this.ui.openPanel({ data: { html: filterContainer }, actions: [link] }); + var addFeature = function (feature) { + var feature_li = L.DomUtil.create('li', feature.getClassName() + ' feature'), + zoom_to = L.DomUtil.create('i', 'feature-zoom_to', feature_li), + edit = L.DomUtil.create('i', 'show-on-edit feature-edit', feature_li), + color = L.DomUtil.create('i', 'feature-color', feature_li), + title = L.DomUtil.create('span', 'feature-title', feature_li), + symbol = feature._getIconUrl + ? L.U.Icon.prototype.formatUrl(feature._getIconUrl(), feature) + : null + zoom_to.title = L._('Bring feature to center') + edit.title = L._('Edit this feature') + title.textContent = feature.getDisplayName() || '—' + color.style.backgroundColor = feature.getOption('color') + if (symbol) { + color.style.backgroundImage = 'url(' + symbol + ')' + } + L.DomEvent.on( + zoom_to, + 'click', + function (e) { + e.callback = L.bind(this.view, this) + this.zoomTo(e) + }, + feature + ) + L.DomEvent.on( + title, + 'click', + function (e) { + e.callback = L.bind(this.view, this) + this.zoomTo(e) + }, + feature + ) + L.DomEvent.on( + edit, + 'click', + function () { + this.edit() + }, + feature + ) + return feature_li } -}); + var append = function (datalayer) { + var container = L.DomUtil.create( + 'div', + datalayer.getHidableClass(), + featuresContainer + ), + headline = L.DomUtil.create('h5', '', container) + container.id = 'browse_data_datalayer_' + datalayer.umap_id + datalayer.renderToolbox(headline) + L.DomUtil.add('span', '', headline, datalayer.options.name) + var ul = L.DomUtil.create('ul', '', container) + L.DomUtil.classIf(container, 'off', !datalayer.isVisible()) + var build = function () { + ul.innerHTML = '' + datalayer.eachFeature(function (feature) { + if ( + (filterValue && !feature.matchFilter(filterValue, filterKeys)) || + feature.properties.isVisible === false + ) + return + ul.appendChild(addFeature(feature)) + }) + } + build() + datalayer.on('datachanged', build) + datalayer.map.ui.once('panel:closed', function () { + datalayer.off('datachanged', build) + }) + datalayer.map.ui.once('panel:ready', function () { + datalayer.map.ui.once('panel:ready', function () { + datalayer.off('datachanged', build) + }) + }) + } + var appendAll = function () { + this.options.filter = filterValue = filter.value + featuresContainer.innerHTML = '' + this.eachBrowsableDataLayer(function (datalayer) { + append(datalayer) + }) + } + var resetLayers = function () { + this.eachBrowsableDataLayer(function (datalayer) { + datalayer.resetLayer(true) + }) + } + L.bind(appendAll, this)() + L.DomEvent.on(filter, 'input', appendAll, this) + L.DomEvent.on(filter, 'input', resetLayers, this) + var link = L.DomUtil.create('li', '') + L.DomUtil.create('i', 'umap-icon-16 umap-caption', link) + var label = L.DomUtil.create('span', '', link) + label.textContent = label.title = L._('About') + L.DomEvent.on(link, 'click', this.displayCaption, this) + this.ui.openPanel({ data: { html: browserContainer }, actions: [link] }) + }, + + _openFilter: function () { + var filterContainer = L.DomUtil.create('div', 'umap-filter-data'), + title = L.DomUtil.add( + 'h3', + 'umap-filter-title', + filterContainer, + this.options.name + ), + propertiesContainer = L.DomUtil.create( + 'div', + 'umap-filter-properties', + filterContainer + ), + advancedFilterKeys = this.getAdvancedFilterKeys() + + var advancedFiltersFull = {} + var filtersAlreadyLoaded = true + if (!this.getMap().options.advancedFilters) { + this.getMap().options.advancedFilters = {} + filtersAlreadyLoaded = false + } + advancedFilterKeys.forEach((property) => { + advancedFiltersFull[property] = [] + if (!filtersAlreadyLoaded || !this.getMap().options.advancedFilters[property]) { + this.getMap().options.advancedFilters[property] = [] + } + }) + this.eachDataLayer(function (datalayer) { + datalayer.eachFeature(function (feature) { + advancedFilterKeys.forEach((property) => { + if (feature.properties[property]) { + if (!advancedFiltersFull[property].includes(feature.properties[property])) { + advancedFiltersFull[property].push(feature.properties[property]) + } + } + }) + }) + }) + + var addPropertyValue = function (property, value) { + var property_li = L.DomUtil.create('li', ''), + filter_check = L.DomUtil.create('input', '', property_li), + filter_label = L.DomUtil.create('label', '', property_li) + filter_check.type = 'checkbox' + filter_check.id = `checkbox_${property}_${value}` + filter_check.checked = + this.getMap().options.advancedFilters[property] && + this.getMap().options.advancedFilters[property].includes(value) + filter_check.setAttribute('data-property', property) + filter_check.setAttribute('data-value', value) + filter_label.htmlFor = `checkbox_${property}_${value}` + filter_label.innerHTML = value + L.DomEvent.on( + filter_check, + 'change', + function (e) { + var property = e.srcElement.dataset.property + var value = e.srcElement.dataset.value + if (e.srcElement.checked) { + this.getMap().options.advancedFilters[property].push(value) + } else { + this.getMap().options.advancedFilters[property].splice( + this.getMap().options.advancedFilters[property].indexOf(value), + 1 + ) + } + L.bind(filterFeatures, this)() + }, + this + ) + return property_li + } + + var addProperty = function (property) { + var container = L.DomUtil.create( + 'div', + 'property-container', + propertiesContainer + ), + headline = L.DomUtil.add('h5', '', container, property) + var ul = L.DomUtil.create('ul', '', container) + var orderedValues = advancedFiltersFull[property] + orderedValues.sort() + orderedValues.forEach((value) => { + ul.appendChild(L.bind(addPropertyValue, this)(property, value)) + }) + } + + var filterFeatures = function () { + var noResults = true + this.eachDataLayer(function (datalayer) { + datalayer.eachFeature(function (feature) { + feature.properties.isVisible = true + for (const [property, values] of Object.entries( + this.map.options.advancedFilters + )) { + if (values.length > 0) { + if ( + !feature.properties[property] || + !values.includes(feature.properties[property]) + ) { + feature.properties.isVisible = false + } + } + } + if (feature.properties.isVisible) { + noResults = false + if (!this.isLoaded()) this.fetchData() + this.map.addLayer(feature) + this.fire('show') + } else { + this.map.removeLayer(feature) + this.fire('hide') + } + }) + }) + if (noResults) { + this.help.show('advancedFiltersNoResults') + } else { + this.help.hide() + } + } + + propertiesContainer.innerHTML = '' + advancedFilterKeys.forEach((property) => { + L.bind(addProperty, this)(property) + }) + + var link = L.DomUtil.create('li', '') + L.DomUtil.create('i', 'umap-icon-16 umap-caption', link) + var label = L.DomUtil.create('span', '', link) + label.textContent = label.title = L._('About') + L.DomEvent.on(link, 'click', this.displayCaption, this) + this.ui.openPanel({ data: { html: filterContainer }, actions: [link] }) + }, +}) L.U.TileLayerControl = L.Control.extend({ + options: { + position: 'topleft', + }, - options: { - position: 'topleft' - }, + initialize: function (map, options) { + this.map = map + L.Control.prototype.initialize.call(this, options) + }, - initialize: function (map, options) { - this.map = map; - L.Control.prototype.initialize.call(this, options); - }, + onAdd: function () { + var container = L.DomUtil.create('div', 'leaflet-control-tilelayers umap-control') - onAdd: function () { - var container = L.DomUtil.create('div', 'leaflet-control-tilelayers umap-control'); + var link = L.DomUtil.create('a', '', container) + link.href = '#' + link.title = L._('Change map background') - var link = L.DomUtil.create('a', '', container); - link.href = '#'; - link.title = L._('Change map background'); + L.DomEvent.on(link, 'click', L.DomEvent.stop) + .on(link, 'click', this.openSwitcher, this) + .on(link, 'dblclick', L.DomEvent.stopPropagation) - L.DomEvent - .on(link, 'click', L.DomEvent.stop) - .on(link, 'click', this.openSwitcher, this) - .on(link, 'dblclick', L.DomEvent.stopPropagation); + return container + }, - return container; - }, + openSwitcher: function (options) { + this._tilelayers_container = L.DomUtil.create( + 'ul', + 'umap-tilelayer-switcher-container' + ) + this.buildList(options) + }, - openSwitcher: function (options) { - this._tilelayers_container = L.DomUtil.create('ul', 'umap-tilelayer-switcher-container'); - this.buildList(options); - }, + buildList: function (options) { + this.map.eachTileLayer(function (tilelayer) { + if ( + window.location.protocol === 'https:' && + tilelayer.options.url_template.indexOf('http:') === 0 + ) + return + this.addTileLayerElement(tilelayer, options) + }, this) + this.map.ui.openPanel({ + data: { html: this._tilelayers_container }, + className: options.className, + }) + }, - buildList: function (options) { - this.map.eachTileLayer(function (tilelayer) { - if (window.location.protocol === 'https:' && tilelayer.options.url_template.indexOf('http:') === 0) return; - this.addTileLayerElement(tilelayer, options); - }, this); - this.map.ui.openPanel({data: {html: this._tilelayers_container}, className: options.className}); - }, - - addTileLayerElement: function (tilelayer, options) { - var selectedClass = this.map.hasLayer(tilelayer) ? 'selected' : '', - el = L.DomUtil.create('li', selectedClass, this._tilelayers_container), - img = L.DomUtil.create('img', '', el), - name = L.DomUtil.create('div', '', el); - img.src = L.Util.template(tilelayer.options.url_template, this.map.demoTileInfos); - name.textContent = tilelayer.options.name; - L.DomEvent.on(el, 'click', function () { - this.map.selectTileLayer(tilelayer); - this.map.ui.closePanel(); - if (options && options.callback) options.callback(tilelayer); - }, this); - } - - -}); + addTileLayerElement: function (tilelayer, options) { + var selectedClass = this.map.hasLayer(tilelayer) ? 'selected' : '', + el = L.DomUtil.create('li', selectedClass, this._tilelayers_container), + img = L.DomUtil.create('img', '', el), + name = L.DomUtil.create('div', '', el) + img.src = L.Util.template(tilelayer.options.url_template, this.map.demoTileInfos) + name.textContent = tilelayer.options.name + L.DomEvent.on( + el, + 'click', + function () { + this.map.selectTileLayer(tilelayer) + this.map.ui.closePanel() + if (options && options.callback) options.callback(tilelayer) + }, + this + ) + }, +}) L.U.AttributionControl = L.Control.Attribution.extend({ + options: { + prefix: '', + }, - options: { - prefix: '' - }, - - _update: function () { - L.Control.Attribution.prototype._update.call(this); - if (this._map.options.shortCredit) { - L.DomUtil.add('span', '', this._container, ' — ' + L.Util.toHTML(this._map.options.shortCredit)); - } - if (this._map.options.captionMenus) { - var link = L.DomUtil.add('a', '', this._container, ' — ' + L._('About')); - L.DomEvent - .on(link, 'click', L.DomEvent.stop) - .on(link, 'click', this._map.displayCaption, this._map) - .on(link, 'dblclick', L.DomEvent.stop); - } - if (window.top === window.self && this._map.options.captionMenus) { - // We are not in iframe mode - var home = L.DomUtil.add('a', '', this._container, ' — ' + L._('Home')); - home.href = '/'; - } + _update: function () { + L.Control.Attribution.prototype._update.call(this) + if (this._map.options.shortCredit) { + L.DomUtil.add( + 'span', + '', + this._container, + ' — ' + L.Util.toHTML(this._map.options.shortCredit) + ) } - -}); - + if (this._map.options.captionMenus) { + var link = L.DomUtil.add('a', '', this._container, ' — ' + L._('About')) + L.DomEvent.on(link, 'click', L.DomEvent.stop) + .on(link, 'click', this._map.displayCaption, this._map) + .on(link, 'dblclick', L.DomEvent.stop) + } + if (window.top === window.self && this._map.options.captionMenus) { + // We are not in iframe mode + var home = L.DomUtil.add('a', '', this._container, ' — ' + L._('Home')) + home.href = '/' + } + }, +}) L.U.Search = L.PhotonSearch.extend({ + initialize: function (map, input, options) { + L.PhotonSearch.prototype.initialize.call(this, map, input, options) + this.options.url = map.options.urls.search + }, - initialize: function (map, input, options) { - L.PhotonSearch.prototype.initialize.call(this, map, input, options); - this.options.url = map.options.urls.search; - }, + onBlur: function (e) { + // Overrided because we don't want to hide the results on blur. + this.fire('blur') + }, - onBlur: function (e) { - // Overrided because we don't want to hide the results on blur. - this.fire('blur'); - }, + formatResult: function (feature, el) { + var self = this + var tools = L.DomUtil.create('span', 'search-result-tools', el), + zoom = L.DomUtil.create('i', 'feature-zoom_to', tools), + edit = L.DomUtil.create('i', 'feature-edit show-on-edit', tools) + zoom.title = L._('Zoom to this place') + edit.title = L._('Save this location as new feature') + // We need to use "mousedown" because Leaflet.Photon listen to mousedown + // on el. + L.DomEvent.on(zoom, 'mousedown', function (e) { + L.DomEvent.stop(e) + self.zoomToFeature(feature) + }) + L.DomEvent.on(edit, 'mousedown', function (e) { + L.DomEvent.stop(e) + var datalayer = self.map.defaultDataLayer() + var layer = datalayer.geojsonToFeatures(feature) + layer.isDirty = true + layer.edit() + }) + this._formatResult(feature, el) + }, - formatResult: function (feature, el) { - var self = this; - var tools = L.DomUtil.create('span', 'search-result-tools', el), - zoom = L.DomUtil.create('i', 'feature-zoom_to', tools), - edit = L.DomUtil.create('i', 'feature-edit show-on-edit', tools); - zoom.title = L._('Zoom to this place'); - edit.title = L._('Save this location as new feature'); - // We need to use "mousedown" because Leaflet.Photon listen to mousedown - // on el. - L.DomEvent.on(zoom, 'mousedown', function (e) { - L.DomEvent.stop(e); - self.zoomToFeature(feature); - }); - L.DomEvent.on(edit, 'mousedown', function (e) { - L.DomEvent.stop(e); - var datalayer = self.map.defaultDataLayer(); - var layer = datalayer.geojsonToFeatures(feature); - layer.isDirty = true; - layer.edit(); - }); - this._formatResult(feature, el); - }, + zoomToFeature: function (feature) { + var zoom = Math.max(this.map.getZoom(), 16) // Never unzoom. + this.map.setView( + [feature.geometry.coordinates[1], feature.geometry.coordinates[0]], + zoom + ) + }, - zoomToFeature: function (feature) { - var zoom = Math.max(this.map.getZoom(), 16); // Never unzoom. - this.map.setView([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], zoom); - }, - - onSelected: function (feature) { - this.zoomToFeature(feature); - this.map.ui.closePanel(); - } - -}); + onSelected: function (feature) { + this.zoomToFeature(feature) + this.map.ui.closePanel() + }, +}) L.U.SearchControl = L.Control.extend({ + options: { + position: 'topleft', + }, - options: { - position: 'topleft', - }, + onAdd: function (map) { + var container = L.DomUtil.create('div', 'leaflet-control-search umap-control'), + self = this - onAdd: function (map) { - var container = L.DomUtil.create('div', 'leaflet-control-search umap-control'), - self = this; + L.DomEvent.disableClickPropagation(container) + var link = L.DomUtil.create('a', '', container) + link.href = '#' + link.title = L._('Search a place name') + L.DomEvent.on(link, 'click', function (e) { + L.DomEvent.stop(e) + self.openPanel(map) + }) + return container + }, - L.DomEvent.disableClickPropagation(container); - var link = L.DomUtil.create('a', '', container); - link.href = '#'; - link.title = L._('Search a place name') - L.DomEvent.on(link, 'click', function (e) { - L.DomEvent.stop(e); - self.openPanel(map); - }); - return container; - }, - - openPanel: function (map) { - var options = { - limit: 10, - noResultLabel: L._('No results'), - } - if (map.options.photonUrl) options.url = map.options.photonUrl; - var container = L.DomUtil.create('div', ''); - - var title = L.DomUtil.create('h3', '', container); - title.textContent = L._('Search location'); - var input = L.DomUtil.create('input', 'photon-input', container); - var resultsContainer = L.DomUtil.create('div', 'photon-autocomplete', container); - this.search = new L.U.Search(map, input, options); - var id = Math.random(); - this.search.on('ajax:send', function () { - map.fire('dataloading', {id: id}); - }); - this.search.on('ajax:return', function () { - map.fire('dataload', {id: id}); - }); - this.search.resultsContainer = resultsContainer; - map.ui.once('panel:ready', function () { - input.focus(); - }); - map.ui.openPanel({data: {html: container}}); + openPanel: function (map) { + var options = { + limit: 10, + noResultLabel: L._('No results'), } + if (map.options.photonUrl) options.url = map.options.photonUrl + var container = L.DomUtil.create('div', '') -}); - + var title = L.DomUtil.create('h3', '', container) + title.textContent = L._('Search location') + var input = L.DomUtil.create('input', 'photon-input', container) + var resultsContainer = L.DomUtil.create('div', 'photon-autocomplete', container) + this.search = new L.U.Search(map, input, options) + var id = Math.random() + this.search.on('ajax:send', function () { + map.fire('dataloading', { id: id }) + }) + this.search.on('ajax:return', function () { + map.fire('dataload', { id: id }) + }) + this.search.resultsContainer = resultsContainer + map.ui.once('panel:ready', function () { + input.focus() + }) + map.ui.openPanel({ data: { html: container } }) + }, +}) L.Control.MiniMap.include({ + initialize: function (layer, options) { + L.Util.setOptions(this, options) + this._layer = this._cloneLayer(layer) + }, - initialize: function (layer, options) { - L.Util.setOptions(this, options); - this._layer = this._cloneLayer(layer); - }, - - onMainMapBaseLayerChange: function (e) { - var layer = this._cloneLayer(e.layer); - if (this._miniMap.hasLayer(this._layer)) { - this._miniMap.removeLayer(this._layer); - } - this._layer = layer; - this._miniMap.addLayer(this._layer); - }, - - _cloneLayer: function (layer) { - return new L.TileLayer(layer._url, L.Util.extend({}, layer.options)); + onMainMapBaseLayerChange: function (e) { + var layer = this._cloneLayer(e.layer) + if (this._miniMap.hasLayer(this._layer)) { + this._miniMap.removeLayer(this._layer) } + this._layer = layer + this._miniMap.addLayer(this._layer) + }, -}); - + _cloneLayer: function (layer) { + return new L.TileLayer(layer._url, L.Util.extend({}, layer.options)) + }, +}) L.Control.Loading.include({ + onAdd: function (map) { + this._container = L.DomUtil.create('div', 'umap-loader', map._controlContainer) + map.on('baselayerchange', this._layerAdd, this) + this._addMapListeners(map) + this._map = map + }, - onAdd: function (map) { - this._container = L.DomUtil.create('div', 'umap-loader', map._controlContainer); - map.on('baselayerchange', this._layerAdd, this); - this._addMapListeners(map); - this._map = map; - }, - - _showIndicator: function () { - L.DomUtil.addClass(this._map._container, 'umap-loading'); - }, - - _hideIndicator: function() { - L.DomUtil.removeClass(this._map._container, 'umap-loading'); - } - -}); + _showIndicator: function () { + L.DomUtil.addClass(this._map._container, 'umap-loading') + }, + _hideIndicator: function () { + L.DomUtil.removeClass(this._map._container, 'umap-loading') + }, +}) /* -* Make it dynamic -*/ + * Make it dynamic + */ L.U.ContextMenu = L.Map.ContextMenu.extend({ + _createItems: function (e) { + this._map.setContextMenuItems(e) + L.Map.ContextMenu.prototype._createItems.call(this) + }, - _createItems: function (e) { - this._map.setContextMenuItems(e); - L.Map.ContextMenu.prototype._createItems.call(this); - }, - - _showAtPoint: function (pt, e) { - this._items = []; - this._container.innerHTML = ''; - this._createItems(e); - L.Map.ContextMenu.prototype._showAtPoint.call(this, pt, e); - } - -}); + _showAtPoint: function (pt, e) { + this._items = [] + this._container.innerHTML = '' + this._createItems(e) + L.Map.ContextMenu.prototype._showAtPoint.call(this, pt, e) + }, +}) L.U.IframeExporter = L.Evented.extend({ + options: { + includeFullScreenLink: true, + currentView: false, + keepCurrentDatalayers: false, + viewCurrentFeature: false, + }, - options: { - includeFullScreenLink: true, - currentView: false, - keepCurrentDatalayers: false, - viewCurrentFeature: false - }, + queryString: { + scaleControl: false, + miniMap: false, + scrollWheelZoom: false, + zoomControl: true, + allowEdit: false, + moreControl: true, + searchControl: null, + tilelayersControl: null, + embedControl: null, + datalayersControl: true, + onLoadPanel: 'none', + captionBar: false, + captionMenus: true, + }, - queryString: { - scaleControl: false, - miniMap: false, - scrollWheelZoom: false, - zoomControl: true, - allowEdit: false, - moreControl: true, - searchControl: null, - tilelayersControl: null, - embedControl: null, - datalayersControl: true, - onLoadPanel: 'none', - captionBar: false, - captionMenus: true - }, + dimensions: { + width: '100%', + height: '300px', + }, - dimensions: { - width: '100%', - height: '300px' - }, + initialize: function (map) { + this.map = map + this.baseUrl = L.Util.getBaseUrl() + // Use map default, not generic default + this.queryString.onLoadPanel = this.map.options.onLoadPanel + }, - initialize: function (map) { - this.map = map; - this.baseUrl = L.Util.getBaseUrl(); - // Use map default, not generic default - this.queryString.onLoadPanel = this.map.options.onLoadPanel; - }, + getMap: function () { + return this.map + }, - getMap: function () { - return this.map; - }, - - build: function () { - var datalayers = []; - if (this.options.viewCurrentFeature && this.map.currentFeature) { - this.queryString.feature = this.map.currentFeature.getSlug(); - } - if (this.options.keepCurrentDatalayers) { - this.map.eachDataLayer(function (datalayer) { - if (datalayer.isVisible() && datalayer.umap_id) { - datalayers.push(datalayer.umap_id); - } - }); - this.queryString.datalayers = datalayers.join(','); - } else { - delete this.queryString.datalayers; - } - var currentView = this.options.currentView ? window.location.hash : '', - iframeUrl = this.baseUrl + '?' + L.Util.buildQueryString(this.queryString) + currentView, - code = ''; - if (this.options.includeFullScreenLink) { - code += '

' + L._('See full screen') + '

'; - } - return code; + build: function () { + var datalayers = [] + if (this.options.viewCurrentFeature && this.map.currentFeature) { + this.queryString.feature = this.map.currentFeature.getSlug() } - -}); + if (this.options.keepCurrentDatalayers) { + this.map.eachDataLayer(function (datalayer) { + if (datalayer.isVisible() && datalayer.umap_id) { + datalayers.push(datalayer.umap_id) + } + }) + this.queryString.datalayers = datalayers.join(',') + } else { + delete this.queryString.datalayers + } + var currentView = this.options.currentView ? window.location.hash : '', + iframeUrl = + this.baseUrl + '?' + L.Util.buildQueryString(this.queryString) + currentView, + code = + '' + if (this.options.includeFullScreenLink) { + code += '

' + L._('See full screen') + '

' + } + return code + }, +}) L.U.Editable = L.Editable.extend({ + initialize: function (map, options) { + L.Editable.prototype.initialize.call(this, map, options) + this.on( + 'editable:drawing:start editable:drawing:click editable:drawing:move', + this.drawingTooltip + ) + this.on('editable:drawing:end', this.closeTooltip) + // Layer for items added by users + this.on('editable:drawing:cancel', function (e) { + if (e.layer._latlngs && e.layer._latlngs.length < e.layer.editor.MIN_VERTEX) + e.layer.del() + if (e.layer instanceof L.U.Marker) e.layer.del() + }) + this.on('editable:drawing:commit', function (e) { + e.layer.isDirty = true + if (this.map.editedFeature !== e.layer) e.layer.edit(e) + }) + this.on('editable:editing', function (e) { + var layer = e.layer + layer.isDirty = true + if (layer._tooltip && layer.isTooltipOpen()) { + layer._tooltip.setLatLng(layer.getCenter()) + layer._tooltip.update() + } + }) + this.on('editable:vertex:ctrlclick', function (e) { + var index = e.vertex.getIndex() + if (index === 0 || (index === e.vertex.getLastIndex() && e.vertex.continue)) + e.vertex.continue() + }) + this.on('editable:vertex:altclick', function (e) { + if (e.vertex.editor.vertexCanBeDeleted(e.vertex)) e.vertex.delete() + }) + this.on('editable:vertex:rawclick', this.onVertexRawClick) + }, - initialize: function (map, options) { - L.Editable.prototype.initialize.call(this, map, options); - this.on('editable:drawing:start editable:drawing:click editable:drawing:move', this.drawingTooltip); - this.on('editable:drawing:end', this.closeTooltip); - // Layer for items added by users - this.on('editable:drawing:cancel', function (e) { - if (e.layer._latlngs && e.layer._latlngs.length < e.layer.editor.MIN_VERTEX) e.layer.del(); - if (e.layer instanceof L.U.Marker) e.layer.del(); - }); - this.on('editable:drawing:commit', function (e) { - e.layer.isDirty = true; - if (this.map.editedFeature !== e.layer) e.layer.edit(e); - }); - this.on('editable:editing', function (e) { - var layer = e.layer; - layer.isDirty = true; - if (layer._tooltip && layer.isTooltipOpen()) { - layer._tooltip.setLatLng(layer.getCenter()); - layer._tooltip.update(); - } - }); - this.on('editable:vertex:ctrlclick', function (e) { - var index = e.vertex.getIndex(); - if (index === 0 || index === e.vertex.getLastIndex() && e.vertex.continue) e.vertex.continue(); - }); - this.on('editable:vertex:altclick', function (e) { - if (e.vertex.editor.vertexCanBeDeleted(e.vertex)) e.vertex.delete(); - }); - this.on('editable:vertex:rawclick', this.onVertexRawClick); - }, + createPolyline: function (latlngs) { + return new L.U.Polyline(this.map, latlngs) + }, - createPolyline: function (latlngs) { - return new L.U.Polyline(this.map, latlngs); - }, + createPolygon: function (latlngs) { + var polygon = new L.U.Polygon(this.map, latlngs) + return polygon + }, - createPolygon: function (latlngs) { - var polygon = new L.U.Polygon(this.map, latlngs); - return polygon; - }, + createMarker: function (latlng) { + return new L.U.Marker(this.map, latlng) + }, - createMarker: function (latlng) { - return new L.U.Marker(this.map, latlng); - }, + connectCreatedToMap: function (layer) { + // Overrided from Leaflet.Editable + var datalayer = this.map.defaultDataLayer() + datalayer.addLayer(layer) + layer.isDirty = true + return layer + }, - connectCreatedToMap: function (layer) { - // Overrided from Leaflet.Editable - var datalayer = this.map.defaultDataLayer(); - datalayer.addLayer(layer); - layer.isDirty = true; - return layer; - }, - - drawingTooltip: function (e) { - if (e.layer instanceof L.Marker && e.type != "editable:drawing:move") { - this.map.ui.tooltip({content: L._('Click to add a marker')}); - } - if (!(e.layer instanceof L.Polyline)) { - // only continue with Polylines and Polygons - return; - } - - var content; - var measure; - if (e.layer.editor._drawnLatLngs) { - // when drawing (a Polyline or Polygon) - if (!e.layer.editor._drawnLatLngs.length) { - // when drawing first point - if (e.layer instanceof L.Polygon){ - content = L._('Click to start drawing a polygon'); - } else if (e.layer instanceof L.Polyline) { - content = L._('Click to start drawing a line'); - } - } else { - var tmpLatLngs = e.layer.editor._drawnLatLngs.slice(); - tmpLatLngs.push(e.latlng); - measure = e.layer.getMeasure(tmpLatLngs); - - if (e.layer.editor._drawnLatLngs.length < e.layer.editor.MIN_VERTEX) { - // when drawing second point - content = L._('Click to continue drawing'); - } else { - // when drawing third point (or more) - content = L._('Click last point to finish shape'); - } - } - } else { - // when moving an existing point - measure = e.layer.getMeasure(); - } - if (measure){ - if (e.layer instanceof L.Polygon){ - content += L._(' (area: {measure})', { measure: measure }); - } else if (e.layer instanceof L.Polyline) { - content += L._(' (length: {measure})', { measure: measure }); - } - } - if (content) { - this.map.ui.tooltip({content: content}); - } - }, - - closeTooltip: function () { - this.map.ui.closeTooltip(); - }, - - onVertexRawClick: function (e) { - e.layer.onVertexRawClick(e); - L.DomEvent.stop(e); - e.cancel(); + drawingTooltip: function (e) { + if (e.layer instanceof L.Marker && e.type != 'editable:drawing:move') { + this.map.ui.tooltip({ content: L._('Click to add a marker') }) + } + if (!(e.layer instanceof L.Polyline)) { + // only continue with Polylines and Polygons + return } -}); + var content + var measure + if (e.layer.editor._drawnLatLngs) { + // when drawing (a Polyline or Polygon) + if (!e.layer.editor._drawnLatLngs.length) { + // when drawing first point + if (e.layer instanceof L.Polygon) { + content = L._('Click to start drawing a polygon') + } else if (e.layer instanceof L.Polyline) { + content = L._('Click to start drawing a line') + } + } else { + var tmpLatLngs = e.layer.editor._drawnLatLngs.slice() + tmpLatLngs.push(e.latlng) + measure = e.layer.getMeasure(tmpLatLngs) + + if (e.layer.editor._drawnLatLngs.length < e.layer.editor.MIN_VERTEX) { + // when drawing second point + content = L._('Click to continue drawing') + } else { + // when drawing third point (or more) + content = L._('Click last point to finish shape') + } + } + } else { + // when moving an existing point + measure = e.layer.getMeasure() + } + if (measure) { + if (e.layer instanceof L.Polygon) { + content += L._(' (area: {measure})', { measure: measure }) + } else if (e.layer instanceof L.Polyline) { + content += L._(' (length: {measure})', { measure: measure }) + } + } + if (content) { + this.map.ui.tooltip({ content: content }) + } + }, + + closeTooltip: function () { + this.map.ui.closeTooltip() + }, + + onVertexRawClick: function (e) { + e.layer.onVertexRawClick(e) + L.DomEvent.stop(e) + e.cancel() + }, +}) diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index 614fce48..43f25d01 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -1,560 +1,632 @@ /* Poor man pub/sub handler, enough for now */ -L.UmapSingleton = L.Evented.extend({}); -L.U = new L.UmapSingleton(); -L.U.Map = L.Map.extend({}); +L.UmapSingleton = L.Evented.extend({}) +L.U = new L.UmapSingleton() +L.U.Map = L.Map.extend({}) /* -* Utils -*/ + * Utils + */ L.Util.queryString = function (name, fallback) { - var decode = function (s) { return decodeURIComponent(s.replace(/\+/g, ' ')); }; - var qs = window.location.search.slice(1).split('&'), qa = {}; - for (var i in qs) { - var key = qs[i].split('='); - if (!key) continue; - qa[decode(key[0])] = key[1] ? decode(key[1]) : 1; - } - return qa[name] || fallback; -}; + var decode = function (s) { + return decodeURIComponent(s.replace(/\+/g, ' ')) + } + var qs = window.location.search.slice(1).split('&'), + qa = {} + for (var i in qs) { + var key = qs[i].split('=') + if (!key) continue + qa[decode(key[0])] = key[1] ? decode(key[1]) : 1 + } + return qa[name] || fallback +} L.Util.booleanFromQueryString = function (name) { - var value = L.Util.queryString(name); - return value === '1' || value === 'true'; -}; + var value = L.Util.queryString(name) + return value === '1' || value === 'true' +} L.Util.setFromQueryString = function (options, name) { - var value = L.Util.queryString(name); - if (typeof value !== 'undefined') options[name] = value; -}; + var value = L.Util.queryString(name) + if (typeof value !== 'undefined') options[name] = value +} L.Util.setBooleanFromQueryString = function (options, name) { - var value = L.Util.queryString(name); - if (typeof value !== 'undefined') options[name] = value == '1' || value == 'true'; -}; + var value = L.Util.queryString(name) + if (typeof value !== 'undefined') options[name] = value == '1' || value == 'true' +} L.Util.setNullableBooleanFromQueryString = function (options, name) { - var value = L.Util.queryString(name); - if (typeof value !== 'undefined') { - if (value === 'null') value = null; - else if (value === '0' || value === 'false') value = false; - else value = true; - options[name] = value; - } -}; + var value = L.Util.queryString(name) + if (typeof value !== 'undefined') { + if (value === 'null') value = null + else if (value === '0' || value === 'false') value = false + else value = true + options[name] = value + } +} L.Util.escapeHTML = function (s) { - s = s? s.toString() : ''; - return s.replace(/$1') + r = r.replace(/^## (.*)/gm, '

$1

') + r = r.replace(/^# (.*)/gm, '

$1

') + r = r.replace(/^---/gm, '
') - // headings and hr - r = r.replace(/^### (.*)/gm, '
$1
'); - r = r.replace(/^## (.*)/gm, '

$1

'); - r = r.replace(/^# (.*)/gm, '

$1

'); - r = r.replace(/^---/gm, '
'); + // bold, italics + r = r.replace(/\*\*(.*?)\*\*/g, '$1') + r = r.replace(/\*(.*?)\*/g, '$1') - // bold, italics - r = r.replace(/\*\*(.*?)\*\*/g, '$1'); - r = r.replace(/\*(.*?)\*/g, '$1'); + // unordered lists + r = r.replace(/^\*\* (.*)/gm, '') + r = r.replace(/^\* (.*)/gm, '') + for (ii = 0; ii < 3; ii++) + r = r.replace(new RegExp('' + newline + '' + newline + '