From 7d3abbd5cadffb49f7419ad25c3a25e46dfef903 Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Wed, 13 Oct 2021 14:35:47 +0200 Subject: [PATCH 01/24] Update PluggableMap.js --- src/ol/PluggableMap.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 136039e3f2..3df2448e4e 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -1239,6 +1239,11 @@ class PluggableMap extends BaseObject { this.handleResize_ = this.updateSize.bind(this); window.addEventListener(EventType.RESIZE, this.handleResize_, false); } + + if (this.getViewport().getRootNode().defaultView != window ){ + window.removeEventListener(EventType.RESIZE, this.handleResize_); + this.getViewport().getRootNode().defaultView.addEventListener(EventType.RESIZE, this.handleResize_, false); + } } this.updateSize(); From b51d16b5756932f3d242f94e1e1246665222707f Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Wed, 13 Oct 2021 17:22:18 +0200 Subject: [PATCH 02/24] Update PluggableMap.js Just changed formatting --- src/ol/PluggableMap.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 3df2448e4e..235a93b49f 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -1239,11 +1239,11 @@ class PluggableMap extends BaseObject { this.handleResize_ = this.updateSize.bind(this); window.addEventListener(EventType.RESIZE, this.handleResize_, false); } - - if (this.getViewport().getRootNode().defaultView != window ){ - window.removeEventListener(EventType.RESIZE, this.handleResize_); - this.getViewport().getRootNode().defaultView.addEventListener(EventType.RESIZE, this.handleResize_, false); - } + + if (this.getViewport().getRootNode().defaultView != window ){ + window.removeEventListener(EventType.RESIZE, this.handleResize_); + this.getViewport().getRootNode().defaultView.addEventListener(EventType.RESIZE, this.handleResize_, false); + } } this.updateSize(); From bc064aba36caa44901b808c6ccd20506d14ff143 Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Thu, 14 Oct 2021 09:52:15 +0200 Subject: [PATCH 03/24] Update PluggableMap.js Removing listener when the target is changed again. --- src/ol/PluggableMap.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 235a93b49f..3befe40c04 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -1240,9 +1240,20 @@ class PluggableMap extends BaseObject { window.addEventListener(EventType.RESIZE, this.handleResize_, false); } + if (this.externView && this.externView != window){ + this.externView.removeEventListener(EventType.RESIZE, this.handleResize_); + } + if (this.getViewport().getRootNode().defaultView != window ){ + this.externView = this.getViewport().getRootNode().defaultView; window.removeEventListener(EventType.RESIZE, this.handleResize_); - this.getViewport().getRootNode().defaultView.addEventListener(EventType.RESIZE, this.handleResize_, false); + this.getViewport() + .getRootNode(). + defaultView.addEventListener( + EventType.RESIZE, + this.handleResize_, + false + ); } } From 7a74ba606a0250725e92339a9d74eb8da3b0b4fa Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Thu, 14 Oct 2021 10:05:46 +0200 Subject: [PATCH 04/24] Test case of new functionality Test case of new functionality that enables to switch map to another browser window and back --- examples/extmap-main.html | 45 +++++++++++++++++++++++++++++++++++++++ examples/extmap-map.html | 22 +++++++++++++++++++ examples/extmap.js | 13 +++++++++++ 3 files changed, 80 insertions(+) create mode 100644 examples/extmap-main.html create mode 100644 examples/extmap-map.html create mode 100644 examples/extmap.js diff --git a/examples/extmap-main.html b/examples/extmap-main.html new file mode 100644 index 0000000000..16a6a4693b --- /dev/null +++ b/examples/extmap-main.html @@ -0,0 +1,45 @@ + + + + + + + + OpenLayers example + + +

External map window test case

+
+ +
+ + + + \ No newline at end of file diff --git a/examples/extmap-map.html b/examples/extmap-map.html new file mode 100644 index 0000000000..0b02d97932 --- /dev/null +++ b/examples/extmap-map.html @@ -0,0 +1,22 @@ + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/examples/extmap.js b/examples/extmap.js new file mode 100644 index 0000000000..fc770a9c15 --- /dev/null +++ b/examples/extmap.js @@ -0,0 +1,13 @@ + var map = new ol.Map({ + target: 'map', + layers: [ + new ol.layer.Tile({ + source: new ol.source.OSM() + }) + ], + view: new ol.View({ + center: ol.proj.fromLonLat([37.41, 8.82]), + zoom: 4 + }) + }); + \ No newline at end of file From 86801d11511b7f591897c52c8793c9f03c579b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Thu, 14 Oct 2021 21:56:42 +0200 Subject: [PATCH 05/24] Make external map example work --- examples/external-map.html | 11 ++++++ examples/external-map.js | 47 ++++++++++++++++++++++++ examples/extmap-main.html | 45 ----------------------- examples/extmap-map.html | 22 ----------- examples/extmap.js | 13 ------- examples/resources/external-map-map.html | 18 +++++++++ 6 files changed, 76 insertions(+), 80 deletions(-) create mode 100644 examples/external-map.html create mode 100644 examples/external-map.js delete mode 100644 examples/extmap-main.html delete mode 100644 examples/extmap-map.html delete mode 100644 examples/extmap.js create mode 100644 examples/resources/external-map-map.html diff --git a/examples/external-map.html b/examples/external-map.html new file mode 100644 index 0000000000..b372bf43f2 --- /dev/null +++ b/examples/external-map.html @@ -0,0 +1,11 @@ +--- +layout: example.html +title: External map +shortdesc: Show a map in a separate window. +docs: > + +tags: "external, window" +resources: +--- +
+ diff --git a/examples/external-map.js b/examples/external-map.js new file mode 100644 index 0000000000..b5ee6d1b8c --- /dev/null +++ b/examples/external-map.js @@ -0,0 +1,47 @@ +import Map from '../src/ol/Map.js'; +import OSM from '../src/ol/source/OSM.js'; +import TileLayer from '../src/ol/layer/Tile.js'; +import View from '../src/ol/View.js'; +import {fromLonLat} from '../src/ol/proj.js'; + +const map = new Map({ + target: 'map', + layers: [ + new TileLayer({ + source: new OSM(), + }), + ], + view: new View({ + center: fromLonLat([37.41, 8.82]), + zoom: 4, + }), +}); + +let mapWindow; +const button = document.getElementById('extMap'); +button.addEventListener('click', function () { + const localMapTarget = document.getElementById('map'); + localMapTarget.style.height = '0px'; + button.disabled = true; + + mapWindow = window.open( + 'resources/external-map-map.html', + 'MapWindow', + 'toolbar=0,location=0,menubar=0,width=800,height=600' + ); + mapWindow.addEventListener('load', function () { + const extMapDiv = mapWindow.document.getElementById('map'); + map.setTarget(extMapDiv); + }); + mapWindow.addEventListener('beforeunload', function () { + localMapTarget.style.height = ''; + map.setTarget(localMapTarget); + button.disabled = false; + mapWindow = undefined; + }); +}); +window.addEventListener('beforeunload', function () { + if (mapWindow) { + mapWindow.close(); + } +}); diff --git a/examples/extmap-main.html b/examples/extmap-main.html deleted file mode 100644 index 16a6a4693b..0000000000 --- a/examples/extmap-main.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - OpenLayers example - - -

