feat(aio): first pass API docs redesign (#21874)

Includes:

* display ToC for API docs
* update dgeni-packages to 0.24.1
* add floating sidebar in API docs
* add breadcrumbs and structured data for Google crawler
* improved rendering of method overloads
* properties rendered in a table
* params rendered with docs
* removal of outdated "infobox" from all API docs

PR Close #21874
This commit is contained in:
Pete Bacon Darwin 2018-02-08 15:00:53 +00:00 committed by Miško Hevery
parent bc1e22922a
commit 7007f51c35
33 changed files with 831 additions and 134 deletions

View File

@ -0,0 +1,175 @@
<div class="breadcrumb">
<a href="#">API<a> / <a href="#">@core<a>
</div>
<header class="api-header">
<h1><label class="api-status-label experimental">experimental</label><label class="api-type-label class">class</label>Class Name</h1>
</header>
<div class="page-actions">
<a href="#"><label class="raised page-label"><i class="material-icons">mode_edit</i>suggest edits</label></a>
<a href="#"><label class="raised page-label"><i class="material-icons">code</i>view source</label></a>
</div>
<p>Class description goes here. This is a short and to the point one or two sentence description that easily introduces the reader to the class.</p>
<div class="api-body">
<section>
<h2>Overview</h2>
<code-example language="ts" hidecopy="true" ng-version="5.2.0"><aio-code class="simple-code" ng-reflect-ng-class="[object Object]" ng-reflect-code="
class <a href=&quot;api/core/Compi" ng-reflect-hide-copy="true" ng-reflect-language="ts" ng-reflect-linenums="" ng-reflect-path="" ng-reflect-region="" ng-reflect-title=""><pre class="prettyprint lang-ts">
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/core/Compiler" class="code-anchor"><span class="typ">Compiler</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleSync"><span class="pln">compileModuleSync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">NgModuleFactory</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAsync"><span class="pln">compileModuleAsync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun">&lt;</span><span class="typ">NgModuleFactory</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsSync"><span class="pln">compileModuleAndAllComponentsSync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">ModuleWithComponentFactories</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsAsync"><span class="pln">compileModuleAndAllComponentsAsync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun">&lt;</span><span class="typ">ModuleWithComponentFactories</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#clearCache"><span class="pln">clearCache</span><span class="pun">():</span><span class="pln"> </span><span class="kwd">void</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#clearCacheFor"><span class="pln">clearCacheFor</span><span class="pun">(</span><span class="pln">type</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">any</span><span class="pun">&gt;)</span></a><span class="pln">
</span><span class="pun">}</span></code>
</pre></aio-code></code-example>
</section>
<section>
<h2>Description</h2>
<p>The longer class description goes here which can include multiple paragraphs.</p>
</p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
<h3>Subclasses</h3>
<ul>
<li><a href="#">Subclass1</a></li>
<li><a href="#">Subclass2</a></li>
<li><a href="#">Subclass3</a></li>
</ul>
<h3>See Also</h3>
<ul>
<li><a href="#">Link1</a></li>
<li><a href="#">Link2</a></li>
</ul>
</section>
<section>
<h2>Constructor</h2>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</section>
<section>
<h2>Properties</h2>
<table class="is-full-width list-table">
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code><strong>Property1</strong></code>
</td>
<td><label class="property-type-label type">Type</label></td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code><strong>Property2</strong></code>
</td>
<td>Type</td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code><strong>Property3</strong></code>
</td>
<td>Type</td>
<td>Description goes here</td>
</tr>
</tbody>
</table>
</section>
<section class="api-method">
<h2>Methods</h2>
<table class="is-full-width item-table">
<thead>
<tr>
<th>Method1Name( )</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Description goes here</p>
<br>
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
</td>
</tr>
</tbody>
</table>
<table class="is-full-width api-method item-table">
<thead>
<tr>
<th>Method2Name( )</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Description goes here</p>
<hr>
<h5>Declaration</h5>
<code-example language="ts" hidecopy="true" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-ts">
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/animations/AnimationBuilder" class="code-anchor"><span class="typ">AnimationBuilder</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln"></span><a class="code-anchor" href="api/animations/AnimationBuilder#build"><span class="pln">build</span><span class="pun">(</span><span class="pln">animation</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pun">[]):</span><span class="pln"> </span><span class="typ">AnimationFactory</span></a><span class="pln"></span><span class="pun">}</span></code></pre>
</aio-code>
</code-example>
<h6>Parameters</h6>
<h6>Returns</h6>
<p>Returns information and results goes here.</p>
<h6>Errors</h6>
<p>Error information goes here</p>
<hr>
<p>Further details provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p><hr>
<h6>Overloads</h6>
<table class="is-full-width">
<tbody>
<tr>
<td>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</td>
<td>Description goes here</td>
</tr>
</tbody>
</table>
<hr>
<h5>Example: Descriptive Title of Method Example</h5>
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
</td>
</tr>
</tbody>
</table>
</section>
<section>
<h2>Example: Descriptive Title of Combined Example Goes Here</h2>
<p>Intro description text about what the example is and how it can be used.</p>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
<p>Further explanation provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p>
</section>
</div>

View File

@ -107,7 +107,7 @@
"cross-spawn": "^5.1.0",
"css-selector-parser": "^1.3.0",
"dgeni": "^0.4.7",
"dgeni-packages": "^0.24.0",
"dgeni-packages": "0.24.1",
"entities": "^1.1.1",
"eslint": "^3.19.0",
"eslint-plugin-jasmine": "^2.2.0",

View File

@ -143,13 +143,13 @@ th {
text-align: left;
}
p > code, li > code, table code {
p > code, li > code, td > code, th > code {
font-family: $code-font;
font-size: 85%;
color: $darkgray;
letter-spacing: 0;
line-height: 1;
padding: 2px 6px;
padding: 2px 0;
background-color: $backgroundgray;
border-radius: 4px;
}

View File

@ -16,7 +16,7 @@
text-transform: none;
padding: 8px 24px;
}
tbody {
pre {
white-space: normal;
@ -36,34 +36,44 @@
}
}
.api-body {
.api-header label {
border-radius: 4px;
padding: 4px 16px;
display: inline;
font-size: 14px;
color: white;
margin: 0 8px 0 16px;
font-weight: 500;
text-transform: uppercase;
@media screen and (max-width: 600px) {
display: block;
margin: 8px 0;
}
max-width: 1200px;
&.api-status-label {
background-color: $mediumgray;
}
table {
&.api-type-label {
background-color: $accentblue;
th {
text-transform: none;
font-size: 16px;
font-weight: bold;
}
@each $name, $symbol in $api-symbols {
&.#{$name} {
background: map-get($symbol, background);
tr {
border-bottom: 1px solid $lightgray;
}
td {
vertical-align: middle;
}
hr {
margin: 16px 0;
}
tr:last-child {
border-bottom: none;
}
&.item-table {
td {
padding: 32px;
}
}
&.list-table {
td {
padding: 16px 24px;
}
}
}
}

View File

@ -37,3 +37,11 @@ aio-shell.page-docs {
margin: 24px 0px;
background: $lightgray;
}
.page-actions {
display: flex;
flex-direction: column;
position: absolute;
top: 80px;
right: 24px;
}

View File

@ -1,23 +1,102 @@
.api-info-bar {
max-width: 800px;
text-align: left;
.api-body {
span {
margin: 0 16px 0 0;
.class-overview {
position: relative;
@media screen and (max-width: 600px) {
display: block;
code-example {
clear: left;
}
}
.sidebar {
box-shadow: 0 2px 2px rgba(10, 16, 20, 0.24), 0 0 2px rgba(10, 16, 20, 0.12);
border-radius: 2px;
background: #FAFAFA;
float: right;
margin: 20px;
padding: 0 24px 14px;
h2 {
margin: 18px 0 4px;
}
ul {
margin: 0;
padding-left: 14px;
}
}
.inline-sidebar {
display: none;
}
@media (max-width: 1200px) {
.sidebar {
display: none;
}
.inline-sidebar {
display: block;
}
}
.method-table {
h3 {
margin: 6px 0;
font-weight: bold;
}
h4 {
font-size: 14px;
font-weight: bold;
margin-top: 12px;
}
}
.api-heading {
padding: 5px 0;
font-size: 16px;
}
.properties-table {
font-size: 14px;
thead th {
&:nth-child(1) {
width: 20%;
}
&:nth-child(2) {
width: 20%;
}
}
}
.parameters-table {
margin-top: 0;
font-size: 14px;
td:nth-child(1) {
width: 20%;
}
}
details.overloads {
margin-left: -8px;
summary {
height: inherit;
padding: 8px 12px;
h4 {
margin: 0;
clear: left;
}
}
}
.api-section aio-code {
background-color: rgba(241, 241, 241, 0.2);
}
.from-constructor {
font-style: italic;
color: $blue;
}
}
.api-heading {
margin-top: 24px;
margin-bottom: 18px;
font-size: 16px;
}
.overloads .detail-contents {
padding-top: 0;
}

View File

@ -69,7 +69,7 @@ code-tabs mat-tab-body-content .fadeIn {
aio-code pre {
display: flex;
min-height: 32px;
margin: 16px 32px;
margin: 16px 24px;
white-space: pre-wrap;
align-items: center;

View File

@ -25,16 +25,13 @@ summary {
display: none; // Remove the built in details marker in webkit
}
&::after {
&::before {
content: '\E5CE'; // See https://material.io/icons/#ic_expand_less
font-family: 'Material Icons';
font-size: 24px;
-webkit-font-smoothing: antialiased;
@include rotate(0deg); // We will rotate 180 degrees when details is open
position: absolute;
top: 12px;
right: 22px;
float: right;
}
}
@ -45,7 +42,7 @@ details {
padding: 16px 24px;
}
&[open] > summary::after {
&[open] > summary::before {
@include rotate(180deg); // Rotate the icon
}
}

View File

@ -0,0 +1,55 @@
label.raised, .api-header label {
border-radius: 4px;
padding: 4px 16px;
display: inline;
font-size: 14px;
color: white;
margin-right: 8px;
font-weight: 500;
text-transform: uppercase;
@media screen and (max-width: 600px) {
display: block;
margin: 8px 0;
}
&.page-label {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background-color: $mist;
color: $mediumgray;
margin-bottom: 8px;
width: 140px;
.material-icons {
margin-right: 8px;
}
}
&.property-type-label {
font-size: 12px;
background-color: $darkgray;
color: $white;
text-transform: none;
}
}
.api-header label {
&.api-status-label {
background-color: $mediumgray;
}
&.api-type-label {
background-color: $accentblue;
@each $name, $symbol in $api-symbols {
&.#{$name} {
background: map-get($symbol, background);
}
}
}
}

View File

@ -30,3 +30,4 @@
@import 'select-menu';
@import 'deploy-theme';
@import 'notification';
@import 'label';

View File

@ -12,7 +12,7 @@ table {
table-layout: fixed;
}
thead {
thead > {
vertical-align: middle;
border-color: inherit;
@ -21,20 +21,20 @@ table {
border-color: inherit;
}
th {
tr > th {
background: rgba($lightgray, 0.2);
border-bottom: 1px solid $lightgray;
color: $darkgray;
font-size: 12px;
font-weight: 500;
padding: 8px 32px;
padding: 8px 24px;
text-align: left;
text-transform: uppercase;
line-height: 28px;
}
}
tbody {
tbody > tr > {
th,
td {
border-bottom: 1px solid $lightgray;
@ -70,7 +70,7 @@ table {
max-width: 100px;
}
tr:last-child td {
&:last-child td {
border: none;
@media (max-width: 480px) {

View File

@ -30,7 +30,7 @@
box-shadow: 0 2px 2px rgba(0,0,0,0.24), 0 0 2px rgba(0,0,0,0.12);
}
table tbody th{
table > tbody > tr > th {
border: 1px solid rgba(mat-color($foreground, secondary-text), .03);
}

View File

@ -24,7 +24,7 @@ export class ApiPage extends SitePage {
//
// and we want to be able to pull out the code elements from only the first level
// if `onlyDirect` is set to `true`.
const selector = `.descendants.${docType} ${onlyDirect ? '>' : ''} li > :not(ul) code`;
const selector = `.inline-sidebar .descendants.${docType} ${onlyDirect ? '>' : ''} ul > li > code`;
return element.all(by.css(selector)).map<string>(item => item && item.getText());
}

View File

@ -21,7 +21,9 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
.processor(require('./processors/extractDecoratedClasses'))
.processor(require('./processors/matchUpDirectiveDecorators'))
.processor(require('./processors/addMetadataAliases'))
.processor(require('./processors/computeApiBreadCrumbs'))
.processor(require('./processors/filterContainedDocs'))
.processor(require('./processors/processClassLikeMembers'))
.processor(require('./processors/markBarredODocsAsPrivate'))
.processor(require('./processors/filterPrivateDocs'))
.processor(require('./processors/computeSearchTitle'))
@ -86,15 +88,6 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
// Load up all the tag definitions in the tag-defs folder
parseTagsProcessor.tagDefinitions =
parseTagsProcessor.tagDefinitions.concat(getInjectables(requireFolder(__dirname, './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 = [];
}
});
})

View File

@ -0,0 +1,19 @@
module.exports = function computeApiBreadCrumbs(EXPORT_DOC_TYPES) {
return {
$runAfter: ['paths-computed'],
$runBefore: ['rendering-docs'],
$process(docs) {
// Compute the breadcrumb for each doc by processing its containers
docs.forEach(doc => {
if (EXPORT_DOC_TYPES.indexOf(doc.docType) !== -1) {
doc.breadCrumbs = [
{ text: 'API', path: '/api' },
{ text: '@angular/' + doc.moduleDoc.id, path: doc.moduleDoc.path },
{ text: doc.name, path: doc.path }
];
}
});
}
};
};

View File

@ -0,0 +1,39 @@
const testPackage = require('../../helpers/test-package');
const processorFactory = require('./computeApiBreadCrumbs');
const Dgeni = require('dgeni');
describe('angular-api-package: computeApiBreadCrumbs processor', () => {
it('should be available on the injector', () => {
const dgeni = new Dgeni([testPackage('angular-api-package')]);
const injector = dgeni.configureInjector();
const processor = injector.get('computeApiBreadCrumbs');
expect(processor.$process).toBeDefined();
expect(processor.$runAfter).toEqual(['paths-computed']);
expect(processor.$runBefore).toEqual(['rendering-docs']);
});
it('should attach a breadCrumbs property to each of the EXPORT_DOC_TYPES docs', () => {
const EXPORT_DOC_TYPES = ['class', 'interface'];
const processor = processorFactory(EXPORT_DOC_TYPES);
const docs = [
{ docType: 'class', name: 'ClassA', path: 'module-1/class-a', moduleDoc: { id: 'moduleOne', path: 'module-1' } },
{ docType: 'interface', name: 'InterfaceB', path: 'module-2/interface-b', moduleDoc: { id: 'moduleTwo', path: 'module-2' } },
{ docType: 'guide', name: 'Guide One', path: 'guide/guide-1' },
];
processor.$process(docs);
expect(docs[0].breadCrumbs).toEqual([
{ text: 'API', path: '/api' },
{ text: '@angular/moduleOne', path: 'module-1' },
{ text: 'ClassA', path: 'module-1/class-a' },
]);
expect(docs[1].breadCrumbs).toEqual([
{ text: 'API', path: '/api' },
{ text: '@angular/moduleTwo', path: 'module-2' },
{ text: 'InterfaceB', path: 'module-2/interface-b' },
]);
expect(docs[2].breadCrumbs).toBeUndefined();
});
});

View File

@ -0,0 +1,59 @@
/**
* A class like API doc contains members, but these can be either properties or method.
* Separate the members into two new collections: `doc.properties` and `doc.methods`.
*/
module.exports = function processClassLikeMembers() {
return {
$runAfter: ['filterContainedDocs'],
$runBefore: ['rendering-docs'],
$process(docs) {
docs.forEach(doc => {
if (doc.members) {
doc.properties = [];
doc.methods = [];
doc.members.forEach(member => {
if (isMethod(member)) {
doc.methods.push(member);
computeMemberDescription(member);
} else {
doc.properties.push(member);
if (!member.description) {
// Is this property defined as a constructor parameter e.g. `constructor(public property: string) { ... }`?
const constructorDoc = member.containerDoc.constructorDoc;
if (constructorDoc) {
const matchingParameterDoc = constructorDoc.parameterDocs.filter(doc => doc.declaration === member.declaration)[0];
member.constructorParamDoc = matchingParameterDoc;
}
}
}
});
}
if (doc.statics) {
doc.staticProperties = [];
doc.staticMethods = [];
doc.statics.forEach(member => {
if (isMethod(member)) {
doc.staticMethods.push(member);
computeMemberDescription(member);
} else {
doc.staticProperties.push(member);
}
});
}
});
}
};
};
function isMethod(doc) {
return doc.hasOwnProperty('parameters') && !doc.isGetAccessor && !doc.isSetAccessor;
}
function computeMemberDescription(member) {
if (!member.description && member.overloads) {
// Perhaps the description is on one of the overloads - take the first non-empty one
member.description = member.overloads.map(overload => overload.description).filter(description => !!description)[0];
}
}

View File

@ -0,0 +1,81 @@
const testPackage = require('../../helpers/test-package');
const processorFactory = require('./processClassLikeMembers');
const Dgeni = require('dgeni');
const property1 = { description: 'property 1' };
const property2 = { description: 'property 2' };
const getter1 = { parameters: [], isGetAccessor: true, description: 'getter 1' };
const setter1 = { parameters: [], isSetAccessor: true, description: 'setter 1' };
const method1 = { parameters: [] };
const method2 = { parameters: [] };
const method3 = { parameters: [] };
describe('angular-api-packge: processClassLikeMembers processor', () => {
it('should be available on the injector', () => {
const dgeni = new Dgeni([testPackage('angular-api-package')]);
const injector = dgeni.configureInjector();
const processor = injector.get('processClassLikeMembers');
expect(processor.$process).toBeDefined();
expect(processor.$runAfter).toEqual(['filterContainedDocs']);
expect(processor.$runBefore).toEqual(['rendering-docs']);
});
it('should copy instance members into properties and methods', () => {
const processor = processorFactory();
const docs = [
{ members: [ property1, method1, getter1] },
{ members: [ method2, property2, method3, setter1] },
{ }
];
processor.$process(docs);
expect(docs[0].properties).toEqual([property1, getter1]);
expect(docs[0].methods).toEqual([method1]);
expect(docs[1].properties).toEqual([property2, setter1]);
expect(docs[1].methods).toEqual([method2, method3]);
expect(docs[2].properties).toBeUndefined();
expect(docs[2].methods).toBeUndefined();
});
it('should copy static members into properties and methods', () => {
const processor = processorFactory();
const docs = [
{ statics: [ property1, method1, getter1] },
{ statics: [ method2, property2, method3, setter1] },
{ }
];
processor.$process(docs);
expect(docs[0].staticProperties).toEqual([property1, getter1]);
expect(docs[0].staticMethods).toEqual([method1]);
expect(docs[1].staticProperties).toEqual([property2, setter1]);
expect(docs[1].staticMethods).toEqual([method2, method3]);
expect(docs[2].staticProperties).toBeUndefined();
expect(docs[2].staticMethods).toBeUndefined();
});
it('should wire up properties that are declared as parameters on the constructor to its associated parameter doc', () => {
const processor = processorFactory();
const propertyDeclaration = {};
const parameterDoc1 = { declaration: {} };
const parameterDoc2 = { declaration: propertyDeclaration };
const parameterDoc3 = { declaration: {} };
const property = {
declaration: propertyDeclaration,
containerDoc: {
constructorDoc: {
parameterDocs: [ parameterDoc1, parameterDoc2, parameterDoc3 ]
}
}
};
const docs = [{ members: [ property] }];
processor.$process(docs);
expect(property.constructorParamDoc).toEqual(parameterDoc2);
});
});

View File

@ -0,0 +1,8 @@
module.exports = function(extractTypeTransform, wholeTagTransform) {
return {
name: 'throws',
aliases: ['exception'],
multi: true,
transforms: [ extractTypeTransform, wholeTagTransform ]
};
};

View File

@ -1,13 +1,46 @@
{% import "lib/githubLinks.html" as github -%}
{% set comma = joiner(',') %}
{% set slash = joiner('/') %}
<article>
<div class="breadcrumb">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{% for crumb in doc.breadCrumbs %}
{$ comma() $}{
"@type": "ListItem",
"position": {$ loop.index $},
"item": {
"@id": "https://angular.io/{$ crumb.path $}",
"name": "{$ crumb.text $}"
}
}{% endfor %}
]
}
</script>
{% for crumb in doc.breadCrumbs %}{% if not loop.last %}
{$ slash() $}
{% if crumb.path %}<a href="{$ crumb.path $}">{$ crumb.text $}<a>{% else %}{$ crumb.text $}{% endif %}
{% endif %}{% endfor %}
</div>
<header class="api-header">
<h1 class="no-toc">{$ doc.name $}</h1>
{% if doc.deprecated !== undefined %}<label class="api-status-label deprecated">deprecated</label>{% endif %}
{% if doc.experimental !== undefined %}<label class="api-status-label experimental">experimental</label>{% endif %}
{% if doc.stable !== undefined %}<label class="api-status-label stable">stable</label>{% endif %}
<label class="api-type-label {$ doc.docType $}">{$ doc.docType $}</label>
{% if doc.deprecated %}<label class="api-status-label deprecated">deprecated</label>{% endif %}
{% if doc.experimental %}<label class="api-status-label experimental">experimental</label>{% endif %}
{% if doc.stable %}<label class="api-status-label stable">stable</label>{% endif %}
<h1>
{$ doc.name $}
</h1>
<span class="version">{$ version $}</span>
</header>
<div class="page-actions">
<a href="#"><label class="raised page-label"><i class="material-icons">mode_edit</i>suggest edits</label></a>
<a href="{$ github.githubHref(doc, versionInfo) $}"><label class="raised page-label"><i class="material-icons">code</i>view source</label></a>
</div>
{% block body %}{% endblock %}
<div class="api-body">
{% block body %}{% endblock %}
</div>
</article>

View File

@ -1,16 +1,27 @@
{% import "lib/memberHelpers.html" as memberHelpers -%}
{% import "lib/descendants.html" as descendants -%}
{% import "lib/paramList.html" as params -%}
{% extends 'export-base.template.html' -%}
{% extends 'base.template.html' -%}
{% block overview %}{% include "includes/class-overview.html" %}{% endblock %}
{% block details %}
{% block additional %}{% endblock %}
{% include "includes/description.html" %}
{$ descendants.renderDescendants(doc, 'class', 'Subclasses') $}
{$ memberHelpers.renderMemberDetails(doc.statics, 'static-members', 'static-member', 'Static Members') $}
{% if doc.constructorDoc %}{$ memberHelpers.renderMemberDetails([doc.constructorDoc], 'constructors', 'constructor', 'Constructor') $}{% endif %}
{$ memberHelpers.renderMemberDetails(doc.members, 'instance-members', 'instance-member', 'Members') $}
{% block annotations %}{% include "includes/annotations.html" %}{% endblock %}
{% block body %}
<p>{$ doc.whatItDoes | marked $}</p>
{% include "includes/security-notes.html" %}
{% include "includes/deprecation.html" %}
{% block overview %}
{% include "includes/class-overview.html" %}
{% endblock %}
{% block details %}
{% block additional %}{% endblock %}
{% include "includes/description.html" %}
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static Properties') $}
{$ memberHelpers.renderMethodDetails(doc.staticMethods, 'static-methods', 'static-method', 'Static Methods') $}
{% if doc.constructorDoc %}{$ memberHelpers.renderMethodDetail(doc.constructorDoc, 'constructor') $}{% endif %}
{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
{$ memberHelpers.renderMethodDetails(doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
{% block annotations %}{% include "includes/annotations.html" %}{% endblock %}
{% endblock %}
{% include "includes/how-to-use.html" %}
{% endblock %}

View File

@ -5,5 +5,5 @@
{% block overview %}{% include "includes/decorator-overview.html" %}{% endblock %}
{% block details %}
{% include "includes/description.html" %}
{$ memberHelper.renderMemberDetails(doc.members, 'metadata-members', 'metadata-member', 'Metadata Properties') $}
{$ memberHelper.renderProperties(doc.members, 'metadata-members', 'metadata-member', 'Metadata Properties') $}
{% endblock %}

View File

@ -1,7 +1,6 @@
{% extends 'base.template.html' -%}
{% block body %}
{% include "includes/info-bar.html" %}
{% include "includes/what-it-does.html" %}
{% include "includes/security-notes.html" %}
{% include "includes/deprecation.html" %}

View File

@ -2,13 +2,23 @@
<section class="{$ doc.docType $}-overview">
<h2>Overview</h2>
{% if (doc.descendants | filterByPropertyValue('docType', 'class')).length or doc.see.length %}
<div class="sidebar">
{$ descendants.renderDescendants(doc, 'class', 'Subclasses') $}
{% include "includes/see-also.html" %}
</div>
{% endif %}
<code-example language="ts" hideCopy="true">
{$ doc.docType $} {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} {
{%- if doc.constructorDoc %}{% if not doc.constructorDoc.internal %}
<a class="code-anchor" href="#{$ doc.constructorDoc.anchor | urlencode $}">{$ memberHelper.renderMember(doc.constructorDoc, 1) $}</a>{% endif %}{% endif -%}
<a class="code-anchor" href="#{$ doc.constructorDoc.anchor | urlencode $}">{$ memberHelper.renderMemberSyntax(doc.constructorDoc, 1) $}</a>{% endif %}{% endif -%}
{%- if doc.statics.length %}{% for member in doc.statics %}{% if not member.internal %}
<a class="code-anchor" href="#{$ member.anchor | urlencode $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif -%}
<a class="code-anchor" href="#{$ member.anchor | urlencode $}">{$ memberHelper.renderMemberSyntax(member, 1) $}</a>{% endif %}{% endfor %}{% endif -%}
{$ memberHelper.renderMembers(doc) $}
}
</code-example>
<div class="inline-sidebar">
{$ descendants.renderDescendants(doc, 'class', 'Subclasses') $}
{% include "includes/see-also.html" %}
</div>
</section>

View File

@ -6,7 +6,7 @@
@{$ decorator.name $}({$ decorator.arguments $}){% endfor %}
class {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} {
{%- if doc.statics.length %}{% for member in doc.statics %}{% if not member.internal %}
<a class="code-anchor" href="#{$ member.anchor | urlencode $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif -%}
<a class="code-anchor" href="#{$ member.anchor | urlencode $}">{$ memberHelper.renderMemberSyntax(member, 1) $}</a>{% endif %}{% endfor %}{% endif -%}
{$ memberHelper.renderMembers(doc) $}
}
</code-example>

View File

@ -2,9 +2,14 @@
<section class="interface-overview">
<h2>Interface Overview</h2>
<div class="sidebar">
{$ descendants.renderDescendants(doc, 'interface', 'Child Interfaces') $}
{$ descendants.renderDescendants(doc, 'class', 'Class Implementations') $}
{% include "includes/see-also.html" %}
</div>
<code-example language="ts" hideCopy="true">
interface {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} { {% if doc.members.length %}{% for member in doc.members %}{% if not member.internal %}
<a class="code-anchor" href="#{$ member.anchor | urlencode $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
<a class="code-anchor" href="#{$ member.anchor | urlencode $}">{$ memberHelper.renderMemberSyntax(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
}
</code-example>
</section>

View File

@ -0,0 +1,9 @@
{%- if doc.see.length %}
<section class="see-also">
<h2>See Also</h2>
<ul>
{% for see in doc.see %}
<li>{$ see | marked $}</li>{% endfor %}
</ul>
</section>
{% endif %}

View File

@ -6,7 +6,11 @@
{% block overview %}{% include "includes/interface-overview.html" %}{% endblock %}
{% block details %}
{% include "includes/description.html" %}
{$ descendants.renderDescendants(doc, 'interface', 'Child Interfaces') $}
{$ descendants.renderDescendants(doc, 'class', 'Class Implementations') $}
{$ memberHelper.renderMemberDetails(doc.members, 'instance-members', 'instance-member', 'Members') $}
<div class="inline-sidebar">
{$ descendants.renderDescendants(doc, 'interface', 'Child Interfaces') $}
{$ descendants.renderDescendants(doc, 'class', 'Class Implementations') $}
{% include "includes/see-also.html" %}
</div>
{$ memberHelper.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
{$ memberHelper.renderMethodDetails(doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
{% endblock %}

View File

@ -1,14 +1,22 @@
{% macro renderDescendants(doc, docType, title='', recursed=false) %}
{% set descendants = doc.descendants | filterByPropertyValue('docType', docType) %}
{% if descendants.length %}
{% if title %}<h2>{$ title $}</h2>{% endif %}
<ul {% if not recursed %}class="descendants {$ docType $}"{% endif %}>
{% macro renderDescendantList(descendants, docType, recursed) %}
{% if descendants.length %}
<ul>
{% for descendant in descendants %}
<li>
<pre class="prettyprint lang-ts"><code>{$ descendant.name $}</code></pre>
{$ renderDescendants(descendant, docType, '', true) $}
<code>{$ descendant.name $}</code>
{$ renderDescendantList(descendant.descendants | filterByPropertyValue('docType', docType), docType, recursed) $}
</li>
{% endfor %}
</ul>
</ul>
{% endif %}
{% endmacro -%}
{%- macro renderDescendants(doc, docType, title='', recursed=true) %}
{% set descendants = doc.descendants | filterByPropertyValue('docType', docType) %}
{% if descendants.length %}
<div class="descendants {$ docType $}">
{% if title %}<h2>{$ title $}</h2>{% endif %}
{$ renderDescendantList(descendants, docType, recursed) $}
</div>
{% endif %}
{% endmacro %}

View File

@ -11,12 +11,12 @@
{%- macro renderMembers(doc) -%}
{%- if doc.members.length %}{% for member in doc.members %}{% if not member.internal %}
<a class="code-anchor" href="{$ doc.path $}#{$ member.anchor | urlencode $}">{$ renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
<a class="code-anchor" href="{$ doc.path $}#{$ member.anchor | urlencode $}">{$ renderMemberSyntax(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
{%- for ancestor in doc.extendsClauses %}{% if ancestor.doc %}
// inherited from <a class="code-anchor" href="{$ ancestor.doc.path $}">{$ ancestor.doc.id $}</a>{$ renderMembers(ancestor.doc) $}{% endif %}{% endfor %}
{%- endmacro -%}
{%- macro renderMember(member, truncateLines) -%}
{%- macro renderMemberSyntax(member, truncateLines) -%}
{%- if member.accessibility !== 'public' %}{$ member.accessibility $} {% endif -%}
{%- if (member.isGetAccessor or member.isReadonly) and not member.isSetAccessor %}get {% endif -%}
{%- if member.isSetAccessor and not member.isGetAccessor %}set {% endif -%}
@ -26,35 +26,101 @@
{$ params.returnType(member.type) | trim | truncateCode(truncateLines) $}
{%- endmacro -%}
{%- macro renderMemberDetail(member, cssClass) -%}
<div class="{$ cssClass $}">
<a id="{$ member.anchor $}"></a>
<code-example language="ts" hideCopy="true" class="no-box api-heading">{$ renderMember(member) $}</code-example>
{%- if not member.notYetDocumented %}
{$ member.description | marked $}
{% endif -%}
</div>
{%- macro renderOverloadInfo(overload, cssClass, method) -%}
{% if overload.description and (overload.description != method.description) %}{$ overload.description | marked $}{% endif %}
<code-example language="ts" hideCopy="true" class="no-box api-heading">{$ renderMemberSyntax(overload) $}</code-example>
<h4 class="no-anchor">Parameters</h4>
{$ params.renderParameters(overload.parameterDocs, cssClass + '-parameters', cssClass + '-parameter') $}
{% if overload.type or overload.returns.type %}
<h4 class="no-anchor">Returns</h4>
{% marked %}`{$ (overload.type or overload.returns.type) $}`{% if overload.returns %}: {$ overload.returns.description $}{% endif %}{% endmarked %}
{% endif %}
{% if overload.throws.length %}
<h4 class="no-anchor">Throws</h4>
{% for error in overload.throws %}
{% marked %}`{$ (error.typeList or 'Error') $}` {$ error.description $}{% endmarked %}
{% endfor %}
{% endif %}
{%- endmacro -%}
{%- macro renderMethodDetail(method, cssClass) -%}
<a id="{$ method.anchor $}"></a>
<table class="is-full-width method-table {$ cssClass $}">
<thead><tr><th><h3>{$ method.name $}()</h3></th></tr></thead>
<tbody>
<tr>
<td>
{% if method.description %}{$ method.description | marked $}{% endif %}
</td>
</tr>
{% if method.overloads.length == 0 %}
<tr>
<td>
{$ renderOverloadInfo(method, cssClass + '-overload', method) $}
</td>
</tr>
{% elseif method.overloads.length < 3 -%}
{% for overload in method.overloads -%}
<tr>
<td>
{$ renderOverloadInfo(overload, cssClass + '-overload', method) $}
</td>
</tr>
{% endfor -%}
{% else -%}
<tr>
<td>
<details class="overloads">
<summary><h4 class="no-anchor">{$ method.overloads.length $} overloads...</h4></summary>
<div class="detail-contents">
{% for overload in method.overloads %}
{$ renderOverloadInfo(overload, cssClass + '-overload', method) $}
{% if not loop.last %}<hr class="hr-margin fullwidth">{% endif %}
{% endfor %}
</div>
</details>
</td>
</tr>
{% endif %}
</tbody>
</table>
{% endmacro -%}
{% macro renderMemberDetails(members, containerClass, itemClass, titleText) %}
{% if members.length %}
{%- macro renderMethodDetails(methods, containerClass, itemClass, headingText) -%}
{% if methods.length %}
<section class="{$ containerClass $}">
<h2>{$ titleText $}</h2>
{% for member in members %}{% if not member.internal %}
{$ renderMemberDetail(member, itemClass) $}
{% if member.overloads.length %}
<details class="overloads">
<summary>Overloads</summary>
<div class="detail-contents">
{% for overload in member.overloads %}
{$ renderMemberDetail(overload, itemClass + '-overload') $}
{% if not loop.last %}<hr>{% endif %}
{% endfor %}
</div>
</details>
{% endif %}
{% if not loop.last %}<hr class="hr-margin">{% endif %}
<h2>{$ headingText $}</h2>
{% for member in methods %}{% if not member.internal %}
{$ renderMethodDetail(member, itemClass) $}
{% endif %}{% endfor %}
</section>
{% endif %}
{% endmacro %}
{%- endmacro -%}
{%- macro renderProperties(properties, containerClass, propertyClass, headingText) -%}
{%- if properties.length -%}
<h2>{$ headingText $}</h2>
<table class="is-full-width list-table properties-table">
<thead>
<tr><th>Property</th><th>Type</th><th>Description</th></tr>
</thead>
<tbody>
{% for property in properties %}{% if not property.internal %}
<tr class="{$ propertyClass $}">
<td><a id="{$ property.anchor $}"></a>{$ property.name $}</td>
<td><label class="property-type-label"><code>{$ property.type | escape $}</code></label></td>
<td>
{$ (property.description or property.constructorParamDoc.description) | marked $}
{% if property.constructorParamDoc %} <span class='from-constructor'>Declared in constructor.</span>{% endif %}
</td>
</tr>
{% endif %}{% endfor %}
</tbody>
</table>
{%- endif -%}
{%- endmacro -%}

View File

@ -10,3 +10,23 @@
{% macro returnType(returnType) -%}
{%- if returnType %}: {$ returnType | escape $}{% endif -%}
{%- endmacro -%}
{%- macro renderParameters(parameters, containerClass, parameterClass) -%}
{%- if parameters.length -%}
<table class="is-full-width list-table parameters-table {$ containerClass $}">
<tbody>
{% for parameter in parameters %}
<tr class="{$ parameterClass $}">
<td class="param-name"><a id="{$ parameter.anchor $}"></a>{$ parameter.name $}</td>
<td class="param-description">
{% if parameter.description | trim %}{$ parameter.description | marked $}
{% elseif parameter.type %}<code>{$ parameter.type $}</code>
{% endif %}
</td>
</tr>{% endfor %}
</tbody>
</table>
{%- else -%}
<p>There are no parameters.</p>
{%- endif -%}
{%- endmacro -%}

View File

@ -2312,9 +2312,9 @@ devtools-timeline-model@1.1.6:
chrome-devtools-frontend "1.0.401423"
resolve "1.1.7"
dgeni-packages@^0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.24.0.tgz#2f995f78fecd6a9ded72d7bdccbbc4c46360c1ea"
dgeni-packages@0.24.1:
version "0.24.1"
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.24.1.tgz#e3e99eb82615b30a9e43fe1a9bb9911ff6bbf913"
dependencies:
canonical-path "0.0.2"
catharsis "^0.8.1"

View File

@ -117,6 +117,9 @@ function isOptionsObj(
* that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
* instantiated directly.
*
* @see [Forms Guide](/guide/forms)
* @see [Reactive Forms Guide](/guide/reactive-forms)
* @see [Dynamic Forms Guide](/guide/dynamic-form)
* @stable
*/
export abstract class AbstractControl {
@ -136,6 +139,12 @@ export abstract class AbstractControl {
private _asyncValidationSubscription: any;
public readonly value: any;
/**
* Initialize the AbstractControl instance.
* @param validator The function that will determine the synchronous validity of this control.
* @param asyncValidator The function that will determine the asynchronous validity of this
* control.
*/
constructor(public validator: ValidatorFn|null, public asyncValidator: AsyncValidatorFn|null) {}
/**
@ -1033,10 +1042,6 @@ export class FormGroup extends AbstractControl {
* Sets the value of the {@link FormGroup}. It accepts an object that matches
* the structure of the group, with control names as keys.
*
* This method performs strict checks, so it will throw an error if you try
* to set the value of a control that doesn't exist or if you exclude the
* value of a control.
*
* ### Example
*
* ```
@ -1050,6 +1055,9 @@ export class FormGroup extends AbstractControl {
* console.log(form.value); // {first: 'Nancy', last: 'Drew'}
*
* ```
* @throws This method performs strict checks, so it will throw an error if you try
* to set the value of a control that doesn't exist or if you exclude the
* value of a control.
*/
setValue(value: {[key: string]: any}, options: {onlySelf?: boolean, emitEvent?: boolean} = {}):
void {