diff --git a/src/Models/ThemeConfig/Conversion/PrepareLayer.ts b/src/Models/ThemeConfig/Conversion/PrepareLayer.ts index bf3028d65..45b7d8ebe 100644 --- a/src/Models/ThemeConfig/Conversion/PrepareLayer.ts +++ b/src/Models/ThemeConfig/Conversion/PrepareLayer.ts @@ -1,18 +1,6 @@ -import { - Concat, - DesugaringContext, - DesugaringStep, - Each, - FirstOf, - Fuse, - On, - SetDefault, -} from "./Conversion" +import { Concat, DesugaringContext, DesugaringStep, Each, FirstOf, Fuse, On, SetDefault } from "./Conversion" import { LayerConfigJson } from "../Json/LayerConfigJson" -import { - MinimalTagRenderingConfigJson, - TagRenderingConfigJson, -} from "../Json/TagRenderingConfigJson" +import { MinimalTagRenderingConfigJson, TagRenderingConfigJson } from "../Json/TagRenderingConfigJson" import { Utils } from "../../../Utils" import RewritableConfigJson from "../Json/RewritableConfigJson" import SpecialVisualizations from "../../../UI/SpecialVisualizations" @@ -36,7 +24,7 @@ import { ExpandTagRendering } from "./ExpandTagRendering" class AddFiltersFromTagRenderings extends DesugaringStep { constructor() { super( - 'Inspects all the tagRenderings. If some tagRenderings have the `filter` attribute set, introduce those filters. This step might introduce shorthand filter names, thus \'ExpandFilter\' should be run afterwards. Can be disabled with "#filter":"no-auto"', + "Inspects all the tagRenderings. If some tagRenderings have the `filter` attribute set, introduce those filters. This step might introduce shorthand filter names, thus 'ExpandFilter' should be run afterwards. Can be disabled with \"#filter\":\"no-auto\"", ["filter"], "AddFiltersFromTagRenderings" ) @@ -139,7 +127,7 @@ class DetectInline extends DesugaringStep { if (json.freeform.inline === true) { context.err( "'inline' is set, but the rendering contains a special visualisation...\n " + - spec[key] + spec[key] ) } json = JSON.parse(JSON.stringify(json)) @@ -238,20 +226,20 @@ export class AddQuestionBox extends DesugaringStep { if (blacklisted?.length > 0 && used?.length > 0) { context.err( "The {questions()}-special rendering only supports either a blacklist OR a whitelist, but not both." + - "\n Whitelisted: " + - used.join(", ") + - "\n Blacklisted: " + - blacklisted.join(", ") + "\n Whitelisted: " + + used.join(", ") + + "\n Blacklisted: " + + blacklisted.join(", ") ) } for (const usedLabel of used) { if (!allLabels.has(usedLabel)) { context.err( "This layers specifies a special question element for label `" + - usedLabel + - "`, but this label doesn't exist.\n" + - " Available labels are " + - Array.from(allLabels).join(", ") + usedLabel + + "`, but this label doesn't exist.\n" + + " Available labels are " + + Array.from(allLabels).join(", ") ) } seen.add(usedLabel) @@ -265,8 +253,8 @@ export class AddQuestionBox extends DesugaringStep { const question: QuestionableTagRenderingConfigJson = { id: "leftover-questions", render: { - "*": `{questions( ,${Array.from(seen).join(";")})}`, - }, + "*": `{questions( ,${Array.from(seen).join(";")})}` + } } json.tagRenderings.push(question) } @@ -348,13 +336,13 @@ export class AddEditingElements extends DesugaringStep { if (json.allowMove && !usedSpecialFunctions.has("move_button")) { json.tagRenderings.push({ id: "move-button", - render: { "*": "{move_button()}" }, + render: { "*": "{move_button()}" } }) } if (json.deletion && !usedSpecialFunctions.has("delete_button")) { json.tagRenderings.push({ id: "delete-button", - render: { "*": "{delete_button()}" }, + render: { "*": "{delete_button()}" } }) } @@ -369,9 +357,9 @@ export class AddEditingElements extends DesugaringStep { or: [ "__featureSwitchIsDebugging=true", "mapcomplete-show_tags=full", - "mapcomplete-show_debug=yes", - ], - }, + "mapcomplete-show_debug=yes" + ] + } } json.tagRenderings?.push(trc) } @@ -479,10 +467,10 @@ export class RewriteSpecial extends DesugaringStep { private static convertIfNeeded( input: | (object & { - special: { - type: string - } - }) + special: { + type: string + } + }) | any, context: ConversionContext ): any { @@ -580,7 +568,7 @@ export class RewriteSpecial extends DesugaringStep { .map((nm) => RewriteSpecial.escapeStr(special[nm] ?? "", context)) .join(",") return { - "*": `{${type}(${args})${clss}}`, + "*": `{${type}(${args})${clss}}` } } @@ -678,11 +666,50 @@ class ExpandIconBadges extends DesugaringStep { }[] = [] for (let i = 0; i < badgesJson.length; i++) { - const iconBadge: { + const iconBadge: string | ({ if: TagConfigJson then: string | MinimalTagRenderingConfigJson - } = badgesJson[i] - const expanded = this._expand.convert( + }) = badgesJson[i] + + + if (typeof iconBadge === "string") { + + const expanded: QuestionableTagRenderingConfigJson[] = this._expand.convert( + iconBadge, + context.enters("iconBadges", i) + ) + + for (const tr of expanded) { + const condition = tr.condition + for (const trElement of tr.mappings) { + const showIf = TagUtils.optimzeJson({ + and: Utils.NoNull([condition, + { + or: Utils.NoNull([ + trElement.alsoShowIf, trElement.if + ]) + } + ]) + }) + if (showIf === true) { + context.warn("Dropping iconBadge that would be _always_ shown: " + (trElement.icon ?? trElement.then)) + continue + } + if (showIf === false) { + continue + } + iconBadges.push({ + if: showIf, + then: trElement.icon ?? trElement.then + }) + } + + + } + continue + } + + const expanded: QuestionableTagRenderingConfigJson[] = this._expand.convert( iconBadge.then, context.enters("iconBadges", i) ) @@ -694,7 +721,7 @@ class ExpandIconBadges extends DesugaringStep { iconBadges.push( ...expanded.map((resolved) => ({ if: iconBadge.if, - then: resolved, + then: resolved })) ) } @@ -707,7 +734,7 @@ class PreparePointRendering extends Fuse { constructor(state: DesugaringContext, layer: LayerConfigJson) { super( "Prepares point renderings by expanding 'icon' and 'iconBadges'." + - " A tagRendering from the host tagRenderings will be substituted in", + " A tagRendering from the host tagRenderings will be substituted in", new On( "marker", new Each( @@ -834,7 +861,7 @@ export class AddRatingBadge extends DesugaringStep { const specialVis: Exclude[] = < Exclude[] - >ValidationUtils.getAllSpecialVisualisations(json.tagRenderings).filter( + >ValidationUtils.getAllSpecialVisualisations(json.tagRenderings).filter( (rs) => typeof rs !== "string" ) const funcs = new Set(specialVis.map((rs) => rs.func.funcName)) @@ -870,7 +897,7 @@ export class AutoTitleIcon extends DesugaringStep { } return { id: "title_icon_auto_" + tr.id, - mappings, + mappings } } @@ -915,8 +942,8 @@ export class AutoTitleIcon extends DesugaringStep { .enters("titleIcons", i) .warn( "TagRendering with id " + - trId + - " does not have any icons, not generating an icon for this" + trId + + " does not have any icons, not generating an icon for this" ) continue } @@ -979,7 +1006,7 @@ export class PrepareLayer extends Fuse { (layer) => new Concat( new ExpandTagRendering(state, layer, { - addToContext: options?.addTagRenderingsToContext ?? false, + addToContext: options?.addTagRenderingsToContext ?? false }) ) ), diff --git a/src/Models/ThemeConfig/Json/PointRenderingConfigJson.ts b/src/Models/ThemeConfig/Json/PointRenderingConfigJson.ts index 947a4d1c2..723aac46e 100644 --- a/src/Models/ThemeConfig/Json/PointRenderingConfigJson.ts +++ b/src/Models/ThemeConfig/Json/PointRenderingConfigJson.ts @@ -70,16 +70,18 @@ export default interface PointRenderingConfigJson { * They will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout. * * Note: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle + * Alternatively, this can reuse a _tagRendering_ from another layer, e.g. one of the 'icons'-tagrenderings. + * See ExpandIconBadges on how this is handled * group: hidden */ - iconBadges?: { + iconBadges?: (string | { if: TagConfigJson /** * Badge to show * Type: icon */ then: string | MinimalTagRenderingConfigJson - }[] + })[] /** * question: What size should the marker be on the map?