diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 7f710b31b..546d1db53 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -69,7 +69,7 @@ jobs: cat circular-dependencies lines=$(cat circular-dependencies | wc -l) echo "Total circular dependencies: $lines" - test $lines -eq 130 + test $lines -eq 90 - name: JavaScript code compatibility run: | npx check-es-compat www/*.js --polyfills="\{Array,String,TypedArray\}.prototype.at,Object.hasOwn" diff --git a/src/core/features/compile/services/compile.ts b/src/core/features/compile/services/compile.ts index 8c9f316b9..688c75576 100644 --- a/src/core/features/compile/services/compile.ts +++ b/src/core/features/compile/services/compile.ts @@ -79,23 +79,30 @@ import { Md5 } from 'ts-md5/dist/md5'; // Import core classes that can be useful for site plugins. import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreArray } from '@singletons/array'; +import { CoreCache } from '@classes/cache'; import { CoreColors } from '@singletons/colors'; +import { CoreCountries } from '@singletons/countries'; +import { CoreDelegate } from '@classes/delegate'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; import { CoreDom } from '@singletons/dom'; +import { CoreFileUtils } from '@singletons/file-utils'; import { CoreForms } from '@singletons/form'; +import { CoreGeolocationError, CoreGeolocationErrorReason } from '@services/geolocation'; import { CoreKeyboard } from '@singletons/keyboard'; +import { CoreMedia } from '@singletons/media'; +import { CoreNetwork } from '@services/network'; import { CoreObject } from '@singletons/object'; +import { CoreOpener } from '@singletons/opener'; import { CorePath } from '@singletons/path'; +import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreSSO } from '@singletons/sso'; import { CoreText } from '@singletons/text'; import { CoreTime } from '@singletons/time'; import { CoreUrl } from '@singletons/url'; +import { CoreUtils } from '@singletons/utils'; import { CoreWait } from '@singletons/wait'; import { CoreWindow } from '@singletons/window'; -import { CoreCache } from '@classes/cache'; -import { CoreDelegate } from '@classes/delegate'; -import { CoreGeolocationError, CoreGeolocationErrorReason } from '@services/geolocation'; import { getCoreErrorsExportedObjects } from '@classes/errors/errors'; -import { CoreNetwork } from '@services/network'; // Import all core modules that define components, directives and pipes. import { CoreSharedModule } from '@/core/shared.module'; @@ -312,19 +319,26 @@ export class CoreCompileProvider { */ instance['Network'] = CoreNetwork.instance; instance['CoreNetwork'] = CoreNetwork.instance; - instance['CorePlatform'] = CorePlatform.instance; - instance['CoreSyncBaseProvider'] = CoreSyncBaseProvider; instance['CoreArray'] = CoreArray; instance['CoreColors'] = CoreColors; + instance['CoreCountries'] = CoreCountries; instance['CoreDirectivesRegistry'] = CoreDirectivesRegistry; instance['CoreDom'] = CoreDom; + instance['CoreFileUtils'] = CoreFileUtils; instance['CoreForms'] = CoreForms; instance['CoreKeyboard'] = CoreKeyboard; + instance['CoreMedia'] = CoreMedia; instance['CoreObject'] = CoreObject; + instance['CoreOpener'] = CoreOpener; instance['CorePath'] = CorePath; + instance['CorePlatform'] = CorePlatform.instance; + instance['CorePromiseUtils'] = CorePromiseUtils; + instance['CoreSSO'] = CoreSSO; + instance['CoreSyncBaseProvider'] = CoreSyncBaseProvider; instance['CoreText'] = CoreText; instance['CoreTime'] = CoreTime; instance['CoreUrl'] = CoreUrl; + instance['CoreUtils'] = CoreUtils; instance['CoreWait'] = CoreWait; instance['CoreWindow'] = CoreWindow; instance['CoreCache'] = CoreCache; // @deprecated since 4.4, plugins should use plain objects instead. diff --git a/src/core/singletons/browser.ts b/src/core/singletons/browser.ts index 5ff1d3dde..30628431b 100644 --- a/src/core/singletons/browser.ts +++ b/src/core/singletons/browser.ts @@ -14,9 +14,16 @@ /** * Helpers to interact with Browser APIs. + * + * This singleton is not necessary to be exported for site plugins. */ export class CoreBrowser { + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Check whether the given cookie is set. * @@ -34,9 +41,9 @@ export class CoreBrowser { * @returns Whether the development setting is set. */ static hasDevelopmentSetting(name: string): boolean { - const setting = this.getDevelopmentSettingKey(name); + const setting = CoreBrowser.getDevelopmentSettingKey(name); - return this.hasCookie(setting) || this.hasLocalStorage(setting); + return CoreBrowser.hasCookie(setting) || CoreBrowser.hasLocalStorage(setting); } /** @@ -84,9 +91,9 @@ export class CoreBrowser { * @returns Development setting value. */ static getDevelopmentSetting(name: string): string | null { - const setting = this.getDevelopmentSettingKey(name); + const setting = CoreBrowser.getDevelopmentSettingKey(name); - return this.getCookie(setting) ?? this.getLocalStorage(setting); + return CoreBrowser.getCookie(setting) ?? CoreBrowser.getLocalStorage(setting); } /** @@ -96,7 +103,7 @@ export class CoreBrowser { * @param value Setting value. */ static setDevelopmentSetting(name: string, value: string): void { - const setting = this.getDevelopmentSettingKey(name); + const setting = CoreBrowser.getDevelopmentSettingKey(name); document.cookie = `${setting}=${value};path=/`; localStorage.setItem(setting, value); @@ -108,7 +115,7 @@ export class CoreBrowser { * @param name Setting name. */ static clearDevelopmentSetting(name: string): void { - const setting = this.getDevelopmentSettingKey(name); + const setting = CoreBrowser.getDevelopmentSettingKey(name); document.cookie = `${setting}=;path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT`; localStorage.removeItem(setting); diff --git a/src/core/singletons/colors.ts b/src/core/singletons/colors.ts index 806fffe74..8fdd18acc 100644 --- a/src/core/singletons/colors.ts +++ b/src/core/singletons/colors.ts @@ -42,6 +42,11 @@ export enum CoreIonicColorNames { */ export class CoreColors { + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Returns better contrast color. * @@ -99,7 +104,7 @@ export class CoreColors { } const hex = [0,1,2].map( - (idx) => this.componentToHex(rgba[idx]), + (idx) => CoreColors.componentToHex(rgba[idx]), ).join(''); return '#' + hex; diff --git a/src/core/singletons/directives-registry.ts b/src/core/singletons/directives-registry.ts index 50fc996b6..47e911571 100644 --- a/src/core/singletons/directives-registry.ts +++ b/src/core/singletons/directives-registry.ts @@ -32,9 +32,9 @@ export class CoreDirectivesRegistry { * @param instance Directive instance. */ static register(element: Element, instance: unknown): void { - const list = this.instances.get(element) ?? []; + const list = CoreDirectivesRegistry.instances.get(element) ?? []; list.push(instance); - this.instances.set(element, list); + CoreDirectivesRegistry.instances.set(element, list); } /** @@ -45,7 +45,7 @@ export class CoreDirectivesRegistry { * @returns Directive instance. */ static resolve(element?: Element | null, directiveClass?: DirectiveConstructor): T | null { - const list = (element && this.instances.get(element) as T[]) ?? []; + const list = (element && CoreDirectivesRegistry.instances.get(element) as T[]) ?? []; return list.find(instance => !directiveClass || instance instanceof directiveClass) ?? null; } @@ -58,7 +58,7 @@ export class CoreDirectivesRegistry { * @returns Directive instances. */ static resolveAll(element?: Element | null, directiveClass?: DirectiveConstructor): T[] { - const list = (element && this.instances.get(element) as T[]) ?? []; + const list = (element && CoreDirectivesRegistry.instances.get(element) as T[]) ?? []; return list.filter(instance => !directiveClass || instance instanceof directiveClass) ?? []; } @@ -71,7 +71,7 @@ export class CoreDirectivesRegistry { * @returns Directive instance. */ static require(element: Element, directiveClass?: DirectiveConstructor): T { - const instance = this.resolve(element, directiveClass); + const instance = CoreDirectivesRegistry.resolve(element, directiveClass); if (!instance) { throw new Error('Couldn\'t resolve directive instance'); @@ -91,9 +91,9 @@ export class CoreDirectivesRegistry { element: Element | null, directiveClass?: DirectiveConstructor, ): Promise { - const instance = this.resolve(element, directiveClass); + const instance = CoreDirectivesRegistry.resolve(element, directiveClass); if (!instance) { - this.logger.error('No instance registered for element ' + directiveClass, element); + CoreDirectivesRegistry.logger.error('No instance registered for element ' + directiveClass, element); return; } @@ -129,7 +129,7 @@ export class CoreDirectivesRegistry { } await Promise.all(elements.map(async element => { - const instances = this.resolveAll(element, directiveClass); + const instances = CoreDirectivesRegistry.resolveAll(element, directiveClass); await Promise.all(instances.map(instance => instance.ready())); })); @@ -139,7 +139,7 @@ export class CoreDirectivesRegistry { // Check if there are new elements now that the found elements are ready (there could be nested elements). if (elements.length !== findElements().length) { - await this.waitDirectivesReady(element, selector, directiveClass); + await CoreDirectivesRegistry.waitDirectivesReady(element, selector, directiveClass); } } @@ -174,7 +174,7 @@ export class CoreDirectivesRegistry { allElements = allElements.concat(elements); await Promise.all(elements.map(async element => { - const instances = this.resolveAll(element, directive.class); + const instances = CoreDirectivesRegistry.resolveAll(element, directive.class); await Promise.all(instances.map(instance => instance.ready())); })); @@ -191,7 +191,7 @@ export class CoreDirectivesRegistry { }, []); if (allElements.length !== elementsAfterReady.length) { - await this.waitMultipleDirectivesReady(element, directives); + await CoreDirectivesRegistry.waitMultipleDirectivesReady(element, directives); } } diff --git a/src/core/singletons/dom.ts b/src/core/singletons/dom.ts index 34a671a62..2e91e4124 100644 --- a/src/core/singletons/dom.ts +++ b/src/core/singletons/dom.ts @@ -512,7 +512,7 @@ export class CoreDom { return resolve(); } - unsubscribe = this.watchElementInViewport(element, intersectionRatio, inViewport => { + unsubscribe = CoreDom.watchElementInViewport(element, intersectionRatio, inViewport => { if (!inViewport) { return; } @@ -632,7 +632,7 @@ export class CoreDom { const value = styles.getPropertyValue(property); if (property === 'font-size') { - if (this.fontSizeZoom === null) { + if (CoreDom.fontSizeZoom === null) { const baseFontSize = 20; const span = document.createElement('span'); span.style.opacity = '0'; @@ -640,13 +640,13 @@ export class CoreDom { document.body.append(span); - this.fontSizeZoom = baseFontSize / Number(getComputedStyle(span).fontSize.slice(0, -2)); + CoreDom.fontSizeZoom = baseFontSize / Number(getComputedStyle(span).fontSize.slice(0, -2)); span.remove(); } - if (this.fontSizeZoom !== 1) { - return `calc(${this.fontSizeZoom} * ${value})`; + if (CoreDom.fontSizeZoom !== 1) { + return `calc(${CoreDom.fontSizeZoom} * ${value})`; } } diff --git a/src/core/singletons/error-logs.ts b/src/core/singletons/error-logs.ts index 8f828034b..f0b02c73b 100644 --- a/src/core/singletons/error-logs.ts +++ b/src/core/singletons/error-logs.ts @@ -11,24 +11,26 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable } from '@angular/core'; -import { makeSingleton } from '@singletons'; /** * Service that stores error logs in memory. */ -@Injectable({ providedIn: 'root' }) -export class CoreErrorLogsService { +export class CoreErrorLogs { - protected errorLogs: CoreSettingsErrorLog[] = []; + protected static errorLogs: CoreSettingsErrorLog[] = []; + + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } /** * Retrieve error logs displayed in the DOM. * * @returns Error logs */ - getErrorLogs(): CoreSettingsErrorLog[] { - return this.errorLogs; + static getErrorLogs(): CoreSettingsErrorLog[] { + return CoreErrorLogs.errorLogs; } /** @@ -36,14 +38,12 @@ export class CoreErrorLogsService { * * @param error Error. */ - addErrorLog(error: CoreSettingsErrorLog): void { - this.errorLogs.push(error); + static addErrorLog(error: CoreSettingsErrorLog): void { + CoreErrorLogs.errorLogs.push(error); } } -export const CoreErrorLogs = makeSingleton(CoreErrorLogsService); - export type CoreSettingsErrorLog = { data?: unknown; message: string; diff --git a/src/core/singletons/events.ts b/src/core/singletons/events.ts index 53ec4d871..df42a0a96 100644 --- a/src/core/singletons/events.ts +++ b/src/core/singletons/events.ts @@ -122,6 +122,11 @@ export class CoreEvents { protected static observables: { [eventName: string]: Subject } = {}; protected static uniqueEvents: { [eventName: string]: {data: unknown} } = {}; + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Listen for a certain event. To stop listening to the event: * let observer = eventsProvider.on('something', myCallBack); @@ -140,8 +145,8 @@ export class CoreEvents { ): CoreEventObserver { // If it's a unique event and has been triggered already, call the callBack. // We don't need to create an observer because the event won't be triggered again. - if (this.uniqueEvents[eventName]) { - callBack(this.uniqueEvents[eventName].data as CoreEventData & CoreEventSiteData); + if (CoreEvents.uniqueEvents[eventName]) { + callBack(CoreEvents.uniqueEvents[eventName].data as CoreEventData & CoreEventSiteData); // Return a fake observer to prevent errors. return { @@ -151,14 +156,14 @@ export class CoreEvents { }; } - this.logger.debug(`New observer listening to event '${eventName}'`); + CoreEvents.logger.debug(`New observer listening to event '${eventName}'`); - if (this.observables[eventName] === undefined) { + if (CoreEvents.observables[eventName] === undefined) { // No observable for this event, create a new one. - this.observables[eventName] = new Subject(); + CoreEvents.observables[eventName] = new Subject(); } - const subscription = this.observables[eventName].subscribe( + const subscription = CoreEvents.observables[eventName].subscribe( (value: CoreEventData & CoreEventSiteData) => { if (!siteId || value.siteId == siteId) { callBack(value); @@ -169,7 +174,7 @@ export class CoreEvents { // Create and return a CoreEventObserver. return { off: (): void => { - this.logger.debug(`Stop listening to event '${eventName}'`); + CoreEvents.logger.debug(`Stop listening to event '${eventName}'`); subscription.unsubscribe(); }, }; @@ -211,7 +216,7 @@ export class CoreEvents { * @returns Observer to stop listening. */ static onMultiple(eventNames: string[], callBack: (value: T) => void, siteId?: string): CoreEventObserver { - const observers = eventNames.map((name) => this.on(name, callBack, siteId)); + const observers = eventNames.map((name) => CoreEvents.on(name, callBack, siteId)); // Create and return a CoreEventObserver. return { @@ -235,12 +240,12 @@ export class CoreEvents { data?: CoreEventData, siteId?: string, ): void { - this.logger.debug(`Event '${eventName}' triggered.`); - if (this.observables[eventName]) { + CoreEvents.logger.debug(`Event '${eventName}' triggered.`); + if (CoreEvents.observables[eventName]) { if (siteId) { Object.assign(data || {}, { siteId }); } - this.observables[eventName].next(data || {}); + CoreEvents.observables[eventName].next(data || {}); } } @@ -256,23 +261,23 @@ export class CoreEvents { data: CoreEventData, siteId?: string, ): void { - if (this.uniqueEvents[eventName]) { - this.logger.debug(`Unique event '${eventName}' ignored because it was already triggered.`); + if (CoreEvents.uniqueEvents[eventName]) { + CoreEvents.logger.debug(`Unique event '${eventName}' ignored because it was already triggered.`); } else { - this.logger.debug(`Unique event '${eventName}' triggered.`); + CoreEvents.logger.debug(`Unique event '${eventName}' triggered.`); if (siteId) { Object.assign(data || {}, { siteId }); } // Store the data so it can be passed to observers that register from now on. - this.uniqueEvents[eventName] = { + CoreEvents.uniqueEvents[eventName] = { data, }; // Now pass the data to observers. - if (this.observables[eventName]) { - this.observables[eventName].next(data); + if (CoreEvents.observables[eventName]) { + CoreEvents.observables[eventName].next(data); } } } @@ -283,7 +288,7 @@ export class CoreEvents { * @param eventName Event name. */ static waitUntil(eventName: string): Promise { - return new Promise(resolve => this.once(eventName, () => resolve())); + return new Promise(resolve => CoreEvents.once(eventName, () => resolve())); } } diff --git a/src/core/singletons/form.ts b/src/core/singletons/form.ts index 5cdc0d77c..80ccda79f 100644 --- a/src/core/singletons/form.ts +++ b/src/core/singletons/form.ts @@ -22,6 +22,11 @@ export class CoreForms { private static formIds: Record = {}; + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Get the data from a form. It will only collect elements that have a name. * @@ -102,9 +107,9 @@ export class CoreForms { * @returns Unique id. */ static uniqueId(name: string): string { - const count = this.formIds[name] ?? 0; + const count = CoreForms.formIds[name] ?? 0; - return `${name}-${this.formIds[name] = count + 1}`; + return `${name}-${CoreForms.formIds[name] = count + 1}`; } } diff --git a/src/core/singletons/html-classes.ts b/src/core/singletons/html-classes.ts index 9803f1e19..27b1ccaad 100644 --- a/src/core/singletons/html-classes.ts +++ b/src/core/singletons/html-classes.ts @@ -29,6 +29,11 @@ export class CoreHTMLClasses { protected static readonly MOODLEAPP_VERSION_PREFIX = 'moodleapp-'; protected static readonly MOODLE_SITE_THEME_PREFIX = 'theme-site-'; + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Initialize HTML classes. */ @@ -101,10 +106,10 @@ export class CoreHTMLClasses { */ static addSiteClasses(siteInfo: CoreSiteInfo | CoreSiteInfoResponse): void { // Add version classes to html tag. - this.removeSiteClasses(); + CoreHTMLClasses.removeSiteClasses(); - this.addVersionClass(CoreHTMLClasses.MOODLE_VERSION_PREFIX, CoreSites.getReleaseNumber(siteInfo.release || '')); - this.addSiteUrlClass(siteInfo.siteurl); + CoreHTMLClasses.addVersionClass(CoreHTMLClasses.MOODLE_VERSION_PREFIX, CoreSites.getReleaseNumber(siteInfo.release || '')); + CoreHTMLClasses.addSiteUrlClass(siteInfo.siteurl); if (siteInfo.theme) { CoreHTMLClasses.toggleModeClass(CoreHTMLClasses.MOODLE_SITE_THEME_PREFIX + siteInfo.theme, true); @@ -116,7 +121,7 @@ export class CoreHTMLClasses { */ static removeSiteClasses(): void { // Remove version classes from html tag. - this.removeModeClasses( + CoreHTMLClasses.removeModeClasses( [ CoreHTMLClasses.MOODLE_VERSION_PREFIX, CoreHTMLClasses.MOODLE_SITE_URL_PREFIX, @@ -161,7 +166,7 @@ export class CoreHTMLClasses { * Convenience function to add site url to html classes. */ static addSiteUrlClass(siteUrl: string): void { - const className = this.urlToClassName(siteUrl); + const className = CoreHTMLClasses.urlToClassName(siteUrl); CoreHTMLClasses.toggleModeClass(CoreHTMLClasses.MOODLE_SITE_URL_PREFIX + className, true); } diff --git a/src/core/singletons/icons.ts b/src/core/singletons/icons.ts index 2a49c7c28..de179372f 100644 --- a/src/core/singletons/icons.ts +++ b/src/core/singletons/icons.ts @@ -28,6 +28,11 @@ export class CoreIcons { protected static logger = CoreLogger.getInstance('CoreIcons'); + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Add custom icons to Ionicons. */ @@ -47,7 +52,7 @@ export class CoreIcons { if (CoreIcons.ALIASES[icon]) { if (isAppIcon) { - this.logger.error(`Icon ${icon} is an alias of ${CoreIcons.ALIASES[icon]}, please use the new name.`); + CoreIcons.logger.error(`Icon ${icon} is an alias of ${CoreIcons.ALIASES[icon]}, please use the new name.`); } return { newLibrary, fileName: CoreIcons.ALIASES[icon] }; @@ -73,7 +78,7 @@ export class CoreIcons { CoreIcons.CUSTOM_ICONS[icon] === undefined && CoreIcons.CUSTOM_ICONS[CoreIcons.prefixIconName(font, library, icon)] === undefined ) { - this.logger.error(`Icon ${icon} not found`); + CoreIcons.logger.error(`Icon ${icon} not found`); } } diff --git a/src/core/singletons/keyboard.ts b/src/core/singletons/keyboard.ts index bb44c0d43..2c3c01269 100644 --- a/src/core/singletons/keyboard.ts +++ b/src/core/singletons/keyboard.ts @@ -25,6 +25,11 @@ export class CoreKeyboard { protected static keyboardOpening = false; protected static keyboardClosing = false; + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Closes the keyboard. */ @@ -51,7 +56,7 @@ export class CoreKeyboard { */ static onKeyboardShow(keyboardHeight: number): void { document.body.classList.add('keyboard-is-open'); - this.setKeyboardShown(true); + CoreKeyboard.setKeyboardShown(true); // Error on iOS calculating size. // More info: https://github.com/ionic-team/ionic-plugin-keyboard/issues/276 . CoreEvents.trigger(CoreEvents.KEYBOARD_CHANGE, keyboardHeight); @@ -62,7 +67,7 @@ export class CoreKeyboard { */ static onKeyboardHide(): void { document.body.classList.remove('keyboard-is-open'); - this.setKeyboardShown(false); + CoreKeyboard.setKeyboardShown(false); CoreEvents.trigger(CoreEvents.KEYBOARD_CHANGE, 0); } diff --git a/src/core/singletons/math.ts b/src/core/singletons/math.ts index af51906ae..d1bb2a9d6 100644 --- a/src/core/singletons/math.ts +++ b/src/core/singletons/math.ts @@ -17,6 +17,11 @@ */ export class CoreMath { + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Clamp a value between a minimum and a maximum. * diff --git a/src/core/singletons/subscriptions.ts b/src/core/singletons/subscriptions.ts index b0cea166d..cb7acb873 100644 --- a/src/core/singletons/subscriptions.ts +++ b/src/core/singletons/subscriptions.ts @@ -26,6 +26,11 @@ type Subscribable = EventEmitter | Observable; */ export class CoreSubscriptions { + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Listen once to a subscribable object. * diff --git a/src/core/singletons/swiper.ts b/src/core/singletons/swiper.ts index 46cb7bb3d..9dbf5ab7d 100644 --- a/src/core/singletons/swiper.ts +++ b/src/core/singletons/swiper.ts @@ -23,6 +23,11 @@ import { SwiperOptions } from 'swiper/types'; */ export class CoreSwiper { + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Initialize a Swiper instance. * It will return swiper instance if current is not set or destroyed and new is set and not destroyed. diff --git a/src/core/singletons/time.ts b/src/core/singletons/time.ts index a1015828d..f647b02e4 100644 --- a/src/core/singletons/time.ts +++ b/src/core/singletons/time.ts @@ -78,6 +78,11 @@ export class CoreTime { '13.0': 'Etc/GMT-13', }; + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Returns years, months, days, hours, minutes and seconds in a human readable format. * diff --git a/src/core/singletons/wait.ts b/src/core/singletons/wait.ts index 72e6c6ea8..b4d41bebe 100644 --- a/src/core/singletons/wait.ts +++ b/src/core/singletons/wait.ts @@ -20,6 +20,11 @@ import { CorePlatform } from '@services/platform'; */ export class CoreWait { + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + /** * Wait until the next tick. *