From 717978388e013e451625e9c518b48e9aca92eb49 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 1 Mar 2022 11:47:57 +0100 Subject: [PATCH 1/2] MOBILE-3982 core: Extract CoreComponentsRegistry --- .../components/context-menu/context-menu.ts | 3 ++- .../components/navbar-buttons/navbar-buttons.ts | 9 +++++---- src/core/components/tabs-outlet/tabs-outlet.ts | 3 +-- src/core/components/tabs/tab.ts | 4 ++-- src/core/core.module.ts | 2 ++ src/core/services/utils/dom.ts | 17 +++++++++++------ 6 files changed, 23 insertions(+), 15 deletions(-) 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); } /** From 6b5d1db43c8b1eb2241fcb9a5bfe3b36ec8fbaa7 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 24 Feb 2022 17:23:22 +0100 Subject: [PATCH 2/2] MOBILE-3982 core: Refactor collapsible-header --- src/addons/calendar/pages/event/event.html | 3 +- .../components/tabs-outlet/tabs-outlet.ts | 14 +- src/core/directives/collapsible-header.ts | 603 +++++++++--------- src/core/directives/format-text.ts | 19 + .../module-info/core-course-module-info.html | 2 +- .../module-summary/module-summary.scss | 2 +- .../components/single-activity.scss | 2 +- .../features/course/pages/index/index.html | 4 +- src/core/features/course/pages/index/index.ts | 4 +- src/core/singletons/components-registry.ts | 53 ++ src/theme/components/collapsible-header.scss | 86 +++ src/theme/globals.mixins.scss | 17 +- src/theme/theme.base.scss | 82 --- src/theme/theme.scss | 1 + 14 files changed, 489 insertions(+), 403 deletions(-) create mode 100644 src/core/singletons/components-registry.ts create mode 100644 src/theme/components/collapsible-header.scss diff --git a/src/addons/calendar/pages/event/event.html b/src/addons/calendar/pages/event/event.html index ae1306688..39364fbc8 100644 --- a/src/addons/calendar/pages/event/event.html +++ b/src/addons/calendar/pages/event/event.html @@ -40,8 +40,7 @@ - +