diff --git a/src/Logic/State/UserSettingsMetaTagging.ts b/src/Logic/State/UserSettingsMetaTagging.ts index 6e568c5c3..33a5ae85b 100644 --- a/src/Logic/State/UserSettingsMetaTagging.ts +++ b/src/Logic/State/UserSettingsMetaTagging.ts @@ -1,42 +1,14 @@ import { Utils } from "../../Utils" /** This code is autogenerated - do not edit. Edit ./assets/layers/usersettings/usersettings.json instead */ export class ThemeMetaTagging { - public static readonly themeName = "usersettings" + public static readonly themeName = "usersettings" - public metaTaggging_for_usersettings(feat: { properties: Record }) { - Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_md", () => - feat.properties._description - .match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/) - ?.at(1) - ) - Utils.AddLazyProperty( - feat.properties, - "_d", - () => feat.properties._description?.replace(/</g, "<")?.replace(/>/g, ">") ?? "" - ) - Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_a", () => - ((feat) => { - const e = document.createElement("div") - e.innerHTML = feat.properties._d - return Array.from(e.getElementsByTagName("a")).filter( - (a) => a.href.match(/mastodon|en.osm.town/) !== null - )[0]?.href - })(feat) - ) - Utils.AddLazyProperty(feat.properties, "_mastodon_link", () => - ((feat) => { - const e = document.createElement("div") - e.innerHTML = feat.properties._d - return Array.from(e.getElementsByTagName("a")).filter( - (a) => a.getAttribute("rel")?.indexOf("me") >= 0 - )[0]?.href - })(feat) - ) - Utils.AddLazyProperty( - feat.properties, - "_mastodon_candidate", - () => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a - ) - feat.properties["__current_backgroun"] = "initial_value" - } -} + public metaTaggging_for_usersettings(feat: {properties: Record}) { + Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_md', () => feat.properties._description.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)?.at(1) ) + Utils.AddLazyProperty(feat.properties, '_d', () => feat.properties._description?.replace(/</g,'<')?.replace(/>/g,'>') ?? '' ) + Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_a', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.href.match(/mastodon|en.osm.town/) !== null)[0]?.href }) (feat) ) + Utils.AddLazyProperty(feat.properties, '_mastodon_link', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.getAttribute("rel")?.indexOf('me') >= 0)[0]?.href})(feat) ) + Utils.AddLazyProperty(feat.properties, '_mastodon_candidate', () => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a ) + feat.properties['__current_backgroun'] = 'initial_value' + } +} \ No newline at end of file diff --git a/src/UI/Base/VariableUIElement.ts b/src/UI/Base/VariableUIElement.ts index c288d8639..7b9127053 100644 --- a/src/UI/Base/VariableUIElement.ts +++ b/src/UI/Base/VariableUIElement.ts @@ -1,6 +1,5 @@ import { Store } from "../../Logic/UIEventSource" import BaseUIElement from "../BaseUIElement" -import Combine from "./Combine" import { Utils } from "../../Utils" /** diff --git a/src/UI/Input/README.md b/src/UI/Input/README.md deleted file mode 100644 index 82b6ff547..000000000 --- a/src/UI/Input/README.md +++ /dev/null @@ -1 +0,0 @@ -This is the old, deprecated directory. New, Svelte-based items go into `InputElement` diff --git a/src/UI/Input/TextField.ts b/src/UI/Input/TextField.ts deleted file mode 100644 index 573ad4e29..000000000 --- a/src/UI/Input/TextField.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { Store, UIEventSource } from "../../Logic/UIEventSource" -import BaseUIElement from "../BaseUIElement" -import { Translation } from "../i18n/Translation" -import Locale from "../i18n/Locale" - -/** - * @deprecated - */ -interface TextFieldOptions { - placeholder?: string | Store | Translation - value?: UIEventSource - htmlType?: "text" | "time" | string -} - -/** - * @deprecated - */ -export class TextField extends BaseUIElement { - public readonly enterPressed = new UIEventSource(undefined) - private readonly value: UIEventSource - private _actualField: HTMLElement - private readonly _rawValue: UIEventSource - private _isFocused = false - private readonly _options: TextFieldOptions - - constructor(options?: TextFieldOptions) { - super() - this._options = options ?? {} - options = options ?? {} - this.value = options?.value ?? new UIEventSource(undefined) - this._rawValue = new UIEventSource("") - } - - private static SetCursorPosition(textfield: HTMLElement, i: number) { - if (textfield === undefined || textfield === null) { - return - } - if (i === -1) { - // @ts-ignore - i = textfield.value.length - } - textfield.focus() - // @ts-ignore - textfield.setSelectionRange(i, i) - } - - protected InnerConstructElement(): HTMLElement { - const options = this._options - const self = this - let placeholderStore: Store - let placeholder: string = "" - if (options.placeholder) { - if (typeof options.placeholder === "string") { - placeholder = options.placeholder - placeholderStore = undefined - } else { - if ( - options.placeholder instanceof Store && - options.placeholder["data"] !== undefined - ) { - placeholderStore = options.placeholder - } else if ( - options.placeholder instanceof Translation && - options.placeholder["translations"] !== undefined - ) { - placeholderStore = >( - Locale.language.map((l) => (options.placeholder).textFor(l)) - ) - } - placeholder = placeholderStore?.data ?? placeholder ?? "" - } - } - - this.SetClass("form-text-field") - let inputEl: HTMLElement - { - const el = document.createElement("input") - el.type = options.htmlType ?? "text" - el.placeholder = placeholder - el.style.cssText = "width: 100%;" - el.dir = "auto" - inputEl = el - if (placeholderStore) { - placeholderStore.addCallbackAndRunD((placeholder) => (el.placeholder = placeholder)) - } - } - - const form = document.createElement("form") - form.appendChild(inputEl) - form.onsubmit = () => false - - const field = inputEl - - this.value.addCallbackAndRunD((value) => { - // We leave the textfield as is in the case of undefined or null (handled by addCallbackAndRunD) - make sure we do not erase it! - field["value"] = value - }) - - field.oninput = () => { - // How much characters are on the right, not including spaces? - // @ts-ignore - const endDistance = field.value.substring(field.selectionEnd).replace(/ /g, "").length - // @ts-ignore - let val: string = field.value - self._rawValue.setData(val) - if (!val) { - self.value.setData(undefined) - } else { - self.value.setData(val) - } - // Setting the value might cause the value to be set again. We keep the distance _to the end_ stable, as phone number formatting might cause the start to change - // See https://source.mapcomplete.org/MapComplete/MapComplete/issues/103 - // We reread the field value - it might have changed! - - // @ts-ignore - val = field.value - let newCursorPos = val.length - endDistance - while ( - newCursorPos >= 0 && - // We count the number of _actual_ characters (non-space characters) on the right of the new value - // This count should become bigger then the end distance - val.substr(newCursorPos).replace(/ /g, "").length < endDistance - ) { - newCursorPos-- - } - TextField.SetCursorPosition(field, newCursorPos) - } - - field.addEventListener("keyup", function (event) { - if (event.key === "Enter") { - // @ts-ignore - self.enterPressed.setData(field.value) - } - }) - - if (this._isFocused) { - field.focus() - } - - this._actualField = field - return form - } - -} diff --git a/src/UI/InputElement/Helpers/TimeInput.svelte b/src/UI/InputElement/Helpers/TimeInput.svelte new file mode 100644 index 000000000..6a76196ed --- /dev/null +++ b/src/UI/InputElement/Helpers/TimeInput.svelte @@ -0,0 +1,10 @@ + + + diff --git a/src/UI/InputElement/WikidataInputHelper.svelte b/src/UI/InputElement/Helpers/WikidataInputHelper.svelte similarity index 82% rename from src/UI/InputElement/WikidataInputHelper.svelte rename to src/UI/InputElement/Helpers/WikidataInputHelper.svelte index 213ec8967..299220708 100644 --- a/src/UI/InputElement/WikidataInputHelper.svelte +++ b/src/UI/InputElement/Helpers/WikidataInputHelper.svelte @@ -4,14 +4,14 @@ Wrapper around 'WikidataInput.svelte' which handles the arguments */ - import { UIEventSource } from "../../Logic/UIEventSource" - import Locale from "../i18n/Locale" - import { Utils } from "../../Utils" - import Wikidata from "../../Logic/Web/Wikidata" - import WikidataInput from "./Helpers/WikidataInput.svelte" + import { UIEventSource } from "../../../Logic/UIEventSource" + import Locale from "../../i18n/Locale" + import { Utils } from "../../../Utils" + import Wikidata from "../../../Logic/Web/Wikidata" + import WikidataInput from "../Helpers/WikidataInput.svelte" import type { Feature } from "geojson" import { onDestroy } from "svelte" - import WikidataValidator from "./Validators/WikidataValidator" + import WikidataValidator from "../Validators/WikidataValidator" export let args: (string | number | boolean)[] = [] export let feature: Feature diff --git a/src/UI/InputElement/InputHelper.svelte b/src/UI/InputElement/InputHelper.svelte index 7b4dbcbe4..c0dddc7da 100644 --- a/src/UI/InputElement/InputHelper.svelte +++ b/src/UI/InputElement/InputHelper.svelte @@ -18,8 +18,9 @@ import OpeningHoursInput from "./Helpers/OpeningHoursInput.svelte" import SlopeInput from "./Helpers/SlopeInput.svelte" import type { SpecialVisualizationState } from "../SpecialVisualization" - import WikidataInputHelper from "./WikidataInputHelper.svelte" + import WikidataInputHelper from "./Helpers/WikidataInputHelper.svelte" import DistanceInput from "./Helpers/DistanceInput.svelte" + import TimeInput from "./Helpers/TimeInput.svelte" export let type: ValidatorType export let value: UIEventSource @@ -39,6 +40,8 @@ /> {:else if type === "date"} +{:else if type === "time"} + {:else if type === "color"} {:else if type === "image"} @@ -55,6 +58,7 @@ {:else if type === "distance"} + {:else} {/if} diff --git a/src/UI/InputElement/InputHelpers.ts b/src/UI/InputElement/InputHelpers.ts index 1f8316134..a7d25514b 100644 --- a/src/UI/InputElement/InputHelpers.ts +++ b/src/UI/InputElement/InputHelpers.ts @@ -25,7 +25,7 @@ export interface InputHelperProperties { } export default class InputHelpers { - public static hideInputField: string[] = ["translation", "simple_tag", "tag"] + public static hideInputField: string[] = ["translation", "simple_tag", "tag","time"] /** * Constructs a mapProperties-object for the given properties. diff --git a/src/UI/InputElement/Validator.ts b/src/UI/InputElement/Validator.ts index f37dbbc1b..b6cc2f4d4 100644 --- a/src/UI/InputElement/Validator.ts +++ b/src/UI/InputElement/Validator.ts @@ -1,5 +1,6 @@ import { Translation } from "../i18n/Translation" import Translations from "../i18n/Translations" +import { HTMLInputTypeAttribute } from "svelte/elements" /** * A 'TextFieldValidator' contains various methods to check and cleanup an entered value or to give feedback. @@ -16,15 +17,7 @@ export abstract class Validator { * What HTML-inputmode to use? * Note: some inputHelpers will completely hide the default text field. This is kept in InputHelpers.hideInputField */ - public readonly inputmode?: - | "none" - | "text" - | "tel" - | "url" - | "email" - | "numeric" - | "decimal" - | "search" + public readonly inputmode?: HTMLInputTypeAttribute public readonly textArea: boolean public readonly isMeta?: boolean diff --git a/src/UI/InputElement/Validators.ts b/src/UI/InputElement/Validators.ts index 9b236858c..ce0d5945b 100644 --- a/src/UI/InputElement/Validators.ts +++ b/src/UI/InputElement/Validators.ts @@ -28,6 +28,7 @@ import VeloparkValidator from "./Validators/VeloparkValidator" import NameSuggestionIndexValidator from "./Validators/NameSuggestionIndexValidator" import CurrencyValidator from "./Validators/CurrencyValidator" import RegexValidator from "./Validators/RegexValidator" +import { TimeValidator } from "./Validators/TimeValidator" export type ValidatorType = (typeof Validators.availableTypes)[number] @@ -36,6 +37,7 @@ export default class Validators { "color", "currency", "date", + "time", "direction", "distance", "email", @@ -68,6 +70,7 @@ export default class Validators { new StringValidator(), new TextValidator(), new DateValidator(), + new TimeValidator(), new NatValidator(), new IntValidator(), new DistanceValidator(), diff --git a/src/UI/InputElement/Validators/TimeValidator.ts b/src/UI/InputElement/Validators/TimeValidator.ts new file mode 100644 index 000000000..867d35226 --- /dev/null +++ b/src/UI/InputElement/Validators/TimeValidator.ts @@ -0,0 +1,11 @@ +import { Validator } from "../Validator" + +export class TimeValidator extends Validator { + + inputmode = "time" + + constructor() { + super("time", "A time picker") + } + +} diff --git a/src/UI/OpeningHours/PublicHolidaySelector.svelte b/src/UI/OpeningHours/PublicHolidaySelector.svelte index c50b3ec75..4fdb8809b 100644 --- a/src/UI/OpeningHours/PublicHolidaySelector.svelte +++ b/src/UI/OpeningHours/PublicHolidaySelector.svelte @@ -3,9 +3,8 @@ import Dropdown from "../Base/Dropdown.svelte" import Tr from "../Base/Tr.svelte" import Translations from "../i18n/Translations" - import ToSvelte from "../Base/ToSvelte.svelte" - import { TextField } from "../Input/TextField" import { OH } from "./OpeningHours" + import TimeInput from "../InputElement/Helpers/TimeInput.svelte" export let value: UIEventSource let startValue: UIEventSource = new UIEventSource(undefined) @@ -71,22 +70,11 @@ {#if $mode === " "} -
+
- + - + +
{/if} diff --git a/src/UI/OpeningHours/Visualisation/OpeningHoursHeader.svelte b/src/UI/OpeningHours/Visualisation/OpeningHoursHeader.svelte index aedbdb01b..c0ffb3496 100644 --- a/src/UI/OpeningHours/Visualisation/OpeningHoursHeader.svelte +++ b/src/UI/OpeningHours/Visualisation/OpeningHoursHeader.svelte @@ -1,7 +1,4 @@