From 6d72f929641158c78efe6075ceba39308a1bdc5a Mon Sep 17 00:00:00 2001 From: johndoe Date: Mon, 6 May 2019 23:23:48 +0300 Subject: [PATCH 1/3] Refactor openPopup/Tooltip to use common functions [Map/Layer]\_initOverlay --- src/layer/DivOverlay.js | 29 +++++++++++++++++++++++++++++ src/layer/Popup.js | 35 +++++++++-------------------------- src/layer/Tooltip.js | 28 +++++----------------------- 3 files changed, 43 insertions(+), 49 deletions(-) diff --git a/src/layer/DivOverlay.js b/src/layer/DivOverlay.js index 4e0a3a95eec..e172ab3f1a1 100644 --- a/src/layer/DivOverlay.js +++ b/src/layer/DivOverlay.js @@ -1,3 +1,4 @@ +import {Map} from '../map/Map'; import {Layer} from './Layer'; import {FeatureGroup} from './FeatureGroup'; import * as Util from '../core/Util'; @@ -248,3 +249,31 @@ export var DivOverlay = Layer.extend({ } }); + +Map.include({ + _initOverlay: function (OverlayClass, content, latlng, options) { + var overlay = content; + if (!(overlay instanceof OverlayClass)) { + overlay = new OverlayClass(options).setContent(content); + } + if (latlng) { + overlay.setLatLng(latlng); + } + return overlay; + } +}); + + +Layer.include({ + _initOverlay: function (OverlayClass, old, content, options) { + var overlay = content; + if (overlay instanceof OverlayClass) { + Util.setOptions(overlay, options); + overlay._source = this; + } else { + overlay = (old && !options) ? old : new OverlayClass(options, this); + overlay.setContent(content); + } + return overlay; + } +}); diff --git a/src/layer/Popup.js b/src/layer/Popup.js index cb4dbbd7fd6..69f63ba3b3a 100644 --- a/src/layer/Popup.js +++ b/src/layer/Popup.js @@ -4,7 +4,6 @@ import * as DomUtil from '../dom/DomUtil'; import {Point, toPoint} from '../geometry/Point'; import {Map} from '../map/Map'; import {Layer} from './Layer'; -import * as Util from '../core/Util'; import {Path} from './vector/Path'; /* @@ -321,24 +320,19 @@ Map.include({ // @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this // Creates a popup with the specified content and options and opens it in the given point on a map. openPopup: function (popup, latlng, options) { - if (!(popup instanceof Popup)) { - popup = new Popup(options).setContent(popup); - } + popup = this._initOverlay(Popup, popup, latlng, options); - if (latlng) { - popup.setLatLng(latlng); - } + if (!this.hasLayer(popup)) { + if (this._popup && this._popup.options.autoClose) { + this.closePopup(); + } - if (this.hasLayer(popup)) { - return this; + this._popup = popup; + this.addLayer(popup); } - if (this._popup && this._popup.options.autoClose) { - this.closePopup(); - } + return this; - this._popup = popup; - return this.addLayer(popup); }, // @method closePopup(popup?: Popup): this @@ -378,18 +372,7 @@ Layer.include({ // necessary event listeners. If a `Function` is passed it will receive // the layer as the first argument and should return a `String` or `HTMLElement`. bindPopup: function (content, options) { - - if (content instanceof Popup) { - Util.setOptions(content, options); - this._popup = content; - content._source = this; - } else { - if (!this._popup || options) { - this._popup = new Popup(options, this); - } - this._popup.setContent(content); - } - + this._popup = this._initOverlay(Popup, this._popup, content, options); if (!this._popupHandlersAdded) { this.on({ click: this._openPopup, diff --git a/src/layer/Tooltip.js b/src/layer/Tooltip.js index 1a898d8ed8f..49bc1e70a15 100644 --- a/src/layer/Tooltip.js +++ b/src/layer/Tooltip.js @@ -2,7 +2,6 @@ import {DivOverlay} from './DivOverlay'; import {toPoint} from '../geometry/Point'; import {Map} from '../map/Map'; import {Layer} from './Layer'; -import * as Util from '../core/Util'; import * as DomUtil from '../dom/DomUtil'; /* @@ -231,19 +230,13 @@ Map.include({ // @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this // Creates a tooltip with the specified content and options and open it. openTooltip: function (tooltip, latlng, options) { - if (!(tooltip instanceof Tooltip)) { - tooltip = new Tooltip(options).setContent(tooltip); - } - - if (latlng) { - tooltip.setLatLng(latlng); - } + tooltip = this._initOverlay(Tooltip, tooltip, latlng, options); - if (this.hasLayer(tooltip)) { - return this; + if (!this.hasLayer(tooltip)) { + this.addLayer(tooltip); } - return this.addLayer(tooltip); + return this; }, // @method closeTooltip(tooltip: Tooltip): this @@ -280,18 +273,7 @@ Layer.include({ this.unbindTooltip(); } - if (content instanceof Tooltip) { - Util.setOptions(content, options); - this._tooltip = content; - content._source = this; - } else { - if (!this._tooltip || options) { - this._tooltip = new Tooltip(options, this); - } - this._tooltip.setContent(content); - - } - + this._tooltip = this._initOverlay(Tooltip, this._tooltip, content, options); this._initTooltipInteractions(); if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) { From 00d9ac7af597c732101443b6a48972ad6edd2785 Mon Sep 17 00:00:00 2001 From: johndoe Date: Mon, 6 May 2019 23:21:14 +0300 Subject: [PATCH 2/3] DivOverlay: common functions openOn/close Refactor [Map\Layer] open/close-Popup/Tooltip to use DivOverlay's openOn/close --- src/layer/DivOverlay.js | 22 +++++++++++++++++ src/layer/Popup.js | 54 ++++++++++++++++++----------------------- src/layer/Tooltip.js | 26 ++++++-------------- 3 files changed, 53 insertions(+), 49 deletions(-) diff --git a/src/layer/DivOverlay.js b/src/layer/DivOverlay.js index e172ab3f1a1..8f4e291748a 100644 --- a/src/layer/DivOverlay.js +++ b/src/layer/DivOverlay.js @@ -38,6 +38,28 @@ export var DivOverlay = Layer.extend({ this._source = source; }, + // @method openOn(map: Map): this + // Adds the overlay to the map. + // Alternative to `map.openPopup(popup)`/`.openTooltip(tooltip)`. + openOn: function (map) { + map = arguments.length ? map : this._source._map; // experimental, not the part of public api + if (!map.hasLayer(this)) { + map.addLayer(this); + } + return this; + }, + + // @method close(): this + // Closes the overlay. + // Alternative to `map.closePopup(popup)`/`.closeTooltip(tooltip)` + // and `layer.closePopup()`/`.closeTooltip()`. + close: function () { + if (this._map) { + this._map.removeLayer(this); + } + return this; + }, + onAdd: function (map) { this._zoomAnimated = map._zoomAnimated; diff --git a/src/layer/Popup.js b/src/layer/Popup.js index 69f63ba3b3a..8cb931c3933 100644 --- a/src/layer/Popup.js +++ b/src/layer/Popup.js @@ -109,10 +109,17 @@ export var Popup = DivOverlay.extend({ // @namespace Popup // @method openOn(map: Map): this - // Adds the popup to the map and closes the previous one. The same as `map.openPopup(popup)`. + // Alternative to `map.openPopup(popup)`. + // Adds the popup to the map and closes the previous one. openOn: function (map) { - map.openPopup(this); - return this; + map = arguments.length ? map : this._source._map; // experimental, not the part of public api + + if (!map.hasLayer(this) && map._popup && map._popup.options.autoClose) { + map.removeLayer(map._popup); + } + map._popup = this; + + return DivOverlay.prototype.openOn.call(this, map); }, onAdd: function (map) { @@ -141,6 +148,10 @@ export var Popup = DivOverlay.extend({ onRemove: function (map) { DivOverlay.prototype.onRemove.call(this, map); + if (this === map._popup) { + map._popup = null; + } + // @namespace Map // @section Popup events // @event popupclose: PopupEvent @@ -163,7 +174,7 @@ export var Popup = DivOverlay.extend({ var events = DivOverlay.prototype.getEvents.call(this); if (this.options.closeOnClick !== undefined ? this.options.closeOnClick : this._map.options.closePopupOnClick) { - events.preclick = this._close; + events.preclick = this.close; } if (this.options.keepInView) { @@ -173,12 +184,6 @@ export var Popup = DivOverlay.extend({ return events; }, - _close: function () { - if (this._map) { - this._map.closePopup(this); - } - }, - _initLayout: function () { var prefix = 'leaflet-popup', container = this._container = DomUtil.create('div', @@ -202,7 +207,7 @@ export var Popup = DivOverlay.extend({ closeButton.href = '#close'; closeButton.innerHTML = ''; - DomEvent.on(closeButton, 'click', this._close, this); + DomEvent.on(closeButton, 'click', this.close, this); } }, @@ -320,30 +325,18 @@ Map.include({ // @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this // Creates a popup with the specified content and options and opens it in the given point on a map. openPopup: function (popup, latlng, options) { - popup = this._initOverlay(Popup, popup, latlng, options); - - if (!this.hasLayer(popup)) { - if (this._popup && this._popup.options.autoClose) { - this.closePopup(); - } - - this._popup = popup; - this.addLayer(popup); - } + this._initOverlay(Popup, popup, latlng, options) + .openOn(this); return this; - }, // @method closePopup(popup?: Popup): this // Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one). closePopup: function (popup) { - if (!popup || popup === this._popup) { - popup = this._popup; - this._popup = null; - } + popup = arguments.length ? popup : this._popup; if (popup) { - this.removeLayer(popup); + popup.close(); } return this; } @@ -407,9 +400,8 @@ Layer.include({ openPopup: function (latlng) { if (this._popup && this._popup._prepareOpen(latlng)) { // open the popup on the map - this._map.openPopup(this._popup, latlng); + this._popup.openOn(this._map); } - return this; }, @@ -417,7 +409,7 @@ Layer.include({ // Closes the popup bound to this layer if it is open. closePopup: function () { if (this._popup) { - this._popup._close(); + this._popup.close(); } return this; }, @@ -427,7 +419,7 @@ Layer.include({ togglePopup: function () { if (this._popup) { if (this._popup._map) { - this.closePopup(); + this._popup.close(); } else { this.openPopup(); } diff --git a/src/layer/Tooltip.js b/src/layer/Tooltip.js index 49bc1e70a15..2b09387565e 100644 --- a/src/layer/Tooltip.js +++ b/src/layer/Tooltip.js @@ -118,18 +118,12 @@ export var Tooltip = DivOverlay.extend({ var events = DivOverlay.prototype.getEvents.call(this); if (!this.options.permanent) { - events.preclick = this._close; + events.preclick = this.close; } return events; }, - _close: function () { - if (this._map) { - this._map.closeTooltip(this); - } - }, - _initLayout: function () { var prefix = 'leaflet-tooltip', className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide'); @@ -230,11 +224,8 @@ Map.include({ // @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this // Creates a tooltip with the specified content and options and open it. openTooltip: function (tooltip, latlng, options) { - tooltip = this._initOverlay(Tooltip, tooltip, latlng, options); - - if (!this.hasLayer(tooltip)) { - this.addLayer(tooltip); - } + this._initOverlay(Tooltip, tooltip, latlng, options) + .openOn(this); return this; }, @@ -242,7 +233,8 @@ Map.include({ // @method closeTooltip(tooltip: Tooltip): this // Closes the tooltip given as parameter. closeTooltip: function (tooltip) { - return this.removeLayer(tooltip); + tooltip.close(); + return this; } }); @@ -320,9 +312,8 @@ Layer.include({ openTooltip: function (latlng) { if (this._tooltip && this._tooltip._prepareOpen(latlng)) { // open the tooltip on the map - this._map.openTooltip(this._tooltip, latlng); + this._tooltip.openOn(this._map); } - return this; }, @@ -330,9 +321,8 @@ Layer.include({ // Closes the tooltip bound to this layer if it is open. closeTooltip: function () { if (this._tooltip) { - this._tooltip._close(); + return this._tooltip.close(); } - return this; }, // @method toggleTooltip(): this @@ -340,7 +330,7 @@ Layer.include({ toggleTooltip: function () { if (this._tooltip) { if (this._tooltip._map) { - this.closeTooltip(); + this._tooltip.close(); } else { this.openTooltip(); } From d9238e264d1f73e35ff244ad1072ea4a58fdf22b Mon Sep 17 00:00:00 2001 From: johndoe Date: Wed, 31 Mar 2021 15:28:45 +0300 Subject: [PATCH 3/3] DivOverlay: new public method `toggle` Refactor Layer\ togglePopup/Tooltip: use common method DivOverlay\toggle Popup: do not clear map._popup on close as it's redundant --- src/layer/DivOverlay.js | 21 +++++++++++++++++++++ src/layer/Popup.js | 10 +--------- src/layer/Tooltip.js | 6 +----- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/layer/DivOverlay.js b/src/layer/DivOverlay.js index 8f4e291748a..f60d04da832 100644 --- a/src/layer/DivOverlay.js +++ b/src/layer/DivOverlay.js @@ -60,6 +60,27 @@ export var DivOverlay = Layer.extend({ return this; }, + // @method toggle(layer?: Layer): this + // Opens or closes the overlay bound to layer depending on its current state. + // Argument may be omitted only for overlay bound to layer. + // Alternative to `layer.togglePopup()`/`.toggleTooltip()`. + toggle: function (layer) { + if (this._map) { + this.close(); + } else { + if (arguments.length) { + this._source = layer; + } else { + layer = this._source; + } + this._prepareOpen(); + + // open the overlay on the map + this.openOn(layer._map); + } + return this; + }, + onAdd: function (map) { this._zoomAnimated = map._zoomAnimated; diff --git a/src/layer/Popup.js b/src/layer/Popup.js index 8cb931c3933..ebe3c77d5af 100644 --- a/src/layer/Popup.js +++ b/src/layer/Popup.js @@ -148,10 +148,6 @@ export var Popup = DivOverlay.extend({ onRemove: function (map) { DivOverlay.prototype.onRemove.call(this, map); - if (this === map._popup) { - map._popup = null; - } - // @namespace Map // @section Popup events // @event popupclose: PopupEvent @@ -418,11 +414,7 @@ Layer.include({ // Opens or closes the popup bound to this layer depending on its current state. togglePopup: function () { if (this._popup) { - if (this._popup._map) { - this._popup.close(); - } else { - this.openPopup(); - } + this._popup.toggle(this); } return this; }, diff --git a/src/layer/Tooltip.js b/src/layer/Tooltip.js index 2b09387565e..ac8d3e1db78 100644 --- a/src/layer/Tooltip.js +++ b/src/layer/Tooltip.js @@ -329,11 +329,7 @@ Layer.include({ // Opens or closes the tooltip bound to this layer depending on its current state. toggleTooltip: function () { if (this._tooltip) { - if (this._tooltip._map) { - this._tooltip.close(); - } else { - this.openTooltip(); - } + this._tooltip.toggle(this); } return this; },