2017-03-29 14:13:40 -07:00
|
|
|
import { Component, ElementRef, HostListener, OnInit,
|
|
|
|
QueryList, ViewChild, ViewChildren } from '@angular/core';
|
2017-04-12 12:25:11 -07:00
|
|
|
import { MdSidenav } from '@angular/material';
|
2017-04-16 22:11:00 +01:00
|
|
|
import { Title } from '@angular/platform-browser';
|
2017-03-13 18:08:23 -07:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
import { AutoScrollService } from 'app/shared/auto-scroll.service';
|
|
|
|
import { CurrentNode, NavigationService, NavigationViews, NavigationNode, VersionInfo } from 'app/navigation/navigation.service';
|
2017-03-01 14:30:25 +00:00
|
|
|
import { DocumentService, DocumentContents } from 'app/documents/document.service';
|
2017-03-13 09:20:09 +00:00
|
|
|
import { DocViewerComponent } from 'app/layout/doc-viewer/doc-viewer.component';
|
2017-03-29 14:13:40 -07:00
|
|
|
import { LocationService } from 'app/shared/location.service';
|
|
|
|
import { NavMenuComponent } from 'app/layout/nav-menu/nav-menu.component';
|
2017-03-12 15:20:55 +00:00
|
|
|
import { SearchResultsComponent } from 'app/search/search-results/search-results.component';
|
2017-03-30 09:55:03 +03:00
|
|
|
import { SwUpdateNotificationsService } from 'app/sw-updates/sw-update-notifications.service';
|
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
const sideNavView = 'SideNav';
|
2017-02-02 23:02:23 -08:00
|
|
|
|
2017-01-27 00:20:51 -08:00
|
|
|
@Component({
|
2017-02-02 12:10:47 -08:00
|
|
|
selector: 'aio-shell',
|
2017-03-06 15:08:34 +00:00
|
|
|
templateUrl: './app.component.html',
|
2017-01-27 00:20:51 -08:00
|
|
|
})
|
2017-03-01 14:30:25 +00:00
|
|
|
export class AppComponent implements OnInit {
|
2017-03-02 13:28:28 +00:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
currentNode: CurrentNode;
|
2017-04-01 21:45:32 -07:00
|
|
|
dtOn = false;
|
2017-04-01 09:58:19 +01:00
|
|
|
pageId: string;
|
2017-03-29 14:13:40 -07:00
|
|
|
currentDocument: DocumentContents;
|
|
|
|
footerNodes: NavigationNode[];
|
2017-03-01 14:30:25 +00:00
|
|
|
isSideBySide = false;
|
2017-03-29 14:13:40 -07:00
|
|
|
private isSideNavDoc = false;
|
|
|
|
private previousNavView: string;
|
2017-03-31 16:36:21 -07:00
|
|
|
|
2017-04-18 21:24:19 -07:00
|
|
|
private sideBySideWidth = 1032;
|
2017-03-29 14:13:40 -07:00
|
|
|
sideNavNodes: NavigationNode[];
|
|
|
|
topMenuNodes: NavigationNode[];
|
|
|
|
versionInfo: VersionInfo;
|
2017-03-01 14:30:25 +00:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
get homeImageUrl() {
|
|
|
|
return this.isSideBySide ?
|
2017-03-30 12:21:50 -07:00
|
|
|
'assets/images/logos/standard/logo-nav@2x.png' :
|
2017-04-11 19:21:56 -07:00
|
|
|
'assets/images/logos/standard/shield-large@2x.png';
|
2017-03-29 14:13:40 -07:00
|
|
|
}
|
|
|
|
get isOpened() { return this.isSideBySide && this.isSideNavDoc; }
|
|
|
|
get mode() { return this.isSideBySide ? 'side' : 'over'; }
|
|
|
|
|
|
|
|
// Need the doc-viewer element for scrolling the contents
|
|
|
|
@ViewChild(DocViewerComponent, { read: ElementRef })
|
|
|
|
docViewer: ElementRef;
|
2017-03-01 14:30:25 +00:00
|
|
|
|
2017-03-12 15:20:55 +00:00
|
|
|
@ViewChildren('searchBox, searchResults', { read: ElementRef })
|
|
|
|
searchElements: QueryList<ElementRef>;
|
|
|
|
|
|
|
|
@ViewChild(SearchResultsComponent)
|
|
|
|
searchResults: SearchResultsComponent;
|
2017-03-13 18:08:23 -07:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
@ViewChild(MdSidenav)
|
|
|
|
sidenav: MdSidenav;
|
2017-03-13 09:20:09 +00:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
constructor(
|
|
|
|
private autoScrollService: AutoScrollService,
|
|
|
|
private documentService: DocumentService,
|
|
|
|
private locationService: LocationService,
|
2017-03-30 09:55:03 +03:00
|
|
|
private navigationService: NavigationService,
|
2017-04-16 22:11:00 +01:00
|
|
|
private swUpdateNotifications: SwUpdateNotificationsService,
|
|
|
|
private titleService: Title
|
2017-03-29 14:13:40 -07:00
|
|
|
) { }
|
2017-02-15 11:22:37 -08:00
|
|
|
|
2017-03-01 14:30:25 +00:00
|
|
|
ngOnInit() {
|
2017-04-18 21:24:19 -07:00
|
|
|
this.onResize(window.innerWidth);
|
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
/* No need to unsubscribe because this root component never dies */
|
|
|
|
|
2017-04-16 22:11:00 +01:00
|
|
|
this.documentService.currentDocument.subscribe(doc => {
|
|
|
|
this.currentDocument = doc;
|
|
|
|
this.setDocumentTitle(doc.title);
|
2017-04-18 16:18:18 +01:00
|
|
|
this.pageId = this.currentDocument.url.replace('/', '-');
|
|
|
|
|
|
|
|
// Special case the home page
|
|
|
|
if (this.pageId === 'index') {
|
|
|
|
this.pageId = 'home';
|
|
|
|
}
|
2017-04-16 22:11:00 +01:00
|
|
|
});
|
2017-03-29 14:13:40 -07:00
|
|
|
|
|
|
|
// scroll even if only the hash fragment changed
|
|
|
|
this.locationService.currentUrl.subscribe(url => this.autoScroll());
|
|
|
|
|
|
|
|
this.navigationService.currentNode.subscribe(currentNode => {
|
|
|
|
this.currentNode = currentNode;
|
|
|
|
|
2017-04-10 12:44:54 -07:00
|
|
|
// Toggle the sidenav if side-by-side and the kind of view changed
|
2017-03-29 14:13:40 -07:00
|
|
|
if (this.previousNavView === currentNode.view) { return; }
|
|
|
|
this.previousNavView = currentNode.view;
|
|
|
|
this.isSideNavDoc = currentNode.view === sideNavView;
|
2017-04-10 12:44:54 -07:00
|
|
|
this.sideNavToggle(this.isSideNavDoc && this.isSideBySide);
|
2017-03-29 14:13:40 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
this.navigationService.navigationViews.subscribe(views => {
|
2017-04-01 10:01:54 +01:00
|
|
|
this.footerNodes = views['Footer'] || [];
|
|
|
|
this.sideNavNodes = views['SideNav'] || [];
|
|
|
|
this.topMenuNodes = views['TopBar'] || [];
|
2017-03-29 14:13:40 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
this.navigationService.versionInfo.subscribe( vi => this.versionInfo = vi );
|
|
|
|
|
2017-03-30 09:55:03 +03:00
|
|
|
this.swUpdateNotifications.enable();
|
2017-03-29 14:13:40 -07:00
|
|
|
}
|
2017-03-13 09:20:09 +00:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
// Scroll to the anchor in the hash fragment.
|
|
|
|
autoScroll() {
|
2017-04-17 15:19:15 -07:00
|
|
|
this.autoScrollService.scroll();
|
2017-03-13 09:20:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-01 21:45:32 -07:00
|
|
|
onDocRendered() {
|
2017-03-13 09:20:09 +00:00
|
|
|
// This handler is needed because the subscription to the `currentUrl` in `ngOnInit`
|
|
|
|
// gets triggered too early before the doc-viewer has finished rendering the doc
|
2017-03-29 14:13:40 -07:00
|
|
|
this.autoScroll();
|
2017-03-01 14:30:25 +00:00
|
|
|
}
|
2017-02-15 11:22:37 -08:00
|
|
|
|
2017-04-18 21:24:19 -07:00
|
|
|
@HostListener('window:resize', ['$event.target.innerWidth'])
|
2017-03-01 14:30:25 +00:00
|
|
|
onResize(width) {
|
2017-04-18 21:24:19 -07:00
|
|
|
this.isSideBySide = width > this.sideBySideWidth;
|
2017-03-01 14:30:25 +00:00
|
|
|
}
|
2017-03-13 21:06:15 +00:00
|
|
|
|
2017-04-01 21:45:32 -07:00
|
|
|
@HostListener('click', ['$event.target', '$event.button', '$event.ctrlKey', '$event.metaKey', '$event.altKey'])
|
|
|
|
onClick(eventTarget: HTMLElement, button: number, ctrlKey: boolean, metaKey: boolean, altKey: boolean): boolean {
|
2017-03-12 15:20:55 +00:00
|
|
|
|
|
|
|
// Hide the search results if we clicked outside both the search box and the search results
|
|
|
|
if (this.searchResults) {
|
|
|
|
const hits = this.searchElements.filter(element => element.nativeElement.contains(eventTarget));
|
|
|
|
if (hits.length === 0) {
|
|
|
|
this.searchResults.hideResults();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-01 21:45:32 -07:00
|
|
|
if (eventTarget.tagName === 'FOOTER' && metaKey && altKey) {
|
|
|
|
this.dtOn = !this.dtOn;
|
2017-04-18 12:13:13 -07:00
|
|
|
return false;
|
2017-04-01 21:45:32 -07:00
|
|
|
}
|
|
|
|
|
2017-04-18 12:13:13 -07:00
|
|
|
// Deal with anchor clicks; climb DOM tree until anchor found (or null)
|
|
|
|
let target = eventTarget;
|
|
|
|
while (target && !(target instanceof HTMLAnchorElement)) {
|
|
|
|
target = target.parentElement;
|
2017-03-29 14:13:40 -07:00
|
|
|
}
|
2017-04-18 12:13:13 -07:00
|
|
|
if (target) {
|
|
|
|
return this.locationService.handleAnchorClick(target as HTMLAnchorElement, button, ctrlKey, metaKey);
|
2017-03-13 21:06:15 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2017-03-29 14:13:40 -07:00
|
|
|
|
|
|
|
sideNavToggle(value?: boolean) {
|
|
|
|
this.sidenav.toggle(value);
|
|
|
|
}
|
2017-04-16 22:11:00 +01:00
|
|
|
|
|
|
|
setDocumentTitle(title) {
|
2017-04-19 09:56:39 +01:00
|
|
|
if (title.trim()) {
|
|
|
|
this.titleService.setTitle(`Angular - ${title}`);
|
|
|
|
} else {
|
|
|
|
this.titleService.setTitle('Angular');
|
|
|
|
}
|
2017-04-16 22:11:00 +01:00
|
|
|
}
|
2017-01-27 00:20:51 -08:00
|
|
|
}
|