More validation and fixes

This commit is contained in:
pietervdvn 2021-04-10 03:50:44 +02:00
parent f10e7f008f
commit 4766f8bbde
13 changed files with 192 additions and 207 deletions

View File

@ -1,90 +1,35 @@
import * as drinkingWater from "../assets/layers/drinking_water/drinking_water.json";
import * as ghostbikes from "../assets/layers/ghost_bike/ghost_bike.json"
import * as viewpoint from "../assets/layers/viewpoint/viewpoint.json"
import * as bike_parking from "../assets/layers/bike_parking/bike_parking.json"
import * as bike_repair_station from "../assets/layers/bike_repair_station/bike_repair_station.json"
import * as birdhides from "../assets/layers/bird_hide/birdhides.json"
import * as nature_reserve from "../assets/layers/nature_reserve/nature_reserve.json"
import * as bike_cafes from "../assets/layers/bike_cafe/bike_cafes.json"
import * as bike_monitoring_station from "../assets/layers/bike_monitoring_station/bike_monitoring_station.json"
import * as cycling_themed_objects from "../assets/layers/cycling_themed_object/cycling_themed_objects.json"
import * as bike_shops from "../assets/layers/bike_shop/bike_shop.json"
import * as bike_cleaning from "../assets/layers/bike_cleaning/bike_cleaning.json"
import * as bicycle_library from "../assets/layers/bicycle_library/bicycle_library.json"
import * as bicycle_tube_vending_machine from "../assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json"
import * as maps from "../assets/layers/maps/maps.json"
import * as information_boards from "../assets/layers/information_board/information_board.json"
import * as direction from "../assets/layers/direction/direction.json"
import * as surveillance_camera from "../assets/layers/surveillance_cameras/surveillance_cameras.json"
import * as toilets from "../assets/layers/toilets/toilets.json"
import * as bookcases from "../assets/layers/public_bookcases/public_bookcases.json"
import * as tree_nodes from "../assets/layers/trees/tree_nodes.json"
import * as benches from "../assets/layers/benches/benches.json"
import * as benches_at_pt from "../assets/layers/benches/benches_at_pt.json"
import * as picnic_tables from "../assets/layers/benches/picnic_tables.json"
import * as play_forest from "../assets/layers/play_forest/play_forest.json"
import * as playground from "../assets/layers/playground/playground.json"
import * as sport_pitch from "../assets/layers/sport_pitch/sport_pitch.json"
import * as slow_roads from "../assets/layers/slow_roads/slow_roads.json"
import LayerConfig from "./JSON/LayerConfig";
import {LayerConfigJson} from "./JSON/LayerConfigJson";
import * as grass_in_parks from "../assets/layers/village_green/grass_in_parks.json"
import * as village_green from "../assets/layers/village_green/village_green.json"
import * as known_layers from "../assets/generated/known_layers_and_themes.json"
import {Utils} from "../Utils";
export default class AllKnownLayers {
private static sharedLayersListRaw : LayerConfigJson[] = [
drinkingWater,
ghostbikes,
viewpoint,
bike_parking,
bike_repair_station,
bike_monitoring_station,
birdhides,
nature_reserve,
bike_cafes,
bicycle_library,
cycling_themed_objects,
bike_shops,
bike_cleaning,
bicycle_tube_vending_machine,
maps,
direction,
information_boards,
toilets,
bookcases,
surveillance_camera,
tree_nodes,
benches,
benches_at_pt,
picnic_tables,
play_forest,
playground,
sport_pitch,
slow_roads,
grass_in_parks,
village_green
];
// Must be below the list...
public static sharedLayers: Map<string, LayerConfig> = AllKnownLayers.getSharedLayers();
public static sharedLayersJson: Map<string, any> = AllKnownLayers.getSharedLayersJson();
private static sharedLayersListRaw: LayerConfigJson[] = known_layers.layers;
private static getSharedLayers(): Map<string, LayerConfig> {
const sharedLayers = new Map<string, LayerConfig>();
for (const layer of AllKnownLayers.sharedLayersListRaw) {
const parsed = new LayerConfig(layer, "shared_layers")
sharedLayers.set(layer.id, parsed);
sharedLayers[layer.id] = parsed;
for (const layer of known_layers.layers) {
try {
const parsed = new LayerConfig(layer, "shared_layers")
sharedLayers.set(layer.id, parsed);
sharedLayers[layer.id] = parsed;
} catch (e) {
if (!Utils.runningFromConsole) {
console.error("CRITICAL: Could not parse a layer configuration!", layer.id, " due to", e)
}
}
}
return sharedLayers;
}
private static getSharedLayersJson(): Map<string, any> {
const sharedLayers = new Map<string, any>();
for (const layer of AllKnownLayers.sharedLayersListRaw) {
for (const layer of known_layers.layers) {
sharedLayers.set(layer.id, layer);
sharedLayers[layer.id] = layer;
}

View File

@ -1,74 +1,29 @@
import * as bookcases from "../assets/themes/bookcases/Bookcases.json";
import * as aed from "../assets/themes/aed/aed.json";
import * as toilets from "../assets/themes/toilets/toilets.json";
import * as artworks from "../assets/themes/artwork/artwork.json";
import * as cyclestreets from "../assets/themes/cyclestreets/cyclestreets.json";
import * as ghostbikes from "../assets/themes/ghostbikes/ghostbikes.json"
import * as cyclofix from "../assets/themes/cyclofix/cyclofix.json"
import * as buurtnatuur from "../assets/themes/buurtnatuur/buurtnatuur.json"
import * as nature from "../assets/themes/nature/nature.json"
import * as maps from "../assets/themes/maps/maps.json"
import * as shops from "../assets/themes/shops/shops.json"
import * as bike_monitoring_stations from "../assets/themes/bike_monitoring_station/bike_monitoring_stations.json"
import * as fritures from "../assets/themes/fritures/fritures.json"
import * as benches from "../assets/themes/benches/benches.json";
import * as charging_stations from "../assets/themes/charging_stations/charging_stations.json"
import * as widths from "../assets/themes/widths/width.json"
import * as drinking_water from "../assets/themes/drinking_water/drinking_water.json"
import * as climbing from "../assets/themes/climbing/climbing.json"
import * as surveillance_cameras from "../assets/themes/surveillance_cameras/surveillance_cameras.json"
import * as trees from "../assets/themes/trees/trees.json"
import * as personal from "../assets/themes/personalLayout/personalLayout.json"
import * as playgrounds from "../assets/themes/playgrounds/playgrounds.json"
import * as bicycle_lib from "../assets/themes/bicycle_library/bicycle_library.json"
import * as campersites from "../assets/themes/campersites/campersites.json"
import * as play_forests from "../assets/themes/play_forests/play_forests.json"
import * as speelplekken from "../assets/themes/speelplekken/speelplekken.json"
import * as sport_pitches from "../assets/themes/sport_pitches/sport_pitches.json"
import * as grb from "../assets/themes/grb.json"
import * as facadegardens from "../assets/themes/facadegardens/facadegardens.json"
import LayerConfig from "./JSON/LayerConfig";
import LayoutConfig from "./JSON/LayoutConfig";
import AllKnownLayers from "./AllKnownLayers";
import * as known_themes from "../assets/generated/known_layers_and_themes.json"
import {LayoutConfigJson} from "./JSON/LayoutConfigJson";
export class AllKnownLayouts {
public static allLayers: Map<string, LayerConfig> = undefined;
public static layoutsList: LayoutConfig[] = [
new LayoutConfig(personal),
AllKnownLayouts.GenerateCycloFix(),
new LayoutConfig(aed),
new LayoutConfig(bookcases),
new LayoutConfig(toilets),
new LayoutConfig(artworks),
new LayoutConfig(ghostbikes),
new LayoutConfig(shops),
new LayoutConfig(drinking_water),
new LayoutConfig(nature),
new LayoutConfig(cyclestreets),
new LayoutConfig(bicycle_lib),
new LayoutConfig(maps),
new LayoutConfig(fritures),
new LayoutConfig(benches),
new LayoutConfig(charging_stations),
new LayoutConfig(widths),
new LayoutConfig(buurtnatuur),
new LayoutConfig(bike_monitoring_stations),
new LayoutConfig(surveillance_cameras),
new LayoutConfig(climbing),
new LayoutConfig(playgrounds),
new LayoutConfig(trees),
new LayoutConfig(campersites),
new LayoutConfig(play_forests),
new LayoutConfig(speelplekken),
new LayoutConfig(sport_pitches),
new LayoutConfig(grb),
new LayoutConfig(facadegardens)
];
public static allSets: Map<string, LayoutConfig> = AllKnownLayouts.AllLayouts();
private static GenerateCycloFix(): LayoutConfig {
const layout = new LayoutConfig(cyclofix)
public static allKnownLayouts: Map<string, LayoutConfig> = AllKnownLayouts.AllLayouts();
public static layoutsList: LayoutConfig[] = AllKnownLayouts.GenerateOrderedList(AllKnownLayouts.allKnownLayouts);
private static GenerateOrderedList(allKnownLayouts: Map<string, LayoutConfig>): LayoutConfig[] {
const keys = ["personal", "cyclofix", "bookcases", "toilets", "aed"]
const list = []
for (const key of keys) {
list.push(allKnownLayouts.get(key))
}
allKnownLayouts.forEach((layout, key) => {
if (keys.indexOf(key) < 0) {
list.push(layout)
}
})
return list;
}
private static AddGhostBikes(layout: LayoutConfig): LayoutConfig {
const now = new Date();
const m = now.getMonth() + 1;
const day = new Date().getDate() + 1;
@ -86,8 +41,15 @@ export class AllKnownLayouts {
}
private static AllLayouts(): Map<string, LayoutConfig> {
this.allLayers = new Map<string, LayerConfig>();
for (const layout of this.layoutsList) {
const dict: Map<string, LayoutConfig> = new Map();
for (const layoutConfigJson of known_themes.themes) {
const layout = new LayoutConfig(layoutConfigJson, true)
if (layout.id === "cyclofix") {
AllKnownLayouts.AddGhostBikes(layout)
}
dict.set(layout.id, layout)
for (let i = 0; i < layout.layers.length; i++) {
let layer = layout.layers[i];
if (typeof (layer) === "string") {
@ -98,20 +60,9 @@ export class AllKnownLayouts {
}
}
if (this.allLayers[layer.id] !== undefined) {
continue;
}
this.allLayers[layer.id] = layer;
this.allLayers[layer.id.toLowerCase()] = layer;
}
}
const allSets: Map<string, LayoutConfig> = new Map();
for (const layout of this.layoutsList) {
allSets[layout.id] = layout;
allSets[layout.id.toLowerCase()] = layout;
}
return allSets;
return dict;
}
}

View File

@ -7,6 +7,7 @@ import {TagRenderingConfigJson} from "./TagRenderingConfigJson";
import {Translation} from "../../UI/i18n/Translation";
import Img from "../../UI/Base/Img";
import Svg from "../../Svg";
import {Utils} from "../../Utils";
import Combine from "../../UI/Base/Combine";
import {VariableUiElement} from "../../UI/Base/VariableUIElement";
@ -18,7 +19,6 @@ import SourceConfig from "./SourceConfig";
import {TagsFilter} from "../../Logic/Tags/TagsFilter";
import {Tag} from "../../Logic/Tags/Tag";
import SubstitutingTag from "../../Logic/Tags/SubstitutingTag";
export default class LayerConfig {

View File

@ -90,6 +90,9 @@ export default class TagRenderingConfig {
this.multiAnswer = json.multiAnswer ?? false
if (json.mappings) {
if(!Array.isArray(json.mappings)){
throw "Tagrendering has a 'mappings'-object, but expected a list ("+context+")"
}
this.mappings = json.mappings.map((mapping, i) => {

View File

@ -34,7 +34,6 @@ export default class AttributionPanel extends Combine {
}
private static IconAttribution(iconPath: string) {
console.log("Attribution panel for ", iconPath)
if (iconPath.startsWith("http")) {
iconPath = "." + new URL(iconPath).pathname;
}

View File

@ -85,16 +85,12 @@ export default class MoreScreen extends UIElement {
const linkButton: UIElement[] = []
for (const k in AllKnownLayouts.allSets) {
const layout: LayoutConfig = AllKnownLayouts.allSets[k];
if (k === personal.id) {
for (const layout of AllKnownLayouts.layoutsList) {
if (layout.id === personal.id) {
if (State.state.osmConnection.userDetails.data.csCount < Constants.userJourney.personalLayoutUnlock) {
continue;
}
}
if (layout.id !== k) {
continue; // This layout was added multiple time due to an uppercase
}
linkButton.push(this.createLinkButton(layout));
}

View File

@ -19,6 +19,9 @@ export class Translation extends UIElement {
let count = 0;
for (const translationsKey in translations) {
count++;
if(typeof(translations[translationsKey]) != "string"){
throw "Error in an object depicting a translation: a non-string object was found. ("+context+")\n You probably put some other section accidentally in the translation"
}
}
this.translations = translations;
if (count === 0) {
@ -134,12 +137,17 @@ export class Translation extends UIElement {
} else {
// We are running this in ts-node (~= nodejs), and can not access document
// So, we fallback to simple regex
const matches = render.match(/<img[^>]+>/g)
if (matches != null) {
const sources = matches.map(img => img.match(/src=("[^"]+"|'[^']+'|[^/ ]+)/))
.filter(match => match != null)
.map(match => match[1].trim().replace(/^['"]/, '').replace(/['"]$/, ''));
allIcons.push(...sources)
try {
const matches = render.match(/<img[^>]+>/g)
if (matches != null) {
const sources = matches.map(img => img.match(/src=("[^"]+"|'[^']+'|[^/ ]+)/))
.filter(match => match != null)
.map(match => match[1].trim().replace(/^['"]/, '').replace(/['"]$/, ''));
allIcons.push(...sources)
}
}catch(e){
console.error("Could not search for images: ", render, this.txt)
throw e
}
}
}

View File

@ -28,11 +28,12 @@
"nl": "Boomgaarden"
},
"minzoom": 12,
"overpassTags": {
"source":{
"osmTags": {
"and": [
"landuse=orchard"
]
},
} },
"title": {
"render": {
"nl": "Boomgaard"
@ -73,11 +74,12 @@
"nl": "Boom"
},
"minzoom": 12,
"overpassTags": {
"source":{
"osmTags": {
"and": [
"natural=tree"
]
},
}},
"title": {
"render": {
"nl": "Boom"

View File

@ -52,7 +52,7 @@ if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
}
// ----------------- SELECT THE RIGHT QUESTSET -----------------
// ----------------- SELECT THE RIGHT Theme -----------------
const path = window.location.pathname.split("/").slice(-1)[0];
@ -64,7 +64,7 @@ if (path !== "index.html" && path !== "") {
console.log("Using layout", defaultLayout);
}
defaultLayout = QueryParameters.GetQueryParameter("layout", defaultLayout, "The layout to load into MapComplete").data;
let layoutToUse: LayoutConfig = AllKnownLayouts.allSets[defaultLayout.toLowerCase()];
let layoutToUse: LayoutConfig = AllKnownLayouts.allKnownLayouts.get(defaultLayout.toLowerCase());
const userLayoutParam = QueryParameters.GetQueryParameter("userlayout", "false");
@ -81,7 +81,7 @@ if (layoutFromBase64.startsWith("http")) {
$.ajax({
url: link,
success: function (data) {
success: (data) => {
try {
const parsed = JSON.parse(data);
@ -121,6 +121,6 @@ if (layoutFromBase64.startsWith("http")) {
.SetStyle("pointer-events: all;")
.AttachTo("topleft-tools");
}
window.addEventListener('contextmenu', function (e) { // Not compatible with IE < 9
window.addEventListener('contextmenu', (e) => { // Not compatible with IE < 9
e.preventDefault();
}, false);

74
package-lock.json generated
View File

@ -4731,6 +4731,11 @@
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
},
"builtin-modules": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
},
"builtin-status-codes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
@ -11611,6 +11616,75 @@
}
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"tslint": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
"integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
"requires": {
"@babel/code-frame": "^7.0.0",
"builtin-modules": "^1.1.1",
"chalk": "^2.3.0",
"commander": "^2.12.1",
"diff": "^4.0.1",
"glob": "^7.1.1",
"js-yaml": "^3.13.1",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.3",
"resolve": "^1.3.2",
"semver": "^5.3.0",
"tslib": "^1.13.0",
"tsutils": "^2.29.0"
},
"dependencies": {
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"tslint-no-circular-imports": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/tslint-no-circular-imports/-/tslint-no-circular-imports-0.7.0.tgz",
"integrity": "sha512-k3wxpeMC4ef40UbpfBVHEHIzKfNZq5/SCtAO1YjGsaNTklo+K53/TWLrym+poA65RJFDiYgYNWvkeIIkJNA0Vw==",
"dev": true
},
"tsutils": {
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
"integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
"requires": {
"tslib": "^1.8.1"
}
},
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",

View File

@ -8,20 +8,23 @@
"main": "index.js",
"scripts": {
"increase-memory": "export NODE_OPTIONS=--max_old_space_size=4096",
"start": "npm run increase-memory && parcel *.html UI/** Logic/** assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*",
"start": "ts-node scripts/generateLayerOverview.ts && npm run increase-memory && parcel *.html UI/** Logic/** assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*",
"test": "ts-node test/Tag.spec.ts && ts-node test/TagQuestion.spec.ts && ts-node test/ImageSearcher.spec.ts && ts-node test/ImageAttribution.spec.ts",
"generate:editor-layer-index": "cd assets/ && wget https://osmlab.github.io/editor-layer-index/imagery.geojson --output-document=editor-layer-index.json",
"generate:images": "ts-node scripts/generateIncludedImages.ts",
"generate:translations": "ts-node scripts/generateTranslations.ts",
"generate:layouts": "ts-node scripts/generateLayouts.ts",
"generate:docs": "ts-node scripts/generateDocs.ts",
"generate:layeroverview": "ts-node scripts/generateLayerOverview.ts",
"generate:licenses": "ts-node scripts/generateLicenseInfo.ts",
"optimize-images": "cd assets/generated/ && find -name '*.png' -exec optipng '{}' \\; && echo 'PNGs are optimized'",
"generate": "npm run generate:images && npm run generate:translations",
"build": "rm -rf dist/ && npm run generate && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*",
"prepare-deploy": "npm run test && npm run generate:editor-layer-index && npm run generate:layouts && npm run generate && npm run build && rm -rf .cache && npm run generate:docs",
"prepare-deploy": "npm run test && npm run generate:editor-layer-index && npm run generate:layouts && npm run generate:layeroverview && npm run generate && npm run build && rm -rf .cache && npm run generate:docs",
"deploy:staging": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/Staging/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/Staging/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean",
"deploy:pietervdvn": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/MapComplete/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/MapComplete/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean",
"deploy:production": "rm -rf ./assets/generated && npm run prepare-deploy && npm run optimize-images && rm -rf /home/pietervdvn/git/mapcomplete.github.io/* && cp -r dist/* /home/pietervdvn/git/mapcomplete.github.io/ && cd /home/pietervdvn/git/mapcomplete.github.io/ && echo \"mapcomplete.osm.be\" > CNAME && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean",
"lint": "tslint --project . -c tslint.json '**.ts' ",
"clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(index\\|land\\|test\\|preferences\\|customGenerator\\).html\" | xargs rm) && rm *.webmanifest"
},
"keywords": [
@ -64,6 +67,7 @@
"sharp": "^0.27.0",
"slick-carousel": "^1.8.1",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2",
"tslint": "^6.1.3",
"turf": "^3.0.14"
},
"devDependencies": {
@ -76,6 +80,7 @@
"read-file": "^0.2.0",
"ts-node": "^9.0.0",
"ts-node-dev": "^1.0.0-pre.63",
"tslint-no-circular-imports": "^0.7.0",
"turndown": "^7.0.0",
"typescript": "^3.9.7",
"write-file": "^1.0.0"

View File

@ -17,9 +17,7 @@ function createTable(preferences: any) {
}
rendered = true;
const prefs = [];
console.log(preferences);
for (const key in preferences) {
console.log(key)
const pref = connection.GetPreference(key, "");
let value: UIElement = new FixedUiElement(pref.data);
@ -36,19 +34,17 @@ function createTable(preferences: any) {
"</td><td>",
new Button("delete", () => pref.setData("")),
"</td><td>",
value,
value,
"</td></tr>"
];
prefs.push(...c);
}
const el = new Combine(
new Combine(
["<table>",
...prefs,
"</table>"]
); // .AttachTo("maindiv");
console.log(el.InnerRender())
el.AttachTo("maindiv");
).AttachTo("maindiv");
}
connection.preferencesHandler.preferences.addCallback((prefs) => createTable(prefs))

View File

@ -8,6 +8,7 @@ import {error} from "util";
import * as licenses from "../assets/generated/license_info.json"
import SmallLicense from "../Models/smallLicense";
import LayoutConfig from "../Customizations/JSON/LayoutConfig";
import {LayerConfigJson} from "../Customizations/JSON/LayerConfigJson";
// This scripts scans 'assets/layers/*.json' for layer definition files and 'assets/themes/*.json' for theme definition files.
// It spits out an overview of those to be used to load them
@ -28,7 +29,7 @@ const layerFiles = ScriptUtils.readDirRecSync("./assets/layers")
console.error("Could not parse file ", path, "due to ", e)
}
})
const themeFiles : any[] = ScriptUtils.readDirRecSync("./assets/themes")
const themeFiles: any[] = ScriptUtils.readDirRecSync("./assets/themes")
.filter(path => path.indexOf(".json") > 0)
.filter(path => path.indexOf("license_info.json") < 0)
.map(path => {
@ -49,57 +50,62 @@ for (const i in licenses) {
}
const knownPaths = new Set<string>(licensePaths)
function validateLayer(layer: LayerConfig, context?:string) : number{
function validateLayer(layerJson: LayerConfigJson, context?: string): number {
let errorCount = 0;
const images = Array.from(layer.ExtractImages())
const remoteImages = images.filter(img => img.indexOf("http") == 0)
for (const remoteImage of remoteImages) {
console.error("Found a remote image:", remoteImage, "in layer", layer.id)
if (layerJson["overpassTags"] !== undefined) {
errorCount++
console.error("CRIT! Layer ", layerJson.id, "still uses the old 'overpassTags'-format. Please use 'source: {osmTags: <tags>}' instead")
}
for (const image of images) {
if (!knownPaths.has(image)) {
console.error("Image with path", image, "not found or not attributed; it is used in", layer.id, context === undefined ? "" : ` in a layer defined in the theme ${context}`)
try {
const layer = new LayerConfig(layerJson, "test", true)
const images = Array.from(layer.ExtractImages())
const remoteImages = images.filter(img => img.indexOf("http") == 0)
for (const remoteImage of remoteImages) {
console.error("Found a remote image:", remoteImage, "in layer", layer.id)
errorCount++
}
for (const image of images) {
if (!knownPaths.has(image)) {
console.error("Image with path", image, "not found or not attributed; it is used in", layer.id, context === undefined ? "" : ` in a layer defined in the theme ${context}`)
errorCount++
}
}
} catch (e) {
console.error("Layer ", layerJson.id ?? JSON.stringify(layerJson).substring(0, 50), " is invalid: ", e)
return 1
}
return errorCount
}
let layerErrorCount = 0
const knownLayerIds = new Set<string>();
for (const layerFile of layerFiles) {
knownLayerIds.add(layerFile.id)
try {
const layer = new LayerConfig(layerFile, "test", true)
layerErrorCount += validateLayer(layer)
} catch (e) {
console.error("Layer ", layerFile.id, " is invalid: ", e)
layerErrorCount++
}
if (layerFile.overpassTags !== undefined) {
layerErrorCount++
console.warn("Layer ", layerFile.id, "still uses the old 'overpassTags'-format. Please use 'source: {osmTags: <tags>}' instead")
}
layerErrorCount += validateLayer(layerFile)
}
let themeErrorCount = 0
for (const themeFile of themeFiles) {
for (const layer of themeFile.layers) {
if(typeof layer === "string"){
if(!knownLayerIds.has(layer)){
if (typeof layer === "string") {
if (!knownLayerIds.has(layer)) {
console.error("Unknown layer id: ", layer)
themeErrorCount++
}
}else if(layer.builtin === undefined){
// layer.builtin contains layer overrides - we can skip those
layerErrorCount += validateLayer(layer, themeFile.id)
}
}
themeFile.layers = themeFile.layers.filter(l => typeof l != "string")
try {
const layout = new LayoutConfig(themeFile, true, "test")
for (const layer of layout.layers) {
layerErrorCount += validateLayer(layer, layout.id)
const theme = new LayoutConfig(themeFile, true, "test")
if(theme.id !== theme.id.toLowerCase()){
console.error("Theme ids should be in lowercase, but it is ", theme.id)
}
} catch (e) {
console.error("Could not parse theme", themeFile["id"], "due to", e)
@ -107,4 +113,4 @@ for (const themeFile of themeFiles) {
}
}
console.log("Found ", layerErrorCount, "errors in the layers; "+themeErrorCount+" errors in the themes")
console.log("Found ", layerErrorCount, "errors in the layers; " + themeErrorCount + " errors in the themes")