forked from MapComplete/MapComplete
chore: automated housekeeping...
This commit is contained in:
parent
92352ed274
commit
535e36a006
68 changed files with 2734 additions and 382 deletions
|
|
@ -1,4 +1,14 @@
|
|||
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"
|
||||
|
|
@ -30,7 +40,7 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs
|
|||
const knownLayers = Array.from(state.sharedLayers.keys())
|
||||
const withDistance: [string, number][] = knownLayers.map((lname) => [
|
||||
lname,
|
||||
Utils.levenshteinDistance(name, lname)
|
||||
Utils.levenshteinDistance(name, lname),
|
||||
])
|
||||
withDistance.sort((a, b) => a[1] - b[1])
|
||||
const ids = withDistance.map((n) => n[0])
|
||||
|
|
@ -120,9 +130,9 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs
|
|||
usedLabels.add(labels[forbiddenLabel])
|
||||
context.info(
|
||||
"Dropping tagRendering " +
|
||||
tr["id"] +
|
||||
" as it has a forbidden label: " +
|
||||
labels[forbiddenLabel]
|
||||
tr["id"] +
|
||||
" as it has a forbidden label: " +
|
||||
labels[forbiddenLabel]
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
|
@ -140,10 +150,10 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs
|
|||
usedLabels.add(tr["group"])
|
||||
context.info(
|
||||
"Dropping tagRendering " +
|
||||
tr["id"] +
|
||||
" as its group `" +
|
||||
tr["group"] +
|
||||
"` is a forbidden label"
|
||||
tr["id"] +
|
||||
" as its group `" +
|
||||
tr["group"] +
|
||||
"` is a forbidden label"
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
|
@ -154,8 +164,8 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs
|
|||
if (unused.length > 0) {
|
||||
context.err(
|
||||
"This theme specifies that certain tagrenderings have to be removed based on forbidden layers. One or more of these layers did not match any tagRenderings and caused no deletions: " +
|
||||
unused.join(", ") +
|
||||
"\n This means that this label can be removed or that the original tagRendering that should be deleted does not have this label anymore"
|
||||
unused.join(", ") +
|
||||
"\n This means that this label can be removed or that the original tagRendering that should be deleted does not have this label anymore"
|
||||
)
|
||||
}
|
||||
found.tagRenderings = filtered
|
||||
|
|
@ -195,10 +205,10 @@ export class AddDefaultLayers extends DesugaringStep<ThemeConfigJson> {
|
|||
if (alreadyLoaded.has(v.id)) {
|
||||
context.warn(
|
||||
"Layout " +
|
||||
context +
|
||||
" already has a layer with name " +
|
||||
v.id +
|
||||
"; skipping inclusion of this builtin layer"
|
||||
context +
|
||||
" already has a layer with name " +
|
||||
v.id +
|
||||
"; skipping inclusion of this builtin layer"
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
|
@ -342,10 +352,10 @@ class AddDependencyLayersToTheme extends DesugaringStep<ThemeConfigJson> {
|
|||
.enters("layer dependency")
|
||||
.err(
|
||||
"Layer " +
|
||||
dependency.neededLayer +
|
||||
" is loaded because " +
|
||||
dependency.reason +
|
||||
"; so it must specify a `snapName`. This is used in the sentence `move this point to snap it to {snapName}`"
|
||||
dependency.neededLayer +
|
||||
" is loaded because " +
|
||||
dependency.reason +
|
||||
"; so it must specify a `snapName`. This is used in the sentence `move this point to snap it to {snapName}`"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -370,12 +380,12 @@ class AddDependencyLayersToTheme extends DesugaringStep<ThemeConfigJson> {
|
|||
if (dep === undefined) {
|
||||
const message = [
|
||||
"Loading a dependency failed: layer " +
|
||||
unmetDependency.neededLayer +
|
||||
" is not found, neither as layer of " +
|
||||
themeId +
|
||||
" nor as builtin layer.",
|
||||
unmetDependency.neededLayer +
|
||||
" is not found, neither as layer of " +
|
||||
themeId +
|
||||
" nor as builtin layer.",
|
||||
reason,
|
||||
"Loaded layers are: " + alreadyLoaded.map((l) => l.id).join(",")
|
||||
"Loaded layers are: " + alreadyLoaded.map((l) => l.id).join(","),
|
||||
]
|
||||
throw message.join("\n\t")
|
||||
}
|
||||
|
|
@ -385,7 +395,7 @@ class AddDependencyLayersToTheme extends DesugaringStep<ThemeConfigJson> {
|
|||
dep.description = reason
|
||||
dependenciesToAdd.unshift({
|
||||
config: dep,
|
||||
reason
|
||||
reason,
|
||||
})
|
||||
loadedLayerIds.add(dep.id)
|
||||
unmetDependencies = unmetDependencies.filter(
|
||||
|
|
@ -430,7 +440,7 @@ class AddDependencyLayersToTheme extends DesugaringStep<ThemeConfigJson> {
|
|||
|
||||
return {
|
||||
...theme,
|
||||
layers: layers
|
||||
layers: layers,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -500,10 +510,10 @@ class WarnForUnsubstitutedLayersInTheme extends DesugaringStep<ThemeConfigJson>
|
|||
|
||||
context.warn(
|
||||
"The theme " +
|
||||
json.id +
|
||||
" has an inline layer: " +
|
||||
layer["id"] +
|
||||
". This is discouraged."
|
||||
json.id +
|
||||
" has an inline layer: " +
|
||||
layer["id"] +
|
||||
". This is discouraged."
|
||||
)
|
||||
}
|
||||
return json
|
||||
|
|
@ -545,12 +555,12 @@ class PostvalidateTheme extends DesugaringStep<ThemeConfigJson> {
|
|||
if (minZoomAll < layer.minzoom) {
|
||||
context.err(
|
||||
"There are multiple layers based on " +
|
||||
basedOn +
|
||||
". The layer with id " +
|
||||
layer.id +
|
||||
" has a minzoom of " +
|
||||
layer.minzoom +
|
||||
", and has a name set. Another similar layer has a lower minzoom. As such, the layer selection might show 'zoom in to see features' even though some of the features are already visible. Set `\"name\": null` for this layer and eventually remove the 'name':null for the other layer."
|
||||
basedOn +
|
||||
". The layer with id " +
|
||||
layer.id +
|
||||
" has a minzoom of " +
|
||||
layer.minzoom +
|
||||
", and has a name set. Another similar layer has a lower minzoom. As such, the layer selection might show 'zoom in to see features' even though some of the features are already visible. Set `\"name\": null` for this layer and eventually remove the 'name':null for the other layer."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -576,11 +586,11 @@ class PostvalidateTheme extends DesugaringStep<ThemeConfigJson> {
|
|||
.enters("layers", config.id, "filter", "sameAs")
|
||||
.err(
|
||||
"The layer " +
|
||||
config.id +
|
||||
" follows the filter state of layer " +
|
||||
sameAs +
|
||||
", but no layer with this name was found.\n\tDid you perhaps mean one of: " +
|
||||
closeLayers.slice(0, 3).join(", ")
|
||||
config.id +
|
||||
" follows the filter state of layer " +
|
||||
sameAs +
|
||||
", but no layer with this name was found.\n\tDid you perhaps mean one of: " +
|
||||
closeLayers.slice(0, 3).join(", ")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -608,12 +618,16 @@ export class PrepareTheme extends Fuse<ThemeConfigJson> {
|
|||
new SetDefault("socialImage", "assets/SocialImage.png", true),
|
||||
// We expand all tagrenderings first...
|
||||
new On("layers", new Each(new PrepareLayer(state))),
|
||||
new On("popup", new Each(
|
||||
new Fuse("Prepare popups",
|
||||
new On("body", new Each(new RewriteSpecial())),
|
||||
new On("title", new RewriteSpecial())
|
||||
new On(
|
||||
"popup",
|
||||
new Each(
|
||||
new Fuse(
|
||||
"Prepare popups",
|
||||
new On("body", new Each(new RewriteSpecial())),
|
||||
new On("title", new RewriteSpecial())
|
||||
)
|
||||
)
|
||||
)),
|
||||
),
|
||||
|
||||
// Then we apply the override all. We must first expand everything in case that we override something in an expanded tag
|
||||
// Note that it'll cheat with tagRenderings+
|
||||
|
|
|
|||
|
|
@ -483,11 +483,11 @@ export interface ThemeConfigJson {
|
|||
*/
|
||||
dismissible?: boolean
|
||||
condition?: TagConfigJson
|
||||
title: TagRenderingConfigJson,
|
||||
body: TagRenderingConfigJson[],
|
||||
title: TagRenderingConfigJson
|
||||
body: TagRenderingConfigJson[]
|
||||
/**
|
||||
* id of the popup, mostly to keep the translations in check
|
||||
*/
|
||||
id: string,
|
||||
id: string
|
||||
}[]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ import { TagUtils } from "../../Logic/Tags/TagUtils"
|
|||
import { And } from "../../Logic/Tags/And"
|
||||
import { Utils } from "../../Utils"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "./Json/QuestionableTagRenderingConfigJson"
|
||||
import {
|
||||
MappingConfigJson,
|
||||
QuestionableTagRenderingConfigJson,
|
||||
} from "./Json/QuestionableTagRenderingConfigJson"
|
||||
import Validators, { ValidatorType } from "../../UI/InputElement/Validators"
|
||||
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson"
|
||||
import { RegexTag } from "../../Logic/Tags/RegexTag"
|
||||
|
|
@ -223,7 +226,7 @@ export default class TagRenderingConfig {
|
|||
inline: json.freeform.inline ?? false,
|
||||
default: json.freeform.default,
|
||||
postfixDistinguished: json.freeform.postfixDistinguished?.trim(),
|
||||
args: json.freeform.helperArgs
|
||||
args: json.freeform.helperArgs,
|
||||
}
|
||||
if (json.freeform["extraTags"] !== undefined) {
|
||||
throw `Freeform.extraTags is defined. This should probably be 'freeform.addExtraTag' (at ${context})`
|
||||
|
|
@ -447,7 +450,7 @@ export default class TagRenderingConfig {
|
|||
iconClass,
|
||||
addExtraTags,
|
||||
searchTerms: mapping.searchTerms,
|
||||
priorityIf: prioritySearch
|
||||
priorityIf: prioritySearch,
|
||||
}
|
||||
if (isQuestionable) {
|
||||
if (hideInAnswer !== true && mp.if !== undefined && !mp.if.isUsableAsAnswer()) {
|
||||
|
|
@ -554,7 +557,7 @@ export default class TagRenderingConfig {
|
|||
then: new TypedTranslation<object>(
|
||||
this.render.replace("{" + this.freeform.key + "}", leftover).translations,
|
||||
this.render.context
|
||||
)
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -607,7 +610,7 @@ export default class TagRenderingConfig {
|
|||
return {
|
||||
then: this.render.PartialSubs({ [this.freeform.key]: v.trim() }),
|
||||
icon: this.renderIcon,
|
||||
iconClass: this.renderIconClass
|
||||
iconClass: this.renderIconClass,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -662,7 +665,7 @@ export default class TagRenderingConfig {
|
|||
key: commonKey,
|
||||
values: Utils.NoNull(
|
||||
values.map((arr) => arr.filter((item) => item.k === commonKey)[0]?.v)
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -677,7 +680,7 @@ export default class TagRenderingConfig {
|
|||
return {
|
||||
key,
|
||||
type: this.freeform.type,
|
||||
values
|
||||
values,
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Could not create FreeformValues for tagrendering", this.id)
|
||||
|
|
@ -753,7 +756,7 @@ export default class TagRenderingConfig {
|
|||
const allValues = v.split(";").map((s) => s.trim())
|
||||
const perPostfix: Record<string, string> = {}
|
||||
for (const value of allValues) {
|
||||
const [v, postfix] = value.split("/").map(s => s.trim())
|
||||
const [v, postfix] = value.split("/").map((s) => s.trim())
|
||||
perPostfix[postfix ?? pf] = v.trim()
|
||||
}
|
||||
if (freeformValue === "" || freeformValue === undefined) {
|
||||
|
|
@ -790,7 +793,7 @@ export default class TagRenderingConfig {
|
|||
// Either no mappings, or this is a radio-button selected freeform value
|
||||
const tag = [
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
]
|
||||
const newProperties = new And(tag).applyOn(currentProperties)
|
||||
if (this.invalidValues?.matchesProperties(newProperties)) {
|
||||
|
|
@ -814,7 +817,7 @@ export default class TagRenderingConfig {
|
|||
selectedMappings.push(
|
||||
new And([
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
|
@ -847,12 +850,12 @@ export default class TagRenderingConfig {
|
|||
if (useFreeform) {
|
||||
return [
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
]
|
||||
} else if (singleSelectedMapping !== undefined) {
|
||||
return [
|
||||
this.mappings[singleSelectedMapping].if,
|
||||
...(this.mappings[singleSelectedMapping].addExtraTags ?? [])
|
||||
...(this.mappings[singleSelectedMapping].addExtraTags ?? []),
|
||||
]
|
||||
} else {
|
||||
console.error("TagRenderingConfig.ConstructSpecification has a weird fallback for", {
|
||||
|
|
@ -860,7 +863,7 @@ export default class TagRenderingConfig {
|
|||
singleSelectedMapping,
|
||||
multiSelectedMapping,
|
||||
currentProperties,
|
||||
useFreeform
|
||||
useFreeform,
|
||||
})
|
||||
return undefined
|
||||
}
|
||||
|
|
@ -889,11 +892,11 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
const msgs: string[] = [
|
||||
icon +
|
||||
" " +
|
||||
"*" +
|
||||
m.then.textFor(lang) +
|
||||
"* is shown if with " +
|
||||
m.if.asHumanString(true, false, {})
|
||||
" " +
|
||||
"*" +
|
||||
m.then.textFor(lang) +
|
||||
"* is shown if with " +
|
||||
m.if.asHumanString(true, false, {}),
|
||||
]
|
||||
|
||||
if (m.hideInAnswer === true) {
|
||||
|
|
@ -902,7 +905,7 @@ export default class TagRenderingConfig {
|
|||
if (m.ifnot !== undefined) {
|
||||
msgs.push(
|
||||
"Unselecting this answer will add " +
|
||||
m.ifnot.asHumanString(true, false, {})
|
||||
m.ifnot.asHumanString(true, false, {})
|
||||
)
|
||||
}
|
||||
return msgs.join(". ")
|
||||
|
|
@ -926,7 +929,7 @@ export default class TagRenderingConfig {
|
|||
if (this.labels?.length > 0) {
|
||||
labels = [
|
||||
"This tagrendering has labels ",
|
||||
...this.labels.map((label) => "`" + label + "`")
|
||||
...this.labels.map((label) => "`" + label + "`"),
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
|
|
@ -939,7 +942,7 @@ export default class TagRenderingConfig {
|
|||
freeform,
|
||||
mappings,
|
||||
condition,
|
||||
labels
|
||||
labels,
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
|
|
@ -983,7 +986,7 @@ export default class TagRenderingConfig {
|
|||
if (part.indexOf("/") < 0) {
|
||||
continue
|
||||
}
|
||||
const [v, denom] = part.split("/").map(s => s.trim())
|
||||
const [v, denom] = part.split("/").map((s) => s.trim())
|
||||
if (denom === distinguish) {
|
||||
return v
|
||||
}
|
||||
|
|
@ -1043,19 +1046,21 @@ export default class TagRenderingConfig {
|
|||
/**
|
||||
* Gives all the tags that should be applied to "reset" the freeform key to an "unknown" state
|
||||
*/
|
||||
public markUnknown(layer: LayerConfig, currentProperties: Record<string, string>): UploadableTag[] {
|
||||
public markUnknown(
|
||||
layer: LayerConfig,
|
||||
currentProperties: Record<string, string>
|
||||
): UploadableTag[] {
|
||||
if (this.freeform?.postfixDistinguished) {
|
||||
const v = currentProperties[this.freeform.key] ?? ""
|
||||
const allValues = v.split(";").filter(
|
||||
part => part.split("/")[1]?.trim() !== this.freeform.postfixDistinguished
|
||||
)
|
||||
const allValues = v
|
||||
.split(";")
|
||||
.filter((part) => part.split("/")[1]?.trim() !== this.freeform.postfixDistinguished)
|
||||
return [new Tag(this.freeform.key, allValues.join(";"))]
|
||||
}
|
||||
|
||||
const keys = this.removeToSetUnknown(layer, currentProperties)
|
||||
|
||||
|
||||
return keys?.map(k => new Tag(k, ""))
|
||||
return keys?.map((k) => new Tag(k, ""))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1095,7 +1100,7 @@ export class TagRenderingConfigUtils {
|
|||
clone.mappings?.map((m) => {
|
||||
const mapping = {
|
||||
...m,
|
||||
priorityIf: m.priorityIf ?? TagUtils.Tag("id~*")
|
||||
priorityIf: m.priorityIf ?? TagUtils.Tag("id~*"),
|
||||
}
|
||||
if (m.if.usedKeys().indexOf("nobrand") < 0) {
|
||||
// Erase 'nobrand=yes', unless this option explicitly sets it
|
||||
|
|
|
|||
|
|
@ -98,10 +98,10 @@ export default class ThemeConfig implements ThemeInformation {
|
|||
public readonly enableCache: boolean
|
||||
|
||||
public readonly popups: Readonly<{
|
||||
id: string,
|
||||
dismissible?: boolean,
|
||||
condition: TagsFilter,
|
||||
title: TagRenderingConfig,
|
||||
id: string
|
||||
dismissible?: boolean
|
||||
condition: TagsFilter
|
||||
title: TagRenderingConfig
|
||||
body: TagRenderingConfig[]
|
||||
}>[]
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ export default class ThemeConfig implements ThemeInformation {
|
|||
icon: "./assets/svg/pop-out.svg",
|
||||
href: "https://{basepath}/{theme}.html?lat={lat}&lon={lon}&z={zoom}&language={language}",
|
||||
newTab: true,
|
||||
requirements: ["iframe", "no-welcome-message"]
|
||||
requirements: ["iframe", "no-welcome-message"],
|
||||
},
|
||||
context + ".extraLink"
|
||||
)
|
||||
|
|
@ -213,7 +213,7 @@ export default class ThemeConfig implements ThemeInformation {
|
|||
this.popups = (json.popup ?? []).map((p, i) => {
|
||||
const ctx = context + ".popup." + i
|
||||
if (!p.id) {
|
||||
throw (ctx + ": an id is required")
|
||||
throw ctx + ": an id is required"
|
||||
}
|
||||
const body: TagRenderingConfigJson[] = Array.isArray(p.body) ? p.body : [p.body]
|
||||
return {
|
||||
|
|
@ -221,7 +221,7 @@ export default class ThemeConfig implements ThemeInformation {
|
|||
dismissible: p.dismissible ?? false,
|
||||
condition: TagUtils.Tag(p.condition),
|
||||
title: new TagRenderingConfig(p.title, ctx + ".title"),
|
||||
body: body.map((body, i) => new TagRenderingConfig(body, ctx + ".body." + i))
|
||||
body: body.map((body, i) => new TagRenderingConfig(body, ctx + ".body." + i)),
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -378,7 +378,7 @@ export default class ThemeConfig implements ThemeInformation {
|
|||
// The 'favourite'-layer contains pretty much all images as it bundles all layers, so we exclude it
|
||||
const jsonNoFavourites = {
|
||||
...json,
|
||||
layers: json.layers.filter((l) => l["id"] !== "favourite")
|
||||
layers: json.layers.filter((l) => l["id"] !== "favourite"),
|
||||
}
|
||||
const usedImages = jsonNoFavourites._usedImages
|
||||
usedImages.sort()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue