From 98e7ba17c96ebb2ef94c037ee87d08588e478383 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 14 Mar 2024 17:28:33 +0100 Subject: [PATCH] MOBILE-3622 h5p: Apply styles defined in h5pcustomcss --- .../h5pactivity/services/handlers/prefetch.ts | 1 + .../features/h5p/assets/moodle/js/params.js | 3 ++ src/core/features/h5p/classes/player.ts | 5 +++ src/core/features/h5p/services/h5p.ts | 38 ++++++++++++++++++- src/core/services/filepool.ts | 18 +++++++++ 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/addons/mod/h5pactivity/services/handlers/prefetch.ts b/src/addons/mod/h5pactivity/services/handlers/prefetch.ts index bd1d658478c..97a25f59b3a 100644 --- a/src/addons/mod/h5pactivity/services/handlers/prefetch.ts +++ b/src/addons/mod/h5pactivity/services/handlers/prefetch.ts @@ -115,6 +115,7 @@ export class AddonModH5PActivityPrefetchHandlerService extends CoreCourseActivit this.prefetchWSData(h5pActivity, siteId), CoreFilepool.addFilesToQueue(siteId, introFiles, AddonModH5PActivityProvider.COMPONENT, module.id), this.prefetchMainFile(module, h5pActivity, siteId), + CoreH5P.getCustomCssSrc(siteId), ]); } diff --git a/src/core/features/h5p/assets/moodle/js/params.js b/src/core/features/h5p/assets/moodle/js/params.js index cea8b9e1f9f..d7ba58bdbb5 100644 --- a/src/core/features/h5p/assets/moodle/js/params.js +++ b/src/core/features/h5p/assets/moodle/js/params.js @@ -48,6 +48,9 @@ if (window.H5PIntegration && window.H5PIntegration.contents && location.search) window.H5PIntegration.saveFreq = nameAndValue[1]; } else if (nameAndValue[0] == 'state' && nameAndValue[1] !== undefined && contentData) { contentData.contentUserData = [{ state: decodeURIComponent(nameAndValue[1]) }]; + } else if (nameAndValue[0] == 'customCssUrl' && nameAndValue[1] !== undefined) { + contentData.styles = contentData.styles || []; + contentData.styles.push(nameAndValue[1]); } }); } diff --git a/src/core/features/h5p/classes/player.ts b/src/core/features/h5p/classes/player.ts index 8397647dd81..917c0fd3b88 100644 --- a/src/core/features/h5p/classes/player.ts +++ b/src/core/features/h5p/classes/player.ts @@ -298,6 +298,11 @@ export class CoreH5PPlayer { params.state = otherOptions.state; } + const customCssUrl = await CoreUtils.ignoreErrors(CoreH5P.getCustomCssSrc(siteId)); + if (customCssUrl) { + params.customCssUrl = customCssUrl; + } + return CoreUrlUtils.addParamsToUrl(path, params); } diff --git a/src/core/features/h5p/services/h5p.ts b/src/core/features/h5p/services/h5p.ts index 81586e55afa..de53844e032 100644 --- a/src/core/features/h5p/services/h5p.ts +++ b/src/core/features/h5p/services/h5p.ts @@ -30,6 +30,9 @@ import { makeSingleton } from '@singletons'; import { CoreError } from '@classes/errors/error'; import { CorePath } from '@singletons/path'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; +import { CoreFilepool } from '@services/filepool'; +import { DownloadStatus } from '@/core/constants'; +import { CoreUtils } from '@services/utils/utils'; /** * Service to provide H5P functionalities. @@ -44,7 +47,8 @@ export class CoreH5PProvider { h5pValidator: CoreH5PValidator; queueRunner: CoreQueueRunner; - protected readonly ROOT_CACHE_KEY = 'CoreH5P:'; + protected static readonly ROOT_CACHE_KEY = 'CoreH5P:'; + protected static readonly CUSTOM_CSS_COMPONENT = 'CoreH5PCustomCSS'; constructor() { this.queueRunner = new CoreQueueRunner(1); @@ -82,6 +86,36 @@ export class CoreH5PProvider { return !!(site?.wsAvailable('core_h5p_get_trusted_h5p_file')); } + /** + * Get the src URL to load custom CSS styles for H5P. + * + * @param siteId Site ID. If not defined, current site. + * @returns Src URL, undefined if no custom CSS. + */ + async getCustomCssSrc(siteId?: string): Promise { + const site = await CoreSites.getSite(siteId); + + const customCssUrl = await site.getStoredConfig('h5pcustomcssurl'); + if (!customCssUrl) { + return; + } + + const state = await CoreFilepool.getFileStateByUrl(site.getId(), customCssUrl); + if (state === DownloadStatus.DOWNLOADABLE_NOT_DOWNLOADED) { + // File not downloaded, URL has changed or first time. Delete previously downloaded file. + await CoreUtils.ignoreErrors( + CoreFilepool.removeFilesByComponent(site.getId(), CoreH5PProvider.CUSTOM_CSS_COMPONENT, 1), + ); + } + + if (state !== DownloadStatus.DOWNLOADED) { + // Download CSS styles first. + await CoreFilepool.downloadUrl(site.getId(), customCssUrl, false, CoreH5PProvider.CUSTOM_CSS_COMPONENT, 1); + } + + return await CoreFilepool.getInternalSrcByUrl(site.getId(), customCssUrl); + } + /** * Get a trusted H5P file. * @@ -148,7 +182,7 @@ export class CoreH5PProvider { * @returns Cache key. */ protected getTrustedH5PFilePrefixCacheKey(): string { - return this.ROOT_CACHE_KEY + 'trustedH5PFile:'; + return CoreH5PProvider.ROOT_CACHE_KEY + 'trustedH5PFile:'; } /** diff --git a/src/core/services/filepool.ts b/src/core/services/filepool.ts index 8dad71e354d..438211b3a53 100644 --- a/src/core/services/filepool.ts +++ b/src/core/services/filepool.ts @@ -1718,6 +1718,24 @@ export class CoreFilepoolProvider { return CoreFile.getFileEntryURL(fileEntry); } + /** + * Returns the local src of a file. + * + * @param siteId The site ID. + * @param fileUrl The file URL. + * @returns Src URL. + */ + async getInternalSrcByUrl(siteId: string, fileUrl: string): Promise { + if (!CoreFile.isAvailable()) { + throw new CoreError('File system cannot be used.'); + } + + const file = await this.fixPluginfileURL(siteId, fileUrl); + const fileId = this.getFileIdByUrl(CoreFileHelper.getFileUrl(file)); + + return this.getInternalSrcById(siteId, fileId); + } + /** * Returns the local URL of a file. *