diff --git a/Utils.ts b/Utils.ts index 9b41a260d..5fc4c8ec8 100644 --- a/Utils.ts +++ b/Utils.ts @@ -1,4 +1,5 @@ import * as colors from "./assets/colors.json" +import {Util} from "leaflet"; export class Utils { @@ -10,8 +11,7 @@ export class Utils { public static runningFromConsole = false; public static readonly assets_path = "./assets/svg/"; - - + private static knownKeys = ["addExtraTags", "and", "calculatedTags", "changesetmessage", "clustering", "color", "condition", "customCss", "dashArray", "defaultBackgroundId", "description", "descriptionTail", "doNotDownload", "enableAddNewPoints", "enableBackgroundLayerSelection", "enableGeolocation", "enableLayers", "enableMoreQuests", "enableSearch", "enableShareScreen", "enableUserBadge", "freeform", "hideFromOverview", "hideInAnswer", "icon", "iconOverlays", "iconSize", "id", "if", "ifnot", "isShown", "key", "language", "layers", "lockLocation", "maintainer", "mappings", "maxzoom", "maxZoom", "minNeededElements", "minzoom", "multiAnswer", "name", "or", "osmTags", "passAllFeatures", "presets", "question", "render", "roaming", "roamingRenderings", "rotation", "shortDescription", "socialImage", "source", "startLat", "startLon", "startZoom", "tagRenderings", "tags", "then", "title", "titleIcons", "type", "version", "wayHandling", "widenFactor", "width"] private static extraKeys = ["nl", "en", "fr", "de", "pt", "es", "name", "phone", "email", "amenity", "leisure", "highway", "building", "yes", "no", "true", "false"] @@ -162,14 +162,39 @@ export class Utils { console.log("Added custom layout ", location) } + /** + * Copies all key-value pairs of the source into the target. + * If the key starts with a '+', the values of the list will be appended to the target instead of overwritten + * @param source + * @param target + * @constructor + */ static Merge(source: any, target: any) { for (const key in source) { if (!source.hasOwnProperty(key)) { continue } + if (key.startsWith("+") || key.endsWith("+")) { + const trimmedKey = key.replace("+", ""); + const sourceV = source[key]; + const targetV = (target[trimmedKey] ?? []) + + let newList: any[]; + if (key.startsWith("+")) { + newList = sourceV.concat(targetV) + } else { + newList = targetV.concat(sourceV) + } + + target[trimmedKey] = newList; + continue; + } + const sourceV = source[key]; const targetV = target[key] - if (typeof sourceV === "object") { + if (sourceV?.length !== undefined && targetV?.length !== undefined && key.startsWith("+")) { + target[key] = targetV.concat(sourceV) + } else if (typeof sourceV === "object") { if (targetV === undefined) { target[key] = sourceV; } else { @@ -330,7 +355,6 @@ export class Utils { } - private static tile2long(x, z) { return (x / Math.pow(2, z) * 360 - 180); } diff --git a/test/Utils.spec.ts b/test/Utils.spec.ts index b6f601e60..c94494eba 100644 --- a/test/Utils.spec.ts +++ b/test/Utils.spec.ts @@ -77,6 +77,33 @@ export default class UtilsSpec extends T { console.log("Restored version has ", restored.length, "chars") equal(str, restored) + }], + ["TestMerge", () => { + + const source = { + abc: "def", + foo: "bar", + list0: ["overwritten"], + "list1+": ["appended"] + } + const target = { + "xyz": "omega", + "list0": ["should-be-gone"], + "list1": ["should-be-kept"], + "list2": ["should-be-untouched"] + } + const result = Utils.Merge(source, target) + + equal(result.abc, "def") + equal(result.foo, "bar") + equal(result.xyz, "omega") + equal(result.list0.length, 1) + equal(result.list0[0], "overwritten") + equal(result.list1.length, 2) + equal(result.list1[0], "should-be-kept") + equal(result.list1[1], "appended") + equal(result.list2.length, 1) + equal(result.list2[0], "should-be-untouched") }] ]); }