diff --git a/src/core/directives/collapsible-footer.ts b/src/core/directives/collapsible-footer.ts index 4a44fa0b9..73e9dbd5a 100644 --- a/src/core/directives/collapsible-footer.ts +++ b/src/core/directives/collapsible-footer.ts @@ -50,11 +50,10 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy { protected contentScrollListener?: EventListener; protected endContentScrollListener?: EventListener; protected resizeListener?: CoreEventObserver; - protected domPromise?: CoreCancellablePromise; + protected slotPromise?: CoreCancellablePromise; constructor(el: ElementRef, protected ionContent: IonContent) { this.element = el.nativeElement; - this.element.setAttribute('slot', 'fixed'); // Just in case somebody forgets to add it. } /** @@ -63,9 +62,9 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy { async ngOnInit(): Promise { // Only if not present or explicitly falsy it will be false. this.appearOnBottom = !CoreUtils.isFalseOrZero(this.appearOnBottom); - this.domPromise = CoreDom.waitToBeInDOM(this.element); + this.slotPromise = CoreDom.slotOnContent(this.element); - await this.domPromise; + await this.slotPromise; await this.waitLoadingsDone(); await this.waitFormatTextsRendered(); @@ -229,7 +228,7 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy { } this.resizeListener?.off(); - this.domPromise?.cancel(); + this.slotPromise?.cancel(); } } diff --git a/src/core/directives/fab.ts b/src/core/directives/fab.ts index 90f700fc5..fe18f8274 100644 --- a/src/core/directives/fab.ts +++ b/src/core/directives/fab.ts @@ -31,19 +31,18 @@ export class CoreFabDirective implements OnInit, OnDestroy { protected element: HTMLElement; protected content?: HTMLIonContentElement | null; protected initialPaddingBottom = 0; - protected domPromise?: CoreCancellablePromise; + protected slotPromise?: CoreCancellablePromise; constructor(el: ElementRef) { this.element = el.nativeElement; - this.element.setAttribute('slot', 'fixed'); } /** * @inheritdoc */ async ngOnInit(): Promise { - this.domPromise = CoreDom.waitToBeInDOM(this.element); - await this.domPromise; + this.slotPromise = CoreDom.slotOnContent(this.element); + await this.slotPromise; this.content = this.element.closest('ion-content'); @@ -70,12 +69,6 @@ export class CoreFabDirective implements OnInit, OnDestroy { } const initialHeight = this.element.getBoundingClientRect().height || 56; - - // Move element to the nearest ion-content if it's not the parent - if (this.element.parentElement?.nodeName != 'ION-CONTENT') { - this.content.appendChild(this.element); - } - this.content.style.setProperty('--padding-bottom', this.initialPaddingBottom + initialHeight + 'px'); } @@ -86,7 +79,7 @@ export class CoreFabDirective implements OnInit, OnDestroy { if (this.content) { this.content.style.setProperty('--padding-bottom', this.initialPaddingBottom + 'px'); } - this.domPromise?.cancel(); + this.slotPromise?.cancel(); } } diff --git a/src/core/features/block/components/side-blocks-button/side-blocks-button.ts b/src/core/features/block/components/side-blocks-button/side-blocks-button.ts index e8b369c29..e748b67aa 100644 --- a/src/core/features/block/components/side-blocks-button/side-blocks-button.ts +++ b/src/core/features/block/components/side-blocks-button/side-blocks-button.ts @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { CoreCancellablePromise } from '@classes/cancellable-promise'; import { CoreUserTours, CoreUserToursAlignment, CoreUserToursSide } from '@features/usertours/services/user-tours'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreDom } from '@singletons/dom'; import { CoreBlockSideBlocksTourComponent } from '../side-blocks-tour/side-blocks-tour'; import { CoreBlockSideBlocksComponent } from '../side-blocks/side-blocks'; @@ -26,11 +28,25 @@ import { CoreBlockSideBlocksComponent } from '../side-blocks/side-blocks'; templateUrl: 'side-blocks-button.html', styleUrls: ['side-blocks-button.scss'], }) -export class CoreBlockSideBlocksButtonComponent { +export class CoreBlockSideBlocksButtonComponent implements OnInit, OnDestroy { @Input() courseId!: number; @ViewChild('button', { read: ElementRef }) button?: ElementRef; + protected element: HTMLElement; + protected slotPromise?: CoreCancellablePromise; + + constructor(el: ElementRef) { + this.element = el.nativeElement; + } + + /** + * @inheritdoc + */ + async ngOnInit(): Promise { + this.slotPromise = CoreDom.slotOnContent(this.element); + } + /** * Open side blocks. */ @@ -62,4 +78,11 @@ export class CoreBlockSideBlocksButtonComponent { }); } + /** + * @inheritdoc + */ + ngOnDestroy(): void { + this.slotPromise?.cancel(); + } + } diff --git a/src/core/features/course/format/singleactivity/components/core-course-format-single-activity.html b/src/core/features/course/format/singleactivity/components/core-course-format-single-activity.html index 68eedcebf..aa42eeadb 100644 --- a/src/core/features/course/format/singleactivity/components/core-course-format-single-activity.html +++ b/src/core/features/course/format/singleactivity/components/core-course-format-single-activity.html @@ -1,4 +1,4 @@ - + diff --git a/src/core/features/courses/pages/dashboard/dashboard.html b/src/core/features/courses/pages/dashboard/dashboard.html index 1e9771413..38dc1f17e 100644 --- a/src/core/features/courses/pages/dashboard/dashboard.html +++ b/src/core/features/courses/pages/dashboard/dashboard.html @@ -15,7 +15,7 @@ - + diff --git a/src/core/features/sitehome/pages/index/index.html b/src/core/features/sitehome/pages/index/index.html index 97f7ba85a..f7c3d0856 100644 --- a/src/core/features/sitehome/pages/index/index.html +++ b/src/core/features/sitehome/pages/index/index.html @@ -45,7 +45,7 @@ - + diff --git a/src/core/singletons/dom.ts b/src/core/singletons/dom.ts index 7bb8be177..fdd0dd9d0 100644 --- a/src/core/singletons/dom.ts +++ b/src/core/singletons/dom.ts @@ -205,6 +205,38 @@ export class CoreDom { return CoreDom.scrollToElement(container, '.core-input-error'); } + /** + * Move element to content so it can be slotted. + * + * @param element HTML Element. + * @param slot Slot name. + * @return Promise resolved when done. + */ + static slotOnContent(element: HTMLElement, slot = 'fixed'): CoreCancellablePromise { + element.setAttribute('slot', slot); + if (element.parentElement?.nodeName === 'ION-CONTENT') { + return CoreCancellablePromise.resolve(); + } + + const domPromise = CoreDom.waitToBeInDOM(element); + + return new CoreCancellablePromise( + async (resolve) => { + await domPromise; + + // Move element to the nearest ion-content if it's not the parent + if (element.parentElement?.nodeName !== 'ION-CONTENT') { + element.closest('ion-content')?.appendChild(element); + } + + resolve(); + }, + () => { + domPromise.cancel(); + }, + ); + } + /** * Wait an element to be added to the root DOM. *