diff --git a/src/addons/mod/h5pactivity/components/index/index.ts b/src/addons/mod/h5pactivity/components/index/index.ts index bb7e74b94..4c1fc4335 100644 --- a/src/addons/mod/h5pactivity/components/index/index.ts +++ b/src/addons/mod/h5pactivity/components/index/index.ts @@ -241,6 +241,7 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv protected async loadContentState(): Promise { if (!this.h5pActivity || !this.accessInfo || !AddonModH5PActivity.isSaveStateEnabled(this.h5pActivity, this.accessInfo)) { this.saveStateEnabled = false; + this.contentState = undefined; return; } @@ -260,6 +261,8 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv ); if (contentState === null) { + this.contentState = undefined; + return; } diff --git a/src/core/features/editor/components/rich-text-editor/rich-text-editor.ts b/src/core/features/editor/components/rich-text-editor/rich-text-editor.ts index e39a3a882..c9c122540 100644 --- a/src/core/features/editor/components/rich-text-editor/rich-text-editor.ts +++ b/src/core/features/editor/components/rich-text-editor/rich-text-editor.ts @@ -45,6 +45,7 @@ import { Swiper } from 'swiper'; import { SwiperOptions } from 'swiper/types'; import { ContextLevel } from '@/core/constants'; import { CoreSwiper } from '@singletons/swiper'; +import { CoreTextUtils } from '@services/utils/text'; /** * Component to display a rich text editor if enabled. @@ -398,7 +399,7 @@ export class CoreEditorRichTextEditorComponent implements OnInit, AfterViewInit, return; } - if (this.isNullOrWhiteSpace(this.editorElement.textContent)) { + if (this.isNullOrWhiteSpace(this.editorElement)) { this.clearText(); } else { // The textarea and the form control must receive the original URLs. @@ -417,7 +418,7 @@ export class CoreEditorRichTextEditorComponent implements OnInit, AfterViewInit, return; } - if (this.isNullOrWhiteSpace(this.textarea.value || '')) { + if (this.isNullOrWhiteSpace(this.textarea.value)) { this.clearText(); } else { // Don't emit event so our valueChanges doesn't get notified by this change. @@ -549,20 +550,17 @@ export class CoreEditorRichTextEditorComponent implements OnInit, AfterViewInit, /** * Check if text is empty. * - * @param value text + * @param value Text or element containing the text. * @returns If value is null only a white space. */ - protected isNullOrWhiteSpace(value: string | null | undefined): boolean { - if (value === null || value === undefined) { + protected isNullOrWhiteSpace(valueOrEl: string | HTMLElement | null | undefined): boolean { + if (valueOrEl === null || valueOrEl === undefined) { this.isEmpty = true; return true; } - value = value.replace(/[\n\r]/g, ''); - value = value.split(' ').join(''); - - this.isEmpty = value.length === 0; + this.isEmpty = typeof valueOrEl === 'string' ? CoreTextUtils.htmlIsBlank(valueOrEl) : !CoreDom.elementHasContent(valueOrEl); return this.isEmpty; } diff --git a/src/core/services/utils/text.ts b/src/core/services/utils/text.ts index ba5c93c35..526f3c732 100644 --- a/src/core/services/utils/text.ts +++ b/src/core/services/utils/text.ts @@ -28,6 +28,7 @@ import { AlertButton } from '@ionic/angular'; import { CorePath } from '@singletons/path'; import { CorePlatform } from '@services/platform'; import { ContextLevel } from '@/core/constants'; +import { CoreDom } from '@singletons/dom'; /** * Different type of errors the app can treat. @@ -588,12 +589,9 @@ export class CoreTextUtilsProvider { return true; } - this.template.innerHTML = content.trim().replace(/(\r\n|\n|\r)/g, ''); - const tags = this.template.content.querySelectorAll( - 'img, audio, video, object, iframe, canvas, svg, input, select, textarea, frame, embed', - ); + this.template.innerHTML = content; - return this.template.content.textContent === '' && tags.length === 0; + return !CoreDom.elementHasContent(this.template.content); } /** diff --git a/src/core/singletons/dom.ts b/src/core/singletons/dom.ts index 367418436..f52d8e5f5 100644 --- a/src/core/singletons/dom.ts +++ b/src/core/singletons/dom.ts @@ -56,6 +56,23 @@ export class CoreDom { return CoreDom.closest(node.parentNode, selector); } + /** + * Check if an element has some text or embedded content inside. + * + * @param element Element or document to check. + * @returns Whether has content. + */ + static elementHasContent(element: Element | DocumentFragment): boolean { + const textContent = (element.textContent ?? '').trim().replace(/(\r\n|\n|\r)/g, ''); + if (textContent.length > 0) { + return true; + } + + return element.querySelectorAll( + 'img, audio, video, object, iframe, canvas, svg, input, select, textarea, frame, embed', + ).length > 0; + } + /** * Retrieve the position of a element relative to another element. *