From eb9935a1d76b4c68efe4ee41b1b67f0fa698f330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 19 Jun 2024 16:43:48 +0200 Subject: [PATCH 1/2] MOBILE-4632 database: Load styles from site plugins --- .../index/addon-mod-data-index.html | 4 +- src/addons/mod/data/pages/edit/edit.html | 5 +-- src/addons/mod/data/pages/entry/entry.html | 5 +-- src/core/components/components.module.ts | 2 + src/core/components/style/style.ts | 30 ++----------- .../components/compile-html/compile-html.ts | 44 ++++++++++++++++--- src/core/features/compile/services/compile.ts | 8 +++- .../siteplugins/classes/call-ws-directive.ts | 2 +- src/core/services/platform.ts | 34 ++++++++++++++ src/core/singletons/dom.ts | 39 ++++++++++++++++ 10 files changed, 129 insertions(+), 44 deletions(-) diff --git a/src/addons/mod/data/components/index/addon-mod-data-index.html b/src/addons/mod/data/components/index/addon-mod-data-index.html index d71ce8244df..d521f8e6085 100644 --- a/src/addons/mod/data/components/index/addon-mod-data-index.html +++ b/src/addons/mod/data/components/index/addon-mod-data-index.html @@ -75,9 +75,7 @@
- - - +
diff --git a/src/addons/mod/data/pages/edit/edit.html b/src/addons/mod/data/pages/edit/edit.html index df520ec87ad..c27206afb67 100644 --- a/src/addons/mod/data/pages/edit/edit.html +++ b/src/addons/mod/data/pages/edit/edit.html @@ -21,10 +21,9 @@

[courseId]="database?.course" />
- -
- +
diff --git a/src/addons/mod/data/pages/entry/entry.html b/src/addons/mod/data/pages/entry/entry.html index 0c8d7026ee9..a29f4fe43d4 100644 --- a/src/addons/mod/data/pages/entry/entry.html +++ b/src/addons/mod/data/pages/entry/entry.html @@ -28,9 +28,8 @@

