From 9bff7be222aa27040fcb2f795103a1824239453b Mon Sep 17 00:00:00 2001 From: German Zargaryan <2526045+germanz@users.noreply.github.com> Date: Thu, 1 Jul 2021 17:03:35 +0200 Subject: [PATCH] MINOR: Fix theme extends to respect multiple image textures (#2230) Signed-off-by: German Zargaryan <2526045+germanz@users.noreply.github.com> --- @here/harp-mapview/lib/ThemeLoader.ts | 38 ++++++++++++- @here/harp-mapview/test/ThemeLoaderTest.ts | 65 ++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/@here/harp-mapview/lib/ThemeLoader.ts b/@here/harp-mapview/lib/ThemeLoader.ts index b0948844e3..4c0307f50d 100644 --- a/@here/harp-mapview/lib/ThemeLoader.ts +++ b/@here/harp-mapview/lib/ThemeLoader.ts @@ -10,6 +10,7 @@ import { isJsonExpr } from "@here/harp-datasource-protocol"; import { Definitions, FlatTheme, + ImageTexture, isJsonExprReference, Style, Styles, @@ -524,7 +525,42 @@ export class ThemeLoader { } else if (theme.styles) { styles = { ...theme.styles }; } - return { ...baseTheme, ...theme, definitions, styles }; + + return { + ...baseTheme, + ...theme, + // Due to nested structure of the images/textures it needs a + // deep merge with a duplicate exclusion. + ...ThemeLoader.mergeImageTextures(theme, baseTheme), + definitions, + styles + }; + } + + private static mergeImageTextures( + theme: Theme, + baseTheme: Theme + ): Pick { + const images = { ...baseTheme.images, ...theme.images }; + let imageTextures: ImageTexture[] = []; + + if (!baseTheme.imageTextures && theme.imageTextures) { + imageTextures = theme.imageTextures; + } else if (baseTheme.imageTextures && !theme.imageTextures) { + imageTextures = baseTheme.imageTextures; + } else if (baseTheme.imageTextures && theme.imageTextures) { + imageTextures = theme.imageTextures.slice(); + baseTheme.imageTextures.forEach(val => { + if (!imageTextures.find(({ name }) => name === val.name)) { + imageTextures.push(val); + } + }); + } + + return { + images, + imageTextures + }; } private static convertFlatTheme(theme: Theme | FlatTheme): Theme { diff --git a/@here/harp-mapview/test/ThemeLoaderTest.ts b/@here/harp-mapview/test/ThemeLoaderTest.ts index 1324e43ef5..9c96c89499 100644 --- a/@here/harp-mapview/test/ThemeLoaderTest.ts +++ b/@here/harp-mapview/test/ThemeLoaderTest.ts @@ -306,6 +306,71 @@ describe("ThemeLoader", function () { assert.deepEqual(result.definitions!.roadColor, { type: "color", value: "#fff" }); assert.deepEqual(result.definitions!.waterColor, { type: "color", value: "#0f0" }); }); + it("supports multiple inheritance with textures", async function () { + const inheritedTheme: Theme = { + extends: [ + { + images: { + foo: { + url: "icons://maki_icons.png", + preload: true + }, + baz: { + url: "icons://maki_icons.png", + preload: true + } + }, + imageTextures: [ + { + name: "foo", + image: "foo" + }, + { + name: "baz", + image: "baz" + } + ] + }, + { + images: { + bar: { + url: "icons://maki_icons.png", + preload: true + }, + baz: { + url: "icons://override.png", + atlas: "icons://icons/maki_icons.json", + preload: true + } + }, + imageTextures: [ + { + name: "bar", + image: "bar" + }, + { + name: "baz", + image: "baz" + } + ] + } + ] + }; + + const result = await ThemeLoader.load(inheritedTheme); + assert.exists(result.images?.foo); + assert.exists(result.images?.bar); + assert.exists(result.images?.baz); + + assert.equal(result.images?.baz.url, "icons://override.png"); + assert.exists(result.images?.baz.atlas); + + assert.deepEqual(result.imageTextures?.map(imageTexture => imageTexture.name).sort(), [ + "bar", + "baz", + "foo" + ]); + }); }); describe("#load support for inheritance and optional reference resolving", function () {