MOBILE-2327 core: Hide navbar-buttons when change core-tab
parent
ac6b54322c
commit
3ed3ded3da
|
@ -34,6 +34,7 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
|
||||||
hideMenu: boolean;
|
hideMenu: boolean;
|
||||||
ariaLabel: string;
|
ariaLabel: string;
|
||||||
protected items: CoreContextMenuItemComponent[] = [];
|
protected items: CoreContextMenuItemComponent[] = [];
|
||||||
|
protected itemsMovedToParent: CoreContextMenuItemComponent[] = [];
|
||||||
protected itemsChangedStream: Subject<void>; // Stream to update the hideMenu boolean when items change.
|
protected itemsChangedStream: Subject<void>; // Stream to update the hideMenu boolean when items change.
|
||||||
protected instanceId: string;
|
protected instanceId: string;
|
||||||
protected parentContextMenu: CoreContextMenuComponent;
|
protected parentContextMenu: CoreContextMenuComponent;
|
||||||
|
@ -74,7 +75,11 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
|
||||||
if (this.parentContextMenu) {
|
if (this.parentContextMenu) {
|
||||||
// All items were moved to the "parent" menu. Add the item in there.
|
// All items were moved to the "parent" menu. Add the item in there.
|
||||||
this.parentContextMenu.addItem(item);
|
this.parentContextMenu.addItem(item);
|
||||||
} else {
|
|
||||||
|
if (this.itemsMovedToParent.indexOf(item) == -1) {
|
||||||
|
this.itemsMovedToParent.push(item);
|
||||||
|
}
|
||||||
|
} else if (this.items.indexOf(item) == -1) {
|
||||||
this.items.push(item);
|
this.items.push(item);
|
||||||
this.itemsChanged();
|
this.itemsChanged();
|
||||||
}
|
}
|
||||||
|
@ -103,7 +108,9 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
// Add all the items to the other menu.
|
// Add all the items to the other menu.
|
||||||
for (let i = 0; i < this.items.length; i++) {
|
for (let i = 0; i < this.items.length; i++) {
|
||||||
contextMenu.addItem(this.items[i]);
|
const item = this.items[i];
|
||||||
|
contextMenu.addItem(item);
|
||||||
|
this.itemsMovedToParent.push(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all items from the current menu.
|
// Remove all items from the current menu.
|
||||||
|
@ -120,6 +127,11 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
|
||||||
if (this.parentContextMenu) {
|
if (this.parentContextMenu) {
|
||||||
// All items were moved to the "parent" menu. Remove the item from there.
|
// All items were moved to the "parent" menu. Remove the item from there.
|
||||||
this.parentContextMenu.removeItem(item);
|
this.parentContextMenu.removeItem(item);
|
||||||
|
|
||||||
|
const index = this.itemsMovedToParent.indexOf(item);
|
||||||
|
if (index >= 0) {
|
||||||
|
this.itemsMovedToParent.splice(index, 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const index = this.items.indexOf(item);
|
const index = this.items.indexOf(item);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
@ -129,6 +141,28 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the items that were merged to a parent context menu.
|
||||||
|
*/
|
||||||
|
removeMergedItems(): void {
|
||||||
|
if (this.parentContextMenu) {
|
||||||
|
for (let i = 0; i < this.itemsMovedToParent.length; i++) {
|
||||||
|
this.parentContextMenu.removeItem(this.itemsMovedToParent[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the items that were merged to a parent context menu.
|
||||||
|
*/
|
||||||
|
restoreMergedItems(): void {
|
||||||
|
if (this.parentContextMenu) {
|
||||||
|
for (let i = 0; i < this.itemsMovedToParent.length; i++) {
|
||||||
|
this.parentContextMenu.addItem(this.itemsMovedToParent[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the context menu.
|
* Show the context menu.
|
||||||
*
|
*
|
||||||
|
@ -146,5 +180,6 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
|
||||||
*/
|
*/
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.domUtils.removeInstanceById(this.instanceId);
|
this.domUtils.removeInstanceById(this.instanceId);
|
||||||
|
this.removeMergedItems();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { Component, Input, OnInit, OnDestroy, ContentChildren, ElementRef, Query
|
||||||
import { Button } from 'ionic-angular';
|
import { Button } from 'ionic-angular';
|
||||||
import { CoreLoggerProvider } from '../../providers/logger';
|
import { CoreLoggerProvider } from '../../providers/logger';
|
||||||
import { CoreDomUtilsProvider } from '../../providers/utils/dom';
|
import { CoreDomUtilsProvider } from '../../providers/utils/dom';
|
||||||
|
import { CoreContextMenuComponent } from '../context-menu/context-menu';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to add buttons to the app's header without having to place them inside the header itself. This is meant for
|
* Component to add buttons to the app's header without having to place them inside the header itself. This is meant for
|
||||||
|
@ -59,12 +60,16 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
protected _hidden: boolean;
|
protected _hidden: boolean;
|
||||||
|
protected forceHidden = false;
|
||||||
protected logger: any;
|
protected logger: any;
|
||||||
protected movedChildren: Node[];
|
protected movedChildren: Node[];
|
||||||
|
protected instanceId: string;
|
||||||
|
protected mergedContextMenu: CoreContextMenuComponent;
|
||||||
|
|
||||||
constructor(element: ElementRef, logger: CoreLoggerProvider, private domUtils: CoreDomUtilsProvider) {
|
constructor(element: ElementRef, logger: CoreLoggerProvider, private domUtils: CoreDomUtilsProvider) {
|
||||||
this.element = element.nativeElement;
|
this.element = element.nativeElement;
|
||||||
this.logger = logger.getInstance('CoreNavBarButtonsComponent');
|
this.logger = logger.getInstance('CoreNavBarButtonsComponent');
|
||||||
|
this.instanceId = this.domUtils.storeInstanceByElement(this.element, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,6 +105,17 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force or unforce hiding all buttons. If this is true, it will override the "hidden" input.
|
||||||
|
*
|
||||||
|
* @param {boolean} value The value to set.
|
||||||
|
*/
|
||||||
|
forceHide(value: boolean): void {
|
||||||
|
this.forceHidden = value;
|
||||||
|
|
||||||
|
this.showHideAllElements();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If both button containers have a context menu, merge them into a single one.
|
* If both button containers have a context menu, merge them into a single one.
|
||||||
*
|
*
|
||||||
|
@ -122,7 +138,9 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
secondaryContextMenuInstance = this.domUtils.getInstanceByElement(secondaryContextMenu);
|
secondaryContextMenuInstance = this.domUtils.getInstanceByElement(secondaryContextMenu);
|
||||||
|
|
||||||
if (mainContextMenuInstance && secondaryContextMenuInstance) {
|
if (mainContextMenuInstance && secondaryContextMenuInstance) {
|
||||||
secondaryContextMenuInstance.mergeContextMenus(mainContextMenuInstance);
|
this.mergedContextMenu = secondaryContextMenuInstance;
|
||||||
|
|
||||||
|
this.mergedContextMenu.mergeContextMenus(mainContextMenuInstance);
|
||||||
|
|
||||||
// Remove the empty context menu from the DOM.
|
// Remove the empty context menu from the DOM.
|
||||||
secondaryContextMenu.parentElement.removeChild(secondaryContextMenu);
|
secondaryContextMenu.parentElement.removeChild(secondaryContextMenu);
|
||||||
|
@ -189,11 +207,21 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
* Show or hide all the elements.
|
* Show or hide all the elements.
|
||||||
*/
|
*/
|
||||||
protected showHideAllElements(): void {
|
protected showHideAllElements(): void {
|
||||||
|
// Show or hide all moved children.
|
||||||
if (this.movedChildren) {
|
if (this.movedChildren) {
|
||||||
this.movedChildren.forEach((child: Node) => {
|
this.movedChildren.forEach((child: Node) => {
|
||||||
this.showHideElement(child);
|
this.showHideElement(child);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show or hide all the context menu items that were merged to another context menu.
|
||||||
|
if (this.mergedContextMenu) {
|
||||||
|
if (this.forceHidden || this._hidden) {
|
||||||
|
this.mergedContextMenu.removeMergedItems();
|
||||||
|
} else {
|
||||||
|
this.mergedContextMenu.restoreMergedItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -204,7 +232,7 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
protected showHideElement(element: Node): void {
|
protected showHideElement(element: Node): void {
|
||||||
// Check if it's an HTML Element
|
// Check if it's an HTML Element
|
||||||
if (element instanceof Element) {
|
if (element instanceof Element) {
|
||||||
if (this._hidden) {
|
if (this.forceHidden || this._hidden) {
|
||||||
element.classList.add(this.BUTTON_HIDDEN_CLASS);
|
element.classList.add(this.BUTTON_HIDDEN_CLASS);
|
||||||
} else {
|
} else {
|
||||||
element.classList.remove(this.BUTTON_HIDDEN_CLASS);
|
element.classList.remove(this.BUTTON_HIDDEN_CLASS);
|
||||||
|
@ -216,6 +244,8 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
* Component destroyed.
|
* Component destroyed.
|
||||||
*/
|
*/
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
|
this.domUtils.removeInstanceById(this.instanceId);
|
||||||
|
|
||||||
// This component was destroyed, remove all the buttons that were moved.
|
// This component was destroyed, remove all the buttons that were moved.
|
||||||
// The buttons can be moved outside of the current page, that's why we need to manually destroy them.
|
// The buttons can be moved outside of the current page, that's why we need to manually destroy them.
|
||||||
// There's no need to destroy context menu items that were merged because they weren't moved from their DOM position.
|
// There's no need to destroy context menu items that were merged because they weren't moved from their DOM position.
|
||||||
|
@ -226,5 +256,9 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.mergedContextMenu) {
|
||||||
|
this.mergedContextMenu.removeMergedItems();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
import { Component, Input, Output, OnInit, OnDestroy, ElementRef, EventEmitter, ContentChild, TemplateRef } from '@angular/core';
|
import { Component, Input, Output, OnInit, OnDestroy, ElementRef, EventEmitter, ContentChild, TemplateRef } from '@angular/core';
|
||||||
import { CoreTabsComponent } from './tabs';
|
import { CoreTabsComponent } from './tabs';
|
||||||
import { Content } from 'ionic-angular';
|
import { Content } from 'ionic-angular';
|
||||||
|
import { CoreDomUtilsProvider } from '../../providers/utils/dom';
|
||||||
|
import { CoreNavBarButtonsComponent } from '../navbar-buttons/navbar-buttons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A tab to use inside core-tabs. The content of this tab will be displayed when the tab is selected.
|
* A tab to use inside core-tabs. The content of this tab will be displayed when the tab is selected.
|
||||||
|
@ -55,7 +57,7 @@ export class CoreTabComponent implements OnInit, OnDestroy {
|
||||||
element: HTMLElement; // The core-tab element.
|
element: HTMLElement; // The core-tab element.
|
||||||
loaded = false;
|
loaded = false;
|
||||||
|
|
||||||
constructor(private tabs: CoreTabsComponent, element: ElementRef) {
|
constructor(protected tabs: CoreTabsComponent, element: ElementRef, protected domUtils: CoreDomUtilsProvider) {
|
||||||
this.element = element.nativeElement;
|
this.element = element.nativeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +83,7 @@ export class CoreTabComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
this.ionSelect.emit(this);
|
this.ionSelect.emit(this);
|
||||||
|
this.showHideNavBarButtons(true);
|
||||||
|
|
||||||
// Setup tab scrolling.
|
// Setup tab scrolling.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -97,5 +100,39 @@ export class CoreTabComponent implements OnInit, OnDestroy {
|
||||||
*/
|
*/
|
||||||
unselectTab(): void {
|
unselectTab(): void {
|
||||||
this.element.classList.remove('selected');
|
this.element.classList.remove('selected');
|
||||||
|
this.showHideNavBarButtons(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all child core-navbar-buttons. We need to use querySelectorAll because ContentChildren doesn't work with ng-template.
|
||||||
|
* https://github.com/angular/angular/issues/14842
|
||||||
|
*
|
||||||
|
* @return {CoreNavBarButtonsComponent[]} List of component instances.
|
||||||
|
*/
|
||||||
|
protected getChildrenNavBarButtons(): CoreNavBarButtonsComponent[] {
|
||||||
|
const elements = this.element.querySelectorAll('core-navbar-buttons'),
|
||||||
|
instances: CoreNavBarButtonsComponent[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < elements.length; i++) {
|
||||||
|
const instance = this.domUtils.getInstanceByElement(elements[i]);
|
||||||
|
if (instance) {
|
||||||
|
instances.push(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show all hide all children navbar buttons.
|
||||||
|
*
|
||||||
|
* @param {boolean} show Whether to show or hide the buttons.
|
||||||
|
*/
|
||||||
|
protected showHideNavBarButtons(show: boolean): void {
|
||||||
|
const instances = this.getChildrenNavBarButtons();
|
||||||
|
|
||||||
|
for (const i in instances) {
|
||||||
|
instances[i].forceHide(!show);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,7 @@
|
||||||
<ion-navbar>
|
<ion-navbar>
|
||||||
<ion-title><core-format-text [text]="title"></core-format-text></ion-title>
|
<ion-title><core-format-text [text]="title"></core-format-text></ion-title>
|
||||||
|
|
||||||
<ion-buttons end>
|
<ion-buttons end></ion-buttons>
|
||||||
<core-context-menu>
|
|
||||||
<core-context-menu-item *ngIf="displayEnableDownload" [priority]="2000" [content]="'core.settings.enabledownloadsection' | translate" (action)="toggleDownload()" [iconAction]="downloadEnabledIcon"></core-context-menu-item>
|
|
||||||
<core-context-menu-item [priority]="1900" [content]="'core.course.downloadcourse' | translate" (action)="prefetchCourse()" [iconAction]="prefetchCourseData.prefetchCourseIcon" [closeOnClick]="false"></core-context-menu-item>
|
|
||||||
</core-context-menu>
|
|
||||||
</ion-buttons>
|
|
||||||
</ion-navbar>
|
</ion-navbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
|
@ -15,6 +10,12 @@
|
||||||
<!-- Course contents tab. -->
|
<!-- Course contents tab. -->
|
||||||
<core-tab [title]="'core.course.contents' | translate">
|
<core-tab [title]="'core.course.contents' | translate">
|
||||||
<ng-template>
|
<ng-template>
|
||||||
|
<core-navbar-buttons>
|
||||||
|
<core-context-menu>
|
||||||
|
<core-context-menu-item *ngIf="displayEnableDownload" [priority]="2000" [content]="'core.settings.enabledownloadsection' | translate" (action)="toggleDownload()" [iconAction]="downloadEnabledIcon"></core-context-menu-item>
|
||||||
|
<core-context-menu-item [priority]="1900" [content]="'core.course.downloadcourse' | translate" (action)="prefetchCourse()" [iconAction]="prefetchCourseData.prefetchCourseIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||||
|
</core-context-menu>
|
||||||
|
</core-navbar-buttons>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ion-refresher [enabled]="dataLoaded" (ionRefresh)="doRefresh($event)">
|
<ion-refresher [enabled]="dataLoaded" (ionRefresh)="doRefresh($event)">
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
|
|
|
@ -152,7 +152,7 @@ export class CoreDomUtilsProvider {
|
||||||
this.element.innerHTML = html;
|
this.element.innerHTML = html;
|
||||||
elements = this.element.querySelectorAll('a, img, audio, video, source, track');
|
elements = this.element.querySelectorAll('a, img, audio, video, source, track');
|
||||||
|
|
||||||
for (const i in elements) {
|
for (let i = 0; i < elements.length; i++) {
|
||||||
const element = elements[i];
|
const element = elements[i];
|
||||||
let url = element.tagName === 'A' ? element.href : element.src;
|
let url = element.tagName === 'A' ? element.href : element.src;
|
||||||
|
|
||||||
|
@ -525,7 +525,7 @@ export class CoreDomUtilsProvider {
|
||||||
|
|
||||||
if (removeAll) {
|
if (removeAll) {
|
||||||
selected = this.element.querySelectorAll(selector);
|
selected = this.element.querySelectorAll(selector);
|
||||||
for (const i in selected) {
|
for (let i = 0; i < selected.length; i++) {
|
||||||
selected[i].remove();
|
selected[i].remove();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -568,7 +568,7 @@ export class CoreDomUtilsProvider {
|
||||||
for (const key in map) {
|
for (const key in map) {
|
||||||
const foundElements = element.querySelectorAll('.' + key);
|
const foundElements = element.querySelectorAll('.' + key);
|
||||||
|
|
||||||
for (const i in foundElements) {
|
for (let i = 0; i < foundElements.length; i++) {
|
||||||
const foundElement = foundElements[i];
|
const foundElement = foundElements[i];
|
||||||
foundElement.className = foundElement.className.replace(key, map[key]);
|
foundElement.className = foundElement.className.replace(key, map[key]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue