build(aio): move doc-gen stuff from angular.io (#14097)
This commit is contained in:
committed by
Igor Minar
parent
d1d0ce7613
commit
b7763559cd
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
||||
import {Component, OnInit, NgZone } from '@angular/core';
|
||||
import {FormControl, ReactiveFormsModule} from '@angular/forms';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import 'rxjs/add/operator/do';
|
||||
import 'rxjs/add/operator/switchMap';
|
||||
import {QueryResults, SearchWorkerClient} from './search-worker-client';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `
|
||||
<h1>Angular Docs Search</h1>
|
||||
<div class="search-bar"><input [formControl]="searchInput"></div>
|
||||
<div class="search-results">
|
||||
<div *ngIf="!(indexReady | async)">Waiting...</div>
|
||||
<ul>
|
||||
<li *ngFor="let result of (searchResult$ | async)">
|
||||
<a href="{{result.path}}">{{ result.title }} ({{result.type}})</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
searchResult$: Observable<QueryResults>;
|
||||
indexReady: Promise<boolean>;
|
||||
searchInput: FormControl;
|
||||
|
||||
constructor(private zone: NgZone) {}
|
||||
|
||||
ngOnInit() {
|
||||
const searchWorker = new SearchWorkerClient('app/search-worker.js', this.zone);
|
||||
this.indexReady = searchWorker.ready;
|
||||
this.searchInput = new FormControl();
|
||||
this.searchResult$ = this.searchInput.valueChanges
|
||||
.switchMap((searchText: string) => searchWorker.search(searchText));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
import {AppComponent} from 'app/app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule, ReactiveFormsModule ],
|
||||
declarations: [ AppComponent ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
class AppModule {
|
||||
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
||||
import {NgZone} from '@angular/core';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {Subscriber} from 'rxjs/Subscriber';
|
||||
import 'rxjs/add/observable/fromPromise';
|
||||
import 'rxjs/add/observable/of';
|
||||
import 'rxjs/add/operator/switchMap';
|
||||
|
||||
|
||||
export interface QueryResults {}
|
||||
|
||||
export interface ResultsReadyMessage {
|
||||
type: 'query-results';
|
||||
id: number;
|
||||
query: string;
|
||||
results: QueryResults;
|
||||
}
|
||||
|
||||
export class SearchWorkerClient {
|
||||
ready: Promise<boolean>;
|
||||
worker: Worker;
|
||||
private _queryId = 0;
|
||||
|
||||
constructor(url: string, private zone: NgZone) {
|
||||
this.worker = new Worker(url);
|
||||
this.ready = this._waitForIndex(this.worker);
|
||||
}
|
||||
|
||||
search(query: string) {
|
||||
return Observable.fromPromise(this.ready)
|
||||
.switchMap(() => this._createQuery(query));
|
||||
}
|
||||
|
||||
private _waitForIndex(worker: Worker) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
worker.onmessage = (e) => {
|
||||
if(e.data.type === 'index-ready') {
|
||||
resolve(true);
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
|
||||
worker.onerror = (e) => {
|
||||
reject(e);
|
||||
cleanup();
|
||||
};
|
||||
});
|
||||
|
||||
function cleanup() {
|
||||
worker.onmessage = null;
|
||||
worker.onerror = null;
|
||||
}
|
||||
}
|
||||
|
||||
private _createQuery(query: string) {
|
||||
return new Observable<QueryResults>((subscriber: Subscriber<QueryResults>) => {
|
||||
|
||||
// get a new identifier for this query that we can match to results
|
||||
const id = this._queryId++;
|
||||
|
||||
const handleMessage = (message: MessageEvent) => {
|
||||
const {type, id: queryId, results} = message.data as ResultsReadyMessage;
|
||||
if (type === 'query-results' && id === queryId) {
|
||||
this.zone.run(() => {
|
||||
subscriber.next(results);
|
||||
subscriber.complete();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleError = (error: ErrorEvent) => {
|
||||
this.zone.run(() => {
|
||||
subscriber.error(error);
|
||||
});
|
||||
};
|
||||
|
||||
// Wire up the event listeners for this query
|
||||
this.worker.addEventListener('message', handleMessage);
|
||||
this.worker.addEventListener('error', handleError);
|
||||
|
||||
// Post the query to the web worker
|
||||
this.worker.postMessage({query, id});
|
||||
|
||||
// At completion/error unwire the event listeners
|
||||
return () => {
|
||||
this.worker.removeEventListener('message', handleMessage);
|
||||
this.worker.removeEventListener('error', handleError);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint-env worker */
|
||||
/* global importScripts, lunr */
|
||||
|
||||
importScripts('https://unpkg.com/lunr@0.7.2');
|
||||
|
||||
var index = createIndex();
|
||||
var pages = {};
|
||||
|
||||
makeRequest('search-data.json', loadIndex);
|
||||
|
||||
self.onmessage = handleMessage;
|
||||
|
||||
// Create the lunr index - the docs should be an array of objects, each object containing
|
||||
// the path and search terms for a page
|
||||
function createIndex() {
|
||||
return lunr(/** @this */function() {
|
||||
this.ref('path');
|
||||
this.field('titleWords', {boost: 50});
|
||||
this.field('members', {boost: 40});
|
||||
this.field('keywords', {boost: 20});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Use XHR to make a request to the server
|
||||
function makeRequest(url, callback) {
|
||||
var searchDataRequest = new XMLHttpRequest();
|
||||
searchDataRequest.onload = function() {
|
||||
callback(JSON.parse(this.responseText));
|
||||
};
|
||||
searchDataRequest.open('GET', url);
|
||||
searchDataRequest.send();
|
||||
}
|
||||
|
||||
|
||||
// Create the search index from the searchInfo which contains the information about each page to be indexed
|
||||
function loadIndex(searchInfo) {
|
||||
// Store the pages data to be used in mapping query results back to pages
|
||||
// Add search terms from each page to the search index
|
||||
searchInfo.forEach(function(page) {
|
||||
index.add(page);
|
||||
pages[page.path] = page;
|
||||
});
|
||||
self.postMessage({type: 'index-ready'});
|
||||
}
|
||||
|
||||
|
||||
// The worker receives a message everytime the web app wants to query the index
|
||||
function handleMessage(message) {
|
||||
var id = message.data.id;
|
||||
var query = message.data.query;
|
||||
var results = queryIndex(query);
|
||||
self.postMessage({type: 'query-results', id: id, query: query, results: results});
|
||||
}
|
||||
|
||||
|
||||
// Query the index and return the processed results
|
||||
function queryIndex(query) {
|
||||
// Only return the array of paths to pages
|
||||
return index.search(query).map(function(hit) { return pages[hit.ref]; });
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"declaration": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "../dist/tools/",
|
||||
"noImplicitAny": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"paths": {
|
||||
},
|
||||
"rootDir": ".",
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
"lib": ["es6", "dom"],
|
||||
"target": "es5",
|
||||
"skipLibCheck": true,
|
||||
"typeRoots": [
|
||||
"../../../node_modules"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"typings-test",
|
||||
"public_api_guard",
|
||||
"docs"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello Angular</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
body {color:#369;font-family: Arial,Helvetica,sans-serif;}
|
||||
</style>
|
||||
|
||||
<!-- Polyfills for older browsers -->
|
||||
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/zone.js@0.7.2?main=browser"></script>
|
||||
<script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
|
||||
<script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.web.js"></script>
|
||||
<script>
|
||||
System.import('app').catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<my-app>Loading AppComponent content here ...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
||||
System.config({
|
||||
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
|
||||
transpiler: 'ts',
|
||||
typescriptOptions: {
|
||||
// Copy of compiler options in standard tsconfig.json
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
},
|
||||
meta: {
|
||||
'typescript': {
|
||||
"exports": "ts"
|
||||
}
|
||||
},
|
||||
paths: {
|
||||
// paths serve as alias
|
||||
'npm:': 'https://unpkg.com/'
|
||||
},
|
||||
// map tells the System loader where to look for things
|
||||
map: {
|
||||
// our app is within the app folder
|
||||
app: 'app',
|
||||
|
||||
// angular bundles
|
||||
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
|
||||
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
|
||||
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
|
||||
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
|
||||
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
|
||||
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
|
||||
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
|
||||
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
|
||||
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
|
||||
'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
|
||||
|
||||
// other libraries
|
||||
'rxjs': 'npm:rxjs',
|
||||
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
|
||||
'ts': 'npm:plugin-typescript@4.0.10/lib/plugin.js',
|
||||
'typescript': 'npm:typescript@2.0.3/lib/typescript.js',
|
||||
|
||||
},
|
||||
// packages tells the System loader how to load when no filename and/or no extension
|
||||
packages: {
|
||||
app: {
|
||||
main: './main.ts',
|
||||
defaultExtension: 'ts'
|
||||
},
|
||||
rxjs: {
|
||||
defaultExtension: 'js'
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user