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-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-24 14:34:31 -07:00
|
|
|
currentPath: string;
|
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-04-24 17:15:11 -07:00
|
|
|
isStarting = true;
|
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[];
|
2017-04-25 14:48:01 -07:00
|
|
|
|
|
|
|
currentDocVersion: NavigationNode;
|
|
|
|
docVersions: NavigationNode[];
|
2017-03-29 14:13:40 -07:00
|
|
|
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-27 15:32:46 -07:00
|
|
|
private swUpdateNotifications: SwUpdateNotificationsService
|
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;
|
2017-04-20 14:16:36 +01:00
|
|
|
this.setPageId(doc.id);
|
2017-04-16 22:11:00 +01:00
|
|
|
});
|
2017-03-29 14:13:40 -07:00
|
|
|
|
2017-04-24 14:34:31 -07:00
|
|
|
this.locationService.currentPath.subscribe(path => {
|
|
|
|
if (this.currentPath && path === this.currentPath) {
|
|
|
|
// scroll only if on same page (most likely a change to the hash)
|
|
|
|
this.autoScroll();
|
|
|
|
} else {
|
|
|
|
// don't scroll; leave that to `onDocRendered`
|
|
|
|
this.currentPath = path;
|
|
|
|
}
|
|
|
|
});
|
2017-03-29 14:13:40 -07:00
|
|
|
|
|
|
|
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-25 14:48:01 -07:00
|
|
|
this.docVersions = views['docVersions'] || [];
|
2017-04-01 10:01:54 +01:00
|
|
|
this.footerNodes = views['Footer'] || [];
|
|
|
|
this.sideNavNodes = views['SideNav'] || [];
|
|
|
|
this.topMenuNodes = views['TopBar'] || [];
|
2017-04-25 14:48:01 -07:00
|
|
|
|
|
|
|
this.currentDocVersion = this.docVersions[0];
|
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-04-24 14:34:31 -07:00
|
|
|
// Scroll to the anchor in the hash fragment or top of doc.
|
2017-03-29 14:13:40 -07:00
|
|
|
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-04-24 17:15:11 -07:00
|
|
|
// Scroll after the doc-viewer has finished rendering the new doc
|
2017-03-29 14:13:40 -07:00
|
|
|
this.autoScroll();
|
2017-04-24 17:15:11 -07:00
|
|
|
this.isStarting = false;
|
2017-03-01 14:30:25 +00:00
|
|
|
}
|
2017-02-15 11:22:37 -08:00
|
|
|
|
2017-04-25 14:48:01 -07:00
|
|
|
onDocVersionChange(versionIndex: number) {
|
|
|
|
const version = this.docVersions[versionIndex];
|
|
|
|
if (version.url) {
|
|
|
|
this.locationService.go(version.url);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2017-04-20 14:16:36 +01:00
|
|
|
setPageId(id: string) {
|
|
|
|
// Special case the home page
|
|
|
|
this.pageId = (id === 'index') ? 'home' : id.replace('/', '-');
|
|
|
|
}
|
2017-01-27 00:20:51 -08:00
|
|
|
}
|