build(aio): move doc-gen stuff from angular.io (#14097)
This commit is contained in:
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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
[{% for module, items in doc.data %}
|
||||||
|
{% for item in items %}
|
||||||
|
{
|
||||||
|
"title": "{$ item.title $}",
|
||||||
|
"path": "{$ item.exportDoc.path $}",
|
||||||
|
"docType": "{$ item.docType $}",
|
||||||
|
"stability": "{$ item.stability $}",
|
||||||
|
"secure": "{$ item.security $}",
|
||||||
|
"howToUse": "{$ item.howToUse | replace('"','\\"') $}",
|
||||||
|
"whatItDoes": {% if item.whatItDoes %}"Exists"{% else %}"Not Done"{% endif %},
|
||||||
|
"barrel" : "{$ module | replace("/index", "") $}"
|
||||||
|
}{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
]
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
{%- for module, items in doc.data %}
|
||||||
|
"{$ module | replace("/index", "") $}" : [{% for item in items %}
|
||||||
|
{
|
||||||
|
"title": "{$ item.title $}",
|
||||||
|
"path": "{$ item.exportDoc.path $}",
|
||||||
|
"docType": "{$ item.docType $}",
|
||||||
|
"stability": "{$ item.stability $}",
|
||||||
|
"secure": "{$ item.security $}",
|
||||||
|
"barrel" : "{$ module | replace("/index", "") $}"
|
||||||
|
}{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}]{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor -%}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"currentEnvironment": {$ doc.currentEnvironment | json | trim $},
|
||||||
|
"version": {$ doc.version.currentVersion | json | indent(2) | trim $},
|
||||||
|
"sections": {$ doc.sections | json | indent(2) | trim $}
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% import "lib/paramList.html" as params -%}
|
||||||
|
{% extends 'layout/base.template.html' -%}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include "layout/_what-it-does.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_security-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_deprecated-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_how-to-use.html" %}
|
||||||
|
|
||||||
|
<div layout="row" layout-xs="column" class="ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Class Overview</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
<code class="no-bg api-doc-code openParens">class {$ doc.name $} {</code>
|
||||||
|
{% if doc.statics.length %}
|
||||||
|
<div layout="column">
|
||||||
|
{% for member in doc.statics %}{% if not member.internal %}
|
||||||
|
<pre class="prettyprint no-bg-with-indent">static
|
||||||
|
<a class="code-anchor" href="#{$ member.name $}-anchor">
|
||||||
|
<code(class="code-background api-doc-code">{$ member.name | indent(6, false) | trim $}</code>
|
||||||
|
</a>
|
||||||
|
<code class="api-doc-code">
|
||||||
|
{$ params.paramList(member.parameters) | indent(8, false) | trim $}{$ params.returnType(member.returnType) $}
|
||||||
|
</code>
|
||||||
|
{% endif %}{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if doc.constructorDoc.name %}
|
||||||
|
<div layout="column">
|
||||||
|
<pre class="prettyprint no-bg-with-indent">
|
||||||
|
<a class="code-anchor" href="#constructor">
|
||||||
|
<code class="code-background api-doc-code">{$ doc.constructorDoc.name $}</code>
|
||||||
|
</a>
|
||||||
|
<code class="api-doc-code">
|
||||||
|
{$ params.paramList(doc.constructorDoc.parameters) | indent(8, false) | trim $}
|
||||||
|
</code>
|
||||||
|
{% endif %}
|
||||||
|
{% if doc.members.length %}
|
||||||
|
<div layout="column">
|
||||||
|
{% for member in doc.members %}{% if not member.internal %}
|
||||||
|
<pre class="prettyprint no-bg-with-indent">
|
||||||
|
<a class="code-anchor" href="#{$ member.name $}-anchor">
|
||||||
|
<code class="code-background api-doc-code">{$ member.name | indent(6, false) | trim $}</code>
|
||||||
|
</a>
|
||||||
|
<code class="api-doc-code">{$ params.paramList(member.parameters) | indent(8, false) | trim $}{$ params.returnType(member.returnType) $}</code>
|
||||||
|
</pre>
|
||||||
|
{% endif %}{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
<p class="selector endParens">
|
||||||
|
<code class="api-doc-code no-bg">}</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% block additional %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Class Description</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{%- if doc.description.length > 2 %}
|
||||||
|
{$ doc.description | trimBlankLines | marked $}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{%- if doc.decorators.length %}
|
||||||
|
{% block annotations %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Annotations</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
{%- for decorator in doc.decorators %}
|
||||||
|
<pre class="prettyprint no-bg">
|
||||||
|
<code class="api-doc-code">
|
||||||
|
@{$ decorator.name $}{$ params.paramList(decorator.arguments) | indent(10, false) $}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
{%- if not decorator.notYetDocumented %}
|
||||||
|
{$ decorator.description | indentForMarkdown(8) | trimBlankLines | marked $}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{%- if doc.constructorDoc and not doc.constructorDoc.internal %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Constructor</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
<a name="constructor" class="anchor-offset"></a>
|
||||||
|
<pre class="prettyprint no-bg" ng-class="{ 'anchor-focused': appCtrl.isApiDocMemberFocused('{$ doc.constructorDoc.name $}') }">
|
||||||
|
<code class="api-doc-code">
|
||||||
|
{$ doc.constructorDoc.name $}{$ params.paramList(doc.constructorDoc.parameters) | indent(8, false) | trim $}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
{%- if not doc.constructorDoc.notYetDocumented %}
|
||||||
|
{$ doc.constructorDoc.description | replace('### Example', '') | replace('## Example', '') | replace('# Example', '') | trimBlankLines | marked $}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if doc.statics.length %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Static Members</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{% for member in doc.statics %}{% if not member.internal %}
|
||||||
|
<a name="{$ member.name $}-anchor" class="anchor-offset"></a>
|
||||||
|
<pre class="prettyprint no-bg" ng-class="{ 'anchor-focused': appCtrl.isApiDocMemberFocused('{$ member.name $}') }">
|
||||||
|
<code class="api-doc-code">
|
||||||
|
{$ member.name $}{$ params.paramList(member.parameters) | indent(8, false) | trim $}{$ params.returnType(member.returnType) $}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
{%- if not member.notYetDocumented %}
|
||||||
|
{$ member.description | replace('### Example', '') | replace('## Example', '') | replace('# Example', '') | trimBlankLines | marked $}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not loop.last %}
|
||||||
|
<hr class="hr-margin">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if doc.members.length %}
|
||||||
|
<div layout="row" layout-xs="column" class="instance-members" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Class Details</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{% for member in doc.members %}{% if not member.internal %}
|
||||||
|
<a name="{$ member.name $}-anchor" class="anchor-offset">
|
||||||
|
<pre class="prettyprint no-bg" ng-class="{ 'anchor-focused': appCtrl.isApiDocMemberFocused('{$ member.name $}') }">
|
||||||
|
<code class="api-doc-code">
|
||||||
|
{$ member.name $}{$ params.paramList(member.parameters) | indent(8, false) | trim $}{$ params.returnType(member.returnType) $}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
{%- if not member.notYetDocumented %}
|
||||||
|
{$ member.description | replace('### Example', '') | replace('## Example', '') | replace('# Example', '') | trimBlankLines | marked $}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% if not loop.last %}
|
||||||
|
<hr class="hr-margin">
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p class="location-badge">
|
||||||
|
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} },
|
||||||
|
defined in {$ github.githubViewLink(doc, versionInfo) $}
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1 @@
|
||||||
|
{% extends 'var.template.html' -%}
|
|
@ -0,0 +1 @@
|
||||||
|
export const {$ doc.serviceName $} = {$ doc.value | json $};
|
|
@ -0,0 +1,44 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% import "lib/paramList.html" as params -%}
|
||||||
|
{% extends 'layout/base.template.html' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include "layout/_what-it-does.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_security-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_deprecated-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_how-to-use.html" %}
|
||||||
|
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Description</h2>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{%- if not doc.notYetDocumented %}{$ doc.description | trimBlankLines | marked $}{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if doc.metadataDoc and doc.metadataDoc.members.length %}
|
||||||
|
<div layout="row" layout-xs="column" class="metadata" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Metadata Properties</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{% for metadata in doc.metadataDoc.members %}{% if not metadata.internal %}
|
||||||
|
<a name="{$ metadata.name $}-anchor" class="anchor-offset"></a>
|
||||||
|
<pre class="prettyprint no-bg" ng-class="{ 'anchor-focused': appCtrl.isApiDocMemberFocused('{$ metadata.name $}') }">
|
||||||
|
<code class="api-doc-code">
|
||||||
|
{$ metadata.name $}{$ params.paramList(metadata.parameters) | indent(8, false) | trim $}{$ params.returnType(metadata.returnType) $}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
{%- if not metadata.notYetDocumented %}{$ metadata.description | replace('### Example', '') | replace('## Example', '') | replace('# Example', '') | trimBlankLines | marked $}{% endif -%}
|
||||||
|
{% if not loop.last %}<hr class="hr-margin">{% endif %}
|
||||||
|
{% endif %}{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p class="location-badge">
|
||||||
|
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} } defined in {$ github.githubViewLink(doc, versionInfo) $}
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,62 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% import "lib/paramList.html" as params -%}
|
||||||
|
{% extends 'class.template.html' -%}
|
||||||
|
|
||||||
|
{% block annotations %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block additional -%}
|
||||||
|
|
||||||
|
{%- if doc.directiveOptions.selector.split(',').length %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Selectors</h2>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
{% for selector in doc.directiveOptions.selector.split(',') %}
|
||||||
|
<p class="selector">
|
||||||
|
<code>{$ selector $}</code>
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if doc.outputs %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Outputs</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
{% for binding, property in doc.outputs %}
|
||||||
|
<div class="code-margin">
|
||||||
|
<code>{$ property.bindingName $} bound to </code>
|
||||||
|
<code>{$ property.memberDoc.classDoc.name $}.{$ property.propertyName $}</code
|
||||||
|
</div>
|
||||||
|
{$ property.memberDoc.description | trimBlankLines | marked $}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if doc.inputs %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Inputs</h2>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
{% for binding, property in doc.inputs %}
|
||||||
|
<div class="code-margin">
|
||||||
|
<code>{$ property.bindingName $} bound to </code>
|
||||||
|
<code>{$ property.memberDoc.classDoc.name $}.{$ property.propertyName $}</code>
|
||||||
|
{$ property.memberDoc.description | trimBlankLines | marked $}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{%- if doc.directiveOptions.exportAs %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Exported as</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
<p class="input">
|
||||||
|
<code>{$ doc.directiveOptions.exportAs $}</code>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1 @@
|
||||||
|
{% extends 'class.template.html' -%}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="code-example">
|
||||||
|
{% marked %}
|
||||||
|
```
|
||||||
|
{$ doc.contents $}
|
||||||
|
```
|
||||||
|
{% endmarked %}
|
||||||
|
</div>
|
|
@ -0,0 +1,31 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% import "lib/paramList.html" as params -%}
|
||||||
|
{% extends 'layout/base.template.html' -%}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include "layout/_what-it-does.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_security-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_deprecated-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_how-to-use.html" %}
|
||||||
|
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Class Export</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
<pre class="prettyprint no-bg">
|
||||||
|
<code>
|
||||||
|
export {$ doc.name $}{$ params.paramList(doc.parameters) | indent(8, true) | trim $}{$ params.returnType(doc.returnType) $}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
{%- if not doc.notYetDocumented %}{$ doc.description | trimBlankLines | marked $}{% endif %}
|
||||||
|
|
||||||
|
<p class="location-badge">
|
||||||
|
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} } defined in {$ github.githubViewLink(doc, versionInfo) $}
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,72 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% import "lib/paramList.html" as params -%}
|
||||||
|
{% extends 'layout/base.template.html' -%}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include "layout/_what-it-does.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_security-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_deprecated-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_how-to-use.html" %}
|
||||||
|
|
||||||
|
<div layout="row" layout-xs="column" class="ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Interface Overview</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
<code class="no-bg api-doc-code openParens">interface {$ doc.name $} {</code>
|
||||||
|
|
||||||
|
{% if doc.members.length %}
|
||||||
|
<div layout="column">
|
||||||
|
{% for member in doc.members %}{% if not member.internal %}
|
||||||
|
<pre class="prettyprint no-bg-with-indent">
|
||||||
|
<a class="code-anchor" href="#{$ member.name $}-anchor">
|
||||||
|
<code class="code-background api-doc-code">{$ member.name | indent(6, false) | trim $}</code>
|
||||||
|
<code class="api-doc-code">{$ params.paramList(member.parameters) | indent(8, false) | trim $}{$ params.returnType(member.returnType) $}</code>
|
||||||
|
</a>
|
||||||
|
</pre>
|
||||||
|
{% endif %}{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
<p class="selector endParens">
|
||||||
|
<code class="api-doc-code no-bg">}</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% block additional %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Interface Description</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{%- if doc.description.length > 2 %}{$ doc.description | trimBlankLines | marked $}{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if doc.members.length %}
|
||||||
|
<div layout="row" layout-xs="column" class="instance-members" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Interface Details</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{% for member in doc.members %}{% if not member.internal %}
|
||||||
|
<a name="{$ member.name $}-anchor" class="anchor-offset"></a>
|
||||||
|
<pre class="prettyprint no-bg" ng-class="{ 'anchor-focused': appCtrl.isApiDocMemberFocused('{$ member.name $}') }">
|
||||||
|
<code class="api-doc-code">
|
||||||
|
{$ member.name $}{$ params.paramList(member.parameters) | indent(8, false) | trim $}{$ params.returnType(member.returnType) $}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
{%- if not member.notYetDocumented %}{$ member.description | replace('### Example', '') | replace('## Example', '') | replace('# Example', '') | trimBlankLines | marked $}{% endif -%}
|
||||||
|
{% if not loop.last %}<hr class="hr-margin">{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p class="location-badge">
|
||||||
|
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} },
|
||||||
|
defined in {$ github.githubViewLink(doc, versionInfo) $}
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1 @@
|
||||||
|
{$ doc.data | json $}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{% if doc.showDeprecatedNotes %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Deprecation Notes</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
{%- if doc.deprecated %}{$ doc.deprecated | marked $}
|
||||||
|
{% else %}<em>Not yet documented</em>{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{%- if doc.howToUse %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">How to use</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
{$ doc.howToUse | marked $}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">NgModule</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{$ doc.ngModule $}
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,10 @@
|
||||||
|
{% if doc.showSecurityNotes and doc.security %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Security Risk</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
{$ doc.security | marked $}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{%- if doc.whatItDoes %}
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">What it does</h2>
|
||||||
|
</div>
|
||||||
|
<div flex="80" flex-xs="100">
|
||||||
|
{$ doc.whatItDoes | marked $}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
|
@ -0,0 +1 @@
|
||||||
|
{% block body %}{% endblock %}
|
|
@ -0,0 +1 @@
|
||||||
|
{% extends 'var.template.html' -%}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{% macro githubHref(doc, versionInfo) -%}
|
||||||
|
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/tree/{$ versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw $}/modules/{$ doc.fileInfo.projectRelativePath $}#L{$ doc.location.start.line+1 $}-L{$ doc.location.end.line+1 $}
|
||||||
|
{%- endmacro %}
|
||||||
|
|
||||||
|
{% macro githubViewLink(doc, versionInfo) -%}
|
||||||
|
<a href="{$ githubHref(doc, versionInfo) $}">{$ doc.fileInfo.projectRelativePath $}</a>
|
||||||
|
{%- endmacro %}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{% macro paramList(params) -%}
|
||||||
|
{%- if params -%}
|
||||||
|
({%- for param in params -%}
|
||||||
|
{$ param | escape $}{% if not loop.last %}, {% endif %}
|
||||||
|
{%- endfor %})
|
||||||
|
{%- endif %}
|
||||||
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
|
||||||
|
{% macro returnType(returnType) -%}
|
||||||
|
{%- if returnType %} : {$ returnType | escape $}{% endif -%}
|
||||||
|
{%- endmacro -%}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% extends 'layout/base.template.html' -%}
|
||||||
|
|
||||||
|
{% block body -%}
|
||||||
|
<p class="location-badge">defined in {$ github.githubViewLink(doc, versionInfo) $}</p>
|
||||||
|
<ul>
|
||||||
|
{% for page in doc.childPages -%}
|
||||||
|
<li>
|
||||||
|
<!-- TODO: convert to hovercard -->
|
||||||
|
<a href="{$ relativePath(doc.moduleFolder, page.exportDoc.path) $}">{$ page.title $}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,74 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% import "lib/paramList.html" as params -%}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
max-width: 1000px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-bottom: solid 1px black;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
padding-left: 30px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.not-documented::after {
|
||||||
|
content: "(not documented)";
|
||||||
|
font-size: small;
|
||||||
|
font-style: italic;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>Module Overview</h1>
|
||||||
|
|
||||||
|
{% for module in doc.modules %}
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<code>{$ module.id $}{%- if module.public %} (public){% endif %}</code>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
{% for export in module.exports %}
|
||||||
|
<h3 {% if export.notYetDocumented %}class="not-documented"{% endif %}>
|
||||||
|
<a href="{$ github.githubHref(export, versionInfo) $}">
|
||||||
|
<code>{$ export.docType $} {$ export.name $}</code>
|
||||||
|
</a>
|
||||||
|
</h3>
|
||||||
|
{%- if export.constructorDoc %}
|
||||||
|
<h4 {% if export.constructorDoc.notYetDocumented %}class="not-documented"{% endif %}>
|
||||||
|
<a href="{$ github.githubHref(export.constructorDoc, versionInfo) $}">
|
||||||
|
<code>{$ export.constructorDoc.name $}{$ params.paramList(export.constructorDoc.params) $}</code>
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
{% endif -%}
|
||||||
|
{%- for member in export.members %}
|
||||||
|
<h4 {% if member.notYetDocumented %}class="not-documented"{% endif %}>
|
||||||
|
<a href="{$ github.githubHref(member, versionInfo) $}">
|
||||||
|
<code>{$ member.name $}{$ params.paramList(member.params) $}</code>
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,30 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% import "lib/paramList.html" as params -%}
|
||||||
|
{% extends 'layout/base.template.html' -%}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include "layout/_what-it-does.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_security-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_deprecated-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_how-to-use.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_ng-module.html" %}
|
||||||
|
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Description</h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
{%- if doc.description.length > 2 %}{$ doc.description | trimBlankLines | marked $}{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="location-badge">
|
||||||
|
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }
|
||||||
|
defined in {$ github.githubViewLink(doc, versionInfo) $}
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1 @@
|
||||||
|
{% extends 'interface.template.html' %}
|
|
@ -0,0 +1,33 @@
|
||||||
|
{% import "lib/githubLinks.html" as github -%}
|
||||||
|
{% import "lib/paramList.html" as params -%}
|
||||||
|
{% extends 'layout/base.template.html' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include "layout/_what-it-does.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_security-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_deprecated-notes.html" %}
|
||||||
|
|
||||||
|
{% include "layout/_how-to-use.html" %}
|
||||||
|
|
||||||
|
<div layout="row" layout-xs="column" class="row-margin ng-cloak">
|
||||||
|
<div flex="20" flex-xs="100">
|
||||||
|
<h2 class="h2-api-docs">Variable Export<h2>
|
||||||
|
</div>
|
||||||
|
<div class="code-links" flex="80" flex-xs="100">
|
||||||
|
<pre class="prettyprint no-bg">
|
||||||
|
<code>
|
||||||
|
export {$ doc.name $}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
{%- if not doc.notYetDocumented %}{$ doc.description | trimBlankLines | marked $}{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="location-badge">
|
||||||
|
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }
|
||||||
|
defined in {$ github.githubViewLink(doc, versionInfo) $}
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
18
gulpfile.js
18
gulpfile.js
|
@ -252,6 +252,24 @@ gulp.task('changelog', () => {
|
||||||
.pipe(gulp.dest('./'));
|
.pipe(gulp.dest('./'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task('docs', ['doc-gen', 'docs-app']);
|
||||||
|
gulp.task('doc-gen', () => {
|
||||||
|
const Dgeni = require('dgeni');
|
||||||
|
const angularDocsPackage = require(path.resolve(__dirname, 'tools/docs/angular.io-package'));
|
||||||
|
const dgeni = new Dgeni([angularDocsPackage]);
|
||||||
|
return dgeni.generate();
|
||||||
|
});
|
||||||
|
gulp.task('docs-app', () => { gulp.src('docs/src/**/*').pipe(gulp.dest('dist/docs')); });
|
||||||
|
|
||||||
|
gulp.task('docs-test', ['doc-gen-test', 'docs-app-test']);
|
||||||
|
gulp.task('doc-gen-test', () => {
|
||||||
|
const execSync = require('child_process').execSync;
|
||||||
|
execSync(
|
||||||
|
'node dist/tools/cjs-jasmine/index-tools ../../tools/docs/**/*.spec.js',
|
||||||
|
{stdio: ['inherit', 'inherit', 'inherit']});
|
||||||
|
});
|
||||||
|
gulp.task('docs-app-test', () => {});
|
||||||
|
|
||||||
function tsc(projectPath, done) {
|
function tsc(projectPath, done) {
|
||||||
const childProcess = require('child_process');
|
const childProcess = require('child_process');
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Documentation Generation
|
||||||
|
|
||||||
|
The dgeni tool is used to generate the documentation from the source files held in this repository.
|
||||||
|
The documentation generation is configured by a dgeni package defined in `docs/angular.io-package/index.js`.
|
||||||
|
This package, in turn requires a number of other packages, some are defined locally in the `docs` folder,
|
||||||
|
such as `docs/cheatsheet-package` and `docs/content-package`, etc. And some are brought in from the
|
||||||
|
`dgeni-packages` node modules, such as `jsdoc` and `nunjucks`.
|
||||||
|
|
||||||
|
## Generating the docs
|
||||||
|
|
||||||
|
To generate the documentation simply run `gulp docs` from the command line.
|
||||||
|
|
||||||
|
## Testing the dgeni packages
|
||||||
|
|
||||||
|
The local packages have unit tests that you can execute by running `gulp docs-test` from the command line.
|
||||||
|
|
||||||
|
## What does it generate?
|
||||||
|
|
||||||
|
The output from dgeni is written to files in the `dist/docs` folder.
|
||||||
|
|
||||||
|
Notably this includes a partial HTML file for each "page" of the documentation, such as API pages and guides.
|
||||||
|
It also includes JavaScript files that contain metadata about the documentation such as navigation data and
|
||||||
|
keywords for building a search index.
|
||||||
|
|
||||||
|
## Viewing the docs
|
||||||
|
|
||||||
|
You can view the dummy demo app using a simple HTTP server hosting `dist/docs/index.html`
|
|
@ -0,0 +1,701 @@
|
||||||
|
a
|
||||||
|
able
|
||||||
|
about
|
||||||
|
above
|
||||||
|
abst
|
||||||
|
accordance
|
||||||
|
according
|
||||||
|
accordingly
|
||||||
|
across
|
||||||
|
act
|
||||||
|
actually
|
||||||
|
added
|
||||||
|
adj
|
||||||
|
adopted
|
||||||
|
affected
|
||||||
|
affecting
|
||||||
|
affects
|
||||||
|
after
|
||||||
|
afterwards
|
||||||
|
again
|
||||||
|
against
|
||||||
|
ah
|
||||||
|
all
|
||||||
|
almost
|
||||||
|
alone
|
||||||
|
along
|
||||||
|
already
|
||||||
|
also
|
||||||
|
although
|
||||||
|
always
|
||||||
|
am
|
||||||
|
among
|
||||||
|
amongst
|
||||||
|
an
|
||||||
|
and
|
||||||
|
announce
|
||||||
|
another
|
||||||
|
any
|
||||||
|
anybody
|
||||||
|
anyhow
|
||||||
|
anymore
|
||||||
|
anyone
|
||||||
|
anything
|
||||||
|
anyway
|
||||||
|
anyways
|
||||||
|
anywhere
|
||||||
|
apparently
|
||||||
|
approximately
|
||||||
|
are
|
||||||
|
aren
|
||||||
|
arent
|
||||||
|
arise
|
||||||
|
around
|
||||||
|
as
|
||||||
|
aside
|
||||||
|
ask
|
||||||
|
asking
|
||||||
|
at
|
||||||
|
auth
|
||||||
|
available
|
||||||
|
away
|
||||||
|
awfully
|
||||||
|
b
|
||||||
|
back
|
||||||
|
be
|
||||||
|
became
|
||||||
|
because
|
||||||
|
become
|
||||||
|
becomes
|
||||||
|
becoming
|
||||||
|
been
|
||||||
|
before
|
||||||
|
beforehand
|
||||||
|
begin
|
||||||
|
beginning
|
||||||
|
beginnings
|
||||||
|
begins
|
||||||
|
behind
|
||||||
|
being
|
||||||
|
believe
|
||||||
|
below
|
||||||
|
beside
|
||||||
|
besides
|
||||||
|
between
|
||||||
|
beyond
|
||||||
|
biol
|
||||||
|
both
|
||||||
|
brief
|
||||||
|
briefly
|
||||||
|
but
|
||||||
|
by
|
||||||
|
c
|
||||||
|
ca
|
||||||
|
came
|
||||||
|
can
|
||||||
|
cannot
|
||||||
|
can't
|
||||||
|
cant
|
||||||
|
cause
|
||||||
|
causes
|
||||||
|
certain
|
||||||
|
certainly
|
||||||
|
co
|
||||||
|
com
|
||||||
|
come
|
||||||
|
comes
|
||||||
|
contain
|
||||||
|
containing
|
||||||
|
contains
|
||||||
|
could
|
||||||
|
couldnt
|
||||||
|
d
|
||||||
|
date
|
||||||
|
did
|
||||||
|
didn't
|
||||||
|
didnt
|
||||||
|
different
|
||||||
|
do
|
||||||
|
does
|
||||||
|
doesn't
|
||||||
|
doesnt
|
||||||
|
doing
|
||||||
|
done
|
||||||
|
don't
|
||||||
|
dont
|
||||||
|
down
|
||||||
|
downwards
|
||||||
|
due
|
||||||
|
during
|
||||||
|
e
|
||||||
|
each
|
||||||
|
ed
|
||||||
|
edu
|
||||||
|
effect
|
||||||
|
eg
|
||||||
|
eight
|
||||||
|
eighty
|
||||||
|
either
|
||||||
|
else
|
||||||
|
elsewhere
|
||||||
|
end
|
||||||
|
ending
|
||||||
|
enough
|
||||||
|
especially
|
||||||
|
et
|
||||||
|
et-al
|
||||||
|
etc
|
||||||
|
even
|
||||||
|
ever
|
||||||
|
every
|
||||||
|
everybody
|
||||||
|
everyone
|
||||||
|
everything
|
||||||
|
everywhere
|
||||||
|
ex
|
||||||
|
except
|
||||||
|
f
|
||||||
|
far
|
||||||
|
few
|
||||||
|
ff
|
||||||
|
fifth
|
||||||
|
first
|
||||||
|
five
|
||||||
|
fix
|
||||||
|
followed
|
||||||
|
following
|
||||||
|
follows
|
||||||
|
for
|
||||||
|
former
|
||||||
|
formerly
|
||||||
|
forth
|
||||||
|
found
|
||||||
|
four
|
||||||
|
from
|
||||||
|
further
|
||||||
|
furthermore
|
||||||
|
g
|
||||||
|
gave
|
||||||
|
get
|
||||||
|
gets
|
||||||
|
getting
|
||||||
|
give
|
||||||
|
given
|
||||||
|
gives
|
||||||
|
giving
|
||||||
|
go
|
||||||
|
goes
|
||||||
|
gone
|
||||||
|
got
|
||||||
|
gotten
|
||||||
|
h
|
||||||
|
had
|
||||||
|
happens
|
||||||
|
hardly
|
||||||
|
has
|
||||||
|
hasn't
|
||||||
|
hasnt
|
||||||
|
have
|
||||||
|
haven't
|
||||||
|
havent
|
||||||
|
having
|
||||||
|
he
|
||||||
|
hed
|
||||||
|
hence
|
||||||
|
her
|
||||||
|
here
|
||||||
|
hereafter
|
||||||
|
hereby
|
||||||
|
herein
|
||||||
|
heres
|
||||||
|
hereupon
|
||||||
|
hers
|
||||||
|
herself
|
||||||
|
hes
|
||||||
|
hi
|
||||||
|
hid
|
||||||
|
him
|
||||||
|
himself
|
||||||
|
his
|
||||||
|
hither
|
||||||
|
home
|
||||||
|
how
|
||||||
|
howbeit
|
||||||
|
however
|
||||||
|
hundred
|
||||||
|
i
|
||||||
|
id
|
||||||
|
ie
|
||||||
|
if
|
||||||
|
i'll
|
||||||
|
ill
|
||||||
|
im
|
||||||
|
immediate
|
||||||
|
immediately
|
||||||
|
importance
|
||||||
|
important
|
||||||
|
in
|
||||||
|
inc
|
||||||
|
indeed
|
||||||
|
index
|
||||||
|
information
|
||||||
|
instead
|
||||||
|
into
|
||||||
|
invention
|
||||||
|
inward
|
||||||
|
is
|
||||||
|
isn't
|
||||||
|
isnt
|
||||||
|
it
|
||||||
|
itd
|
||||||
|
it'll
|
||||||
|
itll
|
||||||
|
its
|
||||||
|
itself
|
||||||
|
i've
|
||||||
|
ive
|
||||||
|
j
|
||||||
|
just
|
||||||
|
k
|
||||||
|
keep
|
||||||
|
keeps
|
||||||
|
kept
|
||||||
|
keys
|
||||||
|
kg
|
||||||
|
km
|
||||||
|
know
|
||||||
|
known
|
||||||
|
knows
|
||||||
|
l
|
||||||
|
largely
|
||||||
|
last
|
||||||
|
lately
|
||||||
|
later
|
||||||
|
latter
|
||||||
|
latterly
|
||||||
|
least
|
||||||
|
less
|
||||||
|
lest
|
||||||
|
let
|
||||||
|
lets
|
||||||
|
like
|
||||||
|
liked
|
||||||
|
likely
|
||||||
|
line
|
||||||
|
little
|
||||||
|
'll
|
||||||
|
'll
|
||||||
|
look
|
||||||
|
looking
|
||||||
|
looks
|
||||||
|
ltd
|
||||||
|
m
|
||||||
|
made
|
||||||
|
mainly
|
||||||
|
make
|
||||||
|
makes
|
||||||
|
many
|
||||||
|
may
|
||||||
|
maybe
|
||||||
|
me
|
||||||
|
mean
|
||||||
|
means
|
||||||
|
meantime
|
||||||
|
meanwhile
|
||||||
|
merely
|
||||||
|
mg
|
||||||
|
might
|
||||||
|
million
|
||||||
|
miss
|
||||||
|
ml
|
||||||
|
more
|
||||||
|
moreover
|
||||||
|
most
|
||||||
|
mostly
|
||||||
|
mr
|
||||||
|
mrs
|
||||||
|
much
|
||||||
|
mug
|
||||||
|
must
|
||||||
|
my
|
||||||
|
myself
|
||||||
|
n
|
||||||
|
na
|
||||||
|
name
|
||||||
|
namely
|
||||||
|
nay
|
||||||
|
nd
|
||||||
|
near
|
||||||
|
nearly
|
||||||
|
necessarily
|
||||||
|
necessary
|
||||||
|
need
|
||||||
|
needs
|
||||||
|
neither
|
||||||
|
never
|
||||||
|
nevertheless
|
||||||
|
new
|
||||||
|
next
|
||||||
|
nine
|
||||||
|
ninety
|
||||||
|
no
|
||||||
|
nobody
|
||||||
|
non
|
||||||
|
none
|
||||||
|
nonetheless
|
||||||
|
noone
|
||||||
|
nor
|
||||||
|
normally
|
||||||
|
nos
|
||||||
|
not
|
||||||
|
noted
|
||||||
|
nothing
|
||||||
|
now
|
||||||
|
nowhere
|
||||||
|
o
|
||||||
|
obtain
|
||||||
|
obtained
|
||||||
|
obviously
|
||||||
|
of
|
||||||
|
off
|
||||||
|
often
|
||||||
|
oh
|
||||||
|
ok
|
||||||
|
okay
|
||||||
|
old
|
||||||
|
omitted
|
||||||
|
on
|
||||||
|
once
|
||||||
|
one
|
||||||
|
ones
|
||||||
|
only
|
||||||
|
onto
|
||||||
|
or
|
||||||
|
ord
|
||||||
|
other
|
||||||
|
others
|
||||||
|
otherwise
|
||||||
|
ought
|
||||||
|
our
|
||||||
|
ours
|
||||||
|
ourselves
|
||||||
|
out
|
||||||
|
outside
|
||||||
|
over
|
||||||
|
overall
|
||||||
|
owing
|
||||||
|
own
|
||||||
|
p
|
||||||
|
page
|
||||||
|
pages
|
||||||
|
part
|
||||||
|
particular
|
||||||
|
particularly
|
||||||
|
past
|
||||||
|
per
|
||||||
|
perhaps
|
||||||
|
placed
|
||||||
|
please
|
||||||
|
plus
|
||||||
|
poorly
|
||||||
|
possible
|
||||||
|
possibly
|
||||||
|
potentially
|
||||||
|
pp
|
||||||
|
predominantly
|
||||||
|
present
|
||||||
|
previously
|
||||||
|
primarily
|
||||||
|
probably
|
||||||
|
promptly
|
||||||
|
proud
|
||||||
|
provides
|
||||||
|
put
|
||||||
|
q
|
||||||
|
que
|
||||||
|
quickly
|
||||||
|
quite
|
||||||
|
qv
|
||||||
|
r
|
||||||
|
ran
|
||||||
|
rather
|
||||||
|
rd
|
||||||
|
re
|
||||||
|
readily
|
||||||
|
really
|
||||||
|
recent
|
||||||
|
recently
|
||||||
|
ref
|
||||||
|
refs
|
||||||
|
regarding
|
||||||
|
regardless
|
||||||
|
regards
|
||||||
|
related
|
||||||
|
relatively
|
||||||
|
research
|
||||||
|
respectively
|
||||||
|
resulted
|
||||||
|
resulting
|
||||||
|
results
|
||||||
|
right
|
||||||
|
run
|
||||||
|
s
|
||||||
|
said
|
||||||
|
same
|
||||||
|
saw
|
||||||
|
say
|
||||||
|
saying
|
||||||
|
says
|
||||||
|
sec
|
||||||
|
section
|
||||||
|
see
|
||||||
|
seeing
|
||||||
|
seem
|
||||||
|
seemed
|
||||||
|
seeming
|
||||||
|
seems
|
||||||
|
seen
|
||||||
|
self
|
||||||
|
selves
|
||||||
|
sent
|
||||||
|
seven
|
||||||
|
several
|
||||||
|
shall
|
||||||
|
she
|
||||||
|
shed
|
||||||
|
she'll
|
||||||
|
shell
|
||||||
|
shes
|
||||||
|
should
|
||||||
|
shouldn't
|
||||||
|
shouldnt
|
||||||
|
show
|
||||||
|
showed
|
||||||
|
shown
|
||||||
|
showns
|
||||||
|
shows
|
||||||
|
significant
|
||||||
|
significantly
|
||||||
|
similar
|
||||||
|
similarly
|
||||||
|
since
|
||||||
|
six
|
||||||
|
slightly
|
||||||
|
so
|
||||||
|
some
|
||||||
|
somebody
|
||||||
|
somehow
|
||||||
|
someone
|
||||||
|
somethan
|
||||||
|
something
|
||||||
|
sometime
|
||||||
|
sometimes
|
||||||
|
somewhat
|
||||||
|
somewhere
|
||||||
|
soon
|
||||||
|
sorry
|
||||||
|
specifically
|
||||||
|
specified
|
||||||
|
specify
|
||||||
|
specifying
|
||||||
|
state
|
||||||
|
states
|
||||||
|
still
|
||||||
|
stop
|
||||||
|
strongly
|
||||||
|
sub
|
||||||
|
substantially
|
||||||
|
successfully
|
||||||
|
such
|
||||||
|
sufficiently
|
||||||
|
suggest
|
||||||
|
sup
|
||||||
|
sure
|
||||||
|
t
|
||||||
|
take
|
||||||
|
taken
|
||||||
|
taking
|
||||||
|
tell
|
||||||
|
tends
|
||||||
|
th
|
||||||
|
than
|
||||||
|
thank
|
||||||
|
thanks
|
||||||
|
thanx
|
||||||
|
that
|
||||||
|
that'll
|
||||||
|
thatll
|
||||||
|
thats
|
||||||
|
that've
|
||||||
|
thatve
|
||||||
|
the
|
||||||
|
their
|
||||||
|
theirs
|
||||||
|
them
|
||||||
|
themselves
|
||||||
|
then
|
||||||
|
thence
|
||||||
|
there
|
||||||
|
thereafter
|
||||||
|
thereby
|
||||||
|
thered
|
||||||
|
therefore
|
||||||
|
therein
|
||||||
|
there'll
|
||||||
|
therell
|
||||||
|
thereof
|
||||||
|
therere
|
||||||
|
theres
|
||||||
|
thereto
|
||||||
|
thereupon
|
||||||
|
there've
|
||||||
|
thereve
|
||||||
|
these
|
||||||
|
they
|
||||||
|
theyd
|
||||||
|
they'll
|
||||||
|
theyll
|
||||||
|
theyre
|
||||||
|
they've
|
||||||
|
theyve
|
||||||
|
think
|
||||||
|
this
|
||||||
|
those
|
||||||
|
thou
|
||||||
|
though
|
||||||
|
thoughh
|
||||||
|
thousand
|
||||||
|
throug
|
||||||
|
through
|
||||||
|
throughout
|
||||||
|
thru
|
||||||
|
thus
|
||||||
|
til
|
||||||
|
tip
|
||||||
|
to
|
||||||
|
together
|
||||||
|
too
|
||||||
|
took
|
||||||
|
toward
|
||||||
|
towards
|
||||||
|
tried
|
||||||
|
tries
|
||||||
|
truly
|
||||||
|
try
|
||||||
|
trying
|
||||||
|
ts
|
||||||
|
twice
|
||||||
|
two
|
||||||
|
u
|
||||||
|
un
|
||||||
|
under
|
||||||
|
unfortunately
|
||||||
|
unless
|
||||||
|
unlike
|
||||||
|
unlikely
|
||||||
|
until
|
||||||
|
unto
|
||||||
|
up
|
||||||
|
upon
|
||||||
|
ups
|
||||||
|
us
|
||||||
|
use
|
||||||
|
used
|
||||||
|
useful
|
||||||
|
usefully
|
||||||
|
usefulness
|
||||||
|
uses
|
||||||
|
using
|
||||||
|
usually
|
||||||
|
v
|
||||||
|
value
|
||||||
|
various
|
||||||
|
've
|
||||||
|
've
|
||||||
|
very
|
||||||
|
via
|
||||||
|
viz
|
||||||
|
vol
|
||||||
|
vols
|
||||||
|
vs
|
||||||
|
w
|
||||||
|
want
|
||||||
|
wants
|
||||||
|
was
|
||||||
|
wasn't
|
||||||
|
wasnt
|
||||||
|
way
|
||||||
|
we
|
||||||
|
wed
|
||||||
|
welcome
|
||||||
|
we'll
|
||||||
|
well
|
||||||
|
went
|
||||||
|
were
|
||||||
|
weren't
|
||||||
|
werent
|
||||||
|
we've
|
||||||
|
weve
|
||||||
|
what
|
||||||
|
whatever
|
||||||
|
what'll
|
||||||
|
whatll
|
||||||
|
whats
|
||||||
|
when
|
||||||
|
whence
|
||||||
|
whenever
|
||||||
|
where
|
||||||
|
whereafter
|
||||||
|
whereas
|
||||||
|
whereby
|
||||||
|
wherein
|
||||||
|
wheres
|
||||||
|
whereupon
|
||||||
|
wherever
|
||||||
|
whether
|
||||||
|
which
|
||||||
|
while
|
||||||
|
whim
|
||||||
|
whither
|
||||||
|
who
|
||||||
|
whod
|
||||||
|
whoever
|
||||||
|
whole
|
||||||
|
who'll
|
||||||
|
wholl
|
||||||
|
whom
|
||||||
|
whomever
|
||||||
|
whos
|
||||||
|
whose
|
||||||
|
why
|
||||||
|
widely
|
||||||
|
will
|
||||||
|
willing
|
||||||
|
wish
|
||||||
|
with
|
||||||
|
within
|
||||||
|
without
|
||||||
|
won't
|
||||||
|
wont
|
||||||
|
words
|
||||||
|
would
|
||||||
|
wouldn't
|
||||||
|
wouldnt
|
||||||
|
www
|
||||||
|
x
|
||||||
|
y
|
||||||
|
yes
|
||||||
|
yet
|
||||||
|
you
|
||||||
|
youd
|
||||||
|
you'll
|
||||||
|
youll
|
||||||
|
your
|
||||||
|
youre
|
||||||
|
yours
|
||||||
|
yourself
|
||||||
|
yourselves
|
||||||
|
you've
|
||||||
|
youve
|
||||||
|
z
|
||||||
|
zero
|
|
@ -0,0 +1,223 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 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 https://angular.io/license
|
||||||
|
*/
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const Package = require('dgeni').Package;
|
||||||
|
|
||||||
|
const jsdocPackage = require('dgeni-packages/jsdoc');
|
||||||
|
const nunjucksPackage = require('dgeni-packages/nunjucks');
|
||||||
|
const typescriptPackage = require('dgeni-packages/typescript');
|
||||||
|
const gitPackage = require('dgeni-packages/git');
|
||||||
|
const linksPackage = require('../links-package');
|
||||||
|
const examplesPackage = require('../examples-package');
|
||||||
|
const targetPackage = require('../target-package');
|
||||||
|
const cheatsheetPackage = require('../cheatsheet-package');
|
||||||
|
|
||||||
|
const PROJECT_ROOT = path.resolve(__dirname, '../../..');
|
||||||
|
const API_SOURCE_PATH = path.resolve(PROJECT_ROOT, 'modules');
|
||||||
|
const CONTENTS_PATH = path.resolve(PROJECT_ROOT, 'docs/content');
|
||||||
|
const TEMPLATES_PATH = path.resolve(PROJECT_ROOT, 'docs/templates');
|
||||||
|
|
||||||
|
module.exports =
|
||||||
|
new Package(
|
||||||
|
'angular.io',
|
||||||
|
[
|
||||||
|
jsdocPackage, nunjucksPackage, typescriptPackage, linksPackage, examplesPackage,
|
||||||
|
gitPackage, targetPackage, cheatsheetPackage
|
||||||
|
])
|
||||||
|
|
||||||
|
// Register the processors
|
||||||
|
.processor(require('./processors/convertPrivateClassesToInterfaces'))
|
||||||
|
.processor(require('./processors/generateNavigationDoc'))
|
||||||
|
.processor(require('./processors/generateKeywords'))
|
||||||
|
.processor(require('./processors/extractTitleFromGuides'))
|
||||||
|
.processor(require('./processors/createOverviewDump'))
|
||||||
|
.processor(require('./processors/checkUnbalancedBackTicks'))
|
||||||
|
.processor(require('./processors/addNotYetDocumentedProperty'))
|
||||||
|
.processor(require('./processors/mergeDecoratorDocs'))
|
||||||
|
.processor(require('./processors/extractDecoratedClasses'))
|
||||||
|
.processor(require('./processors/matchUpDirectiveDecorators'))
|
||||||
|
.processor(require('./processors/filterMemberDocs'))
|
||||||
|
|
||||||
|
.config(function(checkAnchorLinksProcessor, log) {
|
||||||
|
// TODO: re-enable
|
||||||
|
checkAnchorLinksProcessor.$enabled = false;
|
||||||
|
})
|
||||||
|
|
||||||
|
// Where do we get the source files?
|
||||||
|
.config(function(
|
||||||
|
readTypeScriptModules, readFilesProcessor, collectExamples, generateKeywordsProcessor) {
|
||||||
|
|
||||||
|
// API files are typescript
|
||||||
|
readTypeScriptModules.basePath = API_SOURCE_PATH;
|
||||||
|
readTypeScriptModules.ignoreExportsMatching = [/^_/];
|
||||||
|
readTypeScriptModules.hidePrivateMembers = true;
|
||||||
|
readTypeScriptModules.sourceFiles = [
|
||||||
|
'@angular/common/index.ts',
|
||||||
|
'@angular/common/testing/index.ts',
|
||||||
|
'@angular/core/index.ts',
|
||||||
|
'@angular/core/testing/index.ts',
|
||||||
|
'@angular/forms/index.ts',
|
||||||
|
'@angular/http/index.ts',
|
||||||
|
'@angular/http/testing/index.ts',
|
||||||
|
'@angular/platform-browser/index.ts',
|
||||||
|
'@angular/platform-browser/testing/index.ts',
|
||||||
|
'@angular/platform-browser-dynamic/index.ts',
|
||||||
|
'@angular/platform-browser-dynamic/testing/index.ts',
|
||||||
|
'@angular/platform-server/index.ts',
|
||||||
|
'@angular/platform-server/testing/index.ts',
|
||||||
|
'@angular/platform-webworker/index.ts',
|
||||||
|
'@angular/platform-webworker-dynamic/index.ts',
|
||||||
|
'@angular/router/index.ts',
|
||||||
|
'@angular/router/testing/index.ts',
|
||||||
|
'@angular/upgrade/index.ts',
|
||||||
|
'@angular/upgrade/static.ts',
|
||||||
|
];
|
||||||
|
|
||||||
|
readFilesProcessor.basePath = PROJECT_ROOT;
|
||||||
|
readFilesProcessor.sourceFiles = [
|
||||||
|
{basePath: CONTENTS_PATH, include: CONTENTS_PATH + '/cheatsheet/*.md'}, {
|
||||||
|
basePath: API_SOURCE_PATH,
|
||||||
|
include: API_SOURCE_PATH + '/@angular/examples/**/*',
|
||||||
|
fileReader: 'exampleFileReader'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
collectExamples.exampleFolders = ['@angular/examples'];
|
||||||
|
|
||||||
|
generateKeywordsProcessor.ignoreWordsFile = 'tools/docs/angular.io-package/ignore.words';
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Where do we write the output files?
|
||||||
|
.config(function(writeFilesProcessor) { writeFilesProcessor.outputFolder = 'dist/docs'; })
|
||||||
|
|
||||||
|
|
||||||
|
// Target environments
|
||||||
|
.config(function(targetEnvironments) {
|
||||||
|
const ALLOWED_LANGUAGES = ['ts', 'js', 'dart'];
|
||||||
|
const TARGET_LANGUAGE = 'ts';
|
||||||
|
|
||||||
|
ALLOWED_LANGUAGES.forEach(target => targetEnvironments.addAllowed(target));
|
||||||
|
targetEnvironments.activate(TARGET_LANGUAGE);
|
||||||
|
|
||||||
|
// TODO: we may need to do something with `linkDocsInlineTagDef`
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// Configure jsdoc-style tag parsing
|
||||||
|
.config(function(parseTagsProcessor, getInjectables) {
|
||||||
|
// Load up all the tag definitions in the tag-defs folder
|
||||||
|
parseTagsProcessor.tagDefinitions =
|
||||||
|
parseTagsProcessor.tagDefinitions.concat(getInjectables(requireFolder('./tag-defs')));
|
||||||
|
|
||||||
|
// We actually don't want to parse param docs in this package as we are getting the data
|
||||||
|
// out using TS
|
||||||
|
// TODO: rewire the param docs to the params extracted from TS
|
||||||
|
parseTagsProcessor.tagDefinitions.forEach(function(tagDef) {
|
||||||
|
if (tagDef.name === 'param') {
|
||||||
|
tagDef.docProperty = 'paramData';
|
||||||
|
tagDef.transforms = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Configure nunjucks rendering of docs via templates
|
||||||
|
.config(function(
|
||||||
|
renderDocsProcessor, versionInfo, templateFinder, templateEngine, getInjectables) {
|
||||||
|
|
||||||
|
// Where to find the templates for the doc rendering
|
||||||
|
templateFinder.templateFolders = [TEMPLATES_PATH];
|
||||||
|
// templateFinder.templateFolders.unshift(TEMPLATES_PATH);
|
||||||
|
|
||||||
|
// Standard patterns for matching docs to templates
|
||||||
|
templateFinder.templatePatterns = [
|
||||||
|
'${ doc.template }', '${ doc.id }.${ doc.docType }.template.html',
|
||||||
|
'${ doc.id }.template.html', '${ doc.docType }.template.html',
|
||||||
|
'${ doc.id }.${ doc.docType }.template.js', '${ doc.id }.template.js',
|
||||||
|
'${ doc.docType }.template.js', '${ doc.id }.${ doc.docType }.template.json',
|
||||||
|
'${ doc.id }.template.json', '${ doc.docType }.template.json', 'common.template.html'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Nunjucks and Angular conflict in their template bindings so change Nunjucks
|
||||||
|
templateEngine.config.tags = {variableStart: '{$', variableEnd: '$}'};
|
||||||
|
|
||||||
|
templateEngine.filters =
|
||||||
|
templateEngine.filters.concat(getInjectables(requireFolder('./rendering')));
|
||||||
|
|
||||||
|
// Add the version data to the renderer, for use in things like github links
|
||||||
|
renderDocsProcessor.extraData.versionInfo = versionInfo;
|
||||||
|
|
||||||
|
// helpers are made available to the nunjucks templates
|
||||||
|
renderDocsProcessor.helpers.relativePath = function(from, to) {
|
||||||
|
return path.relative(from, to);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// We are going to be relaxed about ambigous links
|
||||||
|
.config(function(getLinkInfo) {
|
||||||
|
getLinkInfo.useFirstAmbiguousLink = false;
|
||||||
|
// TODO: I think we don't need this for Igor's shell app
|
||||||
|
// getLinkInfo.relativeLinks = true;
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.config(function(
|
||||||
|
computeIdsProcessor, computePathsProcessor, EXPORT_DOC_TYPES, generateNavigationDoc,
|
||||||
|
generateKeywordsProcessor) {
|
||||||
|
|
||||||
|
const API_SEGMENT = 'api';
|
||||||
|
const GUIDE_SEGMENT = 'guide';
|
||||||
|
const APP_SEGMENT = 'app';
|
||||||
|
|
||||||
|
generateNavigationDoc.outputFolder = APP_SEGMENT;
|
||||||
|
generateKeywordsProcessor.outputFolder = APP_SEGMENT;
|
||||||
|
|
||||||
|
// Replace any path templates inherited from other packages
|
||||||
|
// (we want full and transparent control)
|
||||||
|
computePathsProcessor.pathTemplates = [
|
||||||
|
{
|
||||||
|
docTypes: ['module'],
|
||||||
|
getPath: function computeModulePath(doc) {
|
||||||
|
doc.moduleFolder =
|
||||||
|
doc.id.replace(/^@angular\//, API_SEGMENT + '/').replace(/\/index$/, '');
|
||||||
|
return doc.moduleFolder;
|
||||||
|
},
|
||||||
|
outputPathTemplate: '${moduleFolder}/index.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
docTypes: EXPORT_DOC_TYPES.concat(['decorator', 'directive', 'pipe']),
|
||||||
|
pathTemplate: '${moduleDoc.moduleFolder}/${name}',
|
||||||
|
outputPathTemplate: '${moduleDoc.moduleFolder}/${name}.html',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
docTypes: ['api-list-data', 'api-list-audit'],
|
||||||
|
pathTemplate: APP_SEGMENT + '/${docType}.json',
|
||||||
|
outputPathTemplate: '${path}'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
docTypes: ['cheatsheet-data'],
|
||||||
|
pathTemplate: GUIDE_SEGMENT + '/cheatsheet.json',
|
||||||
|
outputPathTemplate: '${path}'
|
||||||
|
},
|
||||||
|
{docTypes: ['example-region'], getOutputPath: function() {}}
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
function requireFolder(folderPath) {
|
||||||
|
const absolutePath = path.resolve(__dirname, folderPath);
|
||||||
|
return fs.readdirSync(absolutePath)
|
||||||
|
.filter(p => !/[._]spec\.js$/.test(p)) // ignore spec files
|
||||||
|
.map(p => require(path.resolve(absolutePath, p)));
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 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 https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const x = 100;
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 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 https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @module
|
||||||
|
* @description
|
||||||
|
* This is the module description
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './importedSrc';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is some random other comment
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is MyClass
|
||||||
|
*/
|
||||||
|
export class MyClass {
|
||||||
|
message: String;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MyClass
|
||||||
|
* @param {String} name The name to say hello to
|
||||||
|
*/
|
||||||
|
constructor(name) { this.message = 'hello ' + name; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a greeting message
|
||||||
|
*/
|
||||||
|
greet() { return this.message; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exported function
|
||||||
|
*/
|
||||||
|
export const myFn = (val: number) => val * 2;
|
|
@ -0,0 +1,37 @@
|
||||||
|
module.exports = function addNotYetDocumentedProperty(EXPORT_DOC_TYPES, log, createDocMessage) {
|
||||||
|
return {
|
||||||
|
$runAfter: ['tags-parsed'],
|
||||||
|
$runBefore: ['rendering-docs'],
|
||||||
|
$process: function(docs) {
|
||||||
|
docs.forEach(function(doc) {
|
||||||
|
|
||||||
|
if (EXPORT_DOC_TYPES.indexOf(doc.docType) === -1) return;
|
||||||
|
|
||||||
|
// NotYetDocumented means that no top level comments and no member level comments
|
||||||
|
doc.notYetDocumented = notYetDocumented(doc);
|
||||||
|
|
||||||
|
if (doc.constructorDoc) {
|
||||||
|
doc.constructorDoc.notYetDocumented = notYetDocumented(doc.constructorDoc);
|
||||||
|
doc.notYetDocumented = doc.notYetDocumented && doc.constructorDoc.notYetDocumented;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc.members) {
|
||||||
|
doc.members.forEach(function(member) {
|
||||||
|
member.notYetDocumented = notYetDocumented(member);
|
||||||
|
doc.notYetDocumented = doc.notYetDocumented && member.notYetDocumented;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc.notYetDocumented) {
|
||||||
|
log.debug(createDocMessage('Not yet documented', doc));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return docs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function notYetDocumented(doc) {
|
||||||
|
return !doc.noDescription && doc.description.trim().length == 0;
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
var testPackage = require('../../helpers/test-package');
|
||||||
|
var Dgeni = require('dgeni');
|
||||||
|
|
||||||
|
describe('addNotYetDocumentedProperty', function() {
|
||||||
|
var dgeni, injector, processor, log;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
dgeni = new Dgeni([testPackage('angular.io-package')]);
|
||||||
|
injector = dgeni.configureInjector();
|
||||||
|
processor = injector.get('addNotYetDocumentedProperty');
|
||||||
|
log = injector.get('log');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mark export docs with no description as "not yet documented"', function() {
|
||||||
|
var a, b, c, d, a1, b1, c1, d1;
|
||||||
|
var docs = [
|
||||||
|
a = {id: 'a', docType: 'interface', description: 'some content'},
|
||||||
|
b = {id: 'b', docType: 'class', description: 'some content'},
|
||||||
|
c = {id: 'c', docType: 'var', description: 'some content'},
|
||||||
|
d = {id: 'd', docType: 'function', description: 'some content'},
|
||||||
|
a1 = {id: 'a1', docType: 'interface', description: ''},
|
||||||
|
b1 = {id: 'b1', docType: 'class', description: ''},
|
||||||
|
c1 = {id: 'c1', docType: 'var', description: ''},
|
||||||
|
d1 = {id: 'd1', docType: 'function', description: ''}
|
||||||
|
];
|
||||||
|
|
||||||
|
processor.$process(docs);
|
||||||
|
|
||||||
|
expect(a.notYetDocumented).toBeFalsy();
|
||||||
|
expect(b.notYetDocumented).toBeFalsy();
|
||||||
|
expect(c.notYetDocumented).toBeFalsy();
|
||||||
|
expect(d.notYetDocumented).toBeFalsy();
|
||||||
|
|
||||||
|
expect(a1.notYetDocumented).toBeTruthy();
|
||||||
|
expect(b1.notYetDocumented).toBeTruthy();
|
||||||
|
expect(c1.notYetDocumented).toBeTruthy();
|
||||||
|
expect(d1.notYetDocumented).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mark member docs with no description as "not yet documented"', function() {
|
||||||
|
var a, a1, a2, b, b1, b2, c, c1, c2;
|
||||||
|
var docs = [
|
||||||
|
a = {
|
||||||
|
id: 'a',
|
||||||
|
docType: 'interface',
|
||||||
|
description: 'some content',
|
||||||
|
members: [a1 = {id: 'a1', description: 'some content'}, a2 = {id: 'a2', description: ''}]
|
||||||
|
},
|
||||||
|
b = {
|
||||||
|
id: 'b',
|
||||||
|
docType: 'class',
|
||||||
|
description: '',
|
||||||
|
members: [b1 = {id: 'b1', description: 'some content'}, b2 = {id: 'b2', description: ''}]
|
||||||
|
},
|
||||||
|
c = {
|
||||||
|
id: 'c',
|
||||||
|
docType: 'class',
|
||||||
|
description: '',
|
||||||
|
members: [c1 = {id: 'c1', description: ''}, c2 = {id: 'c2', description: ''}]
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
processor.$process(docs);
|
||||||
|
|
||||||
|
expect(a.notYetDocumented).toBeFalsy();
|
||||||
|
expect(b.notYetDocumented).toBeFalsy();
|
||||||
|
expect(c.notYetDocumented).toBeTruthy();
|
||||||
|
|
||||||
|
expect(a1.notYetDocumented).toBeFalsy();
|
||||||
|
expect(a2.notYetDocumented).toBeTruthy();
|
||||||
|
expect(b1.notYetDocumented).toBeFalsy();
|
||||||
|
expect(b2.notYetDocumented).toBeTruthy();
|
||||||
|
expect(c1.notYetDocumented).toBeTruthy();
|
||||||
|
expect(c2.notYetDocumented).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should mark constructor doc with no description as "not yet documented"', function() {
|
||||||
|
var a, a1, b, b1;
|
||||||
|
var docs = [
|
||||||
|
a = {
|
||||||
|
id: 'a',
|
||||||
|
docType: 'interface',
|
||||||
|
description: '',
|
||||||
|
constructorDoc: a1 = {id: 'a1', description: 'some content'}
|
||||||
|
},
|
||||||
|
b = {
|
||||||
|
id: 'b',
|
||||||
|
docType: 'interface',
|
||||||
|
description: '',
|
||||||
|
constructorDoc: b1 = {id: 'b1', description: ''}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
processor.$process(docs);
|
||||||
|
|
||||||
|
expect(a.notYetDocumented).toBeFalsy();
|
||||||
|
expect(b.notYetDocumented).toBeTruthy();
|
||||||
|
|
||||||
|
expect(a1.notYetDocumented).toBeFalsy();
|
||||||
|
expect(b1.notYetDocumented).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should not mark documents explicity tagged as `@noDescription`', function() {
|
||||||
|
var a, a1, a2, b, b1, b2, c, c1, c2;
|
||||||
|
var docs = [
|
||||||
|
a = {
|
||||||
|
id: 'a',
|
||||||
|
docType: 'interface',
|
||||||
|
description: 'some content',
|
||||||
|
members: [
|
||||||
|
a1 = {id: 'a1', description: 'some content'},
|
||||||
|
a2 = {id: 'a2', description: '', noDescription: true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
b = {
|
||||||
|
id: 'b',
|
||||||
|
docType: 'class',
|
||||||
|
description: '',
|
||||||
|
members: [
|
||||||
|
b1 = {id: 'b1', description: 'some content'},
|
||||||
|
b2 = {id: 'b2', description: '', noDescription: true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
c = {
|
||||||
|
id: 'c',
|
||||||
|
docType: 'class',
|
||||||
|
description: '',
|
||||||
|
noDescription: true,
|
||||||
|
members: [c1 = {id: 'c1', description: ''}, c2 = {id: 'c2', description: ''}]
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
processor.$process(docs);
|
||||||
|
|
||||||
|
expect(a.notYetDocumented).toBeFalsy();
|
||||||
|
expect(b.notYetDocumented).toBeFalsy();
|
||||||
|
expect(c.notYetDocumented).toBeFalsy();
|
||||||
|
|
||||||
|
expect(a1.notYetDocumented).toBeFalsy();
|
||||||
|
expect(a2.notYetDocumented).toBeFalsy();
|
||||||
|
expect(b1.notYetDocumented).toBeFalsy();
|
||||||
|
expect(b2.notYetDocumented).toBeFalsy();
|
||||||
|
expect(c1.notYetDocumented).toBeTruthy();
|
||||||
|
expect(c2.notYetDocumented).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,33 @@
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dgProcessor checkUnbalancedBackTicks
|
||||||
|
* @description
|
||||||
|
* Searches the rendered content for an odd number of (```) backticks,
|
||||||
|
* which would indicate an unbalanced pair and potentially a typo in the
|
||||||
|
* source content.
|
||||||
|
*/
|
||||||
|
module.exports = function checkUnbalancedBackTicks(log, createDocMessage) {
|
||||||
|
|
||||||
|
var BACKTICK_REGEX = /^ *```/gm;
|
||||||
|
|
||||||
|
return {
|
||||||
|
// $runAfter: ['checkAnchorLinksProcessor'],
|
||||||
|
$runAfter: ['inlineTagProcessor'],
|
||||||
|
$runBefore: ['writeFilesProcessor'],
|
||||||
|
$process: function(docs) {
|
||||||
|
_.forEach(docs, function(doc) {
|
||||||
|
if (doc.renderedContent) {
|
||||||
|
var matches = doc.renderedContent.match(BACKTICK_REGEX);
|
||||||
|
if (matches && matches.length % 2 !== 0) {
|
||||||
|
doc.unbalancedBackTicks = true;
|
||||||
|
log.warn(createDocMessage(
|
||||||
|
'checkUnbalancedBackTicks processor: unbalanced backticks found in rendered content',
|
||||||
|
doc));
|
||||||
|
log.warn(doc.renderedContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
var testPackage = require('../../helpers/test-package');
|
||||||
|
var Dgeni = require('dgeni');
|
||||||
|
var path = require('canonical-path');
|
||||||
|
|
||||||
|
describe('checkUnbalancedBackTicks', function() {
|
||||||
|
var dgeni, injector, processor, log;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
dgeni = new Dgeni([testPackage('angular.io-package')]);
|
||||||
|
injector = dgeni.configureInjector();
|
||||||
|
processor = injector.get('checkUnbalancedBackTicks');
|
||||||
|
log = injector.get('log');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should warn if there are an odd number of back ticks in the rendered content', function() {
|
||||||
|
var docs = [{
|
||||||
|
renderedContent: '```\n' +
|
||||||
|
'code block\n' +
|
||||||
|
'```\n' +
|
||||||
|
'```\n' +
|
||||||
|
'code block with missing closing back ticks\n'
|
||||||
|
}];
|
||||||
|
|
||||||
|
processor.$process(docs);
|
||||||
|
|
||||||
|
expect(log.warn).toHaveBeenCalledWith(
|
||||||
|
'checkUnbalancedBackTicks processor: unbalanced backticks found in rendered content - doc');
|
||||||
|
expect(docs[0].unbalancedBackTicks).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
module.exports = function convertPrivateClassesToInterfacesProcessor(
|
||||||
|
convertPrivateClassesToInterfaces) {
|
||||||
|
return {
|
||||||
|
$runAfter: ['processing-docs'],
|
||||||
|
$runBefore: ['docs-processed'],
|
||||||
|
$process: function(docs) {
|
||||||
|
convertPrivateClassesToInterfaces(docs, false);
|
||||||
|
return docs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function createOverviewDump() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
$runAfter: ['processing-docs'],
|
||||||
|
$runBefore: ['docs-processed'],
|
||||||
|
$process: function(docs) {
|
||||||
|
var overviewDoc = {
|
||||||
|
id: 'overview-dump',
|
||||||
|
aliases: ['overview-dump'],
|
||||||
|
path: 'overview-dump',
|
||||||
|
outputPath: 'overview-dump.html',
|
||||||
|
modules: []
|
||||||
|
};
|
||||||
|
_.forEach(docs, function(doc) {
|
||||||
|
if (doc.docType === 'module') {
|
||||||
|
overviewDoc.modules.push(doc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
docs.push(overviewDoc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function extractDecoratedClassesProcessor(EXPORT_DOC_TYPES) {
|
||||||
|
|
||||||
|
// Add the "directive" docType into those that can be exported from a module
|
||||||
|
EXPORT_DOC_TYPES.push('directive', 'pipe');
|
||||||
|
|
||||||
|
return {
|
||||||
|
$runAfter: ['processing-docs'],
|
||||||
|
$runBefore: ['docs-processed'],
|
||||||
|
decoratorTypes: ['Directive', 'Component', 'Pipe'],
|
||||||
|
$process: function(docs) {
|
||||||
|
var decoratorTypes = this.decoratorTypes;
|
||||||
|
|
||||||
|
_.forEach(docs, function(doc) {
|
||||||
|
|
||||||
|
_.forEach(doc.decorators, function(decorator) {
|
||||||
|
|
||||||
|
if (decoratorTypes.indexOf(decorator.name) !== -1) {
|
||||||
|
doc.docType = decorator.name.toLowerCase();
|
||||||
|
doc[doc.docType + 'Options'] = decorator.argumentInfo[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return docs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,48 @@
|
||||||
|
var testPackage = require('../../helpers/test-package');
|
||||||
|
var Dgeni = require('dgeni');
|
||||||
|
|
||||||
|
describe('extractDecoratedClasses processor', function() {
|
||||||
|
var dgeni, injector, processor;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
dgeni = new Dgeni([testPackage('angular.io-package')]);
|
||||||
|
injector = dgeni.configureInjector();
|
||||||
|
processor = injector.get('extractDecoratedClassesProcessor');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should extract specified decorator arguments', function() {
|
||||||
|
var doc1 = {
|
||||||
|
id: '@angular/common/ngFor',
|
||||||
|
name: 'ngFor',
|
||||||
|
docType: 'class',
|
||||||
|
decorators: [{
|
||||||
|
name: 'Directive',
|
||||||
|
arguments: ['{selector: \'[ng-for][ng-for-of]\', properties: [\'ngForOf\']}'],
|
||||||
|
argumentInfo: [{selector: '[ng-for][ng-for-of]', properties: ['ngForOf']}]
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
var doc2 = {
|
||||||
|
id: '@angular/core/DecimalPipe',
|
||||||
|
name: 'DecimalPipe',
|
||||||
|
docType: 'class',
|
||||||
|
decorators:
|
||||||
|
[{name: 'Pipe', arguments: ['{name: \'number\'}'], argumentInfo: [{name: 'number'}]}]
|
||||||
|
};
|
||||||
|
|
||||||
|
processor.$process([doc1, doc2]);
|
||||||
|
|
||||||
|
expect(doc1).toEqual(jasmine.objectContaining({
|
||||||
|
id: '@angular/common/ngFor',
|
||||||
|
name: 'ngFor',
|
||||||
|
docType: 'directive',
|
||||||
|
directiveOptions: {selector: '[ng-for][ng-for-of]', properties: ['ngForOf']}
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(doc2).toEqual(jasmine.objectContaining({
|
||||||
|
id: '@angular/core/DecimalPipe',
|
||||||
|
name: 'DecimalPipe',
|
||||||
|
docType: 'pipe',
|
||||||
|
pipeOptions: {name: 'number'}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,24 @@
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function extractTitleFromGuides() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
$runAfter: ['processing-docs'],
|
||||||
|
$runBefore: ['docs-processed'],
|
||||||
|
$process: function(docs) {
|
||||||
|
_(docs).forEach(function(doc) {
|
||||||
|
if (doc.docType === 'guide') {
|
||||||
|
doc.name = doc.name || getNameFromHeading(doc.description);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function getNameFromHeading(text) {
|
||||||
|
var match = /^\s*#\s*(.*)/.exec(text);
|
||||||
|
if (match) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
module.exports = function filterMemberDocs() {
|
||||||
|
return {
|
||||||
|
$runAfter: ['extra-docs-added'], $runBefore: ['computing-paths'], $process: function(docs) {
|
||||||
|
return docs.filter(function(doc) { return doc.docType !== 'member'; });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,139 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('canonical-path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dgProcessor generateKeywordsProcessor
|
||||||
|
* @description
|
||||||
|
* This processor extracts all the keywords from each document and creates
|
||||||
|
* a new document that will be rendered as a JavaScript file containing all
|
||||||
|
* this data.
|
||||||
|
*/
|
||||||
|
module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
|
||||||
|
return {
|
||||||
|
ignoreWordsFile: undefined,
|
||||||
|
propertiesToIgnore: [],
|
||||||
|
docTypesToIgnore: [],
|
||||||
|
outputFolder: '',
|
||||||
|
$validate: {
|
||||||
|
ignoreWordsFile: {},
|
||||||
|
docTypesToIgnore: {},
|
||||||
|
propertiesToIgnore: {},
|
||||||
|
outputFolder: {presence: true}
|
||||||
|
},
|
||||||
|
$runAfter: ['paths-computed'],
|
||||||
|
$runBefore: ['rendering-docs'],
|
||||||
|
$process: function(docs) {
|
||||||
|
|
||||||
|
// Keywords to ignore
|
||||||
|
var wordsToIgnore = [];
|
||||||
|
var propertiesToIgnore;
|
||||||
|
var docTypesToIgnore;
|
||||||
|
|
||||||
|
// Keywords start with "ng:" or one of $, _ or a letter
|
||||||
|
var KEYWORD_REGEX = /^((ng:|[$_a-z])[\w\-_]+)/;
|
||||||
|
|
||||||
|
// Load up the keywords to ignore, if specified in the config
|
||||||
|
if (this.ignoreWordsFile) {
|
||||||
|
var ignoreWordsPath = path.resolve(readFilesProcessor.basePath, this.ignoreWordsFile);
|
||||||
|
wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm);
|
||||||
|
|
||||||
|
log.debug('Loaded ignore words from "' + ignoreWordsPath + '"');
|
||||||
|
log.silly(wordsToIgnore);
|
||||||
|
}
|
||||||
|
|
||||||
|
propertiesToIgnore = convertToMap(this.propertiesToIgnore);
|
||||||
|
log.debug('Properties to ignore', propertiesToIgnore);
|
||||||
|
docTypesToIgnore = convertToMap(this.docTypesToIgnore);
|
||||||
|
log.debug('Doc types to ignore', docTypesToIgnore);
|
||||||
|
|
||||||
|
var ignoreWordsMap = convertToMap(wordsToIgnore);
|
||||||
|
|
||||||
|
// If the title contains a name starting with ng, e.g. "ngController", then add the module
|
||||||
|
// name
|
||||||
|
// without the ng to the title text, e.g. "controller".
|
||||||
|
function extractTitleWords(title) {
|
||||||
|
var match = /ng([A-Z]\w*)/.exec(title);
|
||||||
|
if (match) {
|
||||||
|
title = title + ' ' + match[1].toLowerCase();
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractWords(text, words, keywordMap) {
|
||||||
|
var tokens = text.toLowerCase().split(/[.\s,`'"#]+/mg);
|
||||||
|
tokens.forEach(function(token) {
|
||||||
|
var match = token.match(KEYWORD_REGEX);
|
||||||
|
if (match) {
|
||||||
|
var key = match[1];
|
||||||
|
if (!keywordMap[key]) {
|
||||||
|
keywordMap[key] = true;
|
||||||
|
words.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We are only interested in docs that live in the right area
|
||||||
|
const filteredDocs = docs.filter(function(doc) { return !docTypesToIgnore[doc.docType]; });
|
||||||
|
|
||||||
|
filteredDocs.forEach(function(doc) {
|
||||||
|
|
||||||
|
|
||||||
|
var words = [];
|
||||||
|
var keywordMap = Object.assign({}, ignoreWordsMap);
|
||||||
|
var members = [];
|
||||||
|
var membersMap = {};
|
||||||
|
|
||||||
|
// Search each top level property of the document for search terms
|
||||||
|
Object.keys(doc).forEach(function(key) {
|
||||||
|
const value = doc[key];
|
||||||
|
|
||||||
|
if (isString(value) && !propertiesToIgnore[key]) {
|
||||||
|
extractWords(value, words, keywordMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === 'methods' || key === 'properties' || key === 'events') {
|
||||||
|
value.forEach(function(member) { extractWords(member.name, members, membersMap); });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
doc.searchTerms = {
|
||||||
|
titleWords: extractTitleWords(doc.name),
|
||||||
|
keywords: words.sort().join(' '),
|
||||||
|
members: members.sort().join(' ')
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var searchData =
|
||||||
|
filteredDocs.filter(function(page) { return page.searchTerms; }).map(function(page) {
|
||||||
|
return Object.assign(
|
||||||
|
{path: page.path, title: page.name, type: page.docType}, page.searchTerms);
|
||||||
|
});
|
||||||
|
|
||||||
|
docs.push({
|
||||||
|
docType: 'json-doc',
|
||||||
|
id: 'search-data-json',
|
||||||
|
template: 'json-doc.template.json',
|
||||||
|
path: this.outputFolder + '/search-data.json',
|
||||||
|
outputPath: this.outputFolder + '/search-data.json',
|
||||||
|
data: searchData
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function isString(value) {
|
||||||
|
return typeof value == 'string';
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertToMap(collection) {
|
||||||
|
const obj = {};
|
||||||
|
collection.forEach(key => { obj[key] = true; });
|
||||||
|
return obj;
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
module.exports = function generateNavigationDoc() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
$runAfter: ['extra-docs-added'],
|
||||||
|
$runBefore: ['rendering-docs'],
|
||||||
|
outputFolder: '',
|
||||||
|
$validate: {outputFolder: {presence: true}},
|
||||||
|
$process: function(docs) {
|
||||||
|
var modulesDoc = {
|
||||||
|
docType: 'data-module',
|
||||||
|
value: {api: {sections: []}, guide: {pages: []}},
|
||||||
|
path: this.outputFolder + '/navigation',
|
||||||
|
outputPath: this.outputFolder + '/navigation.ts',
|
||||||
|
serviceName: 'NAVIGATION'
|
||||||
|
};
|
||||||
|
|
||||||
|
docs.forEach(function(doc) {
|
||||||
|
if (doc.docType === 'module') {
|
||||||
|
var moduleNavItem =
|
||||||
|
{path: doc.path, partial: doc.outputPath, name: doc.id, type: 'module', pages: []};
|
||||||
|
|
||||||
|
modulesDoc.value.api.sections.push(moduleNavItem);
|
||||||
|
|
||||||
|
doc.exports.forEach(function(exportDoc) {
|
||||||
|
if (!exportDoc.internal) {
|
||||||
|
var exportNavItem = {
|
||||||
|
path: exportDoc.path,
|
||||||
|
partial: exportDoc.outputPath,
|
||||||
|
name: exportDoc.name,
|
||||||
|
type: exportDoc.docType
|
||||||
|
};
|
||||||
|
moduleNavItem.pages.push(exportNavItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
docs.forEach(function(doc) {
|
||||||
|
if (doc.docType === 'guide') {
|
||||||
|
console.log('guide', doc.name);
|
||||||
|
var guideDoc = {path: doc.path, partial: doc.outputPath, name: doc.name, type: 'guide'};
|
||||||
|
modulesDoc.value.guide.pages.push(guideDoc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
docs.push(modulesDoc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,62 @@
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dgProcessor
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
module.exports = function matchUpDirectiveDecoratorsProcessor(aliasMap) {
|
||||||
|
|
||||||
|
return {
|
||||||
|
$runAfter: ['ids-computed', 'paths-computed'],
|
||||||
|
$runBefore: ['rendering-docs'],
|
||||||
|
decoratorMappings: {'Inputs': 'inputs', 'Outputs': 'outputs'},
|
||||||
|
$process: function(docs) {
|
||||||
|
var decoratorMappings = this.decoratorMappings;
|
||||||
|
_.forEach(docs, function(doc) {
|
||||||
|
if (doc.docType === 'directive') {
|
||||||
|
doc.selector = doc.directiveOptions.selector;
|
||||||
|
|
||||||
|
for (decoratorName in decoratorMappings) {
|
||||||
|
var propertyName = decoratorMappings[decoratorName];
|
||||||
|
doc[propertyName] =
|
||||||
|
getDecoratorValues(doc.directiveOptions[propertyName], decoratorName, doc.members);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function getDecoratorValues(classDecoratorValues, memberDecoratorName, members) {
|
||||||
|
var optionMap = {};
|
||||||
|
var decoratorValues = {};
|
||||||
|
|
||||||
|
// Parse the class decorator
|
||||||
|
_.forEach(classDecoratorValues, function(option) {
|
||||||
|
// Options are of the form: "propName : bindingName" (bindingName is optional)
|
||||||
|
var optionPair = option.split(':');
|
||||||
|
var propertyName = optionPair.shift().trim();
|
||||||
|
var bindingName = (optionPair.shift() || '').trim() || propertyName;
|
||||||
|
|
||||||
|
decoratorValues[propertyName] = {propertyName: propertyName, bindingName: bindingName};
|
||||||
|
});
|
||||||
|
|
||||||
|
_.forEach(members, function(member) {
|
||||||
|
_.forEach(member.decorators, function(decorator) {
|
||||||
|
if (decorator.name === memberDecoratorName) {
|
||||||
|
decoratorValues[member.name] = {
|
||||||
|
propertyName: member.name,
|
||||||
|
bindingName: decorator.arguments[0] || member.name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (decoratorValues[member.name]) {
|
||||||
|
decoratorValues[member.name].memberDoc = member;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (Object.keys(decoratorValues).length) {
|
||||||
|
return decoratorValues;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function mergeDecoratorDocs() {
|
||||||
|
return {
|
||||||
|
$runAfter: ['processing-docs'],
|
||||||
|
$runBefore: ['docs-processed'],
|
||||||
|
docsToMergeInfo: [
|
||||||
|
{nameTemplate: _.template('${name}Decorator'), decoratorProperty: 'decoratorInterfaceDoc'}, {
|
||||||
|
nameTemplate: _.template('${name}Metadata'),
|
||||||
|
decoratorProperty: 'metadataDoc',
|
||||||
|
useFields: ['howToUse', 'whatItDoes']
|
||||||
|
},
|
||||||
|
{nameTemplate: _.template('${name}MetadataType'), decoratorProperty: 'metadataInterfaceDoc'},
|
||||||
|
{
|
||||||
|
nameTemplate: _.template('${name}MetadataFactory'),
|
||||||
|
decoratorProperty: 'metadataFactoryDoc'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
$process: function(docs) {
|
||||||
|
|
||||||
|
var docsToMergeInfo = this.docsToMergeInfo;
|
||||||
|
var docsToMerge = Object.create(null);
|
||||||
|
|
||||||
|
docs.forEach(function(doc) {
|
||||||
|
|
||||||
|
// find all the decorators, signified by a call to `makeDecorator(metadata)`
|
||||||
|
var makeDecorator = getMakeDecoratorCall(doc);
|
||||||
|
if (makeDecorator) {
|
||||||
|
doc.docType = 'decorator';
|
||||||
|
// get the type of the decorator metadata
|
||||||
|
doc.decoratorType = makeDecorator.arguments[0].text;
|
||||||
|
// clear the symbol type named (e.g. ComponentMetadataFactory) since it is not needed
|
||||||
|
doc.symbolTypeName = undefined;
|
||||||
|
|
||||||
|
// keep track of the docs that need to be merged into this decorator doc
|
||||||
|
docsToMergeInfo.forEach(function(info) {
|
||||||
|
docsToMerge[info.nameTemplate({name: doc.name})] = {
|
||||||
|
decoratorDoc: doc,
|
||||||
|
property: info.decoratorProperty
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// merge the metadata docs into the decorator docs
|
||||||
|
docs = docs.filter(function(doc) {
|
||||||
|
if (docsToMerge[doc.name]) {
|
||||||
|
var decoratorDoc = docsToMerge[doc.name].decoratorDoc;
|
||||||
|
var property = docsToMerge[doc.name].property;
|
||||||
|
var useFields = docsToMerge[doc.name].useFields;
|
||||||
|
|
||||||
|
// attach this document to its decorator
|
||||||
|
decoratorDoc[property] = doc;
|
||||||
|
|
||||||
|
// Copy over fields from the merged doc if specified
|
||||||
|
if (useFields) {
|
||||||
|
useFields.forEach(function(field) { decoratorDoc[field] = doc[field]; });
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove doc from its module doc's exports
|
||||||
|
doc.moduleDoc.exports =
|
||||||
|
doc.moduleDoc.exports.filter(function(exportDoc) { return exportDoc !== doc; });
|
||||||
|
|
||||||
|
|
||||||
|
// remove from the overall list of docs to be rendered
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function getMakeDecoratorCall(doc, type) {
|
||||||
|
var makeDecoratorFnName = 'make' + (type || '') + 'Decorator';
|
||||||
|
|
||||||
|
var initializer = doc.exportSymbol && doc.exportSymbol.valueDeclaration &&
|
||||||
|
doc.exportSymbol.valueDeclaration.initializer;
|
||||||
|
|
||||||
|
if (initializer) {
|
||||||
|
// There appear to be two forms of initializer:
|
||||||
|
// export var Injectable: InjectableFactory =
|
||||||
|
// <InjectableFactory>makeDecorator(InjectableMetadata);
|
||||||
|
// and
|
||||||
|
// export var RouteConfig: (configs: RouteDefinition[]) => ClassDecorator =
|
||||||
|
// makeDecorator(RouteConfigAnnotation);
|
||||||
|
// In the first case, the type assertion `<InjectableFactory>` causes the AST to contain an
|
||||||
|
// extra level of expression
|
||||||
|
// to hold the new type of the expression.
|
||||||
|
if (initializer.expression && initializer.expression.expression) {
|
||||||
|
initializer = initializer.expression;
|
||||||
|
}
|
||||||
|
if (initializer.expression && initializer.expression.text === makeDecoratorFnName) {
|
||||||
|
return initializer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
var testPackage = require('../../helpers/test-package');
|
||||||
|
var Dgeni = require('dgeni');
|
||||||
|
|
||||||
|
describe('mergeDecoratorDocs processor', function() {
|
||||||
|
var dgeni, injector, processor, decoratorDoc, otherDoc;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
dgeni = new Dgeni([testPackage('angular.io-package')]);
|
||||||
|
injector = dgeni.configureInjector();
|
||||||
|
processor = injector.get('mergeDecoratorDocs');
|
||||||
|
|
||||||
|
decoratorDoc = {
|
||||||
|
name: 'X',
|
||||||
|
docType: 'var',
|
||||||
|
exportSymbol: {
|
||||||
|
valueDeclaration: {
|
||||||
|
initializer: {expression: {text: 'makeDecorator'}, arguments: [{text: 'XMetadata'}]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
decoratorDocWithTypeAssertion = {
|
||||||
|
name: 'Y',
|
||||||
|
docType: 'var',
|
||||||
|
exportSymbol: {
|
||||||
|
valueDeclaration: {
|
||||||
|
initializer: {
|
||||||
|
expression: {
|
||||||
|
type: {},
|
||||||
|
expression: {text: 'makeDecorator'},
|
||||||
|
arguments: [{text: 'YMetadata'}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
otherDoc = {
|
||||||
|
name: 'Y',
|
||||||
|
docType: 'var',
|
||||||
|
exportSymbol: {
|
||||||
|
valueDeclaration:
|
||||||
|
{initializer: {expression: {text: 'otherCall'}, arguments: [{text: 'param1'}]}}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should change the docType of only the docs that are initialied by a call to makeDecorator',
|
||||||
|
function() {
|
||||||
|
processor.$process([decoratorDoc, decoratorDocWithTypeAssertion, otherDoc]);
|
||||||
|
expect(decoratorDoc.docType).toEqual('decorator');
|
||||||
|
expect(decoratorDocWithTypeAssertion.docType).toEqual('decorator');
|
||||||
|
expect(otherDoc.docType).toEqual('var');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should extract the "type" of the decorator meta data', function() {
|
||||||
|
processor.$process([decoratorDoc, decoratorDocWithTypeAssertion, otherDoc]);
|
||||||
|
expect(decoratorDoc.decoratorType).toEqual('XMetadata');
|
||||||
|
expect(decoratorDocWithTypeAssertion.decoratorType).toEqual('YMetadata');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,62 @@
|
||||||
|
module.exports = function(encodeCodeBlock) {
|
||||||
|
// var MIXIN_PATTERN = /\S*\+\S*\(.*/;
|
||||||
|
return {
|
||||||
|
name: 'indentForMarkdown',
|
||||||
|
process: function(str, width) {
|
||||||
|
if (str == null || str.length === 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
width = width || 4;
|
||||||
|
|
||||||
|
var lines = str.split('\n');
|
||||||
|
var newLines = [];
|
||||||
|
var sp = spaces(width);
|
||||||
|
var spMixin = spaces(width - 2);
|
||||||
|
var isAfterMarkdownTag = true;
|
||||||
|
lines.forEach(function(line) {
|
||||||
|
// indent lines that match mixin pattern by 2 less than specified width
|
||||||
|
if (line.indexOf('{@example') >= 0) {
|
||||||
|
if (isAfterMarkdownTag) {
|
||||||
|
// happens if example follows example
|
||||||
|
if (newLines.length > 0) {
|
||||||
|
newLines.pop();
|
||||||
|
} else {
|
||||||
|
// wierd case - first expression in str is an @example
|
||||||
|
// in this case the :marked appear above the str passed in,
|
||||||
|
// so we need to put 'something' into the markdown tag.
|
||||||
|
newLines.push(sp + '.'); // '.' is a dummy char
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newLines.push(spMixin + line);
|
||||||
|
// after a mixin line we need to reenter markdown.
|
||||||
|
newLines.push(spMixin + ':marked');
|
||||||
|
isAfterMarkdownTag = true;
|
||||||
|
} else {
|
||||||
|
if ((!isAfterMarkdownTag) || (line.trim().length > 0)) {
|
||||||
|
newLines.push(sp + line);
|
||||||
|
isAfterMarkdownTag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (isAfterMarkdownTag) {
|
||||||
|
if (newLines.length > 0) {
|
||||||
|
// if last line is a markdown tag remove it.
|
||||||
|
newLines.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// force character to be a newLine.
|
||||||
|
if (newLines.length > 0) newLines.push('');
|
||||||
|
var res = newLines.join('\n');
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function spaces(n) {
|
||||||
|
var str = '';
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
|
str += ' ';
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = function toId() {
|
||||||
|
return {
|
||||||
|
name: 'toId',
|
||||||
|
process: function(str) { return str.replace(/[^(a-z)(A-Z)(0-9)._-]/g, '-'); }
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
var factory = require('./toId');
|
||||||
|
|
||||||
|
describe('toId filter', function() {
|
||||||
|
var filter;
|
||||||
|
|
||||||
|
beforeEach(function() { filter = factory(); });
|
||||||
|
|
||||||
|
it('should be called "toId"', function() { expect(filter.name).toEqual('toId'); });
|
||||||
|
|
||||||
|
it('should convert a string to make it appropriate for use as an HTML id', function() {
|
||||||
|
expect(filter.process('This is a big string with €bad#characaters¢\nAnd even NewLines'))
|
||||||
|
.toEqual('This-is-a-big-string-with--bad-characaters--And-even-NewLines');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {
|
||||||
|
name: 'trimBlankLines',
|
||||||
|
process: function(str) {
|
||||||
|
var lines = str.split(/\r?\n/);
|
||||||
|
while (lines.length && (lines[0].trim() === '')) {
|
||||||
|
lines.shift();
|
||||||
|
}
|
||||||
|
while (lines.length && (lines[lines.length - 1].trim() === '')) {
|
||||||
|
lines.pop();
|
||||||
|
}
|
||||||
|
return lines.join('\n');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
var factory = require('./trimBlankLines');
|
||||||
|
|
||||||
|
describe('trimBlankLines filter', function() {
|
||||||
|
var filter;
|
||||||
|
|
||||||
|
beforeEach(function() { filter = factory(); });
|
||||||
|
|
||||||
|
it('should be called "trimBlankLines"',
|
||||||
|
function() { expect(filter.name).toEqual('trimBlankLines'); });
|
||||||
|
|
||||||
|
it('should remove empty lines from the start and end of the string', function() {
|
||||||
|
expect(filter.process('\n \n\nsome text\n \nmore text\n \n'))
|
||||||
|
.toEqual('some text\n \nmore text');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,4 @@
|
||||||
|
// A ts2dart compiler annotation that can be ignored in API docs.
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'Annotation', ignore: true};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'deprecated'};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'docsNotRequired'};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'experimental'};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'howToUse'};
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {
|
||||||
|
name: 'internal', transforms: function() { return true; }
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'ngModule'};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'noDescription', transforms: function() { return true; }};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'security'};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'stable'};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'syntax'};
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
// A ts2dart compiler annotation that can be ignored in API docs.
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'ts2dart_const', ignore: true};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {name: 'whatItDoes'};
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
var Package = require('dgeni').Package;
|
||||||
|
|
||||||
|
module.exports = new Package(
|
||||||
|
'cheatsheet',
|
||||||
|
[
|
||||||
|
require('../content-package'), require('../target-package'),
|
||||||
|
require('dgeni-packages/git'), require('dgeni-packages/nunjucks')
|
||||||
|
])
|
||||||
|
|
||||||
|
.factory(require('./services/cheatsheetItemParser'))
|
||||||
|
.processor(require('./processors/createCheatsheetDoc'))
|
||||||
|
|
||||||
|
.config(function(parseTagsProcessor, getInjectables) {
|
||||||
|
parseTagsProcessor.tagDefinitions = parseTagsProcessor.tagDefinitions.concat(
|
||||||
|
getInjectables(require('./tag-defs')));
|
||||||
|
});
|
|
@ -0,0 +1,48 @@
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function createCheatsheetDoc(
|
||||||
|
createDocMessage, renderMarkdown, versionInfo, targetEnvironments) {
|
||||||
|
return {
|
||||||
|
$runAfter: ['processing-docs'],
|
||||||
|
$runBefore: ['docs-processed'],
|
||||||
|
$process: function(docs) {
|
||||||
|
|
||||||
|
var currentEnvironment = targetEnvironments.isActive('ts') && 'TypeScript' ||
|
||||||
|
targetEnvironments.isActive('js') && 'JavaScript' ||
|
||||||
|
targetEnvironments.isActive('dart') && 'Dart';
|
||||||
|
|
||||||
|
var cheatsheetDoc = {
|
||||||
|
id: 'cheatsheet',
|
||||||
|
aliases: ['cheatsheet'],
|
||||||
|
docType: 'cheatsheet-data',
|
||||||
|
sections: [],
|
||||||
|
version: versionInfo,
|
||||||
|
currentEnvironment: currentEnvironment
|
||||||
|
};
|
||||||
|
|
||||||
|
docs = docs.filter(function(doc) {
|
||||||
|
if (doc.docType === 'cheatsheet-section') {
|
||||||
|
var section = _.pick(doc, ['name', 'description', 'items', 'index']);
|
||||||
|
|
||||||
|
// Let's make sure that the descriptions are rendered as markdown
|
||||||
|
section.description = renderMarkdown(section.description);
|
||||||
|
section.items.forEach(function(item) {
|
||||||
|
item.description = renderMarkdown(item.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
cheatsheetDoc.sections.push(section);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort the sections by their index
|
||||||
|
cheatsheetDoc.sections.sort(function(a, b) { return a.index - b.index; });
|
||||||
|
|
||||||
|
docs.push(cheatsheetDoc);
|
||||||
|
|
||||||
|
return docs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
* @dgService
|
||||||
|
* @description
|
||||||
|
* Parse the text from a cheatsheetItem tag into a cheatsheet item object
|
||||||
|
* The text must contain a syntax block followed by zero or more bold matchers and finally a
|
||||||
|
* description
|
||||||
|
* The syntax block and bold matchers must be wrapped in backticks and be separated by pipes.
|
||||||
|
* For example
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* `<div [ng-switch]="conditionExpression">
|
||||||
|
* <template [ng-switch-when]="case1Exp">...</template>
|
||||||
|
* <template ng-switch-when="case2LiteralString">...</template>
|
||||||
|
* <template ng-switch-default>...</template>
|
||||||
|
* </div>`|`[ng-switch]`|`[ng-switch-when]`|`ng-switch-when`|`ng-switch-default`
|
||||||
|
* Conditionally swaps the contents of the div by selecting one of the embedded templates based on
|
||||||
|
* the current value of conditionExpression.
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* will be parsed into
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* {
|
||||||
|
* syntax: '<div [ng-switch]="conditionExpression">\n'+
|
||||||
|
* ' <template [ng-switch-when]="case1Exp">...</template>\n'+
|
||||||
|
* ' <template ng-switch-when="case2LiteralString">...</template>\n'+
|
||||||
|
* ' <template ng-switch-default>...</template>\n'+
|
||||||
|
* '</div>',
|
||||||
|
* bold: ['[ng-switch]', '[ng-switch-when]', 'ng-switch-when', 'ng-switch-default'],
|
||||||
|
* description: 'Conditionally swaps the contents of the div by selecting one of the embedded
|
||||||
|
* templates based on the current value of conditionExpression.'
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
module.exports =
|
||||||
|
function cheatsheetItemParser(targetEnvironments) {
|
||||||
|
return function(text) {
|
||||||
|
var fields = getFields(text, ['syntax', 'description']);
|
||||||
|
|
||||||
|
var item = {syntax: '', bold: [], description: ''};
|
||||||
|
|
||||||
|
fields.forEach(function(field) {
|
||||||
|
if (!field.languages || targetEnvironments.someActive(field.languages)) {
|
||||||
|
switch (field.name) {
|
||||||
|
case 'syntax':
|
||||||
|
parseSyntax(field.value.trim());
|
||||||
|
break;
|
||||||
|
case 'description':
|
||||||
|
item.description = field.value.trim();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return item;
|
||||||
|
|
||||||
|
function parseSyntax(text) {
|
||||||
|
var index = 0;
|
||||||
|
|
||||||
|
if (text.charAt(index) !== '`') throw new Error('item syntax must start with a backtick');
|
||||||
|
|
||||||
|
var start = index + 1;
|
||||||
|
index = text.indexOf('`', start);
|
||||||
|
if (index === -1) throw new Error('item syntax must end with a backtick');
|
||||||
|
item.syntax = text.substring(start, index);
|
||||||
|
start = index + 1;
|
||||||
|
|
||||||
|
// skip to next pipe
|
||||||
|
while (index < text.length && text.charAt(index) !== '|') index += 1;
|
||||||
|
|
||||||
|
while (text.charAt(start) === '|') {
|
||||||
|
start += 1;
|
||||||
|
|
||||||
|
// skip whitespace
|
||||||
|
while (start < text.length && /\s/.test(text.charAt(start))) start++;
|
||||||
|
|
||||||
|
if (text.charAt(start) !== '`') throw new Error('bold matcher must start with a backtick');
|
||||||
|
|
||||||
|
start += 1;
|
||||||
|
index = text.indexOf('`', start);
|
||||||
|
if (index === -1) throw new Error('bold matcher must end with a backtick');
|
||||||
|
item.bold.push(text.substring(start, index));
|
||||||
|
start = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start !== text.length) {
|
||||||
|
throw new Error(
|
||||||
|
'syntax field must only contain a syntax code block and zero or more bold ' +
|
||||||
|
'matcher code blocks, delimited by pipes.\n' +
|
||||||
|
'Instead it was "' + text + '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getFields(text, fieldNames) {
|
||||||
|
var FIELD_START = /^([^:(]+)\(?([^)]+)?\)?:$/;
|
||||||
|
var lines = text.split('\n');
|
||||||
|
var fields = [];
|
||||||
|
var field, line;
|
||||||
|
while (lines.length) {
|
||||||
|
line = lines.shift();
|
||||||
|
var match = FIELD_START.exec(line);
|
||||||
|
if (match && fieldNames.indexOf(match[1]) !== -1) {
|
||||||
|
// start new field
|
||||||
|
if (field) {
|
||||||
|
fields.push(field);
|
||||||
|
}
|
||||||
|
field = {name: match[1], languages: (match[2] && match[2].split(' ')), value: ''};
|
||||||
|
} else {
|
||||||
|
if (!field)
|
||||||
|
throw new Error(
|
||||||
|
'item must start with one of the following field specifiers:\n' +
|
||||||
|
fieldNames.map(function(field) { return field + ':'; }).join('\n') + '\n' +
|
||||||
|
'but instead it contained: "' + text + '"');
|
||||||
|
field.value += line + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (field) {
|
||||||
|
fields.push(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
var testPackage = require('../../helpers/test-package');
|
||||||
|
var Dgeni = require('dgeni');
|
||||||
|
|
||||||
|
describe('cheatsheetItemParser', function() {
|
||||||
|
var dgeni, injector, cheatsheetItemParser;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
dgeni = new Dgeni([testPackage('cheatsheet-package')]);
|
||||||
|
injector = dgeni.configureInjector();
|
||||||
|
cheatsheetItemParser = injector.get('cheatsheetItemParser');
|
||||||
|
var targetEnvironments = injector.get('targetEnvironments');
|
||||||
|
targetEnvironments.addAllowed('js');
|
||||||
|
targetEnvironments.addAllowed('ts', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('no language targets', function() {
|
||||||
|
it('should extract the syntax', function() {
|
||||||
|
expect(cheatsheetItemParser('syntax:\n`abc`'))
|
||||||
|
.toEqual({syntax: 'abc', bold: [], description: ''});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should extract the bolds', function() {
|
||||||
|
expect(cheatsheetItemParser('syntax:\n`abc`|`bold1`|`bold2`'))
|
||||||
|
.toEqual({syntax: 'abc', bold: ['bold1', 'bold2'], description: ''});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should extract the description', function() {
|
||||||
|
expect(cheatsheetItemParser('syntax:\n`abc`|`bold1`|`bold2`\ndescription:\nsome description'))
|
||||||
|
.toEqual({syntax: 'abc', bold: ['bold1', 'bold2'], description: 'some description'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow bold to be optional', function() {
|
||||||
|
expect(cheatsheetItemParser('syntax:\n`abc`\ndescription:\nsome description'))
|
||||||
|
.toEqual({syntax: 'abc', bold: [], description: 'some description'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow whitespace between the parts', function() {
|
||||||
|
expect(cheatsheetItemParser(
|
||||||
|
'syntax:\n`abc`| `bold1`| `bold2`\ndescription:\n\nsome description'))
|
||||||
|
.toEqual({syntax: 'abc', bold: ['bold1', 'bold2'], description: 'some description'});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with language targets', function() {
|
||||||
|
it('should extract the active language', function() {
|
||||||
|
expect(cheatsheetItemParser(
|
||||||
|
'syntax(ts):\n`abc`|`bold1`|`bold2`\ndescription(ts):\nsome description'))
|
||||||
|
.toEqual({syntax: 'abc', bold: ['bold1', 'bold2'], description: 'some description'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore the non-active language', function() {
|
||||||
|
expect(cheatsheetItemParser(
|
||||||
|
'syntax(js):\n`abc`|`bold1`|`bold2`\ndescription(js):\nsome description'))
|
||||||
|
.toEqual({syntax: '', bold: [], description: ''});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the active language and ignore non-active language', function() {
|
||||||
|
expect(cheatsheetItemParser(
|
||||||
|
'syntax(js):\n`JS`|`boldJS``\n' +
|
||||||
|
'syntax(ts):\n`TS`|`boldTS`\n' +
|
||||||
|
'description(js):\nJS description\n' +
|
||||||
|
'description(ts):\nTS description'))
|
||||||
|
.toEqual({syntax: 'TS', bold: ['boldTS'], description: 'TS description'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error if a language target is used that is not allowed', function() {
|
||||||
|
expect(function() {
|
||||||
|
cheatsheetItemParser(
|
||||||
|
'syntax(dart):\n`abc`|`bold1`|`bold2`\ndescription(ts):\nsome description');
|
||||||
|
})
|
||||||
|
.toThrowError(
|
||||||
|
'Error accessing target "dart". It is not in the list of allowed targets: js,ts');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,14 @@
|
||||||
|
module.exports = function(createDocMessage) {
|
||||||
|
return {
|
||||||
|
name: 'cheatsheetIndex',
|
||||||
|
docProperty: 'index',
|
||||||
|
transforms: function(doc, tag, value) {
|
||||||
|
try {
|
||||||
|
return parseInt(value, 10);
|
||||||
|
} catch (x) {
|
||||||
|
throw new Error(
|
||||||
|
createDocMessage('"@' + tag.tagName + '" must be followed by a number', doc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
module.exports = function(createDocMessage, cheatsheetItemParser) {
|
||||||
|
return {
|
||||||
|
name: 'cheatsheetItem',
|
||||||
|
multi: true,
|
||||||
|
docProperty: 'items',
|
||||||
|
transforms: function(doc, tag, value) {
|
||||||
|
try {
|
||||||
|
return cheatsheetItemParser(value);
|
||||||
|
} catch (x) {
|
||||||
|
throw new Error(createDocMessage(
|
||||||
|
'"@' + tag.tagName + '" tag has an invalid format - ' + x.message, doc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,10 @@
|
||||||
|
module.exports = function() {
|
||||||
|
return {
|
||||||
|
name: 'cheatsheetSection',
|
||||||
|
docProperty: 'docType',
|
||||||
|
transforms: function(doc, tag, value) {
|
||||||
|
doc.name = value ? value.trim() : '';
|
||||||
|
return 'cheatsheet-section';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,2 @@
|
||||||
|
module.exports =
|
||||||
|
[require('./cheatsheet-section'), require('./cheatsheet-index'), require('./cheatsheet-item')];
|
|
@ -0,0 +1,35 @@
|
||||||
|
var Package = require('dgeni').Package;
|
||||||
|
var jsdocPackage = require('dgeni-packages/jsdoc');
|
||||||
|
var linksPackage = require('../links-package');
|
||||||
|
var path = require('canonical-path');
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
// Define the dgeni package for generating the docs
|
||||||
|
module.exports = new Package('content', [jsdocPackage, linksPackage])
|
||||||
|
|
||||||
|
// Register the services and file readers
|
||||||
|
.factory(require('./readers/content'))
|
||||||
|
|
||||||
|
// Configure file reading
|
||||||
|
.config(function(readFilesProcessor, contentFileReader) {
|
||||||
|
readFilesProcessor.fileReaders.push(contentFileReader);
|
||||||
|
})
|
||||||
|
|
||||||
|
// Configure ids and paths
|
||||||
|
.config(function(computeIdsProcessor, computePathsProcessor) {
|
||||||
|
|
||||||
|
computeIdsProcessor.idTemplates.push({
|
||||||
|
docTypes: ['content'],
|
||||||
|
getId: function(doc) {
|
||||||
|
return doc.fileInfo
|
||||||
|
.relativePath
|
||||||
|
// path should be relative to `modules` folder
|
||||||
|
.replace(/.*\/?modules\//, '')
|
||||||
|
// path should not include `/docs/`
|
||||||
|
.replace(/\/docs\//, '/')
|
||||||
|
// path should not have a suffix
|
||||||
|
.replace(/\.\w*$/, '');
|
||||||
|
},
|
||||||
|
getAliases: function(doc) { return [doc.id]; }
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
var path = require('canonical-path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dgService
|
||||||
|
* @description
|
||||||
|
* This file reader will pull the contents from a text file (by default .md)
|
||||||
|
*
|
||||||
|
* The doc will initially have the form:
|
||||||
|
* ```
|
||||||
|
* {
|
||||||
|
* content: 'the content of the file',
|
||||||
|
* startingLine: 1
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
module.exports = function contentFileReader() {
|
||||||
|
return {
|
||||||
|
name: 'contentFileReader',
|
||||||
|
defaultPattern: /\.md$/,
|
||||||
|
getDocs: function(fileInfo) {
|
||||||
|
|
||||||
|
// We return a single element array because content files only contain one document
|
||||||
|
return [{docType: 'guide', content: fileInfo.content, startingLine: 1}];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,44 @@
|
||||||
|
var testPackage = require('../../helpers/test-package');
|
||||||
|
var Dgeni = require('dgeni');
|
||||||
|
var path = require('canonical-path');
|
||||||
|
|
||||||
|
describe('contentFileReader', function() {
|
||||||
|
var dgeni, injector, fileReader;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
dgeni = new Dgeni([testPackage('content-package', true)]);
|
||||||
|
injector = dgeni.configureInjector();
|
||||||
|
fileReader = injector.get('contentFileReader');
|
||||||
|
});
|
||||||
|
|
||||||
|
var createFileInfo = function(file, content, basePath) {
|
||||||
|
return {
|
||||||
|
fileReader: fileReader.name,
|
||||||
|
filePath: file,
|
||||||
|
baseName: path.basename(file, path.extname(file)),
|
||||||
|
extension: path.extname(file).replace(/^\./, ''),
|
||||||
|
basePath: basePath,
|
||||||
|
relativePath: path.relative(basePath, file),
|
||||||
|
content: content
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('defaultPattern', function() {
|
||||||
|
it('should match .md files', function() {
|
||||||
|
expect(fileReader.defaultPattern.test('abc.md')).toBeTruthy();
|
||||||
|
expect(fileReader.defaultPattern.test('abc.js')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('getDocs', function() {
|
||||||
|
it('should return an object containing info about the file and its contents', function() {
|
||||||
|
var fileInfo = createFileInfo(
|
||||||
|
'project/path/modules/someModule/foo/docs/subfolder/bar.ngdoc', 'A load of content',
|
||||||
|
'project/path');
|
||||||
|
expect(fileReader.getDocs(fileInfo)).toEqual([
|
||||||
|
{docType: 'guide', content: 'A load of content', startingLine: 1}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
module.exports = {
|
||||||
|
'globals': {'describe': true, 'beforeEach': true, 'it': true, 'expect': true},
|
||||||
|
'env': {'node': true},
|
||||||
|
'extends': 'eslint:recommended',
|
||||||
|
'rules': {
|
||||||
|
'indent': ['error', 2],
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
|
'quotes': ['error', 'single'],
|
||||||
|
'semi': ['error', 'always']
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* The point of this reader is to tag all the files that are going to be used as examples in the
|
||||||
|
* documentation.
|
||||||
|
* Later on we can extract the regions, via "shredding"; and we can also construct runnable examples
|
||||||
|
* for passing to plunker and the like.
|
||||||
|
*/
|
||||||
|
module.exports = function exampleFileReader(log) {
|
||||||
|
return {
|
||||||
|
name: 'exampleFileReader',
|
||||||
|
getDocs: function(fileInfo) {
|
||||||
|
return [{docType: 'example-file', content: fileInfo.content, startingLine: 1}];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
var Package = require('dgeni').Package;
|
||||||
|
var jsdocPackage = require('dgeni-packages/jsdoc');
|
||||||
|
|
||||||
|
module.exports =
|
||||||
|
new Package('examples', [jsdocPackage])
|
||||||
|
|
||||||
|
.factory(require('./inline-tag-defs/example'))
|
||||||
|
// .factory(require('./inline-tag-defs/exampleTabs'))
|
||||||
|
.factory(require('./services/parseArgString'))
|
||||||
|
.factory(require('./services/getExampleFilename'))
|
||||||
|
.factory(require('./services/example-map'))
|
||||||
|
.factory(require('./file-readers/example-reader'))
|
||||||
|
.factory(require('./services/region-parser'))
|
||||||
|
|
||||||
|
.processor(require('./processors/collect-examples'))
|
||||||
|
|
||||||
|
.config(function(readFilesProcessor, exampleFileReader) {
|
||||||
|
readFilesProcessor.fileReaders.push(exampleFileReader);
|
||||||
|
})
|
||||||
|
|
||||||
|
.config(function(inlineTagProcessor, exampleInlineTagDef) {
|
||||||
|
inlineTagProcessor.inlineTagDefinitions.push(exampleInlineTagDef);
|
||||||
|
// inlineTagProcessor.inlineTagDefinitions.push(exampleTabsInlineTagDef);
|
||||||
|
})
|
||||||
|
|
||||||
|
.config(function(computePathsProcessor) {
|
||||||
|
computePathsProcessor.pathTemplates.push(
|
||||||
|
{docTypes: ['example-region'], getPath: function() {}, getOutputPath: function() {}});
|
||||||
|
});
|
|
@ -0,0 +1,57 @@
|
||||||
|
var path = require('canonical-path');
|
||||||
|
var fs = require('fs');
|
||||||
|
var entities = require('entities');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dgService exampleInlineTagDef
|
||||||
|
* @description
|
||||||
|
* Process inline example tags (of the form {@example relativePath region -title='some title'
|
||||||
|
* -stylePattern='{some style pattern}' }),
|
||||||
|
* replacing them with code from a shredded file
|
||||||
|
* Examples:
|
||||||
|
* {@example core/application_spec.ts hello-app -title='Sample component' }
|
||||||
|
* {@example core/application_spec.ts -region=hello-app -title='Sample component' }
|
||||||
|
* @kind function
|
||||||
|
*/
|
||||||
|
module.exports = function exampleInlineTagDef(
|
||||||
|
parseArgString, exampleMap, getExampleFilename, createDocMessage, log, collectExamples) {
|
||||||
|
return {
|
||||||
|
name: 'example',
|
||||||
|
description:
|
||||||
|
'Process inline example tags (of the form {@example some/uri Some Title}), replacing them with HTML anchors',
|
||||||
|
|
||||||
|
|
||||||
|
handler: function(doc, tagName, tagDescription) {
|
||||||
|
const EXAMPLES_FOLDER = collectExamples.exampleFolders[0];
|
||||||
|
|
||||||
|
var tagArgs = parseArgString(entities.decodeHTML(tagDescription));
|
||||||
|
|
||||||
|
var unnamedArgs = tagArgs._;
|
||||||
|
var relativePath = unnamedArgs[0];
|
||||||
|
var regionName = tagArgs.region || (unnamedArgs.length > 1 ? unnamedArgs[1] : null);
|
||||||
|
var title = tagArgs.title || (unnamedArgs.length > 2 ? unnamedArgs[2] : null);
|
||||||
|
var stylePattern = tagArgs.stylePattern; // TODO: not yet implemented here
|
||||||
|
|
||||||
|
var exampleFile = exampleMap[EXAMPLES_FOLDER][relativePath];
|
||||||
|
if (!exampleFile) {
|
||||||
|
log.error(
|
||||||
|
createDocMessage('Missing example file... relativePath: "' + relativePath + '".', doc));
|
||||||
|
log.error(
|
||||||
|
'Example files available are:', Object.keys(exampleMap[EXAMPLES_FOLDER]).join('\n'));
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceCode = exampleFile.regions[regionName];
|
||||||
|
if (!sourceCode) {
|
||||||
|
log.error(createDocMessage(
|
||||||
|
'Missing example region... relativePath: "' + relativePath + '", region: "' +
|
||||||
|
regionName + '".',
|
||||||
|
doc));
|
||||||
|
log.error('Regions available are:', Object.keys[exampleFile.regions]);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return sourceCode.renderedContent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue