From a0b7a322231462c520ddb88e0bde5e6328f6c140 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 16 May 2025 15:48:55 +0200 Subject: [PATCH] Refactoring: change order of parameters and remove parameter for Conversion.ts --- scripts/fixQuestionHint.ts | 27 +++---- scripts/generateLayerOverview.ts | 17 ++--- .../Conversion/AddContextToTranslations.ts | 3 +- .../AddPrefixToTagRenderingConfig.ts | 12 +-- .../ThemeConfig/Conversion/Conversion.ts | 56 +++++--------- .../Conversion/DetectMappingsWithImages.ts | 3 +- .../ThemeConfig/Conversion/ExpandFilter.ts | 6 +- .../ThemeConfig/Conversion/ExpandRewrite.ts | 2 +- .../Conversion/ExpandTagRendering.ts | 6 +- .../ThemeConfig/Conversion/FixImages.ts | 2 +- .../Conversion/LegacyJsonConvert.ts | 5 +- .../Conversion/MiscTagRenderingChecks.ts | 7 +- .../ThemeConfig/Conversion/PrepareLayer.ts | 76 +++++++++---------- .../ThemeConfig/Conversion/PrepareTheme.ts | 37 +++------ .../Conversion/PrevalidateLayer.ts | 10 +-- .../ThemeConfig/Conversion/ValidateTheme.ts | 2 +- .../ThemeConfig/Conversion/Validation.ts | 51 +++++-------- .../ThemeConfig/Json/LayerConfigJson.ts | 2 +- .../QuestionableTagRenderingConfigJson.ts | 23 ++++++ src/UI/Studio/EditLayerState.ts | 13 +--- 20 files changed, 147 insertions(+), 213 deletions(-) diff --git a/scripts/fixQuestionHint.ts b/scripts/fixQuestionHint.ts index 1406d2b32..bd868f109 100644 --- a/scripts/fixQuestionHint.ts +++ b/scripts/fixQuestionHint.ts @@ -5,32 +5,26 @@ import { QuestionableTagRenderingConfigJson } from "../src/Models/ThemeConfig/Js import * as fakedom from "fake-dom" import Script from "./Script" import { FixedUiElement } from "../src/UI/Base/FixedUiElement" +import { ConversionContext } from "../src/Models/ThemeConfig/Conversion/ConversionContext" class ExtractQuestionHint extends DesugaringStep { constructor() { super( + "ExtractQuestionHint", "Tries to extract a 'questionHint' from the question", - ["question", "questionhint"], - "ExtractQuestionHint" ) } convert( - json: QuestionableTagRenderingConfigJson, - context: string - ): { - result: QuestionableTagRenderingConfigJson - errors?: string[] - warnings?: string[] - information?: string[] - } { + json: QuestionableTagRenderingConfigJson + ): QuestionableTagRenderingConfigJson { json = { ...json } if (json.question === undefined || json.questionHint !== undefined) { - return { result: json } + return json } if (typeof json.question === "string") { - return { result: json } + return json } const hint: Record = {} @@ -64,12 +58,11 @@ class ExtractQuestionHint extends DesugaringSteptagRendering, + ConversionContext.construct([], [ "While automatically extracting questionHints of " + filepath + ]) ) } } diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index 8ecc391c8..a1492af39 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -9,16 +9,12 @@ import { DoesImageExist, PrevalidateTheme, ValidateLayer, - ValidateThemeEnsemble, + ValidateThemeEnsemble } from "../src/Models/ThemeConfig/Conversion/Validation" import { Translation } from "../src/UI/i18n/Translation" import { PrepareLayer } from "../src/Models/ThemeConfig/Conversion/PrepareLayer" import { PrepareTheme } from "../src/Models/ThemeConfig/Conversion/PrepareTheme" -import { - Conversion, - DesugaringContext, - DesugaringStep, -} from "../src/Models/ThemeConfig/Conversion/Conversion" +import { Conversion, DesugaringContext, DesugaringStep } from "../src/Models/ThemeConfig/Conversion/Conversion" import { Utils } from "../src/Utils" import Script from "./Script" import { AllSharedLayers } from "../src/Customizations/AllSharedLayers" @@ -35,10 +31,7 @@ import { Translatable } from "../src/Models/ThemeConfig/Json/Translatable" import { ValidateThemeAndLayers } from "../src/Models/ThemeConfig/Conversion/ValidateThemeAndLayers" import { ExtractImages } from "../src/Models/ThemeConfig/Conversion/FixImages" import { TagRenderingConfigJson } from "../src/Models/ThemeConfig/Json/TagRenderingConfigJson" -import { - LayerConfigDependencyGraph, - LevelInfo, -} from "../src/Models/ThemeConfig/LayerConfigDependencyGraph" +import { LayerConfigDependencyGraph, LevelInfo } from "../src/Models/ThemeConfig/LayerConfigDependencyGraph" // This scripts scans 'src/assets/layers/*.json' for layer definition files and 'src/assets/themes/*.json' for theme definition files. // It spits out an overview of those to be used to load them @@ -54,7 +47,7 @@ class ParseLayer extends Conversion< private readonly _doesImageExist: DoesImageExist constructor(prepareLayer: PrepareLayer, doesImageExist: DoesImageExist) { - super("Parsed a layer from file, validates it", [], "ParseLayer") + super("ParseLayer", "Parsed a layer from file, validates it", []) this._prepareLayer = prepareLayer this._doesImageExist = doesImageExist } @@ -158,7 +151,7 @@ class LayerBuilder extends Conversion> { states: Map, sharedTagRenderings: QuestionableTagRenderingConfigJson[] ) { - super("Builds all the layers, writes them to file", [], "LayerBuilder") + super("LayerBuilder", "Builds all the layers, writes them to file", []) this._levels = levels this._dependencies = dependencies this._states = states diff --git a/src/Models/ThemeConfig/Conversion/AddContextToTranslations.ts b/src/Models/ThemeConfig/Conversion/AddContextToTranslations.ts index adbea661f..0a9334d05 100644 --- a/src/Models/ThemeConfig/Conversion/AddContextToTranslations.ts +++ b/src/Models/ThemeConfig/Conversion/AddContextToTranslations.ts @@ -8,9 +8,8 @@ export class AddContextToTranslations extends DesugaringStep { constructor(prefix = "") { super( + "AddContextToTranslation", "Adds a '_context' to every object that is probably a translation", - ["_context"], - "AddContextToTranslation" ) this._prefix = prefix } diff --git a/src/Models/ThemeConfig/Conversion/AddPrefixToTagRenderingConfig.ts b/src/Models/ThemeConfig/Conversion/AddPrefixToTagRenderingConfig.ts index 90e3f978a..b769ce531 100644 --- a/src/Models/ThemeConfig/Conversion/AddPrefixToTagRenderingConfig.ts +++ b/src/Models/ThemeConfig/Conversion/AddPrefixToTagRenderingConfig.ts @@ -1,21 +1,16 @@ import { DesugaringStep } from "./Conversion" -import { ConversionContext } from "./ConversionContext" import SpecialVisualizations from "../../../UI/SpecialVisualizations" import { Translatable } from "../Json/Translatable" import { TagConfigJson } from "../Json/TagConfigJson" -import { - MappingConfigJson, - QuestionableTagRenderingConfigJson, -} from "../Json/QuestionableTagRenderingConfigJson" +import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson" export default class AddPrefixToTagRenderingConfig extends DesugaringStep { private readonly _prefix: string constructor(prefix: string) { super( + "AddPrefixToTagRenderingConfig", "Adds `prefix` to _all_ keys. Used to add information about a subamenity withing a bigger amenity (e.g. toilets in a restaurant, a sauna in a water park, ...)", - ["*"], - "AddPrefixToTagRenderingConfig" ) this._prefix = prefix } @@ -106,8 +101,7 @@ export default class AddPrefixToTagRenderingConfig extends DesugaringStep, - context: ConversionContext + json: Readonly ): QuestionableTagRenderingConfigJson { let freeform = json.freeform if (freeform) { diff --git a/src/Models/ThemeConfig/Conversion/Conversion.ts b/src/Models/ThemeConfig/Conversion/Conversion.ts index 5d7875757..36702b920 100644 --- a/src/Models/ThemeConfig/Conversion/Conversion.ts +++ b/src/Models/ThemeConfig/Conversion/Conversion.ts @@ -22,13 +22,11 @@ export interface ConversionMessage { } export abstract class Conversion { - public readonly modifiedAttributes: string[] public readonly name: string protected readonly doc: string - constructor(doc: string, modifiedAttributes: string[] = [], name: string) { - this.modifiedAttributes = modifiedAttributes - this.doc = doc + "\n\nModified attributes are\n" + modifiedAttributes.join(", ") + constructor(name: string, doc: string) { + this.doc = doc this.name = name } @@ -76,7 +74,7 @@ export class Pipe extends Conversion { private readonly _failfast: boolean constructor(step0: Conversion, step1: Conversion, failfast = false) { - super("Merges two steps with different types", [], `Pipe(${step0.name}, ${step1.name})`) + super(`Pipe(${step0.name}, ${step1.name})`, "Merges two steps with different types") this._step0 = step0 this._step1 = step1 this._failfast = failfast @@ -95,11 +93,11 @@ export class Pure extends Conversion { private readonly _f: (t: TIn) => TOut constructor(f: (t: TIn) => TOut) { - super("Wrapper around a pure function", [], "Pure") + super("Pure", "Wrapper around a pure function") this._f = f } - convert(json: TIn, context: ConversionContext): TOut { + convert(json: TIn): TOut { return this._f(json) } } @@ -109,7 +107,7 @@ export class Bypass extends DesugaringStep { private readonly _step: DesugaringStep constructor(applyIf: (t: T) => boolean, step: DesugaringStep) { - super("Applies the step on the object, if the object satisfies the predicate", [], "Bypass") + super("Bypass", "Applies the step on the object, if the object satisfies the predicate") this._applyIf = applyIf this._step = step } @@ -127,11 +125,7 @@ export class Each extends Conversion { private readonly _msg: string constructor(step: Conversion, options?: { msg?: string }) { - super( - "Applies the given step on every element of the list", - [], - "OnEach(" + step.name + ")" - ) + super("OnEach(" + step.name + ")", "Applies the given step on every element of the list") this._step = step this._msg = options?.msg } @@ -168,14 +162,13 @@ export class On extends DesugaringStep { constructor(key: string, step: Conversion | ((t: T) => Conversion)) { super( + `On(${key}, ${step.name})`, "Applies " + step.name + " onto property `" + key + "`", - [key], - `On(${key}, ${step.name})` ) if (typeof step === "function") { this.step = step } else { - this.step = (_) => step + this.step = () => step } this.key = key } @@ -196,10 +189,10 @@ export class On extends DesugaringStep { export class Pass extends Conversion { constructor(message?: string) { - super(message ?? "Does nothing, often to swap out steps in testing", [], "Pass") + super("Pass", message ?? "Does nothing, often to swap out steps in testing") } - convert(json: T, _: ConversionContext): T { + convert(json: T): T { return json } } @@ -208,11 +201,7 @@ export class Concat extends Conversion { private readonly _step: Conversion constructor(step: Conversion) { - super( - "Executes the given step, flattens the resulting list", - [], - "Concat(" + step.name + ")" - ) + super("Concat(" + step.name + ")", "Executes the given step, flattens the resulting list") this._step = step } @@ -230,11 +219,7 @@ export class FirstOf extends Conversion { private readonly _conversion: Conversion constructor(conversion: Conversion) { - super( - "Picks the first result of the conversion step", - [], - "FirstOf(" + conversion.name + ")" - ) + super("FirstOf(" + conversion.name + ")", "Picks the first result of the conversion step") this._conversion = conversion } @@ -252,7 +237,7 @@ export class Cached extends Conversion { private readonly key: string constructor(step: Conversion) { - super("Secretly caches the output for the given input", [], "cached") + super("cached", "Secretly caches the output for the given input") this._step = step this.key = "__super_secret_caching_key_" + step.name } @@ -276,11 +261,10 @@ export class Fuse extends DesugaringStep { constructor(doc: string, ...steps: DesugaringStep[]) { super( + "Fuse", (doc ?? "") + "This fused pipeline of the following steps: " + steps.map((s) => s.name).join(", "), - Utils.Dedup([].concat(...steps.map((step) => step.modifiedAttributes))), - "Fuse" ) this.steps = Utils.NoNull(steps) } @@ -318,19 +302,19 @@ export class Fuse extends DesugaringStep { } } -export class SetDefault extends DesugaringStep { - private readonly value: any +export class SetDefault extends DesugaringStep { + private readonly value: X private readonly key: string private readonly _overrideEmptyString: boolean - constructor(key: string, value: any, overrideEmptyString = false) { - super("Sets " + key + " to a default value if undefined", [], "SetDefault of " + key) + constructor(key: string, value: X, overrideEmptyString = false) { + super("SetDefault of " + key, "Sets " + key + " to a default value if undefined") this.key = key this.value = value this._overrideEmptyString = overrideEmptyString } - convert(json: T, _: ConversionContext): T { + convert(json: T): T { if (json === undefined) { return undefined } diff --git a/src/Models/ThemeConfig/Conversion/DetectMappingsWithImages.ts b/src/Models/ThemeConfig/Conversion/DetectMappingsWithImages.ts index aa9f787fb..4dfe4c9e4 100644 --- a/src/Models/ThemeConfig/Conversion/DetectMappingsWithImages.ts +++ b/src/Models/ThemeConfig/Conversion/DetectMappingsWithImages.ts @@ -10,9 +10,8 @@ export class DetectMappingsWithImages extends DesugaringStep { constructor() { super( + "PruneFilters", "Removes all filters which are impossible, e.g. because they conflict with the base tags", - ["filter"], - "PruneFilters" ) } @@ -114,12 +113,11 @@ export class ExpandFilter extends DesugaringStep { constructor(state: DesugaringContext) { super( + "ExpandFilter", [ "Expands filters: replaces a shorthand by the value found in 'filters.json'.", "If the string is formatted 'layername.filtername, it will be looked up into that layer instead. Note that pruning should still be done", ].join(" "), - ["filter"], - "ExpandFilter" ) this._state = state } diff --git a/src/Models/ThemeConfig/Conversion/ExpandRewrite.ts b/src/Models/ThemeConfig/Conversion/ExpandRewrite.ts index 4cc6c0f25..81f78bd12 100644 --- a/src/Models/ThemeConfig/Conversion/ExpandRewrite.ts +++ b/src/Models/ThemeConfig/Conversion/ExpandRewrite.ts @@ -6,7 +6,7 @@ import { Utils } from "../../../Utils" export class ExpandRewrite extends Conversion, T[]> { constructor() { - super("Applies a rewrite", [], "ExpandRewrite") + super("ExpandRewrite", "Applies a rewrite", []) } /** diff --git a/src/Models/ThemeConfig/Conversion/ExpandTagRendering.ts b/src/Models/ThemeConfig/Conversion/ExpandTagRendering.ts index 4d2e4a1b0..b8738b2a3 100644 --- a/src/Models/ThemeConfig/Conversion/ExpandTagRendering.ts +++ b/src/Models/ThemeConfig/Conversion/ExpandTagRendering.ts @@ -39,11 +39,7 @@ export class ExpandTagRendering extends Conversion< addToContext?: false | boolean } ) { - super( - "Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question and reusing the builtins", - [], - "ExpandTagRendering" - ) + super("ExpandTagRendering", "Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question and reusing the builtins", []) this._state = state this._self = self this._options = options diff --git a/src/Models/ThemeConfig/Conversion/FixImages.ts b/src/Models/ThemeConfig/Conversion/FixImages.ts index 331e3d02e..b8fd90100 100644 --- a/src/Models/ThemeConfig/Conversion/FixImages.ts +++ b/src/Models/ThemeConfig/Conversion/FixImages.ts @@ -28,7 +28,7 @@ export class ExtractImages extends Conversion< private _sharedTagRenderings: Set constructor(isOfficial: boolean, sharedTagRenderings: Set) { - super("Extract all images from a layoutConfig using the meta paths.", [], "ExctractImages") + super("ExctractImages", "Extract all images from a layoutConfig using the meta paths.", []) this._isOfficial = isOfficial this._sharedTagRenderings = sharedTagRenderings } diff --git a/src/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts b/src/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts index f3594a283..1a9f9ea65 100644 --- a/src/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts +++ b/src/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts @@ -11,9 +11,8 @@ export class UpdateLegacyLayer extends DesugaringStep< > { constructor() { super( + "UpdateLegacyLayer", "Updates various attributes from the old data format to the new to provide backwards compatibility with the formats", - ["overpassTags", "source.osmtags", "tagRenderings[*].id", "mapRendering"], - "UpdateLegacyLayer" ) } @@ -259,7 +258,7 @@ export class UpdateLegacyLayer extends DesugaringStep< class UpdateLegacyTheme extends DesugaringStep { constructor() { - super("Small fixes in the theme config", ["roamingRenderings"], "UpdateLegacyTheme") + super("UpdateLegacyTheme", "Small fixes in the theme config") } convert(json: ThemeConfigJson, context: ConversionContext): ThemeConfigJson { diff --git a/src/Models/ThemeConfig/Conversion/MiscTagRenderingChecks.ts b/src/Models/ThemeConfig/Conversion/MiscTagRenderingChecks.ts index 5cc4b3ff6..05fbe2b2b 100644 --- a/src/Models/ThemeConfig/Conversion/MiscTagRenderingChecks.ts +++ b/src/Models/ThemeConfig/Conversion/MiscTagRenderingChecks.ts @@ -1,10 +1,7 @@ import { DesugaringStep } from "./Conversion" import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson" import { LayerConfigJson } from "../Json/LayerConfigJson" -import { - MappingConfigJson, - QuestionableTagRenderingConfigJson, -} from "../Json/QuestionableTagRenderingConfigJson" +import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson" import { ConversionContext } from "./ConversionContext" import { Translation } from "../../../UI/i18n/Translation" import Validators from "../../../UI/InputElement/Validators" @@ -14,7 +11,7 @@ export class MiscTagRenderingChecks extends DesugaringStep { constructor() { super( + "AddFiltersFromTagRenderings", '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" ) } @@ -108,9 +95,8 @@ class AddFiltersFromTagRenderings extends DesugaringStep { class DetectInline extends DesugaringStep { constructor() { super( + "DetectInline", "If no 'inline' is set on the freeform key, it will be automatically added. If no special renderings are used, it'll be set to true", - ["freeform.inline"], - "DetectInline" ) } @@ -173,9 +159,8 @@ class DetectInline extends DesugaringStep { export class AddQuestionBox extends DesugaringStep { constructor() { super( + "AddQuestionBox", "Adds a 'questions'-object if no question element is added yet", - ["tagRenderings"], - "AddQuestionBox" ) } @@ -284,9 +269,8 @@ export class AddEditingElements extends DesugaringStep { constructor(desugaring: DesugaringContext) { super( - "Add some editing elements, such as the delete button or the move button if they are configured. These used to be handled by the feature info box, but this has been replaced by special visualisation elements", - [], - "AddEditingElements" + "AddEditingElements", + "Add some editing elements, such as the delete button or the move button if they are configured. These used to be handled by the feature info box, but this has been replaced by special visualisation elements" ) this._desugaring = desugaring this.builtinQuestions = Array.from(this._desugaring.tagRenderings?.values() ?? []) @@ -388,9 +372,8 @@ export class AddEditingElements extends DesugaringStep { export class RewriteSpecial extends DesugaringStep { constructor() { super( + "RewriteSpecial", "Converts a 'special' translation into a regular translation which uses parameters", - ["special"], - "RewriteSpecial" ) } @@ -664,7 +647,7 @@ class ExpandIconBadges extends DesugaringStep { private _expand: ExpandTagRendering constructor(state: DesugaringContext, layer: LayerConfigJson) { - super("Expands shorthand properties on iconBadges", ["iconBadges"], "ExpandIconBadges") + super("ExpandIconBadges", "Expands shorthand properties on iconBadges") this._expand = new ExpandTagRendering(state, layer) } @@ -766,9 +749,8 @@ class PreparePointRendering extends Fuse { class SetFullNodeDatabase extends DesugaringStep { constructor() { super( + "SetFullNodeDatabase", "sets the fullNodeDatabase-bit if needed", - ["fullNodeDatabase"], - "SetFullNodeDatabase" ) } @@ -795,9 +777,8 @@ class ExpandMarkerRenderings extends DesugaringStep { constructor(state: DesugaringContext, layer: LayerConfigJson) { super( + "ExpandMarkerRenderings", "Expands tagRenderings in the icons, if needed", - ["icon", "color"], - "ExpandMarkerRenderings" ) this._layer = layer this._state = state @@ -829,9 +810,8 @@ class ExpandMarkerRenderings extends DesugaringStep { class AddFavouriteBadges extends DesugaringStep { constructor() { super( + "AddFavouriteBadges", "Adds the favourite heart to the title and the rendering badges", - [], - "AddFavouriteBadges" ) } @@ -854,9 +834,8 @@ class AddFavouriteBadges extends DesugaringStep { export class AddRatingBadge extends DesugaringStep { constructor() { super( + "AddRatingBadge", "Adds the 'rating'-element if a reviews-element is used in the tagRenderings", - ["titleIcons"], - "AddRatingBadge" ) } @@ -890,9 +869,8 @@ export class AddRatingBadge extends DesugaringStep { export class AutoTitleIcon extends DesugaringStep { constructor() { super( + "AutoTitleIcon", "The auto-icon creates a (non-clickable) title icon based on a tagRendering which has icons", - ["titleIcons"], - "AutoTitleIcon" ) } @@ -967,12 +945,34 @@ export class AutoTitleIcon extends DesugaringStep { } } +class MoveUnitConfigs extends DesugaringStep { + + constructor() { + super("MoveUnitConfigs", "Looks into all the tagRenderings for a 'unitConfig', moves them to the layer level") + } + + convert(json: LayerConfigJson, context: ConversionContext): LayerConfigJson { + json = { ...json, units: [...(json.units ?? [])] } + for (const tr of json.tagRenderings ?? []) { + const qtr = (tr) + const unitConfig = qtr?.freeform?.unit + if (!unitConfig) { + continue + } + json.units.push({ + [qtr.freeform.key]: unitConfig + }) + } + return json + } + +} + class DeriveSource extends DesugaringStep { constructor() { super( + "DeriveSource", "If no source is given, automatically derives the osmTags by 'or'-ing all the preset tags", - ["source"], - "DeriveSource" ) } diff --git a/src/Models/ThemeConfig/Conversion/PrepareTheme.ts b/src/Models/ThemeConfig/Conversion/PrepareTheme.ts index 79ecbd138..dd45c7416 100644 --- a/src/Models/ThemeConfig/Conversion/PrepareTheme.ts +++ b/src/Models/ThemeConfig/Conversion/PrepareTheme.ts @@ -1,14 +1,4 @@ -import { - Concat, - Conversion, - DesugaringContext, - DesugaringStep, - Each, - Fuse, - On, - Pass, - SetDefault, -} from "./Conversion" +import { Concat, Conversion, DesugaringContext, DesugaringStep, Each, Fuse, On, Pass, SetDefault } from "./Conversion" import { ThemeConfigJson } from "../Json/ThemeConfigJson" import { PrepareLayer, RewriteSpecial } from "./PrepareLayer" import { LayerConfigJson } from "../Json/LayerConfigJson" @@ -25,11 +15,7 @@ class SubstituteLayer extends Conversion { constructor(state: DesugaringContext) { super( + "AddDefaultLayers", "Adds the default layers, namely: " + Constants.added_by_default.join(", "), - ["layers"], - "AddDefaultLayers" ) this._state = state } @@ -225,9 +210,8 @@ export class AddDefaultLayers extends DesugaringStep { class AddContextToTranslationsInLayout extends DesugaringStep { constructor() { super( + "AddContextToTranlationsInLayout", "Adds context to translations, including the prefix 'themes:json.id'; this is to make sure terms in an 'overrides' or inline layer are linkable too", - ["_context"], - "AddContextToTranlationsInLayout" ) } @@ -244,9 +228,8 @@ class AddContextToTranslationsInLayout extends DesugaringStep { class ApplyOverrideAll extends DesugaringStep { constructor() { super( + "ApplyOverrideAll", "Applies 'overrideAll' onto every 'layer'. The 'overrideAll'-field is removed afterwards", - ["overrideAll", "layers"], - "ApplyOverrideAll" ) } @@ -296,9 +279,8 @@ class AddDependencyLayersToTheme extends DesugaringStep { constructor(state: DesugaringContext) { super( + "AddDependencyLayersToTheme", `If a layer has a dependency on another layer, these layers are added automatically on the theme. (For example: defibrillator depends on 'walls_and_buildings' to snap onto. This layer is added automatically)`, - ["layers"], - "AddDependencyLayersToTheme" ) this._state = state } @@ -456,7 +438,7 @@ class PreparePersonalTheme extends DesugaringStep { private readonly _state: DesugaringContext constructor(state: DesugaringContext) { - super("Adds every public layer to the personal theme", ["layers"], "PreparePersonalTheme") + super("PreparePersonalTheme", "Adds every public layer to the personal theme") this._state = state } @@ -479,9 +461,8 @@ class PreparePersonalTheme extends DesugaringStep { class WarnForUnsubstitutedLayersInTheme extends DesugaringStep { constructor() { super( + "WarnForUnsubstitutedLayersInTheme", "Generates a warning if a theme uses an inline layer; we recommend splitting of all layers in separate files", - ["layers"], - "WarnForUnsubstitutedLayersInTheme" ) } @@ -531,7 +512,7 @@ class PostvalidateTheme extends DesugaringStep { private readonly _state: DesugaringContext constructor(state: DesugaringContext) { - super("Various validation steps when everything is done", [], "PostvalidateTheme") + super("PostvalidateTheme", "Various validation steps when everything is done") this._state = state } diff --git a/src/Models/ThemeConfig/Conversion/PrevalidateLayer.ts b/src/Models/ThemeConfig/Conversion/PrevalidateLayer.ts index 92ac3b77f..623e073b3 100644 --- a/src/Models/ThemeConfig/Conversion/PrevalidateLayer.ts +++ b/src/Models/ThemeConfig/Conversion/PrevalidateLayer.ts @@ -27,7 +27,7 @@ export class PrevalidateLayer extends DesugaringStep { doesImageExist: DoesImageExist, studioValidations: boolean ) { - super("Runs various checks against common mistakes for a layer", [], "PrevalidateLayer") + super("PrevalidateLayer", "Runs various checks against common mistakes for a layer") this._path = path this._isBuiltin = isBuiltin this._doesImageExist = doesImageExist @@ -57,6 +57,7 @@ export class PrevalidateLayer extends DesugaringStep { } } else { if (json.source === "special" || json.source === "special:library") { + // pass } else if (json.source && json.source["osmTags"] === undefined) { context .enters("source", "osmTags") @@ -232,11 +233,6 @@ export class PrevalidateLayer extends DesugaringStep { } } - try { - } catch (e) { - context.err("Could not validate layer due to: " + e + e.stack) - } - if (this._studioValidations) { if (!json.description) { context.enter("description").err("A description is required") @@ -358,7 +354,7 @@ export class PrevalidateLayer extends DesugaringStep { if (pointRendering.marker === undefined) { continue } - for (const icon of pointRendering?.marker) { + for (const icon of pointRendering?.marker ?? []) { const indexM = pointRendering?.marker.indexOf(icon) if (!icon.icon) { continue diff --git a/src/Models/ThemeConfig/Conversion/ValidateTheme.ts b/src/Models/ThemeConfig/Conversion/ValidateTheme.ts index 2b6949c96..d0dad222a 100644 --- a/src/Models/ThemeConfig/Conversion/ValidateTheme.ts +++ b/src/Models/ThemeConfig/Conversion/ValidateTheme.ts @@ -24,7 +24,7 @@ export class ValidateTheme extends DesugaringStep { isBuiltin: boolean, sharedTagRenderings?: Set ) { - super("Doesn't change anything, but emits warnings and errors", [], "ValidateTheme") + super("ValidateTheme", "Doesn't change anything, but emits warnings and errors") this._validateImage = doesImageExist this._path = path this._isBuiltin = isBuiltin diff --git a/src/Models/ThemeConfig/Conversion/Validation.ts b/src/Models/ThemeConfig/Conversion/Validation.ts index afb4ffed6..f6451a40c 100644 --- a/src/Models/ThemeConfig/Conversion/Validation.ts +++ b/src/Models/ThemeConfig/Conversion/Validation.ts @@ -28,9 +28,8 @@ export class ValidateLanguageCompleteness extends DesugaringStep { constructor(...languages: string[]) { super( + "ValidateLanguageCompleteness", "Checks that the given object is fully translated in the specified languages", - [], - "ValidateLanguageCompleteness" ) this._languages = languages ?? ["en"] } @@ -74,7 +73,7 @@ export class DoesImageExist extends DesugaringStep { checkExistsSync: (path: string) => boolean = undefined, ignore?: Set ) { - super("Checks if an image exists", [], "DoesImageExist") + super("DoesImageExist", "Checks if an image exists") this._ignore = ignore this._knownImagePaths = knownImagePaths this.doesPathExist = checkExistsSync @@ -129,9 +128,8 @@ export class DoesImageExist extends DesugaringStep { class OverrideShadowingCheck extends DesugaringStep { constructor() { super( + "OverrideShadowingCheck", "Checks that an 'overrideAll' does not override a single override", - [], - "OverrideShadowingCheck" ) } @@ -170,7 +168,7 @@ class OverrideShadowingCheck extends DesugaringStep { class MiscThemeChecks extends DesugaringStep { constructor() { - super("Miscelleanous checks on the theme", [], "MiscThemesChecks") + super("Miscelleanous checks on the theme", "MiscThemesChecks") } convert(json: ThemeConfigJson, context: ConversionContext): ThemeConfigJson { @@ -265,9 +263,8 @@ export class PrevalidateTheme extends Fuse { export class DetectConflictingAddExtraTags extends DesugaringStep { constructor() { super( + "DetectConflictingAddExtraTags", "The `if`-part in a mapping might set some keys. Those keys are not allowed to be set in the `addExtraTags`, as this might result in conflicting values", - [], - "DetectConflictingAddExtraTags" ) } @@ -310,9 +307,8 @@ export class DetectConflictingAddExtraTags extends DesugaringStep { constructor() { super( + "DetectNonErasedKeysInMappings", "A tagRendering might set a freeform key (e.g. `name` and have an option that _should_ erase this name, e.g. `noname=yes`). Under normal circumstances, every mapping/freeform should affect all touched keys", - [], - "DetectNonErasedKeysInMappings" ) } @@ -407,9 +403,8 @@ export class DetectMappingsShadowedByCondition extends DesugaringStep> { constructor() { super( + "ValidatePossibleLinks", "Given a possible set of translations, validates that does have `rel='noopener'` set", - [], - "ValidatePossibleLinks" ) } @@ -661,9 +655,8 @@ export class CheckTranslation extends DesugaringStep { constructor(allowUndefined: boolean = false) { super( + "CheckTranslation", "Checks that a translation is valid and internally consistent", - ["*"], - "CheckTranslation" ) this._allowUndefined = allowUndefined } @@ -712,7 +705,7 @@ export class ValidateLayerConfig extends DesugaringStep { studioValidations: boolean = false, skipDefaultLayers: boolean = false ) { - super("Thin wrapper around 'ValidateLayer", [], "ValidateLayerConfig") + super("ValidateLayerConfig", "Thin wrapper around 'ValidateLayer") this.validator = new ValidateLayer( path, isBuiltin, @@ -734,7 +727,7 @@ export class ValidateLayerConfig extends DesugaringStep { export class ValidatePointRendering extends DesugaringStep { constructor() { - super("Various checks for pointRenderings", [], "ValidatePOintRendering") + super("ValidatePointRendering", "Various checks for pointRenderings") } convert(json: PointRenderingConfigJson, context: ConversionContext): PointRenderingConfigJson { @@ -777,7 +770,7 @@ export class ValidateLayer extends Conversion< studioValidations: boolean = false, skipDefaultLayers: boolean = false ) { - super("Doesn't change anything, but emits warnings and errors", [], "ValidateLayer") + super("ValidateLayer", "Doesn't change anything, but emits warnings and errors") this._prevalidation = new PrevalidateLayer( path, isBuiltin, @@ -819,7 +812,7 @@ export class ValidateLayer extends Conversion< } for (let i = 0; i < (layerConfig.calculatedTags ?? []).length; i++) { - const [_, code, __] = layerConfig.calculatedTags[i] + const code = layerConfig.calculatedTags[i][1] try { new Function("feat", "return " + code + ";") } catch (e) { @@ -894,7 +887,7 @@ export class ValidateLayer extends Conversion< export class ValidateFilter extends DesugaringStep { constructor() { - super("Detect common errors in the filters", [], "ValidateFilter") + super("ValidateFilter", "Detect common errors in the filters") } convert(filter: FilterConfigJson, context: ConversionContext): FilterConfigJson { @@ -931,9 +924,8 @@ export class DetectDuplicateFilters extends DesugaringStep<{ }> { constructor() { super( - "Tries to detect layers where a shared filter can be used (or where similar filters occur)", - [], - "DetectDuplicateFilters" + "DetectDuplicateFilters", + "Tries to detect layers where a shared filter can be used (or where similar filters occur)" ) } @@ -1041,9 +1033,8 @@ export class DetectDuplicateFilters extends DesugaringStep<{ export class DetectDuplicatePresets extends DesugaringStep { constructor() { super( + "DetectDuplicatePresets", "Detects mappings which have identical (english) names or identical mappings.", - ["presets"], - "DetectDuplicatePresets" ) } @@ -1107,11 +1098,7 @@ export class ValidateThemeEnsemble extends Conversion< > > { constructor() { - super( - "Validates that all themes together are logical, i.e. no duplicate ids exists within (overriden) themes", - [], - "ValidateThemeEnsemble" - ) + super("ValidateThemeEnsemble", "Validates that all themes together are logical, i.e. no duplicate ids exists within (overriden) themes") } convert( diff --git a/src/Models/ThemeConfig/Json/LayerConfigJson.ts b/src/Models/ThemeConfig/Json/LayerConfigJson.ts index 9a179072a..25fc08297 100644 --- a/src/Models/ThemeConfig/Json/LayerConfigJson.ts +++ b/src/Models/ThemeConfig/Json/LayerConfigJson.ts @@ -556,7 +556,7 @@ export interface LayerConfigJson { allowSplit?: boolean /** - * Either a list with [{"key": "unitname", "key2": {"quantity": "unitname", "denominations": ["denom", "denom"]}}] + * Either a list of unitConfigs with [{"key": "unitname", "key2": {"quantity": "unitname", "denominations": ["denom", "denom"]}}] * * Use `"inverted": true` if the amount should be _divided_ by the denomination, e.g. for charge over time (`€5/day`) * diff --git a/src/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson.ts b/src/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson.ts index f7d9e957a..c27b0fed1 100644 --- a/src/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson.ts +++ b/src/Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson.ts @@ -290,6 +290,29 @@ export interface QuestionableTagRenderingConfigJson extends TagRenderingConfigJs * group: hidden */ helperArgs?: any + + /** + * question: what units + * + * group: hidden + * + * Note: this is actually a syntactic sugar and is translated to the unit-syntax on layer level + */ + unit?: { + /** + * What is the quantity? E.g. 'voltage', 'speed', ... + * See [builtin_units.md] for options + */ + quantity: string + /** + * The possible denominations for the quantities. E.g. For 'length', might be 'cm', 'm', 'km', ... + * If none given, will allow all the defaults + */ + denominations: string[] + + canonical?: string + inverted?: boolean + } } /** diff --git a/src/UI/Studio/EditLayerState.ts b/src/UI/Studio/EditLayerState.ts index 09301d8e5..7c086960a 100644 --- a/src/UI/Studio/EditLayerState.ts +++ b/src/UI/Studio/EditLayerState.ts @@ -1,12 +1,7 @@ import { ConfigMeta } from "./configMeta" import { Store, UIEventSource } from "../../Logic/UIEventSource" import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson" -import { - Conversion, - ConversionMessage, - DesugaringContext, - Pipe, -} from "../../Models/ThemeConfig/Conversion/Conversion" +import { Conversion, ConversionMessage, DesugaringContext, Pipe } from "../../Models/ThemeConfig/Conversion/Conversion" import { PrepareLayer } from "../../Models/ThemeConfig/Conversion/PrepareLayer" import { PrevalidateTheme, ValidateLayer } from "../../Models/ThemeConfig/Conversion/Validation" import { AllSharedLayers } from "../../Customizations/AllSharedLayers" @@ -281,11 +276,7 @@ class ContextRewritingStep extends Conversion { step: Conversion, getTagRenderings: (t: T) => TagRenderingConfigJson[] ) { - super( - "When validating a layer, the tagRenderings are first expanded. Some builtin tagRendering-calls (e.g. `contact`) will introduce _multiple_ tagRenderings, causing the count to be off. This class rewrites the error messages to fix this", - [], - "ContextRewritingStep" - ) + super("ContextRewritingStep", "When validating a layer, the tagRenderings are first expanded. Some builtin tagRendering-calls (e.g. `contact`) will introduce _multiple_ tagRenderings, causing the count to be off. This class rewrites the error messages to fix this", []) this._state = state this._step = step this._getTagRenderings = getTagRenderings