forked from EVOgeek/Vmeda.Online
		
	MOBILE-4653 chore: Fix singleton constructors and compiler
This commit is contained in:
		
							parent
							
								
									43606fbfb1
								
							
						
					
					
						commit
						0a37db2151
					
				
							
								
								
									
										2
									
								
								.github/workflows/testing.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/testing.yml
									
									
									
									
										vendored
									
									
								
							@ -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"
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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<T>(element?: Element | null, directiveClass?: DirectiveConstructor<T>): 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<T>(element?: Element | null, directiveClass?: DirectiveConstructor<T>): 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<T>(element: Element, directiveClass?: DirectiveConstructor<T>): 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<T>,
 | 
			
		||||
    ): Promise<void> {
 | 
			
		||||
        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<T>(element, directiveClass);
 | 
			
		||||
            const instances = CoreDirectivesRegistry.resolveAll<T>(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<AsyncDirective>(element, directive.class);
 | 
			
		||||
                const instances = CoreDirectivesRegistry.resolveAll<AsyncDirective>(element, directive.class);
 | 
			
		||||
 | 
			
		||||
                await Promise.all(instances.map(instance => instance.ready()));
 | 
			
		||||
            }));
 | 
			
		||||
@ -191,7 +191,7 @@ export class CoreDirectivesRegistry {
 | 
			
		||||
        }, <Element[]> []);
 | 
			
		||||
 | 
			
		||||
        if (allElements.length !== elementsAfterReady.length) {
 | 
			
		||||
            await this.waitMultipleDirectivesReady(element, directives);
 | 
			
		||||
            await CoreDirectivesRegistry.waitMultipleDirectivesReady(element, directives);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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})`;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -122,6 +122,11 @@ export class CoreEvents {
 | 
			
		||||
    protected static observables: { [eventName: string]: Subject<unknown> } = {};
 | 
			
		||||
    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<Event, Fallback> & CoreEventSiteData);
 | 
			
		||||
        if (CoreEvents.uniqueEvents[eventName]) {
 | 
			
		||||
            callBack(CoreEvents.uniqueEvents[eventName].data as CoreEventData<Event, Fallback> & 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<Event, Fallback> & 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<T = unknown>(eventNames: string[], callBack: (value: T) => void, siteId?: string): CoreEventObserver {
 | 
			
		||||
        const observers = eventNames.map((name) => this.on<T>(name, callBack, siteId));
 | 
			
		||||
        const observers = eventNames.map((name) => CoreEvents.on<T>(name, callBack, siteId));
 | 
			
		||||
 | 
			
		||||
        // Create and return a CoreEventObserver.
 | 
			
		||||
        return {
 | 
			
		||||
@ -235,12 +240,12 @@ export class CoreEvents {
 | 
			
		||||
        data?: CoreEventData<Event, Fallback>,
 | 
			
		||||
        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<Event, Fallback>,
 | 
			
		||||
        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<void> {
 | 
			
		||||
        return new Promise(resolve => this.once(eventName, () => resolve()));
 | 
			
		||||
        return new Promise(resolve => CoreEvents.once(eventName, () => resolve()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,11 @@ export class CoreForms {
 | 
			
		||||
 | 
			
		||||
    private static formIds: Record<string, number> = {};
 | 
			
		||||
 | 
			
		||||
    // 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}`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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`);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,11 @@ type Subscribable<T> = EventEmitter<T> | Observable<T>;
 | 
			
		||||
 */
 | 
			
		||||
export class CoreSubscriptions {
 | 
			
		||||
 | 
			
		||||
    // Avoid creating singleton instances.
 | 
			
		||||
    private constructor() {
 | 
			
		||||
        // Nothing to do.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Listen once to a subscribable object.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user