forked from MapComplete/MapComplete
Merge master
This commit is contained in:
commit
01483ab3f9
264 changed files with 15566 additions and 4192 deletions
|
|
@ -45,7 +45,6 @@ export class OsmConnectionFeatureSwitches {
|
|||
}
|
||||
|
||||
export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
|
||||
|
||||
public readonly featureSwitchEnableLogin: UIEventSource<boolean>
|
||||
public readonly featureSwitchSearch: UIEventSource<boolean>
|
||||
public readonly featureSwitchBackgroundSelection: UIEventSource<boolean>
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import FilterConfig from "../../Models/ThemeConfig/FilterConfig"
|
|||
import Constants from "../../Models/Constants"
|
||||
|
||||
export type ActiveFilter = {
|
||||
layer: LayerConfig,
|
||||
filter: FilterConfig,
|
||||
layer: LayerConfig
|
||||
filter: FilterConfig
|
||||
control: UIEventSource<string | number | undefined>
|
||||
}
|
||||
/**
|
||||
|
|
@ -36,9 +36,13 @@ export default class LayerState {
|
|||
private readonly _activeFilters: UIEventSource<ActiveFilter[]> = new UIEventSource([])
|
||||
|
||||
public readonly activeFilters: Store<ActiveFilter[]> = this._activeFilters
|
||||
private readonly _activeLayers: UIEventSource<FilteredLayer[]> = new UIEventSource<FilteredLayer[]>(undefined)
|
||||
private readonly _activeLayers: UIEventSource<FilteredLayer[]> = new UIEventSource<
|
||||
FilteredLayer[]
|
||||
>(undefined)
|
||||
public readonly activeLayers: Store<FilteredLayer[]> = this._activeLayers
|
||||
private readonly _nonactiveLayers: UIEventSource<FilteredLayer[]> = new UIEventSource<FilteredLayer[]>(undefined)
|
||||
private readonly _nonactiveLayers: UIEventSource<FilteredLayer[]> = new UIEventSource<
|
||||
FilteredLayer[]
|
||||
>(undefined)
|
||||
public readonly nonactiveLayers: Store<FilteredLayer[]> = this._nonactiveLayers
|
||||
private readonly osmConnection: OsmConnection
|
||||
|
||||
|
|
@ -71,7 +75,7 @@ export default class LayerState {
|
|||
this.filteredLayers = filteredLayers
|
||||
layers.forEach((l) => LayerState.linkFilterStates(l, filteredLayers))
|
||||
|
||||
this.filteredLayers.forEach(fl => {
|
||||
this.filteredLayers.forEach((fl) => {
|
||||
fl.isDisplayed.addCallback(() => this.updateActiveFilters())
|
||||
for (const [_, appliedFilter] of fl.appliedFilters) {
|
||||
appliedFilter.addCallback(() => this.updateActiveFilters())
|
||||
|
|
@ -80,27 +84,27 @@ export default class LayerState {
|
|||
this.updateActiveFilters()
|
||||
}
|
||||
|
||||
private updateActiveFilters(){
|
||||
private updateActiveFilters() {
|
||||
const filters: ActiveFilter[] = []
|
||||
const activeLayers: FilteredLayer[] = []
|
||||
const nonactiveLayers: FilteredLayer[] = []
|
||||
this.filteredLayers.forEach(fl => {
|
||||
if(!fl.isDisplayed.data){
|
||||
const nonactiveLayers: FilteredLayer[] = []
|
||||
this.filteredLayers.forEach((fl) => {
|
||||
if (!fl.isDisplayed.data) {
|
||||
nonactiveLayers.push(fl)
|
||||
return
|
||||
}
|
||||
activeLayers.push(fl)
|
||||
|
||||
if(fl.layerDef.filterIsSameAs){
|
||||
if (fl.layerDef.filterIsSameAs) {
|
||||
return
|
||||
}
|
||||
for (const [filtername, appliedFilter] of fl.appliedFilters) {
|
||||
if (appliedFilter.data === undefined) {
|
||||
continue
|
||||
}
|
||||
const filter = fl.layerDef.filters.find(f => f.id === filtername)
|
||||
if(typeof appliedFilter.data === "number"){
|
||||
if(filter.options[appliedFilter.data].osmTags === undefined){
|
||||
const filter = fl.layerDef.filters.find((f) => f.id === filtername)
|
||||
if (typeof appliedFilter.data === "number") {
|
||||
if (filter.options[appliedFilter.data].osmTags === undefined) {
|
||||
// This is probably the first, generic option which doesn't _actually_ filter
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import { Feature } from "geojson"
|
|||
import OpenLocationCodeSearch from "../Search/OpenLocationCodeSearch"
|
||||
|
||||
export default class SearchState {
|
||||
|
||||
public readonly feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined)
|
||||
public readonly searchTerm: UIEventSource<string> = new UIEventSource<string>("")
|
||||
public readonly searchIsFocused = new UIEventSource(false)
|
||||
|
|
@ -47,53 +46,62 @@ export default class SearchState {
|
|||
]
|
||||
|
||||
const bounds = state.mapProperties.bounds
|
||||
const suggestionsList = this.searchTerm.stabilized(250).mapD(search => {
|
||||
const suggestionsList = this.searchTerm.stabilized(250).mapD(
|
||||
(search) => {
|
||||
if (search.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
return this.locationSearchers.map(ls => ls.suggest(search, { bbox: bounds.data }))
|
||||
|
||||
}, [bounds]
|
||||
return this.locationSearchers.map((ls) => ls.suggest(search, { bbox: bounds.data }))
|
||||
},
|
||||
[bounds]
|
||||
)
|
||||
this.suggestionsSearchRunning = suggestionsList.bind(suggestions => {
|
||||
this.suggestionsSearchRunning = suggestionsList.bind((suggestions) => {
|
||||
if (suggestions === undefined) {
|
||||
return new ImmutableStore(true)
|
||||
}
|
||||
return Stores.concat(suggestions).map(suggestions => suggestions.some(list => list === undefined))
|
||||
return Stores.concat(suggestions).map((suggestions) =>
|
||||
suggestions.some((list) => list === undefined)
|
||||
)
|
||||
})
|
||||
this.suggestions = suggestionsList.bindD(suggestions =>
|
||||
Stores.concat(suggestions).map(suggestions => CombinedSearcher.merge(suggestions))
|
||||
this.suggestions = suggestionsList.bindD((suggestions) =>
|
||||
Stores.concat(suggestions).map((suggestions) => CombinedSearcher.merge(suggestions))
|
||||
)
|
||||
|
||||
const themeSearch = new ThemeSearch(state)
|
||||
this.themeSuggestions = this.searchTerm.mapD(query => themeSearch.search(query, 3))
|
||||
this.themeSuggestions = this.searchTerm.mapD((query) => themeSearch.search(query, 3))
|
||||
|
||||
const layerSearch = new LayerSearch(state.theme)
|
||||
this.layerSuggestions = this.searchTerm.mapD(query => layerSearch.search(query, 5))
|
||||
this.layerSuggestions = this.searchTerm.mapD((query) => layerSearch.search(query, 5))
|
||||
|
||||
const filterSearch = new FilterSearch(state)
|
||||
this.filterSuggestions = this.searchTerm.stabilized(50)
|
||||
.mapD(query => filterSearch.search(query))
|
||||
.mapD(filterResult => {
|
||||
const active = state.layerState.activeFilters.data
|
||||
return filterResult.filter(({ filter, index, layer }) => {
|
||||
const foundMatch = active.some(active =>
|
||||
active.filter.id === filter.id && layer.id === active.layer.id && active.control.data === index)
|
||||
this.filterSuggestions = this.searchTerm
|
||||
.stabilized(50)
|
||||
.mapD((query) => filterSearch.search(query))
|
||||
.mapD(
|
||||
(filterResult) => {
|
||||
const active = state.layerState.activeFilters.data
|
||||
return filterResult.filter(({ filter, index, layer }) => {
|
||||
const foundMatch = active.some(
|
||||
(active) =>
|
||||
active.filter.id === filter.id &&
|
||||
layer.id === active.layer.id &&
|
||||
active.control.data === index
|
||||
)
|
||||
|
||||
return !foundMatch
|
||||
})
|
||||
}, [state.layerState.activeFilters])
|
||||
return !foundMatch
|
||||
})
|
||||
},
|
||||
[state.layerState.activeFilters]
|
||||
)
|
||||
this.locationResults = new GeocodingFeatureSource(this.suggestions.stabilized(250))
|
||||
|
||||
this.showSearchDrawer = new UIEventSource(false)
|
||||
|
||||
this.searchIsFocused.addCallbackAndRunD(sugg => {
|
||||
this.searchIsFocused.addCallbackAndRunD((sugg) => {
|
||||
if (sugg) {
|
||||
this.showSearchDrawer.set(true)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async apply(result: FilterSearchResult[] | LayerConfig) {
|
||||
|
|
@ -112,7 +120,7 @@ export default class SearchState {
|
|||
private async applyFilter(payload: FilterSearchResult[]) {
|
||||
const state = this.state
|
||||
|
||||
const layersToShow = payload.map(fsr => fsr.layer.id)
|
||||
const layersToShow = payload.map((fsr) => fsr.layer.id)
|
||||
console.log("Layers to show are", layersToShow)
|
||||
for (const [name, otherLayer] of state.layerState.filteredLayers) {
|
||||
const layer = otherLayer.layerDef
|
||||
|
|
@ -148,7 +156,7 @@ export default class SearchState {
|
|||
}
|
||||
// This feature might not be loaded because we zoomed out
|
||||
const object = await this.state.osmObjectDownloader.DownloadObjectAsync(osmid)
|
||||
if(object === "deleted"){
|
||||
if (object === "deleted") {
|
||||
return
|
||||
}
|
||||
const f = object.asGeoJson()
|
||||
|
|
|
|||
|
|
@ -22,9 +22,7 @@ import Showdown from "showdown"
|
|||
import { LocalStorageSource } from "../Web/LocalStorageSource"
|
||||
import { GeocodeResult } from "../Search/GeocodingProvider"
|
||||
|
||||
|
||||
export class OptionallySyncedHistory<T> {
|
||||
|
||||
public readonly syncPreference: UIEventSource<"sync" | "local" | "no">
|
||||
public readonly value: Store<T[]>
|
||||
private readonly synced: UIEventSource<T[]>
|
||||
|
|
@ -34,18 +32,26 @@ export class OptionallySyncedHistory<T> {
|
|||
private readonly _isSame: (a: T, b: T) => boolean
|
||||
private osmconnection: OsmConnection
|
||||
|
||||
constructor(key: string, osmconnection: OsmConnection, maxHistory: number = 20, isSame?: (a: T, b: T) => boolean) {
|
||||
constructor(
|
||||
key: string,
|
||||
osmconnection: OsmConnection,
|
||||
maxHistory: number = 20,
|
||||
isSame?: (a: T, b: T) => boolean
|
||||
) {
|
||||
this.osmconnection = osmconnection
|
||||
this._maxHistory = maxHistory
|
||||
this._isSame = isSame
|
||||
this.syncPreference = osmconnection.getPreference(
|
||||
"preference-" + key + "-history",
|
||||
"sync",
|
||||
)
|
||||
const synced = this.synced = UIEventSource.asObject<T[]>(osmconnection.getPreference(key + "-history"), [])
|
||||
const local = this.local = LocalStorageSource.getParsed<T[]>(key + "-history", [])
|
||||
const thisSession = this.thisSession = new UIEventSource<T[]>([], "optionally-synced:" + key + "(session only)")
|
||||
this.syncPreference.addCallback(syncmode => {
|
||||
this.syncPreference = osmconnection.getPreference("preference-" + key + "-history", "sync")
|
||||
const synced = (this.synced = UIEventSource.asObject<T[]>(
|
||||
osmconnection.getPreference(key + "-history"),
|
||||
[]
|
||||
))
|
||||
const local = (this.local = LocalStorageSource.getParsed<T[]>(key + "-history", []))
|
||||
const thisSession = (this.thisSession = new UIEventSource<T[]>(
|
||||
[],
|
||||
"optionally-synced:" + key + "(session only)"
|
||||
))
|
||||
this.syncPreference.addCallback((syncmode) => {
|
||||
if (syncmode === "sync") {
|
||||
let list = [...thisSession.data, ...synced.data].slice(0, maxHistory)
|
||||
if (this._isSame) {
|
||||
|
|
@ -67,9 +73,7 @@ export class OptionallySyncedHistory<T> {
|
|||
}
|
||||
})
|
||||
|
||||
this.value = this.syncPreference.bind(syncPref => this.getAppropriateStore(syncPref))
|
||||
|
||||
|
||||
this.value = this.syncPreference.bind((syncPref) => this.getAppropriateStore(syncPref))
|
||||
}
|
||||
|
||||
private getAppropriateStore(syncPref?: string) {
|
||||
|
|
@ -87,7 +91,7 @@ export class OptionallySyncedHistory<T> {
|
|||
const store = this.getAppropriateStore()
|
||||
let oldList = store.data ?? []
|
||||
if (this._isSame) {
|
||||
oldList = oldList.filter(x => !this._isSame(t, x))
|
||||
oldList = oldList.filter((x) => !this._isSame(t, x))
|
||||
}
|
||||
store.set([t, ...oldList].slice(0, this._maxHistory))
|
||||
}
|
||||
|
|
@ -100,14 +104,13 @@ export class OptionallySyncedHistory<T> {
|
|||
if (t === undefined) {
|
||||
return
|
||||
}
|
||||
this.osmconnection.isLoggedIn.addCallbackAndRun(loggedIn => {
|
||||
this.osmconnection.isLoggedIn.addCallbackAndRun((loggedIn) => {
|
||||
if (!loggedIn) {
|
||||
return
|
||||
}
|
||||
this.add(t)
|
||||
return true
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
clear() {
|
||||
|
|
@ -157,7 +160,7 @@ export default class UserRelatedState {
|
|||
*/
|
||||
public readonly gpsLocationHistoryRetentionTime = new UIEventSource(
|
||||
7 * 24 * 60 * 60,
|
||||
"gps_location_retention",
|
||||
"gps_location_retention"
|
||||
)
|
||||
|
||||
public readonly addNewFeatureMode = new UIEventSource<
|
||||
|
|
@ -180,18 +183,17 @@ export default class UserRelatedState {
|
|||
public readonly recentlyVisitedThemes: OptionallySyncedHistory<string>
|
||||
public readonly recentlyVisitedSearch: OptionallySyncedHistory<GeocodeResult>
|
||||
|
||||
|
||||
constructor(
|
||||
osmConnection: OsmConnection,
|
||||
layout?: ThemeConfig,
|
||||
featureSwitches?: FeatureSwitchState,
|
||||
mapProperties?: MapProperties,
|
||||
mapProperties?: MapProperties
|
||||
) {
|
||||
this.osmConnection = osmConnection
|
||||
this._mapProperties = mapProperties
|
||||
|
||||
this.showAllQuestionsAtOnce = UIEventSource.asBoolean(
|
||||
this.osmConnection.getPreference("show-all-questions", "false"),
|
||||
this.osmConnection.getPreference("show-all-questions", "false")
|
||||
)
|
||||
this.language = this.osmConnection.getPreference("language")
|
||||
this.showTags = this.osmConnection.getPreference("show_tags")
|
||||
|
|
@ -203,15 +205,19 @@ export default class UserRelatedState {
|
|||
|
||||
this.mangroveIdentity = new MangroveIdentity(
|
||||
this.osmConnection.getPreference("identity", undefined, "mangrove"),
|
||||
this.osmConnection.getPreference("identity-creation-date", undefined, "mangrove"),
|
||||
this.osmConnection.getPreference("identity-creation-date", undefined, "mangrove")
|
||||
)
|
||||
this.preferredBackgroundLayer = this.osmConnection.getPreference(
|
||||
"preferred-background-layer"
|
||||
)
|
||||
this.preferredBackgroundLayer = this.osmConnection.getPreference("preferred-background-layer")
|
||||
|
||||
this.addNewFeatureMode = this.osmConnection.getPreference(
|
||||
"preferences-add-new-mode",
|
||||
"button_click_right",
|
||||
"button_click_right"
|
||||
)
|
||||
this.showScale = UIEventSource.asBoolean(
|
||||
this.osmConnection.GetPreference("preference-show-scale", "false")
|
||||
)
|
||||
this.showScale = UIEventSource.asBoolean(this.osmConnection.GetPreference("preference-show-scale", "false"))
|
||||
|
||||
this.imageLicense = this.osmConnection.getPreference("pictures-license", "CC0")
|
||||
this.installedUserThemes = UserRelatedState.initInstalledUserThemes(osmConnection)
|
||||
|
|
@ -224,12 +230,13 @@ export default class UserRelatedState {
|
|||
"theme",
|
||||
this.osmConnection,
|
||||
10,
|
||||
(a, b) => a === b,
|
||||
(a, b) => a === b
|
||||
)
|
||||
this.recentlyVisitedSearch = new OptionallySyncedHistory<GeocodeResult>("places",
|
||||
this.recentlyVisitedSearch = new OptionallySyncedHistory<GeocodeResult>(
|
||||
"places",
|
||||
this.osmConnection,
|
||||
15,
|
||||
(a, b) => a.osm_id === b.osm_id && a.osm_type === b.osm_type,
|
||||
(a, b) => a.osm_id === b.osm_id && a.osm_type === b.osm_type
|
||||
)
|
||||
this.syncLanguage()
|
||||
this.recentlyVisitedThemes.addDefferred(layout?.id)
|
||||
|
|
@ -279,9 +286,7 @@ export default class UserRelatedState {
|
|||
*/
|
||||
public addUnofficialTheme(themeInfo: MinimalThemeInformation) {
|
||||
const pref = this.osmConnection.getPreference("unofficial-theme-" + themeInfo.id)
|
||||
this.osmConnection.isLoggedIn.when(
|
||||
() => pref.set(JSON.stringify(themeInfo))
|
||||
)
|
||||
this.osmConnection.isLoggedIn.when(() => pref.set(JSON.stringify(themeInfo)))
|
||||
}
|
||||
|
||||
public getUnofficialTheme(id: string): MinimalThemeInformation | undefined {
|
||||
|
|
@ -298,9 +303,9 @@ export default class UserRelatedState {
|
|||
} catch (e) {
|
||||
console.warn(
|
||||
"Removing theme " +
|
||||
id +
|
||||
" as it could not be parsed from the preferences; the content is:",
|
||||
str,
|
||||
id +
|
||||
" as it could not be parsed from the preferences; the content is:",
|
||||
str
|
||||
)
|
||||
pref.setData(null)
|
||||
return undefined
|
||||
|
|
@ -330,7 +335,7 @@ export default class UserRelatedState {
|
|||
title: layout.title.translations,
|
||||
shortDescription: layout.shortDescription.translations,
|
||||
definition: layout["definition"],
|
||||
}),
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -340,7 +345,7 @@ export default class UserRelatedState {
|
|||
return osmConnection.preferencesHandler.allPreferences.map((prefs) =>
|
||||
Object.keys(prefs)
|
||||
.filter((k) => k.startsWith(prefix))
|
||||
.map((k) => k.substring(prefix.length)),
|
||||
.map((k) => k.substring(prefix.length))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -354,7 +359,7 @@ export default class UserRelatedState {
|
|||
return userPreferences.map((preferences) =>
|
||||
Object.keys(preferences)
|
||||
.filter((key) => key.startsWith(prefix))
|
||||
.map((key) => key.substring(prefix.length, key.length - "-enabled".length)),
|
||||
.map((key) => key.substring(prefix.length, key.length - "-enabled".length))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -370,7 +375,7 @@ export default class UserRelatedState {
|
|||
return undefined
|
||||
}
|
||||
return [home.lon, home.lat]
|
||||
}),
|
||||
})
|
||||
).map((homeLonLat) => {
|
||||
if (homeLonLat === undefined) {
|
||||
return empty
|
||||
|
|
@ -400,7 +405,7 @@ export default class UserRelatedState {
|
|||
* */
|
||||
private initAmendedPrefs(
|
||||
layout?: ThemeConfig,
|
||||
featureSwitches?: FeatureSwitchState,
|
||||
featureSwitches?: FeatureSwitchState
|
||||
): UIEventSource<Record<string, string>> {
|
||||
const amendedPrefs = new UIEventSource<Record<string, string>>({
|
||||
_theme: layout?.id,
|
||||
|
|
@ -446,19 +451,19 @@ export default class UserRelatedState {
|
|||
const missingLayers = Utils.Dedup(
|
||||
untranslated
|
||||
.filter((k) => k.startsWith("layers:"))
|
||||
.map((k) => k.slice("layers:".length).split(".")[0]),
|
||||
.map((k) => k.slice("layers:".length).split(".")[0])
|
||||
)
|
||||
|
||||
const zenLinks: { link: string; id: string }[] = Utils.NoNull([
|
||||
hasMissingTheme
|
||||
? {
|
||||
id: "theme:" + layout.id,
|
||||
link: LinkToWeblate.hrefToWeblateZen(
|
||||
language,
|
||||
"themes",
|
||||
layout.id,
|
||||
),
|
||||
}
|
||||
id: "theme:" + layout.id,
|
||||
link: LinkToWeblate.hrefToWeblateZen(
|
||||
language,
|
||||
"themes",
|
||||
layout.id
|
||||
),
|
||||
}
|
||||
: undefined,
|
||||
...missingLayers.map((id) => ({
|
||||
id: "layer:" + id,
|
||||
|
|
@ -475,7 +480,7 @@ export default class UserRelatedState {
|
|||
}
|
||||
amendedPrefs.ping()
|
||||
},
|
||||
[this.translationMode],
|
||||
[this.translationMode]
|
||||
)
|
||||
|
||||
this.mangroveIdentity.getKeyId().addCallbackAndRun((kid) => {
|
||||
|
|
@ -494,7 +499,7 @@ export default class UserRelatedState {
|
|||
.makeHtml(userDetails.description)
|
||||
?.replace(/>/g, ">")
|
||||
?.replace(/</g, "<")
|
||||
?.replace(/\n/g, ""),
|
||||
?.replace(/\n/g, "")
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -505,7 +510,7 @@ export default class UserRelatedState {
|
|||
(c: { contributor: string; commits: number }) => {
|
||||
const replaced = c.contributor.toLowerCase().replace(/\s+/g, "")
|
||||
return replaced === simplifiedName
|
||||
},
|
||||
}
|
||||
)
|
||||
if (isTranslator) {
|
||||
amendedPrefs.data["_translation_contributions"] = "" + isTranslator.commits
|
||||
|
|
@ -514,7 +519,7 @@ export default class UserRelatedState {
|
|||
(c: { contributor: string; commits: number }) => {
|
||||
const replaced = c.contributor.toLowerCase().replace(/\s+/g, "")
|
||||
return replaced === simplifiedName
|
||||
},
|
||||
}
|
||||
)
|
||||
if (isCodeContributor) {
|
||||
amendedPrefs.data["_code_contributions"] = "" + isCodeContributor.commits
|
||||
|
|
|
|||
|
|
@ -1,14 +1,42 @@
|
|||
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<string, string>}) {
|
||||
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<string, string> }) {
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue