Refactoring: fix 'delete' and 'move'-buttons as special elements

This commit is contained in:
Pieter Vander Vennet 2023-04-14 02:42:57 +02:00
parent 466dd16568
commit 8a1f0599d9
19 changed files with 317 additions and 296 deletions

View file

@ -234,9 +234,9 @@ class ExpandTagRendering extends Conversion<
if (typeof layer.source !== "string") {
if (found.condition === undefined) {
found.condition = layer.source.osmTags
found.condition = layer.source["osmTags"]
} else {
found.condition = { and: [found.condition, layer.source.osmTags] }
found.condition = { and: [found.condition, layer.source["osmTags"]] }
}
}
}
@ -436,7 +436,7 @@ class DetectInline extends DesugaringStep<QuestionableTagRenderingConfigJson> {
if (typeof json.render === "string") {
spec = { "*": json.render }
} else {
spec = json.render
spec = <Record<string, string>>json.render
}
const errors: string[] = []
for (const key in spec) {
@ -480,7 +480,10 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
json: LayerConfigJson,
context: string
): { result: LayerConfigJson; errors?: string[]; warnings?: string[]; information?: string[] } {
if (json.tagRenderings === undefined) {
if (
json.tagRenderings === undefined ||
json.tagRenderings.some((tr) => tr["id"] === "leftover-questions")
) {
return { result: json }
}
json = JSON.parse(JSON.stringify(json))
@ -500,7 +503,6 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
const errors: string[] = []
const warnings: string[] = []
if (noLabels.length > 1) {
console.log(json.tagRenderings)
errors.push(
"At " +
context +
@ -572,6 +574,45 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
}
}
export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
constructor() {
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"
)
}
convert(
json: LayerConfigJson,
context: string
): { result: LayerConfigJson; errors?: string[]; warnings?: string[]; information?: string[] } {
json = JSON.parse(JSON.stringify(json))
if (json.allowSplit && !ValidationUtils.hasSpecialVisualisation(json, "split_button")) {
json.tagRenderings.push({
id: "split-button",
render: { "*": "{split_button()}" },
})
}
if (json.allowMove && !ValidationUtils.hasSpecialVisualisation(json, "move_button")) {
json.tagRenderings.push({
id: "move-button",
render: { "*": "{move_button()}" },
})
}
if (json.deletion && !ValidationUtils.hasSpecialVisualisation(json, "delete_button")) {
json.tagRenderings.push({
id: "delete-button",
render: { "*": "{delete_button()}" },
})
}
return { result: json }
}
}
export class ExpandRewrite<T> extends Conversion<T | RewritableConfigJson<T>, T[]> {
constructor() {
super("Applies a rewrite", [], "ExpandRewrite")
@ -1064,6 +1105,36 @@ class PreparePointRendering extends Fuse<PointRenderingConfigJson | LineRenderin
}
}
export class AddMiniMap extends DesugaringStep<LayerConfigJson> {
private readonly _state: DesugaringContext
constructor(state: DesugaringContext) {
super(
"Adds a default 'minimap'-element to the tagrenderings if none of the elements define such a minimap",
["tagRenderings"],
"AddMiniMap"
)
this._state = state
}
convert(layerConfig: LayerConfigJson, context: string): { result: LayerConfigJson } {
if (!layerConfig.tagRenderings) {
return { result: layerConfig }
}
const state = this._state
const hasMinimap = ValidationUtils.hasSpecialVisualisation(layerConfig, "minimap")
if (!hasMinimap) {
layerConfig = { ...layerConfig }
layerConfig.tagRenderings = [...layerConfig.tagRenderings]
layerConfig.tagRenderings.push(state.tagRenderings.get("minimap"))
}
return {
result: layerConfig,
}
}
}
export class PrepareLayer extends Fuse<LayerConfigJson> {
constructor(state: DesugaringContext) {
super(
@ -1072,6 +1143,9 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer))),
new On("tagRenderings", new Each(new DetectInline())),
new AddQuestionBox(),
new AddMiniMap(state),
new AddEditingElements(),
new On("mapRendering", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
new On<(PointRenderingConfigJson | LineRenderingConfigJson)[], LayerConfigJson>(
"mapRendering",

View file

@ -10,7 +10,7 @@ import {
SetDefault,
} from "./Conversion"
import { LayoutConfigJson } from "../Json/LayoutConfigJson"
import { AddQuestionBox, PrepareLayer } from "./PrepareLayer"
import { PrepareLayer } from "./PrepareLayer"
import { LayerConfigJson } from "../Json/LayerConfigJson"
import { Utils } from "../../../Utils"
import Constants from "../../Constants"
@ -295,56 +295,6 @@ class AddImportLayers extends DesugaringStep<LayoutConfigJson> {
}
}
export class AddMiniMap extends DesugaringStep<LayerConfigJson> {
private readonly _state: DesugaringContext
constructor(state: DesugaringContext) {
super(
"Adds a default 'minimap'-element to the tagrenderings if none of the elements define such a minimap",
["tagRenderings"],
"AddMiniMap"
)
this._state = state
}
/**
* Returns true if this tag rendering has a minimap in some language.
* Note: this minimap can be hidden by conditions
*
* AddMiniMap.hasMinimap({render: "{minimap()}"}) // => true
* AddMiniMap.hasMinimap({render: {en: "{minimap()}"}}) // => true
* AddMiniMap.hasMinimap({render: {en: "{minimap()}", nl: "{minimap()}"}}) // => true
* AddMiniMap.hasMinimap({render: {en: "{minimap()}", nl: "No map for the dutch!"}}) // => true
* AddMiniMap.hasMinimap({render: "{minimap()}"}) // => true
* AddMiniMap.hasMinimap({render: "{minimap(18,featurelist)}"}) // => true
* AddMiniMap.hasMinimap({mappings: [{if: "xyz=abc",then: "{minimap(18,featurelist)}"}]}) // => true
* AddMiniMap.hasMinimap({render: "Some random value {key}"}) // => false
* AddMiniMap.hasMinimap({render: "Some random value {minimap}"}) // => false
*/
static hasMinimap(renderingConfig: TagRenderingConfigJson): boolean {
return ValidationUtils.getSpecialVisualisations(renderingConfig).some(
(vis) => vis.funcName === "minimap"
)
}
convert(layerConfig: LayerConfigJson, context: string): { result: LayerConfigJson } {
const state = this._state
const hasMinimap =
layerConfig.tagRenderings?.some((tr) =>
AddMiniMap.hasMinimap(<TagRenderingConfigJson>tr)
) ?? true
if (!hasMinimap) {
layerConfig = { ...layerConfig }
layerConfig.tagRenderings = [...layerConfig.tagRenderings]
layerConfig.tagRenderings.push(state.tagRenderings.get("minimap"))
}
return {
result: layerConfig,
}
}
}
class AddContextToTranslationsInLayout extends DesugaringStep<LayoutConfigJson> {
constructor() {
super(
@ -660,9 +610,7 @@ export class PrepareTheme extends Fuse<LayoutConfigJson> {
? new Pass("AddDefaultLayers is disabled due to the set flag")
: new AddDefaultLayers(state),
new AddDependencyLayersToTheme(state),
new AddImportLayers(),
new On("layers", new Each(new AddQuestionBox())),
new On("layers", new Each(new AddMiniMap(state)))
new AddImportLayers()
)
}

View file

@ -2,8 +2,22 @@ import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
import { Utils } from "../../../Utils"
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
import { RenderingSpecification, SpecialVisualization } from "../../../UI/SpecialVisualization"
import { LayerConfigJson } from "../Json/LayerConfigJson"
export default class ValidationUtils {
public static hasSpecialVisualisation(
layer: LayerConfigJson,
specialVisualisation: string
): boolean {
return (
layer.tagRenderings?.some((tagRendering) =>
ValidationUtils.getSpecialVisualisations(<TagRenderingConfigJson>tagRendering).some(
(vis) => vis.funcName === specialVisualisation
)
) ?? false
)
}
/**
* Gives all the (function names of) used special visualisations
* @param renderingConfig
@ -15,6 +29,7 @@ export default class ValidationUtils {
(spec) => spec["func"]
)
}
public static getSpecialVisualsationsWithArgs(
renderingConfig: TagRenderingConfigJson
): RenderingSpecification[] {

View file

@ -90,7 +90,7 @@ export default class LayerConfig extends WithContextLoader {
if (json.source === "special" || json.source === "special:library") {
this.source = null
} else if (json.source.osmTags === undefined) {
} else if (json.source["osmTags"] === undefined) {
throw (
"Layer " +
this.id +
@ -122,8 +122,8 @@ export default class LayerConfig extends WithContextLoader {
}
this.syncSelection = json.syncSelection ?? "no"
if (typeof json.source !== "string") {
this.maxAgeOfCache = json.source.maxCacheAge ?? 24 * 60 * 60 * 30
const osmTags = TagUtils.Tag(json.source.osmTags, context + "source.osmTags")
this.maxAgeOfCache = json.source["maxCacheAge"] ?? 24 * 60 * 60 * 30
const osmTags = TagUtils.Tag(json.source["osmTags"], context + "source.osmTags")
if (osmTags.isNegative()) {
throw (
context +