{
return;
}
console.log("Deleting image...", key, " --> ", url);
- State.state.changes.addTag(this._tags.data.id, new Tag(key, ""));
this._deletedImages.data.push(url);
this._deletedImages.ping();
+ this.ping();
+ State.state?.changes?.addTag(this._tags.data.id, new Tag(key, ""));
}
- public Activate() {
- if (this._activated) {
- return;
- }
- this._activated = true;
- this.LoadImages();
- const self = this;
- this._tags.addCallback(() => self.LoadImages());
- }
private LoadImages(): void {
- if (!this._activated) {
- return;
- }
const imageTag = this._tags.data.image;
if (imageTag !== undefined) {
const bareImages = imageTag.split(";");
diff --git a/Logic/Leaflet/StrayClickHandler.ts b/Logic/Leaflet/StrayClickHandler.ts
index 308ba11c4..e8275c327 100644
--- a/Logic/Leaflet/StrayClickHandler.ts
+++ b/Logic/Leaflet/StrayClickHandler.ts
@@ -31,16 +31,12 @@ export class StrayClickHandler {
});
const uiElement = uiToShow();
const popup = L.popup().setContent(uiElement.Render());
- uiElement.Update();
- uiElement.Activate();
self._lastMarker.addTo(map);
self._lastMarker.bindPopup(popup);
self._lastMarker.on("click", () => {
State.state.fullScreenMessage.setData(self._uiToShow());
});
- uiElement.Update();
- uiElement.Activate();
});
State.state.selectedElement.addCallback(() => {
diff --git a/Logic/Tags.ts b/Logic/Tags.ts
index a4727f38b..0eecb4880 100644
--- a/Logic/Tags.ts
+++ b/Logic/Tags.ts
@@ -465,7 +465,6 @@ export class TagUtils {
let leftoverTag = undefined;
if (keyValues[freeformKey] !== undefined && keyValues[freeformKey].length !== 0) {
leftoverTag = new Tag(freeformKey, keyValues[freeformKey].join(";"));
- console.log("Leftovers are ", leftoverTag)
if (freeformExtraTags !== undefined) {
leftoverTag = new And([
leftoverTag,
diff --git a/UI/Base/Combine.ts b/UI/Base/Combine.ts
index 6dd9fda56..275da44b1 100644
--- a/UI/Base/Combine.ts
+++ b/UI/Base/Combine.ts
@@ -1,45 +1,23 @@
import {UIElement} from "../UIElement";
-import Translations from "../i18n/Translations";
+import {FixedUiElement} from "./FixedUiElement";
+import {Utils} from "../../Utils";
export default class Combine extends UIElement {
- private readonly uiElements: (string | UIElement)[];
- private readonly className: string = undefined;
+ private readonly uiElements: UIElement[];
- constructor(uiElements: (string | UIElement)[], className: string = undefined) {
- super(undefined);
- this.dumbMode = false;
- this.className = className;
- this.uiElements = uiElements;
- if (className) {
- console.error("Deprecated used of className")
- }
+ constructor(uiElements: (string | UIElement)[]) {
+ super();
+ this.uiElements = Utils.NoNull(uiElements)
+ .map(el => {
+ if (typeof el === "string") {
+ return new FixedUiElement(el);
+ }
+ return el;
+ });
}
InnerRender(): string {
- let elements = "";
- for (const element of this.uiElements) {
- if(element === undefined){
- continue;
- }
-
- if (element instanceof UIElement) {
- elements += element.Render();
- } else {
- elements += element;
- }
- }
- if(this.className !== undefined){
- elements = `${elements}`;
- }
-
- return elements;
+ return this.uiElements.map(ui => ui.Render()).join("");
}
- InnerUpdate(htmlElement: HTMLElement) {
- for (const element of this.uiElements) {
- if (element instanceof UIElement) {
- element.Update();
- }
- }
- }
}
\ No newline at end of file
diff --git a/UI/Base/TabbedComponent.ts b/UI/Base/TabbedComponent.ts
index b7c5d47cf..e7204db02 100644
--- a/UI/Base/TabbedComponent.ts
+++ b/UI/Base/TabbedComponent.ts
@@ -13,7 +13,9 @@ export class TabbedComponent extends UIElement {
for (let i = 0; i < elements.length; i++) {
let element = elements[i];
this.headers.push(Translations.W(element.header).onClick(() => self._source.setData(i)));
- this.content.push(Translations.W(element.content));
+ const content = Translations.W(element.content)
+ this.ListenTo(content)
+ this.content.push(content);
}
}
@@ -35,10 +37,4 @@ export class TabbedComponent extends UIElement {
return headerBar + "" + (content?.Render() ?? "") + "
";
}
- protected InnerUpdate(htmlElement: HTMLElement) {
-
- super.InnerUpdate(htmlElement);
- this.content[this._source.data].Update();
- }
-
}
\ No newline at end of file
diff --git a/UI/Base/VariableUIElement.ts b/UI/Base/VariableUIElement.ts
index 40c18c78a..6e5e246ef 100644
--- a/UI/Base/VariableUIElement.ts
+++ b/UI/Base/VariableUIElement.ts
@@ -3,13 +3,10 @@ import {UIEventSource} from "../../Logic/UIEventSource";
export class VariableUiElement extends UIElement {
private _html: UIEventSource;
- private _innerUpdate: (htmlElement: HTMLElement) => void;
- constructor(html: UIEventSource, innerUpdate : ((htmlElement : HTMLElement) => void) = undefined) {
+ constructor(html: UIEventSource) {
super(html);
this._html = html;
- this._innerUpdate = innerUpdate;
-
}
InnerRender(): string {
diff --git a/UI/FullScreenMessageBoxHandler.ts b/UI/FullScreenMessageBoxHandler.ts
index c1cb34bbb..2490e400d 100644
--- a/UI/FullScreenMessageBoxHandler.ts
+++ b/UI/FullScreenMessageBoxHandler.ts
@@ -8,25 +8,40 @@ import Combine from "./Base/Combine";
*/
export class FullScreenMessageBox extends UIElement {
+ private static readonly _toTheMap_height : string = "5em";
+
private _uielement: UIElement;
- private returnToTheMap: UIElement;
+ private readonly returnToTheMap: UIElement;
constructor(onClear: (() => void)) {
super(undefined);
const self = this;
- State.state.fullScreenMessage.addCallback(uielement => {
- return self._uielement = uielement?.SetClass("messagesboxmobile-scroll")?.Activate();
+
+ State.state.fullScreenMessage.addCallbackAndRun(uiElement => {
+ this._uielement = new Combine([State.state.fullScreenMessage.data]).SetStyle(
+ "display:block;"+
+ "padding: 1em;"+
+ "padding-bottom:5em;"+
+ `margin-bottom:${FullScreenMessageBox._toTheMap_height};`+
+ "box-sizing:border-box;"+
+ `height:calc(100vh - ${FullScreenMessageBox._toTheMap_height});`+
+ "overflow-y: auto;" +
+ "background:white;"
+
+ );
});
- this._uielement = State.state.fullScreenMessage.data;
+
this.ListenTo(State.state.fullScreenMessage);
+
this.HideOnEmpty(true);
State.state.fullScreenMessage.addCallback(latestData => {
if (latestData === undefined) {
location.hash = "";
} else {
+ // The 'hash' makes sure a new piece of history is added. This makes the 'back-button' on android remove the popup
location.hash = "#element";
}
this.Update();
@@ -42,8 +57,23 @@ export class FullScreenMessageBox extends UIElement {
}
}
- this.returnToTheMap = Translations.t.general.returnToTheMap.Clone()
- .SetClass("to-the-map")
+ this.returnToTheMap =
+ new Combine([Translations.t.general.returnToTheMap.Clone().SetStyle("font-size:xx-large")])
+ .SetStyle("background:#7ebc6f;" +
+ "position: fixed;" +
+ "z-index: 10000;" +
+ "bottom: 0;" +
+ "left: 0;" +
+ `height: ${FullScreenMessageBox._toTheMap_height};` +
+ "width: 100vw;" +
+ "color: white;" +
+ "font-weight: bold;" +
+ "pointer-events: all;" +
+ "cursor: pointer;" +
+ "padding-top: 1.2em;" +
+ "text-align: center;" +
+ "padding-bottom: 1.2em;" +
+ "box-sizing:border-box")
.onClick(() => {
console.log("Returning...")
State.state.fullScreenMessage.setData(undefined);
@@ -55,10 +85,11 @@ export class FullScreenMessageBox extends UIElement {
InnerRender(): string {
- if (this._uielement === undefined) {
+ if (State.state.fullScreenMessage.data === undefined) {
return "";
}
- return new Combine([this._uielement, this.returnToTheMap]).Render();
+ return new Combine([this._uielement, this.returnToTheMap])
+ .Render();
}
diff --git a/UI/Image/ImageCarousel.ts b/UI/Image/ImageCarousel.ts
index e56826680..6c8055791 100644
--- a/UI/Image/ImageCarousel.ts
+++ b/UI/Image/ImageCarousel.ts
@@ -49,6 +49,7 @@ export class ImageCarousel extends TagDependantUIElement {
private readonly _uiElements: UIEventSource;
private readonly _deleteButton: UIElement;
+ private readonly _confirmation: UIElement;
constructor(tags: UIEventSource, osmConnection: OsmConnection = undefined) {
super(tags);
@@ -76,74 +77,78 @@ export class ImageCarousel extends TagDependantUIElement {
return false;
}
return self.searcher.IsDeletable(self.searcher.data[i]);
- }, [this.searcher, osmConnection?.userDetails]);
+ }, [this.searcher, osmConnection?.userDetails, this.slideshow._currentSlide]);
const isDeleted: UIEventSource = this.slideshow._currentSlide.map((i: number) => {
- return self.searcher._deletedImages.data.indexOf(self.searcher.data[i]) >= 0;
- }, [this.searcher, this.searcher._deletedImages]);
-
- this.slideshow._currentSlide.addCallback(() => {
- showDeleteButton.ping(); // This pings the showDeleteButton, which indicates that it has to hide it's subbuttons
- })
-
-
- const deleteCurrent = () => {
- self.searcher.Delete(self.searcher.data[self.slideshow._currentSlide.data]);
- }
-
+ const isDeleted = self.searcher._deletedImages.data.indexOf(self.searcher.data[i]) >= 0;
+ console.log("Now deleted: ", i, isDeleted);
+ return isDeleted;
+ }, [this.searcher, this.searcher._deletedImages, this.slideshow._currentSlide]);
const style = ";padding:0.4em;height:2em;padding: 0.4em; font-weight:bold;";
const backButton = Translations.t.image.dontDelete
.SetStyle("background:black;border-radius:0.4em 0.4em 0 0" + style)
- const deleteButton = Translations.t.image.doDelete
- .SetStyle("background:#ff8c8c;border-radius:0 0 0.4em 0.4em" + style)
- .onClick(deleteCurrent);
+ const deleteButton =
+ Translations.t.image.doDelete
+ .SetStyle("background:#ff8c8c;border-radius:0 0 0.4em 0.4em" + style);
+ this._confirmation = deleteButton;
+
+ const isDeletedBadge = Translations.t.image.isDeleted
+ .SetStyle("display:block;" +
+ "background-color: black;color:white;padding:0.4em;border-radius:0.4em");
+
+ const confirmDialog = new Combine([
+ backButton,
+ deleteButton]
+ ).SetStyle("display:flex;" +
+ "flex-direction:column;" +
+ "background:black;" +
+ "color:white;" +
+ "border-radius:0.5em;" +
+ "width:max-content;" +
+ "height:min-content;");
+
+ const smallDeleteButton = new FixedUiElement("")
+ .SetStyle("display:block;" +
+ "width: 1.5em;" +
+ "height: 1.5em;" +
+ "padding: 0.5em;" +
+ "border-radius: 3em;" +
+ "background-color: black;")
const deleteButtonCheckbox = new CheckBox(
- new Combine([
- backButton,
- deleteButton]
- ).SetStyle("display:flex;" +
- "flex-direction:column;" +
- "background:black;" +
- "color:white;" +
- "border-radius:0.5em;" +
- "width:max-content;" +
- "height:min-content;"),
+ confirmDialog,
new VariableUiElement(
showDeleteButton.map(showDelete => {
if (isDeleted.data) {
- return Translations.t.image.isDeleted
- .SetStyle("display:block;" +
- "background-color: black;color:white;padding:0.4em;border-radius:0.4em").Render()
+ return isDeletedBadge.Render()
}
if (!showDelete) {
return "";
}
- return new FixedUiElement("")
- .SetStyle("display:block;" +
- "width: 1.5em;" +
- "height: 1.5em;" +
- "padding: 0.5em;" +
- "border-radius: 3em;" +
- "background-color: black;").Render();
+ return smallDeleteButton.Render();
}, [this.searcher._deletedImages, isDeleted]
)));
+ deleteButton.onClick(() => {
+ console.log("Deleting image...");
+ deleteButtonCheckbox.isEnabled.setData(false);
+ deleteButtonCheckbox.Update();
+ self.searcher.Delete(self.searcher.data[self.slideshow._currentSlide.data]);
+ });
+
+ isDeleted.addCallback(isD => {
+ if(isD){
+ deleteButtonCheckbox.isEnabled.setData(false);
+ }
+ })
+
this._deleteButton = deleteButtonCheckbox;
this._deleteButton.SetStyle(
"position:absolute;display:block;top:1em;left:5em;z-index: 7000;width:min-content;height:min-content;"
)
- this.slideshow._currentSlide.addCallback(() => {
- deleteButtonCheckbox.isEnabled.setData(false)
- })
-
- this.searcher._deletedImages.addCallback(() => {
- this.slideshow._currentSlide.ping();
- })
-
}
@@ -171,10 +176,5 @@ export class ImageCarousel extends TagDependantUIElement {
}
- Activate() {
- super.Activate();
- this.searcher.Activate();
- return this;
- }
}
\ No newline at end of file
diff --git a/UI/Image/ImageCarouselWithUpload.ts b/UI/Image/ImageCarouselWithUpload.ts
index 99e84ed2a..eaa6d2c02 100644
--- a/UI/Image/ImageCarouselWithUpload.ts
+++ b/UI/Image/ImageCarouselWithUpload.ts
@@ -50,19 +50,6 @@ class ImageCarouselWithUpload extends TagDependantUIElement {
this._pictureUploader.Render();
}
- Activate() {
- super.Activate();
- this._imageElement.Activate();
- this._pictureUploader.Activate();
- return this;
- }
-
- Update() {
- super.Update();
- this._imageElement.Update();
- this._pictureUploader.Update();
- }
-
IsKnown(): boolean {
return true;
}
diff --git a/UI/ImageUploadFlow.ts b/UI/ImageUploadFlow.ts
index edecac4bd..3be2d408a 100644
--- a/UI/ImageUploadFlow.ts
+++ b/UI/ImageUploadFlow.ts
@@ -1,16 +1,11 @@
import {UIElement} from "./UIElement";
import $ from "jquery"
-import {UserDetails} from "../Logic/Osm/OsmConnection";
import {DropDown} from "./Input/DropDown";
-import {VariableUiElement} from "./Base/VariableUIElement";
import Translations from "./i18n/Translations";
-import {fail} from "assert";
import Combine from "./Base/Combine";
-import {VerticalCombine} from "./Base/VerticalCombine";
import {State} from "../State";
import {UIEventSource} from "../Logic/UIEventSource";
import {Imgur} from "../Logic/Web/Imgur";
-import {SubtleButton} from "./Base/SubtleButton";
export class ImageUploadFlow extends UIElement {
private _licensePicker: UIElement;
@@ -107,9 +102,20 @@ export class ImageUploadFlow extends UIElement {
const label = new Combine([
" ",
Translations.t.image.addPicture
- .SetStyle("width:max-content;font-size: 28px;font-weight: bold;float: left;margin-top: 4px;padding-top: 4px;padding-bottom: 4px;padding-left: 13px;"),
+ .SetStyle("width:max-content;font-size: 28px;" +
+ "font-weight: bold;" +
+ "float: left;" +
+ "margin-top: 4px;" +
+ "padding-top: 4px;" +
+ "padding-bottom: 4px;" +
+ "padding-left: 13px;"),
- ]).SetStyle(" display: flex;cursor:pointer;padding: 0.5em;border-radius: 1em;border: 3px solid black;box-sizing:border-box;")
+ ]).SetStyle(" display: flex;" +
+ "cursor:pointer;" +
+ "padding: 0.5em;" +
+ "border-radius: 1em;" +
+ "border: 3px solid black;" +
+ "box-sizing:border-box;")
const actualInputElement =
``;
diff --git a/UI/Input/CheckBox.ts b/UI/Input/CheckBox.ts
index 20357e6b5..85baba458 100644
--- a/UI/Input/CheckBox.ts
+++ b/UI/Input/CheckBox.ts
@@ -1,20 +1,19 @@
import {UIElement} from "../UIElement";
-import { FilteredLayer } from "../../Logic/FilteredLayer";
import Translations from "../../UI/i18n/Translations";
import {UIEventSource} from "../../Logic/UIEventSource";
export class CheckBox extends UIElement{
public readonly isEnabled: UIEventSource;
- private readonly _showEnabled: string|UIElement;
- private readonly _showDisabled: string|UIElement;
+ private readonly _showEnabled: UIElement;
+ private readonly _showDisabled: UIElement;
constructor(showEnabled: string | UIElement, showDisabled: string | UIElement, data: UIEventSource | boolean = false) {
super(undefined);
this.isEnabled =
data instanceof UIEventSource ? data : new UIEventSource(data ?? false);
this.ListenTo(this.isEnabled);
- this._showEnabled = showEnabled;
- this._showDisabled = showDisabled;
+ this._showEnabled = Translations.W(showEnabled);
+ this._showDisabled =Translations.W(showDisabled);
const self = this;
this.onClick(() => {
self.isEnabled.setData(!self.isEnabled.data);
diff --git a/UI/Input/TextField.ts b/UI/Input/TextField.ts
index 30e7ff92c..44014854b 100644
--- a/UI/Input/TextField.ts
+++ b/UI/Input/TextField.ts
@@ -178,8 +178,10 @@ export class TextField extends InputElement {
return ``
}
+ const placeholder = this._placeholder.InnerRender().replace("'", "'");
+
return ``;
}
@@ -246,11 +248,5 @@ export class TextField extends InputElement {
return result !== undefined && result !== null;
}
- Clear() {
- const field = document.getElementById('text-' + this.id);
- if (field !== undefined) {
- // @ts-ignore
- field.value = "";
- }
- }
-}
\ No newline at end of file
+}
+
\ No newline at end of file
diff --git a/UI/SearchAndGo.ts b/UI/SearchAndGo.ts
index afe1f6937..047ae1e4f 100644
--- a/UI/SearchAndGo.ts
+++ b/UI/SearchAndGo.ts
@@ -44,13 +44,13 @@ export class SearchAndGo extends UIElement {
// Triggered by 'enter' or onclick
private RunSearch() {
const searchString = this._searchField.GetValue().data;
- this._searchField.Clear();
+ this._searchField.GetValue().setData("");
this._placeholder.setData(Translations.t.general.search.searching);
const self = this;
Geocoding.Search(searchString, (result) => {
if (result.length == 0) {
- this._placeholder.setData(Translations.t.general.search.nothing);
+ self._placeholder.setData(Translations.t.general.search.nothing);
return;
}
@@ -60,10 +60,11 @@ export class SearchAndGo extends UIElement {
[bb[1], bb[3]]
]
State.state.bm.map.fitBounds(bounds);
- this._placeholder.setData(Translations.t.general.search.search);
+ self._placeholder.setData(Translations.t.general.search.search);
},
() => {
- this._placeholder.setData(Translations.t.general.search.error);
+ self._searchField.GetValue().setData("");
+ self._placeholder.setData(Translations.t.general.search.error);
});
}
@@ -74,15 +75,5 @@ export class SearchAndGo extends UIElement {
}
- Update() {
- super.Update();
- this._searchField.Update();
- this._goButton.Update();
- }
- Activate() {
- super.Activate();
- this._searchField.Activate();
- this._goButton.Activate();
- }
}
\ No newline at end of file
diff --git a/UI/SlideShow.ts b/UI/SlideShow.ts
index 38ee92992..3abd0b2a2 100644
--- a/UI/SlideShow.ts
+++ b/UI/SlideShow.ts
@@ -8,8 +8,8 @@ export class SlideShow extends UIElement {
public readonly _currentSlide: UIEventSource = new UIEventSource(0);
private readonly _noimages: UIElement;
- private _prev: FixedUiElement;
- private _next: FixedUiElement;
+ private _prev: UIElement;
+ private _next: UIElement;
constructor(
embeddedElements: UIEventSource,
@@ -75,18 +75,4 @@ export class SlideShow extends UIElement {
this._currentSlide.setData(index);
}
- InnerUpdate(htmlElement) {
- this._next.Update();
- this._prev.Update();
- }
-
- Activate() {
- for (const embeddedElement of this._embeddedElements.data) {
- embeddedElement.Activate();
- }
- this._next.Update();
- this._prev.Update();
- return this;
- }
-
-}
\ No newline at end of file
+ }
\ No newline at end of file
diff --git a/UI/TagRendering.ts b/UI/TagRendering.ts
index c9a24e9ba..ab6a02eb6 100644
--- a/UI/TagRendering.ts
+++ b/UI/TagRendering.ts
@@ -179,11 +179,11 @@ export class TagRendering extends UIElement implements TagDependantUIElement {
}
const cancelContents = this._editMode.map((isEditing) => {
- if (isEditing) {
- return "" + Translations.t.general.cancel.R() + "";
- } else {
- return "" + Translations.t.general.skip.R() + "";
- }
+ const tr = Translations.t.general;
+ const text = isEditing ? tr.cancel : tr.skip;
+ return text
+ .SetStyle("display: inline-block;border: solid black 0.5px;padding: 0.2em 0.3em;border-radius: 1.5em;")
+ .Render();
}, [Locale.language]);
// And at last, set up the skip button
this._skipButton = new VariableUiElement(cancelContents).onClick(cancel);
diff --git a/UI/UIElement.ts b/UI/UIElement.ts
index 13311c078..dea90002b 100644
--- a/UI/UIElement.ts
+++ b/UI/UIElement.ts
@@ -28,6 +28,7 @@ export abstract class UIElement extends UIEventSource {
this.id = "ui-element-" + UIElement.nextId;
this._source = source;
UIElement.nextId++;
+ this.dumbMode = true;
this.ListenTo(source);
}
@@ -74,32 +75,18 @@ export abstract class UIElement extends UIEventSource {
let element = document.getElementById(this.id);
if (element === undefined || element === null) {
- // The element is not painted
-
+ // The element is not painted or, in the case of 'dumbmode' this UI-element is not explicitely present
if (this.dumbMode) {
// We update all the children anyway
- for (const i in this) {
- const child = this[i];
- if (child instanceof UIElement) {
- child.Update();
- } else if (child instanceof Array) {
- for (const ch of child) {
- if (ch instanceof UIElement) {
- ch.Update();
- }
- }
- }
- }
+ this.UpdateAllChildren();
}
-
-
return;
}
const newRender = this.InnerRender();
if (newRender !== this.lastInnerRender) {
+ this.lastInnerRender = newRender;
this.setData(this.InnerRender());
element.innerHTML = this.data;
- this.lastInnerRender = newRender;
}
if (this._hideIfEmpty) {
@@ -132,7 +119,11 @@ export abstract class UIElement extends UIEventSource {
}
this.InnerUpdate(element);
+ this.UpdateAllChildren();
+ }
+
+ private UpdateAllChildren() {
for (const i in this) {
const child = this[i];
if (child instanceof UIElement) {
@@ -146,27 +137,32 @@ export abstract class UIElement extends UIEventSource {
}
}
}
-
- HideOnEmpty(hide : boolean){
+
+ HideOnEmpty(hide: boolean) {
this._hideIfEmpty = hide;
this.Update();
return this;
}
-
+
// Called after the HTML has been replaced. Can be used for css tricks
- protected InnerUpdate(htmlElement: HTMLElement) {
- }
+ protected InnerUpdate(htmlElement: HTMLElement) {
+ }
Render(): string {
- this.lastInnerRender = this.lastInnerRender ?? this.InnerRender();
+ this.lastInnerRender = this.InnerRender();
if (this.dumbMode) {
return this.lastInnerRender;
}
+
let style = "";
if (this.style !== undefined && this.style !== "") {
- style = `style="${this.style}"`;
+ style = `style="${this.style}" `;
}
- return `${this.lastInnerRender}`
+ const clss = "";
+ if (this.clss.length > 0) {
+ `class='${this.clss.join(" ")}' `;
+ }
+ return `${this.lastInnerRender}`
}
AttachTo(divId: string) {
@@ -182,32 +178,20 @@ export abstract class UIElement extends UIEventSource {
public abstract InnerRender(): string;
- public Activate(): UIElement {
- for (const i in this) {
- const child = this[i];
- if (child instanceof UIElement) {
- child.Activate();
- } else if (child instanceof Array) {
- for (const ch of child) {
- if (ch instanceof UIElement) {
- ch.Activate();
- }
- }
- }
- }
- return this;
- };
-
public IsEmpty(): boolean {
return this.InnerRender() === "";
}
public SetClass(clss: string): UIElement {
this.dumbMode = false;
+ if(clss === "" && this.clss.length > 0){
+ this.clss = [];
+ this.Update();
+ }
if (this.clss.indexOf(clss) < 0) {
this.clss.push(clss);
+ this.Update();
}
- this.Update();
return this;
}
diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts
index 1e0f6106b..316a3f346 100644
--- a/UI/i18n/Translation.ts
+++ b/UI/i18n/Translation.ts
@@ -41,6 +41,9 @@ export default class Translation extends UIElement {
get txt(): string {
+ if(this.translations["*"]){
+ return this.translations["*"];
+ }
const txt = this.translations[Translation.forcedLanguage ?? Locale.language.data];
if (txt !== undefined) {
return txt;
@@ -79,10 +82,6 @@ export default class Translation extends UIElement {
return result;
}
- public R(): string {
- return new Translation(this.translations).Render();
- }
-
public Clone() {
return new Translation(this.translations)
}
diff --git a/customGenerator.html b/customGenerator.html
index a47a77a9a..a87a8d4d2 100644
--- a/customGenerator.html
+++ b/customGenerator.html
@@ -2,6 +2,7 @@
+
Custom Theme Generator for Mapcomplete