build(docs-infra): improve directive API doc templates (#25768)
Closes #22790 Closes #25530 PR Close #25768
This commit is contained in:
parent
57de9fc41a
commit
f22deb2e2d
|
@ -31,6 +31,10 @@
|
|||
}
|
||||
|
||||
.method-table, .option-table, .list-table {
|
||||
td > code {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.with-github-links {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
|
|
@ -137,6 +137,7 @@ aio-code pre {
|
|||
.sidenav-content code a {
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/* PRETTY PRINTING STYLES for prettify.js. */
|
||||
|
|
|
@ -21,7 +21,9 @@ module.exports = function matchUpDirectiveDecorators() {
|
|||
if (doc.docType === 'directive') {
|
||||
|
||||
doc.selector = stripQuotes(doc.directiveOptions.selector);
|
||||
doc.selectorArray = doc.selector ? doc.selector.split(',') : [];
|
||||
doc.exportAs = stripQuotes(doc.directiveOptions.exportAs);
|
||||
doc.exportAsArray = doc.exportAs ? doc.exportAs.split(',') : [];
|
||||
|
||||
doc.inputs = getBindingInfo(doc.directiveOptions.inputs, doc.members, 'Input');
|
||||
doc.outputs = getBindingInfo(doc.directiveOptions.outputs, doc.members, 'Output');
|
||||
|
|
|
@ -3,7 +3,21 @@ module.exports = function hasValues() {
|
|||
name: 'hasValues',
|
||||
process: function(list, property) {
|
||||
if (!list || !Array.isArray(list)) return false;
|
||||
return list.some(item => item[property]);
|
||||
return list.some(item => readProperty(item, property.split('.'), 0));
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Search deeply into an object via a collection of property segments, starting at the
|
||||
* indexed segment.
|
||||
*
|
||||
* E.g. if `obj = { a: { b: { c: 10 }}}` then
|
||||
* `readProperty(obj, ['a', 'b', 'c'], 0)` will return true;
|
||||
* but
|
||||
* `readProperty(obj, ['a', 'd'], 0)` will return false;
|
||||
*/
|
||||
function readProperty(obj, propertySegments, index) {
|
||||
const value = obj[propertySegments[index]];
|
||||
return !!value && (index === propertySegments.length - 1 || readProperty(value, propertySegments, index + 1));
|
||||
}
|
||||
|
|
|
@ -7,13 +7,37 @@ describe('hasValues filter', () => {
|
|||
|
||||
it('should be called "hasValues"', function() { expect(filter.name).toEqual('hasValues'); });
|
||||
|
||||
it('should return true if the specified property is truthy on any item in the list', function() {
|
||||
expect(filter.process([], 'a')).toEqual(false);
|
||||
expect(filter.process(0, 'a')).toEqual(false);
|
||||
expect(filter.process({}, 'a')).toEqual(false);
|
||||
it('should return true if the specified property path is truthy on any item in the list', function() {
|
||||
expect(filter.process([{a: 1}], 'a')).toEqual(true);
|
||||
expect(filter.process([{b: 2}], 'a')).toEqual(false);
|
||||
expect(filter.process([{a: 1, b: 2}], 'a')).toEqual(true);
|
||||
expect(filter.process([{b: 2}, {a: 1}], 'a')).toEqual(true);
|
||||
|
||||
expect(filter.process([{a:{b:1}}], 'a.b')).toEqual(true);
|
||||
expect(filter.process([{a:{b:1}, b: 2}], 'a.b')).toEqual(true);
|
||||
expect(filter.process([{b: 2}, {a:{b:1}}], 'a.b')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return false if the value is not an object', () => {
|
||||
expect(filter.process([], 'a')).toEqual(false);
|
||||
expect(filter.process(0, 'a')).toEqual(false);
|
||||
expect(filter.process([], 'a.b')).toEqual(false);
|
||||
expect(filter.process(0, 'a.b')).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return false if the property exists but is falsy', () => {
|
||||
expect(filter.process([{a: false}], 'a')).toEqual(false);
|
||||
expect(filter.process([{a: ''}], 'a')).toEqual(false);
|
||||
expect(filter.process([{a: 0}], 'a')).toEqual(false);
|
||||
expect(filter.process([{a: null}], 'a')).toEqual(false);
|
||||
expect(filter.process([{a: undefined}], 'a')).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return false if any of the properties in the path do not exist', () => {
|
||||
expect(filter.process({}, 'a')).toEqual(false);
|
||||
expect(filter.process({}, 'a.b')).toEqual(false);
|
||||
|
||||
expect(filter.process([{b: 2}], 'a')).toEqual(false);
|
||||
expect(filter.process([{a: 2}], 'a.b')).toEqual(false);
|
||||
expect(filter.process([{a: {}}], 'a.b.c')).toEqual(false);
|
||||
});
|
||||
});
|
|
@ -1,21 +1,9 @@
|
|||
{% import "lib/memberHelpers.html" as memberHelpers -%}
|
||||
{% import "lib/descendants.html" as descendants -%}
|
||||
{% import "lib/paramList.html" as params -%}
|
||||
{% extends 'export-base.template.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(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $}
|
||||
{% if doc.constructorDoc %}
|
||||
<h2>Constructor</h2>
|
||||
{$ memberHelpers.renderMethodDetail(versionInfo, doc.constructorDoc, 'constructor') $}{% endif %}
|
||||
|
||||
{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
|
||||
|
||||
{$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
|
||||
{% include "includes/class-members.html" %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,14 +1,30 @@
|
|||
{% import "lib/directiveHelpers.html" as directiveHelper -%}
|
||||
{% import "lib/paramList.html" as params -%}
|
||||
{% extends 'class.template.html' -%}
|
||||
|
||||
{% block overview %}{% include "includes/directive-overview.html" %}{% endblock %}
|
||||
{% block additional -%}
|
||||
{% include "includes/ngmodule.html" %}
|
||||
{% include "includes/selectors.html" %}
|
||||
{% block overview %}{% endblock %}
|
||||
|
||||
{% block details -%}
|
||||
{% include "includes/ngmodule.html" %}
|
||||
{% include "includes/selectors.html" %}
|
||||
|
||||
{$ directiveHelper.renderBindings(doc.inputs, 'inputs', 'input', 'Inputs') $}
|
||||
|
||||
{$ directiveHelper.renderBindings(doc.outputs, 'outputs', 'output', 'Outputs') $}
|
||||
|
||||
{% include "includes/export-as.html" %}
|
||||
|
||||
{% if doc.description or doc.usageNotes %}
|
||||
<section class="description">
|
||||
<h2>Description</h2>
|
||||
{$ (doc.description or '') | trimBlankLines | marked $}
|
||||
{$ (doc.usageNotes or '') | trimBlankLines | marked $}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
<h2>Class</h2>
|
||||
{% include "includes/directive-overview.html" %}
|
||||
|
||||
{% include "includes/class-members.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block annotations %}{% endblock %}
|
||||
{% block endNotes %}{% endblock %}
|
|
@ -7,5 +7,5 @@
|
|||
{% block overview %}{% endblock %}
|
||||
{% include "includes/see-also.html" %}
|
||||
{% block details %}{% endblock %}
|
||||
{% include "includes/usageNotes.html" %}
|
||||
{% block endNotes %}{% include "includes/usageNotes.html" %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
{% import "lib/memberHelpers.html" as memberHelpers -%}
|
||||
|
||||
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $}
|
||||
|
||||
{$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $}
|
||||
|
||||
{% if doc.constructorDoc %}
|
||||
<h2>Constructor</h2>
|
||||
{$ memberHelpers.renderMethodDetail(versionInfo, doc.constructorDoc, 'constructor') $}
|
||||
{% endif %}
|
||||
|
||||
{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
|
||||
|
||||
{$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
|
|
@ -1,4 +1,5 @@
|
|||
{% import "lib/memberHelpers.html" as memberHelper -%}
|
||||
{% import "lib/descendants.html" as descendants -%}
|
||||
|
||||
<section class="{$ doc.docType $}-overview">
|
||||
<code-example language="ts" hideCopy="true" linenums="false">
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
{%- if doc.exportAs %}
|
||||
<section class="export-as">
|
||||
<h2>Exported as</h2>
|
||||
<div>
|
||||
<code>{$ doc.exportAs $}</code>
|
||||
</div>
|
||||
<h2>Template variable references</h2>
|
||||
<table class="is-full-width list-table export-as-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Identifier</th>
|
||||
<th>Usage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%- for exportAs in doc.exportAsArray %}
|
||||
<tr class="export-as">
|
||||
<td><code>{$ exportAs $}</code></td>
|
||||
<td><code>#var="{$ exportAs $}"</code></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
{%- if doc.selector %}
|
||||
<section class="selectors">
|
||||
<h2>Selectors</h2>
|
||||
<code-example hideCopy="true" class="no-box api-heading selector">
|
||||
{%- for selector in doc.selector.split(',') %}
|
||||
{$ selector $}{% endfor %}
|
||||
</code-example>
|
||||
<table class="is-full-width list-table selector-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Selector</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%- for selector in doc.selectorArray %}
|
||||
<tr class="selector">
|
||||
<td><code>{$ selector $}</code></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,13 +1,40 @@
|
|||
{% macro renderBindings(bindings, cssContainerClass, cssItemClass, title) -%}
|
||||
{% set hasDescription = bindings | hasValues('memberDoc.description') %}
|
||||
{% set hasTypes = bindings | hasValues('memberDoc.type') %}
|
||||
{% if bindings.length %}
|
||||
<section class="{$ cssContainerClass $}">
|
||||
<h2>{$ title $}</h2>
|
||||
{% for binding in bindings %}
|
||||
<div class="{$ cssItemClass $}">
|
||||
<code>{$ binding.bindingName $}</code> bound to <code>{$ binding.memberDoc.containerDoc.name $}.{$ binding.propertyName $}</code>
|
||||
{#{$ binding.memberDoc.description | trimBlankLines | marked $}#}
|
||||
</div>
|
||||
<table class="is-full-width list-table binding-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Binding</th>
|
||||
{% if hasTypes %}<th>Type</th>{% endif %}
|
||||
{% if hasDescription %}<th>Description</th>{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for binding in bindings %}
|
||||
<tr class="{$ cssItemClass $}">
|
||||
<td><a href="#{$ binding.memberDoc.anchor $}">
|
||||
<code>{$ binding.bindingName $}
|
||||
{%- if binding.bindingName != binding.propertyName %} ({$ binding.propertyName $}){% endif-%}
|
||||
</code>
|
||||
</a></td>
|
||||
{% if hasTypes %}
|
||||
<td><label class="property-type-label"><code>{$ binding.memberDoc.type | escape $}</code></label></td>
|
||||
{% endif %}
|
||||
{% if hasDescription %}
|
||||
<td>
|
||||
{$ binding.memberDoc.shortDescription | marked $}
|
||||
{$ binding.memberDoc.description | marked $}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
{%- endmacro %}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue