diff --git a/scripts/generateDocs.ts b/scripts/generateDocs.ts index 97dee3ff0..767986a6a 100644 --- a/scripts/generateDocs.ts +++ b/scripts/generateDocs.ts @@ -165,7 +165,7 @@ export class GenerateDocs extends Script { this.generateForTheme(theme) }) - this.WriteFile("./Docs/SpecialRenderings.md", SpecialVisualizations.HelpMessage(), [ + this.WriteMarkdownFile("./Docs/SpecialRenderings.md", SpecialVisualizations.HelpMessage(), [ "src/UI/SpecialVisualizations.ts" ]) this.WriteFile( @@ -244,7 +244,7 @@ export class GenerateDocs extends Script { let md = markdown if (options?.noTableOfContents !== false) { - md = TableOfContents.insertTocIntoMd(md) + md = TableOfContents.insertTocIntoMd(md) } md.replace(/\n\n\n+/g, "\n\n") diff --git a/src/Logic/Osm/OsmConnection.ts b/src/Logic/Osm/OsmConnection.ts index d7fae19cb..580521097 100644 --- a/src/Logic/Osm/OsmConnection.ts +++ b/src/Logic/Osm/OsmConnection.ts @@ -143,7 +143,7 @@ export class OsmConnection { options.oauth_token.setData(undefined) } - if (this.auth.authenticated() && options.attemptLogin !== false) { + if (!Utils.runningFromConsole && this.auth.authenticated() && options.attemptLogin !== false) { this.AttemptLogin() } else { console.log("Not authenticated") diff --git a/src/UI/Base/TableOfContents.ts b/src/UI/Base/TableOfContents.ts index 14aed6b23..6191390db 100644 --- a/src/UI/Base/TableOfContents.ts +++ b/src/UI/Base/TableOfContents.ts @@ -1,11 +1,8 @@ -import Combine from "./Combine" import BaseUIElement from "../BaseUIElement" -import Title from "./Title" import List from "./List" -import Link from "./Link" import { marked } from "marked" import { parse as parse_html } from "node-html-parser" -import {default as turndown} from "turndown" +import { default as turndown } from "turndown" import { Utils } from "../../Utils" export default class TableOfContents { @@ -56,7 +53,7 @@ export default class TableOfContents { const htmlSource = marked.parse(md) const el = parse_html(htmlSource) const structure = TableOfContents.generateStructure(el) - let firstTitle = structure[1] + const firstTitle = structure[1] let minDepth = undefined do { minDepth = Math.min(...structure.map(s => s.depth)) @@ -81,7 +78,7 @@ export default class TableOfContents { let topLevelCount = 0 for (const el of structure) { const depthDiff = el.depth - minDepth - let link = `[${el.title}](#${TableOfContents.asLinkableId(el.title)})` + const link = `[${el.title}](#${TableOfContents.asLinkableId(el.title)})` if (depthDiff === 0) { topLevelCount++ toc += `${topLevelCount}. ${link}\n` @@ -91,16 +88,14 @@ export default class TableOfContents { } const heading = Utils.Times(() => "#", firstTitle.depth) - toc = heading +" Table of contents\n\n"+toc + toc = heading + " Table of contents\n\n" + toc - const original = el.outerHTML - const firstTitleIndex = original.indexOf(firstTitle.el.outerHTML) - const tocHtml = (marked.parse(toc)) - const withToc = original.substring(0, firstTitleIndex) + tocHtml + original.substring(firstTitleIndex) + const firstTitleIndex = md.indexOf(firstTitle.title) - const htmlToMd = new turndown() - return htmlToMd.turndown(withToc) + const intro = md.substring(0, firstTitleIndex) + const splitPoint = intro.lastIndexOf("\n") + return md.substring(0, splitPoint) + toc + md.substring(splitPoint) } diff --git a/src/UI/Popup/AutoApplyButton.ts b/src/UI/Popup/AutoApplyButton.ts index ca565f696..5ca206336 100644 --- a/src/UI/Popup/AutoApplyButton.ts +++ b/src/UI/Popup/AutoApplyButton.ts @@ -216,7 +216,7 @@ class ApplyButton extends UIElement { } export default class AutoApplyButton implements SpecialVisualization { - public readonly docs: BaseUIElement + public readonly docs: string public readonly funcName: string = "auto_apply" public readonly needsUrls = [] @@ -273,7 +273,7 @@ export default class AutoApplyButton implements SpecialVisualization { "Then, use a calculated tag on the host feature to determine the overlapping object ids", "At last, add this component", ]), - ]) + ]).AsMarkdown() } constr( diff --git a/src/UI/SpecialVisualizations.ts b/src/UI/SpecialVisualizations.ts index d2437a527..17a17babf 100644 --- a/src/UI/SpecialVisualizations.ts +++ b/src/UI/SpecialVisualizations.ts @@ -2,11 +2,10 @@ import Combine from "./Base/Combine" import { FixedUiElement } from "./Base/FixedUiElement" import BaseUIElement from "./BaseUIElement" import Title from "./Base/Title" -import Table from "./Base/Table" import { RenderingSpecification, SpecialVisualization, - SpecialVisualizationState, + SpecialVisualizationState } from "./SpecialVisualization" import { HistogramViz } from "./Popup/HistogramViz" import { MinimapViz } from "./Popup/MinimapViz" @@ -96,6 +95,7 @@ import SplitRoadWizard from "./Popup/SplitRoadWizard.svelte" import DynLink from "./Base/DynLink.svelte" import Locale from "./i18n/Locale" import LanguageUtils from "../Utils/LanguageUtils" +import MarkdownUtils from "../Utils/MarkdownUtils" class NearbyImageVis implements SpecialVisualization { // Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests @@ -103,13 +103,13 @@ class NearbyImageVis implements SpecialVisualization { { name: "mode", defaultValue: "closed", - doc: "Either `open` or `closed`. If `open`, then the image carousel will always be shown", + doc: "Either `open` or `closed`. If `open`, then the image carousel will always be shown" }, { name: "readonly", required: false, - doc: "If 'readonly', will not show the 'link'-button", - }, + doc: "If 'readonly', will not show the 'link'-button" + } ] docs = "A component showing nearby images loaded from various online services such as Mapillary. In edit mode and when used on a feature, the user can select an image to add to the feature" @@ -134,7 +134,7 @@ class NearbyImageVis implements SpecialVisualization { lat, feature, layer, - linkable: !readonly, + linkable: !readonly }) } } @@ -148,13 +148,13 @@ class StealViz implements SpecialVisualization { { name: "featureId", doc: "The key of the attribute which contains the id of the feature from which to use the tags", - required: true, + required: true }, { name: "tagRenderingId", doc: "The layer-id and tagRenderingId to render. Can be multiple value if ';'-separated (in which case every value must also contain the layerId, e.g. `layerId.tagRendering0; layerId.tagRendering1`). Note: this can cause layer injection", - required: true, - }, + required: true + } ] needsUrls = [] svelteBased = true @@ -188,7 +188,7 @@ class StealViz implements SpecialVisualization { tags: otherTags, selectedElement: otherFeature, state, - layer, + layer }) ) } @@ -223,12 +223,12 @@ export class QuestionViz implements SpecialVisualization { args = [ { name: "labels", - doc: "One or more ';'-separated labels. If these are given, only questions with these labels will be given. Use `unlabeled` for all questions that don't have an explicit label. If none given, all questions will be shown", + doc: "One or more ';'-separated labels. If these are given, only questions with these labels will be given. Use `unlabeled` for all questions that don't have an explicit label. If none given, all questions will be shown" }, { name: "blacklisted-labels", - doc: "One or more ';'-separated labels of questions which should _not_ be included", - }, + doc: "One or more ';'-separated labels of questions which should _not_ be included" + } ] svelteBased = true @@ -253,7 +253,7 @@ export class QuestionViz implements SpecialVisualization { selectedElement: feature, state, onlyForLabels: labels, - notForLabels: blacklist, + notForLabels: blacklist }).SetClass("w-full") } } @@ -261,38 +261,37 @@ export class QuestionViz implements SpecialVisualization { export default class SpecialVisualizations { public static specialVisualizations: SpecialVisualization[] = SpecialVisualizations.initList() - public static DocumentationFor(viz: string | SpecialVisualization): BaseUIElement | undefined { + public static DocumentationFor(viz: string | SpecialVisualization): string { if (typeof viz === "string") { viz = SpecialVisualizations.specialVisualizations.find((sv) => sv.funcName === viz) } if (viz === undefined) { - return undefined + return "" } - return new Combine([ - new Title(viz.funcName, 3), + const example = viz.example ?? + "`{" + + viz.funcName + + "(" + + viz.args.map((arg) => arg.defaultValue).join(",") + + ")}`" + return [ + "### " + viz.funcName, viz.docs, viz.args.length > 0 - ? new Table( - ["name", "default", "description"], - viz.args.map((arg) => { - let defaultArg = arg.defaultValue ?? "_undefined_" - if (defaultArg == "") { - defaultArg = "_empty string_" - } - return [arg.name, defaultArg, arg.doc] - }) - ) + ? MarkdownUtils.table( + ["name", "default", "description"], + viz.args.map((arg) => { + let defaultArg = arg.defaultValue ?? "_undefined_" + if (defaultArg == "") { + defaultArg = "_empty string_" + } + return [arg.name, defaultArg, arg.doc] + }) + ) : undefined, - new Title("Example usage of " + viz.funcName, 4), - new FixedUiElement( - viz.example ?? - "`{" + - viz.funcName + - "(" + - viz.args.map((arg) => arg.defaultValue).join(",") + - ")}`" - ).SetClass("literal-code"), - ]) + "#### Example usage of " + viz.funcName, + "" + example + "" + ].join("\n\n") } public static constructSpecification( @@ -302,49 +301,48 @@ export default class SpecialVisualizations { return SpecialVisualisationUtils.constructSpecification(template, extraMappings) } - public static HelpMessage() { - const helpTexts = SpecialVisualizations.specialVisualizations.map((viz) => + public static HelpMessage(): string { + const helpTexts: string[] = SpecialVisualizations.specialVisualizations.map((viz) => SpecialVisualizations.DocumentationFor(viz) ) - return new Combine([ - new Combine([ - new Title("Special tag renderings", 1), + const firstPart = new Combine([ + new Title("Special tag renderings", 1), - "In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's.", - "General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_name(args):cssStyle}`. Note that you _do not_ need to use quotes around your arguments, the comma is enough to separate them. This also implies you cannot use a comma in your args", - new Title("Using expanded syntax", 4), - `Instead of using \`{"render": {"en": "{some_special_visualisation(some_arg, some other really long message, more args)} , "nl": "{some_special_visualisation(some_arg, een boodschap in een andere taal, more args)}}\`, one can also write`, - new FixedUiElement( - JSON.stringify( - { - render: { - special: { - type: "some_special_visualisation", - argname: "some_arg", - message: { - en: "some other really long message", - nl: "een boodschap in een andere taal", - }, - other_arg_name: "more args", - }, - before: { - en: "Some text to prefix before the special element (e.g. a title)", - nl: "Een tekst om voor het element te zetten (bv. een titel)", - }, - after: { - en: "Some text to put after the element, e.g. a footer", + "In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's.", + "General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_name(args):cssStyle}`. Note that you _do not_ need to use quotes around your arguments, the comma is enough to separate them. This also implies you cannot use a comma in your args", + new Title("Using expanded syntax", 4), + `Instead of using \`{"render": {"en": "{some_special_visualisation(some_arg, some other really long message, more args)} , "nl": "{some_special_visualisation(some_arg, een boodschap in een andere taal, more args)}}\`, one can also write`, + new FixedUiElement( + JSON.stringify( + { + render: { + special: { + type: "some_special_visualisation", + argname: "some_arg", + message: { + en: "some other really long message", + nl: "een boodschap in een andere taal" }, + other_arg_name: "more args" }, - }, - null, - " " - ) - ).SetClass("code"), - 'In other words: use `{ "before": ..., "after": ..., "special": {"type": ..., "argname": ...argvalue...}`. The args are in the `special` block; an argvalue can be a string, a translation or another value. (Refer to class `RewriteSpecial` in case of problems)', - ]).SetClass("flex flex-col"), - ...helpTexts, - ]).SetClass("flex flex-col") + before: { + en: "Some text to prefix before the special element (e.g. a title)", + nl: "Een tekst om voor het element te zetten (bv. een titel)" + }, + after: { + en: "Some text to put after the element, e.g. a footer" + } + } + }, + null, + " " + ) + ).SetClass("code"), + "In other words: use `{ \"before\": ..., \"after\": ..., \"special\": {\"type\": ..., \"argname\": ...argvalue...}`. The args are in the `special` block; an argvalue can be a string, a translation or another value. (Refer to class `RewriteSpecial` in case of problems)" + ]).SetClass("flex flex-col").AsMarkdown() +console.log(">>> ",helpTexts.join("\n\n")) + return firstPart + "\n\n" + helpTexts.join("\n\n") } // noinspection JSUnusedGlobalSymbols @@ -356,14 +354,14 @@ export default class SpecialVisualizations { s.structuredExamples === undefined ? [] : s.structuredExamples().map((e) => { - return s.constr( - state, - new UIEventSource>(e.feature.properties), - e.args, - e.feature, - undefined - ) - }) + return s.constr( + state, + new UIEventSource>(e.feature.properties), + e.args, + e.feature, + undefined + ) + }) return new Combine([new Title(s.funcName), s.docs, ...examples]) } @@ -379,9 +377,9 @@ export default class SpecialVisualizations { const [lon, lat] = GeoOperations.centerpointCoordinates(feature) return new SvelteUIElement(AddNewPoint, { state, - coordinate: { lon, lat }, + coordinate: { lon, lat } }).SetClass("w-full h-full overflow-auto") - }, + } }, { funcName: "user_profile", @@ -390,9 +388,9 @@ export default class SpecialVisualizations { docs: "A component showing information about the currently logged in user (username, profile description, profile picture + link to edit them). Mostly meant to be used in the 'user-settings'", constr(state: SpecialVisualizationState): BaseUIElement { return new SvelteUIElement(UserProfile, { - osmConnection: state.osmConnection, + osmConnection: state.osmConnection }) - }, + } }, { funcName: "language_picker", @@ -407,11 +405,11 @@ export default class SpecialVisualizations { availableLanguages: languages, preferredLanguages: state.osmConnection.userDetails.map( (ud) => ud.languages - ), + ) }) }) ) - }, + } }, { funcName: "logout", @@ -421,7 +419,7 @@ export default class SpecialVisualizations { constr(state: SpecialVisualizationState): BaseUIElement { return new SvelteUIElement(LogoutButton, { osmConnection: state.osmConnection }) - }, + } }, new HistogramViz(), new StealViz(), @@ -445,7 +443,7 @@ export default class SpecialVisualizations { return undefined }) ) - }, + } }, { funcName: "move_button", @@ -466,9 +464,9 @@ export default class SpecialVisualizations { return new SvelteUIElement(MoveWizard, { state, featureToMove: feature, - layer, + layer }) - }, + } }, { funcName: "delete_button", @@ -490,9 +488,9 @@ export default class SpecialVisualizations { deleteConfig: layer.deletion, state, feature, - layer, + layer }) - }, + } }, new ShareLinkViz(), new ExportAsGpxViz(), @@ -513,9 +511,9 @@ export default class SpecialVisualizations { const [lon, lat] = GeoOperations.centerpointCoordinates(feature) return new SvelteUIElement(CreateNewNote, { state, - coordinate: new UIEventSource({ lon, lat }), + coordinate: new UIEventSource({ lon, lat }) }) - }, + } }, new CloseNoteButton(), new PlantNetDetectionViz(), @@ -535,8 +533,8 @@ export default class SpecialVisualizations { { name: "keyToShowWikipediaFor", doc: "Use the wikidata entry from this key to show the wikipedia article for. Multiple keys can be given (separated by ';'), in which case the first matching value is used", - defaultValue: "wikidata;wikipedia", - }, + defaultValue: "wikidata;wikipedia" + } ], needsUrls: [...Wikidata.neededUrls, ...Wikipedia.neededUrls], @@ -549,9 +547,9 @@ export default class SpecialVisualizations { return tags[key]?.split(";")?.map((id) => id.trim()) ?? [] }) return new SvelteUIElement(WikipediaPanel, { - wikiIds, + wikiIds }) - }, + } }, { funcName: "wikidata_label", @@ -560,8 +558,8 @@ export default class SpecialVisualizations { { name: "keyToShowWikidataFor", doc: "Use the wikidata entry from this key to show the label", - defaultValue: "wikidata", - }, + defaultValue: "wikidata" + } ], needsUrls: Wikidata.neededUrls, example: @@ -585,7 +583,7 @@ export default class SpecialVisualizations { }) ) }) - ), + ) }, new MapillaryLinkVis(), new LanguageElement(), @@ -599,7 +597,7 @@ export default class SpecialVisualizations { _, __, layer: LayerConfig - ) => new SvelteUIElement(AllTagsPanel, { tags, layer }), + ) => new SvelteUIElement(AllTagsPanel, { tags, layer }) }, { funcName: "image_carousel", @@ -608,8 +606,8 @@ export default class SpecialVisualizations { { name: "image_key", defaultValue: AllImageProviders.defaultKeys.join(","), - doc: "The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... Multiple values are allowed if ';'-separated ", - }, + doc: "The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... Multiple values are allowed if ';'-separated " + } ], needsUrls: AllImageProviders.apiUrls, constr: (state, tags, args) => { @@ -622,7 +620,7 @@ export default class SpecialVisualizations { tags, state ) - }, + } }, { funcName: "image_upload", @@ -632,13 +630,13 @@ export default class SpecialVisualizations { { name: "image-key", doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)", - required: false, + required: false }, { name: "label", doc: "The text to show on the button", - required: false, - }, + required: false + } ], constr: (state, tags, args) => { const targetKey = args[0] === "" ? undefined : args[0] @@ -647,9 +645,9 @@ export default class SpecialVisualizations { tags, targetKey, labelText: args[1], - image: args[2], + image: args[2] }) - }, + } }, { funcName: "rating", @@ -659,12 +657,12 @@ export default class SpecialVisualizations { { name: "subjectKey", defaultValue: "name", - doc: "The key to use to determine the subject. If specified, the subject will be tags[subjectKey]", + doc: "The key to use to determine the subject. If specified, the subject will be tags[subjectKey]" }, { name: "fallback", - doc: "The identifier to use, if tags[subjectKey] as specified above is not available. This is effectively a fallback value", - }, + doc: "The identifier to use, if tags[subjectKey] as specified above is not available. This is effectively a fallback value" + } ], constr: (state, tags, args, feature) => { const nameKey = args[0] ?? "name" @@ -675,14 +673,14 @@ export default class SpecialVisualizations { state.userRelatedState.mangroveIdentity, { nameKey: nameKey, - fallbackName, + fallbackName }, state.featureSwitchIsTesting ) return new SvelteUIElement(StarsBarIcon, { - score: reviews.average, + score: reviews.average }) - }, + } }, { @@ -693,12 +691,12 @@ export default class SpecialVisualizations { { name: "subjectKey", defaultValue: "name", - doc: "The key to use to determine the subject. If specified, the subject will be tags[subjectKey]", + doc: "The key to use to determine the subject. If specified, the subject will be tags[subjectKey]" }, { name: "fallback", - doc: "The identifier to use, if tags[subjectKey] as specified above is not available. This is effectively a fallback value", - }, + doc: "The identifier to use, if tags[subjectKey] as specified above is not available. This is effectively a fallback value" + } ], constr: (state, tags, args, feature, layer) => { const nameKey = args[0] ?? "name" @@ -709,12 +707,12 @@ export default class SpecialVisualizations { state.userRelatedState?.mangroveIdentity, { nameKey: nameKey, - fallbackName, + fallbackName }, state.featureSwitchIsTesting ) return new SvelteUIElement(ReviewForm, { reviews, state, tags, feature, layer }) - }, + } }, { funcName: "list_reviews", @@ -726,12 +724,12 @@ export default class SpecialVisualizations { { name: "subjectKey", defaultValue: "name", - doc: "The key to use to determine the subject. If specified, the subject will be tags[subjectKey]", + doc: "The key to use to determine the subject. If specified, the subject will be tags[subjectKey]" }, { name: "fallback", - doc: "The identifier to use, if tags[subjectKey] as specified above is not available. This is effectively a fallback value", - }, + doc: "The identifier to use, if tags[subjectKey] as specified above is not available. This is effectively a fallback value" + } ], constr: (state, tags, args, feature, layer) => { const nameKey = args[0] ?? "name" @@ -742,12 +740,12 @@ export default class SpecialVisualizations { state.userRelatedState?.mangroveIdentity, { nameKey: nameKey, - fallbackName, + fallbackName }, state.featureSwitchIsTesting ) return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer }) - }, + } }, { funcName: "import_mangrove_key", @@ -755,8 +753,8 @@ export default class SpecialVisualizations { args: [ { name: "text", - doc: "The text that is shown on the button", - }, + doc: "The text that is shown on the button" + } ], needsUrls: [], constr( @@ -766,7 +764,7 @@ export default class SpecialVisualizations { ): BaseUIElement { const [text] = argument return new SvelteUIElement(ImportReviewIdentity, { state, text }) - }, + } }, { funcName: "opening_hours_table", @@ -775,18 +773,18 @@ export default class SpecialVisualizations { { name: "key", defaultValue: "opening_hours", - doc: "The tagkey from which the table is constructed.", + doc: "The tagkey from which the table is constructed." }, { name: "prefix", defaultValue: "", - doc: "Remove this string from the start of the value before parsing. __Note: use `&LPARENs` to indicate `(` if needed__", + doc: "Remove this string from the start of the value before parsing. __Note: use `&LPARENs` to indicate `(` if needed__" }, { name: "postfix", defaultValue: "", - doc: "Remove this string from the end of the value before parsing. __Note: use `&RPARENs` to indicate `)` if needed__", - }, + doc: "Remove this string from the end of the value before parsing. __Note: use `&RPARENs` to indicate `)` if needed__" + } ], needsUrls: [Constants.countryCoderEndpoint], example: @@ -794,7 +792,7 @@ export default class SpecialVisualizations { constr: (state, tagSource: UIEventSource, args) => { const [key, prefix, postfix] = args return new OpeningHoursVisualization(tagSource, state, key, prefix, postfix) - }, + } }, { funcName: "opening_hours_state", @@ -803,18 +801,18 @@ export default class SpecialVisualizations { { name: "key", defaultValue: "opening_hours", - doc: "The tagkey from which the opening hours are read.", + doc: "The tagkey from which the opening hours are read." }, { name: "prefix", defaultValue: "", - doc: "Remove this string from the start of the value before parsing. __Note: use `&LPARENs` to indicate `(` if needed__", + doc: "Remove this string from the start of the value before parsing. __Note: use `&LPARENs` to indicate `(` if needed__" }, { name: "postfix", defaultValue: "", - doc: "Remove this string from the end of the value before parsing. __Note: use `&RPARENs` to indicate `)` if needed__", - }, + doc: "Remove this string from the end of the value before parsing. __Note: use `&RPARENs` to indicate `)` if needed__" + } ], constr( state: SpecialVisualizationState, @@ -829,9 +827,9 @@ export default class SpecialVisualizations { keyToUse, tags, prefix, - postfix, + postfix }) - }, + } }, { funcName: "canonical", @@ -843,8 +841,8 @@ export default class SpecialVisualizations { { name: "key", doc: "The key of the tag to give the canonical text for", - required: true, - }, + required: true + } ], constr: (state, tagSource, args) => { const key = args[0] @@ -868,7 +866,7 @@ export default class SpecialVisualizations { return unit.asHumanLongValue(value, getCountry) }) ) - }, + } }, { funcName: "export_as_geojson", @@ -882,7 +880,7 @@ export default class SpecialVisualizations { Svg.download_svg(), new Combine([ t.downloadFeatureAsGeojson.SetClass("font-bold text-lg"), - t.downloadGeoJsonHelper.SetClass("subtle"), + t.downloadGeoJsonHelper.SetClass("subtle") ]).SetClass("flex flex-col") ) .onClick(() => { @@ -895,12 +893,12 @@ export default class SpecialVisualizations { data, title + "_mapcomplete_export.geojson", { - mimetype: "application/vnd.geo+json", + mimetype: "application/vnd.geo+json" } ) }) .SetClass("w-full") - }, + } }, { funcName: "open_in_iD", @@ -910,9 +908,9 @@ export default class SpecialVisualizations { constr: (state, feature) => { return new SvelteUIElement(OpenIdEditor, { mapProperties: state.mapProperties, - objectId: feature.data.id, + objectId: feature.data.id }) - }, + } }, { funcName: "open_in_josm", @@ -922,7 +920,7 @@ export default class SpecialVisualizations { constr: (state) => { return new SvelteUIElement(OpenJosm, { state }) - }, + } }, { funcName: "clear_location_history", @@ -937,7 +935,7 @@ export default class SpecialVisualizations { state.historicalUserLocations.features.setData([]) state.selectedElement.setData(undefined) }) - }, + } }, { funcName: "visualize_note_comments", @@ -946,13 +944,13 @@ export default class SpecialVisualizations { { name: "commentsKey", doc: "The property name of the comments, which should be stringified json", - defaultValue: "comments", + defaultValue: "comments" }, { name: "start", doc: "Drop the first 'start' comments", - defaultValue: "0", - }, + defaultValue: "0" + } ], needsUrls: [Constants.osmAuthConfig.url], constr: (state, tags, args) => @@ -974,7 +972,7 @@ export default class SpecialVisualizations { ) ).SetClass("flex flex-col") }) - ), + ) }, { funcName: "add_image_to_note", @@ -983,8 +981,8 @@ export default class SpecialVisualizations { { name: "Id-key", doc: "The property name where the ID of the note to close can be found", - defaultValue: "id", - }, + defaultValue: "id" + } ], needsUrls: [Imgur.apiUrl], @@ -993,7 +991,7 @@ export default class SpecialVisualizations { tags = state.featureProperties.getStore(id) console.log("Id is", id) return new SvelteUIElement(UploadImage, { state, tags }) - }, + } }, { funcName: "title", @@ -1023,12 +1021,12 @@ export default class SpecialVisualizations { tags: tagsSource, state, feature, - layer, + layer }) .SetClass("px-1") .setSpan() }) - ), + ) }, { funcName: "maproulette_task", @@ -1072,7 +1070,7 @@ export default class SpecialVisualizations { }) ) }, - docs: "Fetches the metadata of MapRoulette campaign that this task is part of and shows those details (namely `title`, `description` and `instruction`).\n\nThis reads the property `mr_challengeId` to detect the parent campaign.", + docs: "Fetches the metadata of MapRoulette campaign that this task is part of and shows those details (namely `title`, `description` and `instruction`).\n\nThis reads the property `mr_challengeId` to detect the parent campaign." }, { funcName: "maproulette_set_status", @@ -1083,15 +1081,15 @@ export default class SpecialVisualizations { "\n" + "```json\n" + "{\n" + - ' "id": "mark_duplicate",\n' + - ' "render": {\n' + - ' "special": {\n' + - ' "type": "maproulette_set_status",\n' + - ' "message": {\n' + - ' "en": "Mark as not found or false positive"\n' + + " \"id\": \"mark_duplicate\",\n" + + " \"render\": {\n" + + " \"special\": {\n" + + " \"type\": \"maproulette_set_status\",\n" + + " \"message\": {\n" + + " \"en\": \"Mark as not found or false positive\"\n" + " },\n" + - ' "status": "2",\n' + - ' "image": "close"\n' + + " \"status\": \"2\",\n" + + " \"image\": \"close\"\n" + " }\n" + " }\n" + "}\n" + @@ -1099,32 +1097,32 @@ export default class SpecialVisualizations { args: [ { name: "message", - doc: "A message to show to the user", + doc: "A message to show to the user" }, { name: "image", doc: "Image to show", - defaultValue: "confirm", + defaultValue: "confirm" }, { name: "message_confirm", - doc: "What to show when the task is closed, either by the user or was already closed.", + doc: "What to show when the task is closed, either by the user or was already closed." }, { name: "status", doc: "A statuscode to apply when the button is clicked. 1 = `close`, 2 = `false_positive`, 3 = `skip`, 4 = `deleted`, 5 = `already fixed` (on the map, e.g. for duplicates), 6 = `too hard`", - defaultValue: "1", + defaultValue: "1" }, { name: "maproulette_id", doc: "The property name containing the maproulette id", - defaultValue: "mr_taskId", + defaultValue: "mr_taskId" }, { name: "ask_feedback", doc: "If not an empty string, this will be used as question to ask some additional feedback. A text field will be added", - defaultValue: "", - }, + defaultValue: "" + } ], constr: (state, tagsSource, args) => { @@ -1134,7 +1132,7 @@ export default class SpecialVisualizations { message_closed, statusToSet, maproulette_id_key, - askFeedback, + askFeedback ] = args if (image === "") { image = "confirm" @@ -1151,9 +1149,9 @@ export default class SpecialVisualizations { message_closed, statusToSet, maproulette_id_key, - askFeedback, + askFeedback }) - }, + } }, { funcName: "statistics", @@ -1180,7 +1178,7 @@ export default class SpecialVisualizations { [state.mapProperties.bounds] ) ) - }, + } }, { funcName: "send_email", @@ -1189,29 +1187,29 @@ export default class SpecialVisualizations { { name: "to", doc: "Who to send the email to?", - required: true, + required: true }, { name: "subject", doc: "The subject of the email", - required: true, + required: true }, { name: "body", doc: "The text in the email", - required: true, + required: true }, { name: "button_text", doc: "The text shown on the button in the UI", - required: true, - }, + required: true + } ], constr(__, tags, args) { return new SvelteUIElement(SendEmail, { args, tags }) - }, + } }, { funcName: "link", @@ -1220,25 +1218,25 @@ export default class SpecialVisualizations { { name: "text", doc: "Text to be shown", - required: true, + required: true }, { name: "href", doc: "The URL to link to. Note that this will be URI-encoded before ", - required: true, + required: true }, { name: "class", - doc: "CSS-classes to add to the element", + doc: "CSS-classes to add to the element" }, { name: "download", - doc: "Expects a string which denotes the filename to download the contents of `href` into. If set, this link will act as a download-button.", + doc: "Expects a string which denotes the filename to download the contents of `href` into. If set, this link will act as a download-button." }, { name: "arialabel", - doc: "If set, this text will be used as aria-label", - }, + doc: "If set, this text will be used as aria-label" + } ], constr( @@ -1265,9 +1263,9 @@ export default class SpecialVisualizations { classnames: new ImmutableStore(classnames), download: tagSource.map((tags) => Utils.SubstituteKeys(download, tags)), ariaLabel: tagSource.map((tags) => Utils.SubstituteKeys(ariaLabel, tags)), - newTab: new ImmutableStore(newTab), + newTab: new ImmutableStore(newTab) }).setSpan() - }, + } }, { funcName: "multi", @@ -1281,10 +1279,10 @@ export default class SpecialVisualizations { type: "multi", key: "_doors_from_building_properties", tagrendering: { - en: "The building containing this feature has a door of width {entrance:width}", - }, - }, - }, + en: "The building containing this feature has a door of width {entrance:width}" + } + } + } }, null, " " @@ -1294,17 +1292,17 @@ export default class SpecialVisualizations { { name: "key", doc: "The property to read and to interpret as a list of properties", - required: true, + required: true }, { name: "tagrendering", doc: "An entire tagRenderingConfig", - required: true, + required: true }, { name: "classes", - doc: "CSS-classes to apply on every individual item. Seperated by `space`", - }, + doc: "CSS-classes to apply on every individual item. Seperated by `space`" + } ], constr( state: SpecialVisualizationState, @@ -1340,14 +1338,14 @@ export default class SpecialVisualizations { tags: new ImmutableStore(property), state, feature, - layer, + layer }).SetClass(classes) elements.push(subsTr) } return elements }) ) - }, + } }, { funcName: "translated", @@ -1357,8 +1355,8 @@ export default class SpecialVisualizations { { name: "key", doc: "The attribute to interpret as json", - defaultValue: "value", - }, + defaultValue: "value" + } ], constr( state: SpecialVisualizationState, @@ -1379,7 +1377,7 @@ export default class SpecialVisualizations { } }) ) - }, + } }, { funcName: "fediverse_link", @@ -1388,8 +1386,8 @@ export default class SpecialVisualizations { { name: "key", doc: "The attribute-name containing the link", - required: true, - }, + required: true + } ], constr( @@ -1413,13 +1411,13 @@ export default class SpecialVisualizations { const normalLink = new SvelteUIElement(Link, { text: fediAccount, href: "https://" + host + "/@" + username, - newTab: true, + newTab: true }) const loggedInContributorMastodon = state.userRelatedState?.preferencesAsTags?.data?.[ "_mastodon_link" - ] + ] console.log( "LoggedinContributorMastodon", loggedInContributorMastodon @@ -1435,12 +1433,12 @@ export default class SpecialVisualizations { new SvelteUIElement(Link, { href: homeHost + "/" + fediAccount, text: Translations.t.validation.fediverse.onYourServer, - newTab: true, - }).SetClass("button"), + newTab: true + }).SetClass("button") ]) }) ) - }, + } }, { funcName: "braced", @@ -1450,8 +1448,8 @@ export default class SpecialVisualizations { { name: "text", required: true, - doc: "The value to show", - }, + doc: "The value to show" + } ], constr( state: SpecialVisualizationState, @@ -1461,7 +1459,7 @@ export default class SpecialVisualizations { layer: LayerConfig ): BaseUIElement { return new FixedUiElement("{" + args[0] + "}") - }, + } }, { funcName: "tags", @@ -1471,8 +1469,8 @@ export default class SpecialVisualizations { { name: "key", defaultValue: "value", - doc: "The key to look for the tags", - }, + doc: "The key to look for the tags" + } ], constr( state: SpecialVisualizationState, @@ -1497,14 +1495,14 @@ export default class SpecialVisualizations { } catch (e) { return new FixedUiElement( "Could not parse this tag: " + - JSON.stringify(value) + - " due to " + - e + JSON.stringify(value) + + " due to " + + e ).SetClass("alert") } }) ) - }, + } }, { funcName: "giggity", @@ -1512,8 +1510,8 @@ export default class SpecialVisualizations { { name: "giggityUrl", required: true, - doc: "The URL of the giggity-XML", - }, + doc: "The URL of the giggity-XML" + } ], docs: "Shows events that are happening based on a Giggity URL", needsUrls: (args) => args[0], @@ -1527,7 +1525,7 @@ export default class SpecialVisualizations { ): BaseUIElement { const giggityUrl = argument[0] return new SvelteUIElement(Giggity, { tags: tagSource, state, giggityUrl }) - }, + } }, { funcName: "gps_all_tags", @@ -1550,10 +1548,10 @@ export default class SpecialVisualizations { new SvelteUIElement(OrientationDebugPanel, {}), new SvelteUIElement(AllTagsPanel, { state, - tags, - }), + tags + }) ]) - }, + } }, { funcName: "favourite_status", @@ -1572,9 +1570,9 @@ export default class SpecialVisualizations { tags: tagSource, state, layer, - feature, + feature }) - }, + } }, { funcName: "favourite_icon", @@ -1592,9 +1590,9 @@ export default class SpecialVisualizations { tags: tagSource, state, layer, - feature, + feature }).SetClass("w-full h-full") - }, + } }, { funcName: "direction_indicator", @@ -1609,7 +1607,7 @@ export default class SpecialVisualizations { layer: LayerConfig ): BaseUIElement { return new SvelteUIElement(DirectionIndicator, { state, feature }) - }, + } }, { funcName: "qr_code", @@ -1620,8 +1618,7 @@ export default class SpecialVisualizations { state: SpecialVisualizationState, tagSource: UIEventSource>, argument: string[], - feature: Feature, - layer: LayerConfig + feature: Feature ): BaseUIElement { const smallSize = 100 const bigSize = 200 @@ -1659,7 +1656,7 @@ export default class SpecialVisualizations { size.setData(smallSize) } }) - }, + } }, { funcName: "direction_absolute", @@ -1668,16 +1665,14 @@ export default class SpecialVisualizations { { name: "key", doc: "The attribute containing the degrees", - defaultValue: "_direction:centerpoint", - }, + defaultValue: "_direction:centerpoint" + } ], constr( state: SpecialVisualizationState, tagSource: UIEventSource>, - args: string[], - feature: Feature, - layer: LayerConfig + args: string[] ): BaseUIElement { const key = args[0] === "" ? "_direction:centerpoint" : args[0] return new VariableUiElement( @@ -1694,7 +1689,7 @@ export default class SpecialVisualizations { return Translations.t.general.visualFeedback.directionsAbsolute[dir] }) ) - }, + } }, { funcName: "compare_data", @@ -1703,18 +1698,18 @@ export default class SpecialVisualizations { { name: "url", required: true, - doc: "The attribute containing the url where to fetch more data", + doc: "The attribute containing the url where to fetch more data" }, { name: "host", required: true, - doc: "The domain name(s) where data might be fetched from - this is needed to set the CSP. A domain must include 'https', e.g. 'https://example.com'. For multiple domains, separate them with ';'. If you don't know the possible domains, use '*'. ", + doc: "The domain name(s) where data might be fetched from - this is needed to set the CSP. A domain must include 'https', e.g. 'https://example.com'. For multiple domains, separate them with ';'. If you don't know the possible domains, use '*'. " }, { name: "readonly", required: false, - doc: "If 'yes', will not show 'apply'-buttons", - }, + doc: "If 'yes', will not show 'apply'-buttons" + } ], docs: "Gives an interactive element which shows a tag comparison between the OSM-object and the upstream object. This allows to copy some or all tags into OSM", constr( @@ -1734,9 +1729,9 @@ export default class SpecialVisualizations { layer, feature, readonly, - externalData, + externalData }) - }, + } }, { funcName: "login_button", @@ -1755,7 +1750,7 @@ export default class SpecialVisualizations { new SvelteUIElement(LoginButton), state.osmConnection.isLoggedIn ) - }, + } }, { funcName: "linked_data_from_website", @@ -1764,21 +1759,21 @@ export default class SpecialVisualizations { { name: "key", defaultValue: "website", - doc: "Attempt to load ld+json from the specified URL. This can be in an embedded