feat(aio): add initial doc viewer
with lots of fixes from Igor and Ward <3
This commit is contained in:
parent
559cf9d192
commit
6e2c9cb586
|
@ -16,7 +16,7 @@
|
|||
"polyfills": "polyfills.ts",
|
||||
"test": "test.ts",
|
||||
"tsconfig": "tsconfig.json",
|
||||
"prefix": "app",
|
||||
"prefix": "aio",
|
||||
"styles": [
|
||||
"styles.scss"
|
||||
],
|
||||
|
|
|
@ -7,8 +7,10 @@ describe('site App', function() {
|
|||
page = new SitePage();
|
||||
});
|
||||
|
||||
it('should display message saying app works', () => {
|
||||
it('should show features text after clicking "Features"', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('home-page works!');
|
||||
page.featureLink.click().then(() => {
|
||||
expect(page.getDocViewerText()).toContain('Progressive web apps');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import { browser, element, by } from 'protractor';
|
||||
|
||||
export class SitePage {
|
||||
|
||||
featureLink = element(by.css('md-toolbar a[aioNavLink=features]'));
|
||||
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-home-page p')).getText();
|
||||
getDocViewerText() {
|
||||
return element(by.css('aio-doc-viewer')).getText();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<md-toolbar color="primary" class="app-toolbar">
|
||||
<span>Angular</span>
|
||||
|
||||
<span><a class="nav-link" aioNavLink="home"> Home </a></span>
|
||||
<span><a class="nav-link" aioNavLink="news"> News</a></span>
|
||||
<span><a class="nav-link" aioNavLink="features"> Features</a></span>
|
||||
<span class="fill-remaining-space"></span>
|
||||
</md-toolbar>
|
||||
<section class="app-content">
|
||||
<router-outlet></router-outlet>
|
||||
<aio-doc-viewer [doc]="navEngine.currentDoc"></aio-doc-viewer>
|
||||
</section>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.fill-remaining-space {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.nav-link {
|
||||
margin-right: 10px;
|
||||
margin-left: 20px;
|
||||
cursor: pointer;
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
import { NavEngine } from './nav-engine/nav-engine';
|
||||
@Component({
|
||||
selector: 'app-shell',
|
||||
selector: 'aio-shell',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'app works!';
|
||||
constructor(public navEngine: NavEngine) {}
|
||||
}
|
||||
|
|
|
@ -3,19 +3,23 @@ import { NgModule } from '@angular/core';
|
|||
import { RouterModule } from '@angular/router';
|
||||
import { AppComponent } from './app.component';
|
||||
import { MdToolbarModule } from '@angular/material/toolbar';
|
||||
import { MdButtonModule} from '@angular/material/button';
|
||||
import { DocViewerComponent } from './doc-viewer/doc-viewer.component';
|
||||
import { NavEngine } from './nav-engine/nav-engine';
|
||||
import { NavLinkDirective } from './nav-engine/nav-link';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
AppComponent,
|
||||
DocViewerComponent,
|
||||
NavLinkDirective
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
MdToolbarModule.forRoot(),
|
||||
RouterModule.forRoot([
|
||||
{ path: '', loadChildren: './home-page/home-page.module#HomePageModule'}
|
||||
])
|
||||
MdButtonModule.forRoot()
|
||||
],
|
||||
providers: [],
|
||||
providers: [NavEngine],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/* tslint:disable:no-unused-variable */
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { DebugElement } from '@angular/core';
|
||||
|
||||
import { DocViewerComponent } from './doc-viewer.component';
|
||||
|
||||
describe('DocViewerComponent', () => {
|
||||
let component: DocViewerComponent;
|
||||
let fixture: ComponentFixture<DocViewerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DocViewerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DocViewerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
import { Component, OnInit, Input, ElementRef, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'aio-doc-viewer',
|
||||
templateUrl: './doc-viewer.component.html',
|
||||
styleUrls: ['./doc-viewer.component.css'],
|
||||
// TODO(robwormald): shadow DOM and emulated don't work here (?!)
|
||||
// encapsulation: ViewEncapsulation.Native
|
||||
})
|
||||
export class DocViewerComponent implements OnInit {
|
||||
|
||||
@Input()
|
||||
set doc(currentDoc) {
|
||||
if (currentDoc) {
|
||||
this.element.nativeElement.innerHTML = currentDoc.content;
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private element: ElementRef) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-ngio-docs',
|
||||
selector: 'aio-ngio-docs',
|
||||
templateUrl: './docs-app.component.html',
|
||||
styleUrls: ['./docs-app.component.css']
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home-page',
|
||||
selector: 'aio-home-page',
|
||||
templateUrl: './home-page.component.html',
|
||||
styleUrls: ['./home-page.component.css']
|
||||
})
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
declare var fetch;
|
||||
|
||||
// TODO(robwormald): figure out how to handle this properly...
|
||||
const siteMap = [
|
||||
{ 'title': 'Home', 'url': 'assets/documents/home.html', id: 'home'},
|
||||
{ 'title': 'Features', 'url': 'assets/documents/features.html', id: 'features'},
|
||||
{ 'title': 'News', 'url': 'assets/documents/news.html', id: 'news'}
|
||||
];
|
||||
|
||||
|
||||
export class NavEngine {
|
||||
currentDoc: any;
|
||||
constructor() {}
|
||||
navigate(documentId) {
|
||||
console.log('navigating to', documentId);
|
||||
const doc = siteMap.find(d => d.id === documentId);
|
||||
if (doc) {
|
||||
this._fetchDoc(doc.url)
|
||||
.then(content => {
|
||||
console.log('fetched content', content);
|
||||
this.currentDoc = Object.assign({}, doc, {content});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _fetchDoc(url) {
|
||||
// TODO(robwormald): use Http proper once new API is done.
|
||||
return fetch(url).then(res => res.text());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { Directive, HostListener, Input } from '@angular/core';
|
||||
import { NavEngine } from './nav-engine';
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* tslint:disable:no-unused-variable */
|
||||
|
||||
import { TestBed, async, inject } from '@angular/core/testing';
|
||||
import { PageManagerService } from './page-manager.service';
|
||||
|
||||
describe('PageManagerService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [PageManagerService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should ...', inject([PageManagerService], (service: PageManagerService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class PageManagerService {
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<body>
|
||||
|
||||
<app-shell></app-shell>
|
||||
<aio-shell></aio-shell>
|
||||
|
||||
<!-- TODO: google analytics -->
|
||||
<!-- TODO: google feedback -->
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
// import 'core-js/es6/regexp';
|
||||
// import 'core-js/es6/map';
|
||||
// import 'core-js/es6/set';
|
||||
import 'reflect-metadata';
|
||||
|
||||
|
||||
// If you need to support the browsers/features below, uncomment the import
|
||||
|
|
|
@ -98,8 +98,8 @@
|
|||
"check-type"
|
||||
],
|
||||
|
||||
"directive-selector": [true, "attribute", "app", "camelCase"],
|
||||
"component-selector": [true, "element", "app", "kebab-case"],
|
||||
"directive-selector": [true, "attribute", "aio", "camelCase"],
|
||||
"component-selector": [true, "element", "aio", "kebab-case"],
|
||||
"use-input-property-decorator": true,
|
||||
"use-output-property-decorator": true,
|
||||
"use-host-property-decorator": true,
|
||||
|
|
Loading…
Reference in New Issue