External map window test case

-
- -
- - - - \ No newline at end of file diff --git a/examples/extmap-map.html b/examples/extmap-map.html deleted file mode 100644 index 0b02d97932..0000000000 --- a/examples/extmap-map.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - -
- - - - \ No newline at end of file diff --git a/examples/extmap.js b/examples/extmap.js deleted file mode 100644 index fc770a9c15..0000000000 --- a/examples/extmap.js +++ /dev/null @@ -1,13 +0,0 @@ - var map = new ol.Map({ - target: 'map', - layers: [ - new ol.layer.Tile({ - source: new ol.source.OSM() - }) - ], - view: new ol.View({ - center: ol.proj.fromLonLat([37.41, 8.82]), - zoom: 4 - }) - }); - \ No newline at end of file diff --git a/examples/resources/external-map-map.html b/examples/resources/external-map-map.html new file mode 100644 index 0000000000..4d3ca1fc5b --- /dev/null +++ b/examples/resources/external-map-map.html @@ -0,0 +1,18 @@ + + + + + + + +
+ + From d1560176bad648aec2151da8e4b904d49cef970e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Thu, 14 Oct 2021 23:51:50 +0200 Subject: [PATCH 06/24] Fix mouse interactions with tabindex in external window --- src/ol/events/condition.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ol/events/condition.js b/src/ol/events/condition.js index bff7b81b81..56cdde0d41 100644 --- a/src/ol/events/condition.js +++ b/src/ol/events/condition.js @@ -83,7 +83,11 @@ export const altShiftKeysOnly = function (mapBrowserEvent) { * @api */ export const focus = function (event) { - return event.target.getTargetElement().contains(document.activeElement); + const targetElement = event.map.getTargetElement(); + return targetElement.contains( + /** @type {Document} */ (targetElement.getRootNode({composed: true})) + .activeElement + ); }; /** From c799cf0cfd5aeada3610c256aba864ec016d55fc Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Fri, 15 Oct 2021 14:36:45 +0200 Subject: [PATCH 07/24] Update external-map-map.html Handle situation when user reloads external map window --- examples/resources/external-map-map.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/resources/external-map-map.html b/examples/resources/external-map-map.html index 4d3ca1fc5b..179770b800 100644 --- a/examples/resources/external-map-map.html +++ b/examples/resources/external-map-map.html @@ -13,6 +13,10 @@ +
From a807af75f1ee2c30798cb8c7fcf51a6760dd6125 Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Fri, 15 Oct 2021 15:51:43 +0200 Subject: [PATCH 08/24] Update external-map.js --- examples/external-map.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/external-map.js b/examples/external-map.js index b5ee6d1b8c..dc8f087162 100644 --- a/examples/external-map.js +++ b/examples/external-map.js @@ -3,9 +3,11 @@ import OSM from '../src/ol/source/OSM.js'; import TileLayer from '../src/ol/layer/Tile.js'; import View from '../src/ol/View.js'; import {fromLonLat} from '../src/ol/proj.js'; +import {FullScreen, defaults as defaultControls} from 'ol/control'; const map = new Map({ target: 'map', + controls: defaultControls().extend([new FullScreen()]), layers: [ new TileLayer({ source: new OSM(), @@ -32,13 +34,16 @@ button.addEventListener('click', function () { mapWindow.addEventListener('load', function () { const extMapDiv = mapWindow.document.getElementById('map'); map.setTarget(extMapDiv); + + mapWindow.addEventListener('beforeunload', function () { + localMapTarget.style.height = ''; + map.setTarget(localMapTarget); + button.disabled = false; + mapWindow = undefined; + }); + }); - mapWindow.addEventListener('beforeunload', function () { - localMapTarget.style.height = ''; - map.setTarget(localMapTarget); - button.disabled = false; - mapWindow = undefined; - }); + }); window.addEventListener('beforeunload', function () { if (mapWindow) { From 770f53b5e367d4f195ca32b09ee878e73e15a3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Sat, 16 Oct 2021 00:34:05 +0200 Subject: [PATCH 09/24] Make FullScreen control work in external window --- src/ol/control/FullScreen.js | 101 ++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/src/ol/control/FullScreen.js b/src/ol/control/FullScreen.js index 3c21dcd079..c3c81f823c 100644 --- a/src/ol/control/FullScreen.js +++ b/src/ol/control/FullScreen.js @@ -4,7 +4,7 @@ import Control from './Control.js'; import EventType from '../events/EventType.js'; import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_UNSUPPORTED} from '../css.js'; -import {listen} from '../events.js'; +import {listen, unlistenByKey} from '../events.js'; import {replaceNode} from '../dom.js'; const events = [ @@ -111,6 +111,12 @@ class FullScreen extends Control { this.cssClassName_ = options.className !== undefined ? options.className : 'ol-full-screen'; + /** + * @private + * @type {Array} + */ + this.documentListeners_ = []; + /** * @private * @type {Array} @@ -157,7 +163,6 @@ class FullScreen extends Control { this.button_ = document.createElement('button'); const tipLabel = options.tipLabel ? options.tipLabel : 'Toggle full-screen'; - this.setClassName_(this.button_, isFullScreen()); this.button_.setAttribute('type', 'button'); this.button_.title = tipLabel; this.button_.appendChild(this.labelNode_); @@ -168,17 +173,8 @@ class FullScreen extends Control { false ); - const cssClasses = - this.cssClassName_ + - ' ' + - CLASS_UNSELECTABLE + - ' ' + - CLASS_CONTROL + - ' ' + - (!isFullScreenSupported() ? CLASS_UNSUPPORTED : ''); - const element = this.element; - element.className = cssClasses; - element.appendChild(this.button_); + this.element.className = `${this.cssClassName_} ${CLASS_UNSELECTABLE} ${CLASS_CONTROL}`; + this.element.appendChild(this.button_); /** * @private @@ -206,15 +202,16 @@ class FullScreen extends Control { * @private */ handleFullScreen_() { - if (!isFullScreenSupported()) { - return; - } const map = this.getMap(); if (!map) { return; } - if (isFullScreen()) { - exitFullScreen(); + const doc = map.getOwnerDocument(); + if (!isFullScreenSupported(doc)) { + return; + } + if (isFullScreen(doc)) { + exitFullScreen(doc); } else { let element; if (this.source_) { @@ -238,7 +235,7 @@ class FullScreen extends Control { */ handleFullScreenChange_() { const map = this.getMap(); - if (isFullScreen()) { + if (isFullScreen(map.getOwnerDocument())) { this.setClassName_(this.button_, true); replaceNode(this.labelActiveNode_, this.labelNode_); this.dispatchEvent(FullScreenEventType.ENTERFULLSCREEN); @@ -275,10 +272,39 @@ class FullScreen extends Control { */ setMap(map) { super.setMap(map); + + this.handleMapTargetChange_(); if (map) { + const doc = map.getOwnerDocument(); + if (isFullScreenSupported(doc)) { + this.element.classList.remove(CLASS_UNSUPPORTED); + } else { + this.element.classList.add(CLASS_UNSUPPORTED); + } + this.setClassName_(this.button_, isFullScreen(doc)); + + this.listenerKeys.push( + listen(map, 'change:target', this.handleMapTargetChange_, this) + ); + } + } + + /** + * @private + */ + handleMapTargetChange_() { + const listeners = this.documentListeners_; + for (let i = 0, ii = listeners.length; i < ii; ++i) { + unlistenByKey(listeners[i]); + } + listeners.length = 0; + + const map = this.getMap(); + if (map) { + const doc = map.getOwnerDocument(); for (let i = 0, ii = events.length; i < ii; ++i) { - this.listenerKeys.push( - listen(document, events[i], this.handleFullScreenChange_, this) + listeners.push( + listen(doc, events[i], this.handleFullScreenChange_, this) ); } } @@ -286,25 +312,27 @@ class FullScreen extends Control { } /** + * @param {Document} doc The root document to check. * @return {boolean} Fullscreen is supported by the current platform. */ -function isFullScreenSupported() { - const body = document.body; +function isFullScreenSupported(doc) { + const body = doc.body; return !!( body['webkitRequestFullscreen'] || - (body['msRequestFullscreen'] && document['msFullscreenEnabled']) || - (body.requestFullscreen && document.fullscreenEnabled) + (body['msRequestFullscreen'] && doc['msFullscreenEnabled']) || + (body.requestFullscreen && doc.fullscreenEnabled) ); } /** + * @param {Document} doc The root document to check. * @return {boolean} Element is currently in fullscreen. */ -function isFullScreen() { +function isFullScreen(doc) { return !!( - document['webkitIsFullScreen'] || - document['msFullscreenElement'] || - document.fullscreenElement + doc['webkitIsFullScreen'] || + doc['msFullscreenElement'] || + doc.fullscreenElement ); } @@ -336,14 +364,15 @@ function requestFullScreenWithKeys(element) { /** * Exit fullscreen. + * @param {Document} doc The document to exit fullscren from */ -function exitFullScreen() { - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document['msExitFullscreen']) { - document['msExitFullscreen'](); - } else if (document['webkitExitFullscreen']) { - document['webkitExitFullscreen'](); +function exitFullScreen(doc) { + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else if (doc['msExitFullscreen']) { + doc['msExitFullscreen'](); + } else if (doc['webkitExitFullscreen']) { + doc['webkitExitFullscreen'](); } } From 8f24467ea47f33443e6a519589802446a7580a98 Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Sat, 16 Oct 2021 08:49:27 +0200 Subject: [PATCH 10/24] Update PluggableMap.js --- src/ol/PluggableMap.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 3befe40c04..493570d8e2 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -1244,16 +1244,10 @@ class PluggableMap extends BaseObject { this.externView.removeEventListener(EventType.RESIZE, this.handleResize_); } - if (this.getViewport().getRootNode().defaultView != window ){ - this.externView = this.getViewport().getRootNode().defaultView; + if (this.getOwnerDocument().defaultView != window ){ + this.externView = this.getOwnerDocument().defaultView; window.removeEventListener(EventType.RESIZE, this.handleResize_); - this.getViewport() - .getRootNode(). - defaultView.addEventListener( - EventType.RESIZE, - this.handleResize_, - false - ); + this.getOwnerDocument().defaultView.addEventListener(EventType.RESIZE,this.handleResize_,false); } } From f4739df90771e75eb710ef84b6911f2df2990b17 Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Tue, 19 Oct 2021 09:48:47 +0200 Subject: [PATCH 11/24] Update external-map.js --- examples/external-map.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/external-map.js b/examples/external-map.js index dc8f087162..523fd8d695 100644 --- a/examples/external-map.js +++ b/examples/external-map.js @@ -34,11 +34,13 @@ button.addEventListener('click', function () { mapWindow.addEventListener('load', function () { const extMapDiv = mapWindow.document.getElementById('map'); map.setTarget(extMapDiv); + extMapDiv.focus(); mapWindow.addEventListener('beforeunload', function () { localMapTarget.style.height = ''; map.setTarget(localMapTarget); button.disabled = false; + mapWindow.close(); mapWindow = undefined; }); From f353d52da3b8e70ee6060360f6168e30e61f2cb2 Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Tue, 19 Oct 2021 09:50:00 +0200 Subject: [PATCH 12/24] Update external-map.js --- examples/external-map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/external-map.js b/examples/external-map.js index 523fd8d695..ab5113ef67 100644 --- a/examples/external-map.js +++ b/examples/external-map.js @@ -40,7 +40,7 @@ button.addEventListener('click', function () { localMapTarget.style.height = ''; map.setTarget(localMapTarget); button.disabled = false; - mapWindow.close(); + mapWindow = undefined; }); From f2f9f68840d38d3170a56e909dd3d7e0aa1e7940 Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Tue, 19 Oct 2021 12:55:04 +0200 Subject: [PATCH 13/24] Update condition.js --- src/ol/events/condition.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/events/condition.js b/src/ol/events/condition.js index 56cdde0d41..02d2d1feb8 100644 --- a/src/ol/events/condition.js +++ b/src/ol/events/condition.js @@ -85,7 +85,7 @@ export const altShiftKeysOnly = function (mapBrowserEvent) { export const focus = function (event) { const targetElement = event.map.getTargetElement(); return targetElement.contains( - /** @type {Document} */ (targetElement.getRootNode({composed: true})) + /** @type {Document} */ (event.map.getOwnerDocument()) .activeElement ); }; From 51492243541d9915966b4372c46809f493a316f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Tue, 19 Oct 2021 22:07:33 +0200 Subject: [PATCH 14/24] Improve code and its formatting --- examples/external-map.js | 12 ++++---- src/ol/PluggableMap.js | 53 +++++++++--------------------------- src/ol/control/FullScreen.js | 19 +++++++++++-- src/ol/events/condition.js | 6 ++-- 4 files changed, 37 insertions(+), 53 deletions(-) diff --git a/examples/external-map.js b/examples/external-map.js index ab5113ef67..453b37faeb 100644 --- a/examples/external-map.js +++ b/examples/external-map.js @@ -2,8 +2,8 @@ import Map from '../src/ol/Map.js'; import OSM from '../src/ol/source/OSM.js'; import TileLayer from '../src/ol/layer/Tile.js'; import View from '../src/ol/View.js'; +import {FullScreen, defaults as defaultControls} from '../src/ol/control.js'; import {fromLonLat} from '../src/ol/proj.js'; -import {FullScreen, defaults as defaultControls} from 'ol/control'; const map = new Map({ target: 'map', @@ -34,18 +34,16 @@ button.addEventListener('click', function () { mapWindow.addEventListener('load', function () { const extMapDiv = mapWindow.document.getElementById('map'); map.setTarget(extMapDiv); - extMapDiv.focus(); - - mapWindow.addEventListener('beforeunload', function () { + extMapDiv.focus(); + + mapWindow.addEventListener('beforeunload', function () { localMapTarget.style.height = ''; map.setTarget(localMapTarget); button.disabled = false; - + mapWindow = undefined; }); - }); - }); window.addEventListener('beforeunload', function () { if (mapWindow) { diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 493570d8e2..81c38e070d 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -323,7 +323,7 @@ class PluggableMap extends BaseObject { * @private * @type {?Array} */ - this.keyHandlerKeys_ = null; + this.targetChangeHandlerKeys_ = null; /** * @type {Collection} @@ -356,12 +356,6 @@ class PluggableMap extends BaseObject { */ this.renderer_ = null; - /** - * @type {undefined|function(Event): void} - * @private - */ - this.handleResize_; - /** * @private * @type {!Array} @@ -1146,21 +1140,11 @@ class PluggableMap extends BaseObject { * @private */ handleTargetChanged_() { - // target may be undefined, null, a string or an Element. - // If it's a string we convert it to an Element before proceeding. - // If it's not now an Element we remove the viewport from the DOM. - // If it's an Element we append the viewport element to it. - - let targetElement; - if (this.getTarget()) { - targetElement = this.getTargetElement(); - } - if (this.mapBrowserEventHandler_) { - for (let i = 0, ii = this.keyHandlerKeys_.length; i < ii; ++i) { - unlistenByKey(this.keyHandlerKeys_[i]); + for (let i = 0, ii = this.targetChangeHandlerKeys_.length; i < ii; ++i) { + unlistenByKey(this.targetChangeHandlerKeys_[i]); } - this.keyHandlerKeys_ = null; + this.targetChangeHandlerKeys_ = null; this.viewport_.removeEventListener( EventType.CONTEXTMENU, this.boundHandleBrowserEvent_ @@ -1169,15 +1153,17 @@ class PluggableMap extends BaseObject { EventType.WHEEL, this.boundHandleBrowserEvent_ ); - if (this.handleResize_ !== undefined) { - removeEventListener(EventType.RESIZE, this.handleResize_, false); - this.handleResize_ = undefined; - } this.mapBrowserEventHandler_.dispose(); this.mapBrowserEventHandler_ = null; removeNode(this.viewport_); } + // target may be undefined, null, a string or an Element. + // If it's a string we convert it to an Element before proceeding. + // If it's not now an Element we remove the viewport from the DOM. + // If it's an Element we append the viewport element to it. + + const targetElement = this.getTargetElement(); if (!targetElement) { if (this.renderer_) { clearTimeout(this.postRenderTimeoutHandle_); @@ -1217,10 +1203,11 @@ class PluggableMap extends BaseObject { PASSIVE_EVENT_LISTENERS ? {passive: false} : false ); + const defaultView = this.getOwnerDocument().defaultView; const keyboardEventTarget = !this.keyboardEventTarget_ ? targetElement : this.keyboardEventTarget_; - this.keyHandlerKeys_ = [ + this.targetChangeHandlerKeys_ = [ listen( keyboardEventTarget, EventType.KEYDOWN, @@ -1233,22 +1220,8 @@ class PluggableMap extends BaseObject { this.handleBrowserEvent, this ), + listen(defaultView, EventType.RESIZE, this.updateSize, this), ]; - - if (!this.handleResize_) { - this.handleResize_ = this.updateSize.bind(this); - window.addEventListener(EventType.RESIZE, this.handleResize_, false); - } - - if (this.externView && this.externView != window){ - this.externView.removeEventListener(EventType.RESIZE, this.handleResize_); - } - - if (this.getOwnerDocument().defaultView != window ){ - this.externView = this.getOwnerDocument().defaultView; - window.removeEventListener(EventType.RESIZE, this.handleResize_); - this.getOwnerDocument().defaultView.addEventListener(EventType.RESIZE,this.handleResize_,false); - } } this.updateSize(); diff --git a/src/ol/control/FullScreen.js b/src/ol/control/FullScreen.js index c3c81f823c..4d2507042d 100644 --- a/src/ol/control/FullScreen.js +++ b/src/ol/control/FullScreen.js @@ -3,6 +3,7 @@ */ import Control from './Control.js'; import EventType from '../events/EventType.js'; +import MapProperty from '../MapProperty.js'; import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_UNSUPPORTED} from '../css.js'; import {listen, unlistenByKey} from '../events.js'; import {replaceNode} from '../dom.js'; @@ -187,6 +188,11 @@ class FullScreen extends Control { * @type {HTMLElement|string|undefined} */ this.source_ = options.source; + + /** + * @private + */ + this.boundHandleMapTargetChange_ = this.handleMapTargetChange_.bind(this); } /** @@ -271,6 +277,14 @@ class FullScreen extends Control { * @api */ setMap(map) { + const oldMap = this.getMap(); + if (oldMap) { + oldMap.removeChangeListener( + MapProperty.TARGET, + this.boundHandleMapTargetChange_ + ); + } + super.setMap(map); this.handleMapTargetChange_(); @@ -283,8 +297,9 @@ class FullScreen extends Control { } this.setClassName_(this.button_, isFullScreen(doc)); - this.listenerKeys.push( - listen(map, 'change:target', this.handleMapTargetChange_, this) + map.addChangeListener( + MapProperty.TARGET, + this.boundHandleMapTargetChange_ ); } } diff --git a/src/ol/events/condition.js b/src/ol/events/condition.js index 02d2d1feb8..2f6fdcd61c 100644 --- a/src/ol/events/condition.js +++ b/src/ol/events/condition.js @@ -84,10 +84,8 @@ export const altShiftKeysOnly = function (mapBrowserEvent) { */ export const focus = function (event) { const targetElement = event.map.getTargetElement(); - return targetElement.contains( - /** @type {Document} */ (event.map.getOwnerDocument()) - .activeElement - ); + const activeElement = event.map.getOwnerDocument().activeElement; + return targetElement.contains(activeElement); }; /** From 7bed63bf3f30027f829db5e6dbd412481b1d5891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Wed, 20 Oct 2021 01:18:05 +0200 Subject: [PATCH 15/24] Improve window open and close handling Use pagehide event instead of beforeunload, seems to be more reliable Add a timeout and info message when opening the window fails --- examples/external-map.html | 8 ++-- examples/external-map.js | 61 ++++++++++++++++-------- examples/resources/external-map-map.html | 4 -- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/examples/external-map.html b/examples/external-map.html index b372bf43f2..405fe44080 100644 --- a/examples/external-map.html +++ b/examples/external-map.html @@ -1,11 +1,11 @@ --- layout: example.html title: External map -shortdesc: Show a map in a separate window. +shortdesc: Move a map to a seperate window. docs: > - + Move a map to a seperate window. tags: "external, window" -resources: ---
- + + diff --git a/examples/external-map.js b/examples/external-map.js index 453b37faeb..f76e2aa62f 100644 --- a/examples/external-map.js +++ b/examples/external-map.js @@ -5,8 +5,10 @@ import View from '../src/ol/View.js'; import {FullScreen, defaults as defaultControls} from '../src/ol/control.js'; import {fromLonLat} from '../src/ol/proj.js'; +const localMapTarget = document.getElementById('map'); + const map = new Map({ - target: 'map', + target: localMapTarget, controls: defaultControls().extend([new FullScreen()]), layers: [ new TileLayer({ @@ -20,33 +22,54 @@ const map = new Map({ }); let mapWindow; -const button = document.getElementById('extMap'); +function closeMapWindow() { + if (mapWindow) { + mapWindow.close(); + mapWindow = undefined; + } +} +// Close external window in case the main page is closed or reloaded +window.addEventListener('pagehide', closeMapWindow); + +const button = document.getElementById('external-map-button'); + +function resetMapTarget() { + localMapTarget.style.height = ''; + map.setTarget(localMapTarget); + button.disabled = false; +} + button.addEventListener('click', function () { - const localMapTarget = document.getElementById('map'); - localMapTarget.style.height = '0px'; + const blockerNotice = document.getElementById('blocker-notice'); + blockerNotice.setAttribute('hidden', 'hidden'); button.disabled = true; + // Reset button and map target in case window did not load or open + let timeoutKey = setTimeout(function () { + closeMapWindow(); + resetMapTarget(); + blockerNotice.removeAttribute('hidden'); + timeoutKey = undefined; + }, 3000); + mapWindow = window.open( 'resources/external-map-map.html', 'MapWindow', 'toolbar=0,location=0,menubar=0,width=800,height=600' ); - mapWindow.addEventListener('load', function () { - const extMapDiv = mapWindow.document.getElementById('map'); - map.setTarget(extMapDiv); - extMapDiv.focus(); + mapWindow.addEventListener('DOMContentLoaded', function () { + const externalMapTarget = mapWindow.document.getElementById('map'); + localMapTarget.style.height = '0px'; + map.setTarget(externalMapTarget); + externalMapTarget.focus(); - mapWindow.addEventListener('beforeunload', function () { - localMapTarget.style.height = ''; - map.setTarget(localMapTarget); - button.disabled = false; - - mapWindow = undefined; + if (timeoutKey) { + timeoutKey = clearTimeout(timeoutKey); + } + mapWindow.addEventListener('pagehide', function () { + resetMapTarget(); + // Close window in case user does a page reload + closeMapWindow(); }); }); }); -window.addEventListener('beforeunload', function () { - if (mapWindow) { - mapWindow.close(); - } -}); diff --git a/examples/resources/external-map-map.html b/examples/resources/external-map-map.html index 179770b800..4d3ca1fc5b 100644 --- a/examples/resources/external-map-map.html +++ b/examples/resources/external-map-map.html @@ -13,10 +13,6 @@ -
From f74cd628272042210fbd71f2f1ac9077edac791e Mon Sep 17 00:00:00 2001 From: andrewcoder002 <92372311+andrewcoder002@users.noreply.github.com> Date: Wed, 20 Oct 2021 09:29:01 +0200 Subject: [PATCH 16/24] Update external-map.js Handle situations when main window loose focus - e.g. by selecting of differen browser tab. --- examples/external-map.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/external-map.js b/examples/external-map.js index f76e2aa62f..2dc39d52e3 100644 --- a/examples/external-map.js +++ b/examples/external-map.js @@ -71,5 +71,19 @@ button.addEventListener('click', function () { // Close window in case user does a page reload closeMapWindow(); }); + + window.addEventListener('blur', function (evt) { + externalMapTarget.style.opacity=0.3; + }); + + window.addEventListener('focus', function (evt) { + externalMapTarget.style.opacity=1.0; + }); + + mapWindow.addEventListener('focus', function (evt) { + if (!window.document.hidden){ + externalMapTarget.style.opacity=1.0; + } + }); }); }); From 9a6bb4d75133179e866834c4bb20d6dfc38ed134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Wed, 20 Oct 2021 22:06:28 +0200 Subject: [PATCH 17/24] Fix FullScreen state when changing target in fullscreen mode --- src/ol/control/FullScreen.js | 43 ++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/ol/control/FullScreen.js b/src/ol/control/FullScreen.js index 4d2507042d..6c91aeb449 100644 --- a/src/ol/control/FullScreen.js +++ b/src/ol/control/FullScreen.js @@ -189,6 +189,12 @@ class FullScreen extends Control { */ this.source_ = options.source; + /** + * @type {boolean} + * @private + */ + this.isInFullscreen_ = false; + /** * @private */ @@ -241,16 +247,20 @@ class FullScreen extends Control { */ handleFullScreenChange_() { const map = this.getMap(); - if (isFullScreen(map.getOwnerDocument())) { - this.setClassName_(this.button_, true); - replaceNode(this.labelActiveNode_, this.labelNode_); - this.dispatchEvent(FullScreenEventType.ENTERFULLSCREEN); - } else { - this.setClassName_(this.button_, false); - replaceNode(this.labelNode_, this.labelActiveNode_); - this.dispatchEvent(FullScreenEventType.LEAVEFULLSCREEN); + if (!map) { + return; } - if (map) { + const wasInFullscreen = this.isInFullscreen_; + this.isInFullscreen_ = isFullScreen(map.getOwnerDocument()); + if (wasInFullscreen !== this.isInFullscreen_) { + this.setClassName_(this.button_, this.isInFullscreen_); + if (this.isInFullscreen_) { + replaceNode(this.labelActiveNode_, this.labelNode_); + this.dispatchEvent(FullScreenEventType.ENTERFULLSCREEN); + } else { + replaceNode(this.labelNode_, this.labelActiveNode_); + this.dispatchEvent(FullScreenEventType.LEAVEFULLSCREEN); + } map.updateSize(); } } @@ -289,14 +299,6 @@ class FullScreen extends Control { this.handleMapTargetChange_(); if (map) { - const doc = map.getOwnerDocument(); - if (isFullScreenSupported(doc)) { - this.element.classList.remove(CLASS_UNSUPPORTED); - } else { - this.element.classList.add(CLASS_UNSUPPORTED); - } - this.setClassName_(this.button_, isFullScreen(doc)); - map.addChangeListener( MapProperty.TARGET, this.boundHandleMapTargetChange_ @@ -317,11 +319,18 @@ class FullScreen extends Control { const map = this.getMap(); if (map) { const doc = map.getOwnerDocument(); + if (isFullScreenSupported(doc)) { + this.element.classList.remove(CLASS_UNSUPPORTED); + } else { + this.element.classList.add(CLASS_UNSUPPORTED); + } + for (let i = 0, ii = events.length; i < ii; ++i) { listeners.push( listen(doc, events[i], this.handleFullScreenChange_, this) ); } + this.handleFullScreenChange_(); } } } From 50dc9f1f88215a1eea990231e3f96cf1245f8805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Wed, 20 Oct 2021 22:06:55 +0200 Subject: [PATCH 18/24] Fix map tests --- test/browser/spec/ol/Map.test.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/browser/spec/ol/Map.test.js b/test/browser/spec/ol/Map.test.js index d96422eb79..5c436503e4 100644 --- a/test/browser/spec/ol/Map.test.js +++ b/test/browser/spec/ol/Map.test.js @@ -816,7 +816,7 @@ describe('ol/Map', function () { it('removes window listeners', function () { map.dispose(); - expect(map.handleResize_).to.be(undefined); + expect(map.targetChangeHandlerKeys_).to.be(null); }); }); @@ -828,7 +828,7 @@ describe('ol/Map', function () { map = new Map({ target: document.createElement('div'), }); - expect(map.handleResize_).to.be.ok(); + expect(map.targetChangeHandlerKeys_).to.be.ok(); }); describe('map with target not attached to dom', function () { @@ -840,7 +840,7 @@ describe('ol/Map', function () { describe('call setTarget with null', function () { it('unregisters the viewport resize listener', function () { map.setTarget(null); - expect(map.handleResize_).to.be(undefined); + expect(map.targetChangeHandlerKeys_).to.be(null); }); }); @@ -848,7 +848,7 @@ describe('ol/Map', function () { it('registers a viewport resize listener', function () { map.setTarget(null); map.setTarget(document.createElement('div')); - expect(map.handleResize_).to.be.ok(); + expect(map.targetChangeHandlerKeys_).to.be.ok(); }); }); }); @@ -877,8 +877,14 @@ describe('ol/Map', function () { hasAttribute: function (attribute) { return hasTabIndex; }, + contains: function () { + return hasFocus; + }, }; }, + getOwnerDocument: function () { + return {}; + }, }, originalEvent: { isPrimary: isPrimary, From 8cff6206915a02c52ddc7a3d0e140397165c8673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Sat, 30 Oct 2021 15:39:46 +0200 Subject: [PATCH 19/24] Improve unusable map window As long as the original window is visible animation frames will run and the external map will be usable --- examples/external-map.js | 37 +++++++++++++++--------- examples/resources/external-map-map.html | 32 ++++++++++++++++++-- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/examples/external-map.js b/examples/external-map.js index 2dc39d52e3..9a42661061 100644 --- a/examples/external-map.js +++ b/examples/external-map.js @@ -39,6 +39,28 @@ function resetMapTarget() { button.disabled = false; } +function updateOverlay() { + if (!mapWindow) { + return; + } + const container = mapWindow.document.querySelector('.container'); + if (!container) { + return; + } + const externalMapTarget = mapWindow.document.getElementById('map'); + if (document.visibilityState === 'visible') { + // Show controls and enable keyboard input + container.classList.remove('unusable'); + externalMapTarget.setAttribute('tabindex', '0'); + externalMapTarget.focus(); + } else { + // Hide all controls and disable keyboard input + externalMapTarget.removeAttribute('tabindex'); + container.classList.add('unusable'); + } +} +window.addEventListener('visibilitychange', updateOverlay); + button.addEventListener('click', function () { const blockerNotice = document.getElementById('blocker-notice'); blockerNotice.setAttribute('hidden', 'hidden'); @@ -61,7 +83,6 @@ button.addEventListener('click', function () { const externalMapTarget = mapWindow.document.getElementById('map'); localMapTarget.style.height = '0px'; map.setTarget(externalMapTarget); - externalMapTarget.focus(); if (timeoutKey) { timeoutKey = clearTimeout(timeoutKey); @@ -72,18 +93,6 @@ button.addEventListener('click', function () { closeMapWindow(); }); - window.addEventListener('blur', function (evt) { - externalMapTarget.style.opacity=0.3; - }); - - window.addEventListener('focus', function (evt) { - externalMapTarget.style.opacity=1.0; - }); - - mapWindow.addEventListener('focus', function (evt) { - if (!window.document.hidden){ - externalMapTarget.style.opacity=1.0; - } - }); + updateOverlay(); }); }); diff --git a/examples/resources/external-map-map.html b/examples/resources/external-map-map.html index 4d3ca1fc5b..8526da9a6d 100644 --- a/examples/resources/external-map-map.html +++ b/examples/resources/external-map-map.html @@ -6,13 +6,39 @@ body { margin: 0; } - .map { + .container { + position: relative; height: 100%; width: 100%; } + #unusable-overlay, + .map { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + } + .unusable #unusable-overlay { + background-color: rgba(0, 0, 0, .7); + font-size: 3rem; + font-weight: bold; + color: white; + display: flex; + align-items: center; + user-select: none; + justify-content: center; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + } + .unusable .map .ol-control { + display: none; + } - -
+ +
+ From 46d9e8db8e916d63fc5e8310f8f12439023e98ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Tue, 2 Nov 2021 00:06:37 +0100 Subject: [PATCH 20/24] Fix codesandbox edit for offscreen-canvas example --- examples/webpack/example-builder.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/webpack/example-builder.js b/examples/webpack/example-builder.js index 6574685807..8f41398982 100644 --- a/examples/webpack/example-builder.js +++ b/examples/webpack/example-builder.js @@ -307,7 +307,10 @@ export default class ExampleBuilder { /import Worker from 'worker-loader![^\n]*\n/g, '' ); - jsSource = jsSource.replace('new Worker()', "new Worker('./worker.js')"); + jsSource = jsSource.replace( + 'new Worker()', + "new Worker('./worker.js', {type: 'module'})" + ); data.js = { tag: ` From ca9fc92f70715125b7c455d37a0f94d51b173547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Mon, 1 Nov 2021 23:34:44 +0100 Subject: [PATCH 21/24] Example builder code cleanup Add function for transforming js source and cloaking Use to parse source for import statements Use now released parcel 2.0.0 --- examples/webpack/example-builder.js | 92 ++++++++++++----------------- 1 file changed, 38 insertions(+), 54 deletions(-) diff --git a/examples/webpack/example-builder.js b/examples/webpack/example-builder.js index 8f41398982..c8efc6370a 100644 --- a/examples/webpack/example-builder.js +++ b/examples/webpack/example-builder.js @@ -13,7 +13,7 @@ const baseDir = dirname(fileURLToPath(import.meta.url)); const isCssRegEx = /\.css(\?.*)?$/; const isJsRegEx = /\.js(\?.*)?$/; -const importRegEx = /^import .* from '(.*)';$/; +const importRegEx = /(?:^|\n)import .* from '(.*)';(?:\n|$)/g; const isTemplateJs = /\/(jquery(-\d+\.\d+\.\d+)?|(bootstrap(\.bundle)?))(\.min)?\.js(\?.*)?$/; const isTemplateCss = /\/bootstrap(\.min)?\.css(\?.*)?$/; @@ -134,26 +134,18 @@ function createWordIndex(exampleData) { * @return {Object} dependencies */ function getDependencies(jsSource, pkg) { - const lines = jsSource.split('\n'); const dependencies = { ol: pkg.version, }; - for (let i = 0, ii = lines.length; i < ii; ++i) { - const line = lines[i]; - const importMatch = line.match(importRegEx); - if (importMatch) { - const imp = importMatch[1]; - if (!imp.startsWith('ol/') && imp != 'ol') { - const parts = imp.split('/'); - let dep; - if (imp.startsWith('@')) { - dep = parts.slice(0, 2).join('/'); - } else { - dep = parts[0]; - } - if (dep in pkg.devDependencies) { - dependencies[dep] = pkg.devDependencies[dep]; - } + + let importMatch; + while ((importMatch = importRegEx.exec(jsSource))) { + const imp = importMatch[1]; + if (!imp.startsWith('ol/') && imp != 'ol') { + const parts = imp.split('/'); + const dep = imp.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]; + if (dep in pkg.devDependencies) { + dependencies[dep] = pkg.devDependencies[dep]; } } } @@ -279,39 +271,40 @@ export default class ExampleBuilder { data.jsSource = jsSource; // process tags - if (data.tags) { - data.tags = data.tags.replace(/[\s"]+/g, '').split(','); - } else { - data.tags = []; - } + data.tags = data.tags ? data.tags.replace(/[\s"]+/g, '').split(',') : []; return data; } + transformJsSource(source) { + return ( + source + // remove "../src/" prefix and ".js" to have the same import syntax as the documentation + .replace(/'\.\.\/src\//g, "'") + .replace(/\.js';/g, "';") + // Remove worker loader import and modify `new Worker()` to add source + .replace(/import Worker from 'worker-loader![^\n]*\n/g, '') + .replace('new Worker()', "new Worker('./worker.js', {type: 'module'})") + ); + } + + cloakSource(source, cloak) { + if (cloak) { + for (const entry of cloak) { + source = source.replace(new RegExp(entry.key, 'g'), entry.value); + } + } + return source; + } + async render(data) { const assets = {}; const readOptions = {encoding: 'utf8'}; // add in script tag const jsName = `${data.name}.js`; - - // remove "../src/" prefix and ".js" to have the same import syntax as the documentation - let jsSource = data.jsSource.replace(/'\.\.\/src\//g, "'"); - jsSource = jsSource.replace(/\.js';/g, "';"); - if (data.cloak) { - for (const entry of data.cloak) { - jsSource = jsSource.replace(new RegExp(entry.key, 'g'), entry.value); - } - } - // Remove worker loader import and modify `new Worker()` to add source - jsSource = jsSource.replace( - /import Worker from 'worker-loader![^\n]*\n/g, - '' + const jsSource = this.transformJsSource( + this.cloakSource(data.jsSource, data.cloak) ); - jsSource = jsSource.replace( - 'new Worker()', - "new Worker('./worker.js', {type: 'module'})" - ); - data.js = { tag: ` `, @@ -328,17 +321,9 @@ export default class ExampleBuilder { // pass } if (workerSource) { - // remove "../src/" prefix and ".js" to have the same import syntax as the documentation - workerSource = workerSource.replace(/'\.\.\/src\//g, "'"); - workerSource = workerSource.replace(/\.js';/g, "';"); - if (data.cloak) { - for (const entry of data.cloak) { - workerSource = workerSource.replace( - new RegExp(entry.key, 'g'), - entry.value - ); - } - } + workerSource = this.transformJsSource( + this.cloakSource(workerSource, data.cloak) + ); data.worker = { source: workerSource, }; @@ -346,7 +331,6 @@ export default class ExampleBuilder { } const pkg = await getPackageInfo(); - data.pkgJson = JSON.stringify( { name: data.name, @@ -355,7 +339,7 @@ export default class ExampleBuilder { pkg ), devDependencies: { - parcel: '^2.0.0-beta.1', + parcel: '^2.0.0', }, scripts: { start: 'parcel index.html', From a10bc713f2347cf7ffd13887928a23db78ec9050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Tue, 2 Nov 2021 00:12:57 +0100 Subject: [PATCH 22/24] Configure additional sources displayed below map --- examples/external-map.html | 4 ++- examples/offscreen-canvas.html | 3 +- examples/templates/example.html | 11 ++++--- examples/webpack/example-builder.js | 45 ++++++++++++++++------------- 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/examples/external-map.html b/examples/external-map.html index 405fe44080..1cf5f4c030 100644 --- a/examples/external-map.html +++ b/examples/external-map.html @@ -5,7 +5,9 @@ shortdesc: Move a map to a seperate window. docs: > Move a map to a seperate window. tags: "external, window" +sources: + - resources/external-map-map.html ---
- + diff --git a/examples/offscreen-canvas.html b/examples/offscreen-canvas.html index 65438c4519..7218b3a78a 100644 --- a/examples/offscreen-canvas.html +++ b/examples/offscreen-canvas.html @@ -6,10 +6,11 @@ docs: > The map in this example is rendered in a web worker, using `OffscreenCanvas`. **Note:** This is currently only supported in Chrome and Edge. tags: "worker, offscreencanvas, vector-tiles" experimental: true +sources: + - offscreen-canvas.worker.js as worker.js cloak: - key: get_your_own_D6rA4zTHduk6KOKTXzGB value: Get your own API key at https://www.maptiler.com/cloud/ - ---
diff --git a/examples/templates/example.html b/examples/templates/example.html
index fdead5dd47..a9d2958068 100644
--- a/examples/templates/example.html
+++ b/examples/templates/example.html
@@ -211,13 +211,12 @@
 </html>
-{{#if worker.source}} -
-
worker.js
-
{{ worker.source }}
+{{#each extraSources}} +
+
{{./name}}
+
{{ ./source }}
-{{/if}} - +{{/each}}
package.json
{{ pkgJson }}
diff --git a/examples/webpack/example-builder.js b/examples/webpack/example-builder.js index c8efc6370a..55b307ab72 100644 --- a/examples/webpack/example-builder.js +++ b/examples/webpack/example-builder.js @@ -311,33 +311,38 @@ export default class ExampleBuilder { source: jsSource, }; - // check for worker js - const workerName = `${data.name}.worker.js`; - const workerPath = path.join(data.dir, workerName); - let workerSource; - try { - workerSource = await fse.readFile(workerPath, readOptions); - } catch (err) { - // pass - } - if (workerSource) { - workerSource = this.transformJsSource( - this.cloakSource(workerSource, data.cloak) + let jsSources = jsSource; + if (data.sources) { + data.extraSources = await Promise.all( + data.sources.map(async (fileName) => { + const as = fileName.split(/ +as +/); + fileName = as[0]; + const extraSourcePath = path.join(data.dir, fileName); + let source = await fse.readFile(extraSourcePath, readOptions); + let ext = fileName.match(/\.(\w+)$/)[1]; + if (ext === 'mjs') { + ext = 'js'; + } + if (ext === 'js') { + source = this.transformJsSource(source); + jsSources += '\n' + source; + } + source = this.cloakSource(source, data.cloak); + assets[fileName] = source; + return { + name: as[1] || fileName, + source: source, + type: ext, + }; + }) ); - data.worker = { - source: workerSource, - }; - assets[workerName] = workerSource; } const pkg = await getPackageInfo(); data.pkgJson = JSON.stringify( { name: data.name, - dependencies: getDependencies( - jsSource + (workerSource ? `\n${workerSource}` : ''), - pkg - ), + dependencies: getDependencies(jsSources, pkg), devDependencies: { parcel: '^2.0.0', }, From 12de93b397f1c8fb99d3a2f37e82a2070a38fd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Tue, 2 Nov 2021 20:06:06 +0100 Subject: [PATCH 23/24] Fixed unusable overlay in fullscreen mode --- examples/external-map.js | 28 ++++++++++++++++------ examples/resources/external-map-map.html | 30 +++++++----------------- src/ol/control/FullScreen.js | 2 +- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/examples/external-map.js b/examples/external-map.js index 9a42661061..358f57cf43 100644 --- a/examples/external-map.js +++ b/examples/external-map.js @@ -2,14 +2,29 @@ import Map from '../src/ol/Map.js'; import OSM from '../src/ol/source/OSM.js'; import TileLayer from '../src/ol/layer/Tile.js'; import View from '../src/ol/View.js'; -import {FullScreen, defaults as defaultControls} from '../src/ol/control.js'; +import { + Control, + FullScreen, + defaults as defaultControls, +} from '../src/ol/control.js'; import {fromLonLat} from '../src/ol/proj.js'; +class UnusableMask extends Control { + constructor() { + super({ + element: document.createElement('div'), + }); + this.element.setAttribute('hidden', 'hidden'); + this.element.className = 'ol-mask'; + this.element.innerHTML = '
Map not usable
'; + } +} + const localMapTarget = document.getElementById('map'); const map = new Map({ target: localMapTarget, - controls: defaultControls().extend([new FullScreen()]), + controls: defaultControls().extend([new FullScreen(), new UnusableMask()]), layers: [ new TileLayer({ source: new OSM(), @@ -43,20 +58,19 @@ function updateOverlay() { if (!mapWindow) { return; } - const container = mapWindow.document.querySelector('.container'); - if (!container) { + const externalMapTarget = mapWindow.document.getElementById('map'); + if (!externalMapTarget) { return; } - const externalMapTarget = mapWindow.document.getElementById('map'); if (document.visibilityState === 'visible') { // Show controls and enable keyboard input - container.classList.remove('unusable'); + externalMapTarget.classList.remove('unusable'); externalMapTarget.setAttribute('tabindex', '0'); externalMapTarget.focus(); } else { // Hide all controls and disable keyboard input externalMapTarget.removeAttribute('tabindex'); - container.classList.add('unusable'); + externalMapTarget.classList.add('unusable'); } } window.addEventListener('visibilitychange', updateOverlay); diff --git a/examples/resources/external-map-map.html b/examples/resources/external-map-map.html index 8526da9a6d..0bc2512495 100644 --- a/examples/resources/external-map-map.html +++ b/examples/resources/external-map-map.html @@ -6,39 +6,25 @@ body { margin: 0; } - .container { - position: relative; - height: 100%; - width: 100%; - } - #unusable-overlay, .map { - position: absolute; - top: 0; - left: 0; height: 100%; - width: 100%; } - .unusable #unusable-overlay { - background-color: rgba(0, 0, 0, .7); - font-size: 3rem; - font-weight: bold; - color: white; + .map.unusable .ol-mask { + height: 100%; display: flex; align-items: center; - user-select: none; justify-content: center; - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + user-select: none; + background-color: rgba(0, 0, 0, .7); + color: white; + font: bold 3rem 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } - .unusable .map .ol-control { + .map.unusable .ol-control { display: none; } - +
- diff --git a/src/ol/control/FullScreen.js b/src/ol/control/FullScreen.js index 6c91aeb449..429c1bfc90 100644 --- a/src/ol/control/FullScreen.js +++ b/src/ol/control/FullScreen.js @@ -229,7 +229,7 @@ class FullScreen extends Control { if (this.source_) { element = typeof this.source_ === 'string' - ? document.getElementById(this.source_) + ? doc.getElementById(this.source_) : this.source_; } else { element = map.getTargetElement(); From 07fa1adfe8249fa799041c89eb5b3629a29dc068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Tue, 2 Nov 2021 22:02:23 +0100 Subject: [PATCH 24/24] Use more structured yaml for examples source path --- examples/external-map.html | 2 +- examples/offscreen-canvas.html | 3 ++- examples/webpack/example-builder.js | 7 +++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/external-map.html b/examples/external-map.html index 1cf5f4c030..ed37467931 100644 --- a/examples/external-map.html +++ b/examples/external-map.html @@ -6,7 +6,7 @@ docs: > Move a map to a seperate window. tags: "external, window" sources: - - resources/external-map-map.html + - path: resources/external-map-map.html ---
diff --git a/examples/offscreen-canvas.html b/examples/offscreen-canvas.html index 7218b3a78a..c76d014fee 100644 --- a/examples/offscreen-canvas.html +++ b/examples/offscreen-canvas.html @@ -7,7 +7,8 @@ docs: > tags: "worker, offscreencanvas, vector-tiles" experimental: true sources: - - offscreen-canvas.worker.js as worker.js + - path: offscreen-canvas.worker.js + as: worker.js cloak: - key: get_your_own_D6rA4zTHduk6KOKTXzGB value: Get your own API key at https://www.maptiler.com/cloud/ diff --git a/examples/webpack/example-builder.js b/examples/webpack/example-builder.js index 55b307ab72..e2b4ffef70 100644 --- a/examples/webpack/example-builder.js +++ b/examples/webpack/example-builder.js @@ -314,9 +314,8 @@ export default class ExampleBuilder { let jsSources = jsSource; if (data.sources) { data.extraSources = await Promise.all( - data.sources.map(async (fileName) => { - const as = fileName.split(/ +as +/); - fileName = as[0]; + data.sources.map(async (sourceConfig) => { + const fileName = sourceConfig.path; const extraSourcePath = path.join(data.dir, fileName); let source = await fse.readFile(extraSourcePath, readOptions); let ext = fileName.match(/\.(\w+)$/)[1]; @@ -330,7 +329,7 @@ export default class ExampleBuilder { source = this.cloakSource(source, data.cloak); assets[fileName] = source; return { - name: as[1] || fileName, + name: sourceConfig.as ?? fileName, source: source, type: ext, };