diff --git a/aio/src/app/doc-viewer/doc-viewer.component.spec.ts b/aio/src/app/doc-viewer/doc-viewer.component.spec.ts
deleted file mode 100644
index 4b40ac6741..0000000000
--- a/aio/src/app/doc-viewer/doc-viewer.component.spec.ts
+++ /dev/null
@@ -1,306 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { By } from '@angular/platform-browser';
-import { Component, DebugElement } from '@angular/core';
-
-import { ComponentFactoryResolver, ElementRef, Injector, NgModule, OnInit, ViewChild } from '@angular/core';
-
-import { Doc, DocMetadata } from '../nav-engine';
-import { DocViewerComponent } from '../doc-viewer/doc-viewer.component';
-
-import { embeddedComponents, EmbeddedComponents } from '../embedded';
-
-
-/// Embedded Test Components ///
-
-///// FooComponent /////
-
-@Component({
- selector: 'aio-foo',
- template: `Foo Component`
-})
-class FooComponent { }
-
-///// BarComponent /////
-
-@Component({
- selector: 'aio-bar',
- template: `
-
- Bar Component
-
-
- `
-})
-class BarComponent implements OnInit {
-
- @ViewChild('barContent') barContentRef: ElementRef;
-
- constructor(public elementRef: ElementRef) { }
-
- // Project content in ngOnInit just like CodeExampleComponent
- ngOnInit() {
- // Security: this is a test component; never deployed
- this.barContentRef.nativeElement.innerHTML = this.elementRef.nativeElement.aioBarContent;
- }
-}
-
-///// BazComponent /////
-
-@Component({
- selector: 'aio-baz',
- template: `
- ++++++++++++++
- Baz Component
-
- ++++++++++++++
- `
-})
-class BazComponent implements OnInit {
-
- @ViewChild('bazContent') bazContentRef: ElementRef;
-
- constructor(public elementRef: ElementRef) { }
-
- // Project content in ngOnInit just like CodeExampleComponent
- ngOnInit() {
- // Security: this is a test component; never deployed
- this.bazContentRef.nativeElement.innerHTML = this.elementRef.nativeElement.aioBazContent;
- }
-}
-///// Test Module //////
-
-const embeddedTestComponents = [FooComponent, BarComponent, BazComponent, ...embeddedComponents];
-
-@NgModule({
- entryComponents: embeddedTestComponents
-})
-class TestModule { }
-
-//// Test Component //////
-
-@Component({
- selector: 'aio-test',
- template: `
- Test Component
- `
-})
-class TestComponent {
- private currentDoc: Doc;
-
- @ViewChild(DocViewerComponent) docViewer: DocViewerComponent;
-
- setDoc(doc: Doc) {
- if (this.docViewer) {
- this.docViewer.doc = doc;
- }
- }
-}
-
-//////// Tests //////////////
-
-describe('DocViewerComponent', () => {
- const fakeDocMetadata: DocMetadata = { docId: 'fake', title: 'fake Doc' };
- let component: TestComponent;
- let docViewerDE: DebugElement;
- let docViewerEl: HTMLElement;
- let fixture: ComponentFixture;
-
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports: [ TestModule ],
- declarations: [
- TestComponent,
- DocViewerComponent,
- embeddedTestComponents
- ],
- providers: [
- {provide: EmbeddedComponents, useValue: {components: embeddedTestComponents}}
- ]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(TestComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- docViewerDE = fixture.debugElement.children[0];
- docViewerEl = docViewerDE.nativeElement;
- });
-
- it('should create a DocViewer', () => {
- expect(component.docViewer).toBeTruthy();
- });
-
- it(('should display nothing when set DocViewer.doc to doc w/o content'), () => {
- component.docViewer.doc = { metadata: fakeDocMetadata, content: '' };
- expect(docViewerEl.innerHTML).toBe('');
- });
-
- it(('should display simple static content doc'), () => {
- const content = 'Howdy, doc viewer
';
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
- expect(docViewerEl.innerHTML).toEqual(content);
- });
-
- it(('should display nothing after reset static content doc'), () => {
- const content = 'Howdy, doc viewer
';
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
- fixture.detectChanges();
- component.docViewer.doc = { metadata: fakeDocMetadata, content: '' };
- expect(docViewerEl.innerHTML).toEqual('');
- });
-
- it(('should apply FooComponent'), () => {
- const content = `
- Above Foo
-
- Below Foo
- `;
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
- const fooHtml = docViewerEl.querySelector('aio-foo').innerHTML;
- expect(fooHtml).toContain('Foo Component');
- });
-
- it(('should apply multiple FooComponents'), () => {
- const content = `
- Above Foo
-
-
- Holds a
-
Ignored text
-
- Below Foo
- `;
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
- const foos = docViewerEl.querySelectorAll('aio-foo');
- expect(foos.length).toBe(2);
- });
-
- it(('should apply BarComponent'), () => {
- const content = `
- Above Bar
-
- Below Bar
- `;
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
- const barHtml = docViewerEl.querySelector('aio-bar').innerHTML;
- expect(barHtml).toContain('Bar Component');
- });
-
- it(('should project bar content into BarComponent'), () => {
- const content = `
- Above Bar
- ###bar content###
- Below Bar
- `;
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
-
- // necessary to trigger projection within ngOnInit
- fixture.detectChanges();
-
- const barHtml = docViewerEl.querySelector('aio-bar').innerHTML;
- expect(barHtml).toContain('###bar content###');
- });
-
-
- it(('should include Foo and Bar'), () => {
- const content = `
- Top
- ignored
- ###bar content###
-
- Bottom
- `;
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
-
- // necessary to trigger Bar's projection within ngOnInit
- fixture.detectChanges();
-
- const foos = docViewerEl.querySelectorAll('aio-foo');
- expect(foos.length).toBe(2, 'should have 2 foos');
-
- const barHtml = docViewerEl.querySelector('aio-bar').innerHTML;
- expect(barHtml).toContain('###bar content###', 'should have bar with projected content');
- });
-
- it(('should not include Bar within Foo'), () => {
- const content = `
- Top
-
-
- ###bar content###
-
-
-
-
Bottom
- `;
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
-
- // necessary to trigger Bar's projection within ngOnInit
- fixture.detectChanges();
-
- const foos = docViewerEl.querySelectorAll('aio-foo');
- expect(foos.length).toBe(2, 'should have 2 foos');
-
- const bars = docViewerEl.querySelectorAll('aio-bar');
- expect(bars.length).toBe(0, 'did not expect Bar inside Foo');
- });
-
- // because FooComponents are processed before BazComponents
- it(('should include Foo within Bar'), () => {
- const content = `
- Top
-
-
-
-
- Bottom
- `;
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
-
- // necessary to trigger Bar's projection within ngOnInit
- fixture.detectChanges();
-
- const foos = docViewerEl.querySelectorAll('aio-foo');
- expect(foos.length).toBe(2, 'should have 2 foos');
-
- const bars = docViewerEl.querySelectorAll('aio-bar');
- expect(bars.length).toBe(1, 'should have a bar');
- expect(bars[0].innerHTML).toContain('Bar Component', 'should have bar template content');
- });
-
- // The tag and its inner content is copied
- // But the BazComponent is not created and therefore its template content is not displayed
- // because BarComponents are processed before BazComponents
- // and no chance for first Baz inside Bar to be processed by builder.
- it(('should NOT include Bar within Baz'), () => {
- const content = `
- Top
-
-
- Inner
---baz stuff---
-
-
- ---More baz--
- Bottom
- `;
- component.docViewer.doc = { metadata: fakeDocMetadata, content };
-
- // necessary to trigger Bar's projection within ngOnInit
- fixture.detectChanges();
- const bazs = docViewerEl.querySelectorAll('aio-baz');
-
- // Both baz tags are there ...
- expect(bazs.length).toBe(2, 'should have 2 bazs');
-
- expect(bazs[0].innerHTML).not.toContain('Baz Component',
- 'did not expect 1st Baz template content');
-
- expect(bazs[1].innerHTML).toContain('Baz Component',
- 'expected 2nd Baz template content');
-
- });
-});
diff --git a/aio/src/app/doc-viewer/doc-viewer.component.ts b/aio/src/app/doc-viewer/doc-viewer.component.ts
deleted file mode 100644
index 182e15549d..0000000000
--- a/aio/src/app/doc-viewer/doc-viewer.component.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-import {
- Component, ComponentFactory, ComponentFactoryResolver, ComponentRef,
- DoCheck, ElementRef, Injector, Input, OnDestroy, ViewEncapsulation
-} from '@angular/core';
-
-import { Doc, DocMetadata, DocMetadataService, NavNode } from '../nav-engine';
-import { EmbeddedComponents } from '../embedded';
-
-interface EmbeddedComponentFactory {
- contentPropertyName: string;
- factory: ComponentFactory;
-}
-
-// Initialization prevents flicker once pre-rendering is on
-const initialDocViewerElement = document.querySelector('aio-doc-viewer');
-const initialDocViewerContent = initialDocViewerElement ? initialDocViewerElement.innerHTML : '';
-
-@Component({
- selector: 'aio-doc-viewer',
- template: '',
- providers: [ DocMetadataService ],
- styles: [ `
- :host >>> doc-title.not-found h1 {
- color: white;
- background-color: red;
- }
- `]
- // TODO(robwormald): shadow DOM and emulated don't work here (?!)
- // encapsulation: ViewEncapsulation.Native
-})
-export class DocViewerComponent implements DoCheck, OnDestroy {
-
- private displayedDoc: DisplayedDoc;
- private embeddedComponentFactories: Map = new Map();
- private hostElement: HTMLElement;
-
- constructor(
- componentFactoryResolver: ComponentFactoryResolver,
- elementRef: ElementRef,
- embeddedComponents: EmbeddedComponents,
- private docMetadataService: DocMetadataService,
- private injector: Injector
- ) {
- this.hostElement = elementRef.nativeElement;
- // Security: the initialDocViewerContent comes from the prerendered DOM and is considered to be secure
- this.hostElement.innerHTML = initialDocViewerContent;
-
- for (const component of embeddedComponents.components) {
- const factory = componentFactoryResolver.resolveComponentFactory(component);
- const selector = factory.selector;
- const contentPropertyName = this.selectorToContentPropertyName(selector);
- this.embeddedComponentFactories.set(selector, { contentPropertyName, factory });
- }
- }
-
- @Input()
- set doc(newDoc: Doc) {
- this.ngOnDestroy();
- if (newDoc) {
- this.docMetadataService.metadata = newDoc.metadata;
- window.scrollTo(0, 0);
- this.build(newDoc);
- }
- }
-
- /**
- * Add doc content to host element and build it out with embedded components
- */
- private build(doc: Doc) {
-
- const displayedDoc = this.displayedDoc = new DisplayedDoc(doc);
-
- // security: the doc.content is always authored by the documentation team
- // and is considered to be safe
- this.hostElement.innerHTML = doc.content || '';
-
- if (!doc.content) { return; }
-
- // TODO(i): why can't I use for-of? why doesn't typescript like Map#value() iterators?
- this.embeddedComponentFactories.forEach(({ contentPropertyName, factory }, selector) => {
- const embeddedComponentElements = this.hostElement.querySelectorAll(selector);
-
- // cast due to https://github.com/Microsoft/TypeScript/issues/4947
- for (const element of embeddedComponentElements as any as HTMLElement[]){
- // hack: preserve the current element content because the factory will empty it out
- // security: the source of this innerHTML is always authored by the documentation team
- // and is considered to be safe
- element[contentPropertyName] = element.innerHTML;
- displayedDoc.addEmbeddedComponent(factory.create(this.injector, [], element));
- }
- });
- }
-
- ngDoCheck() {
- if (this.displayedDoc) { this.displayedDoc.detectChanges(); }
- }
-
- ngOnDestroy() {
- // destroy components otherwise there will be memory leaks
- if (this.displayedDoc) {
- this.displayedDoc.destroy();
- this.displayedDoc = undefined;
- }
- }
-
- /**
- * Compute the component content property name by converting the selector to camelCase and appending
- * 'Content', e.g. live-example => liveExampleContent
- */
- private selectorToContentPropertyName(selector: string) {
- return selector.replace(/-(.)/g, (match, $1) => $1.toUpperCase()) + 'Content';
- }
-}
-
-class DisplayedDoc {
-
- metadata: DocMetadata;
-
- private embeddedComponents: ComponentRef[] = [];
-
- constructor(doc: Doc) {
- // ignore doc.content ... don't need to keep it around
- this.metadata = doc.metadata;
- }
-
- addEmbeddedComponent(component: ComponentRef) {
- this.embeddedComponents.push(component);
- }
-
- detectChanges() {
- this.embeddedComponents.forEach(comp => comp.changeDetectorRef.detectChanges());
- }
-
- destroy() {
- // destroy components otherwise there will be memory leaks
- this.embeddedComponents.forEach(comp => comp.destroy());
- this.embeddedComponents.length = 0;
- }
-}
diff --git a/aio/src/app/nav-engine/doc-fetching.service.spec.ts b/aio/src/app/nav-engine/doc-fetching.service.spec.ts
deleted file mode 100644
index 9b69019df8..0000000000
--- a/aio/src/app/nav-engine/doc-fetching.service.spec.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import { DocFetchingService } from './doc-fetching.service';
-// Write tests when/if this service is retained.
diff --git a/aio/src/app/nav-engine/doc-fetching.service.ts b/aio/src/app/nav-engine/doc-fetching.service.ts
deleted file mode 100644
index 887b3b1ee6..0000000000
--- a/aio/src/app/nav-engine/doc-fetching.service.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import { Http, Response } from '@angular/http';
-import { Injectable } from '@angular/core';
-
-import { Observable } from 'rxjs/Observable';
-import { of } from 'rxjs/observable/of';
-import 'rxjs/add/operator/catch';
-import 'rxjs/add/operator/do';
-import 'rxjs/add/operator/map';
-
-import { Doc, DocMetadata } from './doc.model';
-import { Logger } from '../logger.service';
-
-@Injectable()
-export class DocFetchingService {
-
- private base = 'content/';
-
- constructor(
- private http: Http,
- private logger: Logger) { }
-
- getPath(docId: string) {
- return this.base + addPathExtension(docId);
- }
-
- /**
- * Fetch document from server.
- * NB: pass 404 response to caller as Doc with empty string content
- * Other errors and non-OK status responses are thrown errors.
- * TODO: add timeout and retry for lost connection
- */
- getDocFile(docId: string): Observable {
-
- if (!docId) {
- const emsg = 'getFile: no document id';
- this.logger.error(emsg);
- throw new Error(emsg);
- }
-
- // TODO: Metadata will be updated from file
- const metadata: DocMetadata = { docId, title: docId };
- const url = this.getPath(docId);
-
- this.logger.log(`Fetching document file at '${url}'`);
-
- return this.http.get(url)
- .map(res => { metadata, content: res.text() }) // TODO: It will come as JSON soon
- .do(content => this.logger.log(`Fetched document file at '${url}'`) )
- .catch((error: Response) => {
- if (error.status === 404) {
- this.logger.error(`Document file not found at '${url}'`);
- return of({metadata, content: ''} as Doc);
- } else {
- throw error;
- }
- });
- }
-}
-
-function addPathExtension(path: string) {
- if (path) {
- if (path.endsWith('/')) {
- return path + 'index.html';
- } else if (!path.endsWith('.html')) {
- return path + '.html';
- }
- }
- return path;
-}
-
-// function removePathExtension(path: string) {
-// if (path) {
-// if (path.endsWith('/index.html')) {
-// return path.substring(0, path.length - 10);
-// } else if (path.endsWith('.html')) {
-// return path.substring(0, path.length - 5);
-// }
-// }
-// return path;
-// }
diff --git a/aio/src/app/nav-engine/doc-metadata.service.ts b/aio/src/app/nav-engine/doc-metadata.service.ts
deleted file mode 100644
index cdeda1398c..0000000000
--- a/aio/src/app/nav-engine/doc-metadata.service.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Injectable } from '@angular/core';
-import { DocMetadata } from './doc.model';
-
-@Injectable()
-export class DocMetadataService {
- metadata: DocMetadata;
-}
diff --git a/aio/src/app/nav-engine/doc.model.ts b/aio/src/app/nav-engine/doc.model.ts
deleted file mode 100644
index 48d9b11287..0000000000
--- a/aio/src/app/nav-engine/doc.model.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-export interface DocMetadata {
- docId: string;
- title: string;
-}
-
-export interface Doc {
- metadata: DocMetadata;
- content: string;
-}
-
-/**
- * UI navigation node that describes a document or container of documents
- * Each node corresponds to a link in the UI.
- */
-export interface NavNode {
- /** unique integer id for this node */
- id: number;
- /** Document id if this is a document node */
- docId: string;
- /** Document path (calculated from docId) if this is a document node */
- docPath: string;
- /** url to an external web page; docPath and url are mutually exclusive. */
- url?: string;
- /** Title to display in the navigation link; typically shorter */
- navTitle: string;
- /** Tooltip for links */
- tooltip: string;
- /** Ids of ancestor nodes higher in the hierarchy */
- ancestorIds: number[];
- /** true if should not be displayed in UI. Can still be loaded directly */
- // hide?: boolean; NO NO. If the JSON says, hide, simply omit it from this map
- /** If defined, this node is a container of child nodes */
- children?: NavNode[];
-}
-
-
-/**
- * Navigation for the site.
- * - nodes: the top-level navigation nodes; node can have children.
- * - docs: find node for a given document id.
- */
-export interface NavMap {
- /**
- * Map that drives the UI navigation.
- * Each node correspond to a navigation link in the UI.
- * Supports unlimited node nesting.
- */
- nodes: NavNode[];
-
- /**
- * NavNode for a document id in the NavMap.
- */
- docs: Map;
-}
diff --git a/aio/src/app/nav-engine/doc.service.spec.ts b/aio/src/app/nav-engine/doc.service.spec.ts
deleted file mode 100644
index cd5d8df0b5..0000000000
--- a/aio/src/app/nav-engine/doc.service.spec.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-import { fakeAsync, tick } from '@angular/core/testing';
-
-import { DocService } from './doc.service';
-import { Doc, DocMetadata, NavNode } from './doc.model';
-import { DocFetchingService } from './doc-fetching.service';
-
-import { Observable } from 'rxjs/Observable';
-import { of } from 'rxjs/observable/of';
-import 'rxjs/add/observable/throw';
-import 'rxjs/add/operator/catch';
-import 'rxjs/add/operator/delay';
-import 'rxjs/add/operator/first';
-
-describe('DocService', () => {
- let docFetchingService: DocFetchingService;
- let getFileSpy: jasmine.Spy;
- let loggerSpy: any;
- let docService: DocService;
- let testDoc: Doc;
- let testDocId: string;
- let testContent: string;
-
- beforeEach(() => {
- testDocId = 'fake';
- testContent = 'fake file contents';
- testDoc = {
- metadata: {docId: testDocId, title: 'Fake Title'} as DocMetadata,
- content: testContent
- };
-
- loggerSpy = jasmine.createSpyObj('logger', ['log', 'warn', 'error']);
- docFetchingService = new DocFetchingService(null, loggerSpy);
- getFileSpy = spyOn(docFetchingService, 'getDocFile').and
- .returnValue(of(testDoc).delay(0).first()); // first() -> completes
-
- docService = new DocService(docFetchingService, loggerSpy);
- });
-
- it('should return fake doc for fake id', fakeAsync(() => {
- docService.getDoc(testDocId).subscribe(doc =>
- expect(doc.content).toBe(testContent)
- );
- tick();
- }));
-
- it('should retrieve file once for first file request', fakeAsync(() => {
- let doc: Doc;
- expect(getFileSpy.calls.count()).toBe(0, 'no call before tick');
- docService.getDoc(testDocId).subscribe(d => doc = d);
- tick();
- expect(getFileSpy.calls.count()).toBe(1, 'one call after tick');
- expect(doc).toBe(testDoc, 'expected doc');
- }));
-
- it('should retrieve file from cache the second time', fakeAsync(() => {
- docService.getDoc(testDocId).subscribe(doc =>
- expect(doc).toBe(testDoc, 'expected doc from server')
- );
- tick();
- expect(getFileSpy.calls.count()).toBe(1, 'one call after 1st request');
-
- docService.getDoc(testDocId).subscribe(doc =>
- expect(doc).toBe(testDoc, 'expected doc from cache')
- );
- tick();
- expect(getFileSpy.calls.count()).toBe(1, 'still only one call after 2nd request');
- }));
-
- it('should pass along file error through its getDoc observable result', fakeAsync(() => {
-
- const err = 'deliberate file error';
- getFileSpy.and.returnValue(
- // simulate async error in the file retrieval
- of('').delay(0).map(() => { throw new Error(err); })
- );
-
- docService.getDoc(testDocId).subscribe(
- doc => expect(false).toBe(true, 'should have failed'),
- error => expect(error.message).toBe(err)
- );
- tick();
- }));
-});
diff --git a/aio/src/app/nav-engine/doc.service.ts b/aio/src/app/nav-engine/doc.service.ts
deleted file mode 100644
index d5403f799a..0000000000
--- a/aio/src/app/nav-engine/doc.service.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { Injectable } from '@angular/core';
-
-import { Observable } from 'rxjs/Observable';
-import { of } from 'rxjs/observable/of';
-import 'rxjs/add/operator/do';
-import 'rxjs/add/operator/map';
-import 'rxjs/add/operator/switchMap';
-
-import { Doc, NavNode } from './doc.model';
-import { DocFetchingService } from './doc-fetching.service';
-import { Logger } from '../logger.service';
-
-import { NavMapService } from './nav-map.service';
-
-@Injectable()
-export class DocService {
- private cache = new Map();
- private notFoundContent: string;
-
- constructor(
- private fileService: DocFetchingService,
- private logger: Logger
- ) { }
-
- /**
- * Get document for id, from cache if found else server.
- * Pass server errors along to caller
- * Constructs and caches a "Not Found" doc when fileservice returns a doc with no content.
- */
- getDoc(docId: string): Observable {
- const cached = this.cache.get(docId);
- if (cached) {
- this.logger.log(`Returned cached document for '${docId}'`);
- return of(cached);
- }
-
- return this.fileService.getDocFile(docId)
- .switchMap(doc => {
- this.logger.log(`Fetched document for '${docId}'`);
- return doc.content ? of(doc) :
- this.getNotFound()
- .map(nfContent => {metadata: {docId, title: docId}, content: nfContent});
- })
- .do(doc => this.cache.set(docId, doc));
- }
-
- getNotFound(): Observable {
- if (this.notFoundContent) { return of(this.notFoundContent); }
- const nfDocId = 'not-found';
- return this.fileService.getDocFile(nfDocId)
- .map(doc => {
- this.logger.log(`Fetched "not found" document for '${nfDocId}'`);
- this.notFoundContent = doc.content;
- return doc.content;
- });
- }
-}
diff --git a/aio/src/app/nav-engine/index.ts b/aio/src/app/nav-engine/index.ts
deleted file mode 100644
index 32a4982a51..0000000000
--- a/aio/src/app/nav-engine/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { DocService } from './doc.service';
-import { DocFetchingService } from './doc-fetching.service';
-import { NavEngine } from './nav-engine.service';
-import { NavLinkDirective } from './nav-link.directive';
-import { NavMapService } from './nav-map.service';
-
-export { Doc, DocMetadata, NavNode, NavMap } from './doc.model';
-export { DocMetadataService } from './doc-metadata.service';
-export { NavEngine } from './nav-engine.service';
-export { NavMapService } from './nav-map.service';
-
-export const navDirectives = [
- NavLinkDirective
-];
-
-export const navProviders = [
- DocService,
- DocFetchingService,
- NavEngine,
- NavMapService,
-];
diff --git a/aio/src/app/nav-engine/nav-engine.service.spec.ts b/aio/src/app/nav-engine/nav-engine.service.spec.ts
deleted file mode 100644
index 9e64ac767a..0000000000
--- a/aio/src/app/nav-engine/nav-engine.service.spec.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { fakeAsync, tick} from '@angular/core/testing';
-
-import { Observable } from 'rxjs/Observable';
-import { of } from 'rxjs/observable/of';
-import 'rxjs/add/operator/delay';
-
-import { DocService } from './doc.service';
-import { Doc, DocMetadata, NavNode } from './doc.model';
-
-import { NavEngine } from './nav-engine.service';
-
-describe('NavEngine', () => {
-
- let fakeDoc: Doc;
- let navEngine: NavEngine;
-
- beforeEach(() => {
- fakeDoc = {
- metadata: {
- docId: 'fake',
- title: 'All about the fake'
- },
- content: 'fake content'
- };
-
- const docService: any = jasmine.createSpyObj('docService', ['getDoc']);
- docService.getDoc.and.returnValue(of(fakeDoc).delay(0));
-
- navEngine = new NavEngine(docService);
- });
-
- it('should set currentDoc to fake doc when navigate to fake id', fakeAsync(() => {
- navEngine.navigate('fake');
- navEngine.currentDoc.subscribe(doc =>
- expect(doc.content).toBe(fakeDoc.content)
- );
- tick();
- }));
-});
diff --git a/aio/src/app/nav-engine/nav-engine.service.ts b/aio/src/app/nav-engine/nav-engine.service.ts
deleted file mode 100644
index 2e2b8bdbde..0000000000
--- a/aio/src/app/nav-engine/nav-engine.service.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Injectable, OnDestroy } from '@angular/core';
-
-import { ReplaySubject } from 'rxjs/ReplaySubject';
-import { Subscription } from 'rxjs/Subscription';
-
-import { Doc } from './doc.model';
-import { DocService } from './doc.service';
-
-@Injectable()
-export class NavEngine implements OnDestroy {
-
- private docSubject = new ReplaySubject(1);
- private subscription: Subscription;
-
- /** Observable of the most recent document from a `navigate` call */
- currentDoc = this.docSubject.asObservable();
-
- constructor(private docService: DocService) {}
-
- /**
- * Navigate pushes new doc for the given `id` into the `currentDoc` observable.
- * TODO: handle document retrieval error
- */
- navigate(docId: string) {
- this.ngOnDestroy();
- this.subscription = this.docService.getDoc(docId).subscribe(doc => this.docSubject.next(doc));
- }
-
- ngOnDestroy() {
- if (this.subscription) { this.subscription.unsubscribe(); }
- }
-}
-
-
diff --git a/aio/src/app/nav-engine/nav-link.directive.ts b/aio/src/app/nav-engine/nav-link.directive.ts
deleted file mode 100644
index 7d5af41361..0000000000
--- a/aio/src/app/nav-engine/nav-link.directive.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Directive, HostListener, Input } from '@angular/core';
-import { NavEngine } from './nav-engine.service';
-
-@Directive({
- selector: '[aioNavLink]'
-})
-export class NavLinkDirective {
-
- @Input()
- aioNavLink: string;
-
- constructor(private navEngine: NavEngine) { }
-
- @HostListener('click', ['$event'])
- onClick($event) {
- this.navEngine.navigate(this.aioNavLink);
- return false;
- }
-}
diff --git a/aio/src/app/nav-engine/nav-map.service.spec.ts b/aio/src/app/nav-engine/nav-map.service.spec.ts
deleted file mode 100644
index 5943dbba22..0000000000
--- a/aio/src/app/nav-engine/nav-map.service.spec.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import { fakeAsync, tick } from '@angular/core/testing';
-import { Http, Response } from '@angular/http';
-
-import { of } from 'rxjs/observable/of';
-import 'rxjs/add/operator/catch';
-import 'rxjs/add/operator/delay';
-
-import { DocFetchingService } from './doc-fetching.service';
-import { NavNode, NavMap } from './doc.model';
-import { NavMapService } from './nav-map.service';
-
-import { getTestNavMapResponse } from '../../testing/nav-map-json-response';
-
-describe('NavMapService', () => {
- let httpSpy: any;
- let loggerSpy: any;
- let navMapService: NavMapService;
- let navMap: NavMap;
-
- beforeEach(done => {
- httpSpy = jasmine.createSpyObj('http', ['get']);
- httpSpy.get.and.returnValue(of(getTestNavMapResponse()).delay(0).first()); // first() -> completes
- loggerSpy = jasmine.createSpyObj('logger', ['log', 'warn', 'error']);
-
- navMapService = new NavMapService(new DocFetchingService(null, null), httpSpy, loggerSpy);
-
- navMapService.navMap.first().subscribe(
- nm => navMap = nm,
- null,
- done);
- });
-
- it('should return a navMap', () => {
- expect(navMap).toBeDefined();
- });
-
- it('should have filtered away the "cli-quickstart" because `hide`===true', () => {
- const item = navMap.nodes.find(n => n.docId === 'guide/cli-quickstart');
- expect(item).toBeUndefined();
- });
-
- describe('Quickstart', () => {
- let item: NavNode;
-
- beforeEach(() => {
- item = navMap.nodes.find(n => n.navTitle === 'Quickstart');
- });
-
- it('should have expected item', () => {
- expect(item).toBeDefined();
- });
-
- it('should have expected docId', () => {
- expect(item.docId).toBe('guide/quickstart');
- });
-
- it('should have calculated expected docPath', () => {
- expect(item.docPath).toBe('content/guide/quickstart.html');
- });
-
- it('should have no ancestors because it is a top-level item', () => {
- expect(item.ancestorIds).toEqual([]);
- });
- });
-
- describe('Getting Started', () => {
- let section: NavNode;
-
- beforeEach(() => {
- section = navMap.nodes.find(n => n.navTitle === 'Getting started');
- });
-
- it('should have an id', () => {
- expect(section.id).toBeGreaterThan(0);
- });
-
- it('should have distinct tooltip', () => {
- expect(section.tooltip).not.toBe(section.navTitle);
- });
-
- it('should have 2 children', () => {
- expect(section.children.length).toBe(2);
- });
-
- it('should have itself as ancestor because it has children', () => {
- expect(section.ancestorIds).toEqual([section.id]);
- });
- });
-
- describe('Tutorial', () => {
- let section: NavNode;
- let intro: NavNode;
-
- beforeEach(() => {
- section = navMap.nodes.find(n => n.navTitle === 'Tutorial');
- if (section && section.children) {
- intro = section.children.find(n => n.navTitle === 'Introduction');
- }
- });
-
- it('should have 2 children', () => {
- expect(section.children.length).toBe(2);
- });
-
- it('intro child\'s docId ends in "/"', () => {
- expect(intro.docId[intro.docId.length - 1]).toEqual('/');
- });
-
- it('intro child\'s calculated docPath ends in "index.html"', () => {
- expect(intro.docPath).toMatch(/index.html$/);
- });
- });
-
- describe('Core (3-level)', () => {
- let section: NavNode;
-
- beforeEach(() => {
- section = navMap.nodes.find(n => n.navTitle === 'Core');
- });
-
- it('should have 2 children', () => {
- expect(section.children.length).toBe(2);
- });
-
- describe('->directives', () => {
- let directives: NavNode;
-
- beforeEach(() => {
- directives = section.children.find(n => n.navTitle === 'Directives');
- });
-
- it('should have a heading docId', () => {
- expect(directives.docId).toBeTruthy();
- });
-
- it('should have calculated expected docPath', () => {
- expect(directives.docPath).toBe('content/guide/directives.html');
- });
-
- it('should have 2 children', () => {
- expect(directives.children.length).toBe(2);
- });
-
- it('children should have two ancestor ids in lineal order', () => {
- const expectedAncestors = [section.id, directives.id];
- expect(directives.children[0].ancestorIds).toEqual(expectedAncestors, '#1');
- expect(directives.children[1].ancestorIds).toEqual(expectedAncestors, '#2');
- });
- });
- });
-
- describe('Empty Heading', () => {
- let section: NavNode;
-
- beforeEach(() => {
- section = navMap.nodes.find(n => n.navTitle === 'Empty Heading');
- });
-
- it('should have no children', () => {
- expect(section.children.length).toBe(0);
- });
-
- it('should have itself as ancestor because it has a `children` array', () => {
- expect(section.ancestorIds).toEqual([section.id]);
- });
- });
-
- describe('External', () => {
- let section: NavNode;
- let gitter: NavNode;
-
- beforeEach(() => {
- section = navMap.nodes.find(n => n.navTitle === 'External');
- if (section && section.children) {
- gitter = section.children[0];
- }
- });
-
- it('should have one child (gitter)', () => {
- expect(section.children.length).toBe(1);
- });
-
- it('child should have a url', () => {
- expect(gitter.url).toBeTruthy();
- });
-
- it('child should not have a docId', () => {
- expect(gitter.docId).toBeUndefined();
- });
-
- it('child should not have a docPath', () => {
- expect(gitter.docPath).toBeUndefined();
- });
-
- it('child should have parent as only ancestor id', () => {
- expect(gitter.ancestorIds).toEqual([section.id]);
- });
- });
-});
diff --git a/aio/src/app/nav-engine/nav-map.service.ts b/aio/src/app/nav-engine/nav-map.service.ts
deleted file mode 100644
index 7fd8ee6f63..0000000000
--- a/aio/src/app/nav-engine/nav-map.service.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { Injectable } from '@angular/core';
-import { Http } from '@angular/http';
-
-import { Observable } from 'rxjs/Observable';
-import { of } from 'rxjs/observable/of';
-import { ReplaySubject } from 'rxjs/ReplaySubject';
-import 'rxjs/add/operator/do';
-import 'rxjs/add/operator/map';
-
-import { Doc, NavNode, NavMap } from './doc.model';
-import { DocFetchingService } from './doc-fetching.service';
-import { Logger } from '../logger.service';
-
-const navMapUrl = 'content/navmap.json';
-
-@Injectable()
-export class NavMapService {
-
- private getDocPath: (string) => string;
- private navMapSubject: ReplaySubject;
- private nextNodeId = 1;
-
- constructor(
- docFetchingService: DocFetchingService,
- private http: Http,
- private logger: Logger) {
- this.getDocPath = docFetchingService.getPath.bind(docFetchingService);
- }
-
- get navMap(): Observable {
- return (this.navMapSubject ? this.navMapSubject : this.createNavMapSubject()).asObservable() ;
- }
-
- private createNavMapSubject(): ReplaySubject {
- this.navMapSubject = new ReplaySubject(1);
-
- this.http.get(navMapUrl)
- .map(res => res.json().nodes)
- .do(() => this.logger.log(`Fetched navigation map JSON at '${navMapUrl}'`))
- .subscribe(
- navNodes => this.navMapSubject.next(this.createNavMap(navNodes))
- );
-
- return this.navMapSubject;
- }
-
-
- ////// private helper functions ////
-
- private createNavMap(nodes: NavNode[]) {
- nodes = this.removeHidden(nodes);
- const navMap: NavMap = { nodes, docs: new Map()};
- nodes.forEach(node => this.adjustNode(node, navMap, []));
- return navMap;
- }
-
- // Adjust properties of a node from JSON and build navMap.docs
- private adjustNode(node: NavNode, navMap: NavMap, ancestorIds: number[] ) {
- node.id = this.nextNodeId++;
- node.ancestorIds = ancestorIds;
- if ( node.tooltip === undefined ) { node.tooltip = node.navTitle; }
-
- if (node.docId) {
- // This node is associated with a document
- node.docId = node.docId.toLocaleLowerCase();
- node.docPath = this.getDocPath(node.docId);
- navMap.docs.set(node.docId, node);
- }
-
-
- if (node.children) {
- // Ancestors include self when this node has children
- node.ancestorIds = ancestorIds.concat(node.id);
- node.children.forEach(n => this.adjustNode(n, navMap, node.ancestorIds));
- }
- }
-
- private removeHidden(nodes: NavNode[]) {
- return nodes.filter(node => {
- if (node['hide'] === true ) { return false; }
- if (node.children) {
- node.children = this.removeHidden(node.children);
- }
- return true;
- });
- }
-}
-
diff --git a/aio/src/app/sidenav/menu.component.scss b/aio/src/app/sidenav/menu.component.scss
deleted file mode 100644
index 8ac7a69556..0000000000
--- a/aio/src/app/sidenav/menu.component.scss
+++ /dev/null
@@ -1,23 +0,0 @@
-.fill-remaining-space {
- flex: 1 1 auto;
-}
-
-.nav-link {
- margin-right: 10px;
- margin-left: 20px;
- cursor: pointer;
-}
-
-@media (max-width: 700px) {
- .nav-link {
- margin-right: 8px;
- margin-left: 0px;
- }
-}
-@media (max-width: 600px) {
- .nav-link {
- font-size: 80%;
- margin-right: 8px;
- margin-left: 0px;
- }
-}
diff --git a/aio/src/app/sidenav/menu.component.ts b/aio/src/app/sidenav/menu.component.ts
deleted file mode 100644
index 1e66304357..0000000000
--- a/aio/src/app/sidenav/menu.component.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Component } from '@angular/core';
-
-@Component({
- selector: 'aio-menu',
- template: `
- Home
-
- API
- News
- Features
- `,
- styleUrls: ['./menu.component.scss'],
- animations: []
-})
-export class MenuComponent {
-}
diff --git a/aio/src/app/sidenav/nav-item.component.html b/aio/src/app/sidenav/nav-item.component.html
deleted file mode 100644
index 882228d190..0000000000
--- a/aio/src/app/sidenav/nav-item.component.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
diff --git a/aio/src/app/sidenav/nav-item.component.scss b/aio/src/app/sidenav/nav-item.component.scss
deleted file mode 100644
index 19ba2a0b86..0000000000
--- a/aio/src/app/sidenav/nav-item.component.scss
+++ /dev/null
@@ -1,114 +0,0 @@
-
-/************************************
-
- Media queries
-
-To use these, put this snippet in the approriate selector:
-
- @include bp(tiny) {
- background-color: purple;
- }
-
- Replace "tiny" with "medium" or "big" as necessary.
-
-*************************************/
-
-@mixin bp($point) {
-
- $bp-xsmall: "(min-width: 320px)";
- $bp-teeny: "(min-width: 480px)";
- $bp-tiny: "(min-width: 600px)";
- $bp-small: "(min-width: 650px)";
- $bp-medium: "(min-width: 800px)";
- $bp-big: "(min-width: 1000px)";
-
- @if $point == big {
- @media #{$bp-big} { @content; }
- }
- @else if $point == medium {
- @media #{$bp-medium} { @content; }
- }
- @else if $point == small {
- @media #{$bp-small} { @content; }
- }
- @else if $point == tiny {
- @media #{$bp-tiny} { @content; }
- }
- @else if $point == teeny {
- @media #{$bp-teeny} { @content; }
- }
- @else if $point == xsmall {
- @media #{$bp-xsmall} { @content; }
- }
-}
-
-/************************************/
-
-.vertical-menu {
- padding-left: 0;
-}
-
-a.vertical-menu {
- color: #545454;
- cursor: pointer;
- display: block;
- padding-bottom: 10px;
- padding-top: 10px;
- padding-right: 10px;
- text-decoration: none;
- text-align: left;
- &:hover {
- background-color: #ddd;
- }
-}
-
-.vertical-menu.selected {
- color:#018494;
-}
-
-.heading {
- color: #444;
- cursor: pointer;
- font-size: .85rem;
- min-width: 200px;
- padding-left: 10px;
- position: relative;
- text-transform: uppercase;
-}
-
-.material-icons {
- display: none;
-}
-
-.material-icons.active {
- display: inline-block;
- position: absolute;
- top: 6px;
- // left: 4px;
-}
-
-.heading-children {
- display: none;
-}
-
-.heading-children.active {
- display: block;
-}
-
-
-.heading.selected.level-1,
-.heading-children.selected.level-1 {
- border-left: 3px #00bcd4 solid;
-}
-
-.level-1 {
- padding-left: 10px;
-}
-
-.level-2 {
- padding-left: 20px;
-}
-
-.level-3 {
- padding-left: 30px;
-}
diff --git a/aio/src/app/sidenav/nav-item.component.ts b/aio/src/app/sidenav/nav-item.component.ts
deleted file mode 100644
index aa6283f715..0000000000
--- a/aio/src/app/sidenav/nav-item.component.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-import { Component, EventEmitter, Input, OnInit, OnDestroy } from '@angular/core';
-import { Subscription } from 'rxjs/Subscription';
-
-import { Doc, NavNode } from '../nav-engine';
-
-@Component({
- selector: 'aio-navitem',
- templateUrl: 'nav-item.component.html',
- styleUrls: ['nav-item.component.scss']
-})
-export class NavItemComponent implements OnInit, OnDestroy {
- @Input() selectedNode: EventEmitter;
- @Input() node: NavNode;
- @Input() level = 1;
-
- isActive = false;
- isSelected = false;
- isItem = false;
- classes: {[index: string]: boolean };
- href = '';
- label = '';
- selectedNodeSubscription: Subscription;
- target = '';
- tooltip = '';
-
- ngOnInit() {
- this.label = this.node.navTitle;
- this.tooltip = this.node.tooltip;
- this.isItem = this.node.children == null;
- this.href = this.node.url || this.node.docPath ;
- this.target = this.node.url ? '_blank' : '_self';
- this.setClasses();
-
- if (this.selectedNode) {
- this.selectedNodeSubscription = this.selectedNode.subscribe((n: NavNode) => {
- this.isSelected = n &&
- ( n === this.node ||
- (n.ancestorIds && n.ancestorIds.indexOf(this.node.id) > -1)
- );
- // this.isActive = this.isSelected; // disabled per meeting Feb 13
- this.setClasses();
- });
- }
- }
-
- ngOnDestroy() {
- if (this.selectedNodeSubscription) {
- this.selectedNodeSubscription.unsubscribe();
- this.selectedNodeSubscription = null;
- }
- }
-
- setClasses() {
- this.classes = {
- ['level-' + this.level]: true,
- active: this.isActive,
- selected: this.isSelected
- };
- }
-
- itemClicked() {
- this.isActive = true;
- this.isSelected = !!this.node.docId;
- this.setClasses();
- if (this.isSelected) {
- this.selectedNode.emit(this.node);
- return false;
- }
- return !!this.node.url; // let browser handle the external page request.
- }
-
- headerClicked() {
- this.isActive = !this.isActive;
- if (this.isActive && this.node.docId) {
- this.isSelected = true;
- if (this.selectedNode) {
- this.selectedNode.emit(this.node);
- }
- }
- this.setClasses();
- return false;
- }
-}
diff --git a/aio/src/app/sidenav/sidenav.component.html b/aio/src/app/sidenav/sidenav.component.html
deleted file mode 100644
index 8cf111103e..0000000000
--- a/aio/src/app/sidenav/sidenav.component.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/aio/src/app/sidenav/sidenav.component.scss b/aio/src/app/sidenav/sidenav.component.scss
deleted file mode 100644
index c1577d1036..0000000000
--- a/aio/src/app/sidenav/sidenav.component.scss
+++ /dev/null
@@ -1,27 +0,0 @@
-.sidenav-container {
- width: 100%;
- height: 100vh;
-}
-
-.sidenav-content {
- height: 100%;
- width: 100%;
- margin: auto;
- padding: 1rem;
-}
-
-.sidenav-content button {
- min-width: 50px;
-}
-
-.sidenav {
- padding: 0;
-}
-
-md-toolbar {
- display: none;
- padding-left: 10px !important;
-}
-md-toolbar.active {
- display: block;
-}
diff --git a/aio/src/app/sidenav/sidenav.component.spec.ts b/aio/src/app/sidenav/sidenav.component.spec.ts
deleted file mode 100644
index f845ce3d11..0000000000
--- a/aio/src/app/sidenav/sidenav.component.spec.ts
+++ /dev/null
@@ -1,223 +0,0 @@
-/* tslint:disable:no-unused-variable */
-import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
-import { By } from '@angular/platform-browser';
-
-import { Component, CUSTOM_ELEMENTS_SCHEMA, DebugElement, EventEmitter, Input, OnInit } from '@angular/core';
-
-import { Observable } from 'rxjs/Observable';
-import { of } from 'rxjs/observable/of';
-import 'rxjs/add/operator/delay';
-
-import { Doc, DocMetadata, NavEngine, NavMapService, NavMap, NavNode } from '../nav-engine';
-import { SidenavComponent } from './sidenav.component';
-
-//// Test Components ///
-@Component({
- // tslint:disable-next-line:component-selector
- selector: 'md-sidenav',
- template: ''
-})
-class FakeMdSideNavComponent {
- _isOpen = false;
- @Input() opened: boolean;
- @Input() mode: 'side' | 'over';
- toggle = jasmine.createSpy('toggle');
-}
-
-@Component({
- selector: 'aio-doc-viewer',
- template: ''
-})
-class FakeDocViewerComponent {
- @Input() doc: Doc;
-}
-
-//// Tests /////
-describe('SidenavComponent', () => {
- let component: SidenavComponent;
- let fixture: ComponentFixture;
-
- let fakeDoc: Doc;
- let fakeNode: NavNode;
- let fakeNavMap: NavMap;
- let navEngine: NavEngine;
- let navMapService: NavMapService;
- let navigateSpy: jasmine.Spy;
-
- beforeEach(async(() => {
- fakeDoc = {
- metadata: {docId: 'fake'} as DocMetadata,
- content: 'Fake content'
- };
-
- navEngine = {
- currentDoc: of(fakeDoc).delay(0).first(),
- navigate: (docId: string) => { }
- } as NavEngine;
- navigateSpy = spyOn(navEngine, 'navigate');
-
- fakeNode = {
- id: 42,
- docId: fakeDoc.metadata.docId,
- navTitle: 'Fakery',
- docPath: 'content/fake.hmlt'
- } as NavNode;
-
- fakeNavMap = {
- nodes: [fakeNode],
- docs: new Map([[fakeNode.docId, fakeNode]])
- };
-
- navMapService = {
- navMap: of(fakeNavMap).delay(0).first()
- } as NavMapService;
-
- TestBed.configureTestingModule({
- declarations: [
- SidenavComponent,
- FakeMdSideNavComponent,
- FakeDocViewerComponent
- ],
- providers: [
- {provide: NavEngine, useValue: navEngine },
- {provide: NavMapService, useValue: navMapService }
- ],
- schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(SidenavComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- describe('#currentDoc', () => {
- it('should have "currentDoc" after a tick', fakeAsync(() => {
- component.currentDoc.subscribe(doc => {
- expect(doc).toBe(fakeDoc);
- });
- tick();
- }));
- it('should set "currentDocId" as side effect', fakeAsync(() => {
- component.currentDoc.subscribe(doc => {
- expect(component.currentDocId).toEqual(fakeDoc.metadata.docId);
- });
- tick();
- }));
- });
-
- describe('#nodes', () => {
- it('should have "nodes" after a tick', fakeAsync(() => {
- component.nodes.subscribe(nodes => {
- expect(nodes).toEqual(fakeNavMap.nodes);
- });
- tick();
- }));
- });
-
- describe('#selectedNode', () => {
- // Simulate when user clicks a left nav link in a `NavItemComponent`
- // which calls `emit` on the selectedNode navigates
- // all of this synchronously
- it('should call navigate after emitting a node', () => {
- expect(navigateSpy.calls.count()).toBe(0, 'before emit');
- component.selectedNode.emit(fakeNode);
- expect(navigateSpy.calls.count()).toBe(1, 'after emit');
- });
-
- it('should raise event when currentDoc changes', done => {
- component.selectedNode.subscribe((node: NavNode) => {
- expect(node.docId).toBe(fakeDoc.metadata.docId);
- done();
- });
- });
- });
-
- describe('#onResize', () => {
- it('should go into side-by-side when width > 600', () => {
- component.onResize(601);
- expect(component.isSideBySide).toBe(true);
- });
-
- it('should emit overlay mode when width > 600', () => {
- component.isOverlayMode.subscribe(isOverlay =>
- expect(isOverlay).toBe(false)
- );
- component.onResize(601);
- });
- it('should go into side-by-side when width == 600', () => {
- component.onResize(600);
- expect(component.isSideBySide).toBe(false);
- });
-
- it('should emit overlay mode when width == 600', () => {
- component.isOverlayMode.subscribe(isOverlay =>
- expect(isOverlay).toBe(true)
- );
- component.onResize(600);
- });
- });
-
- describe('-> MdSideNav', () => {
-
- let mdSideNavComponent: FakeMdSideNavComponent;
-
- beforeEach(() => {
- mdSideNavComponent = fixture.debugElement
- .query(By.directive(FakeMdSideNavComponent))
- .componentInstance as FakeMdSideNavComponent;
- });
-
- it('toggle should call through to MdSideNav toggle', () => {
- const calls = mdSideNavComponent.toggle.calls;
- expect(calls.count()).toBe(0, 'before toggle');
- component.toggle();
- expect(calls.count()).toBe(1, 'after toggle');
- });
-
- it('should be opened when width > 600', () => {
- component.onResize(601);
- fixture.detectChanges();
- expect(mdSideNavComponent.opened).toBe(true);
- });
-
- it('should be not open when width == 600', () => {
- component.onResize(600);
- fixture.detectChanges();
- expect(mdSideNavComponent.opened).toBe(false);
- });
- });
-
- describe('-> DocViewer', () => {
- let docViewer: FakeDocViewerComponent;
-
- beforeEach(() => {
- docViewer = fixture.debugElement
- .query(By.directive(FakeDocViewerComponent))
- .componentInstance as FakeDocViewerComponent;
- });
-
- it('should not have a document at the start', () => {
- expect(docViewer.doc).toBeNull();
- });
-
- // Doesn't work with fakeAsync and async complains about the delay timer (setInterval);
- // it('should have a document after NavEngine has a current doc', (fakeAsync(() => {
- // tick();
- // fixture.detectChanges();
- // expect(docViewer.doc).toBe(fakeDoc);
- // })));
-
- // Must go old school with setTimeout and `done`
- it('should have a document after NavEngine has a current doc', (done => {
- setTimeout(() => {
- fixture.detectChanges();
- expect(docViewer.doc).toBe(fakeDoc);
- done();
- }, 1);
- }));
-
- });
-});
diff --git a/aio/src/app/sidenav/sidenav.component.ts b/aio/src/app/sidenav/sidenav.component.ts
deleted file mode 100644
index cc0d39673e..0000000000
--- a/aio/src/app/sidenav/sidenav.component.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { Component, EventEmitter, Output, OnInit, OnChanges, ViewChild } from '@angular/core';
-import { MdSidenav } from '@angular/material/sidenav';
-
-import { Observable } from 'rxjs/Observable';
-import 'rxjs/add/operator/do';
-import 'rxjs/add/operator/map';
-import 'rxjs/add/operator/take';
-
-import { Doc, NavEngine, NavMap, NavMapService, NavNode } from '../nav-engine';
-
-@Component({
- selector: 'aio-sidenav',
- templateUrl: './sidenav.component.html',
- styleUrls: ['./sidenav.component.scss'],
- animations: []
-})
-export class SidenavComponent implements OnInit {
-
- @Output() isOverlayMode = new EventEmitter();
- @ViewChild('sidenav') private sidenav: MdSidenav;
-
- currentDoc: Observable;
- currentDocId: string;
- isSideBySide = false;
- nodes: Observable;
- selectedNode = new EventEmitter();
- sideBySideWidth = 600;
- windowWidth = 0;
-
- constructor(
- private navEngine: NavEngine,
- private navMapService: NavMapService ) {}
-
- ngOnInit() {
- this.onResize(window.innerWidth);
-
- this.nodes = this.navMapService.navMap.map( navMap => navMap.nodes );
-
- this.currentDoc = this.navEngine.currentDoc
- .do(doc => {
- // Side effect: when the current doc changes,
- // get its NavNode and alert the navigation panel
- this.currentDocId = doc.metadata.docId;
- this.navMapService.navMap.first() // take makes sure it completes!
- .map(navMap => navMap.docs.get(this.currentDocId))
- .subscribe( node => this.selectedNode.emit(node));
- });
-
- this.selectedNode.subscribe((node: NavNode) => {
- // Navigate when the user selects a doc other than the current doc
- const docId = node && node.docId;
- if (docId && docId !== this.currentDocId) {
- this.navEngine.navigate(docId);
- }
- });
- }
-
- onResize(width) {
- this.windowWidth = width;
- this.isSideBySide = width > this.sideBySideWidth;
- this.sidenav.mode = this.isSideBySide ? 'side' : 'over';
- this.isOverlayMode.emit(!this.isSideBySide);
- }
-
- toggle() {
- this.sidenav.toggle();
- }
-}
diff --git a/aio/src/content/navmap.json b/aio/src/content/navmap.json
deleted file mode 100644
index 259a895d56..0000000000
--- a/aio/src/content/navmap.json
+++ /dev/null
@@ -1,402 +0,0 @@
-{ "nodes": [
- {
- "docId": "guide/quickstart",
- "navTitle": "Quickstart",
- "tooltip": "A quick look at an Angular app."
- },
-
- {
- "docId": "guide/cli-quickstart",
- "navTitle": "CLI Quickstart",
- "tooltip": "A quick look at an Angular app built with the Angular CLI."
- },
-
- {
- "navTitle": "Tutorial",
- "tooltip": "The Tour of Heroes tutorial takes you through the steps of creating an Angular application in TypeScript.",
- "children": [
- {
- "docId": " tutorial/",
- "navTitle": "Introduction",
- "tooltip": "Introduction to the Tour of Heroes tutorial"
- },
- {
- "docId": "tutorial/toh-1",
- "navTitle": "The hero editor",
- "tooltip": "Build a simple hero editor"
- },
- {
- "docId": "tutorial/toh-2",
- "navTitle": "Master/detail",
- "tooltip": "Build a master/detail page with a list of heroes."
- },
- {
- "docId": "tutorial/toh-3",
- "navTitle": "Multiple components",
- "tooltip": "Refactor the master/detail view into separate components."
- },
- {
- "docId": "tutorial/toh-4",
- "navTitle": "Services",
- "tooltip": "Create a reusable service to manage hero data."
- },
- {
- "docId": "tutorial/toh-5",
- "navTitle": "Routing",
- "tooltip": "Add the Angular router and navigate among the views."
- },
- {
- "docId": "tutorial/toh-6",
- "navTitle": "HTTP",
- "tooltip": "Use HTTP to retrieve and save hero data."
- }
- ]
- },
-
- {
- "navTitle": "Getting started",
- "tooltip": "A gentle introduction to Angular.",
- "children": [
- {
- "docId": "guide/docs-overview",
- "navTitle": "Overview",
- "tooltip": "How to read and use this documentation."
- },
- {
- "docId": "guide/setup",
- "navTitle": "Setup",
- "tooltip": "Install the Angular QuickStart seed for faster, more efficient development on your machine."
- },
-
- {
- "docId": "guide/learning-angular",
- "navTitle": "Learning Angular",
- "tooltip": "A suggested path through the documentation for Angular newcomers."
- },
-
- {
- "docId": "guide/architecture",
- "navTitle": "Architecture",
- "tooltip": "The basic building blocks of Angular applications."
- },
-
- {
- "docId": "guide/appmodule",
- "navTitle": "The root AppModule",
- "tooltip": "Tell Angular how to construct and bootstrap the app in the root \"AppModule\"."
- },
-
- {
- "docId": "guide/displaying-data",
- "navTitle": "Displaying data",
- "tooltip": "Property binding helps show app data in the UI."
- },
-
- {
- "docId": "guide/user-input",
- "navTitle": "User Input",
- "tooltip": "User input triggers DOM events. We listen to those events with event bindings that funnel updated values back into our components and models."
- },
-
- {
- "docId": "guide/forms",
- "navTitle": "Forms",
- "tooltip": "A form creates a cohesive, effective, and compelling data entry experience. An Angular form coordinates a set of data-bound user controls, tracks changes, validates input, and presents errors."
- },
-
- {
- "docId": "guide/dependency-injection",
- "navTitle": "Dependency Injection",
- "tooltip": "Angular's dependency injection system creates and delivers dependent services \"just-in-time\"."
- },
-
- {
- "docId": "guide/template-syntax",
- "navTitle": "Template Syntax",
- "tooltip": "Learn how to write templates that display data and consume user events with the help of data binding."
- },
-
- {
- "docId": "guide/cheatsheet",
- "navTitle": "Cheat Sheet",
- "tooltip": "A quick guide to common Angular coding techniques."
- },
-
- {
- "docId": "guide/style-guide",
- "navTitle": "Style guide",
- "tooltip": "Write Angular with style."
- },
-
- {
- "docId": "guide/glossary",
- "navTitle": "Glossary",
- "tooltip": "Brief definitions of the most important words in the Angular vocabulary."
- },
-
- {
- "docId": "guide/change-log",
- "navTitle": "Change Log",
- "tooltip": "An annotated history of recent documentation improvements."
- }
- ]},
-
- {
- "navTitle": "Core",
- "tooltip": "Learn the core capabilities of Angular",
- "children": [
- {
- "navTitle": "Angular Modules",
- "tooltip": "Learn how directives modify the layout and behavior of elements.",
- "children": [
- {
- "docId": "guide/ngmodule",
- "navTitle": "NgModule",
- "tooltip": "Define application modules with @NgModule."
- },
-
- {
- "docId": "guide/ngmodule-faq",
- "navTitle": "Angular module FAQs",
- "tooltip": "Answers to frequently asked questions about @NgModule."
- }
- ]},
-
- {
- "docId": "guide/component-communication",
- "navTitle": "Component interaction",
- "tooltip": "Share information between different directives and components."
- },
-
- {
- "docId": "guide/component-relative-paths",
- "navTitle": "Component-relative paths",
- "tooltip": "Use relative URLs for component templates and styles."
- },
-
- {
- "navTitle": "Dependency Injection",
- "tooltip": "More about Dependency Injection",
- "children": [
- {
- "docId": "guide/cb-dependency-injection",
- "navTitle": "Dependency injection",
- "tooltip": "Techniques for Dependency Injection."
- },
-
- {
- "docId": "guide/hierarchical-dependency-injection",
- "navTitle": "Hierarchical injectors",
- "tooltip": "Angular's hierarchical dependency injection system supports nested injectors in parallel with the component tree."
- }
- ]},
-
- {
- "docId": "guide/dynamic-component-loader",
- "navTitle": "Dynamic components",
- "tooltip": "Load components dynamically."
- },
-
- {
- "docId": "guide/directives",
- "navTitle": "Directives",
- "tooltip": "Learn how directives modify the layout and behavior of elements.",
- "children": [
- {
- "docId": "guide/attribute-directives",
- "navTitle": "Attribute directives",
- "tooltip": "Attribute directives attach behavior to elements."
- },
- {
- "docId": "guide/structural-directives",
- "navTitle": "Structural directives",
- "tooltip": "Structural directives manipulate the layout of the page."
- }
- ]
- },
-
- {
- "navTitle": "Forms",
- "tooltip": "More about forms",
- "children": [
- {
- "docId": "guide/dynamic-form",
- "navTitle": "Dynamic forms",
- "tooltip": "Render dynamic forms with FormGroup."
- },
-
- {
- "docId": "guide/form-validation",
- "navTitle": "Form validation",
- "tooltip": "Validate user's form entries."
- },
-
- {
- "docId": "guide/reactive-forms",
- "navTitle": "Reactive forms",
- "tooltip": "Create a reactive form using FormBuilder, groups, and arrays."
- }
- ]},
-
- {
- "docId": "guide/server-communication",
- "navTitle": "HTTP client",
- "tooltip": "Use an HTTP Client to talk to a remote server."
- },
-
- {
- "docId": "guide/lifecycle-hooks",
- "navTitle": "Lifecycle hooks",
- "tooltip": "Angular calls lifecycle hook methods on directives and components as it creates, changes, and destroys them."
- },
-
- {
- "docId": "guide/pipes",
- "navTitle": "Pipes",
- "tooltip": "Pipes transform displayed values within a template."
- },
-
- {
- "docId": "guide/router",
- "navTitle": "Routing & navigation",
- "tooltip": "Discover the basics of screen navigation with the Angular Router."
- }
- ]},
-
- {
- "navTitle": "Additional Techniques",
- "tooltip": "Other",
- "children": [
- {
- "docId": "guide/aot-compiler",
- "navTitle": "Ahead-of-Time compilation",
- "tooltip": "Learn why and how to use the Ahead-of-Time (AOT) compiler."
- },
-
- {
- "docId": "guide/animations",
- "navTitle": "Animations",
- "tooltip": "A guide to Angular's animation system."
- },
-
- {
- "docId": "guide/ajs-quick-reference",
- "navTitle": "AngularJS to Angular",
- "tooltip": "Learn how AngularJS concepts and techniques map to Angular."
- },
-
- {
- "docId": "guide/component-styles",
- "navTitle": "Component styles",
- "tooltip": "Learn how to apply CSS styles to components."
- },
-
- {
- "docId": "guide/deployment",
- "navTitle": "Deployment",
- "tooltip": "Learn how to deploy your Angular app."
- },
-
- {
- "docId": "guide/i18n",
- "navTitle": "Internationalization (i18n)",
- "tooltip": "Translate the app's template text into multiple languages."
- },
-
- {
- "docId": "guide/security",
- "navTitle": "Security",
- "tooltip": "Developing for content security in Angular applications."
- },
-
- {
- "navTitle": "Setup",
- "tooltip": "Details of the local development setup",
- "children": [
- {
- "docId": "guide/setup-systemjs-anatomy",
- "navTitle": "Setup Anatomy",
- "tooltip": "Inside the local development environment for SystemJS."
- },
-
- {
- "docId": "guide/browser-support",
- "navTitle": "Browser support",
- "tooltip": "Browser support and polyfills guide."
- },
-
- {
- "docId": "guide/npm-packages",
- "navTitle": "Npm packages",
- "tooltip": "Recommended npm packages, and how to specify package dependencies."
- },
-
- {
- "docId": "guide/typescript-configuration",
- "navTitle": "TypeScript configuration",
- "tooltip": "TypeScript configuration for Angular developers."
- }
- ]},
-
- {
- "docId": "guide/testing",
- "navTitle": "Testing",
- "tooltip": "Techniques and practices for testing an Angular app."
- },
-
- {
- "docId": "guide/upgrade",
- "navTitle": "Upgrading from AngularJS",
- "tooltip": "Incrementally upgrade an AngularJS application to Angular."
- },
-
- {
- "docId": "guide/ts-to-js",
- "navTitle": "TypeScript to JavaScript",
- "tooltip": "Convert Angular TypeScript examples into ES6 and ES5 JavaScript."
- },
-
- {
- "docId": "guide/visual-studio-2015",
- "navTitle": "Visual Studio 2015 QuickStart",
- "tooltip": "Use Visual Studio 2015 with the QuickStart files."
- },
-
- {
- "docId": "guide/webpack",
- "navTitle": "Webpack: an introduction",
- "tooltip": "Create Angular applications with a Webpack based tooling."
- }
- ]
- },
-
- {
- "docId": "resources/",
- "navTitle": "Resources",
- "children": [
- {
- "docId": "about",
- "navTitle": "About",
- "tooltip": "The people behind Angular."
- }
- ]
- },
-
- {
- "navTitle": "Help",
- "children": [
- {
- "url":
- "http://stackoverflow.com/questions/tagged/angular2",
- "urlNew": "http://stackoverflow.com/questions/tagged/angular2.html",
- "navTitle": "Stack Overflow",
- "tooltip": "Stack Overflow: where the community answers your technical Angular questions."
- },
- {
- "url": "https://gitter.im/angular/angular",
- "navTitle": "Gitter",
- "tooltip": "Chat about Angular with other birds of a feather."
- }
- ]
- }
-]}