diff --git a/src/core/components/context-menu/context-menu.ts b/src/core/components/context-menu/context-menu.ts index e981e7500..157407562 100644 --- a/src/core/components/context-menu/context-menu.ts +++ b/src/core/components/context-menu/context-menu.ts @@ -20,6 +20,7 @@ import { CoreUtils } from '@services/utils/utils'; import { Translate } from '@singletons'; import { CoreContextMenuItemComponent } from './context-menu-item'; import { CoreContextMenuPopoverComponent } from './context-menu-popover'; +import { CoreComponentsRegistry } from '@singletons/components-registry'; /** * This component adds a button (usually in the navigation bar) that displays a context menu popover. @@ -60,7 +61,7 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy { // Calculate the unique ID. this.uniqueId = 'core-context-menu-' + CoreUtils.getUniqueId('CoreContextMenuComponent'); - CoreDomUtils.storeInstanceByElement(elementRef.nativeElement, this); + CoreComponentsRegistry.register(elementRef.nativeElement, this); } /** diff --git a/src/core/components/navbar-buttons/navbar-buttons.ts b/src/core/components/navbar-buttons/navbar-buttons.ts index 48439908e..205ec43db 100644 --- a/src/core/components/navbar-buttons/navbar-buttons.ts +++ b/src/core/components/navbar-buttons/navbar-buttons.ts @@ -25,6 +25,7 @@ import { import { CoreLogger } from '@singletons/logger'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreContextMenuComponent } from '../context-menu/context-menu'; +import { CoreComponentsRegistry } from '@singletons/components-registry'; const BUTTON_HIDDEN_CLASS = 'core-navbar-button-hidden'; @@ -80,7 +81,7 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy { this.element = element.nativeElement; this.logger = CoreLogger.getInstance('CoreNavBarButtonsComponent'); - CoreDomUtils.storeInstanceByElement(this.element, this); + CoreComponentsRegistry.register(this.element, this); } /** @@ -154,11 +155,11 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy { } const mainContextMenu = buttonsContainer.querySelector('core-context-menu'); - const secondaryContextMenuInstance = CoreDomUtils.getInstanceByElement(secondaryContextMenu); - let mainContextMenuInstance: CoreContextMenuComponent | undefined; + const secondaryContextMenuInstance = CoreComponentsRegistry.resolve(secondaryContextMenu, CoreContextMenuComponent); + let mainContextMenuInstance: CoreContextMenuComponent | null; if (mainContextMenu) { // Both containers have a context menu. Merge them to prevent having 2 menus at the same time. - mainContextMenuInstance = CoreDomUtils.getInstanceByElement(mainContextMenu); + mainContextMenuInstance = CoreComponentsRegistry.resolve(mainContextMenu, CoreContextMenuComponent); } else { // There is a context-menu in these buttons, but there is no main context menu in the header. // Create one main context menu dynamically. diff --git a/src/core/components/tabs-outlet/tabs-outlet.ts b/src/core/components/tabs-outlet/tabs-outlet.ts index d7575f2fe..32f0f7872 100644 --- a/src/core/components/tabs-outlet/tabs-outlet.ts +++ b/src/core/components/tabs-outlet/tabs-outlet.ts @@ -29,7 +29,6 @@ import { Subscription } from 'rxjs'; import { CoreUtils } from '@services/utils/utils'; import { Params } from '@angular/router'; import { CoreNavBarButtonsComponent } from '../navbar-buttons/navbar-buttons'; -import { CoreDomUtils } from '@services/utils/dom'; import { StackEvent } from '@ionic/angular/directives/navigation/stack-utils'; import { CoreNavigator } from '@services/navigator'; import { CoreTabBase, CoreTabsBaseComponent } from '@classes/tabs'; @@ -188,7 +187,7 @@ export class CoreTabsOutletComponent extends CoreTabsBaseComponent { - const instance = CoreDomUtils.getInstanceByElement(element); + const instance = CoreComponentsRegistry.resolve(element, CoreNavBarButtonsComponent); if (instance) { const pagetagName = element.closest('.ion-page')?.tagName; diff --git a/src/core/components/tabs/tab.ts b/src/core/components/tabs/tab.ts index 0fb0865fb..2d3166fd5 100644 --- a/src/core/components/tabs/tab.ts +++ b/src/core/components/tabs/tab.ts @@ -15,8 +15,8 @@ import { Component, Input, Output, OnInit, OnDestroy, ElementRef, EventEmitter, ContentChild, TemplateRef } from '@angular/core'; import { CoreTabBase } from '@classes/tabs'; -import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; +import { CoreComponentsRegistry } from '@singletons/components-registry'; import { CoreNavBarButtonsComponent } from '../navbar-buttons/navbar-buttons'; import { CoreTabsComponent } from './tabs'; @@ -144,7 +144,7 @@ export class CoreTabComponent implements OnInit, OnDestroy, CoreTabBase { protected showHideNavBarButtons(show: boolean): void { const elements = this.element.querySelectorAll('core-navbar-buttons'); elements.forEach((element) => { - const instance = CoreDomUtils.getInstanceByElement(element); + const instance = CoreComponentsRegistry.resolve(element, CoreNavBarButtonsComponent); if (instance) { instance.forceHide(!show); diff --git a/src/core/core.module.ts b/src/core/core.module.ts index d5c75b618..aa68a6e2a 100644 --- a/src/core/core.module.ts +++ b/src/core/core.module.ts @@ -51,9 +51,11 @@ import { CoreUpdateManagerProvider } from '@services/update-manager'; import { CoreUrlUtilsProvider } from '@services/utils/url'; import { CoreUtilsProvider } from '@services/utils/utils'; import { CoreWSProvider } from '@services/ws'; +import { CoreComponentsRegistry } from '@singletons/components-registry'; export const CORE_SERVICES: Type[] = [ CoreAppProvider, + CoreComponentsRegistry, CoreConfigProvider, CoreCronDelegateService, CoreCustomURLSchemesProvider, diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index 47c013e9c..a84b182df 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -52,6 +52,7 @@ import { CoreSites } from '@services/sites'; import { NavigationStart } from '@angular/router'; import { filter } from 'rxjs/operators'; import { Subscription } from 'rxjs'; +import { CoreComponentsRegistry } from '@singletons/components-registry'; /* * "Utils" service with helper functions for UI, DOM elements and HTML code. @@ -68,7 +69,6 @@ export class CoreDomUtilsProvider { protected template: HTMLTemplateElement = document.createElement('template'); // A template element to convert HTML to element. protected matchesFunctionName?: string; // Name of the "matches" function to use when simulating a closest call. - protected instances: WeakMap = new WeakMap(); // Store component/directive instances indexed by element. protected debugDisplay = false; // Whether to display debug messages. Store it in a variable to make it synchronous. protected displayedAlerts: Record = {}; // To prevent duplicated alerts. protected displayedModals: Record = {}; // To prevent duplicated modals. @@ -671,9 +671,10 @@ export class CoreDomUtilsProvider { * * @param element The root element of the component/directive. * @return The instance, undefined if not found. + * @deprecated since 4.0.0. Use CoreComponentsRegistry instead. */ getInstanceByElement(element: Element): T | undefined { - return this.instances.get(element) as T; + return CoreComponentsRegistry.resolve(element) ?? undefined; } /** @@ -892,19 +893,22 @@ export class CoreDomUtilsProvider { * Remove a component/directive instance using the DOM Element. * * @param element The root element of the component/directive. + * @deprecated since 4.0.0. It's no longer necessary to remove instances. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars removeInstanceByElement(element: Element): void { - const id = element.getAttribute(this.INSTANCE_ID_ATTR_NAME); - id && delete this.instances[id]; + // } /** * Remove a component/directive instance using the ID. * * @param id The ID to remove. + * @deprecated since 4.0.0. It's no longer necessary to remove instances. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars removeInstanceById(id: string): void { - delete this.instances[id]; + // } /** @@ -1664,9 +1668,10 @@ export class CoreDomUtilsProvider { * * @param element The root element of the component/directive. * @param instance The instance to store. + * @deprecated since 4.0.0. Use CoreComponentsRegistry instead. */ storeInstanceByElement(element: Element, instance: unknown): void { - this.instances.set(element, instance); + CoreComponentsRegistry.register(element, instance); } /**