| 
									
										
										
										
											2017-04-28 15:34:20 -07:00
										 |  |  | import { Component, ElementRef, HostBinding, HostListener, OnInit, | 
					
						
							| 
									
										
										
										
											2017-03-29 14:13:40 -07:00
										 |  |  |          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-05-02 10:13:10 -07:00
										 |  |  |   currentDocument: DocumentContents; | 
					
						
							|  |  |  |   currentDocVersion: NavigationNode; | 
					
						
							| 
									
										
										
										
											2017-03-29 14:13:40 -07:00
										 |  |  |   currentNode: CurrentNode; | 
					
						
							| 
									
										
										
										
											2017-04-24 14:34:31 -07:00
										 |  |  |   currentPath: string; | 
					
						
							| 
									
										
										
										
											2017-05-02 10:13:10 -07:00
										 |  |  |   docVersions: NavigationNode[]; | 
					
						
							| 
									
										
										
										
											2017-04-01 21:45:32 -07:00
										 |  |  |   dtOn = false; | 
					
						
							| 
									
										
										
										
											2017-05-02 10:13:10 -07:00
										 |  |  |   footerNodes: NavigationNode[]; | 
					
						
							| 
									
										
										
										
											2017-05-05 10:02:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * An HTML friendly identifier for the currently displayed page. | 
					
						
							|  |  |  |    * This is computed from the `currentDocument.id` by replacing `/` with `-` | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2017-04-01 09:58:19 +01:00
										 |  |  |   pageId: string; | 
					
						
							| 
									
										
										
										
											2017-05-05 10:02:33 +01:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * An HTML friendly identifer for the "folder" of the currently displayed page. | 
					
						
							|  |  |  |    * This is computed by taking everything up to the first `/` in the `currentDocument.id` | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   folderId: string; | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * These CSS classes are computed from the current state of the application | 
					
						
							|  |  |  |    * (e.g. what document is being viewed) to allow for fine grain control over | 
					
						
							|  |  |  |    * the styling of individual pages. | 
					
						
							|  |  |  |    * You will get three classes: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * * `page-...`: computed from the current document id (e.g. news, guide-security, tutorial-toh-pt2) | 
					
						
							|  |  |  |    * * `folder-...`: computed from the top level folder for an id (e.g. guide, tutorial, etc) | 
					
						
							|  |  |  |    * * `view-...`: computef from the navigation view (e.g. SideNav, TopBar, etc) | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   @HostBinding('class') | 
					
						
							|  |  |  |   hostClasses = ''; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-05-02 10:13:10 -07:00
										 |  |  |   tocMaxHeight: string; | 
					
						
							|  |  |  |   private tocMaxHeightOffset = 0; | 
					
						
							| 
									
										
										
										
											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, | 
					
						
							| 
									
										
										
										
											2017-05-02 10:13:10 -07:00
										 |  |  |     private hostElement: ElementRef, | 
					
						
							| 
									
										
										
										
											2017-03-29 14:13:40 -07:00
										 |  |  |     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-05-02 10:13:10 -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-05-05 10:02:33 +01:00
										 |  |  |       this.setFolderId(doc.id); | 
					
						
							|  |  |  |       this.updateHostClasses(); | 
					
						
							| 
									
										
										
										
											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-05-05 10:02:33 +01:00
										 |  |  |       this.updateHostClasses(); | 
					
						
							| 
									
										
										
										
											2017-03-29 14:13:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-05-05 10:02:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   setFolderId(id: string) { | 
					
						
							|  |  |  |     // Special case the home page
 | 
					
						
							|  |  |  |     this.folderId = (id === 'index') ? 'home' : id.split('/', 1)[0]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   updateHostClasses() { | 
					
						
							|  |  |  |     const pageClass = `page-${this.pageId}`; | 
					
						
							|  |  |  |     const folderClass = `folder-${this.folderId}`; | 
					
						
							|  |  |  |     const viewClass = `view-${this.currentNode && this.currentNode.view}`; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.hostClasses = `${pageClass} ${folderClass} ${viewClass}`; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-05-02 10:13:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Dynamically change height of table of contents container
 | 
					
						
							|  |  |  |   @HostListener('window:scroll') | 
					
						
							|  |  |  |   onScroll() { | 
					
						
							|  |  |  |     if (!this.tocMaxHeightOffset) { | 
					
						
							|  |  |  |       // Must wait until now for md-toolbar to be measurable.
 | 
					
						
							|  |  |  |       const el = this.hostElement.nativeElement as Element; | 
					
						
							|  |  |  |       this.tocMaxHeightOffset = | 
					
						
							|  |  |  |           el.querySelector('footer').clientHeight + | 
					
						
							|  |  |  |           el.querySelector('md-toolbar.app-toolbar').clientHeight + | 
					
						
							|  |  |  |           44; //  margin
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.tocMaxHeight = (document.body.scrollHeight - window.pageYOffset - this.tocMaxHeightOffset).toFixed(2); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-01-27 00:20:51 -08:00
										 |  |  | } |