MOBILE-3063 reading-mode: Find header in splitview if needed
parent
e6733bbd65
commit
170817ed7c
|
@ -89,7 +89,7 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
|||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
try {
|
||||
const header = await this.searchHeader();
|
||||
const header = await CoreDom.findIonHeaderFromElement(this.element);
|
||||
if (header) {
|
||||
// Search the right buttons container (start, end or any).
|
||||
let selector = 'ion-buttons';
|
||||
|
@ -192,43 +192,6 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
|||
return componentRef.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the ion-header where the buttons should be added.
|
||||
*
|
||||
* @returns Promise resolved with the header element.
|
||||
*/
|
||||
protected async searchHeader(): Promise<HTMLIonHeaderElement> {
|
||||
await CoreDom.waitToBeInDOM(this.element);
|
||||
let parentPage: HTMLElement | null = this.element;
|
||||
|
||||
while (parentPage && parentPage.parentElement) {
|
||||
const content = parentPage.closest<HTMLIonContentElement>('ion-content');
|
||||
if (content) {
|
||||
// Sometimes ion-page class is not yet added by the ViewController, wait for content to render.
|
||||
await content.componentOnReady();
|
||||
}
|
||||
|
||||
parentPage = parentPage.parentElement.closest('.ion-page, .ion-page-hidden, .ion-page-invisible');
|
||||
|
||||
// Check if the page has a header. If it doesn't, search the next parent page.
|
||||
let header = parentPage?.querySelector<HTMLIonHeaderElement>(':scope > ion-header');
|
||||
|
||||
if (header && getComputedStyle(header).display !== 'none') {
|
||||
return header;
|
||||
}
|
||||
|
||||
// Find using content if any.
|
||||
header = content?.parentElement?.querySelector<HTMLIonHeaderElement>(':scope > ion-header');
|
||||
|
||||
if (header && getComputedStyle(header).display !== 'none') {
|
||||
return header;
|
||||
}
|
||||
}
|
||||
|
||||
// Header not found, reject.
|
||||
throw Error('Header not found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show or hide all the elements.
|
||||
*/
|
||||
|
|
|
@ -47,7 +47,6 @@ export class CoreReadingModeDirective implements AfterViewInit, OnDestroy {
|
|||
protected hiddenElements: HTMLElement[] = [];
|
||||
protected renamedStyles: HTMLElement[] = [];
|
||||
protected enabled = false;
|
||||
protected contentEl?: HTMLIonContentElement;
|
||||
protected header?: CoreCollapsibleHeaderDirective;
|
||||
protected logger = CoreLogger.getInstance('CoreReadingModeDirective');
|
||||
|
||||
|
@ -64,7 +63,12 @@ export class CoreReadingModeDirective implements AfterViewInit, OnDestroy {
|
|||
async ngAfterViewInit(): Promise<void> {
|
||||
await this.viewportPromise;
|
||||
await CoreWait.nextTick();
|
||||
this.addTextViewerButton();
|
||||
await this.addTextViewerButton();
|
||||
|
||||
this.enabled = document.body.classList.contains('core-reading-mode-enabled');
|
||||
if (this.enabled) {
|
||||
await this.enterReadingMode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,24 +76,26 @@ export class CoreReadingModeDirective implements AfterViewInit, OnDestroy {
|
|||
*/
|
||||
protected async addTextViewerButton(): Promise<void> {
|
||||
const page = CoreDom.closest(this.element, '.ion-page');
|
||||
this.contentEl = page?.querySelector('ion-content') ?? undefined;
|
||||
const contentEl = page?.querySelector('ion-content') ?? undefined;
|
||||
|
||||
const buttonsContainer = page?.querySelector<HTMLIonButtonsElement>('ion-header ion-toolbar ion-buttons[slot="end"]');
|
||||
|
||||
if (!buttonsContainer) {
|
||||
const header = await CoreDom.findIonHeaderFromElement(this.element);
|
||||
const buttonsContainer = header?.querySelector<HTMLIonButtonsElement>('ion-toolbar ion-buttons[slot="end"]');
|
||||
if (!buttonsContainer || !contentEl) {
|
||||
this.logger.warn('The header was not found, or it didn\'t have any ion-buttons on slot end.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
contentEl.classList.add('core-reading-mode-content');
|
||||
|
||||
if (buttonsContainer.querySelector('.core-text-viewer-button')) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.contentEl?.classList.add('core-reading-mode-content');
|
||||
|
||||
const header = CoreDirectivesRegistry.resolve(page?.querySelector('ion-header'), CoreCollapsibleHeaderDirective);
|
||||
if (header) {
|
||||
this.header = header;
|
||||
const collapsibleHeader = CoreDirectivesRegistry.resolve(header, CoreCollapsibleHeaderDirective);
|
||||
if (collapsibleHeader) {
|
||||
this.header = collapsibleHeader;
|
||||
}
|
||||
|
||||
const label = Translate.instant('core.viewer.enterreadingmode');
|
||||
|
@ -118,7 +124,6 @@ export class CoreReadingModeDirective implements AfterViewInit, OnDestroy {
|
|||
} else {
|
||||
this.showReadingSettings();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -214,8 +219,14 @@ export class CoreReadingModeDirective implements AfterViewInit, OnDestroy {
|
|||
* @inheritdoc
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.disableReadingMode();
|
||||
this.viewportPromise?.cancel();
|
||||
|
||||
if (this.enabled && document.body.querySelectorAll('[core-reading-mode]')) {
|
||||
// Do not disable if there are more instances of the directive in the DOM.
|
||||
|
||||
return;
|
||||
}
|
||||
this.disableReadingMode();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -781,6 +781,44 @@ export class CoreDom {
|
|||
return !!units && units.length > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the ion-header of the page.
|
||||
* This function is usually used to find the header of a page to add buttons.
|
||||
*
|
||||
* @returns The header element if found.
|
||||
*/
|
||||
static async findIonHeaderFromElement(element: HTMLElement): Promise<HTMLElement | null> {
|
||||
await CoreDom.waitToBeInDOM(element);
|
||||
let parentPage: HTMLElement | null = element;
|
||||
|
||||
while (parentPage && parentPage.parentElement) {
|
||||
const content = parentPage.closest<HTMLIonContentElement>('ion-content');
|
||||
if (content) {
|
||||
// Sometimes ion-page class is not yet added by the ViewController, wait for content to render.
|
||||
await content.componentOnReady();
|
||||
}
|
||||
|
||||
parentPage = parentPage.parentElement.closest('.ion-page, .ion-page-hidden, .ion-page-invisible');
|
||||
|
||||
// Check if the page has a header. If it doesn't, search the next parent page.
|
||||
let header = parentPage?.querySelector<HTMLIonHeaderElement>(':scope > ion-header');
|
||||
|
||||
if (header && getComputedStyle(header).display !== 'none') {
|
||||
return header;
|
||||
}
|
||||
|
||||
// Find using content if any.
|
||||
header = content?.parentElement?.querySelector<HTMLIonHeaderElement>(':scope > ion-header');
|
||||
|
||||
if (header && getComputedStyle(header).display !== 'none') {
|
||||
return header;
|
||||
}
|
||||
}
|
||||
|
||||
// Header not found, reject.
|
||||
throw Error('Header not found.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,7 +37,8 @@ body.core-reading-mode-enabled {
|
|||
}
|
||||
}
|
||||
|
||||
ion-content.core-reading-mode-content {
|
||||
ion-content.core-reading-mode-content,
|
||||
ion-content.core-reading-mode-content core-split-view ion-content {
|
||||
--background: var(--reading-mode-background, --ion-background-color);
|
||||
background: var(--background);
|
||||
|
||||
|
|
Loading…
Reference in New Issue