MOBILE-4616 chore: Always use convertTextToHTMLElement to convert HTML

main
Pau Ferrer Ocaña 2024-08-14 14:29:51 +02:00
parent b0c494ee51
commit 00951b22d5
5 changed files with 59 additions and 65 deletions

View File

@ -20,7 +20,7 @@ import { makeSingleton } from '@singletons';
import { CoreH5PPlayerComponent } from '@features/h5p/components/h5p-player/h5p-player'; import { CoreH5PPlayerComponent } from '@features/h5p/components/h5p-player/h5p-player';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import { CoreH5PHelper } from '@features/h5p/classes/helper'; import { CoreH5PHelper } from '@features/h5p/classes/helper';
import { CoreTemplateElement } from '@/core/utils/create-html-element'; import { CoreText } from '@singletons/text';
/** /**
* Handler to support the Display H5P filter. * Handler to support the Display H5P filter.
@ -37,9 +37,8 @@ export class AddonFilterDisplayH5PHandlerService extends CoreFilterDefaultHandle
filter( filter(
text: string, text: string,
): string | Promise<string> { ): string | Promise<string> {
CoreTemplateElement.innerHTML = text; return CoreText.processHTML(text, (element) => {
const h5pIframes = <HTMLIFrameElement[]> Array.from(element.querySelectorAll('iframe.h5p-iframe'));
const h5pIframes = <HTMLIFrameElement[]> Array.from(CoreTemplateElement.content.querySelectorAll('iframe.h5p-iframe'));
// Replace all iframes with an empty div that will be treated in handleHtml. // Replace all iframes with an empty div that will be treated in handleHtml.
h5pIframes.forEach((iframe) => { h5pIframes.forEach((iframe) => {
@ -53,7 +52,7 @@ export class AddonFilterDisplayH5PHandlerService extends CoreFilterDefaultHandle
// Handle H5P iframes embedded using the embed HTML code. // Handle H5P iframes embedded using the embed HTML code.
const embeddedH5PIframes = <HTMLIFrameElement[]> Array.from( const embeddedH5PIframes = <HTMLIFrameElement[]> Array.from(
CoreTemplateElement.content.querySelectorAll('iframe.h5p-player'), element.querySelectorAll('iframe.h5p-player'),
); );
embeddedH5PIframes.forEach((iframe) => { embeddedH5PIframes.forEach((iframe) => {
@ -70,8 +69,7 @@ export class AddonFilterDisplayH5PHandlerService extends CoreFilterDefaultHandle
iframe.style.height = '400px'; iframe.style.height = '400px';
} }
}); });
});
return CoreTemplateElement.innerHTML;
} }
/** /**

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { CoreTemplateElement } from '@/core/utils/create-html-element'; import { CoreText } from '@singletons/text';
import { AddonFilterMediaPluginVideoJS } from '@addons/filter/mediaplugin/services/videojs'; import { AddonFilterMediaPluginVideoJS } from '@addons/filter/mediaplugin/services/videojs';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
@ -33,15 +33,13 @@ export class AddonFilterMediaPluginHandlerService extends CoreFilterDefaultHandl
* @inheritdoc * @inheritdoc
*/ */
filter(text: string): string | Promise<string> { filter(text: string): string | Promise<string> {
CoreTemplateElement.innerHTML = text; return CoreText.processHTML(text, (element) => {
const videos = Array.from(element.querySelectorAll('video'));
const videos = Array.from(CoreTemplateElement.content.querySelectorAll('video'));
videos.forEach((video) => { videos.forEach((video) => {
AddonFilterMediaPluginVideoJS.treatYoutubeVideos(video); AddonFilterMediaPluginVideoJS.treatYoutubeVideos(video);
}); });
});
return CoreTemplateElement.innerHTML;
} }
/** /**

View File

@ -55,7 +55,7 @@ import { CorePopovers, OpenPopoverOptions } from '@services/popovers';
import { CoreViewer } from '@features/viewer/services/viewer'; import { CoreViewer } from '@features/viewer/services/viewer';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import { CoreErrorHelper, CoreErrorObject } from '@services/error-helper'; import { CoreErrorHelper, CoreErrorObject } from '@services/error-helper';
import { convertTextToHTMLElement, CoreTemplateElement } from '@/core/utils/create-html-element'; import { convertTextToHTMLElement } from '@/core/utils/create-html-element';
import { CoreHTMLClasses } from '@singletons/html-classes'; import { CoreHTMLClasses } from '@singletons/html-classes';
/* /*
@ -197,7 +197,7 @@ export class CoreDomUtilsProvider {
* @param html Text to convert. * @param html Text to convert.
* @returns Element. * @returns Element.
* *
* @deprecated since 4.5. Use convertToElement directly instead. * @deprecated since 4.5. Use convertTextToHTMLElement directly instead.
*/ */
convertToElement(html: string): HTMLElement { convertToElement(html: string): HTMLElement {
return convertTextToHTMLElement(html); return convertTextToHTMLElement(html);
@ -262,8 +262,7 @@ export class CoreDomUtilsProvider {
* @returns Fixed HTML text. * @returns Fixed HTML text.
*/ */
fixHtml(html: string): string { fixHtml(html: string): string {
CoreTemplateElement.innerHTML = html; return CoreText.processHTML(html, (element) => {
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
const attrNameRegExp = /[^\x00-\x20\x7F-\x9F"'>/=]+/; const attrNameRegExp = /[^\x00-\x20\x7F-\x9F"'>/=]+/;
const fixElement = (element: Element): void => { const fixElement = (element: Element): void => {
@ -277,9 +276,9 @@ export class CoreDomUtilsProvider {
Array.from(element.children).forEach(fixElement); Array.from(element.children).forEach(fixElement);
}; };
Array.from(CoreTemplateElement.content.children).forEach(fixElement); Array.from(element.children).forEach(fixElement);
});
return CoreTemplateElement.innerHTML;
} }
/** /**

View File

@ -17,7 +17,7 @@ import { CoreUtils } from '@services/utils/utils';
import { CoreEventObserver } from '@singletons/events'; import { CoreEventObserver } from '@singletons/events';
import { CorePlatform } from '@services/platform'; import { CorePlatform } from '@services/platform';
import { CoreWait } from './wait'; import { CoreWait } from './wait';
import { CoreTemplateElement } from '../utils/create-html-element'; import { convertTextToHTMLElement } from '../utils/create-html-element';
/** /**
* Singleton with helper functions for dom. * Singleton with helper functions for dom.
@ -118,9 +118,9 @@ export class CoreDom {
return true; return true;
} }
CoreTemplateElement.innerHTML = content; const element = convertTextToHTMLElement(content);
return !CoreDom.elementHasContent(CoreTemplateElement.content); return !CoreDom.elementHasContent(element);
} }
/** /**

View File

@ -12,18 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// A template element to convert HTML to element.
export const CoreTemplateElement: HTMLTemplateElement = document.createElement('template');
/** /**
* Convert some HTML as text into an HTMLElement. This HTML is put inside a div or a body. * Convert some HTML as text into an HTMLElement. This HTML is put inside a div.
* *
* @param html Text to convert. * @param html Text to convert.
* @returns Element. * @returns Element.
*/ */
export function convertTextToHTMLElement(html: string): HTMLElement { export function convertTextToHTMLElement(html: string): HTMLElement {
// Add a div to hold the content, that's the element that will be returned. const element = document.createElement('template');
CoreTemplateElement.innerHTML = '<div>' + html + '</div>';
return <HTMLElement> CoreTemplateElement.content.children[0]; // Add a div to hold the content, that's the element that will be returned.
element.innerHTML = '<div>' + html + '</div>';
return <HTMLElement> element.content.children[0];
} }