diff --git a/src/config.xml b/src/config.xml index ac812f9..3f39067 100644 --- a/src/config.xml +++ b/src/config.xml @@ -1,5 +1,8 @@ - + + + 2 +
OpenLayers Map wirecloud@conwet.com @@ -39,5 +42,13 @@ + + - - - OpenLayers 7 widget - - -
-
-
-
- - - -
+ + + + + +
+
+
+
+ + +
- - - - +
+ \ No newline at end of file diff --git a/src/js/main.js b/src/js/main.js index df6c0c6..322a95a 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -14,108 +14,117 @@ * limitations under the License. */ -/* global Widget */ +/* global _CoNWeT_ol3_Widget_Internal */ (function () { "use strict"; - const parseInputEndpointData = function parseInputEndpointData(data) { - if (typeof data === "string") { - try { - data = JSON.parse(data); - } catch (e) { - throw new MashupPlatform.wiring.EndpointTypeError(); - } - } else if (data == null || typeof data !== "object") { - throw new MashupPlatform.wiring.EndpointTypeError(); - } - return data; - }; - - const widget = new Widget('body', '#incoming-modal'); - widget.init(); - - MashupPlatform.prefs.registerCallback((new_values) => { - if ("useclustering" in new_values) { - widget.setClustering(new_values.useclustering); - } - }); - - MashupPlatform.wiring.registerCallback('layerInfo', (commands) => { - commands = parseInputEndpointData(commands); - - if (!Array.isArray(commands)) { - commands = [commands]; - } - - if (commands.some((command) => {return command == null || ["addLayer", "updateLayer", "removeLayer", "setBaseLayer"].indexOf(command.action) === -1;})) { - throw new MashupPlatform.wiring.EndpointValueError("Invalid command action"); + class Widget { + constructor(MashupPlatform, shadowDOM, extra) { + this.MashupPlatform = MashupPlatform; + this.shadowDOM = shadowDOM; + + this.widget = new _CoNWeT_ol3_Widget_Internal(MashupPlatform, shadowDOM, extra); + this.widget.init(); + + this.MashupPlatform.prefs.registerCallback((new_values) => { + if ("useclustering" in new_values) { + this.widget.setClustering(new_values.useclustering); + } + }); + + this.MashupPlatform.wiring.registerCallback('layerInfo', (commands) => { + commands = this.parseInputEndpointData(commands); + + if (!Array.isArray(commands)) { + commands = [commands]; + } + + if (commands.some((command) => {return command == null || ["addLayer", "updateLayer", "removeLayer", "setBaseLayer"].indexOf(command.action) === -1;})) { + throw new this.MashupPlatform.wiring.EndpointValueError("Invalid command action"); + } + + commands.forEach((command) => { + switch (command.action) { + case "addLayer": + this.widget.addLayer(command.data); + break; + case "updateLayer": + this.widget.updateLayer(command.data); + break; + case "removeLayer": + this.widget.removeLayer(command.data); + break; + case "setBaseLayer": + this.widget.setBaseLayer(command.data); + break; + } + }); + }); + + this.MashupPlatform.wiring.registerCallback('poiInput', (poi_info) => { + poi_info = this.parseInputEndpointData(poi_info); + + if (!Array.isArray(poi_info)) { + poi_info = [poi_info]; + } + poi_info.forEach(this.widget.registerPoI, this.widget); + }); + + this.MashupPlatform.wiring.registerCallback('replacePoIs', (poi_info) => { + poi_info = this.parseInputEndpointData(poi_info); + + if (!Array.isArray(poi_info)) { + poi_info = [poi_info]; + } + this.widget.replacePoIs(poi_info); + }); + + this.MashupPlatform.wiring.registerCallback('poiInputCenter', (poi_info) => { + if (poi_info == null) { + poi_info = []; + } + + poi_info = this.parseInputEndpointData(poi_info); + + if (!Array.isArray(poi_info)) { + poi_info = [poi_info]; + } + + poi_info.forEach((poi) => { + if (poi != null && typeof poi === "object") { + this.widget.registerPoI(poi) + } + }); + this.widget.centerPoI(poi_info); + }); + + this.MashupPlatform.wiring.registerCallback('deletePoiInput', (poi_info) => { + poi_info = this.parseInputEndpointData(poi_info); + + if (!Array.isArray(poi_info)) { + poi_info = [poi_info]; + } + poi_info.forEach(this.widget.removePoI, this.widget); + }); } - commands.forEach((command) => { - switch (command.action) { - case "addLayer": - widget.addLayer(command.data); - break; - case "updateLayer": - widget.updateLayer(command.data); - break; - case "removeLayer": - widget.removeLayer(command.data); - break; - case "setBaseLayer": - widget.setBaseLayer(command.data); - break; + parseInputEndpointData(data) { + if (typeof data === "string") { + try { + data = JSON.parse(data); + } catch (e) { + throw new this.MashupPlatform.wiring.EndpointTypeError(); + } + } else if (data == null || typeof data !== "object") { + throw new this.MashupPlatform.wiring.EndpointTypeError(); } - }); - }); - - MashupPlatform.wiring.registerCallback('poiInput', (poi_info) => { - poi_info = parseInputEndpointData(poi_info); - - if (!Array.isArray(poi_info)) { - poi_info = [poi_info]; + return data; } - poi_info.forEach(widget.registerPoI, widget); - }); - - MashupPlatform.wiring.registerCallback('replacePoIs', (poi_info) => { - poi_info = parseInputEndpointData(poi_info); + } - if (!Array.isArray(poi_info)) { - poi_info = [poi_info]; - } - widget.replacePoIs(poi_info); - }); - - MashupPlatform.wiring.registerCallback('poiInputCenter', (poi_info) => { - if (poi_info == null) { - poi_info = []; - } - - poi_info = parseInputEndpointData(poi_info); - - if (!Array.isArray(poi_info)) { - poi_info = [poi_info]; - } - - poi_info.forEach((poi) => { - if (poi != null && typeof poi === "object") { - widget.registerPoI(poi) - } - }); - widget.centerPoI(poi_info); - }); - - MashupPlatform.wiring.registerCallback('deletePoiInput', (poi_info) => { - poi_info = parseInputEndpointData(poi_info); - - if (!Array.isArray(poi_info)) { - poi_info = [poi_info]; - } - poi_info.forEach(widget.removePoI, widget); - }); + window.CoNWeT_ol3_Widget = Widget; })(); diff --git a/src/js/ol3-map-widget.js b/src/js/ol3-map-widget.js index b5c3ead..d834823 100644 --- a/src/js/ol3-map-widget.js +++ b/src/js/ol3-map-widget.js @@ -1,6 +1,6 @@ /* * Copyright (c) 2017 CoNWeT Lab., Universidad Politecnica de Madrid - * Copyright (c) 2017-2021 Future Internet Consulting and Development Solutions S.L. + * Copyright (c) 2017-2023 Future Internet Consulting and Development Solutions S.L. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,91 +15,23 @@ * limitations under the License. */ -/* globals ol, StyledElements */ +/* globals ol, ResizeObserver */ (function () { "use strict"; const internalUrl = function internalUrl(data) { - const url = document.createElement("a"); - url.setAttribute('href', data); + const url = new URL(data, this.MashupPlatform.location); return url.href; }; - const CORE_LAYERS = { - WIKIMEDIA: new ol.layer.Tile({ - source: new ol.source.OSM({ - url: "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png" - }) - }), - CARTODB_LIGHT: new ol.layer.Tile({ - source: new ol.source.OSM({ - url: "https://cartodb-basemaps-{1-4}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png" - }) - }), - NOKIA_HERE_CARNAV_DAY: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/carnav.day/{z}/{x}/{y}/256/png", - attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' - }) - }), - NOKIA_HERE_NORMAL_DAY: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/normal.day/{z}/{x}/{y}/256/png", - attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' - }) - }), - NOKIA_HERE_NORMAL_DAY_TRANSIT: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/normal.day.transit/{z}/{x}/{y}/256/png", - attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' - }) - }), - NOKIA_HERE_NORMAL_NIGHT: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/normal.night/{z}/{x}/{y}/256/png", - attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' - }) - }), - NOKIA_HERE_PEDESTRIAN: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/pedestrian.day/{z}/{x}/{y}/256/png", - attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' - }) - }), - NOKIA_HERE_TERRAIN_DAY: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/terrain.day/{z}/{x}/{y}/256/png", - attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' - }) - }), - NOKIA_HERE_SATELLITE_DAY: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/satellite.day/{z}/{x}/{y}/256/png", - attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' - }) - }), - NOKIA_HERE_HIBRID_DAY: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/hibrid.day/{z}/{x}/{y}/256/png", - attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' - }) - }), - OSM: new ol.layer.Tile({ - source: new ol.source.OSM() - }), - }; - CORE_LAYERS.GOOGLE_STANDARD = CORE_LAYERS.MAPQUEST_ROAD; - CORE_LAYERS.GOOGLE_HYBRID = CORE_LAYERS.MAPQUEST_HYBRID; - CORE_LAYERS.GOOGLE_SATELLITE = CORE_LAYERS.MAPQUEST_SATELLITE; - const create_popover = function create_popover(feature) { // The feature has content to be used on a popover - this.popover = new StyledElements.Popover({ + this.popover = new this.StyledElements.Popover({ placement: ['top', 'bottom', 'right', 'left'], title: feature.get('title'), - content: new StyledElements.Fragment(feature.get('content')), + content: new this.StyledElements.Fragment(feature.get('content')), sticky: true }); this.popover.on('hide', (popover) => { @@ -118,7 +50,7 @@ // WireCloud 1.4+ this.popover.update( feature.get("title"), - new StyledElements.Fragment(feature.get("content")) + new this.StyledElements.Fragment(feature.get("content")) ); } else { // Workaround for WireCloud 1.3 and below @@ -139,7 +71,7 @@ this.popover = null; popover.hide(); } - MashupPlatform.widget.outputs.poiOutput.pushEvent(feature != null ? feature.get('data') : null); + this.MashupPlatform.widget.outputs.poiOutput.pushEvent(feature != null ? feature.get('data') : null); } }; @@ -164,7 +96,7 @@ anchorXUnits: 'fraction', anchorYUnits: 'pixels', opacity: 0.75, - src: internalUrl('images/icon.png') + src: internalUrl.call(this, 'images/icon.png') }); } @@ -412,7 +344,7 @@ this.visiblePoisTimeout = null; } - if (!MashupPlatform.widget.outputs.poiListOutput.connected) { + if (!this.MashupPlatform.widget.outputs.poiListOutput.connected) { return; } @@ -420,19 +352,90 @@ const data = this.vector_source.getFeaturesInExtent(extent).map((feature) => { return feature.get('data'); }); - MashupPlatform.widget.outputs.poiListOutput.pushEvent(data); + this.MashupPlatform.widget.outputs.poiListOutput.pushEvent(data); }; // Create the default Marker style let DEFAULT_MARKER = null; - const Widget = function Widget() { + const Widget = function Widget(MashupPlatform, shadowDOM, extra) { + this.MashupPlatform = MashupPlatform; + this.shadowDOM = shadowDOM; + this.StyledElements = extra.StyledElements; + this.selected_feature = null; this.layers_widget = null; this.base_layer = null; this.popover = null; this.layers = {}; this.centering = false; + + this.CORE_LAYERS = { + WIKIMEDIA: new ol.layer.Tile({ + source: new ol.source.OSM({ + url: "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png" + }) + }), + CARTODB_LIGHT: new ol.layer.Tile({ + source: new ol.source.OSM({ + url: "https://cartodb-basemaps-{1-4}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png" + }) + }), + NOKIA_HERE_CARNAV_DAY: new ol.layer.Tile({ + source: new ol.source.XYZ({ + url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/carnav.day/{z}/{x}/{y}/256/png", + attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' + }) + }), + NOKIA_HERE_NORMAL_DAY: new ol.layer.Tile({ + source: new ol.source.XYZ({ + url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/normal.day/{z}/{x}/{y}/256/png", + attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' + }) + }), + NOKIA_HERE_NORMAL_DAY_TRANSIT: new ol.layer.Tile({ + source: new ol.source.XYZ({ + url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/normal.day.transit/{z}/{x}/{y}/256/png", + attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' + }) + }), + NOKIA_HERE_NORMAL_NIGHT: new ol.layer.Tile({ + source: new ol.source.XYZ({ + url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/normal.night/{z}/{x}/{y}/256/png", + attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' + }) + }), + NOKIA_HERE_PEDESTRIAN: new ol.layer.Tile({ + source: new ol.source.XYZ({ + url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/pedestrian.day/{z}/{x}/{y}/256/png", + attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' + }) + }), + NOKIA_HERE_TERRAIN_DAY: new ol.layer.Tile({ + source: new ol.source.XYZ({ + url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/terrain.day/{z}/{x}/{y}/256/png", + attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' + }) + }), + NOKIA_HERE_SATELLITE_DAY: new ol.layer.Tile({ + source: new ol.source.XYZ({ + url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/satellite.day/{z}/{x}/{y}/256/png", + attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' + }) + }), + NOKIA_HERE_HIBRID_DAY: new ol.layer.Tile({ + source: new ol.source.XYZ({ + url: "https://{a-c}.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/hibrid.day/{z}/{x}/{y}/256/png", + attribution: 'Map Tiles © ' + new Date().getFullYear() + ' ' + 'HERE' + }) + }), + OSM: new ol.layer.Tile({ + source: new ol.source.OSM() + }), + }; + this.CORE_LAYERS.GOOGLE_STANDARD = this.CORE_LAYERS.MAPQUEST_ROAD; + this.CORE_LAYERS.GOOGLE_HYBRID = this.CORE_LAYERS.MAPQUEST_HYBRID; + this.CORE_LAYERS.GOOGLE_SATELLITE = this.CORE_LAYERS.MAPQUEST_SATELLITE; }; Widget.prototype.init = function init() { @@ -458,15 +461,15 @@ } }; - const layers_button = document.getElementById('button'); + const layers_button = this.shadowDOM.getElementById('button'); layers_button.addEventListener('click', (event) => { if (this.layers_widget == null) { - this.layers_widget = MashupPlatform.mashup.addWidget(MashupPlatform.prefs.get('layerswidget').trim(), {refposition: event.target.getBoundingClientRect()}); + this.layers_widget = this.MashupPlatform.mashup.addWidget(this.MashupPlatform.prefs.get('layerswidget').trim(), {refposition: event.target.getBoundingClientRect()}); this.layers_widget.addEventListener('remove', () => this.layers_widget = null); - this.layers_widget.outputs.layerInfoOutput.connect(MashupPlatform.widget.inputs.layerInfo); + this.layers_widget.outputs.layerInfoOutput.connect(this.MashupPlatform.widget.inputs.layerInfo); } }); - const layers_widget_ref = MashupPlatform.prefs.get('layerswidget').trim(); + const layers_widget_ref = this.MashupPlatform.prefs.get('layerswidget').trim(); if (layers_widget_ref === "") { layers_button.classList.remove('in'); } else { @@ -474,27 +477,27 @@ } // Edit buttons - const setcenter_button = document.getElementById("setcenter-button"); + const setcenter_button = this.shadowDOM.getElementById("setcenter-button"); setcenter_button.addEventListener('click', (event) => { const currentCenter = this.map.getView().getCenter(); const newValue = ol.proj.transform(currentCenter, 'EPSG:3857', 'EPSG:4326'); - MashupPlatform.prefs.set( + this.MashupPlatform.prefs.set( "initialCenter", newValue.join(", ") ); }); - const setzoom_button = document.getElementById("setzoom-button"); + const setzoom_button = this.shadowDOM.getElementById("setzoom-button"); setzoom_button.addEventListener('click', (event) => { - MashupPlatform.prefs.set( + this.MashupPlatform.prefs.set( "initialZoom", this.map.getView().getZoom() ); }); - const setcenterzoom_button = document.getElementById("setcenterzoom-button"); + const setcenterzoom_button = this.shadowDOM.getElementById("setcenterzoom-button"); setcenterzoom_button.addEventListener('click', (event) => { const currentCenter = this.map.getView().getCenter(); const newValue = ol.proj.transform(currentCenter, 'EPSG:3857', 'EPSG:4326'); - MashupPlatform.prefs.set({ + this.MashupPlatform.prefs.set({ initialCenter: newValue.join(", "), initialZoom: this.map.getView().getZoom() }); @@ -512,12 +515,12 @@ setcenterzoom_button.classList.add("hidden"); } }; - MashupPlatform.mashup.context.registerCallback(update_ui_buttons); - update_ui_buttons({editing: MashupPlatform.mashup.context.get("editing")}); + this.MashupPlatform.mashup.context.registerCallback(update_ui_buttons); + update_ui_buttons({editing: this.MashupPlatform.mashup.context.get("editing")}); DEFAULT_MARKER = build_basic_style.call(this); - this.base_layer = CORE_LAYERS.OSM; - let initialCenter = MashupPlatform.prefs.get("initialCenter").split(",").map(Number); + this.base_layer = this.CORE_LAYERS.OSM; + let initialCenter = this.MashupPlatform.prefs.get("initialCenter").split(",").map(Number); if (initialCenter.length != 2 || !Number.isFinite(initialCenter[0]) || !Number.isFinite(initialCenter[1])) { initialCenter = [0, 0]; } @@ -567,23 +570,40 @@ }); this.map = new ol.Map({ - target: document.getElementById('map'), + target: this.shadowDOM.getElementById('map'), layers: [ this.base_layer, - MashupPlatform.prefs.get("useclustering") ? this.cluster_layer : this.vector_layer + this.MashupPlatform.prefs.get("useclustering") ? this.cluster_layer : this.vector_layer ], view: new ol.View({ center: ol.proj.transform(initialCenter, 'EPSG:4326', 'EPSG:3857'), - zoom: parseInt(MashupPlatform.prefs.get('initialZoom'), 10) + zoom: parseInt(this.MashupPlatform.prefs.get('initialZoom'), 10) }) }); + this.map.setSize([this.shadowDOM.getElementById('map').clientWidth, this.shadowDOM.getElementById('map').clientHeight]); + + // We set up a resize observer to update the map size when the widget + // container is resized + if ('ResizeObserver' in window) { + const resizeObserver = new ResizeObserver((entries) => { + const entry = entries[0]; + this.map.setSize([entry.contentRect.width, entry.contentRect.height]); + }); + + resizeObserver.observe(this.shadowDOM.getElementById('map')); + } else { + this.MashupPlatform.widget.context.registerCallback(() => { + this.map.setSize([this.shadowDOM.getElementById('map').clientWidth, this.shadowDOM.getElementById('map').clientHeight]); + }); + } + // display popup on click this.map.on("click", (event) => { const features = []; this.map.forEachFeatureAtPixel( event.pixel, - MashupPlatform.prefs.get('useclustering') ? + this.MashupPlatform.prefs.get('useclustering') ? (feature, layer) => { feature.get('features').forEach((feature) => { if (feature.get('selectable')) { @@ -608,9 +628,9 @@ unselect.call(this, this.selected_feature); update_selected_feature.call(this, null); } else { - const popup_menu = new StyledElements.PopupMenu(); + const popup_menu = new this.StyledElements.PopupMenu(); features.forEach((feature) => { - popup_menu.append(new StyledElements.MenuItem(feature.get('title') || feature.getId(), null, feature)); + popup_menu.append(new this.StyledElements.MenuItem(feature.get('title') || feature.getId(), null, feature)); }); popup_menu.addEventListener("click", (menu, item) => { this.select_feature(item.context); @@ -755,7 +775,7 @@ if (this.popover != null) { update_popover.call(this, iconFeature); } - MashupPlatform.widget.outputs.poiOutput.pushEvent(iconFeature.get('data')); + this.MashupPlatform.widget.outputs.poiOutput.pushEvent(iconFeature.get('data')); } }; @@ -808,7 +828,7 @@ const geometryset = new ol.geom.GeometryCollection(geometries); // Update map view - const zoom = parseInt(MashupPlatform.prefs.get('poiZoom'), 10); + const zoom = parseInt(this.MashupPlatform.prefs.get('poiZoom'), 10); const currentZoom = this.map.getView().getZoom(); if (currentZoom < zoom) { this.centering = true; @@ -859,7 +879,7 @@ const addFormat = function addFormat(layer_info) { if (layer_info.format == null) { - throw new MashupPlatform.wiring.EndpointValueError("format option is required"); + throw new this.MashupPlatform.wiring.EndpointValueError("format option is required"); } if (typeof layer_info.format === "string") { @@ -878,7 +898,7 @@ Widget.prototype.addLayer = function addLayer(layer_info) { const builder = layer_builders[layer_info.type]; if (builder == null) { - throw new MashupPlatform.wiring.EndpointValueError("Invalid layer type: " + layer_info.type); + throw new this.MashupPlatform.wiring.EndpointValueError("Invalid layer type: " + layer_info.type); } // Remove any layer with the same id @@ -895,7 +915,7 @@ Widget.prototype.updateLayer = function updateLayer(layer_info) { const layer = this.layers[layer_info.id]; if (layer == null) { - throw new MashupPlatform.wiring.EndpointValueError("Layer not found: " + layer_info.id); + throw new this.MashupPlatform.wiring.EndpointValueError("Layer not found: " + layer_info.id); } const updater = layer_updaters[layer._layer_type]; @@ -917,13 +937,13 @@ if (required != true && url == null) { return undefined; } else if (required == true && url == null) { - throw new MashupPlatform.wiring.EndpointValueError("Missing layer url option"); + throw new this.MashupPlatform.wiring.EndpointValueError("Missing layer url option"); } const parsed_url = new URL(url); /* istanbul ignore if */ if (document.location.protocol === 'https:' && parsed_url.protocol !== 'https:') { - return MashupPlatform.http.buildProxyURL(parsed_url); + return this.MashupPlatform.http.buildProxyURL(parsed_url); } else { return url; } @@ -958,7 +978,7 @@ const options = { source: new ol.source.ImageWMS({ - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), params: params, projection: layer_info.projection, crossOrigin: layer_info.crossOrigin, @@ -975,7 +995,7 @@ const addImageArcGISRestLayer = function addImageArcGISRestLayer(layer_info) { const options = { source: new ol.source.ImageArcGISRest({ - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), crossOrigin: layer_info.crossOrigin, hidpi: layer_info.hidpi, logo: layer_info.logo, @@ -990,7 +1010,7 @@ const addImageMapGuideLayer = function addImageMapGuideLayer(layer_info) { const options = { source: new ol.source.ImageMapGuide({ - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), displayDpi: layer_info.displayDpi, metersPerUnit: layer_info.metersPerUnit, hidpi: layer_info.hidpi, @@ -1005,7 +1025,7 @@ const addImageStaticLayer = function addImageStaticLayer(layer_info) { const options = { source: new ol.source.ImageStatic({ - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), crossOrigin: layer_info.crossOrigin, logo: layer_info.logo, imageExtent: layer_info.imageExtent, @@ -1020,12 +1040,12 @@ const options = { source: new ol.source.Vector({ crossOrigin: layer_info.crossOrigin, - format: addFormat(layer_info), + format: addFormat.call(this, layer_info), wrapX: layer_info.wrapX, // Vector source does not require an url // But currently we do not provide support to populate this // layer using any other way, so this parameter is required - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), }), style: new ol.style.Style({ stroke: new ol.style.Stroke({ @@ -1043,13 +1063,13 @@ source: new ol.source.VectorTile({ cacheSize: layer_info.cacheSize, crossOrigin: layer_info.crossOrigin, - format: addFormat(layer_info), + format: addFormat.call(this, layer_info), logo: layer_info.logo, overlaps: layer_info.overlaps, projection: layer_info.projection, state: layer_info.state, tileClass: layer_info.tileClass, - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), wrapX: layer_info.wrapX }) }; @@ -1062,7 +1082,7 @@ opacity: layer_info.opacity, source: new ol.source.OSM({ wrapX: layer_info.wrapX, - url: build_compatible_url(layer_info.url, false), + url: build_compatible_url.call(this, layer_info.url, false), cacheSize: layer_info.cacheSize, maxZoom: layer_info.maxZoom, opaque: layer_info.opaque, @@ -1092,7 +1112,7 @@ logo: layer_info.logo, opaque: layer_info.opaque, params: layer_info.params, - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), wrapX: layer_info.wrapX }) }; @@ -1108,7 +1128,7 @@ jsonp: layer_info.jsonp, reprojectionErrorThreshold: layer_info.reprojectionErrorThreshold, tileJSON: layer_info.tileJSON, - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), wrapX: layer_info.wrapX }) }; @@ -1122,7 +1142,7 @@ jsonp: layer_info.jsonp, preemptive: layer_info.preemptive, tileJSON: layer_info.tileJSON, - url: build_compatible_url(layer_info.url, false), + url: build_compatible_url.call(this, layer_info.url, false), }) }; @@ -1135,7 +1155,7 @@ source: new ol.source.XYZ({ cacheSize: layer_info.cacheSize, wrapX: layer_info.wrapX, - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), logo: layer_info.logo, maxZoom: layer_info.maxZoom, minZoom: layer_info.minZoom, @@ -1155,7 +1175,7 @@ maxZoom: layer_info.maxZoom, minZoom: layer_info.minZoom, opaque: layer_info.opaque, - url: build_compatible_url(layer_info.url, false) + url: build_compatible_url.call(this, layer_info.url, false) }) }; @@ -1213,7 +1233,7 @@ style: layer_info.style, tilePixelRatio: layer_info.tilePixelRatio, transition: layer_info.transition, - url: build_compatible_url(layer_info.url, true), + url: build_compatible_url.call(this, layer_info.url, true), version: layer_info.version, wrapX: layer_info.wrapX }) @@ -1230,7 +1250,7 @@ projection: layer_info.projection, tierSizeCalculation: layer_info.tierSizeCalculation, transition: layer_info.transition, - url: build_compatible_url(layer_info.url, false), + url: build_compatible_url.call(this, layer_info.url, false), size: layer_info.size }) }; @@ -1254,12 +1274,12 @@ }; Widget.prototype.setBaseLayer = function setBaseLayer(layer_info) { - if (layer_info.id == null || !(layer_info.id in CORE_LAYERS)) { - throw new MashupPlatform.wiring.EndpointValueError('Invalid layer id'); + if (layer_info.id == null || !(layer_info.id in this.CORE_LAYERS)) { + throw new this.MashupPlatform.wiring.EndpointValueError('Invalid layer id'); } this.map.removeLayer(this.base_layer); - this.base_layer = CORE_LAYERS[layer_info.id]; + this.base_layer = this.CORE_LAYERS[layer_info.id]; this.map.getLayers().insertAt(0, this.base_layer); }; @@ -1337,6 +1357,6 @@ "Zoomify": updateURL }; - window.Widget = Widget; + window._CoNWeT_ol3_Widget_Internal = Widget; })(); diff --git a/tests/js/OpenlayersWidgetSpec.js b/tests/js/OpenlayersWidgetSpec.js index f85177d..00e008f 100644 --- a/tests/js/OpenlayersWidgetSpec.js +++ b/tests/js/OpenlayersWidgetSpec.js @@ -3,7 +3,7 @@ * Copyright (c) 2017-2021 Future Internet Consulting and Development Solutions S.L. */ -/* global MashupPlatform, MockMP, ol, StyledElements, Widget */ +/* global MashupPlatform, MockMP, ol, StyledElements, _CoNWeT_ol3_Widget_Internal, shadowDOM, shadowBody */ (function () { @@ -14,11 +14,7 @@ '
'; const clearDocument = function clearDocument() { - const elements = document.querySelectorAll('body > *:not(.jasmine_html-reporter)'); - - for (let i = 0; i < elements.length; i++) { - elements[i].remove(); - } + shadowBody.innerHTML = ''; }; const deepFreeze = function deepFreeze(obj) { @@ -66,16 +62,30 @@ 'useclustering': false }, inputs: ['layerInfo'], - outputs: ['poiListOutput', 'poiOutput'] + outputs: ['poiListOutput', 'poiOutput'], }); + + window.MashupPlatform.location = window.location.href; + + const container = document.createElement('div'); + container.id = 'container'; + container.attachShadow({mode: 'open'}); + + const containerBody = document.createElement('body'); + container.shadowRoot.appendChild(containerBody); + + document.body.appendChild(container); + + window.shadowDOM = container.shadowRoot; + window.shadowBody = containerBody; }); beforeEach(() => { clearDocument(); - document.body.innerHTML += HTML_FIXTURE; + shadowBody.innerHTML += HTML_FIXTURE; MashupPlatform.reset(); MashupPlatform.prefs.set.calls.reset(); - widget = new Widget(); + widget = new _CoNWeT_ol3_Widget_Internal(MashupPlatform, shadowDOM, {StyledElements: StyledElements}); }); afterEach(() => { @@ -148,7 +158,7 @@ widget.init(); - const layers_button = document.getElementById('button'); + const layers_button = shadowDOM.getElementById('button'); expect(layers_button.className).toBe('se-btn fade'); }); @@ -157,7 +167,7 @@ widget.init(); - const layers_button = document.getElementById('button'); + const layers_button = shadowDOM.getElementById('button'); expect(layers_button.className).toBe('se-btn fade in'); }); @@ -167,7 +177,7 @@ widget.init(); createAddWidgetMock(); - const layers_button = document.getElementById('button'); + const layers_button = shadowDOM.getElementById('button'); layers_button.click(); expect(MashupPlatform.mashup.addWidget).toHaveBeenCalledWith(ref, jasmine.any(Object)); expect(MashupPlatform.mashup.addWidget().outputs.layerInfoOutput.connect).toHaveBeenCalledWith(MashupPlatform.widget.inputs.layerInfo); @@ -179,7 +189,7 @@ widget.init(); createAddWidgetMock(); - const layers_button = document.getElementById('button'); + const layers_button = shadowDOM.getElementById('button'); layers_button.click(); MashupPlatform.mashup.addWidget.calls.reset(); layers_button.click(); @@ -192,7 +202,7 @@ widget.init(); createAddWidgetMock(); - const layers_button = document.getElementById('button'); + const layers_button = shadowDOM.getElementById('button'); layers_button.click(); expect(MashupPlatform.mashup.addWidget().addEventListener).toHaveBeenCalledWith("remove", jasmine.any(Function)); MashupPlatform.mashup.addWidget().addEventListener.calls.argsFor(0)[1](); @@ -205,7 +215,7 @@ createAddWidgetMock(); // Open layers widget - const layers_button = document.getElementById('button'); + const layers_button = shadowDOM.getElementById('button'); layers_button.click(); // Close it MashupPlatform.mashup.addWidget().addEventListener.calls.argsFor(0)[1](); @@ -228,11 +238,11 @@ widget.init(); - const setcenter_button = document.getElementById('setcenter-button'); + const setcenter_button = shadowDOM.getElementById('setcenter-button'); expect(setcenter_button.className).toBe('se-btn hidden'); - const setzoom_button = document.getElementById('setzoom-button'); + const setzoom_button = shadowDOM.getElementById('setzoom-button'); expect(setzoom_button.className).toBe('se-btn hidden'); - const setcenterzoom_button = document.getElementById('setcenterzoom-button'); + const setcenterzoom_button = shadowDOM.getElementById('setcenterzoom-button'); expect(setcenterzoom_button.className).toBe('se-btn hidden'); }); @@ -241,11 +251,11 @@ widget.init(); - const setcenter_button = document.getElementById('setcenter-button'); + const setcenter_button = shadowDOM.getElementById('setcenter-button'); expect(setcenter_button.className).toBe('se-btn'); - const setzoom_button = document.getElementById('setzoom-button'); + const setzoom_button = shadowDOM.getElementById('setzoom-button'); expect(setzoom_button.className).toBe('se-btn'); - const setcenterzoom_button = document.getElementById('setcenterzoom-button'); + const setcenterzoom_button = shadowDOM.getElementById('setcenterzoom-button'); expect(setcenterzoom_button.className).toBe('se-btn'); }); @@ -255,18 +265,18 @@ MashupPlatform.mashup.context.registerCallback.calls.argsFor(0)[0]({editing: true}); - const setcenter_button = document.getElementById('setcenter-button'); + const setcenter_button = shadowDOM.getElementById('setcenter-button'); expect(setcenter_button.className).toBe('se-btn'); - const setzoom_button = document.getElementById('setzoom-button'); + const setzoom_button = shadowDOM.getElementById('setzoom-button'); expect(setzoom_button.className).toBe('se-btn'); - const setcenterzoom_button = document.getElementById('setcenterzoom-button'); + const setcenterzoom_button = shadowDOM.getElementById('setcenterzoom-button'); expect(setcenterzoom_button.className).toBe('se-btn'); }); it("should allow to setup current center as the default value for the initialCenter setting", () => { MashupPlatform.mashup.context.setContext({editing: true}); widget.init(); - const setcenter_button = document.getElementById('setcenter-button'); + const setcenter_button = shadowDOM.getElementById('setcenter-button'); setcenter_button.click(); @@ -276,7 +286,7 @@ it("should allow to setup current zoom level as the default value for the initialZoom setting", () => { MashupPlatform.mashup.context.setContext({editing: true}); widget.init(); - const setzoom_button = document.getElementById('setzoom-button'); + const setzoom_button = shadowDOM.getElementById('setzoom-button'); setzoom_button.click(); @@ -286,7 +296,7 @@ it("should allow to setup current zoom level and center position as the default initial values", () => { MashupPlatform.mashup.context.setContext({editing: true}); widget.init(); - const setcenterzoom_button = document.getElementById('setcenterzoom-button'); + const setcenterzoom_button = shadowDOM.getElementById('setcenterzoom-button'); setcenterzoom_button.click();