diff --git a/Logic/Web/Hash.ts b/Logic/Web/Hash.ts index f9329b2..4ef2691 100644 --- a/Logic/Web/Hash.ts +++ b/Logic/Web/Hash.ts @@ -1,10 +1,15 @@ import {UIEventSource} from "../UIEventSource"; +import Constants from "../../Models/Constants"; +import {Utils} from "../../Utils"; export default class Hash { public static hash : UIEventSource = Hash.Get(); private static Get() : UIEventSource{ + if(Utils.runningFromConsole){ + return new UIEventSource(undefined); + } const hash = new UIEventSource(window.location.hash.substr(1)); hash.addCallback(h => { if(h === undefined || h === ""){ diff --git a/Models/Constants.ts b/Models/Constants.ts index 35214db..2262323 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -14,7 +14,16 @@ export default class Constants { themeGeneratorReadOnlyUnlock: 200, themeGeneratorFullUnlock: 500, addNewPointWithUnreadMessagesUnlock: 500, - minZoomLevelToAddNewPoints: (Utils.isRetina() ? 18 : 19) + minZoomLevelToAddNewPoints: (Constants.isRetina() ? 18 : 19) }; + + private static isRetina(): boolean { + if (Utils.runningFromConsole) { + return; + } + // The cause for this line of code: https://github.com/pietervdvn/MapComplete/issues/115 + // See https://stackoverflow.com/questions/19689715/what-is-the-best-way-to-detect-retina-support-on-a-device-using-javascript + return ((window.matchMedia && (window.matchMedia('only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx), only screen and (min-resolution: 75.6dpcm)').matches || window.matchMedia('only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min--moz-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2)').matches)) || (window.devicePixelRatio && window.devicePixelRatio >= 2)); + } } \ No newline at end of file diff --git a/UI/Base/Img.ts b/UI/Base/Img.ts index 66b4e79..1186ae9 100644 --- a/UI/Base/Img.ts +++ b/UI/Base/Img.ts @@ -1,9 +1,12 @@ +import Constants from "../../Models/Constants"; +import {Utils} from "../../Utils"; + export default class Img { public static runningFromConsole = false; static AsData(source:string){ - if(this.runningFromConsole){ + if(Utils.runningFromConsole){ return source; } return `data:image/svg+xml;base64,${(btoa(source))}`; diff --git a/UI/UIElement.ts b/UI/UIElement.ts index 6c91ad5..d1fda3f 100644 --- a/UI/UIElement.ts +++ b/UI/UIElement.ts @@ -1,27 +1,25 @@ import {UIEventSource} from "../Logic/UIEventSource"; +import Constants from "../Models/Constants"; +import {Utils} from "../Utils"; export abstract class UIElement extends UIEventSource { - private static nextId: number = 0; - - public readonly id: string; - public readonly _source: UIEventSource; - private clss: string[] = [] - - private style: string; - - private _hideIfEmpty = false; - - public dumbMode = false; - - private lastInnerRender: string; - /** * In the 'deploy'-step, some code needs to be run by ts-node. * However, ts-node crashes when it sees 'document'. When running from console, we flag this and disable all code where document is needed. * This is a workaround and yet another hack */ public static runningFromConsole = false; + private static nextId: number = 0; + public readonly id: string; + public readonly _source: UIEventSource; + public dumbMode = false; + private clss: string[] = [] + private style: string; + private _hideIfEmpty = false; + private lastInnerRender: string; + private _onClick: () => void; + private _onHover: UIEventSource; protected constructor(source: UIEventSource = undefined) { super(""); @@ -32,7 +30,6 @@ export abstract class UIElement extends UIEventSource { this.ListenTo(source); } - public ListenTo(source: UIEventSource) { if (source === undefined) { return this; @@ -46,8 +43,6 @@ export abstract class UIElement extends UIEventSource { return this; } - private _onClick: () => void; - public onClick(f: (() => void)) { this.dumbMode = false; this._onClick = f; @@ -56,8 +51,6 @@ export abstract class UIElement extends UIEventSource { return this; } - private _onHover: UIEventSource; - public IsHovered(): UIEventSource { this.dumbMode = false; if (this._onHover !== undefined) { @@ -69,10 +62,10 @@ export abstract class UIElement extends UIEventSource { } Update(): void { - if (UIElement.runningFromConsole) { + if (Utils.runningFromConsole) { return; } - + let element = document.getElementById(this.id); if (element === undefined || element === null) { // The element is not painted or, in the case of 'dumbmode' this UI-element is not explicitely present @@ -101,7 +94,7 @@ export abstract class UIElement extends UIEventSource { const self = this; element.onclick = (e) => { // @ts-ignore - if(e.consumed){ + if (e.consumed) { return; } self._onClick(); @@ -123,31 +116,12 @@ export abstract class UIElement extends UIEventSource { } - private UpdateAllChildren() { - 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(); - } - } - } - } - } - 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) { - } - Render(): string { this.lastInnerRender = this.InnerRender(); if (this.dumbMode) { @@ -192,6 +166,7 @@ export abstract class UIElement extends UIEventSource { } return this; } + public RemoveClass(clss: string): UIElement { const i = this.clss.indexOf(clss); if (i >= 0) { @@ -201,13 +176,31 @@ export abstract class UIElement extends UIEventSource { return this; } - public SetStyle(style: string): UIElement { this.dumbMode = false; this.style = style; this.Update(); return this; } + + // Called after the HTML has been replaced. Can be used for css tricks + protected InnerUpdate(htmlElement: HTMLElement) { + } + + private UpdateAllChildren() { + 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(); + } + } + } + } + } } diff --git a/UI/i18n/Locale.ts b/UI/i18n/Locale.ts index 9482766..55365ce 100644 --- a/UI/i18n/Locale.ts +++ b/UI/i18n/Locale.ts @@ -1,6 +1,6 @@ import {UIEventSource} from "../../Logic/UIEventSource"; -import {UIElement} from "../UIElement"; import {LocalStorageSource} from "../../Logic/Web/LocalStorageSource"; +import {Utils} from "../../Utils"; export default class Locale { @@ -9,7 +9,7 @@ export default class Locale { private static setup() { const source = LocalStorageSource.Get('language', "en"); - if (!UIElement.runningFromConsole) { + if (!Utils.runningFromConsole) { // @ts-ignore window.setLanguage = function (language: string) { source.setData(language) diff --git a/Utils.ts b/Utils.ts index 7866df2..177d528 100644 --- a/Utils.ts +++ b/Utils.ts @@ -1,8 +1,16 @@ -import {UIElement} from "./UI/UIElement"; import * as $ from "jquery" +import Constants from "./Models/Constants"; + export class Utils { + /** + * In the 'deploy'-step, some code needs to be run by ts-node. + * However, ts-node crashes when it sees 'document'. When running from console, we flag this and disable all code where document is needed. + * This is a workaround and yet another hack + */ + public static runningFromConsole = false; + public static readonly assets_path = "./assets/svg/"; static EncodeXmlValue(str) { @@ -59,7 +67,7 @@ export class Utils { } static DoEvery(millis: number, f: (() => void)) { - if (UIElement.runningFromConsole) { + if (Utils.runningFromConsole) { return; } window.setTimeout( @@ -134,15 +142,6 @@ export class Utils { return [a.substr(0, index), a.substr(index + sep.length)]; } - public static isRetina(): boolean { - if (UIElement.runningFromConsole) { - return; - } - // The cause for this line of code: https://github.com/pietervdvn/MapComplete/issues/115 - // See https://stackoverflow.com/questions/19689715/what-is-the-best-way-to-detect-retina-support-on-a-device-using-javascript - return ((window.matchMedia && (window.matchMedia('only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx), only screen and (min-resolution: 75.6dpcm)').matches || window.matchMedia('only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min--moz-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2)').matches)) || (window.devicePixelRatio && window.devicePixelRatio >= 2)); - } - // Date will be undefined on failure public static changesetDate(id: number, action: ((isFound: Date) => void)): void { $.getJSON("https://www.openstreetmap.org/api/0.6/changeset/" + id, diff --git a/assets/themes/bicycle_library/bicycle_library.json b/assets/themes/bicycle_library/bicycle_library.json index 45f22c8..93c8d01 100644 --- a/assets/themes/bicycle_library/bicycle_library.json +++ b/assets/themes/bicycle_library/bicycle_library.json @@ -4,11 +4,11 @@ "version": "2020-08-29", "language": [ "en", - "nl", + "nl" ], "title": { "en": "Bicycle libraries", - "nl": "Fietsbibliotheken", + "nl": "Fietsbibliotheken" }, "description": { "nl": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.", diff --git a/scripts/createLayouts.ts b/scripts/createLayouts.ts index 38d3970..46ebd91 100644 --- a/scripts/createLayouts.ts +++ b/scripts/createLayouts.ts @@ -1,16 +1,16 @@ -import Img from "../UI/Base/Img" -import {UIElement} from "../UI/UIElement"; -Img.runningFromConsole = true; // We HAVE to mark this while importing -UIElement.runningFromConsole = true; +import {Utils} from "../Utils"; +Utils.runningFromConsole = true; +import LayoutConfig from "../Customizations/JSON/LayoutConfig"; import {AllKnownLayouts} from "../Customizations/AllKnownLayouts"; import {existsSync, mkdirSync, readFileSync, writeFile, writeFileSync} from "fs"; import Locale from "../UI/i18n/Locale"; import svg2img from 'promise-svg2img'; import Translations from "../UI/i18n/Translations"; import {Translation} from "../UI/i18n/Translation"; -import LayoutConfig from "../Customizations/JSON/LayoutConfig"; + + function enc(str: string): string { return encodeURIComponent(str.toLowerCase()); diff --git a/test/Tag.spec.ts b/test/Tag.spec.ts index 3bc9c9b..4ef6ddf 100644 --- a/test/Tag.spec.ts +++ b/test/Tag.spec.ts @@ -1,7 +1,5 @@ import {UIElement} from "../UI/UIElement"; UIElement.runningFromConsole = true; -import Img from "../UI/Base/Img"; -Img.runningFromConsole = true; import {equal} from "assert"; import T from "./TestHelper"; import {FromJSON} from "../Customizations/JSON/FromJSON";