From d04226e3ec253714337d6475984e96831f671b1a Mon Sep 17 00:00:00 2001 From: James Lyne Date: Wed, 28 Jul 2021 17:49:38 +0100 Subject: [PATCH] Refactor popup handling - Merge label and popupContent properties for vector layers, as only one is ever used - Move common vector methods to separate file and remove duplicates - Rename isHTML properties to be clearer --- src/index.d.ts | 5 ++-- src/providers/DynmapMapProvider.ts | 21 +++++++------- src/util/areas.ts | 36 +++--------------------- src/util/circles.ts | 23 +++------------ src/util/lines.ts | 23 +++------------ src/util/markers.ts | 11 ++------ src/util/paths.ts | 45 ++++++++++++++++++++++++++++++ 7 files changed, 72 insertions(+), 92 deletions(-) create mode 100644 src/util/paths.ts diff --git a/src/index.d.ts b/src/index.d.ts index a1347d0..8edcc45 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -196,7 +196,7 @@ interface LiveAtlasMarker { dimensions: PointTuple; icon: string; label: string; - isHTML: boolean; + isLabelHTML: boolean; location: Coordinate; minZoom?: number; maxZoom?: number; @@ -205,11 +205,10 @@ interface LiveAtlasMarker { interface LiveAtlasPath { style: PathOptions; - label: string; - isHTML: boolean; minZoom?: number; maxZoom?: number; popupContent?: string; + isPopupHTML: boolean; } interface LiveAtlasArea extends LiveAtlasPath { diff --git a/src/providers/DynmapMapProvider.ts b/src/providers/DynmapMapProvider.ts index 7fd7076..bc4e8ba 100644 --- a/src/providers/DynmapMapProvider.ts +++ b/src/providers/DynmapMapProvider.ts @@ -280,6 +280,7 @@ export default class DynmapMapProvider extends MapProvider { private static buildMarker(marker: any): LiveAtlasMarker { return { label: marker.label || '', + isLabelHTML: marker.markup || false, location: { x: marker.x || 0, y: marker.y || 0, @@ -287,7 +288,6 @@ export default class DynmapMapProvider extends MapProvider { }, dimensions: marker.dim ? marker.dim.split('x') : [16, 16], icon: marker.icon || "default", - isHTML: marker.markup || false, minZoom: typeof marker.minzoom !== 'undefined' && marker.minzoom > -1 ? marker.minzoom : undefined, maxZoom: typeof marker.maxzoom !== 'undefined' && marker.maxzoom > -1 ? marker.maxzoom : undefined, popupContent: marker.desc || undefined, @@ -323,12 +323,12 @@ export default class DynmapMapProvider extends MapProvider { fillOpacity: area.fillopacity || 0, }, outline: !opacity, - label: area.label || '', - isHTML: area.markup || false, points: getPoints(x, y, z, !opacity), minZoom: typeof area.minzoom !== 'undefined' && area.minzoom > -1 ? area.minzoom : undefined, maxZoom: typeof area.maxzoom !== 'undefined' && area.maxzoom > -1 ? area.maxzoom : undefined, - popupContent: area.desc || undefined, + + isPopupHTML: area.desc ? true : area.markup || false, + popupContent: area.desc || area.label || undefined, }); } @@ -353,12 +353,12 @@ export default class DynmapMapProvider extends MapProvider { opacity: line.opacity || 1, weight: line.weight || 1, }, - label: line.label || '', - isHTML: line.markup || false, points: getLinePoints(line.x || [0, 0], line.y || [0, 0], line.z || [0, 0]), minZoom: typeof line.minzoom !== 'undefined' && line.minzoom > -1 ? line.minzoom : undefined, maxZoom: typeof line.maxzoom !== 'undefined' && line.maxzoom > -1 ? line.maxzoom : undefined, - popupContent: line.desc || undefined, + + isPopupHTML: line.desc ? true : line.markup || false, + popupContent: line.desc || line.label || undefined, }); } @@ -391,12 +391,11 @@ export default class DynmapMapProvider extends MapProvider { opacity: circle.opacity || 1, weight: circle.weight || 1, }, - label: circle.label || '', - isHTML: circle.markup || false, - minZoom: typeof circle.minzoom !== 'undefined' && circle.minzoom > -1 ? circle.minzoom : undefined, maxZoom: typeof circle.maxzoom !== 'undefined' && circle.maxzoom > -1 ? circle.maxzoom : undefined, - popupContent: circle.desc || undefined, + + isPopupHTML: circle.desc ? true : circle.markup || false, + popupContent: circle.desc || circle.label || undefined, }); } diff --git a/src/util/areas.ts b/src/util/areas.ts index 53e4ce8..991b41c 100644 --- a/src/util/areas.ts +++ b/src/util/areas.ts @@ -21,14 +21,15 @@ import {LatLngExpression} from "leaflet"; import LiveAtlasPolyline from "@/leaflet/vector/LiveAtlasPolyline"; import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon"; import {Coordinate, LiveAtlasArea} from "@/index"; +import {arePointsEqual, createPopup, isStyleEqual} from "@/util/paths"; export const createArea = (options: LiveAtlasArea, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => { const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0), points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[] | LatLngExpression[][], area = outline ? new LiveAtlasPolyline(points, options) : new LiveAtlasPolygon(points, options); - if (options.label) { - area.bindPopup(() => createPopup(options)); + if (options.popupContent) { + area.bindPopup(() => createPopup(options, 'AreaPopup')); } return area; @@ -57,7 +58,7 @@ export const updateArea = (area: LiveAtlasPolyline | LiveAtlasPolygon | undefine area.closePopup(); area.unbindPopup(); - area.bindPopup(() => createPopup(options)); + area.bindPopup(() => createPopup(options, 'AreaPopup')); if(dirty) { area.redraw(); @@ -66,35 +67,6 @@ export const updateArea = (area: LiveAtlasPolyline | LiveAtlasPolygon | undefine return area; }; -const arePointsEqual = (oldPoints: any, newPoints: any) => { - return JSON.stringify(oldPoints) === JSON.stringify(newPoints); -} - -const isStyleEqual = (oldStyle: any, newStyle: any) => { - return oldStyle && newStyle - && (oldStyle.color === newStyle.color) - && (oldStyle.weight === newStyle.weight) - && (oldStyle.opacity === newStyle.opacity) - && (oldStyle.fillColor === newStyle.fillColor) - && (oldStyle.fillOpacity === newStyle.fillOpacity) -} - -export const createPopup = (options: LiveAtlasArea): HTMLElement => { - const popup = document.createElement('span'); - - if (options.popupContent) { - popup.classList.add('AreaPopup'); - popup.insertAdjacentHTML('afterbegin', options.popupContent); - } else if (options.isHTML) { - popup.classList.add('AreaPopup'); - popup.insertAdjacentHTML('afterbegin', options.label); - } else { - popup.textContent = options.label; - } - - return popup; -}; - const projectPointsMapCallback = function(this: Function, point: Coordinate | Coordinate[] | Coordinate[][]): LatLngExpression | LatLngExpression[] { if(Array.isArray(point)) { return point.map(projectPointsMapCallback, this) as LatLngExpression[]; diff --git a/src/util/circles.ts b/src/util/circles.ts index 51f27e4..fe16aa1 100644 --- a/src/util/circles.ts +++ b/src/util/circles.ts @@ -21,14 +21,15 @@ import {LatLngExpression} from "leaflet"; import LiveAtlasPolyline from "@/leaflet/vector/LiveAtlasPolyline"; import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon"; import {LiveAtlasCircle} from "@/index"; +import {createPopup} from "@/util/paths"; export const createCircle = (options: LiveAtlasCircle, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => { const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0), points = getCirclePoints(options, converter, outline), circle = outline ? new LiveAtlasPolyline(points, options) : new LiveAtlasPolygon(points, options); - if(options.label) { - circle.bindPopup(() => createPopup(options)); + if(options.popupContent) { + circle.bindPopup(() => createPopup(options, 'CirclePopup')); } return circle; @@ -43,7 +44,7 @@ export const updateCircle = (circle: LiveAtlasPolyline | LiveAtlasPolygon | unde circle.closePopup(); circle.unbindPopup(); - circle.bindPopup(() => createPopup(options)); + circle.bindPopup(() => createPopup(options, 'CirclePopup')); circle.setStyle(options.style); circle.setLatLngs(getCirclePoints(options, converter, outline)); circle.redraw(); @@ -51,22 +52,6 @@ export const updateCircle = (circle: LiveAtlasPolyline | LiveAtlasPolygon | unde return circle; } -export const createPopup = (options: LiveAtlasCircle) => { - const popup = document.createElement('span'); - - if (options.popupContent) { - popup.classList.add('CirclePopup'); - popup.insertAdjacentHTML('afterbegin', options.popupContent); - } else if (options.isHTML) { - popup.classList.add('CirclePopup'); - popup.insertAdjacentHTML('afterbegin', options.label); - } else { - popup.textContent = options.label; - } - - return popup; -} - export const getCirclePoints = (options: LiveAtlasCircle, converter: Function, outline: boolean): LatLngExpression[] => { const points = []; diff --git a/src/util/lines.ts b/src/util/lines.ts index cd1ad02..aff19ef 100644 --- a/src/util/lines.ts +++ b/src/util/lines.ts @@ -20,13 +20,14 @@ import LiveAtlasPolyline from "@/leaflet/vector/LiveAtlasPolyline"; import {Coordinate, LiveAtlasLine} from "@/index"; import {LatLngExpression} from "leaflet"; +import {createPopup} from "@/util/paths"; export const createLine = (options: LiveAtlasLine, converter: Function): LiveAtlasPolyline => { const points = options.points.map(projectPointsMapCallback, converter), line = new LiveAtlasPolyline(points, options); - if(options.label) { - line.bindPopup(() => createPopup(options)); + if(options.popupContent) { + line.bindPopup(() => createPopup(options, 'LinePopup')); } return line; @@ -39,7 +40,7 @@ export const updateLine = (line: LiveAtlasPolyline | undefined, options: LiveAtl line.closePopup(); line.unbindPopup(); - line.bindPopup(() => createPopup(options)); + line.bindPopup(() => createPopup(options, 'LinePopup')); line.setStyle(options.style); line.setLatLngs(options.points.map(projectPointsMapCallback, converter)); line.redraw(); @@ -56,22 +57,6 @@ const projectPointsMapCallback = function(point: Coordinate): LatLngExpression { } }; -export const createPopup = (options: LiveAtlasLine) => { - const popup = document.createElement('span'); - - if (options.popupContent) { - popup.classList.add('LinePopup'); - popup.insertAdjacentHTML('afterbegin', options.popupContent); - } else if (options.isHTML) { - popup.classList.add('LinePopup'); - popup.insertAdjacentHTML('afterbegin', options.label); - } else { - popup.textContent = options.label; - } - - return popup; -} - export const getLinePoints = (x: number[], y: number[], z: number[]): Coordinate[] => { const points = []; diff --git a/src/util/markers.ts b/src/util/markers.ts index 553966a..761908a 100644 --- a/src/util/markers.ts +++ b/src/util/markers.ts @@ -28,7 +28,7 @@ export const createMarker = (options: LiveAtlasMarker, converter: Function): Mar icon: options.icon, label: options.label, iconSize: options.dimensions, - isHtml: options.isHTML, + isHtml: options.isLabelHTML, }), maxZoom: options.maxZoom, minZoom: options.minZoom, @@ -65,7 +65,7 @@ export const updateMarker = (marker: Marker | undefined, options: LiveAtlasMarke icon: options.icon, label: options.label, iconSize: options.dimensions, - isHtml: options.isHTML, + isHtml: options.isLabelHTML, }); } } @@ -80,17 +80,12 @@ export const updateMarker = (marker: Marker | undefined, options: LiveAtlasMarke return marker; }; -export const createPopup = (options: LiveAtlasMarker) => { +const createPopup = (options: LiveAtlasMarker) => { const popup = document.createElement('span'); if (options.popupContent) { popup.classList.add('MarkerPopup'); popup.insertAdjacentHTML('afterbegin', options.popupContent); - } else if (options.isHTML) { - popup.classList.add('MarkerPopup'); - popup.insertAdjacentHTML('afterbegin', options.label); - } else { - popup.textContent = options.label; } return popup; diff --git a/src/util/paths.ts b/src/util/paths.ts new file mode 100644 index 0000000..eb63e65 --- /dev/null +++ b/src/util/paths.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2021 James Lyne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {LatLngExpression, PathOptions} from "leaflet"; +import {LiveAtlasPath} from "@/index"; + +export const arePointsEqual = (oldPoints: LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][], + newPoints: LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]) => { + return JSON.stringify(oldPoints) === JSON.stringify(newPoints); +} + +export const isStyleEqual = (oldStyle: PathOptions, newStyle: PathOptions) => { + return oldStyle && newStyle + && (oldStyle.color === newStyle.color) + && (oldStyle.weight === newStyle.weight) + && (oldStyle.opacity === newStyle.opacity) + && (oldStyle.fillColor === newStyle.fillColor) + && (oldStyle.fillOpacity === newStyle.fillOpacity) +} + +export const createPopup = (options: LiveAtlasPath, className: string): HTMLElement => { + const popup = document.createElement('span'); + + if(options.isPopupHTML) { + popup.classList.add(className); + popup.insertAdjacentHTML('afterbegin', options.popupContent as string); + } else { + popup.textContent = options.popupContent as string; + } + + return popup; +};