[courseId]="courseId" />
- - - +
tag. @@ -23,6 +24,7 @@ import { Component, ElementRef, Input, OnChanges } from '@angular/core'; * Example: * * + * @deprecated since 4.5.0. Not needed anymore, core-compile-html accepts now CSS code. */ @Component({ selector: 'core-style', @@ -41,37 +43,11 @@ export class CoreStyleComponent implements OnChanges { ngOnChanges(): void { if (this.element && this.element.nativeElement) { const style = document.createElement('style'); - style.innerHTML = this.prefixCSS(this.css, this.prefix); + style.innerHTML = CoreDom.prefixCSS(this.css, this.prefix); this.element.nativeElement.innerHTML = ''; this.element.nativeElement.appendChild(style); } } - /** - * Add a prefix to all rules in a CSS string. - * - * @param css CSS code to be prefixed. - * @param prefix Prefix css selector. - * @returns Prefixed CSS. - */ - protected prefixCSS(css: string, prefix: string): string { - if (!css) { - return ''; - } - - if (!prefix) { - return css; - } - - // Remove comments first. - let regExp = /\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm; - css = css.replace(regExp, ''); - - // Add prefix. - regExp = /([^]*?)({[^]*?}|,)/g; - - return css.replace(regExp, prefix + ' $1 $2'); - } - } diff --git a/src/core/features/compile/components/compile-html/compile-html.ts b/src/core/features/compile/components/compile-html/compile-html.ts index b657d3d8eb4..10c0c3d2a4d 100644 --- a/src/core/features/compile/components/compile-html/compile-html.ts +++ b/src/core/features/compile/components/compile-html/compile-html.ts @@ -38,6 +38,8 @@ import { CorePromisedValue } from '@classes/promised-value'; import { CoreCompile } from '@features/compile/services/compile'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; +import { CoreWS } from '@services/ws'; +import { CoreDom } from '@singletons/dom'; /** * This component has a behaviour similar to $compile for AngularJS. Given an HTML code, it will compile it so all its @@ -64,6 +66,8 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck { @Input() text!: string; // The HTML text to display. @Input() javascript?: string; // The Javascript to execute in the component. @Input() jsData?: Record; // Data to pass to the fake component. + @Input() cssCode?: string; // The styles to apply. + @Input() stylesPath?: string; // The styles URL to apply (only if cssCode is not set). @Input() extraImports: unknown[] = []; // Extra import modules. @Input() extraProviders: Type[] = []; // Extra providers. @Input() forceCompile = false; // Set it to true to force compile even if the text/javascript hasn't changed. @@ -101,12 +105,13 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck { // Check if there's any change in the jsData object. const changes = this.differ.diff(this.jsData || {}); - if (changes) { - this.setInputData(); + if (!changes) { + return; + } + this.setInputData(); - if (this.componentInstance.ngOnChanges) { - this.componentInstance.ngOnChanges(CoreDomUtils.createChangesFromKeyValueDiff(changes)); - } + if (this.componentInstance.ngOnChanges) { + this.componentInstance.ngOnChanges(CoreDomUtils.createChangesFromKeyValueDiff(changes)); } } @@ -116,7 +121,8 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck { async ngOnChanges(changes: Record): Promise { // Only compile if text/javascript has changed or the forceCompile flag has been set to true. if (this.text === undefined || - !(changes.text || changes.javascript || (changes.forceCompile && CoreUtils.isTrueOrOne(this.forceCompile)))) { + !(changes.text || changes.javascript || changes.cssCode || changes.stylesPath || + (changes.forceCompile && CoreUtils.isTrueOrOne(this.forceCompile)))) { return; } @@ -132,11 +138,14 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck { // Create the component. if (this.container) { + await this.loadCSSCode(); + this.componentRef = await CoreCompile.createAndCompileComponent( this.text, componentClass, this.container, this.extraImports, + this.cssCode, ); this.element.addEventListener('submit', (event) => { @@ -163,6 +172,29 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck { this.componentRef?.destroy(); } + /** + * Retrieve the CSS code from the stylesPath if not loaded yet. + */ + protected async loadCSSCode(): Promise { + // Do not allow (yet) to load CSS code to a component that doesn't have text. + if (!this.text) { + this.cssCode = ''; + + return; + } + + if (this.stylesPath && !this.cssCode) { + this.cssCode = await CoreUtils.ignoreErrors(CoreWS.getText(this.stylesPath)); + } + + // Prepend all CSS rules with :host to avoid conflicts. + if (!this.cssCode || this.cssCode.includes(':host')) { + return; + } + + this.cssCode = CoreDom.prefixCSS(this.cssCode, ':host ::ng-deep', ':host'); + } + /** * Get a class that defines the dynamic component. * diff --git a/src/core/features/compile/services/compile.ts b/src/core/features/compile/services/compile.ts index 2d084e4abec..63849d3d009 100644 --- a/src/core/features/compile/services/compile.ts +++ b/src/core/features/compile/services/compile.ts @@ -175,6 +175,7 @@ export class CoreCompileProvider { * @param componentClass The JS class of the component. * @param viewContainerRef View container reference to inject the component. * @param extraImports Extra imported modules if needed and not imported by this class. + * @param styles CSS code to apply to the component. * @returns Promise resolved with the component reference. */ async createAndCompileComponent( @@ -182,12 +183,17 @@ export class CoreCompileProvider { componentClass: Type, viewContainerRef: ViewContainerRef, extraImports: any[] = [], // eslint-disable-line @typescript-eslint/no-explicit-any + styles?: string, ): Promise | undefined> { // Import the Angular compiler to be able to compile components in runtime. await import('@angular/compiler'); // Create the component using the template and the class. - const component = Component({ template, host: { 'compiled-component-id': String(this.componentId++) } })(componentClass); + const component = Component({ + template, + host: { 'compiled-component-id': String(this.componentId++) }, + styles, + })(componentClass); const lazyImports = await Promise.all(this.LAZY_IMPORTS.map(getModules => getModules())); const imports = [ diff --git a/src/core/features/siteplugins/classes/call-ws-directive.ts b/src/core/features/siteplugins/classes/call-ws-directive.ts index f908c4ed429..f17b7d8a4d4 100644 --- a/src/core/features/siteplugins/classes/call-ws-directive.ts +++ b/src/core/features/siteplugins/classes/call-ws-directive.ts @@ -127,7 +127,7 @@ export class CoreSitePluginsCallWSBaseDirective implements OnInit, OnDestroy { } /** - * Directive destroyed. + * @inheritdoc */ ngOnDestroy(): void { this.invalidateObserver?.unsubscribe(); diff --git a/src/core/services/platform.ts b/src/core/services/platform.ts index c08089d0672..61b1d7194f0 100644 --- a/src/core/services/platform.ts +++ b/src/core/services/platform.ts @@ -22,6 +22,8 @@ import { Device, makeSingleton } from '@singletons'; @Injectable({ providedIn: 'root' }) export class CorePlatformService extends Platform { + private static cssNesting?: boolean; + /** * Get platform major version number. * @@ -117,6 +119,38 @@ export class CorePlatformService extends Platform { return 'WebAssembly' in window; } + /** + * Check if the browser supports CSS nesting. + * + * @returns Whether the browser supports CSS nesting. + */ + supportsCSSNesting(): boolean { + if (CorePlatformService.cssNesting !== undefined) { + return CorePlatformService.cssNesting; + } + + // Add nested CSS to DOM and check if it's supported. + const style = document.createElement('style'); + style.innerHTML = 'div.nested { &.css { color: red; } }'; + document.head.appendChild(style); + + // Add an element to check if the nested CSS is applied. + const div = document.createElement('div'); + div.className = 'nested css'; + document.body.appendChild(div); + + const color = window.getComputedStyle(div).color; + + // Check if color is red. + CorePlatformService.cssNesting = color === 'rgb(255, 0, 0)'; + + // Clean the DOM. + document.head.removeChild(style); + document.body.removeChild(div); + + return CorePlatformService.cssNesting; + } + } export const CorePlatform = makeSingleton(CorePlatformService); diff --git a/src/core/singletons/dom.ts b/src/core/singletons/dom.ts index f52d8e5f5d2..ff22077c03d 100644 --- a/src/core/singletons/dom.ts +++ b/src/core/singletons/dom.ts @@ -16,6 +16,7 @@ import { CoreCancellablePromise } from '@classes/cancellable-promise'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { CoreEventObserver } from '@singletons/events'; +import { CorePlatform } from '@services/platform'; /** * Singleton with helper functions for dom. @@ -684,6 +685,44 @@ export class CoreDom { return element; } + /** + * Prefix CSS rules. + * + * @param css CSS code. + * @param prefix Prefix to add to CSS rules. + * @param prefixIfNested Prefix to add to CSS rules if nested. It may happend we need different prefixes. + * Ie: If nested is supported ::ng-deep is not needed. + * @returns Prefixed CSS. + */ + static prefixCSS(css: string, prefix: string, prefixIfNested?: string): string { + if (!css) { + return ''; + } + + if (!prefix) { + return css; + } + + // Check if browser supports CSS nesting. + const supportsNesting = CorePlatform.supportsCSSNesting(); + if (supportsNesting) { + prefixIfNested = prefixIfNested ?? prefix; + + // Wrap the CSS with the prefix. + return `${prefixIfNested} { ${css} }`; + } + + // Fallback. + // Remove comments first. + let regExp = /\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm; + css = css.replace(regExp, ''); + + // Add prefix. + regExp = /([^]*?)({[^]*?}|,)/g; + + return css.replace(regExp, prefix + ' $1 $2'); + } + } /** From e8a1ff89fa17da96e0c607a53137fa2bd53f0d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 15 Jul 2024 09:35:29 +0200 Subject: [PATCH 2/2] MOBILE-4632 siteplugins: Minor changes on declarations --- src/core/features/siteplugins/constants.ts | 4 ++ ...eplugins-helper.ts => siteplugins-init.ts} | 63 +++++++++---------- .../siteplugins/services/siteplugins.ts | 20 +++--- .../siteplugins/siteplugins.module.ts | 13 ++-- 4 files changed, 53 insertions(+), 47 deletions(-) rename src/core/features/siteplugins/services/{siteplugins-helper.ts => siteplugins-init.ts} (96%) diff --git a/src/core/features/siteplugins/constants.ts b/src/core/features/siteplugins/constants.ts index c971aa1e88e..a215c83e0c0 100644 --- a/src/core/features/siteplugins/constants.ts +++ b/src/core/features/siteplugins/constants.ts @@ -13,3 +13,7 @@ // limitations under the License. export const CORE_SITE_PLUGINS_UPDATE_COURSE_CONTENT = 'siteplugins_update_course_content'; + +export const CORE_SITE_PLUGINS_COMPONENT = 'CoreSitePlugins'; + +export const CORE_SITE_PLUGINS_PATH = 'siteplugins'; diff --git a/src/core/features/siteplugins/services/siteplugins-helper.ts b/src/core/features/siteplugins/services/siteplugins-init.ts similarity index 96% rename from src/core/features/siteplugins/services/siteplugins-helper.ts rename to src/core/features/siteplugins/services/siteplugins-init.ts index 3417db1e33f..fc48549199d 100644 --- a/src/core/features/siteplugins/services/siteplugins-helper.ts +++ b/src/core/features/siteplugins/services/siteplugins-init.ts @@ -62,7 +62,6 @@ import { CoreSitePluginsContent, CoreSitePluginsPlugin, CoreSitePluginsHandlerData, - CoreSitePluginsProvider, CoreSitePluginsCourseOptionHandlerData, CoreSitePluginsMainMenuHandlerData, CoreSitePluginsCourseModuleHandlerData, @@ -89,8 +88,7 @@ import { CoreUrlUtils } from '@services/utils/url'; import { CorePath } from '@singletons/path'; import { CoreEnrolAction, CoreEnrolDelegate } from '@features/enrol/services/enrol-delegate'; import { CoreSitePluginsEnrolHandler } from '../classes/handlers/enrol-handler'; - -const HANDLER_DISABLED = 'core_site_plugins_helper_handler_disabled'; +import { CORE_SITE_PLUGINS_COMPONENT } from '../constants'; /** * Helper service to provide functionalities regarding site plugins. It basically has the features to load and register site @@ -102,7 +100,7 @@ const HANDLER_DISABLED = 'core_site_plugins_helper_handler_disabled'; * inside the host DOM element? */ @Injectable({ providedIn: 'root' }) -export class CoreSitePluginsHelperProvider { +export class CoreSitePluginsInitService { protected logger: CoreLogger; protected courseRestrictHandlers: Record = {}; + protected static readonly HANDLER_DISABLED = 'core_site_plugins_helper_handler_disabled'; + constructor() { - this.logger = CoreLogger.getInstance('CoreSitePluginsHelperProvider'); + this.logger = CoreLogger.getInstance('CoreSitePluginsInit'); } /** * Initialize. */ - initialize(): void { + init(): void { // Fetch the plugins on login. CoreEvents.on(CoreEvents.LOGIN, async (data) => { try { const plugins = await CoreUtils.ignoreErrors(CoreSitePlugins.getPlugins(data.siteId)); // Plugins fetched, check that site hasn't changed. - if (data.siteId != CoreSites.getCurrentSiteId() || !plugins?.length) { + if (data.siteId !== CoreSites.getCurrentSiteId() || !plugins?.length) { return; } @@ -145,7 +145,7 @@ export class CoreSitePluginsHelperProvider { // Re-load plugins restricted for courses when the list of user courses changes. CoreEvents.on(CoreCoursesProvider.EVENT_MY_COURSES_CHANGED, (data) => { - if (data && data.siteId && data.siteId == CoreSites.getCurrentSiteId() && data.added && data.added.length) { + if (data.siteId && data.siteId === CoreSites.getCurrentSiteId() && data.added.length) { this.reloadCourseRestrictHandlers(); } }); @@ -160,7 +160,7 @@ export class CoreSitePluginsHelperProvider { * @param siteId Site ID. If not provided, current site. * @returns Promise resolved with the CSS code. */ - async downloadStyles( + protected async downloadStyles( plugin: CoreSitePluginsPlugin, handlerName: string, handlerSchema: CoreSitePluginsHandlerData, @@ -184,7 +184,7 @@ export class CoreSitePluginsHelperProvider { // Remove the CSS files for this handler that aren't used anymore. Don't block the call for this. const files = await CoreUtils.ignoreErrors( - CoreFilepool.getFilesByComponent(site.getId(), CoreSitePluginsProvider.COMPONENT, componentId), + CoreFilepool.getFilesByComponent(site.getId(), CORE_SITE_PLUGINS_COMPONENT, componentId), ); files?.forEach((file) => { @@ -209,7 +209,7 @@ export class CoreSitePluginsHelperProvider { site.getId(), url, false, - CoreSitePluginsProvider.COMPONENT, + CORE_SITE_PLUGINS_COMPONENT, componentId, 0, undefined, @@ -270,7 +270,7 @@ export class CoreSitePluginsHelperProvider { // Create a "fake" instance to hold all the libraries. const instance = { // eslint-disable-next-line @typescript-eslint/naming-convention - HANDLER_DISABLED: HANDLER_DISABLED, + HANDLER_DISABLED: CoreSitePluginsInitService.HANDLER_DISABLED, }; await CoreCompile.loadLibraries(); @@ -285,7 +285,7 @@ export class CoreSitePluginsHelperProvider { // Now execute the javascript using this instance. result.jsResult = CoreCompile.executeJavascript(instance, result.javascript); - if (result.jsResult == HANDLER_DISABLED) { + if (result.jsResult === CoreSitePluginsInitService.HANDLER_DISABLED) { // The "disabled" field was added in 3.8, this is a workaround for previous versions. result.disabled = true; } @@ -311,10 +311,10 @@ export class CoreSitePluginsHelperProvider { * Given an addon name and the key of a string, return the full string key (prefixed). * * @param addon Name of the addon (plugin.addon). - * @param key The key of the string. + * @param key The key of the string. Defaults to pluginname. * @returns Full string key. */ - protected getPrefixedString(addon: string, key: string): string { + protected getPrefixedString(addon: string, key = 'pluginname'): string { return this.getPrefixForStrings(addon) + key; } @@ -323,7 +323,7 @@ export class CoreSitePluginsHelperProvider { * * @param plugin Data of the plugin. */ - loadLangStrings(plugin: CoreSitePluginsPlugin): void { + protected loadLangStrings(plugin: CoreSitePluginsPlugin): void { if (!plugin.parsedLang) { return; } @@ -339,9 +339,8 @@ export class CoreSitePluginsHelperProvider { * Load a site plugin. * * @param plugin Data of the plugin. - * @returns Promise resolved when loaded. */ - async loadSitePlugin(plugin: CoreSitePluginsPlugin): Promise { + protected async loadSitePlugin(plugin: CoreSitePluginsPlugin): Promise { this.logger.debug('Load site plugin:', plugin); if (!plugin.parsedHandlers && plugin.handlers) { @@ -378,9 +377,8 @@ export class CoreSitePluginsHelperProvider { * Load site plugins. * * @param plugins The plugins to load. - * @returns Promise resolved when loaded. */ - async loadSitePlugins(plugins: CoreSitePluginsPlugin[]): Promise { + protected async loadSitePlugins(plugins: CoreSitePluginsPlugin[]): Promise { this.courseRestrictHandlers = {}; await CoreUtils.allPromises(plugins.map(async (plugin) => { @@ -401,7 +399,7 @@ export class CoreSitePluginsHelperProvider { * @param version Styles version. * @param siteId Site ID. If not provided, current site. */ - loadStyles( + protected loadStyles( plugin: CoreSitePluginsPlugin, handlerName: string, fileUrl: string, @@ -436,7 +434,7 @@ export class CoreSitePluginsHelperProvider { // Styles have been loaded, now treat the CSS. CoreUtils.ignoreErrors( - CoreFilepool.treatCSSCode(siteId, fileUrl, cssCode, CoreSitePluginsProvider.COMPONENT, uniqueName, version), + CoreFilepool.treatCSSCode(siteId, fileUrl, cssCode, CORE_SITE_PLUGINS_COMPONENT, uniqueName, version), ); } @@ -446,9 +444,8 @@ export class CoreSitePluginsHelperProvider { * @param plugin Data of the plugin. * @param handlerName Name of the handler in the plugin. * @param handlerSchema Data about the handler. - * @returns Promise resolved when done. */ - async registerHandler( + protected async registerHandler( plugin: CoreSitePluginsPlugin, handlerName: string, handlerSchema: CoreSitePluginsHandlerData, @@ -700,7 +697,7 @@ export class CoreSitePluginsHelperProvider { const uniqueName = CoreSitePlugins.getHandlerUniqueName(plugin, handlerName); const blockName = (handlerSchema.moodlecomponent || plugin.component).replace('block_', ''); - const titleString = handlerSchema.displaydata?.title ?? 'pluginname'; + const titleString = handlerSchema.displaydata?.title; const prefixedTitle = this.getPrefixedString(plugin.addon, titleString); CoreBlockDelegate.registerHandler( @@ -761,7 +758,7 @@ export class CoreSitePluginsHelperProvider { // Create and register the handler. const uniqueName = CoreSitePlugins.getHandlerUniqueName(plugin, handlerName); - const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'); + const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title); const handler = new CoreSitePluginsCourseOptionHandler( uniqueName, prefixedTitle, @@ -873,7 +870,7 @@ export class CoreSitePluginsHelperProvider { // Create and register the handler. const uniqueName = CoreSitePlugins.getHandlerUniqueName(plugin, handlerName); - const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'); + const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title); CoreMainMenuDelegate.registerHandler( new CoreSitePluginsMainMenuHandler(uniqueName, prefixedTitle, plugin, handlerSchema, initResult), @@ -908,7 +905,7 @@ export class CoreSitePluginsHelperProvider { // Create and register the handler. const uniqueName = CoreSitePlugins.getHandlerUniqueName(plugin, handlerName); - const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'); + const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title); const processorName = (handlerSchema.moodlecomponent || plugin.component).replace('message_', ''); AddonMessageOutputDelegate.registerHandler( @@ -1074,7 +1071,7 @@ export class CoreSitePluginsHelperProvider { // Create and register the handler. const uniqueName = CoreSitePlugins.getHandlerUniqueName(plugin, handlerName); - const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'); + const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title); CoreSettingsDelegate.registerHandler( new CoreSitePluginsSettingsHandler(uniqueName, prefixedTitle, plugin, handlerSchema, initResult), @@ -1109,7 +1106,7 @@ export class CoreSitePluginsHelperProvider { // Create and register the handler. const uniqueName = CoreSitePlugins.getHandlerUniqueName(plugin, handlerName); - const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'); + const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title); const handler = new CoreSitePluginsUserProfileHandler(uniqueName, prefixedTitle, plugin, handlerSchema, initResult); CoreUserDelegate.registerHandler(handler); @@ -1182,8 +1179,6 @@ export class CoreSitePluginsHelperProvider { /** * Reload the handlers that are restricted to certain courses. - * - * @returns Promise resolved when done. */ protected async reloadCourseRestrictHandlers(): Promise { if (!Object.keys(this.courseRestrictHandlers).length) { @@ -1240,7 +1235,7 @@ export class CoreSitePluginsHelperProvider { // Create and register the handler. const uniqueName = CoreSitePlugins.getHandlerUniqueName(plugin, handlerName); - const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'); + const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title); CoreMainMenuHomeDelegate.registerHandler( new CoreSitePluginsMainMenuHomeHandler(uniqueName, prefixedTitle, plugin, handlerSchema, initResult), @@ -1251,4 +1246,4 @@ export class CoreSitePluginsHelperProvider { } -export const CoreSitePluginsHelper = makeSingleton(CoreSitePluginsHelperProvider); +export const CoreSitePluginsInit = makeSingleton(CoreSitePluginsInitService); diff --git a/src/core/features/siteplugins/services/siteplugins.ts b/src/core/features/siteplugins/services/siteplugins.ts index 014e0faa8c9..30deff990c6 100644 --- a/src/core/features/siteplugins/services/siteplugins.ts +++ b/src/core/features/siteplugins/services/siteplugins.ts @@ -34,9 +34,7 @@ import { CorePlatform } from '@services/platform'; import { CoreEnrolAction, CoreEnrolInfoIcon } from '@features/enrol/services/enrol-delegate'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreUserProfileHandlerType } from '@features/user/services/user-delegate'; -import { CORE_SITE_PLUGINS_UPDATE_COURSE_CONTENT } from '../constants'; - -const ROOT_CACHE_KEY = 'CoreSitePlugins:'; +import { CORE_SITE_PLUGINS_COMPONENT, CORE_SITE_PLUGINS_UPDATE_COURSE_CONTENT } from '../constants'; /** * Service to provide functionalities regarding site plugins. @@ -44,7 +42,14 @@ const ROOT_CACHE_KEY = 'CoreSitePlugins:'; @Injectable({ providedIn: 'root' }) export class CoreSitePluginsProvider { - static readonly COMPONENT = 'CoreSitePlugins'; + protected static readonly ROOT_CACHE_KEY = 'CoreSitePlugins:'; + /** + * @deprecated since 4.5.0. Use CORE_SITE_PLUGINS_COMPONENT instead. + */ + static readonly COMPONENT = CORE_SITE_PLUGINS_COMPONENT; + /** + * @deprecated since 4.5.0. Use CORE_SITE_PLUGINS_UPDATE_COURSE_CONTENT instead. + */ static readonly UPDATE_COURSE_CONTENT = CORE_SITE_PLUGINS_UPDATE_COURSE_CONTENT; protected logger: CoreLogger; @@ -183,7 +188,7 @@ export class CoreSitePluginsProvider { * @returns Cache key. */ protected getCallWSCommonCacheKey(method: string): string { - return ROOT_CACHE_KEY + 'ws:' + method; + return CoreSitePluginsProvider.ROOT_CACHE_KEY + 'ws:' + method; } /** @@ -250,7 +255,8 @@ export class CoreSitePluginsProvider { * @returns Cache key. */ protected getContentCacheKey(component: string, method: string, args: Record): string { - return ROOT_CACHE_KEY + 'content:' + component + ':' + method + ':' + CoreUtils.sortAndStringify(args); + return CoreSitePluginsProvider.ROOT_CACHE_KEY + 'content:' + component + ':' + method + + ':' + CoreUtils.sortAndStringify(args); } /** @@ -322,7 +328,7 @@ export class CoreSitePluginsProvider { * @returns Cache key. */ protected getPluginsCacheKey(): string { - return ROOT_CACHE_KEY + 'plugins'; + return CoreSitePluginsProvider.ROOT_CACHE_KEY + 'plugins'; } /** diff --git a/src/core/features/siteplugins/siteplugins.module.ts b/src/core/features/siteplugins/siteplugins.module.ts index 8a58ea4bbb0..187e3633742 100644 --- a/src/core/features/siteplugins/siteplugins.module.ts +++ b/src/core/features/siteplugins/siteplugins.module.ts @@ -20,12 +20,13 @@ import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-ro import { CoreMainMenuHomeRoutingModule } from '@features/mainmenu/mainmenu-home-routing.module'; import { CoreSitePreferencesRoutingModule } from '@features/settings/settings-site-routing.module'; import { CoreSitePluginsComponentsModule } from './components/components.module'; -import { CoreSitePluginsHelper } from './services/siteplugins-helper'; +import { CoreSitePluginsInit } from './services/siteplugins-init'; import { CoreSharedModule } from '@/core/shared.module'; import { CoreSitePluginsPluginPage } from '@features/siteplugins/pages/plugin/plugin'; import { canLeaveGuard } from '@guards/can-leave'; import { CoreSitePluginsCourseOptionPage } from '@features/siteplugins/pages/course-option/course-option'; import { CoreSitePluginsModuleIndexPage } from '@features/siteplugins/pages/module-index/module-index'; +import { CORE_SITE_PLUGINS_PATH } from './constants'; /** * Get site plugins exported objects. @@ -65,7 +66,7 @@ export async function getSitePluginsExportedObjects(): Promise { - CoreSitePluginsHelper.initialize(); + CoreSitePluginsInit.init(); }, }, ],