Merge master
This commit is contained in:
commit
36caf511cf
6 changed files with 286 additions and 7 deletions
|
@ -31,16 +31,22 @@ export default class SharedTagRenderings {
|
||||||
|
|
||||||
if (!iconsOnly) {
|
if (!iconsOnly) {
|
||||||
for (const key in questions) {
|
for (const key in questions) {
|
||||||
|
if(key === "id"){
|
||||||
|
continue
|
||||||
|
}
|
||||||
dict.set(key, <TagRenderingConfigJson>questions[key])
|
dict.set(key, <TagRenderingConfigJson>questions[key])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const key in icons) {
|
for (const key in icons) {
|
||||||
|
if(key === "id"){
|
||||||
|
continue
|
||||||
|
}
|
||||||
dict.set(key, <TagRenderingConfigJson>icons[key])
|
dict.set(key, <TagRenderingConfigJson>icons[key])
|
||||||
}
|
}
|
||||||
|
|
||||||
dict.forEach((value, key) => {
|
dict.forEach((value, key) => {
|
||||||
if(key === "id"){
|
if(key === "id"){
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
value.id = value.id ?? key;
|
value.id = value.id ?? key;
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {Utils} from "../Utils";
|
||||||
|
|
||||||
export default class Constants {
|
export default class Constants {
|
||||||
|
|
||||||
public static vNumber = "0.15.0-alpha-1";
|
public static vNumber = "0.15.0-alpha-2";
|
||||||
public static ImgurApiKey = '7070e7167f0a25a'
|
public static ImgurApiKey = '7070e7167f0a25a'
|
||||||
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"
|
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import LineRenderingConfigJson from "../Json/LineRenderingConfigJson";
|
||||||
import {LayerConfigJson} from "../Json/LayerConfigJson";
|
import {LayerConfigJson} from "../Json/LayerConfigJson";
|
||||||
import Constants from "../../Constants";
|
import Constants from "../../Constants";
|
||||||
import {DesugaringContext, DesugaringStep, Fuse, OnEvery} from "./Conversion";
|
import {DesugaringContext, DesugaringStep, Fuse, OnEvery} from "./Conversion";
|
||||||
|
import {ApplyOverrideAll} from "./ApplyOverrideAll";
|
||||||
|
|
||||||
|
|
||||||
export class UpdateLegacyLayer extends DesugaringStep<LayerConfigJson | string | { builtin, override }> {
|
export class UpdateLegacyLayer extends DesugaringStep<LayerConfigJson | string | { builtin, override }> {
|
||||||
|
@ -395,3 +396,240 @@ export class ValidateThemeAndLayers extends Fuse<LayoutConfigJson> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> {
|
||||||
|
constructor() {
|
||||||
|
super("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"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CalculateDependencies(alreadyLoaded: LayerConfigJson[], allKnownLayers: Map<string, LayerConfigJson>, themeId: string): LayerConfigJson[] {
|
||||||
|
const dependenciesToAdd: LayerConfigJson[] = []
|
||||||
|
const loadedLayerIds: Set<string> = new Set<string>(alreadyLoaded.map(l => l.id));
|
||||||
|
|
||||||
|
// Verify cross-dependencies
|
||||||
|
let unmetDependencies: { neededLayer: string, neededBy: string, reason: string, context?: string }[] = []
|
||||||
|
do {
|
||||||
|
const dependencies: { neededLayer: string, reason: string, context?: string, neededBy: string }[] = []
|
||||||
|
|
||||||
|
for (const layerConfig of alreadyLoaded) {
|
||||||
|
const layerDeps = DependencyCalculator.getLayerDependencies(new LayerConfig(layerConfig))
|
||||||
|
dependencies.push(...layerDeps)
|
||||||
|
}
|
||||||
|
|
||||||
|
// During the generate script, builtin layers are verified but not loaded - so we have to add them manually here
|
||||||
|
// Their existance is checked elsewhere, so this is fine
|
||||||
|
unmetDependencies = dependencies.filter(dep => !loadedLayerIds.has(dep.neededLayer))
|
||||||
|
for (const unmetDependency of unmetDependencies) {
|
||||||
|
if (loadedLayerIds.has(unmetDependency.neededLayer)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const dep = allKnownLayers.get(unmetDependency.neededLayer)
|
||||||
|
if (dep === undefined) {
|
||||||
|
const message =
|
||||||
|
["Loading a dependency failed: layer " + unmetDependency.neededLayer + " is not found, neither as layer of " + themeId + " nor as builtin layer.",
|
||||||
|
"This layer is needed by " + unmetDependency.neededBy,
|
||||||
|
unmetDependency.reason + " (at " + unmetDependency.context + ")",
|
||||||
|
"Loaded layers are: " + alreadyLoaded.map(l => l.id).join(",")
|
||||||
|
|
||||||
|
]
|
||||||
|
throw message.join("\n\t");
|
||||||
|
}
|
||||||
|
dependenciesToAdd.unshift(dep)
|
||||||
|
loadedLayerIds.add(dep.id);
|
||||||
|
unmetDependencies = unmetDependencies.filter(d => d.neededLayer !== unmetDependency.neededLayer)
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (unmetDependencies.length > 0)
|
||||||
|
|
||||||
|
return dependenciesToAdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
convert(state: DesugaringContext, theme: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } {
|
||||||
|
const allKnownLayers: Map<string, LayerConfigJson> = state.sharedLayers;
|
||||||
|
const knownTagRenderings: Map<string, TagRenderingConfigJson> = state.tagRenderings;
|
||||||
|
const errors = [];
|
||||||
|
const warnings = [];
|
||||||
|
const layers: LayerConfigJson[] = <LayerConfigJson[]> theme.layers; // Layers should be expanded at this point
|
||||||
|
|
||||||
|
knownTagRenderings.forEach((value, key) => {
|
||||||
|
value.id = key;
|
||||||
|
})
|
||||||
|
|
||||||
|
const dependencies = AddDependencyLayersToTheme.CalculateDependencies(layers, allKnownLayers, theme.id);
|
||||||
|
if (dependencies.length > 0) {
|
||||||
|
|
||||||
|
warnings.push(context + ": added " + dependencies.map(d => d.id).join(", ") + " to the theme as they are needed")
|
||||||
|
}
|
||||||
|
layers.unshift(...dependencies);
|
||||||
|
|
||||||
|
return {
|
||||||
|
result: {
|
||||||
|
...theme,
|
||||||
|
layers: layers
|
||||||
|
},
|
||||||
|
errors,
|
||||||
|
warnings
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetDefault<T> extends DesugaringStep<T> {
|
||||||
|
private readonly value: any;
|
||||||
|
private readonly key: string;
|
||||||
|
private readonly _overrideEmptyString: boolean;
|
||||||
|
|
||||||
|
constructor(key: string, value: any, overrideEmptyString = false) {
|
||||||
|
super("Sets " + key + " to a default value if undefined");
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
this._overrideEmptyString = overrideEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
convert(state: DesugaringContext, json: T, context: string): { result: T; errors: string[]; warnings: string[] } {
|
||||||
|
if (json[this.key] === undefined || (json[this.key] === "" && this._overrideEmptyString)) {
|
||||||
|
json = {...json}
|
||||||
|
json[this.key] = this.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
errors: [], warnings: [],
|
||||||
|
result: json
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PrepareLayer extends Fuse<LayerConfigJson> {
|
||||||
|
constructor() {
|
||||||
|
super(
|
||||||
|
"Fully prepares and expands a layer for the LayerConfig.",
|
||||||
|
new OnEveryConcat("tagRenderings", new ExpandGroupRewrite()),
|
||||||
|
new OnEveryConcat("tagRenderings", new ExpandTagRendering()),
|
||||||
|
new SetDefault("titleIcons", ["defaults"]),
|
||||||
|
new OnEveryConcat("titleIcons", new ExpandTagRendering())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfigJson[]> {
|
||||||
|
constructor() {
|
||||||
|
super("Converts the identifier of a builtin layer into the actual layer, or converts a 'builtin' syntax with override in the fully expanded form", []);
|
||||||
|
}
|
||||||
|
|
||||||
|
convert(state: DesugaringContext, json: string | LayerConfigJson, context: string): { result: LayerConfigJson[]; errors: string[]; warnings: string[] } {
|
||||||
|
const errors = []
|
||||||
|
const warnings = []
|
||||||
|
if (typeof json === "string") {
|
||||||
|
const found = state.sharedLayers.get(json)
|
||||||
|
if (found === undefined) {
|
||||||
|
return {
|
||||||
|
result: null,
|
||||||
|
errors: [context + ": The layer with name " + json + " was not found as a builtin layer"],
|
||||||
|
warnings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
result: [found],
|
||||||
|
errors, warnings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json["builtin"] !== undefined) {
|
||||||
|
let names = json["builtin"]
|
||||||
|
if (typeof names === "string") {
|
||||||
|
names = [names]
|
||||||
|
}
|
||||||
|
const layers = []
|
||||||
|
for (const name of names) {
|
||||||
|
const found = Utils.Clone(state.sharedLayers.get(name))
|
||||||
|
if (found === undefined) {
|
||||||
|
errors.push(context + ": The layer with name " + json + " was not found as a builtin layer")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (json["override"]["tagRenderings"] !== undefined && (found["tagRenderings"] ?? []).length > 0) {
|
||||||
|
errors.push(`At ${context}: when overriding a layer, an override is not allowed to override into tagRenderings. Use "+tagRenderings" or "tagRenderings+" instead to prepend or append some questions.`)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Utils.Merge(json["override"], found);
|
||||||
|
layers.push(found)
|
||||||
|
} catch (e) {
|
||||||
|
errors.push(`At ${context}: could not apply an override due to: ${e}.\nThe override is: ${JSON.stringify(json["override"],)}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
result: layers,
|
||||||
|
errors, warnings
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
result: [json],
|
||||||
|
errors, warnings
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class AddDefaultLayers extends DesugaringStep<LayoutConfigJson> {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super("Adds the default layers, namely: " + Constants.added_by_default.join(", "), ["layers"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } {
|
||||||
|
const errors = []
|
||||||
|
const warnings = []
|
||||||
|
json.layers = [...json.layers]
|
||||||
|
|
||||||
|
if (json.id === "personal") {
|
||||||
|
json.layers = []
|
||||||
|
for (const publicLayer of AllKnownLayouts.AllPublicLayers()) {
|
||||||
|
const id = publicLayer.id
|
||||||
|
const config = state.sharedLayers.get(id)
|
||||||
|
if(Constants.added_by_default.indexOf(id) >= 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(config === undefined){
|
||||||
|
// This is a layer which is coded within a public theme, not as separate .json
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
json.layers.push(config)
|
||||||
|
}
|
||||||
|
const publicIds = AllKnownLayouts.AllPublicLayers().map(l => l.id)
|
||||||
|
publicIds.map(id => state.sharedLayers.get(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const layerName of Constants.added_by_default) {
|
||||||
|
const v = state.sharedLayers.get(layerName)
|
||||||
|
if (v === undefined) {
|
||||||
|
errors.push("Default layer " + layerName + " not found")
|
||||||
|
}
|
||||||
|
json.layers.push(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
result: json,
|
||||||
|
errors,
|
||||||
|
warnings
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PrepareTheme extends Fuse<LayoutConfigJson> {
|
||||||
|
constructor() {
|
||||||
|
super(
|
||||||
|
"Fully prepares and expands a theme",
|
||||||
|
new OnEveryConcat("layers", new SubstituteLayer()),
|
||||||
|
new SetDefault("socialImage", "assets/SocialImage.png", true),
|
||||||
|
new OnEvery("layers", new PrepareLayer()),
|
||||||
|
new ApplyOverrideAll(),
|
||||||
|
new AddDefaultLayers(),
|
||||||
|
|
||||||
|
new AddDependencyLayersToTheme(),
|
||||||
|
new OnEvery("layers", new AddMiniMap())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>>>>>> master
|
||||||
|
|
|
@ -225,6 +225,37 @@ export class AddMiniMap extends DesugaringStep<LayerConfigJson> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ApplyOverrideAll extends DesugaringStep<LayoutConfigJson> {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super("Applies 'overrideAll' onto every 'layer'. The 'overrideAll'-field is removed afterwards", ["overrideAll", "layers"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } {
|
||||||
|
|
||||||
|
const overrideAll = json.overrideAll;
|
||||||
|
if (overrideAll === undefined) {
|
||||||
|
return {result: json, warnings: [], errors: []}
|
||||||
|
}
|
||||||
|
|
||||||
|
json = {...json}
|
||||||
|
|
||||||
|
delete json.overrideAll
|
||||||
|
const newLayers = []
|
||||||
|
for (let layer of json.layers) {
|
||||||
|
layer = {...<LayerConfigJson>layer}
|
||||||
|
Utils.Merge(overrideAll, layer)
|
||||||
|
newLayers.push(layer)
|
||||||
|
}
|
||||||
|
json.layers = newLayers
|
||||||
|
|
||||||
|
|
||||||
|
return {result: json, warnings: [], errors: []};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> {
|
class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("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"]);
|
super("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"]);
|
||||||
|
@ -306,11 +337,13 @@ export class PrepareTheme extends Fuse<LayoutConfigJson> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(
|
super(
|
||||||
"Fully prepares and expands a theme",
|
"Fully prepares and expands a theme",
|
||||||
|
|
||||||
new OnEveryConcat("layers", new SubstituteLayer()),
|
new OnEveryConcat("layers", new SubstituteLayer()),
|
||||||
new SetDefault("socialImage", "assets/SocialImage.png", true),
|
new SetDefault("socialImage", "assets/SocialImage.png", true),
|
||||||
|
new OnEvery("layers", new PrepareLayer()),
|
||||||
|
new ApplyOverrideAll(),
|
||||||
new AddDefaultLayers(),
|
new AddDefaultLayers(),
|
||||||
new AddDependencyLayersToTheme(),
|
new AddDependencyLayersToTheme(),
|
||||||
new OnEvery("layers", new PrepareLayer()),
|
|
||||||
new AddImportLayers(),
|
new AddImportLayers(),
|
||||||
new OnEvery("layers", new AddMiniMap())
|
new OnEvery("layers", new AddMiniMap())
|
||||||
);
|
);
|
||||||
|
|
|
@ -277,11 +277,10 @@
|
||||||
"render": "<iframe style='width: 100%; height: 300px' src=\"https://www.youtube-nocookie.com/embed/{_video:id}\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
|
"render": "<iframe style='width: 100%; height: 300px' src=\"https://www.youtube-nocookie.com/embed/{_video:id}\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"+iconOverlays": [
|
"+iconBadges": [
|
||||||
{
|
{
|
||||||
"if": "_video:id~*",
|
"if": "_video:id~*",
|
||||||
"then": "./assets/themes/speelplekken/youtube.svg",
|
"then": "./assets/themes/speelplekken/youtube.svg"
|
||||||
"badge": true
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"isShown": {
|
"isShown": {
|
||||||
|
|
|
@ -72,7 +72,7 @@ class LayerOverviewUtils {
|
||||||
const dict = new Map<string, TagRenderingConfigJson>();
|
const dict = new Map<string, TagRenderingConfigJson>();
|
||||||
|
|
||||||
for (const key in questions["default"]) {
|
for (const key in questions["default"]) {
|
||||||
if(key==="id"){
|
if(key === "id"){
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
questions[key].id = key;
|
questions[key].id = key;
|
||||||
|
@ -90,6 +90,9 @@ class LayerOverviewUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
dict.forEach((value, key) => {
|
dict.forEach((value, key) => {
|
||||||
|
if(key === "id"){
|
||||||
|
return
|
||||||
|
}
|
||||||
value.id = value.id ?? key;
|
value.id = value.id ?? key;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue