diff --git a/build/scripts/release/geoportal-extensions-openlayers-3.4.2.tgz b/build/scripts/release/geoportal-extensions-openlayers-3.4.2.tgz new file mode 100644 index 000000000..7e6ebb553 Binary files /dev/null and b/build/scripts/release/geoportal-extensions-openlayers-3.4.2.tgz differ diff --git a/build/scripts/release/package-openlayers.json b/build/scripts/release/package-openlayers.json index efa4f432f..e55a664fd 100644 --- a/build/scripts/release/package-openlayers.json +++ b/build/scripts/release/package-openlayers.json @@ -1,8 +1,28 @@ { + "keywords" : [ + "geoportail", + "geoplateforme", + "plugin", + "javascript", + "OpenLayers" + ], + "version" : "3.4.2", "types" : "src/OpenLayers/index.d.ts", "license" : "CECILL-B", "date" : "17/04/2024", - "devDependencies" : {}, + "dependencies" : { + "loglevel" : "1.6.6", + "@mapbox/mapbox-gl-style-spec" : "13.20.1", + "node-fetch" : "^2.6.1", + "eventbusjs" : "0.2.0", + "proj4" : "2.7.5", + "ol" : "6.9.0", + "sortablejs" : "1.14.0", + "geoportal-access-lib" : "3.4.1", + "xmldom" : "^0.1.27" + }, + "bugs" : {}, + "scripts" : {}, "files" : [ "dist/", "src/", @@ -14,29 +34,9 @@ "type" : "git", "url" : "https://github.com/IGNF/geoportal-extensions.git" }, + "directories" : {}, "module" : "src/OpenLayers/index.js", "peerDependencies" : {}, - "dependencies" : { - "loglevel" : "1.6.6", - "ol" : "6.9.0", - "sortablejs" : "1.14.0", - "node-fetch" : "^2.6.1", - "xmldom" : "^0.1.27", - "@mapbox/mapbox-gl-style-spec" : "13.20.1", - "proj4" : "2.7.5", - "eventbusjs" : "0.2.0", - "geoportal-access-lib" : "3.4.1" - }, - "name" : "geoportal-extensions-openlayers", - "version" : "3.4.2", - "bugs" : {}, - "scripts" : {}, - "keywords" : [ - "geoportail", - "geoplateforme", - "plugin", - "javascript", - "OpenLayers" - ], - "directories" : {} + "devDependencies" : {}, + "name" : "geoportal-extensions-openlayers" } diff --git a/src/OpenLayers/Controls/Editor.js b/src/OpenLayers/Controls/Editor.js index 8d43b5f2a..f2d6f35b7 100644 --- a/src/OpenLayers/Controls/Editor.js +++ b/src/OpenLayers/Controls/Editor.js @@ -141,862 +141,860 @@ var logger = Logger.getLogger("editor"); * // possibility to add listeners with globale variable : eventbus * eventbus.addEventListener("editor:style:scale:onchangemin", function (e) {...}); */ -function Editor (options) { - logger.trace("[constructor] Editor", options); +class Editor { - // options - this.options = options || { - // TODO default... - }; + constructor (options) { + logger.trace("[constructor] Editor", options); - if (!(this instanceof Editor)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } + // options + this.options = options || { + // TODO default... + }; - this._initialize(); -}; + if (!(this instanceof Editor)) { + throw new TypeError("ERROR CLASS_CONSTRUCTOR"); + } -// on récupère les méthodes de la classe DOM -Utils.assign(Editor.prototype, EditorDOM); + this._initialize(); + } -/** - * Constructor (alias) - * - * @private - */ -Editor.prototype.constructor = Editor; + /** + * Initialize component + * (called by constructor) + * + * @private + */ + _initialize () { + // gestion des options + if (!this.options.target) { + logger.info("La 'target' n'est pas renseignée (options.target)."); + } -/** - * Initialize component - * (called by constructor) - * - * @private - */ -Editor.prototype._initialize = function () { - // gestion des options - if (!this.options.target) { - logger.info("La 'target' n'est pas renseignée (options.target)."); - } + if (!this.options.style) { + logger.error("Le 'style' MapBox n'est pas renseigné (options.style) !"); + return; + } - if (!this.options.style) { - logger.error("Le 'style' MapBox n'est pas renseigné (options.style) !"); - return; - } + if (this.options.events) { + this._initEvents(); + } else { + logger.warn("Les 'handlers' ne sont pas renseignés (options.events) !"); + } - if (this.options.events) { - this._initEvents(); - } else { - logger.warn("Les 'handlers' ne sont pas renseignés (options.events) !"); - } + if (!this.options.themes) { + logger.info("Les 'themes' MapBox ne sont pas renseignés (options.themes)."); + } - if (!this.options.themes) { - logger.info("Les 'themes' MapBox ne sont pas renseignés (options.themes)."); - } + // options par defaut + var _toolsDefault = { + themes : false, + layers : true, + search : false, + style : false, + filter : false, + legend : false, + group : false, + groupAuto : false, + sort : true, + sortBy : "id", + sortOrder : "asc", + title : true, + collapse : undefined, + type : true, + pin : true, + visibility : true, + icon : { + image : true, + anchor : "end" + }, + editable : true + }; + + if (!this.options.tools) { + logger.trace("Utilisation des outils MapBox par défaut (options.tools)."); + this.options.tools = _toolsDefault; + } - // options par defaut - var _toolsDefault = { - themes : false, - layers : true, - search : false, - style : false, - filter : false, - legend : false, - group : false, - groupAuto : false, - sort : true, - sortBy : "id", - sortOrder : "asc", - title : true, - collapse : undefined, - type : true, - pin : true, - visibility : true, - icon : { - image : true, - anchor : "end" - }, - editable : true - }; - - if (!this.options.tools) { - logger.trace("Utilisation des outils MapBox par défaut (options.tools)."); - this.options.tools = _toolsDefault; + Utils.mergeParams(this.options.tools, _toolsDefault, false); + + // id unique + this.id = this.options.id || ID.generate(); + + // context + this.context = {}; + // property layers + this.layers = []; + // dom container + this.container = null; + // dom name + this.name = { + target : "GPEditorMapBoxTarget", + container : "GPEditorMapBoxContainer", + containerID : "GPEditorMapBoxContainer_ID_", + containerLayers : "GPEditorMapBoxLayersContainer", + titleLayers : "GPEditorMapBoxLayersTitle", + titleLayersID : "GPEditorMapBoxLayersTitle_ID_", + titleThemes : "GPEditorMapBoxThemesTitle", + titleThemesID : "GPEditorMapBoxThemesTitle_ID_", + sep : "GPEditorMapBoxSep" + }; + // style json + this.mapbox = {}; + // INFO + // sprites : + // { + // url : null, + // size : { + // h : null, + // w : null + // }, + // json : {} + // } + this.sprites = {}; } - Utils.mergeParams(this.options.tools, _toolsDefault, false); - - // id unique - this.id = this.options.id || ID.generate(); - - // context - this.context = {}; - // property layers - this.layers = []; - // dom container - this.container = null; - // dom name - this.name = { - target : "GPEditorMapBoxTarget", - container : "GPEditorMapBoxContainer", - containerID : "GPEditorMapBoxContainer_ID_", - containerLayers : "GPEditorMapBoxLayersContainer", - titleLayers : "GPEditorMapBoxLayersTitle", - titleLayersID : "GPEditorMapBoxLayersTitle_ID_", - titleThemes : "GPEditorMapBoxThemesTitle", - titleThemesID : "GPEditorMapBoxThemesTitle_ID_", - sep : "GPEditorMapBoxSep" - }; - // style json - this.mapbox = {}; - // INFO - // sprites : - // { - // url : null, - // size : { - // h : null, - // w : null - // }, - // json : {} - // } - this.sprites = {}; -}; - -/** -* Initialize events with handlers -* (called by constructor) -* -* List Events : -* "editor:layer:visibility" -* "editor:layer:clone" -* "editor:layer:remove" -* "editor:style:edit" -* "editor:style:minScale" -* "editor:style:maxScale" -* "editor:filter:edit" -* "editor:themes:image", -* "editor:themes:title" -* @private -*/ -Editor.prototype._initEvents = function () { - var ctx = this.options.scope || this; - var events = this.options.events; - if (events) { - for (var event in events) { - if (events.hasOwnProperty(event)) { - var handler = events[event]; - // test sur les events disponibles ! - if (handler) { - if (!EventBus.hasEventListener(event, handler, ctx)) { - EventBus.addEventListener(event, handler, ctx); + /** + * Initialize events with handlers + * (called by constructor) + * + * List Events : + * "editor:layer:visibility" + * "editor:layer:clone" + * "editor:layer:remove" + * "editor:style:edit" + * "editor:style:minScale" + * "editor:style:maxScale" + * "editor:filter:edit" + * "editor:themes:image", + * "editor:themes:title" + * @private + */ + _initEvents () { + var ctx = this.options.scope || this; + var events = this.options.events; + if (events) { + for (var event in events) { + if (events.hasOwnProperty(event)) { + var handler = events[event]; + // test sur les events disponibles ! + if (handler) { + if (!EventBus.hasEventListener(event, handler, ctx)) { + EventBus.addEventListener(event, handler, ctx); + } } } } } } -}; -/** - * Graphical rendering of the component - * (called by constructor) - * - * @example - *
- *
Liste des 'thèmes'
- *
- * ... - *
- *
Liste des 'couches'
- *
- *
- *
- * - * - * - *
- *
- *
...
- *
...
- *
- *
- * @private - */ -Editor.prototype._initContainer = function () { - logger.trace(this.mapbox); - - // existance d'un autre container (editeur) ? - // var _idx = 0; - // var elements = document.querySelectorAll("div[id^=" + this.name.containerID + "]"); - // for (var j = 0; j < elements.length; j++) { - // var element = elements[j]; - // var num = parseInt(element.id.substring(element.id.lastIndexOf("_") + 1), 10); - // if (num > _idx) { - // _idx = num; - // } - // } - // if (elements.length) { - // _idx += 1; - // } - - // container principal de l'editeur - var div = document.createElement("div"); - div.id = this.name.containerID + this.id; - div.className = this.name.container; - - // Themes - var _toolsThemes = this.options.tools.themes; - if (_toolsThemes && this.options.themes) { - // title - if (this.options.tools.title) { - var titleThemes = document.createElement("div"); - titleThemes.id = this.name.titleThemesID + this.id; - titleThemes.className = this.name.titleThemes; - titleThemes.innerHTML = "Liste des 'thèmes'"; - div.appendChild(titleThemes); - } + /** + * Graphical rendering of the component + * (called by constructor) + * + * @example + *
+ *
Liste des 'thèmes'
+ *
+ * ... + *
+ *
Liste des 'couches'
+ *
+ *
+ *
+ * + * + * + *
+ *
+ *
...
+ *
...
+ *
+ *
+ * @private + */ + _initContainer () { + logger.trace(this.mapbox); + + // existance d'un autre container (editeur) ? + // var _idx = 0; + // var elements = document.querySelectorAll("div[id^=" + this.name.containerID + "]"); + // for (var j = 0; j < elements.length; j++) { + // var element = elements[j]; + // var num = parseInt(element.id.substring(element.id.lastIndexOf("_") + 1), 10); + // if (num > _idx) { + // _idx = num; + // } + // } + // if (elements.length) { + // _idx += 1; + // } + // container principal de l'editeur + var div = document.createElement("div"); + div.id = this.name.containerID + this.id; + div.className = this.name.container; + + // Themes + var _toolsThemes = this.options.tools.themes; + if (_toolsThemes && this.options.themes) { + // title + if (this.options.tools.title) { + var titleThemes = document.createElement("div"); + titleThemes.id = this.name.titleThemesID + this.id; + titleThemes.className = this.name.titleThemes; + titleThemes.innerHTML = "Liste des 'thèmes'"; + div.appendChild(titleThemes); + } - // lien vers les styles - var themes = new Themes({ - id : this.id, - target : div, - tools : (typeof _toolsThemes === "object") ? _toolsThemes : {}, - obj : this.options.themes - }); - themes.add(); - } + // lien vers les styles + var themes = new Themes({ + id : this.id, + target : div, + tools : (typeof _toolsThemes === "object") ? _toolsThemes : {}, + obj : this.options.themes + }); + themes.add(); + } - // TODO : Recheche / filtre de couches - if (this.options.tools.search) { - var search = new Search({ - id : this.id, - target : div, - tools : {}, - obj : this.mapbox.layers // liste des objets layers - }); - search.add(); - } + // TODO : Recheche / filtre de couches + if (this.options.tools.search) { + var search = new Search({ + id : this.id, + target : div, + tools : {}, + obj : this.mapbox.layers // liste des objets layers + }); + search.add(); + } - for (var source in this.mapbox.sources) { - if (this.mapbox.sources.hasOwnProperty(source)) { - if (this.options.tools.layers) { - // multisources ? Si oui, on renseigne un titre... - var multisources = (Object.keys(this.mapbox.sources).length > 1) ? 1 : 0; - if (multisources) { - var hr = document.createElement("hr"); - hr.className = this.name.sep; - div.appendChild(hr); - } - // title - if (this.options.tools.title) { - var titleLayers = document.createElement("div"); - titleLayers.id = this.name.titleLayersID + this.id; - titleLayers.className = this.name.titleLayers; - titleLayers.innerHTML = (multisources) ? "Liste des 'couches' (" + source + ")" : "Liste des 'couches'"; - div.appendChild(titleLayers); + for (var source in this.mapbox.sources) { + if (this.mapbox.sources.hasOwnProperty(source)) { + if (this.options.tools.layers) { + // multisources ? Si oui, on renseigne un titre... + var multisources = (Object.keys(this.mapbox.sources).length > 1) ? 1 : 0; + if (multisources) { + var hr = document.createElement("hr"); + hr.className = this.name.sep; + div.appendChild(hr); + } + // title + if (this.options.tools.title) { + var titleLayers = document.createElement("div"); + titleLayers.id = this.name.titleLayersID + this.id; + titleLayers.className = this.name.titleLayers; + titleLayers.innerHTML = (multisources) ? "Liste des 'couches' (" + source + ")" : "Liste des 'couches'"; + div.appendChild(titleLayers); + } } - } - // gestion de l'ordre avant tri avec la metadata 'order' - var _layers = this.mapbox.layers.slice(); // clone - // une fois les layers triés, la metadata:geoportail:order permet - // de savoir l'emplacement du layers dans le fichier de style. - _layers.forEach(function (layer, order) { - // on écarte les layers sans source: ex. "background" - // if (!layer.source) { - // return; - // } - // ajout de la metadata d'ordre - var _metadata = layer["metadata"]; - if (_metadata) { - _metadata["geoportail:order"] = order; - } else { - layer["metadata"] = { - "geoportail:order" : order + // gestion de l'ordre avant tri avec la metadata 'order' + var _layers = this.mapbox.layers.slice(); // clone + + // une fois les layers triés, la metadata:geoportail:order permet + // de savoir l'emplacement du layers dans le fichier de style. + _layers.forEach(function (layer, order) { + // on écarte les layers sans source: ex. "background" + // if (!layer.source) { + // return; + // } + // ajout de la metadata d'ordre + var _metadata = layer["metadata"]; + if (_metadata) { + _metadata["geoportail:order"] = order; + } else { + layer["metadata"] = { + "geoportail:order" : order + }; + } + }); + // tri des layers + if (this.options.tools.sort) { + var sortBy = this.options.tools.sortBy; + var sortOrder = this.options.tools.sortOrder; + var sortFct = function (a, b) { + // si on utilise les groupements utilisateurs, ils doivent + // tous être renseignés sinon..., ça va coincer ! + var result = 0; + if (a["metadata"] && + a["metadata"]["geoportail:group"] && + b["metadata"] && + b["metadata"]["geoportail:group"]) { + var cmpA = null; + var cmpB = null; + cmpA = a["metadata"]["geoportail:group"]; + cmpB = b["metadata"]["geoportail:group"]; + result = cmpA.localeCompare(cmpB); + } else { + switch (sortBy) { + case "geom": + result = sortOrder === "asc" ? a.type.localeCompare(b.type) || a.id.localeCompare(b.id) + : b.type.localeCompare(a.type) || b.id.localeCompare(a.id); + break; + case "class": + result = sortOrder === "asc" ? a["source-layer"].localeCompare(b["source-layer"]) || a.id.localeCompare(b.id) + : b["source-layer"].localeCompare(a["source-layer"]) || b.id.localeCompare(a.id); + break; + case "id": + default: + // tri sur l'id par defaut + result = sortOrder === "asc" ? a.id.localeCompare(b.id) : b.id.localeCompare(a.id); + break; + } + } + return result; }; + + _layers.sort(sortFct); } - }); - // tri des layers - if (this.options.tools.sort) { - var sortBy = this.options.tools.sortBy; - var sortOrder = this.options.tools.sortOrder; - var sortFct = function (a, b) { - // si on utilise les groupements utilisateurs, ils doivent - // tous être renseignés sinon..., ça va coincer ! - var result = 0; - if (a["metadata"] && - a["metadata"]["geoportail:group"] && - b["metadata"] && - b["metadata"]["geoportail:group"]) { - var cmpA = null; - var cmpB = null; - cmpA = a["metadata"]["geoportail:group"]; - cmpB = b["metadata"]["geoportail:group"]; - result = cmpA.localeCompare(cmpB); + + logger.trace("Layers : ", _layers); + + // gestion des groupes avec la metadata de groupe + var groupBy = this.options.tools.sortBy; // le même type de tri que les couches ! + var groupAuto = this.options.tools.groupAuto; + var _groups = {}; // liste et comptage des layers dans chaque groupes + _layers.forEach(function (layer) { + // on écarte les layers sans source: ex. "background" + // if (!layer.source) { + // return; + // } + // balise metadata + var _metadata = layer["metadata"]; + // s'il existe déjà une meta de groupe, on l'utilise... + // sinon, on la met en place. + if (_metadata && _metadata["geoportail:group"]) { + var _groupName = _metadata["geoportail:group"]; + _groups[_groupName] = (_groups[_groupName]) + ? _groups[_groupName] + 1 : 1; } else { - switch (sortBy) { - case "geom": - result = sortOrder === "asc" ? a.type.localeCompare(b.type) || a.id.localeCompare(b.id) - : b.type.localeCompare(a.type) || b.id.localeCompare(a.id); - break; + var _field = null; + switch (groupBy) { case "class": - result = sortOrder === "asc" ? a["source-layer"].localeCompare(b["source-layer"]) || a.id.localeCompare(b.id) - : b["source-layer"].localeCompare(a["source-layer"]) || b.id.localeCompare(a.id); + _field = layer["source-layer"]; + break; + case "geom": + _field = layer.type; break; case "id": default: - // tri sur l'id par defaut - result = sortOrder === "asc" ? a.id.localeCompare(b.id) : b.id.localeCompare(a.id); + _field = layer.id; break; } - } - return result; - }; - - _layers.sort(sortFct); - } - - logger.trace("Layers : ", _layers); - - // gestion des groupes avec la metadata de groupe - var groupBy = this.options.tools.sortBy; // le même type de tri que les couches ! - var groupAuto = this.options.tools.groupAuto; - var _groups = {}; // liste et comptage des layers dans chaque groupes - _layers.forEach(function (layer) { - // on écarte les layers sans source: ex. "background" - // if (!layer.source) { - // return; - // } - // balise metadata - var _metadata = layer["metadata"]; - // s'il existe déjà une meta de groupe, on l'utilise... - // sinon, on la met en place. - if (_metadata && _metadata["geoportail:group"]) { - var _groupName = _metadata["geoportail:group"]; - _groups[_groupName] = (_groups[_groupName]) - ? _groups[_groupName] + 1 : 1; - } else { - var _field = null; - switch (groupBy) { - case "class": - _field = layer["source-layer"]; - break; - case "geom": - _field = layer.type; - break; - case "id": - default: - _field = layer.id; - break; - } - var _newGroupName = _field; - if (groupAuto) { - // separateur - var _regex = /_|-|:|=/; // TODO à definir via une option ! - // index - var _idx = _field.search(_regex); - // y'a t il un separateur ? - _newGroupName = (_idx !== -1) ? _field.substring(0, _idx).trim() : _field; - } - // on compte le nombre d'entrée dans un groupe - _groups[_newGroupName] = (_groups[_newGroupName]) - ? _groups[_newGroupName] + 1 : 1; + var _newGroupName = _field; + if (groupAuto) { + // separateur + var _regex = /_|-|:|=/; // TODO à definir via une option ! + + // index + var _idx = _field.search(_regex); + // y'a t il un separateur ? + _newGroupName = (_idx !== -1) ? _field.substring(0, _idx).trim() : _field; + } + // on compte le nombre d'entrée dans un groupe + _groups[_newGroupName] = (_groups[_newGroupName]) + ? _groups[_newGroupName] + 1 : 1; - // ajout de la metadata de groupe - if (_metadata) { - _metadata["geoportail:group"] = _newGroupName; - } else { - layer["metadata"] = { - "geoportail:group" : _newGroupName - }; + // ajout de la metadata de groupe + if (_metadata) { + _metadata["geoportail:group"] = _newGroupName; + } else { + layer["metadata"] = { + "geoportail:group" : _newGroupName + }; + } } - } - }); + }); - logger.trace("Groups : ", _groups); + logger.trace("Groups : ", _groups); - // container principal des couches - var divLayers = document.createElement("div"); - divLayers.className = this.name.containerLayers; - div.appendChild(divLayers); + // container principal des couches + var divLayers = document.createElement("div"); + divLayers.className = this.name.containerLayers; + div.appendChild(divLayers); - var details; - if (this.options.tools.collapse !== undefined) { - details = document.createElement("details"); - details.className = ""; - details.open = !this.options.tools.collapse; - divLayers.appendChild(details); + var details; + if (this.options.tools.collapse !== undefined) { + details = document.createElement("details"); + details.className = ""; + details.open = !this.options.tools.collapse; + divLayers.appendChild(details); - var summary = document.createElement("summary"); - summary.className = ""; - summary.innerHTML = ""; - details.appendChild(summary); - } + var summary = document.createElement("summary"); + summary.className = ""; + summary.innerHTML = ""; + details.appendChild(summary); + } - // container courant (cf. groupe) pour l'ajout des elements - var target = (this.options.tools.collapse !== undefined) ? details : divLayers; - - // Ex. Layers, Styles, Groups et Filtres - // "id": "ocs - vegetation", - // "type": "fill", - // "source": "pyramide_proto", - // "source-layer": "ocs_vegetation_surf", - // "metadata" : { - // "geoportail:group": "ocs" - // }, - // "layout": { - // "visibility": "visible" - // }, - // "filter": ["in","symbo", - // "SURFACE_D_EAU", - // "BASSIN", - // "ZONE_MARINE" - // ], - // "paint": { - // "fill-color": "#2BB3E1" - // } - var index = -1; - for (var ii = 0; ii < _layers.length; ii++) { - var data = _layers[ii]; - index++; - - // traitement dans l'ordre des sources - if (data.source === source) { - // Groups - // INFO la gestion des groupes est basée sur la balise metadata::geoportail:group - // ainsi que sur l'ordre des couches. - // il n'y a pas de regroupement sans tri des couches ! - if (this.options.tools.group && this.options.tools.sort) { - var mtd = data.metadata; - // creation du container de groupe - // si le tag metadata existe - if (mtd) { - var grp = data.metadata["geoportail:group"]; - if (grp) { - // le groupe doit contenir plus d'un element - if (_groups[grp] > 1) { - // le groupe est déjà créé, on en veut plus par la suite... - _groups[grp] = -1; - // creation du groupe - var oGroup = new Group({ - id : this.id, - target : (this.options.tools.collapse !== undefined) ? details : divLayers, - title : grp, - collapse : true - }); - oGroup.add(); - // le nouveau container pour les elements suivants - target = oGroup.getContainer(); - } else if (_groups[grp] === 1) { - // l'element est seul, donc pas d'ajout dans le - // groupe en cours - target = (this.options.tools.collapse !== undefined) ? details : divLayers; + // container courant (cf. groupe) pour l'ajout des elements + var target = (this.options.tools.collapse !== undefined) ? details : divLayers; + + // Ex. Layers, Styles, Groups et Filtres + // "id": "ocs - vegetation", + // "type": "fill", + // "source": "pyramide_proto", + // "source-layer": "ocs_vegetation_surf", + // "metadata" : { + // "geoportail:group": "ocs" + // }, + // "layout": { + // "visibility": "visible" + // }, + // "filter": ["in","symbo", + // "SURFACE_D_EAU", + // "BASSIN", + // "ZONE_MARINE" + // ], + // "paint": { + // "fill-color": "#2BB3E1" + // } + var index = -1; + for (var ii = 0; ii < _layers.length; ii++) { + var data = _layers[ii]; + index++; + + // traitement dans l'ordre des sources + if (data.source === source) { + // Groups + // INFO la gestion des groupes est basée sur la balise metadata::geoportail:group + // ainsi que sur l'ordre des couches. + // il n'y a pas de regroupement sans tri des couches ! + if (this.options.tools.group && this.options.tools.sort) { + var mtd = data.metadata; + // creation du container de groupe + // si le tag metadata existe + if (mtd) { + var grp = data.metadata["geoportail:group"]; + if (grp) { + // le groupe doit contenir plus d'un element + if (_groups[grp] > 1) { + // le groupe est déjà créé, on en veut plus par la suite... + _groups[grp] = -1; + // creation du groupe + var oGroup = new Group({ + id : this.id, + target : (this.options.tools.collapse !== undefined) ? details : divLayers, + title : grp, + collapse : true + }); + oGroup.add(); + // le nouveau container pour les elements suivants + target = oGroup.getContainer(); + } else if (_groups[grp] === 1) { + // l'element est seul, donc pas d'ajout dans le + // groupe en cours + target = (this.options.tools.collapse !== undefined) ? details : divLayers; + } else { + // on ajoute l'element dans le groupe courant... + } } else { - // on ajoute l'element dans le groupe courant... + target = (this.options.tools.collapse !== undefined) ? details : divLayers; } } else { target = (this.options.tools.collapse !== undefined) ? details : divLayers; } - } else { - target = (this.options.tools.collapse !== undefined) ? details : divLayers; } - } - // Layers - if (this.options.tools.layers) { - var oLayer = new Layer({ - id : this.id, - target : target, - position : index + "_" + this.id, // unique ! - tools : { - visibility : this.options.tools.visibility, - icon : this.options.tools.icon, - type : this.options.tools.type, - pin : this.options.tools.pin - }, - obj : { - id : data.id, - type : data.type, - source : data.source, - "source-layer" : data["source-layer"] + // Layers + if (this.options.tools.layers) { + var oLayer = new Layer({ + id : this.id, + target : target, + position : index + "_" + this.id, // unique ! + tools : { + visibility : this.options.tools.visibility, + icon : this.options.tools.icon, + type : this.options.tools.type, + pin : this.options.tools.pin + }, + obj : { + id : data.id, + type : data.type, + source : data.source, + "source-layer" : data["source-layer"] + } + }); + oLayer.add(); + // update visibility layer + if (data.layout && data.layout.visibility && data.layout.visibility === "none") { + oLayer.visibility(false); } - }); - oLayer.add(); - // update visibility layer - if (data.layout && data.layout.visibility && data.layout.visibility === "none") { - oLayer.visibility(false); + // sauvegarde des layers + this.layers.push(oLayer); } - // sauvegarde des layers - this.layers.push(oLayer); - } - // Legende - if (this.options.tools.legend) { - // gestion de l'edition de la legende : - // l'option "editable" est prioritaire sur le tag "editable" du fichier de style ! - var isEditable = this.options.tools.editable; - if (typeof isEditable === "undefined") { - isEditable = data.editable; - } - var oLegend = new Legend({ - id : this.id, - target : target, - sprites : this.sprites, - obj : { - id : data.id, - source : data.source, - title : data.id, - editable : (typeof isEditable !== "undefined") ? isEditable : false, - paint : data.paint, - layout : data.layout + // Legende + if (this.options.tools.legend) { + // gestion de l'edition de la legende : + // l'option "editable" est prioritaire sur le tag "editable" du fichier de style ! + var isEditable = this.options.tools.editable; + if (typeof isEditable === "undefined") { + isEditable = data.editable; } - }); - oLegend.add(); - oLegend.display(false); - if (oLayer) { - oLayer.addLegend(oLegend); - oLayer.slotLegend(); // integration de la legende dans le container du layers ! - } - } - // Style - if (this.options.tools.style) { - var oStyle = new Style({ - id : this.id, - target : target, - position : index + "_" + this.id, // unique !, - obj : { - id : data.id, - source : data.source, - layout : data.layout, - paint : data.paint + var oLegend = new Legend({ + id : this.id, + target : target, + sprites : this.sprites, + obj : { + id : data.id, + source : data.source, + title : data.id, + editable : (typeof isEditable !== "undefined") ? isEditable : false, + paint : data.paint, + layout : data.layout + } + }); + oLegend.add(); + oLegend.display(false); + if (oLayer) { + oLayer.addLegend(oLegend); + oLayer.slotLegend(); // integration de la legende dans le container du layers ! } - }); - oStyle.add(); - oStyle.display(false); - if (oLayer) { - oLayer.addStyle(oStyle); } - // update visibility layer - if (data.layout && data.layout.visibility && data.layout.visibility === "none") { - oLayer.visibility(false); + // Style + if (this.options.tools.style) { + var oStyle = new Style({ + id : this.id, + target : target, + position : index + "_" + this.id, // unique !, + obj : { + id : data.id, + source : data.source, + layout : data.layout, + paint : data.paint + } + }); + oStyle.add(); + oStyle.display(false); + if (oLayer) { + oLayer.addStyle(oStyle); + } + // update visibility layer + if (data.layout && data.layout.visibility && data.layout.visibility === "none") { + oLayer.visibility(false); + } } - } - // Filter - if (this.options.tools.filter) { - var oFilter = new Filter({ - id : this.id, - target : target, - position : index + "_" + this.id, // unique !, - obj : { - id : data.id, - source : data.source, - filter : data.Filter + // Filter + if (this.options.tools.filter) { + var oFilter = new Filter({ + id : this.id, + target : target, + position : index + "_" + this.id, // unique !, + obj : { + id : data.id, + source : data.source, + filter : data.Filter + } + }); + oFilter.add(); + oFilter.display(false); + if (oLayer) { + oLayer.addFilter(oFilter); } - }); - oFilter.add(); - oFilter.display(false); - if (oLayer) { - oLayer.addFilter(oFilter); } - } - } else { - // on ecarte un layer car il n'est pas reconnu dans la source - // on decremente la position du layer - if (index >= 0) { - index--; + } else { + // on ecarte un layer car il n'est pas reconnu dans la source + // on decremente la position du layer + if (index >= 0) { + index--; + } } } } } - } - // sauvegarde - this.container = div; - - // container principal - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var _target = document.createElement("div"); - _target.id = this.name.target; - var node = document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0] || - document.documentElement; - node.appendChild(_target); + // sauvegarde + this.container = div; + + // container principal + if (!this.options.target) { + if (!document.getElementById(this.name.target)) { + var _target = document.createElement("div"); + _target.id = this.name.target; + var node = document.getElementsByTagName("body")[0] || + document.getElementsByTagName("head")[0] || + document.documentElement; + node.appendChild(_target); + } + this.options.target = document.getElementById(this.name.target); } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); + if (this.container) { + this.options.target.appendChild(this.container); + } + // dispatch event + EventBus.dispatch(Event.onloaded, this); } - // dispatch event - EventBus.dispatch(Event.onloaded, this); -}; -/** - * Getting Sprites informations - * (called by _initialize) - * - * @param {String} sprites - url des sprites - * @returns {Promise} - promise - * @private - */ -Editor.prototype._getSprites = function (sprites) { - var self = this; - - // on ne doit pas mettre de promise en échec... - // car on souhaite continuer le traitement même si on n'a pas de sprites ! - - // si le protocole est mapbox:// - if (sprites && sprites.startsWith("mapbox://")) { - return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars - logger.error("Protocole mapbox:// non géré !"); - resolve(self); - }); - } - // si pas de sprites - if (!sprites) { - return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars - logger.error("Auncun sprites disponibles !"); - resolve(self); - }); - } + /** + * Getting Sprites informations + * (called by _initialize) + * + * @param {String} sprites - url des sprites + * @returns {Promise} - promise + * @private + */ + _getSprites (sprites) { + var self = this; + + // on ne doit pas mettre de promise en échec... + // car on souhaite continuer le traitement même si on n'a pas de sprites ! + // si le protocole est mapbox:// + if (sprites && sprites.startsWith("mapbox://")) { + return new Promise((resolve, reject) => { + logger.error("Protocole mapbox:// non géré !"); + resolve(self); + }); + } + // si pas de sprites + if (!sprites) { + return new Promise((resolve, reject) => { + logger.error("Auncun sprites disponibles !"); + resolve(self); + }); + } - var fetchSpritesImage = function () { - var spritesImage = sprites + ".png"; - return fetch(spritesImage, { - credentials : "same-origin" - }) - .then(function (response) { - if (response.ok) { - return response.blob() - .then(function (blob) { - self.sprites.url = spritesImage; - // decode de l'image - var theImage = new Image(); - theImage.src = spritesImage; - return theImage.decode() - .then(function () { - self.sprites.size = {}; - self.sprites.size.h = theImage.height; - self.sprites.size.w = theImage.width; - }); - }) - .catch(error => { - logger.warn("fetch image sprites exception :", error); - }); - } else { - var err = new Error("HTTP status code: " + response.status); - throw err; - } + var fetchSpritesImage = function () { + var spritesImage = sprites + ".png"; + return fetch(spritesImage, { + credentials : "same-origin" }) - .catch(error => { - return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars - logger.error("fetch image sprites exception :", error); - reject(error); + .then(function (response) { + if (response.ok) { + return response.blob() + .then(function (blob) { + self.sprites.url = spritesImage; + // decode de l'image + var theImage = new Image(); + theImage.src = spritesImage; + return theImage.decode() + .then(function () { + self.sprites.size = {}; + self.sprites.size.h = theImage.height; + self.sprites.size.w = theImage.width; + }); + }) + .catch(error => { + logger.warn("fetch image sprites exception :", error); + }); + } else { + var err = new Error("HTTP status code: " + response.status); + throw err; + } + }) + .catch(error => { + return new Promise((resolve, reject) => { + logger.error("fetch image sprites exception :", error); + reject(error); + }); }); - }); - }; - var fetchSpritesJson = function () { - var spritesJson = sprites + ".json"; - return fetch(spritesJson, { - credentials : "same-origin" - }) - .then(function (response) { - if (response.ok) { - return response.json() - .then(function (json) { - self.sprites.json = json; - }) - .catch(error => { - logger.warn("fetch json sprites exception :", error); - }); - } else { - var err = new Error("HTTP status code: " + response.status); - throw err; - } + }; + var fetchSpritesJson = function () { + var spritesJson = sprites + ".json"; + return fetch(spritesJson, { + credentials : "same-origin" }) - .catch(error => { - return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars - logger.error("fetch json sprites exception :", error); - reject(error); - }); - }); - }; - - // promise - return Promise.all([ - fetchSpritesImage(), - fetchSpritesJson() - ]); -}; - -// ################################################################### // -// ########################## INTERFACE ############################## // -// ################################################################### // -/** - * Create Editor - * - * @returns {Promise} - promise - */ -Editor.prototype.createElement = function () { - var self = this; - // objet json - if (typeof this.options.style === "object") { - this.mapbox = this.options.style; - // les sprites sont utiles que si on veut une legende ! - if (this.options.tools.legend) { - return this._getSprites(this.mapbox.sprite) - .then(function () { - // init du DOM - self._initContainer(); - return self; + .then(function (response) { + if (response.ok) { + return response.json() + .then(function (json) { + self.sprites.json = json; + }) + .catch(error => { + logger.warn("fetch json sprites exception :", error); + }); + } else { + var err = new Error("HTTP status code: " + response.status); + throw err; + } }) .catch(error => { - logger.warn("fetch sprites exception :", error); + return new Promise((resolve, reject) => { + logger.error("fetch json sprites exception :", error); + reject(error); + }); }); - } else { - return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars - self._initContainer(); - resolve(self); - }); - } + }; + + // promise + return Promise.all([ + fetchSpritesImage(), + fetchSpritesJson() + ]); } - // url - if (typeof this.options.style === "string") { - return fetch(this.options.style, { - credentials : "same-origin" - }) - .then(response => { - // sauvegarde du json - return response.json() - .then(style => { - self.mapbox = style; - }) + // ################################################################### // + // ########################## INTERFACE ############################## // + // ################################################################### // + /** + * Create Editor + * + * @returns {Promise} - promise + */ + createElement () { + var self = this; + // objet json + if (typeof this.options.style === "object") { + this.mapbox = this.options.style; + // les sprites sont utiles que si on veut une legende ! + if (this.options.tools.legend) { + return this._getSprites(this.mapbox.sprite) .then(function () { - // les sprites sont utiles que si on veut une legende ! - if (self.options.tools.legend) { - return self._getSprites(self.mapbox.sprite) - .then(function () { - // init du DOM - self._initContainer(); - return self; - }) - .catch(error => { - logger.warn("fetch sprites exception :", error); - }); - } else { - return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars - self._initContainer(); - resolve(self); - }); - } + // init du DOM + self._initContainer(); + return self; }) .catch(error => { - logger.error("json exception :", error); + logger.warn("fetch sprites exception :", error); }); + } else { + return new Promise((resolve, reject) => { + self._initContainer(); + resolve(self); + }); + } + } + + // url + if (typeof this.options.style === "string") { + return fetch(this.options.style, { + credentials : "same-origin" }) - .catch(error => { - logger.error("fetch exception :", error); - }); + .then(response => { + // sauvegarde du json + return response.json() + .then(style => { + self.mapbox = style; + }) + .then(function () { + // les sprites sont utiles que si on veut une legende ! + if (self.options.tools.legend) { + return self._getSprites(self.mapbox.sprite) + .then(function () { + // init du DOM + self._initContainer(); + return self; + }) + .catch(error => { + logger.warn("fetch sprites exception :", error); + }); + } else { + return new Promise((resolve, reject) => { + self._initContainer(); + resolve(self); + }); + } + }) + .catch(error => { + logger.error("json exception :", error); + }); + }) + .catch(error => { + logger.error("fetch exception :", error); + }); + } } -}; -/** - * Set display container (DOM) - * - * @param {Boolean} display - show/hidden container - */ -Editor.prototype.display = function (display) { - this.container.style.display = (display) ? "block" : "none"; -}; + /** + * Set display container (DOM) + * + * @param {Boolean} display - show/hidden container + */ + display (display) { + this.container.style.display = (display) ? "block" : "none"; + } -Editor.prototype.setContext = function (key, value) { - this.context[key] = value; -}; + setContext (key, value) { + this.context[key] = value; + } -Editor.prototype.getContext = function (key) { - return this.context[key]; -}; -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // + getContext (key) { + return this.context[key]; + } -/** - * Get id editor - * @returns {Number} id - */ -Editor.prototype.getID = function () { - return this.id; -}; + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Get id editor + * @returns {Number} id + */ + getID () { + return this.id; + } -/** - * Get container (DOM) - * @returns {DOMElement} DOM element - */ -Editor.prototype.getContainer = function () { - return this.container; -}; + /** + * Get container (DOM) + * @returns {DOMElement} DOM element + */ + getContainer () { + return this.container; + } -/** - * Get Style (json) - * @returns {Object} Style MapBox - */ -Editor.prototype.getStyle = function () { - return this.mapbox; -}; + /** + * Get Style (json) + * @returns {Object} Style MapBox + */ + getStyle () { + return this.mapbox; + } -/** - * Get layer style (json) - * @param {Number} i - index - * @returns {Object} Style MapBox of a layers - */ -Editor.prototype.getStyleLayer = function (i) { - var layer = null; - var o = this.getLayer(i); - var id = o.options.obj.id; - for (var k = 0; k < this.mapbox.layers.length; k++) { - var l = this.mapbox.layers[k]; - if (l.id === id) { - layer = l; - break; + /** + * Get layer style (json) + * @param {Number} i - index + * @returns {Object} Style MapBox of a layers + */ + getStyleLayer (i) { + var layer = null; + var o = this.getLayer(i); + var id = o.options.obj.id; + for (var k = 0; k < this.mapbox.layers.length; k++) { + var l = this.mapbox.layers[k]; + if (l.id === id) { + layer = l; + break; + } } + return layer; } - return layer; -}; -/** - * Get layer object from json style - * @param {Number} i - index into style json - * @returns {Object} Style MapBox of a layers - */ -Editor.prototype.getLayerFromStyle = function (i) { - var layer = null; - var l = this.mapbox.layers[i]; - for (var k = 0; k < this.getLayers().length; k++) { - var o = this.getLayer(k); - if (l.id === o.options.obj.id) { - layer = o; - break; + /** + * Get layer object from json style + * @param {Number} i - index into style json + * @returns {Object} Style MapBox of a layers + */ + getLayerFromStyle (i) { + var layer = null; + var l = this.mapbox.layers[i]; + for (var k = 0; k < this.getLayers().length; k++) { + var o = this.getLayer(k); + if (l.id === o.options.obj.id) { + layer = o; + break; + } } + return layer; } - return layer; -}; -/** - * Get a list of layer object sorted or not (see options.tools.sort) - * @returns {Array} - List of layer object - * @see {ol.style.editor.Layer} - */ -Editor.prototype.getLayers = function () { - return this.layers; -}; + /** + * Get a list of layer object sorted or not (see options.tools.sort) + * @returns {Array} - List of layer object + * @see {ol.style.editor.Layer} + */ + getLayers () { + return this.layers; + } + + /** + * Get the layer object from a list sorted or not (see options.tools.sort) + * @param {Number} i - index + * @returns {Object} - layer object + * @see {ol.style.editor.Layer} + */ + getLayer (i) { + return this.layers[i]; + } -/** - * Get the layer object from a list sorted or not (see options.tools.sort) - * @param {Number} i - index - * @returns {Object} - layer object - * @see {ol.style.editor.Layer} - */ -Editor.prototype.getLayer = function (i) { - return this.layers[i]; }; + +// on récupère les méthodes de la classe DOM +Utils.assign(Editor.prototype, EditorDOM); + // ################################################################### // // ####################### handlers events to dom #################### // // ################################################################### // diff --git a/src/OpenLayers/Controls/Editor/Filter.js b/src/OpenLayers/Controls/Editor/Filter.js index 5bbc27bd3..8bc1f8be9 100644 --- a/src/OpenLayers/Controls/Editor/Filter.js +++ b/src/OpenLayers/Controls/Editor/Filter.js @@ -29,228 +29,224 @@ var logger = Logger.getLogger("editor-filter"); * filter.display(true); * filter.getContainer(); */ -function Filter (options) { - logger.trace("[constructor] Filter", options); - - // options - this.options = options || { - // default... - target : null, - position : 0, - tools : null, - title : null, - obj : null - }; - - if (!(this instanceof Filter)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } +class Filter { + + constructor (options) { + logger.trace("[constructor] Filter", options); + + // options + this.options = options || { + // default... + target : null, + position : 0, + tools : null, + title : null, + obj : null + }; - this._initialize(); + if (!(this instanceof Filter)) { + throw new TypeError("ERROR CLASS_CONSTRUCTOR"); + } - this._initContainer(); -}; + this._initialize(); -/** - * Constructor (alias) - * - * @private - */ -Filter.prototype.constructor = Filter; + this._initContainer(); + } -/** - * Initialize component - * (called by constructor) - * - * @private - */ -Filter.prototype._initialize = function () { - // unique editor id (optional!) - this.id = this.options.id || null; + /** + * Initialize component + * (called by constructor) + * + * @private + */ + _initialize () { + // unique editor id (optional!) + this.id = this.options.id || null; + + if (!this.options.target) { + // cf. add() + } - if (!this.options.target) { - // cf. add() - } + if (!this.options.position) { + this.options.position = 0; + } - if (!this.options.position) { - this.options.position = 0; - } + var _toolsDefault = { + edition : false + }; - var _toolsDefault = { - edition : false - }; + if (!this.options.tools) { + this.options.tools = _toolsDefault; + } - if (!this.options.tools) { - this.options.tools = _toolsDefault; - } + Utils.mergeParams(this.options.tools, _toolsDefault, false); - Utils.mergeParams(this.options.tools, _toolsDefault, false); + if (!this.options.obj) { + // choix d'avoir un objet vide pour une edition futur... + this.options.obj = { + filter : [] + }; + } - if (!this.options.obj) { - // choix d'avoir un objet vide pour une edition futur... - this.options.obj = { - filter : [] + if (!this.options.title) { + this.options.title = "JSON Filtres :"; + } + this.container = null; + + // DOM : className or id + this.name = { + target : "GPEditorMapBoxFilterTarget", + container : "GPEditorMapBoxFilterContainer", + containerjson : "GPEditorMapBoxFilterJsonContainer", + jsonlabel : "GPEditorMapBoxFilterTitleJson", + jsondisplay : "GPEditorMapBoxFilterDisplayJson", + containertoolsedit : "GPEditorMapBoxFilterToolsEditionContainer" }; } - if (!this.options.title) { - this.options.title = "JSON Filtres :"; - } - this.container = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxFilterTarget", - container : "GPEditorMapBoxFilterContainer", - containerjson : "GPEditorMapBoxFilterJsonContainer", - jsonlabel : "GPEditorMapBoxFilterTitleJson", - jsondisplay : "GPEditorMapBoxFilterDisplayJson", - containertoolsedit : "GPEditorMapBoxFilterToolsEditionContainer" - }; -}; + /** + * Graphical rendering of the component + * (called by constructor) + * + * @private + * @example + *
+ *
+ * + *
...
+ *
+ *
+ *
+ */ + _initContainer () { + // contexte + var self = this; + + var _found = false; + var _filter = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! + + // FIXME tag filter est obselete ! + // on doit utiliser les expressions dans "paint" ou "layout" ! + if (_filter.filter) { + _found = true; + if (_filter.filter.length === 0) { + logger.info("tag 'filter' is empty !"); + } + } -/** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- * - *
...
- *
- *
- *
- */ -Filter.prototype._initContainer = function () { - // contexte - var self = this; - - var _found = false; - var _filter = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! - - // FIXME tag filter est obselete ! - // on doit utiliser les expressions dans "paint" ou "layout" ! - if (_filter.filter) { - _found = true; - if (_filter.filter.length === 0) { - logger.info("tag 'filter' is empty !"); + var div = document.createElement("div"); + div.className = this.name.container; + + var json = null; + if (_found) { + json = JSON.stringify(_filter.filter, null, 4); } - } - var div = document.createElement("div"); - div.className = this.name.container; + var divJson = document.createElement("div"); + divJson.className = this.name.containerjson; + + var labelJson = document.createElement("label"); + labelJson.className = this.name.jsonlabel; + labelJson.innerHTML = this.options.title; + divJson.appendChild(labelJson); + + var preJson = document.createElement("pre"); + preJson.className = this.name.jsondisplay; + preJson.innerHTML = json; + if (preJson.addEventListener) { + preJson.addEventListener("click", function (e) { + if (self.options.tools.edition) { + self.onEditJsonFilterMapBox(e); + } + }); + } else if (preJson.attachEvent) { + preJson.attachEvent("onclick", function (e) { + if (self.options.tools.edition) { + self.onEditJsonFilterMapBox(e); + } + }); + } + divJson.appendChild(preJson); + div.appendChild(divJson); - var json = null; - if (_found) { - json = JSON.stringify(_filter.filter, null, 4); - } + if (this.options.tools.edition) { + var divEdit = document.createElement("div"); + divEdit.className = this.name.containertoolsedit; + div.appendChild(divEdit); + } - var divJson = document.createElement("div"); - divJson.className = this.name.containerjson; - - var labelJson = document.createElement("label"); - labelJson.className = this.name.jsonlabel; - labelJson.innerHTML = this.options.title; - divJson.appendChild(labelJson); - - var preJson = document.createElement("pre"); - preJson.className = this.name.jsondisplay; - preJson.innerHTML = json; - if (preJson.addEventListener) { - preJson.addEventListener("click", function (e) { - if (self.options.tools.edition) { - self.onEditJsonFilterMapBox(e); - } - }); - } else if (preJson.attachEvent) { - preJson.attachEvent("onclick", function (e) { - if (self.options.tools.edition) { - self.onEditJsonFilterMapBox(e); - } - }); + // main container + this.container = div; } - divJson.appendChild(preJson); - div.appendChild(divJson); - if (this.options.tools.edition) { - var divEdit = document.createElement("div"); - divEdit.className = this.name.containertoolsedit; - div.appendChild(divEdit); + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Add element into target DOM + * @returns {Object} - Legend instance + */ + add () { + if (!this.options.target) { + if (!document.getElementById(this.name.target)) { + var div = document.createElement("div"); + div.id = this.name.target; + var node = document.documentElement || + document.getElementsByTagName("body")[0] || + document.getElementsByTagName("head")[0]; + node.appendChild(div); + } + this.options.target = document.getElementById(this.name.target); + } + if (this.container) { + this.options.target.appendChild(this.container); + } + return this; } - // main container - this.container = div; -}; - -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // - -/** - * Add element into target DOM - * @returns {Object} - Legend instance - */ -Filter.prototype.add = function () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); + /** + * Set display container or get + * + * @param {Boolean} display - show/hidden container or get status + * @returns {Boolean} - true/false + */ + display (display) { + logger.trace("display()", display); + if (typeof display !== "undefined") { + this.container.style.display = (display) ? "flex" : "none"; } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); + return (this.container.style.display === "flex"); } - return this; -}; -/** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ -Filter.prototype.display = function (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; + /** + * Get container (DOM) + * + * @returns {DOMElement} DOM element + */ + getContainer () { + return this.container; } - return (this.container.style.display === "flex"); -}; -/** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ -Filter.prototype.getContainer = function () { - return this.container; -}; -// ################################################################### // -// ####################### handlers events to dom #################### // -// ################################################################### // + // ################################################################### // + // ####################### handlers events to dom #################### // + // ################################################################### // + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Filter#editor:style:oneditjson + */ + onEditJsonFilterMapBox (e) { + logger.trace("onEditJsonFilterMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.filter.oneditjson, e); + } -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Filter#editor:style:oneditjson - */ -Filter.prototype.onEditJsonFilterMapBox = function (e) { - logger.trace("onEditJsonFilterMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.filter.oneditjson, e); }; export default Filter; diff --git a/src/OpenLayers/Controls/Editor/Group.js b/src/OpenLayers/Controls/Editor/Group.js index 81022b901..73abe86ec 100644 --- a/src/OpenLayers/Controls/Editor/Group.js +++ b/src/OpenLayers/Controls/Editor/Group.js @@ -21,158 +21,154 @@ var logger = Logger.getLogger("editor-group"); * group.add(); * group.add(); */ -function Group (options) { - logger.trace("[constructor] Group", options); +class Group { - // options - this.options = options || { - // default... - }; + constructor (options) { + logger.trace("[constructor] Group", options); - if (!(this instanceof Group)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); -}; + // options + this.options = options || { + // default... + }; -/** - * Constructor (alias) - * - * @private - */ -Group.prototype.constructor = Group; + if (!(this instanceof Group)) { + throw new TypeError("ERROR CLASS_CONSTRUCTOR"); + } -/** - * Initialize component - * (called by constructor) - * - * @private - */ -Group.prototype._initialize = function () { - // unique editor id (optional!) - this.id = this.options.id || null; + this._initialize(); - if (!this.options.target) { - // cf. add() + this._initContainer(); } - if (!this.options.title) { - // cf. summary - this.options.title = "Détails du groupe..."; - } + /** + * Initialize component + * (called by constructor) + * + * @private + */ + _initialize () { + // unique editor id (optional!) + this.id = this.options.id || null; + + if (!this.options.target) { + // cf. add() + } - // plier par defaut - if (typeof this.options.collapse === "undefined") { - this.options.collapse = true; - } + if (!this.options.title) { + // cf. summary + this.options.title = "Détails du groupe..."; + } - this.container = null; + // plier par defaut + if (typeof this.options.collapse === "undefined") { + this.options.collapse = true; + } - // DOM : className or id - this.name = { - target : "GPEditorMapBoxGroupTarget", - container : "GPEditorMapBoxGroupContainer", - details : "GPEditorMapBoxGroupDetails", - summary : "GPEditorMapBoxGroupSummary" - }; -}; + this.container = null; -/** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
...
- */ -Group.prototype._initContainer = function () { - var div = document.createElement("div"); - div.className = this.name.container; - - // FIXME pas compatible IE ! - // https://caniuse.com/#search=details - // cf. https://css-tricks.com/quick-reminder-that-details-summary-is-the-easiest-way-ever-to-make-an-accordion/ - var details = document.createElement("details"); - details.className = this.name.details; - details.open = !this.options.collapse; - div.appendChild(details); - - var summary = document.createElement("summary"); - summary.className = this.name.summary; - summary.innerHTML = this.options.title; - details.appendChild(summary); - - // main container - this.container = div; -}; + // DOM : className or id + this.name = { + target : "GPEditorMapBoxGroupTarget", + container : "GPEditorMapBoxGroupContainer", + details : "GPEditorMapBoxGroupDetails", + summary : "GPEditorMapBoxGroupSummary" + }; + } -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // + /** + * Graphical rendering of the component + * (called by constructor) + * + * @private + * @example + *
...
+ */ + _initContainer () { + var div = document.createElement("div"); + div.className = this.name.container; + + // FIXME pas compatible IE ! + // https://caniuse.com/#search=details + // cf. https://css-tricks.com/quick-reminder-that-details-summary-is-the-easiest-way-ever-to-make-an-accordion/ + var details = document.createElement("details"); + details.className = this.name.details; + details.open = !this.options.collapse; + div.appendChild(details); + + var summary = document.createElement("summary"); + summary.className = this.name.summary; + summary.innerHTML = this.options.title; + details.appendChild(summary); + + // main container + this.container = div; + } -/** - * Add element into target DOM - */ -Group.prototype.add = function () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Add element into target DOM + */ + add () { + if (!this.options.target) { + if (!document.getElementById(this.name.target)) { + var div = document.createElement("div"); + div.id = this.name.target; + var node = document.documentElement || + document.getElementsByTagName("body")[0] || + document.getElementsByTagName("head")[0]; + node.appendChild(div); + } + this.options.target = document.getElementById(this.name.target); + } + if (this.container) { + this.options.target.appendChild(this.container); } - this.options.target = document.getElementById(this.name.target); } - if (this.container) { - this.options.target.appendChild(this.container); + + /** + * Set display container (DOM) + * + * @param {Boolean} display - show/hidden container + */ + display (display) { + this.container.style.display = (display) ? "flex" : "none"; } -}; -/** - * Set display container (DOM) - * - * @param {Boolean} display - show/hidden container - */ -Group.prototype.display = function (display) { - this.container.style.display = (display) ? "flex" : "none"; -}; + /** + * Get container (DOM) + * + * @returns {DOMElement} DOM element + */ + getContainer () { + var nodes = this.container.childNodes; + if (nodes.length) { + // retourne le noeud "details" ! + return nodes[0]; + } + // sinon le container principal + return this.container; + } -/** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ -Group.prototype.getContainer = function () { - var nodes = this.container.childNodes; - if (nodes.length) { - // retourne le noeud "details" ! - return nodes[0]; + // ################################################################### // + // ####################### handlers events to dom #################### // + // ################################################################### // + /** + * this method is called by event '' on '' tag form + * + * NOT USED ! + * @param {Object} e - HTMLElement + * @private + * @fires Group#editor:group:oncollapse + */ + onCollapseGroupMapBox (e) { + logger.trace("onCollapseGroupMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.group.oncollapse, e); } - // sinon le container principal - return this.container; -}; -// ################################################################### // -// ####################### handlers events to dom #################### // -// ################################################################### // -/** - * this method is called by event '' on '' tag form - * - * NOT USED ! - * @param {Object} e - HTMLElement - * @private - * @fires Group#editor:group:oncollapse - */ -Group.prototype.onCollapseGroupMapBox = function (e) { - logger.trace("onCollapseGroupMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.group.oncollapse, e); }; export default Group; diff --git a/src/OpenLayers/Controls/Editor/Layer.js b/src/OpenLayers/Controls/Editor/Layer.js index 5fda791ef..666a53664 100644 --- a/src/OpenLayers/Controls/Editor/Layer.js +++ b/src/OpenLayers/Controls/Editor/Layer.js @@ -52,593 +52,587 @@ var logger = Logger.getLogger("editor-layer"); * // e.target.editorID : id or null * }, this); */ -function Layer (options) { - logger.trace("[constructor] Layer", options); +class Layer { - // options - this.options = options || {}; + constructor (options) { + logger.trace("[constructor] Layer", options); - if (!(this instanceof Layer)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } + // options + this.options = options || {}; - this._initialize(); + if (!(this instanceof Layer)) { + throw new TypeError("ERROR CLASS_CONSTRUCTOR"); + } - this._initContainer(); -}; + this._initialize(); -/** - * Constructor (alias) - * - * @private - */ -Layer.prototype.constructor = Layer; + this._initContainer(); + } -// ################################################################### // -// ##################### private methods ############################# // -// ################################################################### // + // ################################################################### // + // ##################### private methods ############################# // + // ################################################################### // + /** + * Initialize component + * (called by constructor) + * + * @private + */ + _initialize () { + // unique editor id (optional!) + this.id = this.options.id || null; // null si le layer n'appartient pas à un editeur ! + + if (!this.options.target) { + // cf. add() + } -/** - * Initialize component - * (called by constructor) - * - * @private - */ -Layer.prototype._initialize = function () { - // unique editor id (optional!) - this.id = this.options.id || null; // null si le layer n'appartient pas à un editeur ! + if (!this.options.position) { + this.options.position = 0; + } - if (!this.options.target) { - // cf. add() - } + var _toolsDefault = { + visibility : true, + icon : { + image : true, + anchor : "end" + }, + type : true, + pin : true, + remove : false, // TODO + clone : false // TODO + }; + + if (!this.options.tools) { + this.options.tools = _toolsDefault; + } - if (!this.options.position) { - this.options.position = 0; - } + Utils.mergeParams(this.options.tools, _toolsDefault, false); + + var _objDefault = { + id : "", + type : "", // icone sur le type de geometrie + source : "", + "source-layer" : "" + }; + + if (!this.options.obj) { + this.options.obj = _objDefault; + } - var _toolsDefault = { - visibility : true, - icon : { - image : true, - anchor : "end" - }, - type : true, - pin : true, - remove : false, // TODO - clone : false // TODO - }; - - if (!this.options.tools) { - this.options.tools = _toolsDefault; + Utils.mergeParams(this.options.obj, _objDefault, false); + + // legende intégrée + this.bSlotLegend = false; + + // obj + this.oFilter = null; + this.oStyle = null; + this.oLegend = null; + + // dom + this.container = null; + this.DomVisibility = null; + this.DomToggle = null; + + // DOM : className or id + this.name = { + target : "GPEditorMapBoxLayerTarget", + container : "GPEditorMapBoxLayerContainer", + containerlegend : "GPEditorMapBoxLayerLegendContainer", + containertitle : "GPEditorMapBoxLayerTitleContainer", + imagelabelinput : "GPEditorMapBoxLayerImageInput", + imagelabel : "GPEditorMapBoxLayerImageLabel", + typeimg : "GPEditorMapBoxLayerTypeImage", + titleinput : "GPEditorMapBoxLayerTitleInput", + titlelabel : "GPEditorMapBoxLayerTitleLabel", + containertools : "GPEditorMapBoxToolsContainer", + visibilityinput : "GPEditorMapBoxToolsVisibilityInput", + visibilitylabel : "GPEditorMapBoxToolsVisibilityLabel", + visibilityinputdisable : "GPEditorMapBoxToolsVisibilityInputDisable", + visibilitylabeldisable : "GPEditorMapBoxToolsVisibilityLabelDisable" + }; } - Utils.mergeParams(this.options.tools, _toolsDefault, false); + /** + * Graphical rendering of the component + * (called by constructor) + * + * @private + * @example + * // >> Titre 1 |OOO| <- menu tools : visibility, clone, remove + * // >> Titre 2 |OXX| <- affichage configurable (cf. options.tools) + * // Event : clic sur le titre -> ex. affiche le menu des styles / filtres + * // : clic visibility, clone, remove + * // DOM : + *
+ *
+ * + * + * + * + *
+ *
+ * + * + *
+ *
+ */ + _initContainer () { + // contexte + var self = this; + + var obj = this.options.obj; + + var div = document.createElement("div"); + div.className = this.name.container; + + // title + var divTitle = document.createElement("div"); + divTitle.id = this.name.containertitle + "-" + this.options.position; + divTitle.className = this.name.containertitle; - var _objDefault = { - id : "", - type : "", // icone sur le type de geometrie - source : "", - "source-layer" : "" - }; + // puce + if (this.options.tools.pin) { // Optionnel ! + // input + var inputImage = document.createElement("input"); + inputImage.id = this.name.imagelabelinput + "-" + this.options.position; + inputImage.className = this.name.imagelabelinput; + inputImage.type = "checkbox"; + divTitle.appendChild(inputImage); + // puce + var labelImage = document.createElement("label"); + labelImage.className = this.name.imagelabel; + labelImage.htmlFor = inputImage.id; + if (labelImage.addEventListener) { + labelImage.addEventListener("click", function (e) { + self.onClickLayerMapBox(e); + }); + } else if (labelImage.attachEvent) { + labelImage.attachEvent("onclick", function (e) { + self.onClickLayerMapBox(e); + }); + } + divTitle.appendChild(labelImage); + } - if (!this.options.obj) { - this.options.obj = _objDefault; - } + // tools : + // visibility, (remove, clone) + var _addTools = function () { + var divTools = document.createElement("div"); + divTools.id = this.name.containertools + "-" + this.options.position; + divTools.className = this.name.containertools; + + // visibility + if (this.options.tools.visibility) { + var inputTools = document.createElement("input"); + inputTools.id = this.name.visibilityinput + "-" + this.options.position; + inputTools.className = (this.options.tools.icon.image) ? this.name.visibilityinput : this.name.visibilityinputdisable; + inputTools.type = "checkbox"; + inputTools.checked = "checked"; // par défaut, à modifier via visibility(true|false) ! + + // event for visibility change + if (inputTools.addEventListener) { + inputTools.addEventListener("click", function (e) { + self.onVisibilityLayerMapBox(e); + }); + } else if (inputTools.attachEvent) { + // internet explorer + inputTools.attachEvent("onclick", function (e) { + self.onVisibilityLayerMapBox(e); + }); + } + divTools.appendChild(inputTools); + // enregistrement utile pour la méthode : visibility() + this.DomVisibility = inputTools; + + var labelTools = document.createElement("label"); + labelTools.htmlFor = this.name.visibilityinput + "-" + this.options.position; + labelTools.id = this.name.visibilitylabel + "-" + this.options.position; + labelTools.className = (this.options.tools.icon.image) ? this.name.visibilitylabel : this.name.visibilitylabeldisable; + labelTools.title = "Afficher/masquer la couche"; + divTools.appendChild(labelTools); + + div.appendChild(divTools); + } - Utils.mergeParams(this.options.obj, _objDefault, false); - - // legende intégrée - this.bSlotLegend = false; - - // obj - this.oFilter = null; - this.oStyle = null; - this.oLegend = null; - - // dom - this.container = null; - this.DomVisibility = null; - this.DomToggle = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxLayerTarget", - container : "GPEditorMapBoxLayerContainer", - containerlegend : "GPEditorMapBoxLayerLegendContainer", - containertitle : "GPEditorMapBoxLayerTitleContainer", - imagelabelinput : "GPEditorMapBoxLayerImageInput", - imagelabel : "GPEditorMapBoxLayerImageLabel", - typeimg : "GPEditorMapBoxLayerTypeImage", - titleinput : "GPEditorMapBoxLayerTitleInput", - titlelabel : "GPEditorMapBoxLayerTitleLabel", - containertools : "GPEditorMapBoxToolsContainer", - visibilityinput : "GPEditorMapBoxToolsVisibilityInput", - visibilitylabel : "GPEditorMapBoxToolsVisibilityLabel", - visibilityinputdisable : "GPEditorMapBoxToolsVisibilityInputDisable", - visibilitylabeldisable : "GPEditorMapBoxToolsVisibilityLabelDisable" - }; -}; + // clone + if (this.options.tools.clone) { + // TODO... + logger.warn("Dom for tools clone, it's not yet implemented !"); + } -/** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - * // >> Titre 1 |OOO| <- menu tools : visibility, clone, remove - * // >> Titre 2 |OXX| <- affichage configurable (cf. options.tools) - * // Event : clic sur le titre -> ex. affiche le menu des styles / filtres - * // : clic visibility, clone, remove - * // DOM : - *
- *
- * - * - * - * - *
- *
- * - * - *
- *
- */ -Layer.prototype._initContainer = function () { - // contexte - var self = this; + // remove + if (this.options.tools.remove) { + // TODO... + logger.warn("Dom for tools remove, it's not yet implemented !"); + } + }; - var obj = this.options.obj; + // ajout des outils au debut du composant + if (this.options.tools.icon.anchor === "start") { + _addTools.apply(this); + } - var div = document.createElement("div"); - div.className = this.name.container; + // type + if (this.options.tools.type && obj.type) { // Optionnel ! + var imgType = document.createElement("img"); + imgType.className = this.name.typeimg; + // FIXME il faudrait faire la difference entre : + // - icone uniquement : SYMBOL-ICON + // - texte uniquement : SYMBOL-TEXT + // - les 2 : SYMBOL + // Mais il nous faut les styles complets (paint & layout) + // pour determiner les 3 types ! + switch (obj.type.toUpperCase()) { + case "SYMBOL-ICON": // not used ! + imgType.style["background-position"] = "0px 0"; + break; + case "SYMBOL-TEXT": // not used ! + imgType.style["background-position"] = "-194px 0"; + break; + case "SYMBOL": + imgType.style["background-position"] = "-84px 0"; + break; + case "LINE": + imgType.style["background-position"] = "-28px 0"; + break; + case "FILL": + imgType.style["background-position"] = "-56px 0"; + break; + case "BACKGROUND": + imgType.style["background-position"] = "-140px 0"; + break; + case "CIRCLE": + imgType.style["background-position"] = "-168px 0"; + break; + default: + // type inconnu ou non pris en charge ou par defaut + imgType.style["background-position"] = "-112px 0"; + } + divTitle.appendChild(imgType); + } - // title - var divTitle = document.createElement("div"); - divTitle.id = this.name.containertitle + "-" + this.options.position; - divTitle.className = this.name.containertitle; + // container legend (empty) + var divLegend = document.createElement("div"); + divLegend.id = this.name.containerlegend + "-" + this.options.position; + divLegend.className = this.name.containerlegend; + divTitle.appendChild(divLegend); - // puce - if (this.options.tools.pin) { // Optionnel ! // input - var inputImage = document.createElement("input"); - inputImage.id = this.name.imagelabelinput + "-" + this.options.position; - inputImage.className = this.name.imagelabelinput; - inputImage.type = "checkbox"; - divTitle.appendChild(inputImage); - // puce - var labelImage = document.createElement("label"); - labelImage.className = this.name.imagelabel; - labelImage.htmlFor = inputImage.id; - if (labelImage.addEventListener) { - labelImage.addEventListener("click", function (e) { + var inputTitle = document.createElement("input"); + inputTitle.id = this.name.titleinput + "-" + this.options.position; + inputTitle.className = this.name.titleinput; + inputTitle.type = "checkbox"; + divTitle.appendChild(inputTitle); + + // label for + var labelTitle = document.createElement("label"); + labelTitle.className = this.name.titlelabel; + labelTitle.htmlFor = inputTitle.id; + labelTitle.innerHTML = obj["id"] || obj["source-layer"] || obj["source"]; + labelTitle.title = obj["source-layer"] || obj["source"] || obj["id"]; + if (labelTitle.addEventListener) { + labelTitle.addEventListener("click", function (e) { self.onClickLayerMapBox(e); }); - } else if (labelImage.attachEvent) { - labelImage.attachEvent("onclick", function (e) { + } else if (labelTitle.attachEvent) { + labelTitle.attachEvent("onclick", function (e) { self.onClickLayerMapBox(e); }); } - divTitle.appendChild(labelImage); - } + divTitle.appendChild(labelTitle); + // enregistrement utile pour la méthode : collapse() + this.DomToggle = labelTitle; - // tools : - // visibility, (remove, clone) - var _addTools = function () { - var divTools = document.createElement("div"); - divTools.id = this.name.containertools + "-" + this.options.position; - divTools.className = this.name.containertools; - - // visibility - if (this.options.tools.visibility) { - var inputTools = document.createElement("input"); - inputTools.id = this.name.visibilityinput + "-" + this.options.position; - inputTools.className = (this.options.tools.icon.image) ? this.name.visibilityinput : this.name.visibilityinputdisable; - inputTools.type = "checkbox"; - inputTools.checked = "checked"; // par défaut, à modifier via visibility(true|false) ! - // event for visibility change - if (inputTools.addEventListener) { - inputTools.addEventListener("click", function (e) { - self.onVisibilityLayerMapBox(e); - }); - } else if (inputTools.attachEvent) { - // internet explorer - inputTools.attachEvent("onclick", function (e) { - self.onVisibilityLayerMapBox(e); - }); - } - divTools.appendChild(inputTools); - // enregistrement utile pour la méthode : visibility() - this.DomVisibility = inputTools; - - var labelTools = document.createElement("label"); - labelTools.htmlFor = this.name.visibilityinput + "-" + this.options.position; - labelTools.id = this.name.visibilitylabel + "-" + this.options.position; - labelTools.className = (this.options.tools.icon.image) ? this.name.visibilitylabel : this.name.visibilitylabeldisable; - labelTools.title = "Afficher/masquer la couche"; - divTools.appendChild(labelTools); - - div.appendChild(divTools); - } - - // clone - if (this.options.tools.clone) { - // TODO... - logger.warn("Dom for tools clone, it's not yet implemented !"); - } + div.appendChild(divTitle); - // remove - if (this.options.tools.remove) { - // TODO... - logger.warn("Dom for tools remove, it's not yet implemented !"); + // ajout des outils au fin du composant + if (this.options.tools.icon.anchor === "end") { + _addTools.apply(this); } - }; - // ajout des outils au debut du composant - if (this.options.tools.icon.anchor === "start") { - _addTools.apply(this); + // main container + this.container = div; } - // type - if (this.options.tools.type && obj.type) { // Optionnel ! - var imgType = document.createElement("img"); - imgType.className = this.name.typeimg; - // FIXME il faudrait faire la difference entre : - // - icone uniquement : SYMBOL-ICON - // - texte uniquement : SYMBOL-TEXT - // - les 2 : SYMBOL - // Mais il nous faut les styles complets (paint & layout) - // pour determiner les 3 types ! - switch (obj.type.toUpperCase()) { - case "SYMBOL-ICON": // not used ! - imgType.style["background-position"] = "0px 0"; - break; - case "SYMBOL-TEXT": // not used ! - imgType.style["background-position"] = "-194px 0"; - break; - case "SYMBOL": - imgType.style["background-position"] = "-84px 0"; - break; - case "LINE": - imgType.style["background-position"] = "-28px 0"; - break; - case "FILL": - imgType.style["background-position"] = "-56px 0"; - break; - case "BACKGROUND": - imgType.style["background-position"] = "-140px 0"; - break; - case "CIRCLE": - imgType.style["background-position"] = "-168px 0"; - break; - default: - // type inconnu ou non pris en charge ou par defaut - imgType.style["background-position"] = "-112px 0"; + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Add element into target DOM + * @returns {Object} - Layer instance + */ + add () { + logger.trace("add()"); + if (!this.options.target) { + if (!document.getElementById(this.name.target)) { + var div = document.createElement("div"); + div.id = this.name.target; + var node = document.documentElement || + document.getElementsByTagName("body")[0] || + document.getElementsByTagName("head")[0]; + node.appendChild(div); + } + this.options.target = document.getElementById(this.name.target); + } + if (this.container) { + this.options.target.appendChild(this.container); } - divTitle.appendChild(imgType); + return this; } - // container legend (empty) - var divLegend = document.createElement("div"); - divLegend.id = this.name.containerlegend + "-" + this.options.position; - divLegend.className = this.name.containerlegend; - divTitle.appendChild(divLegend); - - // input - var inputTitle = document.createElement("input"); - inputTitle.id = this.name.titleinput + "-" + this.options.position; - inputTitle.className = this.name.titleinput; - inputTitle.type = "checkbox"; - divTitle.appendChild(inputTitle); - - // label for - var labelTitle = document.createElement("label"); - labelTitle.className = this.name.titlelabel; - labelTitle.htmlFor = inputTitle.id; - labelTitle.innerHTML = obj["id"] || obj["source-layer"] || obj["source"]; - labelTitle.title = obj["source-layer"] || obj["source"] || obj["id"]; - if (labelTitle.addEventListener) { - labelTitle.addEventListener("click", function (e) { - self.onClickLayerMapBox(e); - }); - } else if (labelTitle.attachEvent) { - labelTitle.attachEvent("onclick", function (e) { - self.onClickLayerMapBox(e); - }); + /** + * Add style in the submenu + * + * @param {Object} style - style object + */ + addStyle (style) { + logger.trace("addStyle()", style); + if (style && typeof style === "object" && style instanceof Style) { + this.oStyle = style; + this.oStyle.display(false); // par defaut ! + } } - divTitle.appendChild(labelTitle); - // enregistrement utile pour la méthode : collapse() - this.DomToggle = labelTitle; - - div.appendChild(divTitle); - // ajout des outils au fin du composant - if (this.options.tools.icon.anchor === "end") { - _addTools.apply(this); + /** + * Add filter in the submenu + * + * @param {Object} filter - filter object + */ + addFilter (filter) { + logger.trace("addFilter()", filter); + if (filter && typeof filter === "object" && filter instanceof Filter) { + this.oFilter = filter; + this.oFilter.display(false); // par defaut ! + } } - // main container - this.container = div; -}; - -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // - -/** - * Add element into target DOM - * @returns {Object} - Layer instance - */ -Layer.prototype.add = function () { - logger.trace("add()"); - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); + /** + * Add Legend in the submenu + * + * @param {Object} legend - legend object + */ + addLegend (legend) { + logger.trace("addLegend()", legend); + if (legend && typeof legend === "object" && legend instanceof Legend) { + this.oLegend = legend; + this.oLegend.display(false); // par defaut ! } - this.options.target = document.getElementById(this.name.target); } - if (this.container) { - this.options.target.appendChild(this.container); + + /** + * Integrate Legend to the layer container + */ + slotLegend () { + // cas particulier : + // on souhaite intégrer une partie de la legende dans le container du layer. + var legend = this.oLegend; + if (legend) { + // FIXME c'est pourri... + var node = null; + var nodesLvl1 = this.container.childNodes; + if (nodesLvl1.length) { + // selon où se situe l'icone de visibilité : au debut ou à la fin... + var idx = (this.options.tools.icon.anchor === "start") ? 1 : 0; + var nodesLvl2 = nodesLvl1[idx].childNodes; + // on recherche le container de la legende + for (var i = 0; i < nodesLvl2.length; i++) { + var curnode = nodesLvl2[i]; + if (curnode.id.indexOf(this.name.containerlegend) !== -1) { + node = curnode; + } + } + } + if (node) { + var render = legend.getRenderContainer(); + if (render) { + node.appendChild(render); + // legende intégrée + this.bSlotLegend = true; + } + } + } } - return this; -}; -/** - * Add style in the submenu - * - * @param {Object} style - style object - */ -Layer.prototype.addStyle = function (style) { - logger.trace("addStyle()", style); - if (style && typeof style === "object" && style instanceof Style) { - this.oStyle = style; - this.oStyle.display(false); // par defaut ! + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Set visibility or get + * + * @param {Boolean} display - set visibility or undefined to get status + * @returns {Boolean} - true/false + */ + visibility (display) { + logger.trace("visibility()", display); + if (!this.options.tools.visibility) { + return; + } + if (typeof display !== "undefined") { + this.DomVisibility.checked = (display) ? "checked" : ""; + } + return this.DomVisibility.checked; } -}; -/** - * Add filter in the submenu - * - * @param {Object} filter - filter object - */ -Layer.prototype.addFilter = function (filter) { - logger.trace("addFilter()", filter); - if (filter && typeof filter === "object" && filter instanceof Filter) { - this.oFilter = filter; - this.oFilter.display(false); // par defaut ! + /** + * Collapse a layer panel (event) + */ + collapse () { + logger.trace("collapse()"); + this.DomToggle.click(); } -}; -/** - * Add Legend in the submenu - * - * @param {Object} legend - legend object - */ -Layer.prototype.addLegend = function (legend) { - logger.trace("addLegend()", legend); - if (legend && typeof legend === "object" && legend instanceof Legend) { - this.oLegend = legend; - this.oLegend.display(false); // par defaut ! + /** + * Click on visibility icon (event) + */ + visible () { + logger.trace("visible()"); + if (!this.options.tools.visibility) { + return; + } + this.DomVisibility.click(); } -}; -/** - * Integrate Legend to the layer container - */ -Layer.prototype.slotLegend = function () { - // cas particulier : - // on souhaite intégrer une partie de la legende dans le container du layer. - var legend = this.oLegend; - if (legend) { - // FIXME c'est pourri... - var node = null; - var nodesLvl1 = this.container.childNodes; - if (nodesLvl1.length) { - // selon où se situe l'icone de visibilité : au debut ou à la fin... - var idx = (this.options.tools.icon.anchor === "start") ? 1 : 0; - var nodesLvl2 = nodesLvl1[idx].childNodes; - // on recherche le container de la legende - for (var i = 0; i < nodesLvl2.length; i++) { - var curnode = nodesLvl2[i]; - if (curnode.id.indexOf(this.name.containerlegend) !== -1) { - node = curnode; - } + /** + * Set collapse or get + * + * @param {Boolean} display - show/hidden container or get status + * @returns {Boolean} - true/false + */ + display (display) { + logger.trace("display()", display); + var checked = document.getElementById(this.DomToggle.htmlFor).checked; + if (typeof display !== "undefined") { + this.container.style.display = (display) ? "inline-flex" : "none"; + if (this.oStyle) { + this.oStyle.display(display && checked); } - } - if (node) { - var render = legend.getRenderContainer(); - if (render) { - node.appendChild(render); - // legende intégrée - this.bSlotLegend = true; + if (this.oFilter) { + this.oFilter.display(display && checked); + } + if (this.oLegend) { + this.oLegend.display(display && checked); } } + return checked; } -}; - -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // -/** - * Set visibility or get - * - * @param {Boolean} display - set visibility or undefined to get status - * @returns {Boolean} - true/false - */ -Layer.prototype.visibility = function (display) { - logger.trace("visibility()", display); - if (!this.options.tools.visibility) { - return; - } - if (typeof display !== "undefined") { - this.DomVisibility.checked = (display) ? "checked" : ""; + /** + * Set disabled/enabled status or get + * + * @param {Boolean} active - disable/enable layer interaction or get status + * @returns {Boolean} - true/false + */ + active (active) { + logger.trace("active()", active); + if (typeof active !== "undefined") { + this.container.className = (active) + ? this.name.container + : this.name.container + " disabled"; + } + return (this.container.className === this.name.container); } - return this.DomVisibility.checked; -}; - -/** -* Collapse a layer panel (event) -*/ -Layer.prototype.collapse = function () { - logger.trace("collapse()"); - this.DomToggle.click(); -}; -/** -* Click on visibility icon (event) -*/ -Layer.prototype.visible = function () { - logger.trace("visible()"); - if (!this.options.tools.visibility) { - return; + /** + * Get container (DOM) + * + * @returns {DOMElement} DOM element + */ + getContainer () { + return this.container; } - this.DomVisibility.click(); -}; -/** - * Set collapse or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ -Layer.prototype.display = function (display) { - logger.trace("display()", display); - var checked = document.getElementById(this.DomToggle.htmlFor).checked; - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "inline-flex" : "none"; + // ################################################################### // + // ####################### handlers events to dom #################### // + // ################################################################### // + /** + * this method is called by event '' on '' tag form + * + * @param {Object} e - HTMLElement + * @private + */ + onClickLayerMapBox (e) { + logger.trace("onClickLayerMapBox", e); + + var id = e.target.htmlFor.substring(e.target.htmlFor.indexOf("-")); + var checked = document.getElementById(e.target.htmlFor).checked; + + // gestion des inputs + if (e.target.htmlFor === this.name.imagelabelinput + id) { + document.getElementById(this.name.titleinput + id).checked = !checked; + } + if (e.target.htmlFor === this.name.titleinput + id) { + // si options.pin:false, ce DOM n'existe pas ! + if (document.getElementById(this.name.imagelabelinput + id)) { + document.getElementById(this.name.imagelabelinput + id).checked = !checked; + } + } + + // ouverture du panneau des styles / filtres if (this.oStyle) { - this.oStyle.display(display && checked); + this.oStyle.display(!checked); } if (this.oFilter) { - this.oFilter.display(display && checked); + this.oFilter.display(!checked); } - if (this.oLegend) { - this.oLegend.display(display && checked); + // attention, + // si la legende est non editable, elle ne se trouve pas dans le sous menu ! + if (this.oLegend && this.oLegend.isEditable()) { + this.oLegend.display(!checked); } } - return checked; -}; -/** - * Set disabled/enabled status or get - * - * @param {Boolean} active - disable/enable layer interaction or get status - * @returns {Boolean} - true/false - */ -Layer.prototype.active = function (active) { - logger.trace("active()", active); - if (typeof active !== "undefined") { - this.container.className = (active) - ? this.name.container - : this.name.container + " disabled"; + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Layer#editor:layer:onclickvisibility + */ + onVisibilityLayerMapBox (e) { + logger.trace("onVisibilityLayerMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.layer.onclickvisibility, e); } - return (this.container.className === this.name.container); -}; -/** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ -Layer.prototype.getContainer = function () { - return this.container; -}; - -// ################################################################### // -// ####################### handlers events to dom #################### // -// ################################################################### // - -/** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - */ -Layer.prototype.onClickLayerMapBox = function (e) { - logger.trace("onClickLayerMapBox", e); - - var id = e.target.htmlFor.substring(e.target.htmlFor.indexOf("-")); - var checked = document.getElementById(e.target.htmlFor).checked; - - // gestion des inputs - if (e.target.htmlFor === this.name.imagelabelinput + id) { - document.getElementById(this.name.titleinput + id).checked = !checked; - } - if (e.target.htmlFor === this.name.titleinput + id) { - // si options.pin:false, ce DOM n'existe pas ! - if (document.getElementById(this.name.imagelabelinput + id)) { - document.getElementById(this.name.imagelabelinput + id).checked = !checked; - } + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Layer#editor:layer:onclickclone + */ + onCloneLayerMapBox (e) { + logger.trace("onCloneLayerMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.layer.onclickclone, e); } - // ouverture du panneau des styles / filtres - if (this.oStyle) { - this.oStyle.display(!checked); - } - if (this.oFilter) { - this.oFilter.display(!checked); - } - // attention, - // si la legende est non editable, elle ne se trouve pas dans le sous menu ! - if (this.oLegend && this.oLegend.isEditable()) { - this.oLegend.display(!checked); + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Layer#editor:layer:onclickremove + */ + onRemoveLayerMapBox (e) { + logger.trace("onRemoveLayerMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.layer.onclickremove, e); } -}; -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickvisibility - */ -Layer.prototype.onVisibilityLayerMapBox = function (e) { - logger.trace("onVisibilityLayerMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.layer.onclickvisibility, e); -}; - -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickclone - */ -Layer.prototype.onCloneLayerMapBox = function (e) { - logger.trace("onCloneLayerMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.layer.onclickclone, e); -}; - -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickremove - */ -Layer.prototype.onRemoveLayerMapBox = function (e) { - logger.trace("onRemoveLayerMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.layer.onclickremove, e); }; export default Layer; diff --git a/src/OpenLayers/Controls/Editor/Legend.js b/src/OpenLayers/Controls/Editor/Legend.js index cf7bf504a..2c4ea2aae 100644 --- a/src/OpenLayers/Controls/Editor/Legend.js +++ b/src/OpenLayers/Controls/Editor/Legend.js @@ -51,998 +51,990 @@ var logger = Logger.getLogger("editor-legend"); * legend.getToolsContainer(); * legend.getContainer(); */ -function Legend (options) { - logger.trace("[constructor] Legend", options); - - // options - this.options = options || { - // default... - target : null, - position : 0, - sprites : null, - obj : null - }; - - if (!(this instanceof Legend)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } +class Legend { + + constructor (options) { + logger.trace("[constructor] Legend", options); + + // options + this.options = options || { + // default... + target : null, + position : 0, + sprites : null, + obj : null + }; - this._initialize(); + if (!(this instanceof Legend)) { + throw new TypeError("ERROR CLASS_CONSTRUCTOR"); + } - this._initContainer(); -}; + this._initialize(); -/** - * Constructor (alias) - * - * @private - */ -Legend.prototype.constructor = Legend; - -// ################################################################### // -// ########################## CONSTANTES ############################# // -// ################################################################### // + this._initContainer(); + } -/** - * List of supported properties - */ -Legend.PROPERTIES = { - line : [ - "line-color", - "line-dasharray", - "line-opacity", - "line-width" - ], - fill : [ - "fill-color", - "fill-opacity", - "fill-outline-color", - "fill-pattern" - ], - background : [ - "background-color", - "background-opacity", - "background-pattern" - ], - circle : [ - "circle-color", - "circle-opacity", - "circle-stroke-color", - "circle-stroke-opacity", - "circle-stroke-width" - ], - icon : [ - "icon-color", - "icon-image", - "icon-opacity", - "__icon-size" - ], - text : [ - "__text-anchor", - "text-color", - "text-field", - "__text-font", - "__text-opacity", - "__text-size" - ] -}; + // ################################################################### // + // ########################## init methods ########################### // + // ################################################################### // + /** + * Initialize component + * (called by constructor) + * + * @private + */ + _initialize () { + // unique editor id (optional!) + this.id = this.options.id || null; + + if (!this.options.target) { + // cf. add() + } -// ################################################################### // -// ########################## init methods ########################### // -// ################################################################### // + // permet d'avoir un identifiant de position dans la liste des layers + if (!this.options.position) { + this.options.position = 0; + } -/** - * Initialize component - * (called by constructor) - * - * @private - */ -Legend.prototype._initialize = function () { - // unique editor id (optional!) - this.id = this.options.id || null; + if (!this.options.obj) { + // choix d'avoir un objet vide pour une edition... + this.options.obj = { + title : "vide...", + editable : true, + paint : { + "fill-color" : "#FFFFFF" + } + }; + } - if (!this.options.target) { - // cf. add() - } + // la legende est elle editable ? + // le tag 'editable' est à placer dans le fichier de style (dans le layer)... + var _editable = this.options.obj.editable; + this.editable = (typeof _editable !== "undefined") ? _editable : false; + + // liste des caractéristiques de la legende par defaut + this.legendRender = { + type : "fill", + values : { + width : 1, + stroke : "#FFFFFF", + color : "#000000", + opacity : 1 + } + }; - // permet d'avoir un identifiant de position dans la liste des layers - if (!this.options.position) { - this.options.position = 0; - } + // DOM : pointer + this.container = null; + this.rendercontainer = null; + this.toolscontainer = null; + + // DOM : className or id + this.name = { + target : "GPEditorMapBoxLegendTarget", + container : "GPEditorMapBoxLegendContainer", + containerlegendrender : "GPEditorMapBoxLegendRenderContainer", + legendrender : "GPEditorMapBoxLegendRender", + legendeditable : "GPEditorMapBoxLegendEditable", + legendtitle : "GPEditorMapBoxLegendTitle", + containerlegendtools : "GPEditorMapBoxLegendToolsContainer" + }; - if (!this.options.obj) { - // choix d'avoir un objet vide pour une edition... - this.options.obj = { - title : "vide...", - editable : true, - paint : { - "fill-color" : "#FFFFFF" - } + // DOM : Label menu Edition + this.labels = { + "line-color" : "Couleur du trait", + "line-width" : "Epaisseur du trait", + "line-opacity" : "Opacité du trait", + "fill-color" : "Couleur de remplissage", + "fill-opacity" : "Opacité du remplissage" }; } - // la legende est elle editable ? - // le tag 'editable' est à placer dans le fichier de style (dans le layer)... - var _editable = this.options.obj.editable; - this.editable = (typeof _editable !== "undefined") ? _editable : false; - - // liste des caractéristiques de la legende par defaut - this.legendRender = { - type : "fill", - values : { - width : 1, - stroke : "#FFFFFF", - color : "#000000", - opacity : 1 + /** + * Graphical rendering of the component + * (called by constructor) + * + * @private + * @example + *
+ *
+ *
+ * test circle editable... + *
+ *
...
+ *
+ */ + _initContainer () { + var _obj = this.options.obj; + + var div = document.createElement("div"); + div.className = this.name.container; + + // INFO + // on recherche les informations dans le tag 'paint' en priorité, mais pour + // les icones ou textes, les informations peuvent se trouver aussi dans le tag 'layout'... + // on fusionnne paint et layout par facilité + var style = Object.assign({}, _obj.paint, _obj.layout); + + // liste des properties mapbox + // ex. fill-color + var keys = Object.keys(style); + if (keys.length === 0) { + logger.info("tag 'paint' or 'layout' is empty !"); + return; } - }; - - // DOM : pointer - this.container = null; - this.rendercontainer = null; - this.toolscontainer = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxLegendTarget", - container : "GPEditorMapBoxLegendContainer", - containerlegendrender : "GPEditorMapBoxLegendRenderContainer", - legendrender : "GPEditorMapBoxLegendRender", - legendeditable : "GPEditorMapBoxLegendEditable", - legendtitle : "GPEditorMapBoxLegendTitle", - containerlegendtools : "GPEditorMapBoxLegendToolsContainer" - }; - - // DOM : Label menu Edition - this.labels = { - "line-color" : "Couleur du trait", - "line-width" : "Epaisseur du trait", - "line-opacity" : "Opacité du trait", - "fill-color" : "Couleur de remplissage", - "fill-opacity" : "Opacité du remplissage" - }; -}; -/** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- *
- * test circle editable... - *
- *
...
- *
- */ -Legend.prototype._initContainer = function () { - var _obj = this.options.obj; - - var div = document.createElement("div"); - div.className = this.name.container; - - // INFO - // on recherche les informations dans le tag 'paint' en priorité, mais pour - // les icones ou textes, les informations peuvent se trouver aussi dans le tag 'layout'... - // on fusionnne paint et layout par facilité - var style = Object.assign({}, _obj.paint, _obj.layout); - - // liste des properties mapbox - // ex. fill-color - var keys = Object.keys(style); - if (keys.length === 0) { - logger.info("tag 'paint' or 'layout' is empty !"); - return; - } + // FIXME + // - gestion de type plus complexe : texte avec/sans symbole ou symbole ! + // - pour les textes ou icones, les info peuvent être aussi dans le tag 'layout' ! + var params = {}; + var bFound = false; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + // recherche du type + // ex. fill + if (/fill-/.test(key) || + /line-/.test(key) || + /circle-/.test(key) || + /background-/.test(key) || + /text-/.test(key) || + /icon-/.test(key)) { + // style geré & trouvé + bFound = true; + + var title = _obj.title || ""; + + // INFO + // le type texte ou icone est difficile à trouver car les 2 types cohabitent, + // on le gère en symbole... + var type = key.split("-")[0]; + if (type === "text" || type === "icon") { + type = "symbol"; + } - // FIXME - // - gestion de type plus complexe : texte avec/sans symbole ou symbole ! - // - pour les textes ou icones, les info peuvent être aussi dans le tag 'layout' ! - - var params = {}; - var bFound = false; - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - // recherche du type - // ex. fill - if (/fill-/.test(key) || - /line-/.test(key) || - /circle-/.test(key) || - /background-/.test(key) || - /text-/.test(key) || - /icon-/.test(key) - ) { - // style geré & trouvé - bFound = true; - - var title = _obj.title || ""; - - // INFO - // le type texte ou icone est difficile à trouver car les 2 types cohabitent, - // on le gère en symbole... - var type = key.split("-")[0]; - if (type === "text" || type === "icon") { - type = "symbol"; + this.legendRender = this._getProperties(type, style); + params = { + edit : this.editable, + title : title, + type : this.legendRender.type, + values : this.legendRender.values + }; + div.appendChild(this._createElementIconLegend(params)); + + // on stoppe la recherche + break; } + } - this.legendRender = this._getProperties(type, style); + // legende avec un style indeterminé ou non géré !? + if (!bFound) { + // on prend la legende par defaut params = { edit : this.editable, - title : title, + title : "", type : this.legendRender.type, values : this.legendRender.values }; div.appendChild(this._createElementIconLegend(params)); - - // on stoppe la recherche - break; + logger.warn("legend type unknown, default legend used..."); } - } - - // legende avec un style indeterminé ou non géré !? - if (!bFound) { - // on prend la legende par defaut - params = { - edit : this.editable, - title : "", - type : this.legendRender.type, - values : this.legendRender.values - }; - div.appendChild(this._createElementIconLegend(params)); - logger.warn("legend type unknown, default legend used..."); - } - // ajout mode edition graphique de la legende - this.toolscontainer = this._createElementEditionLegend(params); - div.appendChild(this.toolscontainer); + // ajout mode edition graphique de la legende + this.toolscontainer = this._createElementEditionLegend(params); + div.appendChild(this.toolscontainer); - // main container - this.container = div; -}; - -// ################################################################### // -// ##################### private methods ############################# // -// ################################################################### // + // main container + this.container = div; + } -/** -* Get properties supported -* -* @param {Object} type - fill, line, circle, text, icon... -* @param {Object} values - raw values from the JSON file -* @returns {Object} - { type : (fill | line | circle | symbol), values : valuesSupported } -* -* @private -* @example -* -* // TODO -* // symbol with text (1) / symbol without text (2) / text (3) -* // "layout":{ -* // "icon-image":"{maki}-11", -* // "text-font":[ -* // "Open Sans Semibold", -* // "Arial Unicode MS Bold" -* // ], -* // "text-field":"{name_en}", -* // "text-max-width":9, -* // "text-padding":2, -* // "text-offset":[ -* // 0, -* // 0.6 -* // ], -* // "text-anchor":"top", -* // "text-size":12 -* // }, -* // "paint":{ -* // "text-color":"#666", -* // "text-halo-color":"#ffffff", -* // "text-halo-width":1, -* // "text-halo-blur":0.5 -* // }, -* -*/ -Legend.prototype._getProperties = function (type, values) { - // cas particulier du symbole complexe - // il existe plusieurs types pour un symbole : - // - text - // - icon - // - icon with text - if (type === "symbol") { - var isTextValue = values["text-field"]; - var isIconValue = values["icon-image"]; - type = (isTextValue && isIconValue) ? "icon" : (isTextValue) ? "text" : (isIconValue) ? "icon" : "unknow"; - if (type === "unknow") { - logger.warn("type unknow !?"); - return; + // ################################################################### // + // ##################### private methods ############################# // + // ################################################################### // + /** + * Get properties supported + * + * @param {Object} type - fill, line, circle, text, icon... + * @param {Object} values - raw values from the JSON file + * @returns {Object} - { type : (fill | line | circle | symbol), values : valuesSupported } + * + * @private + * @example + * + * // TODO + * // symbol with text (1) / symbol without text (2) / text (3) + * // "layout":{ + * // "icon-image":"{maki}-11", + * // "text-font":[ + * // "Open Sans Semibold", + * // "Arial Unicode MS Bold" + * // ], + * // "text-field":"{name_en}", + * // "text-max-width":9, + * // "text-padding":2, + * // "text-offset":[ + * // 0, + * // 0.6 + * // ], + * // "text-anchor":"top", + * // "text-size":12 + * // }, + * // "paint":{ + * // "text-color":"#666", + * // "text-halo-color":"#ffffff", + * // "text-halo-width":1, + * // "text-halo-blur":0.5 + * // }, + * + */ + _getProperties (type, values) { + // cas particulier du symbole complexe + // il existe plusieurs types pour un symbole : + // - text + // - icon + // - icon with text + if (type === "symbol") { + var isTextValue = values["text-field"]; + var isIconValue = values["icon-image"]; + type = (isTextValue && isIconValue) ? "icon" : (isTextValue) ? "text" : (isIconValue) ? "icon" : "unknow"; + if (type === "unknow") { + logger.warn("type unknow !?"); + return; + } } - } - var valuesSupported = {}; - for (const key in values) { - if (Object.hasOwnProperty.call(values, key)) { - const val = values[key]; - if (Legend.PROPERTIES[type].includes(key)) { - var prop = key.replace(type, "").slice(1); - var value = this._getValue(val); - if (value) { - // cas particulier des sprites - if (prop === "pattern" || prop === "image") { - if (!this.options.sprites || - !this.options.sprites.json || - !this.options.sprites.json[value]) { - var k = type + ":" + prop; - logger.warn("sprites mandatory for key ", k); - break; + var valuesSupported = {}; + for (const key in values) { + if (Object.hasOwnProperty.call(values, key)) { + const val = values[key]; + if (Legend.PROPERTIES[type].includes(key)) { + var prop = key.replace(type, "").slice(1); + var value = this._getValue(val); + if (value) { + // cas particulier des sprites + if (prop === "pattern" || prop === "image") { + if (!this.options.sprites || + !this.options.sprites.json || + !this.options.sprites.json[value]) { + var k = type + ":" + prop; + logger.warn("sprites mandatory for key ", k); + break; + } } + valuesSupported[prop] = value; } - valuesSupported[prop] = value; + } else { + logger.warn("property not supported : ", key); } - } else { - logger.warn("property not supported : ", key); } } - } - - return { - type : type, - values : valuesSupported - }; -}; -/** -* Render thumbnail (SVG) -* -* @param {Object} type - fill, line, circle, text, ... -* @param {Object} values - {"color":..., "width":..., "stroke":...., "opacity":...} -* @returns {Boolean} true/false -* -* @private -* @example -* (...) -*/ -Legend.prototype._renderThumbnail = function (type, values) { - // div de rendu de la legende - var div = this.rendercontainer; - - if (!div) { - return false; + return { + type : type, + values : valuesSupported + }; } - // SVG - var svg = null; - // facteur grossissement (x10) pour le trait - var factor = 3; + /** + * Render thumbnail (SVG) + * + * @param {Object} type - fill, line, circle, text, ... + * @param {Object} values - {"color":..., "width":..., "stroke":...., "opacity":...} + * @returns {Boolean} true/false + * + * @private + * @example + * (...) + */ + _renderThumbnail (type, values) { + // div de rendu de la legende + var div = this.rendercontainer; + + if (!div) { + return false; + } + + // SVG + var svg = null; + // facteur grossissement (x10) pour le trait + var factor = 3; - // valeur par defaut - if (!values.color) { - values.color = "#FFFFFF"; - } - // en fonction du type, on y ajoute le style - switch (type) { - case "text": - var styleText = "font-size: 5em;font-weight: bold;"; - svg = "url(\"data:image/svg+xml;utf8, T \")"; - div.style["background"] = svg - .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%opacity%", values.opacity || 1) - .replace("%style%", styleText); - break; - case "icon": - if (values.image) { - // FIXME on reste dans le paradigme d'utilisation du SVG..., - // mais probleme de ratio de l'image !? - svg = "" - .replace("%x%", this.options.sprites.json[values.image].x) - .replace("%y%", this.options.sprites.json[values.image].y) - .replace(/%w%/g, this.options.sprites.json[values.image].width) - .replace(/%h%/g, this.options.sprites.json[values.image].height) - .replace("%W%", this.options.sprites.size.w) - .replace("%H%", this.options.sprites.size.h) - .replace("%URL%", this.options.sprites.url); - div.innerHTML = svg; - } else { - var styleTextIcon = "fill: transparent;stroke-width: 10;"; - svg = "url(\"data:image/svg+xml;utf8,\")"; + // valeur par defaut + if (!values.color) { + values.color = "#FFFFFF"; + } + // en fonction du type, on y ajoute le style + switch (type) { + case "text": + var styleText = "font-size: 5em;font-weight: bold;"; + svg = "url(\"data:image/svg+xml;utf8, T \")"; div.style["background"] = svg .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%style%", styleTextIcon); - } - break; - case "line": - var lstrockedasharray = (Array.isArray(values["dasharray"])) ? values["dasharray"].join(" ") : 0; - svg = "url(\"data:image/svg+xml;utf8,\")"; - // svg = "url(\"data:image/svg+xml;utf8,\")"; - div.style["background"] = svg - .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%stroke-opacity%", values.opacity || 1) - .replace("%stroke-dasharray%", lstrockedasharray) - .replace("%stroke-width%", (values.width || 0) * factor); - break; - case "circle": - var cstrockcolor = values["stroke-color"] || "#FFFFFF"; - svg = "url(\"data:image/svg+xml;utf8,\")"; - div.style["background"] = svg - .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%opacity%", values.opacity || 1) - .replace("%stroke-color%", (cstrockcolor.indexOf("rgb") === 0) ? cstrockcolor : Color.hexToRgba(cstrockcolor, 1)) - .replace("%stroke-opacity%", values["stroke-opacity"] || 1) - .replace("%stroke-width%", (values["stroke-width"] || 0) * factor); - break; - case "background": - case "fill": - if (values.pattern) { - svg = "" - .replace("%x%", this.options.sprites.json[values.pattern].x) - .replace("%y%", this.options.sprites.json[values.pattern].y) - .replace(/%w%/g, this.options.sprites.json[values.pattern].width) - .replace(/%h%/g, this.options.sprites.json[values.pattern].height) - .replace("%W%", this.options.sprites.size.w) - .replace("%H%", this.options.sprites.size.h) - .replace("%URL%", this.options.sprites.url); - div.innerHTML = svg; - } else { - var fstrokecolor = values["outline-color"] || "#FFFFFF"; - svg = "url(\"data:image/svg+xml;utf8,\")"; + .replace("%opacity%", values.opacity || 1) + .replace("%style%", styleText); + break; + case "icon": + if (values.image) { + // FIXME on reste dans le paradigme d'utilisation du SVG..., + // mais probleme de ratio de l'image !? + svg = "" + .replace("%x%", this.options.sprites.json[values.image].x) + .replace("%y%", this.options.sprites.json[values.image].y) + .replace(/%w%/g, this.options.sprites.json[values.image].width) + .replace(/%h%/g, this.options.sprites.json[values.image].height) + .replace("%W%", this.options.sprites.size.w) + .replace("%H%", this.options.sprites.size.h) + .replace("%URL%", this.options.sprites.url); + div.innerHTML = svg; + } else { + var styleTextIcon = "fill: transparent;stroke-width: 10;"; + svg = "url(\"data:image/svg+xml;utf8,\")"; + div.style["background"] = svg + .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) + .replace("%style%", styleTextIcon); + } + break; + case "line": + var lstrockedasharray = (Array.isArray(values["dasharray"])) ? values["dasharray"].join(" ") : 0; + svg = "url(\"data:image/svg+xml;utf8,\")"; + // svg = "url(\"data:image/svg+xml;utf8,\")"; + div.style["background"] = svg + .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) + .replace("%stroke-opacity%", values.opacity || 1) + .replace("%stroke-dasharray%", lstrockedasharray) + .replace("%stroke-width%", (values.width || 0) * factor); + break; + case "circle": + var cstrockcolor = values["stroke-color"] || "#FFFFFF"; + svg = "url(\"data:image/svg+xml;utf8,\")"; div.style["background"] = svg .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) .replace("%opacity%", values.opacity || 1) - .replace("%stroke-color%", (fstrokecolor.indexOf("rgb") === 0) ? fstrokecolor : Color.hexToRgba(fstrokecolor, 1)); - } - break; - default: - logger.warn("type not found, no thumbnail..."); - return false; - } + .replace("%stroke-color%", (cstrockcolor.indexOf("rgb") === 0) ? cstrockcolor : Color.hexToRgba(cstrockcolor, 1)) + .replace("%stroke-opacity%", values["stroke-opacity"] || 1) + .replace("%stroke-width%", (values["stroke-width"] || 0) * factor); + break; + case "background": + case "fill": + if (values.pattern) { + svg = "" + .replace("%x%", this.options.sprites.json[values.pattern].x) + .replace("%y%", this.options.sprites.json[values.pattern].y) + .replace(/%w%/g, this.options.sprites.json[values.pattern].width) + .replace(/%h%/g, this.options.sprites.json[values.pattern].height) + .replace("%W%", this.options.sprites.size.w) + .replace("%H%", this.options.sprites.size.h) + .replace("%URL%", this.options.sprites.url); + div.innerHTML = svg; + } else { + var fstrokecolor = values["outline-color"] || "#FFFFFF"; + svg = "url(\"data:image/svg+xml;utf8,\")"; + div.style["background"] = svg + .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) + .replace("%opacity%", values.opacity || 1) + .replace("%stroke-color%", (fstrokecolor.indexOf("rgb") === 0) ? fstrokecolor : Color.hexToRgba(fstrokecolor, 1)); + } + break; + default: + logger.warn("type not found, no thumbnail..."); + return false; + } - return true; -}; + return true; + } -/** - * Get value - * - * @param {*} value - value of a property (ex. "#2BB3E1") - * @returns {*} return a verified value (ex. color": "#2BB3E1") - * - * @private - * @example - * // type simple for fill, line or circle type with string : - * // "paint": { - * // "fill-color": "#2BB3E1" - * // } - * - * // type simple for fill, line or circle type with array : - * // "paint": { - * // "line-dasharray": [2,10] - * // } - * - * // TODO type complexe : not yet implemented ! - * // "paint": { - * // "fill-color": [ - * // "match", - * // ["get","symbo"], - * // "ZONE_BOISEE","#A7DA81", - * // "ZONE_MANGROVE","#7E8AB5", - * // "#A7DA81" - * // ] - * // } - * - * // other type complexe : - * // "paint": { - * // "fill-color": { - * // "base": 1, - * // "stops": [ - * // [ - * // 15.5, - * // "#f2eae2" - * // ], - * // [ - * // 16, - * // "#dfdbd7" - * // ] - * // ] - * // } - * // } - */ -Legend.prototype._getValue = function (value) { - var result = null; - if (typeof value === "string") { - result = value; - } else if (typeof value === "number") { - result = value; - } else if (Array.isArray(value)) { - // cas d'un tableau de valeurs numériques : [1,2,3] - var isNumber = true; - value.forEach(v => { - if (typeof v !== "number") { - isNumber = false; - } - }); - if (isNumber) { + /** + * Get value + * + * @param {*} value - value of a property (ex. "#2BB3E1") + * @returns {*} return a verified value (ex. color": "#2BB3E1") + * + * @private + * @example + * // type simple for fill, line or circle type with string : + * // "paint": { + * // "fill-color": "#2BB3E1" + * // } + * + * // type simple for fill, line or circle type with array : + * // "paint": { + * // "line-dasharray": [2,10] + * // } + * + * // TODO type complexe : not yet implemented ! + * // "paint": { + * // "fill-color": [ + * // "match", + * // ["get","symbo"], + * // "ZONE_BOISEE","#A7DA81", + * // "ZONE_MANGROVE","#7E8AB5", + * // "#A7DA81" + * // ] + * // } + * + * // other type complexe : + * // "paint": { + * // "fill-color": { + * // "base": 1, + * // "stops": [ + * // [ + * // 15.5, + * // "#f2eae2" + * // ], + * // [ + * // 16, + * // "#dfdbd7" + * // ] + * // ] + * // } + * // } + */ + _getValue (value) { + var result = null; + if (typeof value === "string") { result = value; - } - } else if (typeof value === "object") { - result = null; - if ("stops" in value) { - // on realise un ordre inversé sur les zooms - value.stops.sort((a, b) => { - var numA = a[0]; - var numB = b[0]; - if (numA > numB) { - return -1; - } - if (numA < numB) { - return 1; + } else if (typeof value === "number") { + result = value; + } else if (Array.isArray(value)) { + // cas d'un tableau de valeurs numériques : [1,2,3] + var isNumber = true; + value.forEach(v => { + if (typeof v !== "number") { + isNumber = false; } - return 0; }); - // et, on prend le plus petit zoom - var lastStopsValue = value.stops.slice(-1); - result = lastStopsValue[0][1]; + if (isNumber) { + result = value; + } + } else if (typeof value === "object") { + result = null; + if ("stops" in value) { + // on realise un ordre inversé sur les zooms + value.stops.sort((a, b) => { + var numA = a[0]; + var numB = b[0]; + if (numA > numB) { + return -1; + } + if (numA < numB) { + return 1; + } + return 0; + }); + // et, on prend le plus petit zoom + var lastStopsValue = value.stops.slice(-1); + result = lastStopsValue[0][1]; + } + } else { + logger.warn("value not supported !"); } - } else { - logger.warn("value not supported !"); + return result; } - return result; -}; -// ################################################################### // -// ######################### DOM methods ############################# // -// ################################################################### // - -/** -* Create a Graphical Legend Icon -* -* @param {Object} params - param -* @param {String} params.title - title -* @param {String} params.type - fill, line, circle, text, icon, ... -* @param {String} params.values - {"color": "#2BB3E1", "width": 10, "opacity": 0.5, "stroke": "#2BB3E1"} -* @param {Boolean} params.edit - editable with a colorPicker for only line, fill and circle legend ! -* @returns {DOMElement} DOM element -* -* @private -* @example -*
-*
-*
-* vide... -*
-*/ -Legend.prototype._createElementIconLegend = function (params) { - // contexte - var self = this; - - var container = document.createElement("div"); - container.className = this.name.containerlegendrender; - - var div = this.rendercontainer = document.createElement("div"); - div.className = this.name.legendrender; - if (params.edit) { - div.className += " "; - div.className += this.name.legendeditable; - if (div.addEventListener) { - div.addEventListener("click", function (e) { - self.onEditionLegendMapBox(e); - }); - } else if (div.attachEvent) { - div.attachEvent("onclick", function (e) { - self.onEditionLegendMapBox(e); - }); + // ################################################################### // + // ######################### DOM methods ############################# // + // ################################################################### // + /** + * Create a Graphical Legend Icon + * + * @param {Object} params - param + * @param {String} params.title - title + * @param {String} params.type - fill, line, circle, text, icon, ... + * @param {String} params.values - {"color": "#2BB3E1", "width": 10, "opacity": 0.5, "stroke": "#2BB3E1"} + * @param {Boolean} params.edit - editable with a colorPicker for only line, fill and circle legend ! + * @returns {DOMElement} DOM element + * + * @private + * @example + *
+ *
+ *
+ * vide... + *
+ */ + _createElementIconLegend (params) { + // contexte + var self = this; + + var container = document.createElement("div"); + container.className = this.name.containerlegendrender; + + var div = this.rendercontainer = document.createElement("div"); + div.className = this.name.legendrender; + if (params.edit) { + div.className += " "; + div.className += this.name.legendeditable; + if (div.addEventListener) { + div.addEventListener("click", function (e) { + self.onEditionLegendMapBox(e); + }); + } else if (div.attachEvent) { + div.attachEvent("onclick", function (e) { + self.onEditionLegendMapBox(e); + }); + } } - } - // type de legende - var type = params.type; - - // TODO className - // div.className += " legend-not-implemented"; - - // ajout du style sur la div de rendu - if (this._renderThumbnail(type, params.values)) { - // className possibles : - // " legend-text" - // " legend-icon" - // " legend-background" - // " legend-line" - // " legend-line-not-editable" - // " legend-circle" - // " legend-circle-not-editable" - // " legend-fill" - // " legend-fill-not-editable" - div.className += (params.edit) ? " legend-" + type : " legend-" + type + "-not-editable"; - } else { - div.className += " legend-unknow"; - } - - container.appendChild(div); + // type de legende + var type = params.type; + + // TODO className + // div.className += " legend-not-implemented"; + // ajout du style sur la div de rendu + if (this._renderThumbnail(type, params.values)) { + // className possibles : + // " legend-text" + // " legend-icon" + // " legend-background" + // " legend-line" + // " legend-line-not-editable" + // " legend-circle" + // " legend-circle-not-editable" + // " legend-fill" + // " legend-fill-not-editable" + div.className += (params.edit) ? " legend-" + type : " legend-" + type + "-not-editable"; + } else { + div.className += " legend-unknow"; + } - var span = document.createElement("span"); - span.className = this.name.legendtitle; - span.innerHTML = params.title || ""; - container.appendChild(span); + container.appendChild(div); - return container; -}; + var span = document.createElement("span"); + span.className = this.name.legendtitle; + span.innerHTML = params.title || ""; + container.appendChild(span); -/** -* Create a Graphical Legend Edition -* -* @param {Object} params - param -* @param {String} params.type - fill, line, (TODO : circle, icon or text) -* @param {String} params.values - {"fill-color": "#2BB3E1"} -* @param {Boolean} params.edit - editable with a colorPicker for only line and fill legend ! -* @returns {DOMElement} DOM element -* -* @private -* @example -*
-*
-* -* -*
-*
-* -* -*
-*
-* -* -*
-*
-* -* -*
-*
-* -* -*
-*
-*/ -Legend.prototype._createElementEditionLegend = function (params) { - // contexte - var self = this; - - var container = document.createElement("div"); - container.className = this.name.containerlegendtools; - - // uniquement les elements editables ! - if (!params.edit) { return container; } - // on ne traite que l'edition du mode 'traits' ou 'surfaciques' - // mode 'line' - switch (params.type) { - case "line": - createLineColor.call(self); - createLineWidth.call(self); - createLineOpacity.call(self); - break; - case "background": - case "fill": - createFillColor.call(self); - createFillOpacity.call(self); - break; - default: - break; - } + /** + * Create a Graphical Legend Edition + * + * @param {Object} params - param + * @param {String} params.type - fill, line, (TODO : circle, icon or text) + * @param {String} params.values - {"fill-color": "#2BB3E1"} + * @param {Boolean} params.edit - editable with a colorPicker for only line and fill legend ! + * @returns {DOMElement} DOM element + * + * @private + * @example + *
+ *
+ * + * + *
+ *
+ * + * + *
+ *
+ * + * + *
+ *
+ * + * + *
+ *
+ * + * + *
+ *
+ */ + _createElementEditionLegend (params) { + // contexte + var self = this; + + var container = document.createElement("div"); + container.className = this.name.containerlegendtools; + + // uniquement les elements editables ! + if (!params.edit) { + return container; + } - // couleur du trait - function createLineColor () { - var linecolor = document.createElement("div"); - linecolor.className = "legend-styling-div"; - var lLineColor = document.createElement("label"); - lLineColor.className = "legend-line"; - lLineColor.htmlFor = this.id ? "line-color-" + this.id : "line-color"; - lLineColor.innerHTML = this.labels["line-color"]; - var inputLineColor = document.createElement("input"); - inputLineColor.className = "legend-styling"; - inputLineColor.id = this.id ? "line-color-" + this.id : "line-color"; - inputLineColor.title = "Selectionner une couleur de trait"; - inputLineColor.type = "color"; - inputLineColor.value = params.values.color; - inputLineColor.setAttribute("data-id", "line-color"); - if (inputLineColor.addEventListener) { - inputLineColor.addEventListener("change", function (e) { - self._renderThumbnail(params.type, Object.assign(params.values, { - color : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputLineColor.attachEvent) { - inputLineColor.attachEvent("onchange", function (e) { - self._renderThumbnail(params.type, Object.assign(params.values, { - color : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); + // on ne traite que l'edition du mode 'traits' ou 'surfaciques' + // mode 'line' + switch (params.type) { + case "line": + createLineColor.call(self); + createLineWidth.call(self); + createLineOpacity.call(self); + break; + case "background": + case "fill": + createFillColor.call(self); + createFillOpacity.call(self); + break; + default: + break; } - linecolor.appendChild(lLineColor); - linecolor.appendChild(inputLineColor); - container.appendChild(linecolor); - } - // epaisseur du trait - function createLineWidth () { - var linewidth = document.createElement("div"); - linewidth.className = "legend-styling-div"; - var lLineWidth = document.createElement("label"); - lLineWidth.className = "legend-line"; - lLineWidth.htmlFor = this.id ? "line-width-" + this.id : "line-width"; - lLineWidth.innerHTML = this.labels["line-width"]; - var inputLineWidth = document.createElement("input"); - inputLineWidth.className = "legend-styling"; - inputLineWidth.id = this.id ? "line-width-" + this.id : "line-width"; - inputLineWidth.title = params.values.width; - inputLineWidth.type = "range"; - inputLineWidth.min = "0"; - inputLineWidth.max = "10"; - inputLineWidth.step = "1"; - inputLineWidth.defaultValue = params.values.width; - inputLineWidth.setAttribute("data-id", "line-width"); - if (inputLineWidth.addEventListener) { - inputLineWidth.addEventListener("change", function (e) { - logger.trace(e); - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - width : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputLineWidth.attachEvent) { - inputLineWidth.attachEvent("onchange", function (e) { - logger.trace(e); - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - width : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); + // couleur du trait + function createLineColor () { + var linecolor = document.createElement("div"); + linecolor.className = "legend-styling-div"; + var lLineColor = document.createElement("label"); + lLineColor.className = "legend-line"; + lLineColor.htmlFor = this.id ? "line-color-" + this.id : "line-color"; + lLineColor.innerHTML = this.labels["line-color"]; + var inputLineColor = document.createElement("input"); + inputLineColor.className = "legend-styling"; + inputLineColor.id = this.id ? "line-color-" + this.id : "line-color"; + inputLineColor.title = "Selectionner une couleur de trait"; + inputLineColor.type = "color"; + inputLineColor.value = params.values.color; + inputLineColor.setAttribute("data-id", "line-color"); + if (inputLineColor.addEventListener) { + inputLineColor.addEventListener("change", function (e) { + self._renderThumbnail(params.type, Object.assign(params.values, { + color : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } else if (inputLineColor.attachEvent) { + inputLineColor.attachEvent("onchange", function (e) { + self._renderThumbnail(params.type, Object.assign(params.values, { + color : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } + linecolor.appendChild(lLineColor); + linecolor.appendChild(inputLineColor); + container.appendChild(linecolor); } - linewidth.appendChild(lLineWidth); - linewidth.appendChild(inputLineWidth); - container.appendChild(linewidth); - } - // opacité du trait - function createLineOpacity () { - var lineopacity = document.createElement("div"); - lineopacity.className = "legend-styling-div"; - var lLineOpacity = document.createElement("label"); - lLineOpacity.className = "legend-line"; - lLineOpacity.htmlFor = this.id ? "line-opacity-" + this.id : "line-opacity"; - lLineOpacity.innerHTML = this.labels["line-opacity"]; - var inputLineOpacity = document.createElement("input"); - inputLineOpacity.className = "legend-styling"; - inputLineOpacity.id = this.id ? "line-opacity-" + this.id : "line-opacity"; - inputLineOpacity.title = params.values.opacity; - inputLineOpacity.type = "range"; - inputLineOpacity.min = "0"; - inputLineOpacity.max = "1"; - inputLineOpacity.step = "0.1"; - inputLineOpacity.defaultValue = params.values.opacity; - inputLineOpacity.setAttribute("data-id", "line-opacity"); - if (inputLineOpacity.addEventListener) { - inputLineOpacity.addEventListener("change", function (e) { - logger.trace(e); - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - opacity : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputLineOpacity.attachEvent) { - inputLineOpacity.attachEvent("onchange", function (e) { - logger.trace(e); - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - opacity : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); + // epaisseur du trait + function createLineWidth () { + var linewidth = document.createElement("div"); + linewidth.className = "legend-styling-div"; + var lLineWidth = document.createElement("label"); + lLineWidth.className = "legend-line"; + lLineWidth.htmlFor = this.id ? "line-width-" + this.id : "line-width"; + lLineWidth.innerHTML = this.labels["line-width"]; + var inputLineWidth = document.createElement("input"); + inputLineWidth.className = "legend-styling"; + inputLineWidth.id = this.id ? "line-width-" + this.id : "line-width"; + inputLineWidth.title = params.values.width; + inputLineWidth.type = "range"; + inputLineWidth.min = "0"; + inputLineWidth.max = "10"; + inputLineWidth.step = "1"; + inputLineWidth.defaultValue = params.values.width; + inputLineWidth.setAttribute("data-id", "line-width"); + if (inputLineWidth.addEventListener) { + inputLineWidth.addEventListener("change", function (e) { + logger.trace(e); + e.target.title = e.target.value; + self._renderThumbnail(params.type, Object.assign(params.values, { + width : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } else if (inputLineWidth.attachEvent) { + inputLineWidth.attachEvent("onchange", function (e) { + logger.trace(e); + e.target.title = e.target.value; + self._renderThumbnail(params.type, Object.assign(params.values, { + width : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } + linewidth.appendChild(lLineWidth); + linewidth.appendChild(inputLineWidth); + container.appendChild(linewidth); } - lineopacity.appendChild(lLineOpacity); - lineopacity.appendChild(inputLineOpacity); - container.appendChild(lineopacity); - } - // couleur de remplissage - function createFillColor () { - var fillcolor = document.createElement("div"); - fillcolor.className = "legend-styling-div"; - var lFillColor = document.createElement("label"); - lFillColor.className = "legend-fill"; - lFillColor.htmlFor = this.id ? "fill-color-" + this.id : "fill-color"; - lFillColor.innerHTML = this.labels["fill-color"]; - var inputFillColor = document.createElement("input"); - inputFillColor.className = "legend-styling"; - inputFillColor.id = this.id ? "fill-color-" + this.id : "fill-color"; - inputFillColor.title = "Selectionner une couleur de remplissage"; - inputFillColor.type = "color"; - inputFillColor.value = params.values.color; - inputFillColor.setAttribute("data-id", "fill-color"); - if (inputFillColor.addEventListener) { - inputFillColor.addEventListener("change", function (e) { - self._renderThumbnail(params.type, Object.assign(params.values, { - color : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputFillColor.attachEvent) { - inputFillColor.attachEvent("onchange", function (e) { - self._renderThumbnail(params.type, Object.assign(params.values, { - color : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); + // opacité du trait + function createLineOpacity () { + var lineopacity = document.createElement("div"); + lineopacity.className = "legend-styling-div"; + var lLineOpacity = document.createElement("label"); + lLineOpacity.className = "legend-line"; + lLineOpacity.htmlFor = this.id ? "line-opacity-" + this.id : "line-opacity"; + lLineOpacity.innerHTML = this.labels["line-opacity"]; + var inputLineOpacity = document.createElement("input"); + inputLineOpacity.className = "legend-styling"; + inputLineOpacity.id = this.id ? "line-opacity-" + this.id : "line-opacity"; + inputLineOpacity.title = params.values.opacity; + inputLineOpacity.type = "range"; + inputLineOpacity.min = "0"; + inputLineOpacity.max = "1"; + inputLineOpacity.step = "0.1"; + inputLineOpacity.defaultValue = params.values.opacity; + inputLineOpacity.setAttribute("data-id", "line-opacity"); + if (inputLineOpacity.addEventListener) { + inputLineOpacity.addEventListener("change", function (e) { + logger.trace(e); + e.target.title = e.target.value; + self._renderThumbnail(params.type, Object.assign(params.values, { + opacity : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } else if (inputLineOpacity.attachEvent) { + inputLineOpacity.attachEvent("onchange", function (e) { + logger.trace(e); + e.target.title = e.target.value; + self._renderThumbnail(params.type, Object.assign(params.values, { + opacity : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } + lineopacity.appendChild(lLineOpacity); + lineopacity.appendChild(inputLineOpacity); + container.appendChild(lineopacity); + } + + // couleur de remplissage + function createFillColor () { + var fillcolor = document.createElement("div"); + fillcolor.className = "legend-styling-div"; + var lFillColor = document.createElement("label"); + lFillColor.className = "legend-fill"; + lFillColor.htmlFor = this.id ? "fill-color-" + this.id : "fill-color"; + lFillColor.innerHTML = this.labels["fill-color"]; + var inputFillColor = document.createElement("input"); + inputFillColor.className = "legend-styling"; + inputFillColor.id = this.id ? "fill-color-" + this.id : "fill-color"; + inputFillColor.title = "Selectionner une couleur de remplissage"; + inputFillColor.type = "color"; + inputFillColor.value = params.values.color; + inputFillColor.setAttribute("data-id", "fill-color"); + if (inputFillColor.addEventListener) { + inputFillColor.addEventListener("change", function (e) { + self._renderThumbnail(params.type, Object.assign(params.values, { + color : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } else if (inputFillColor.attachEvent) { + inputFillColor.attachEvent("onchange", function (e) { + self._renderThumbnail(params.type, Object.assign(params.values, { + color : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } + fillcolor.appendChild(lFillColor); + fillcolor.appendChild(inputFillColor); + container.appendChild(fillcolor); } - fillcolor.appendChild(lFillColor); - fillcolor.appendChild(inputFillColor); - container.appendChild(fillcolor); + + // opacité du remplissage + function createFillOpacity () { + var fillopacity = document.createElement("div"); + fillopacity.className = "legend-styling-div"; + var lFillOpacity = document.createElement("label"); + lFillOpacity.className = "legend-fill"; + lFillOpacity.htmlFor = this.id ? "fill-opacity-" + this.id : "fill-opacity"; + lFillOpacity.innerHTML = this.labels["fill-opacity"]; + var inputFillOpacity = document.createElement("input"); + inputFillOpacity.className = "legend-styling"; + inputFillOpacity.id = this.id ? "fill-opacity-" + this.id : "fill-opacity"; + inputFillOpacity.title = params.values.opacity; + inputFillOpacity.type = "range"; + inputFillOpacity.min = "0"; + inputFillOpacity.max = "1"; + inputFillOpacity.step = "0.1"; + inputFillOpacity.defaultValue = params.values.opacity; + inputFillOpacity.setAttribute("data-id", "fill-opacity"); + if (inputFillOpacity.addEventListener) { + inputFillOpacity.addEventListener("change", function (e) { + e.target.title = e.target.value; + self._renderThumbnail(params.type, Object.assign(params.values, { + opacity : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } else if (inputFillOpacity.attachEvent) { + inputFillOpacity.attachEvent("onchange", function (e) { + e.target.title = e.target.value; + self._renderThumbnail(params.type, Object.assign(params.values, { + opacity : e.target.value + })); + self.onChangeValueLegendMapBox(e); + }); + } + fillopacity.appendChild(lFillOpacity); + fillopacity.appendChild(inputFillOpacity); + container.appendChild(fillopacity); + } + + return container; } - // opacité du remplissage - function createFillOpacity () { - var fillopacity = document.createElement("div"); - fillopacity.className = "legend-styling-div"; - var lFillOpacity = document.createElement("label"); - lFillOpacity.className = "legend-fill"; - lFillOpacity.htmlFor = this.id ? "fill-opacity-" + this.id : "fill-opacity"; - lFillOpacity.innerHTML = this.labels["fill-opacity"]; - var inputFillOpacity = document.createElement("input"); - inputFillOpacity.className = "legend-styling"; - inputFillOpacity.id = this.id ? "fill-opacity-" + this.id : "fill-opacity"; - inputFillOpacity.title = params.values.opacity; - inputFillOpacity.type = "range"; - inputFillOpacity.min = "0"; - inputFillOpacity.max = "1"; - inputFillOpacity.step = "0.1"; - inputFillOpacity.defaultValue = params.values.opacity; - inputFillOpacity.setAttribute("data-id", "fill-opacity"); - if (inputFillOpacity.addEventListener) { - inputFillOpacity.addEventListener("change", function (e) { - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - opacity : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputFillOpacity.attachEvent) { - inputFillOpacity.attachEvent("onchange", function (e) { - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - opacity : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Add element into target DOM + * + * @returns {Object} - Legend instance + */ + add () { + if (!this.options.target) { + if (!document.getElementById(this.name.target)) { + var div = document.createElement("div"); + div.id = this.name.target; + var node = document.documentElement || + document.getElementsByTagName("body")[0] || + document.getElementsByTagName("head")[0]; + node.appendChild(div); + } + this.options.target = document.getElementById(this.name.target); } - fillopacity.appendChild(lFillOpacity); - fillopacity.appendChild(inputFillOpacity); - container.appendChild(fillopacity); + if (this.container) { + this.options.target.appendChild(this.container); + } + return this; } - return container; -}; + /** + * Set display container or get + * + * @param {Boolean} display - show/hidden container or get status + * @returns {Boolean} - true/false + */ + display (display) { + logger.trace("display()", display); + if (typeof display !== "undefined") { + this.container.style.display = (display) ? "flex" : "none"; + } + return (this.container.style.display === "flex"); + } -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // + /** + * Is editable + * + * @returns {Boolean} - true/false + */ + isEditable () { + return this.editable; + } -/** - * Add element into target DOM - * - * @returns {Object} - Legend instance - */ -Legend.prototype.add = function () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); - } - this.options.target = document.getElementById(this.name.target); + /** + * Get container Legend Render (DOM) + * + * @returns {DOMElement} DOM element + * @see Layer.prototype.slotLegend() + * @example + *
+ */ + getRenderContainer () { + return this.rendercontainer; } - if (this.container) { - this.options.target.appendChild(this.container); + + /** + * Get container Legend Tools (DOM) + * + * @returns {DOMElement} DOM element + * @see Layer.prototype.slotLegend() + * @example + *
...
+ */ + getToolsContainer () { + return this.toolscontainer; } - return this; -}; -/** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ -Legend.prototype.display = function (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; + /** + * Get container (DOM) + * + * @returns {DOMElement} DOM element + */ + getContainer () { + return this.container; } - return (this.container.style.display === "flex"); -}; -/** - * Is editable - * - * @returns {Boolean} - true/false - */ -Legend.prototype.isEditable = function () { - return this.editable; -}; + // ################################################################### // + // ####################### handlers events to dom #################### // + // ################################################################### // + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Legend#editor:legend:onclickedition + */ + onEditionLegendMapBox (e) { + logger.trace("onEditionLegendMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.legend.onclickedition, e); + } -/** - * Get container Legend Render (DOM) - * - * @returns {DOMElement} DOM element - * @see Layer.prototype.slotLegend() - * @example - *
- */ -Legend.prototype.getRenderContainer = function () { - return this.rendercontainer; -}; + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Legend#editor:legend:onchangevalue + */ + onChangeValueLegendMapBox (e) { + logger.trace("onChangeValueLegendMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.legend.onchangevalue, e); + } -/** - * Get container Legend Tools (DOM) - * - * @returns {DOMElement} DOM element - * @see Layer.prototype.slotLegend() - * @example - *
...
- */ -Legend.prototype.getToolsContainer = function () { - return this.toolscontainer; }; -/** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ -Legend.prototype.getContainer = function () { - return this.container; -}; +; // ################################################################### // -// ####################### handlers events to dom #################### // +// ########################## CONSTANTES ############################# // // ################################################################### // /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Legend#editor:legend:onclickedition + * List of supported properties */ -Legend.prototype.onEditionLegendMapBox = function (e) { - logger.trace("onEditionLegendMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.legend.onclickedition, e); +Legend.PROPERTIES = { + line : [ + "line-color", + "line-dasharray", + "line-opacity", + "line-width" + ], + fill : [ + "fill-color", + "fill-opacity", + "fill-outline-color", + "fill-pattern" + ], + background : [ + "background-color", + "background-opacity", + "background-pattern" + ], + circle : [ + "circle-color", + "circle-opacity", + "circle-stroke-color", + "circle-stroke-opacity", + "circle-stroke-width" + ], + icon : [ + "icon-color", + "icon-image", + "icon-opacity", + "__icon-size" + ], + text : [ + "__text-anchor", + "text-color", + "text-field", + "__text-font", + "__text-opacity", + "__text-size" + ] }; -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Legend#editor:legend:onchangevalue - */ -Legend.prototype.onChangeValueLegendMapBox = function (e) { - logger.trace("onChangeValueLegendMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.legend.onchangevalue, e); -}; export default Legend; diff --git a/src/OpenLayers/Controls/Editor/Search.js b/src/OpenLayers/Controls/Editor/Search.js index ff5e18026..5eb597463 100644 --- a/src/OpenLayers/Controls/Editor/Search.js +++ b/src/OpenLayers/Controls/Editor/Search.js @@ -27,197 +27,191 @@ var logger = Logger.getLogger("editor-search"); * Search.display(true); * Search.getContainer(); */ -function Search (options) { - logger.trace("[constructor] Search", options); - - // options - this.options = options || { - // default... - target : null, - tools : null, - title : null, - obj : null - }; - - if (!(this instanceof Search)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); -}; - -/** - * Constructor (alias) - * - * @private - */ -Search.prototype.constructor = Search; - -/** - * Initialize component - * (called by constructor) - * - * @private - */ -Search.prototype._initialize = function () { - // unique editor id (optional!) - this.id = this.options.id || null; - - if (!this.options.target) { - // cf. add() - } +class Search { + + constructor (options) { + logger.trace("[constructor] Search", options); + + // options + this.options = options || { + // default... + target : null, + tools : null, + title : null, + obj : null + }; + + if (!(this instanceof Search)) { + throw new TypeError("ERROR CLASS_CONSTRUCTOR"); + } - var _toolsDefault = {}; + this._initialize(); - if (!this.options.tools) { - this.options.tools = _toolsDefault; + this._initContainer(); } - Utils.mergeParams(this.options.tools, _toolsDefault, false); + /** + * Initialize component + * (called by constructor) + * + * @private + */ + _initialize () { + // unique editor id (optional!) + this.id = this.options.id || null; + + if (!this.options.target) { + // cf. add() + } - if (!this.options.obj) { - // choix d'avoir un objet vide pour une edition futur... - this.options.obj = {}; - } + var _toolsDefault = {}; - if (!this.options.title) { - this.options.title = "Recherche de couches :"; - } - this.container = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxSearchTarget", - container : "GPEditorMapBoxSearchContainer" - // TODO ... - }; -}; + if (!this.options.tools) { + this.options.tools = _toolsDefault; + } -/** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- * // ... - *
- */ -Search.prototype._initContainer = function () { - // contexte - // var self = this; + Utils.mergeParams(this.options.tools, _toolsDefault, false); - var _search = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! + if (!this.options.obj) { + // choix d'avoir un objet vide pour une edition futur... + this.options.obj = {}; + } - if (_search.layers) { - if (_search.layers.length === 0) { - logger.info("tag 'layers' is empty !"); + if (!this.options.title) { + this.options.title = "Recherche de couches :"; } + this.container = null; + + // DOM : className or id + this.name = { + target : "GPEditorMapBoxSearchTarget", + container : "GPEditorMapBoxSearchContainer" + // TODO ... + }; } - var div = document.createElement("div"); - div.className = this.name.container; - - // TODO... - // outil de recherche des couches mapbox. - // 2 modes de recherches : exact ou par autocompletion - // affichage des resultats directement dans la liste des couches - // la recherche porte sur les champs suiavnts (options): - // * id (par defaut) - // * source-layer (par defaut) - // * type (ex. Symbol) - // * field (ex. HOPITAL_PONC) > recherche dans le champs filtre - - // main container - this.container = div; -}; + /** + * Graphical rendering of the component + * (called by constructor) + * + * @private + * @example + *
+ * // ... + *
+ */ + _initContainer () { + // contexte + // var self = this; + var _search = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! + + if (_search.layers) { + if (_search.layers.length === 0) { + logger.info("tag 'layers' is empty !"); + } + } -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // + var div = document.createElement("div"); + div.className = this.name.container; + + // TODO... + // outil de recherche des couches mapbox. + // 2 modes de recherches : exact ou par autocompletion + // affichage des resultats directement dans la liste des couches + // la recherche porte sur les champs suiavnts (options): + // * id (par defaut) + // * source-layer (par defaut) + // * type (ex. Symbol) + // * field (ex. HOPITAL_PONC) > recherche dans le champs filtre + // main container + this.container = div; + } -/** - * Add element into target DOM - * @returns {Object} - Search instance - */ -Search.prototype.add = function () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Add element into target DOM + * @returns {Object} - Search instance + */ + add () { + if (!this.options.target) { + if (!document.getElementById(this.name.target)) { + var div = document.createElement("div"); + div.id = this.name.target; + var node = document.documentElement || + document.getElementsByTagName("body")[0] || + document.getElementsByTagName("head")[0]; + node.appendChild(div); + } + this.options.target = document.getElementById(this.name.target); + } + if (this.container) { + this.options.target.appendChild(this.container); } - this.options.target = document.getElementById(this.name.target); + return this; } - if (this.container) { - this.options.target.appendChild(this.container); + + /** + * Set display container or get + * + * @param {Boolean} display - show/hidden container or get status + * @returns {Boolean} - true/false + */ + display (display) { + logger.trace("display()", display); + if (typeof display !== "undefined") { + this.container.style.display = (display) ? "flex" : "none"; + } + return (this.container.style.display === "flex"); } - return this; -}; -/** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ -Search.prototype.display = function (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; + /** + * Get container (DOM) + * + * @returns {DOMElement} DOM element + */ + getContainer () { + return this.container; } - return (this.container.style.display === "flex"); -}; -/** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ -Search.prototype.getContainer = function () { - return this.container; -}; -// ################################################################### // -// ####################### handlers events to dom #################### // -// ################################################################### // + // ################################################################### // + // ####################### handlers events to dom #################### // + // ################################################################### // + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Search#editor:search:onsubmit + */ + onSubmitSearchLayersMapBox (e) { + logger.trace("onSubmitSearchLayersMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.search.onsubmit, e); + } -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Search#editor:search:onsubmit - */ -Search.prototype.onSubmitSearchLayersMapBox = function (e) { - logger.trace("onSubmitSearchLayersMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.search.onsubmit, e); -}; + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Search#editor:search:onautocomplete + */ + onAutocompleteSearchLayersMapBox (e) { + logger.trace("onAutocompleteSearchLayersMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.search.onautocomplete, e); + } -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Search#editor:search:onautocomplete - */ -Search.prototype.onAutocompleteSearchLayersMapBox = function (e) { - logger.trace("onAutocompleteSearchLayersMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.search.onautocomplete, e); }; export default Search; diff --git a/src/OpenLayers/Controls/Editor/Style.js b/src/OpenLayers/Controls/Editor/Style.js index 22fa776f3..5a8ecd55a 100644 --- a/src/OpenLayers/Controls/Editor/Style.js +++ b/src/OpenLayers/Controls/Editor/Style.js @@ -31,434 +31,428 @@ var logger = Logger.getLogger("editor-style"); * style.display(true); * style.getContainer(); */ -function Style (options) { - logger.trace("[constructor] Style", options); - - // options - this.options = options || { - // default... - target : null, - position : 0, - tools : null, - title : null, - obj : null - }; - - if (!(this instanceof Style)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } +class Style { + + constructor (options) { + logger.trace("[constructor] Style", options); + + // options + this.options = options || { + // default... + target : null, + position : 0, + tools : null, + title : null, + obj : null + }; - this._initialize(); + if (!(this instanceof Style)) { + throw new TypeError("ERROR CLASS_CONSTRUCTOR"); + } - this._initContainer(); -}; + this._initialize(); -/** - * Constructor (alias) - * - * @private - */ -Style.prototype.constructor = Style; + this._initContainer(); + } -/** - * Initialize component - * (called by constructor) - * - * @private - */ -Style.prototype._initialize = function () { - // unique editor id (optional!) - this.id = this.options.id || null; + /** + * Initialize component + * (called by constructor) + * + * @private + */ + _initialize () { + // unique editor id (optional!) + this.id = this.options.id || null; + + if (!this.options.target) { + // cf. add() + } - if (!this.options.target) { - // cf. add() - } + if (!this.options.position) { + this.options.position = 0; + } - if (!this.options.position) { - this.options.position = 0; - } + var _toolsDefault = { + scale : true, + edition : false + }; - var _toolsDefault = { - scale : true, - edition : false - }; + if (!this.options.tools) { + this.options.tools = _toolsDefault; + } - if (!this.options.tools) { - this.options.tools = _toolsDefault; - } + Utils.mergeParams(this.options.tools, _toolsDefault, false); - Utils.mergeParams(this.options.tools, _toolsDefault, false); + if (!this.options.obj) { + // choix d'avoir un objet vide pour une edition futur... + this.options.obj = { + paint : {}, + layout : {} + }; + } + + if (!this.options.title) { + this.options.title = "JSON Styles :"; + } - if (!this.options.obj) { - // choix d'avoir un objet vide pour une edition futur... - this.options.obj = { - paint : {}, - layout : {} + this.container = null; + + // DOM : className or id + this.name = { + target : "GPEditorMapBoxStyleTarget", + container : "GPEditorMapBoxStyleContainer", + containerjson : "GPEditorMapBoxStyleJsonContainer", + jsonlabel : "GPEditorMapBoxStyleJsonTitle", + jsondisplay : "GPEditorMapBoxStyleJsonDisplay", + containertoolsscale : "GPEditorMapBoxStyleToolsScaleContainer", + scaletitle : "GPEditorMapBoxStyleScaleTitle", + containertoolsminscale : "GPEditorMapBoxStyleToolsScaleMinContainer", + scalelabelmin : "GPEditorMapBoxStyleScaleLabelMin", + scaleinputmin : "GPEditorMapBoxStyleScaleInputMin", + containertoolsmaxscale : "GPEditorMapBoxStyleToolsScaleMaxContainer", + scalelabelmax : "GPEditorMapBoxStyleScaleLabelMax", + scaleinputmax : "GPEditorMapBoxStyleScaleInputMax", + containertoolsedit : "GPEditorMapBoxStyleToolsEditionContainer" }; } - if (!this.options.title) { - this.options.title = "JSON Styles :"; - } + /** + * Graphical rendering of the component + * ie. this.container + * (called by constructor) + * + * @private + * @example + *
+ *
+ * + *
...
+ *
+ *
+ *
+ *
+ */ + _initContainer () { + // contexte + var self = this; + + var _found = false; + var _obj = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! + var _style = {}; + + // styles into tag 'paint' ? + if (_obj.paint) { + _found = true; + _style.paint = _obj.paint; + if (Object.keys(_obj.paint).length === 0) { + logger.info("tag 'paint' is empty !"); + } + } - this.container = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxStyleTarget", - container : "GPEditorMapBoxStyleContainer", - containerjson : "GPEditorMapBoxStyleJsonContainer", - jsonlabel : "GPEditorMapBoxStyleJsonTitle", - jsondisplay : "GPEditorMapBoxStyleJsonDisplay", - containertoolsscale : "GPEditorMapBoxStyleToolsScaleContainer", - scaletitle : "GPEditorMapBoxStyleScaleTitle", - containertoolsminscale : "GPEditorMapBoxStyleToolsScaleMinContainer", - scalelabelmin : "GPEditorMapBoxStyleScaleLabelMin", - scaleinputmin : "GPEditorMapBoxStyleScaleInputMin", - containertoolsmaxscale : "GPEditorMapBoxStyleToolsScaleMaxContainer", - scalelabelmax : "GPEditorMapBoxStyleScaleLabelMax", - scaleinputmax : "GPEditorMapBoxStyleScaleInputMax", - containertoolsedit : "GPEditorMapBoxStyleToolsEditionContainer" - }; -}; + // if not, search into tag 'layout' ! + if (_obj.layout) { + _found = true; + _style.layout = _obj.layout; + // FIXME delete visibility from display ? + if (_obj.layout.visibility) { + delete _style.visibility; + } + if (Object.keys(_obj.layout).length === 0) { + logger.info("tag 'layout' is empty !"); + } + } -/** - * Graphical rendering of the component - * ie. this.container - * (called by constructor) - * - * @private - * @example - *
- *
- * - *
...
- *
- *
- *
- *
- */ -Style.prototype._initContainer = function () { - // contexte - var self = this; - - var _found = false; - var _obj = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! - var _style = {}; - - // styles into tag 'paint' ? - if (_obj.paint) { - _found = true; - _style.paint = _obj.paint; - if (Object.keys(_obj.paint).length === 0) { - logger.info("tag 'paint' is empty !"); + var div = document.createElement("div"); + div.className = this.name.container; + + var json = null; + if (_found) { + var strJson = JSON.stringify(_style, null, 4); + json = this._syntaxHighlight(strJson); } - } - // if not, search into tag 'layout' ! - if (_obj.layout) { - _found = true; - _style.layout = _obj.layout; - // FIXME delete visibility from display ? - if (_obj.layout.visibility) { - delete _style.visibility; + var divJson = document.createElement("div"); + divJson.className = this.name.containerjson; + + var label = document.createElement("label"); + label.className = this.name.jsonlabel; + label.innerHTML = this.options.title; + divJson.appendChild(label); + + var pre = document.createElement("pre"); + pre.className = this.name.jsondisplay; + pre.innerHTML = json; + if (pre.addEventListener) { + pre.addEventListener("click", function (e) { + if (self.options.tools.edition) { + self.onEditJsonStyleMapBox(e); + } + }); + } else if (pre.attachEvent) { + pre.attachEvent("onclick", function (e) { + if (self.options.tools.edition) { + self.onEditJsonStyleMapBox(e); + } + }); } - if (Object.keys(_obj.layout).length === 0) { - logger.info("tag 'layout' is empty !"); + divJson.appendChild(pre); + div.appendChild(divJson); + + // scale + if (this.options.tools.scale) { + div.appendChild(this._createElementToolsScale({ + min : (_style.layout) ? _style.layout.minzoom : 0, + max : (_style.layout) ? _style.layout.maxzoom : 21 + })); } - } - var div = document.createElement("div"); - div.className = this.name.container; + // TODO menu d'edition + if (this.options.tools.edition) { + div.appendChild(this._createElementToolsEdition()); + } - var json = null; - if (_found) { - var strJson = JSON.stringify(_style, null, 4); - json = this._syntaxHighlight(strJson); + // main container + this.container = div; } - var divJson = document.createElement("div"); - divJson.className = this.name.containerjson; - - var label = document.createElement("label"); - label.className = this.name.jsonlabel; - label.innerHTML = this.options.title; - divJson.appendChild(label); - - var pre = document.createElement("pre"); - pre.className = this.name.jsondisplay; - pre.innerHTML = json; - if (pre.addEventListener) { - pre.addEventListener("click", function (e) { - if (self.options.tools.edition) { - self.onEditJsonStyleMapBox(e); - } - }); - } else if (pre.attachEvent) { - pre.attachEvent("onclick", function (e) { - if (self.options.tools.edition) { - self.onEditJsonStyleMapBox(e); - } - }); - } - divJson.appendChild(pre); - div.appendChild(divJson); - - // scale - if (this.options.tools.scale) { - div.appendChild(this._createElementToolsScale({ - min : (_style.layout) ? _style.layout.minzoom : 0, - max : (_style.layout) ? _style.layout.maxzoom : 21 - })); - } + /** + * Graphical rendering of the scale tools + * + * @param {Object} scale - {min,max} or 0|21 + * @returns {DOMElement} DOM element + * + * @private + * @example + *
+ */ + _createElementToolsScale (scale) { + logger.trace("_createElementToolsScale"); + + var self = this; + + var obj = this.options.obj; + + var divToolsScale = document.createElement("div"); + divToolsScale.className = this.name.containertoolsscale; + + // FIXME Titre ? + // var label = document.createElement("label"); + // label.className = this.name.scaletitle; + // label.innerHTML = "Scale :"; + // divToolsScale.appendChild(label); + var divMin = document.createElement("div"); + divMin.className = this.name.containertoolsminscale; + + var labelMin = document.createElement("label"); + labelMin.className = this.name.scalelabelmin; + labelMin.innerHTML = "min :"; + divMin.appendChild(labelMin); + + var inputMin = document.createElement("input"); + inputMin.className = this.name.scaleinputmin; + inputMin.type = "range"; + inputMin.value = scale.min || 0; + inputMin.title = scale.min || 0; + inputMin.disabled = false; + inputMin.min = 0; + inputMin.max = 21; + inputMin.data = obj; // on lie le DOM et la couche, utile lors d'evenement ! + if (inputMin.addEventListener) { + inputMin.addEventListener("change", function (e) { + self.onChangeStyleScaleMinMapBox(e); + }); + } else if (inputMin.appendChild) { + inputMin.appendChild("onchange", function (e) { + self.onChangeStyleScaleMinMapBox(e); + }); + } + divMin.appendChild(inputMin); + + divToolsScale.appendChild(divMin); + + var divMax = document.createElement("div"); + divMax.className = this.name.containertoolsmaxscale; + + var labelMax = document.createElement("label"); + labelMax.className = this.name.scalelabelmax; + labelMax.innerHTML = "max :"; + divMax.appendChild(labelMax); + + var inputMax = document.createElement("input"); + inputMax.className = this.name.scaleinputmin; + inputMax.type = "range"; + inputMax.value = scale.max || 21; + inputMax.title = scale.max || 21; + inputMax.disabled = false; + inputMax.min = 0; + inputMax.max = 21; + inputMax.data = obj; // on lie le DOM et la couche, utile lors d'evenement ! + if (inputMax.addEventListener) { + inputMax.addEventListener("change", function (e) { + self.onChangeStyleScaleMaxMapBox(e); + }); + } else if (inputMax.appendChild) { + inputMax.appendChild("onchange", function (e) { + self.onChangeStyleScaleMaxMapBox(e); + }); + } + divMax.appendChild(inputMax); - // TODO menu d'edition - if (this.options.tools.edition) { - div.appendChild(this._createElementToolsEdition()); - } + divToolsScale.appendChild(divMax); - // main container - this.container = div; -}; + return divToolsScale; + } -/** - * Graphical rendering of the scale tools - * - * @param {Object} scale - {min,max} or 0|21 - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- */ -Style.prototype._createElementToolsScale = function (scale) { - logger.trace("_createElementToolsScale"); - - var self = this; - - var obj = this.options.obj; - - var divToolsScale = document.createElement("div"); - divToolsScale.className = this.name.containertoolsscale; - - // FIXME Titre ? - // var label = document.createElement("label"); - // label.className = this.name.scaletitle; - // label.innerHTML = "Scale :"; - // divToolsScale.appendChild(label); - - var divMin = document.createElement("div"); - divMin.className = this.name.containertoolsminscale; - - var labelMin = document.createElement("label"); - labelMin.className = this.name.scalelabelmin; - labelMin.innerHTML = "min :"; - divMin.appendChild(labelMin); - - var inputMin = document.createElement("input"); - inputMin.className = this.name.scaleinputmin; - inputMin.type = "range"; - inputMin.value = scale.min || 0; - inputMin.title = scale.min || 0; - inputMin.disabled = false; - inputMin.min = 0; - inputMin.max = 21; - inputMin.data = obj; // on lie le DOM et la couche, utile lors d'evenement ! - if (inputMin.addEventListener) { - inputMin.addEventListener("change", function (e) { - self.onChangeStyleScaleMinMapBox(e); - }); - } else if (inputMin.appendChild) { - inputMin.appendChild("onchange", function (e) { - self.onChangeStyleScaleMinMapBox(e); - }); + /** + * Graphical rendering of the edition tools + * + * @returns {DOMElement} DOM element + * + * @private + * @example + *
+ */ + _createElementToolsEdition () { + logger.warn("_createElementToolsEdition, it's not yet implemented !"); + + var divToolsEdit = document.createElement("div"); + divToolsEdit.className = this.name.containertoolsedit; + + return divToolsEdit; } - divMin.appendChild(inputMin); - - divToolsScale.appendChild(divMin); - - var divMax = document.createElement("div"); - divMax.className = this.name.containertoolsmaxscale; - - var labelMax = document.createElement("label"); - labelMax.className = this.name.scalelabelmax; - labelMax.innerHTML = "max :"; - divMax.appendChild(labelMax); - - var inputMax = document.createElement("input"); - inputMax.className = this.name.scaleinputmin; - inputMax.type = "range"; - inputMax.value = scale.max || 21; - inputMax.title = scale.max || 21; - inputMax.disabled = false; - inputMax.min = 0; - inputMax.max = 21; - inputMax.data = obj; // on lie le DOM et la couche, utile lors d'evenement ! - if (inputMax.addEventListener) { - inputMax.addEventListener("change", function (e) { - self.onChangeStyleScaleMaxMapBox(e); - }); - } else if (inputMax.appendChild) { - inputMax.appendChild("onchange", function (e) { - self.onChangeStyleScaleMaxMapBox(e); + + // ################################################################### // + // ##################### private methods ############################# // + // ################################################################### // + /** + * Transform a JSON into a DOM with a syntax in color + * + * @private + * @param {Object} json - json. + * @returns {DOMElement} dom element + */ + _syntaxHighlight (json) { + json = json.replace(/&/g, "&").replace(//g, ">"); + return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, function (match) { + var cls = "gp-json-number"; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = "gp-json-key"; + } else { + cls = "gp-json-string"; + } + } else if (/true|false/.test(match)) { + cls = "gp-json-boolean"; + } else if (/null/.test(match)) { + cls = "gp-json-null"; + } + return "" + match + ""; }); } - divMax.appendChild(inputMax); - - divToolsScale.appendChild(divMax); - - return divToolsScale; -}; - -/** - * Graphical rendering of the edition tools - * - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- */ -Style.prototype._createElementToolsEdition = function () { - logger.warn("_createElementToolsEdition, it's not yet implemented !"); - - var divToolsEdit = document.createElement("div"); - divToolsEdit.className = this.name.containertoolsedit; - return divToolsEdit; -}; - -// ################################################################### // -// ##################### private methods ############################# // -// ################################################################### // - -/** - * Transform a JSON into a DOM with a syntax in color - * - * @private - * @param {Object} json - json. - * @returns {DOMElement} dom element - */ -Style.prototype._syntaxHighlight = function (json) { - json = json.replace(/&/g, "&").replace(//g, ">"); - return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, function (match) { - var cls = "gp-json-number"; - if (/^"/.test(match)) { - if (/:$/.test(match)) { - cls = "gp-json-key"; - } else { - cls = "gp-json-string"; + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Add element into target DOM + * @returns {Object} - Legend instance + */ + add () { + if (!this.options.target) { + if (!document.getElementById(this.name.target)) { + var div = document.createElement("div"); + div.id = this.name.target; + var node = document.documentElement || + document.getElementsByTagName("body")[0] || + document.getElementsByTagName("head")[0]; + node.appendChild(div); } - } else if (/true|false/.test(match)) { - cls = "gp-json-boolean"; - } else if (/null/.test(match)) { - cls = "gp-json-null"; + this.options.target = document.getElementById(this.name.target); } - return "" + match + ""; - }); -}; - -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // - -/** - * Add element into target DOM - * @returns {Object} - Legend instance - */ -Style.prototype.add = function () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); + if (this.container) { + this.options.target.appendChild(this.container); } - this.options.target = document.getElementById(this.name.target); + return this; } - if (this.container) { - this.options.target.appendChild(this.container); + + /** + * Set display container or get + * + * @param {Boolean} display - show/hidden container or get status + * @returns {Boolean} - true/false + */ + display (display) { + logger.trace("display()", display); + if (typeof display !== "undefined") { + this.container.style.display = (display) ? "flex" : "none"; + } + return (this.container.style.display === "flex"); } - return this; -}; -/** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ -Style.prototype.display = function (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; + /** + * Get container (DOM) + * + * @returns {DOMElement} DOM element + */ + getContainer () { + return this.container; } - return (this.container.style.display === "flex"); -}; -/** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ -Style.prototype.getContainer = function () { - return this.container; -}; -// ################################################################### // -// ####################### handlers events to dom #################### // -// ################################################################### // + // ################################################################### // + // ####################### handlers events to dom #################### // + // ################################################################### // + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Style#editor:style:oneditjson + */ + onEditJsonStyleMapBox (e) { + logger.trace("onEditJsonStyleMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.style.oneditjson, e); + } -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:oneditjson - */ -Style.prototype.onEditJsonStyleMapBox = function (e) { - logger.trace("onEditJsonStyleMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.style.oneditjson, e); -}; + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Style#editor:style:scale:onchangemin + */ + onChangeStyleScaleMinMapBox (e) { + logger.trace("onChangeStyleScaleMinMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.style.scale.onchangemin, e); + } -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:scale:onchangemin - */ -Style.prototype.onChangeStyleScaleMinMapBox = function (e) { - logger.trace("onChangeStyleScaleMinMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.style.scale.onchangemin, e); -}; + /** + * this method is called by event '' on '' tag form... + * + * 'e' contains the option object into 'e.target.data' ! + * 'e' contains the id editor into 'e.target.editorID' ! + * + * @param {Object} e - HTMLElement + * @private + * @fires Style#editor:style:scale:onchangemax + */ + onChangeStyleScaleMaxMapBox (e) { + logger.trace("onChangeStyleScaleMaxMapBox", e); + e.editorID = this.id; + e.data = this.options; + EventBus.dispatch(EventEditor.style.scale.onchangemax, e); + } -/** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:scale:onchangemax - */ -Style.prototype.onChangeStyleScaleMaxMapBox = function (e) { - logger.trace("onChangeStyleScaleMaxMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.style.scale.onchangemax, e); }; export default Style; diff --git a/src/OpenLayers/Controls/Editor/Themes.js b/src/OpenLayers/Controls/Editor/Themes.js index dc50061bf..1c3ed245b 100644 --- a/src/OpenLayers/Controls/Editor/Themes.js +++ b/src/OpenLayers/Controls/Editor/Themes.js @@ -44,344 +44,339 @@ var logger = Logger.getLogger("editor-themes"); * theme.display(true); * theme.getContainer(); */ -function Themes (options) { - logger.trace("[constructor] Themes", options); +class Themes { - // options - this.options = options || { - // TODO default... - }; + constructor (options) { + logger.trace("[constructor] Themes", options); - if (!(this instanceof Themes)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } + // options + this.options = options || { + // TODO default... + }; - this._initialize(); + if (!(this instanceof Themes)) { + throw new TypeError("ERROR CLASS_CONSTRUCTOR"); + } - this._initContainer(); -}; + this._initialize(); -/** - * Constructor (alias) - * - * @private - */ -Themes.prototype.constructor = Themes; - -/** - * Initialize component - * (called by constructor) - * - * @private - */ -Themes.prototype._initialize = function () { - // unique editor id (optional!) - this.id = this.options.id || null; - - if (!this.options.target) { - // cf. add() + this._initContainer(); } - var _toolsDefault = { - thumbnails : true, - button : { - visible : true, - type : "radio" + /** + * Initialize component + * (called by constructor) + * + * @private + */ + _initialize () { + // unique editor id (optional!) + this.id = this.options.id || null; + + if (!this.options.target) { + // cf. add() } - }; - - if (!this.options.tools || Object.keys(this.options.tools).length === 0) { - this.options.tools = _toolsDefault; - } - Utils.mergeParams(this.options.tools, _toolsDefault, false); - - if (typeof this.options.obj === "undefined" || - this.options.obj === null || - !this.options.obj) { - // vide par defaut ? - this.options.obj = { - themesSummary : "", - themes : [] + var _toolsDefault = { + thumbnails : true, + button : { + visible : true, + type : "radio" + } }; - } - - this.container = null; - // DOM : className or id - this.name = { - target : "GPEditorMapBoxThemeTarget", - container : "GPEditorMapBoxThemesContainer", - containertheme : "GPEditorMapBoxThemeContainer", - containerthemeID : "GPEditorMapBoxThemeContainer_ID_", - input : "GPEditorMapBoxThemeInput", - inputID : "GPEditorMapBoxThemeInput_ID_", - label : "GPEditorMapBoxThemeTitle", - labelID : "GPEditorMapBoxThemeTitle_ID_", - image : "GPEditorMapBoxThemeImage", - imageID : "GPEditorMapBoxThemeImage_ID_", - message : "GPEditorMapBoxThemeMessage" - }; -}; - -/** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- * - * Description1 - * - *
- *
- * - * Description2 - * - *
- *
- */ -Themes.prototype._initContainer = function () { - // contexte - var self = this; - - var obj = this.options.obj; - - var id = this.id || ID.generate(); + if (!this.options.tools || Object.keys(this.options.tools).length === 0) { + this.options.tools = _toolsDefault; + } - // div principale - var div = document.createElement("div"); - div.className = this.name.container; - div.title = obj.themesSummary || ""; + Utils.mergeParams(this.options.tools, _toolsDefault, false); - var _lstThemes = obj.themes; - if (_lstThemes) { - for (var i = 0; i < _lstThemes.length; i++) { - var _theme = _lstThemes[i]; + if (typeof this.options.obj === "undefined" || + this.options.obj === null || + !this.options.obj) { + // vide par defaut ? + this.options.obj = { + themesSummary : "", + themes : [] + }; + } - // div pour chaque theme - var divTheme = document.createElement("div"); - divTheme.id = this.name.containerthemeID + i + "_" + id; - divTheme.className = this.name.containertheme; - divTheme.tabIndex = i; + this.container = null; + + // DOM : className or id + this.name = { + target : "GPEditorMapBoxThemeTarget", + container : "GPEditorMapBoxThemesContainer", + containertheme : "GPEditorMapBoxThemeContainer", + containerthemeID : "GPEditorMapBoxThemeContainer_ID_", + input : "GPEditorMapBoxThemeInput", + inputID : "GPEditorMapBoxThemeInput_ID_", + label : "GPEditorMapBoxThemeTitle", + labelID : "GPEditorMapBoxThemeTitle_ID_", + image : "GPEditorMapBoxThemeImage", + imageID : "GPEditorMapBoxThemeImage_ID_", + message : "GPEditorMapBoxThemeMessage" + }; + } - // url du style est obligatoire ! - var _url = _theme.url; - // style selectionné par defaut (uniquement en mode radio-button !?) - var _selected = _theme.selected || false; - if (_url) { - // bouton - var button = this.options.tools.button; - if (button.visible) { - var _type = (button.type === "checkbox") ? "checkbox" : "radio"; - var _button = document.createElement("input"); - _button.type = _type; - _button.id = this.name.inputID + i + "_" + id; - _button.className = this.name.input; - _button.name = id; - _button.checked = _selected; - _button.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! - if (_button.addEventListener) { - _button.addEventListener("click", function (e) { - self.onClickThemeTitleMapBox(e); - }); - } else if (_button.attachEvent) { - _button.attachEvent("onclick", function (e) { - self.onClickThemeTitleMapBox(e); - }); - } - divTheme.appendChild(_button); - } - // vignette - if (this.options.tools.thumbnails) { - if (_theme.thumbnail) { - var _img = document.createElement("img"); - _img.id = this.name.imageID + i + "_" + id; - _img.className = this.name.image; - _img.src = _theme.thumbnail; - _img.alt = _theme.thumbnail; - _img.title = _theme.description || ""; // une description au survol de l'image ou titre... - _img.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! - if (_img.addEventListener) { - _img.addEventListener("click", function (e) { - self.onClickThemeImageMapBox(e); - // maj du radio button - var nodes = e.target.parentElement.childNodes; - if (nodes) { - var node = nodes[0]; - if (node.tagName.toLowerCase() === "input") { - node.checked = !node.checked; - } - } + /** + * Graphical rendering of the component + * (called by constructor) + * + * @private + * @example + *
+ *
+ * + * Description1 + * + *
+ *
+ * + * Description2 + * + *
+ *
+ */ + _initContainer () { + // contexte + var self = this; + + var obj = this.options.obj; + + var id = this.id || ID.generate(); + + // div principale + var div = document.createElement("div"); + div.className = this.name.container; + div.title = obj.themesSummary || ""; + + var _lstThemes = obj.themes; + if (_lstThemes) { + for (var i = 0; i < _lstThemes.length; i++) { + var _theme = _lstThemes[i]; + + // div pour chaque theme + var divTheme = document.createElement("div"); + divTheme.id = this.name.containerthemeID + i + "_" + id; + divTheme.className = this.name.containertheme; + divTheme.tabIndex = i; + + // url du style est obligatoire ! + var _url = _theme.url; + // style selectionné par defaut (uniquement en mode radio-button !?) + var _selected = _theme.selected || false; + if (_url) { + // bouton + var button = this.options.tools.button; + if (button.visible) { + var _type = (button.type === "checkbox") ? "checkbox" : "radio"; + var _button = document.createElement("input"); + _button.type = _type; + _button.id = this.name.inputID + i + "_" + id; + _button.className = this.name.input; + _button.name = id; + _button.checked = _selected; + _button.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! + if (_button.addEventListener) { + _button.addEventListener("click", function (e) { + self.onClickThemeTitleMapBox(e); }); - } else if (_img.attachEvent) { - _img.attachEvent("onclick", function (e) { - self.onClickThemeImageMapBox(e); - var nodes = e.target.parentElement.childNodes; - if (nodes) { - var node = nodes[0]; - if (node.tagName.toLowerCase() === "input") { - node.checked = !node.checked; - } - } + } else if (_button.attachEvent) { + _button.attachEvent("onclick", function (e) { + self.onClickThemeTitleMapBox(e); }); } - divTheme.appendChild(_img); + divTheme.appendChild(_button); } - } - // label - if (_theme.name) { - var _label = document.createElement("label"); - _label.id = this.name.labelID + i + "_" + id; - if (this.options.tools.button.visible) { - _label.htmlFor = _button.id; + // vignette + if (this.options.tools.thumbnails) { + if (_theme.thumbnail) { + var _img = document.createElement("img"); + _img.id = this.name.imageID + i + "_" + id; + _img.className = this.name.image; + _img.src = _theme.thumbnail; + _img.alt = _theme.thumbnail; + _img.title = _theme.description || ""; // une description au survol de l'image ou titre... + _img.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! + if (_img.addEventListener) { + _img.addEventListener("click", function (e) { + self.onClickThemeImageMapBox(e); + // maj du radio button + var nodes = e.target.parentElement.childNodes; + if (nodes) { + var node = nodes[0]; + if (node.tagName.toLowerCase() === "input") { + node.checked = !node.checked; + } + } + }); + } else if (_img.attachEvent) { + _img.attachEvent("onclick", function (e) { + self.onClickThemeImageMapBox(e); + var nodes = e.target.parentElement.childNodes; + if (nodes) { + var node = nodes[0]; + if (node.tagName.toLowerCase() === "input") { + node.checked = !node.checked; + } + } + }); + } + divTheme.appendChild(_img); + } } - _label.className = this.name.label; - _label.innerHTML = _theme.name; - _label.title = _theme.description || ""; // une description au survol de l'image ou titre... - _label.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! - if (!this.options.tools.button.visible) { - if (_label.addEventListener) { - _label.addEventListener("click", function (e) { - self.onClickThemeTitleMapBox(e); - }); - } else if (_label.attachEvent) { - _label.attachEvent("onclick", function (e) { - self.onClickThemeTitleMapBox(e); - }); + // label + if (_theme.name) { + var _label = document.createElement("label"); + _label.id = this.name.labelID + i + "_" + id; + if (this.options.tools.button.visible) { + _label.htmlFor = _button.id; } + _label.className = this.name.label; + _label.innerHTML = _theme.name; + _label.title = _theme.description || ""; // une description au survol de l'image ou titre... + _label.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! + if (!this.options.tools.button.visible) { + if (_label.addEventListener) { + _label.addEventListener("click", function (e) { + self.onClickThemeTitleMapBox(e); + }); + } else if (_label.attachEvent) { + _label.attachEvent("onclick", function (e) { + self.onClickThemeTitleMapBox(e); + }); + } + } + divTheme.appendChild(_label); } - divTheme.appendChild(_label); + } else { + var _msg = document.createElement("label"); + _msg.className = this.name.message; + _msg.innerHTML = "Thème non disponible..."; + divTheme.appendChild(_msg); } - } else { - var _msg = document.createElement("label"); - _msg.className = this.name.message; - _msg.innerHTML = "Thème non disponible..."; - divTheme.appendChild(_msg); - } - div.appendChild(divTheme); + div.appendChild(divTheme); + } } - } - - this.container = div; -}; -// ################################################################### // -// ##################### public methods ############################## // -// ################################################################### // + this.container = div; + } -/** - * Add element into target DOM - * @returns {Object} - Legend instance - */ -Themes.prototype.add = function () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); + // ################################################################### // + // ##################### public methods ############################## // + // ################################################################### // + /** + * Add element into target DOM + * @returns {Object} - Legend instance + */ + add () { + if (!this.options.target) { + if (!document.getElementById(this.name.target)) { + var div = document.createElement("div"); + div.id = this.name.target; + var node = document.documentElement || + document.getElementsByTagName("body")[0] || + document.getElementsByTagName("head")[0]; + node.appendChild(div); + } + this.options.target = document.getElementById(this.name.target); } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); + if (this.container) { + this.options.target.appendChild(this.container); + } + return this; } - return this; -}; -/** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ -Themes.prototype.display = function (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; + /** + * Set display container or get + * + * @param {Boolean} display - show/hidden container or get status + * @returns {Boolean} - true/false + */ + display (display) { + logger.trace("display()", display); + if (typeof display !== "undefined") { + this.container.style.display = (display) ? "flex" : "none"; + } + return (this.container.style.display === "flex"); } - return (this.container.style.display === "flex"); -}; -/** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ -Themes.prototype.getContainer = function () { - return this.container; -}; - -// ################################################################### // -// ####################### handlers events to dom #################### // -// ################################################################### // + /** + * Get container (DOM) + * + * @returns {DOMElement} DOM element + */ + getContainer () { + return this.container; + } -/** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - * @fires Themes#editor:themes:image - */ -Themes.prototype.onClickThemeImageMapBox = function (e) { - logger.trace("onClickThemeImageMapBox", e); - e.editorID = this.id; - e.data = this.options; - if (this.options.tools.button.type === "checkbox") { - // GPEditorMapBoxThemeInput_ID_0_1571317605868 - var targetIDX = e.target.previousSibling.id.substring( - e.target.previousSibling.id.lastIndexOf("_") + 1 - ); - var _inputs = document.getElementsByClassName(this.name.input); - for (var i = 0; i < _inputs.length; i++) { - var el = _inputs[i]; - if (el.id === e.target.previousSibling.id) { - continue; - } - var elIDX = el.id.substring(el.id.lastIndexOf("_") + 1); - if (elIDX !== targetIDX) { - continue; + // ################################################################### // + // ####################### handlers events to dom #################### // + // ################################################################### // + /** + * this method is called by event '' on '' tag form + * + * @param {Object} e - HTMLElement + * @private + * @fires Themes#editor:themes:image + */ + onClickThemeImageMapBox (e) { + logger.trace("onClickThemeImageMapBox", e); + e.editorID = this.id; + e.data = this.options; + if (this.options.tools.button.type === "checkbox") { + // GPEditorMapBoxThemeInput_ID_0_1571317605868 + var targetIDX = e.target.previousSibling.id.substring( + e.target.previousSibling.id.lastIndexOf("_") + 1 + ); + var _inputs = document.getElementsByClassName(this.name.input); + for (var i = 0; i < _inputs.length; i++) { + var el = _inputs[i]; + if (el.id === e.target.previousSibling.id) { + continue; + } + var elIDX = el.id.substring(el.id.lastIndexOf("_") + 1); + if (elIDX !== targetIDX) { + continue; + } + el.checked = false; } - el.checked = false; } + EventBus.dispatch(EventEditor.themes.onclickimage, e); } - EventBus.dispatch(EventEditor.themes.onclickimage, e); -}; -/** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - * @fires Themes#editor:themes:title - */ -Themes.prototype.onClickThemeTitleMapBox = function (e) { - logger.trace("onClickThemeTitleMapBox", e); - e.editorID = this.id; - e.data = this.options; - if (this.options.tools.button.type === "checkbox") { - // GPEditorMapBoxThemeInput_ID_0_1571317605868 - var targetIDX = e.target.id.substring(e.target.id.lastIndexOf("_") + 1); - var _inputs = document.getElementsByClassName(this.name.input); - for (var i = 0; i < _inputs.length; i++) { - var el = _inputs[i]; - if (el.id === e.target.id) { - continue; - } - var elIDX = el.id.substring(el.id.lastIndexOf("_") + 1); - if (elIDX !== targetIDX) { - continue; + /** + * this method is called by event '' on '' tag form + * + * @param {Object} e - HTMLElement + * @private + * @fires Themes#editor:themes:title + */ + onClickThemeTitleMapBox (e) { + logger.trace("onClickThemeTitleMapBox", e); + e.editorID = this.id; + e.data = this.options; + if (this.options.tools.button.type === "checkbox") { + // GPEditorMapBoxThemeInput_ID_0_1571317605868 + var targetIDX = e.target.id.substring(e.target.id.lastIndexOf("_") + 1); + var _inputs = document.getElementsByClassName(this.name.input); + for (var i = 0; i < _inputs.length; i++) { + var el = _inputs[i]; + if (el.id === e.target.id) { + continue; + } + var elIDX = el.id.substring(el.id.lastIndexOf("_") + 1); + if (elIDX !== targetIDX) { + continue; + } + el.checked = false; } - el.checked = false; } + EventBus.dispatch(EventEditor.themes.onclicktitle, e); } - EventBus.dispatch(EventEditor.themes.onclicktitle, e); + }; export default Themes;