From 9837e10794b5005daa181be8fde0af3ee94aebbf Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Fri, 31 Aug 2018 15:57:53 +0100 Subject: [PATCH 01/21] build(docs-infra): improve directive API doc templates Closes #22790 Closes #25530 --- aio/src/styles/2-modules/_api-pages.scss | 4 ++ .../processors/matchUpDirectiveDecorators.js | 2 + .../rendering/hasValues.js | 11 +++++- .../templates/api/class.template.html | 14 +------ .../templates/api/directive.template.html | 28 ++++++++++--- .../templates/api/export-base.template.html | 2 +- .../templates/api/includes/class-members.html | 14 +++++++ .../api/includes/class-overview.html | 1 + .../templates/api/includes/export-as.html | 21 ++++++++-- .../templates/api/includes/selectors.html | 18 +++++++-- .../templates/api/lib/directiveHelpers.html | 39 ++++++++++++++++--- 11 files changed, 118 insertions(+), 36 deletions(-) create mode 100644 aio/tools/transforms/templates/api/includes/class-members.html diff --git a/aio/src/styles/2-modules/_api-pages.scss b/aio/src/styles/2-modules/_api-pages.scss index 81e39b50a4e..e664178343d 100644 --- a/aio/src/styles/2-modules/_api-pages.scss +++ b/aio/src/styles/2-modules/_api-pages.scss @@ -31,6 +31,10 @@ } .method-table, .option-table, .list-table { + td > code { + background-color: inherit; + } + .with-github-links { align-items: center; display: flex; diff --git a/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.js b/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.js index 9557ceac2b7..23893c7adf7 100644 --- a/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.js +++ b/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.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'); diff --git a/aio/tools/transforms/angular-base-package/rendering/hasValues.js b/aio/tools/transforms/angular-base-package/rendering/hasValues.js index 7b15501fa29..d4f82a0a789 100644 --- a/aio/tools/transforms/angular-base-package/rendering/hasValues.js +++ b/aio/tools/transforms/angular-base-package/rendering/hasValues.js @@ -3,7 +3,14 @@ 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)); } }; -}; \ No newline at end of file +}; + +// Read deeply into an object via a collection of property segments +// E.g. if `obj = { a: { b: { c: 10 }}}` then `readProperty(obj, ['a', 'b', 'c'], 0)` will return `10`; +function readProperty(obj, propertySegments, index) { + const value = obj[propertySegments[index]]; + return index < (propertySegments.length - 1) ? readProperty(value, propertySegments, index + 1) : value; +} diff --git a/aio/tools/transforms/templates/api/class.template.html b/aio/tools/transforms/templates/api/class.template.html index 7446b432167..50d52311e68 100644 --- a/aio/tools/transforms/templates/api/class.template.html +++ b/aio/tools/transforms/templates/api/class.template.html @@ -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 %} -

Constructor

- {$ 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 %} diff --git a/aio/tools/transforms/templates/api/directive.template.html b/aio/tools/transforms/templates/api/directive.template.html index daeae4e5268..d49a2402bf5 100644 --- a/aio/tools/transforms/templates/api/directive.template.html +++ b/aio/tools/transforms/templates/api/directive.template.html @@ -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 %} +
+

Description

+ {$ (doc.description or '') | trimBlankLines | marked $} + {$ (doc.usageNotes or '') | trimBlankLines | marked $} +
+ {% endif %} + +

Class

+ {% include "includes/directive-overview.html" %} + + {% include "includes/class-members.html" %} {% endblock %} -{% block annotations %}{% endblock %} +{% block endNotes %}{% endblock %} \ No newline at end of file diff --git a/aio/tools/transforms/templates/api/export-base.template.html b/aio/tools/transforms/templates/api/export-base.template.html index 2d42946f447..94a02eb1a85 100644 --- a/aio/tools/transforms/templates/api/export-base.template.html +++ b/aio/tools/transforms/templates/api/export-base.template.html @@ -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 %} diff --git a/aio/tools/transforms/templates/api/includes/class-members.html b/aio/tools/transforms/templates/api/includes/class-members.html new file mode 100644 index 00000000000..7faf3ebaa75 --- /dev/null +++ b/aio/tools/transforms/templates/api/includes/class-members.html @@ -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 %} +

Constructor

+{$ 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') $} diff --git a/aio/tools/transforms/templates/api/includes/class-overview.html b/aio/tools/transforms/templates/api/includes/class-overview.html index c312d557c12..03807862a1e 100644 --- a/aio/tools/transforms/templates/api/includes/class-overview.html +++ b/aio/tools/transforms/templates/api/includes/class-overview.html @@ -1,4 +1,5 @@ {% import "lib/memberHelpers.html" as memberHelper -%} +{% import "lib/descendants.html" as descendants -%}
diff --git a/aio/tools/transforms/templates/api/includes/export-as.html b/aio/tools/transforms/templates/api/includes/export-as.html index a3fed860db1..880b824a3a0 100644 --- a/aio/tools/transforms/templates/api/includes/export-as.html +++ b/aio/tools/transforms/templates/api/includes/export-as.html @@ -1,8 +1,21 @@ {%- if doc.exportAs %}
-

Exported as

-
- {$ doc.exportAs $} -
+

Template variable references

+ + + + + + + + + {%- for exportAs in doc.exportAsArray %} + + + + + {% endfor %} + +
IdentifierUsage
{$ exportAs $}#var="{$ exportAs $}"
{% endif %} diff --git a/aio/tools/transforms/templates/api/includes/selectors.html b/aio/tools/transforms/templates/api/includes/selectors.html index 0e14513b371..c28f0ed9d91 100644 --- a/aio/tools/transforms/templates/api/includes/selectors.html +++ b/aio/tools/transforms/templates/api/includes/selectors.html @@ -1,9 +1,19 @@ {%- if doc.selector %}

Selectors

- - {%- for selector in doc.selector.split(',') %} - {$ selector $}{% endfor %} - + + + + + + + + {%- for selector in doc.selectorArray %} + + + + {% endfor %} + +
Selector
{$ selector $}
{% endif %} diff --git a/aio/tools/transforms/templates/api/lib/directiveHelpers.html b/aio/tools/transforms/templates/api/lib/directiveHelpers.html index 937f02b891e..5e0ddf91e63 100644 --- a/aio/tools/transforms/templates/api/lib/directiveHelpers.html +++ b/aio/tools/transforms/templates/api/lib/directiveHelpers.html @@ -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 %}

{$ title $}

- {% for binding in bindings %} -
- {$ binding.bindingName $} bound to {$ binding.memberDoc.containerDoc.name $}.{$ binding.propertyName $} - {#{$ binding.memberDoc.description | trimBlankLines | marked $}#} -
+ + + + + {% if hasTypes %}{% endif %} + {% if hasDescription %}{% endif %} + + + + {% for binding in bindings %} + + + {% if hasTypes %} + + {% endif %} + {% if hasDescription %} + + {% endif %} + {% endfor %} + +
BindingTypeDescription
+ {$ binding.bindingName $} + {%- if binding.bindingName != binding.propertyName %} ({$ binding.propertyName $}){% endif-%} + + + {$ binding.memberDoc.shortDescription | marked $} + {$ binding.memberDoc.description | marked $} +
{% endif %} -{%- endmacro %} \ No newline at end of file +{%- endmacro %} + + From cb70463b28255f740433f6d43bd1a2c2e7899743 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 19 Sep 2018 14:28:23 +0100 Subject: [PATCH 02/21] build(docs-infra): improve directive selector rendering If the documentation contains a `@selectors` tag then the content of that is used to describe the selectors of a directive. Otherwise the selector string is split and each selector is listed as a list item in an unordered list. --- aio/src/styles/2-modules/_api-pages.scss | 9 +++++++ .../angular-api-package/tag-defs/selectors.js | 3 +++ .../templates/api/includes/selectors.html | 25 ++++++++----------- 3 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 aio/tools/transforms/angular-api-package/tag-defs/selectors.js diff --git a/aio/src/styles/2-modules/_api-pages.scss b/aio/src/styles/2-modules/_api-pages.scss index e664178343d..4f304e32bbe 100644 --- a/aio/src/styles/2-modules/_api-pages.scss +++ b/aio/src/styles/2-modules/_api-pages.scss @@ -116,6 +116,15 @@ .ngmodule-list { list-style: none; padding: 0; + + .selector-list { + ul { + padding: 0; + li { + list-style: none; + margin-bottom: 12px; + } + } } } diff --git a/aio/tools/transforms/angular-api-package/tag-defs/selectors.js b/aio/tools/transforms/angular-api-package/tag-defs/selectors.js new file mode 100644 index 00000000000..e80cbf18af1 --- /dev/null +++ b/aio/tools/transforms/angular-api-package/tag-defs/selectors.js @@ -0,0 +1,3 @@ +module.exports = function() { + return {name: 'selectors'}; +}; diff --git a/aio/tools/transforms/templates/api/includes/selectors.html b/aio/tools/transforms/templates/api/includes/selectors.html index c28f0ed9d91..f0787340ddf 100644 --- a/aio/tools/transforms/templates/api/includes/selectors.html +++ b/aio/tools/transforms/templates/api/includes/selectors.html @@ -1,19 +1,14 @@ {%- if doc.selector %} -
+

Selectors

- - - - - - - - {%- for selector in doc.selectorArray %} - - - - {% endfor %} - -
Selector
{$ selector $}
+ {% if doc.selectors %} + {$ doc.selectors | marked $} + {% else %} +
    + {%- for selector in doc.selectorArray %} +
  • {$ selector $}
  • + {% endfor %} +
+ {% endif %}
{% endif %} From 35aa44fae44c85b39fd800609150e233c02b1d3e Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 19 Sep 2018 14:30:15 +0100 Subject: [PATCH 03/21] build(docs-infra): remove class overview from directive pages --- aio/tools/transforms/templates/api/directive.template.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/aio/tools/transforms/templates/api/directive.template.html b/aio/tools/transforms/templates/api/directive.template.html index d49a2402bf5..a33d47e5dd3 100644 --- a/aio/tools/transforms/templates/api/directive.template.html +++ b/aio/tools/transforms/templates/api/directive.template.html @@ -22,8 +22,6 @@

Description

{% endif %}

Class

- {% include "includes/directive-overview.html" %} - {% include "includes/class-members.html" %} {% endblock %} From e4bc804eb4d3d50671d8480005f0dbf2e99b4520 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 19 Sep 2018 14:31:14 +0100 Subject: [PATCH 04/21] build(docs-infra): rename example template variable in directive pages --- aio/tools/transforms/templates/api/includes/export-as.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aio/tools/transforms/templates/api/includes/export-as.html b/aio/tools/transforms/templates/api/includes/export-as.html index 880b824a3a0..f003731da8f 100644 --- a/aio/tools/transforms/templates/api/includes/export-as.html +++ b/aio/tools/transforms/templates/api/includes/export-as.html @@ -12,7 +12,7 @@

Template variable references

{%- for exportAs in doc.exportAsArray %} {$ exportAs $} - #var="{$ exportAs $}" + #myTemplateVar="{$ exportAs $}" {% endfor %} From b99c868df8513066e0692507aef32e832dee62a1 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 19 Sep 2018 21:25:30 +0100 Subject: [PATCH 05/21] build(docs-infra): directive inputs and outputs --- aio/src/styles/2-modules/_api-pages.scss | 18 ++--- .../processors/matchUpDirectiveDecorators.js | 41 ++++++----- .../matchUpDirectiveDecorators.spec.js | 68 +++++++++---------- .../templates/api/directive.template.html | 13 ++-- .../templates/api/lib/directiveHelpers.html | 40 ----------- .../templates/api/lib/memberHelpers.html | 9 +-- 6 files changed, 67 insertions(+), 122 deletions(-) delete mode 100644 aio/tools/transforms/templates/api/lib/directiveHelpers.html diff --git a/aio/src/styles/2-modules/_api-pages.scss b/aio/src/styles/2-modules/_api-pages.scss index 4f304e32bbe..db7cce98da1 100644 --- a/aio/src/styles/2-modules/_api-pages.scss +++ b/aio/src/styles/2-modules/_api-pages.scss @@ -33,6 +33,7 @@ .method-table, .option-table, .list-table { td > code { background-color: inherit; + white-space: pre; } .with-github-links { @@ -74,19 +75,6 @@ margin: 6px 0 0 10px; } - .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; @@ -126,6 +114,10 @@ } } } + + .property-name { + font-weight: bold; + } } .deprecated-api-item { diff --git a/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.js b/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.js index 23893c7adf7..797692aed7e 100644 --- a/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.js +++ b/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.js @@ -25,62 +25,59 @@ module.exports = function matchUpDirectiveDecorators() { 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'); + attachBindingInfo(doc.directiveOptions.inputs, doc.members, 'Input'); + attachBindingInfo(doc.directiveOptions.outputs, doc.members, 'Output'); } }); } }; }; -function getBindingInfo(directiveBindings, members, bindingType) { +function attachBindingInfo(directiveBindings, members, bindingType) { const bindings = {}; - // Parse the bindings from the directive decorator - if (directiveBindings) { - directiveBindings.forEach(function(binding) { - const bindingInfo = parseBinding(binding); - bindings[bindingInfo.propertyName] = bindingInfo; - }); - } - if (members) { + // Parse the bindings from the directive decorator + if (directiveBindings) { + directiveBindings.forEach(function(binding) { + const bindingInfo = parseBinding(bindingType, binding); + bindings[bindingInfo.propertyName] = bindingInfo; + }); + } + members.forEach(function(member) { if (member.decorators) { // Search for members with binding decorators member.decorators.forEach(function(decorator) { if (decorator.name === bindingType) { - bindings[member.name] = createBindingInfo(member.name, decorator.arguments[0] || member.name); + bindings[member.name] = createBindingInfo(bindingType, member.name, decorator.arguments[0] || member.name); } }); } - - // Now ensure that any bindings have the associated member attached - // Note that this binding could have come from the directive decorator + // Attach binding info to the member + // Note: this may have come from the `@Directive` decorator or from a property decorator such as `@Input`. if (bindings[member.name]) { - bindings[member.name].memberDoc = member; + member.boundTo = bindings[member.name]; } }); } - - // Convert the map back to an array - return Object.keys(bindings).map(function(key) { return bindings[key]; }); } function stripQuotes(value) { return (typeof(value) === 'string') ? value.trim().replace(/^(['"])(.*)\1$/, '$2') : value; } -function parseBinding(option) { +function parseBinding(bindingType, option) { // Directive decorator bindings are of the form: "propName : bindingName" (bindingName is optional) const optionPair = option.split(':'); const propertyName = optionPair[0].trim(); const bindingName = (optionPair[1] || '').trim() || propertyName; - return createBindingInfo(propertyName, bindingName); + return createBindingInfo(bindingType, propertyName, bindingName); } -function createBindingInfo(propertyName, bindingName) { +function createBindingInfo(bindingType, propertyName, bindingName) { return { + type: bindingType, propertyName: stripQuotes(propertyName), bindingName: stripQuotes(bindingName) }; diff --git a/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.spec.js b/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.spec.js index 6a266203d53..b4d84f6a537 100644 --- a/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.spec.js +++ b/aio/tools/transforms/angular-api-package/processors/matchUpDirectiveDecorators.spec.js @@ -59,7 +59,7 @@ describe('matchUpDirectiveDecorators processor', () => { }); it('should extract inputs and outputs from the directive decorator', () => { - const docs = [{ + const doc = { docType: 'directive', directiveOptions: { inputs: ['in1:in2', 'in3', ' in4:in5 ', ' in6 '], @@ -70,28 +70,30 @@ describe('matchUpDirectiveDecorators processor', () => { { name: 'in3' }, { name: 'in4' }, { name: 'in6' }, + { name: 'prop1' }, { name: 'out1' }, { name: 'out2' }, - { name: 'out4' } + { name: 'out4' }, + { name: 'prop2' }, ] - }]; - processorFactory().$process(docs); - expect(docs[0].inputs).toEqual([ - { propertyName: 'in1', bindingName: 'in2', memberDoc: docs[0].members[0] }, - { propertyName: 'in3', bindingName: 'in3', memberDoc: docs[0].members[1] }, - { propertyName: 'in4', bindingName: 'in5', memberDoc: docs[0].members[2] }, - { propertyName: 'in6', bindingName: 'in6', memberDoc: docs[0].members[3] } - ]); + }; - expect(docs[0].outputs).toEqual([ - { propertyName: 'out1', bindingName: 'out1', memberDoc: docs[0].members[4] }, - { propertyName: 'out2', bindingName: 'out3', memberDoc: docs[0].members[5] }, - { propertyName: 'out4', bindingName: 'out4', memberDoc: docs[0].members[6] } + processorFactory().$process([doc]); + expect(doc.members).toEqual([ + { name: 'in1', boundTo: { type: 'Input', propertyName: 'in1', bindingName: 'in2' } }, + { name: 'in3', boundTo: { type: 'Input', propertyName: 'in3', bindingName: 'in3' } }, + { name: 'in4', boundTo: { type: 'Input', propertyName: 'in4', bindingName: 'in5' } }, + { name: 'in6', boundTo: { type: 'Input', propertyName: 'in6', bindingName: 'in6' }}, + { name: 'prop1' }, + { name: 'out1', boundTo: { type: 'Output', propertyName: 'out1', bindingName: 'out1' } }, + { name: 'out2', boundTo: { type: 'Output', propertyName: 'out2', bindingName: 'out3' } }, + { name: 'out4', boundTo: { type: 'Output', propertyName: 'out4', bindingName: 'out4' }}, + { name: 'prop2' }, ]); }); it('should extract inputs and outputs from decorated properties', () => { - const docs = [{ + const doc = { docType: 'directive', directiveOptions: {}, members: [ @@ -100,21 +102,18 @@ describe('matchUpDirectiveDecorators processor', () => { { name: 'c1', decorators: [{ name: 'Input', arguments: [] }] }, { name: 'd1', decorators: [{ name: 'Output', arguments: [] }] }, ] - }]; - processorFactory().$process(docs); - expect(docs[0].inputs).toEqual([ - { propertyName: 'a1', bindingName: 'a2', memberDoc: docs[0].members[0] }, - { propertyName: 'c1', bindingName: 'c1', memberDoc: docs[0].members[2] } - ]); - - expect(docs[0].outputs).toEqual([ - { propertyName: 'b1', bindingName: 'b2', memberDoc: docs[0].members[1] }, - { propertyName: 'd1', bindingName: 'd1', memberDoc: docs[0].members[3] } + }; + processorFactory().$process([doc]); + expect(doc.members).toEqual([ + { name: 'a1', decorators: [{ name: 'Input', arguments: ['a2'] }], boundTo: { type: 'Input', propertyName: 'a1', bindingName: 'a2' } }, + { name: 'b1', decorators: [{ name: 'Output', arguments: ['b2'] }], boundTo: { type: 'Output', propertyName: 'b1', bindingName: 'b2' } }, + { name: 'c1', decorators: [{ name: 'Input', arguments: [] }], boundTo: { type: 'Input', propertyName: 'c1', bindingName: 'c1' } }, + { name: 'd1', decorators: [{ name: 'Output', arguments: [] }], boundTo: { type: 'Output', propertyName: 'd1', bindingName: 'd1' } }, ]); }); it('should merge directive inputs/outputs with decorator property inputs/outputs', () => { - const docs = [{ + const doc = { docType: 'directive', directiveOptions: { inputs: ['a1:a2'], @@ -126,16 +125,13 @@ describe('matchUpDirectiveDecorators processor', () => { { name: 'b1' }, { name: 'b3', decorators: [{ name: 'Output', arguments: ['b4'] }] }, ] - }]; - processorFactory().$process(docs); - expect(docs[0].inputs).toEqual([ - { propertyName: 'a1', bindingName: 'a2', memberDoc: docs[0].members[0] }, - { propertyName: 'a3', bindingName: 'a4', memberDoc: docs[0].members[1] } - ]); - - expect(docs[0].outputs).toEqual([ - { propertyName: 'b1', bindingName: 'b2', memberDoc: docs[0].members[2] }, - { propertyName: 'b3', bindingName: 'b4', memberDoc: docs[0].members[3] } + }; + processorFactory().$process([doc]); + expect(doc.members).toEqual([ + { name: 'a1', boundTo: { type: 'Input', propertyName: 'a1', bindingName: 'a2' } }, + { name: 'a3', boundTo: { type: 'Input', propertyName: 'a3', bindingName: 'a4' }, decorators: [{ name: 'Input', arguments: ['a4'] }] }, + { name: 'b1', boundTo: { type: 'Output', propertyName: 'b1', bindingName: 'b2' } }, + { name: 'b3', boundTo: { type: 'Output', propertyName: 'b3', bindingName: 'b4' }, decorators: [{ name: 'Output', arguments: ['b4'] }] }, ]); }); }); diff --git a/aio/tools/transforms/templates/api/directive.template.html b/aio/tools/transforms/templates/api/directive.template.html index a33d47e5dd3..e84966307ad 100644 --- a/aio/tools/transforms/templates/api/directive.template.html +++ b/aio/tools/transforms/templates/api/directive.template.html @@ -1,4 +1,4 @@ -{% import "lib/directiveHelpers.html" as directiveHelper -%} +{% import "lib/memberHelpers.html" as memberHelpers -%} {% extends 'class.template.html' -%} {% block overview %}{% endblock %} @@ -7,9 +7,7 @@ {% include "includes/ngmodule.html" %} {% include "includes/selectors.html" %} - {$ directiveHelper.renderBindings(doc.inputs, 'inputs', 'input', 'Inputs') $} - - {$ directiveHelper.renderBindings(doc.outputs, 'outputs', 'output', 'Outputs') $} + {$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $} {% include "includes/export-as.html" %} @@ -21,8 +19,9 @@

Description

{% endif %} -

Class

- {% include "includes/class-members.html" %} -{% endblock %} + {$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $} + {$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $} + {$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $} + {% endblock %} {% block endNotes %}{% endblock %} \ No newline at end of file diff --git a/aio/tools/transforms/templates/api/lib/directiveHelpers.html b/aio/tools/transforms/templates/api/lib/directiveHelpers.html deleted file mode 100644 index 5e0ddf91e63..00000000000 --- a/aio/tools/transforms/templates/api/lib/directiveHelpers.html +++ /dev/null @@ -1,40 +0,0 @@ -{% macro renderBindings(bindings, cssContainerClass, cssItemClass, title) -%} -{% set hasDescription = bindings | hasValues('memberDoc.description') %} -{% set hasTypes = bindings | hasValues('memberDoc.type') %} -{% if bindings.length %} -
-

{$ title $}

- - - - - {% if hasTypes %}{% endif %} - {% if hasDescription %}{% endif %} - - - - {% for binding in bindings %} - - - {% if hasTypes %} - - {% endif %} - {% if hasDescription %} - - {% endif %} - - {% endfor %} - -
BindingTypeDescription
- {$ binding.bindingName $} - {%- if binding.bindingName != binding.propertyName %} ({$ binding.propertyName $}){% endif-%} - - - {$ binding.memberDoc.shortDescription | marked $} - {$ binding.memberDoc.description | marked $} -
-
-{% endif %} -{%- endmacro %} - - diff --git a/aio/tools/transforms/templates/api/lib/memberHelpers.html b/aio/tools/transforms/templates/api/lib/memberHelpers.html index 08134a6499c..9628a531619 100644 --- a/aio/tools/transforms/templates/api/lib/memberHelpers.html +++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html @@ -170,7 +170,6 @@

{$ headingText $}

{%- macro renderProperties(properties, containerClass, propertyClass, headingText, headings) -%} {% set nonInternalProperties = properties | filterByPropertyValue('internal', undefined) %} -{% set hasTypes = properties | hasValues('type') %} {% if nonInternalProperties.length -%}

{$ headingText $}

@@ -178,15 +177,17 @@

{$ headingText $}

{$ headings[0] or 'Property' $} - {% if hasTypes %}{$ headings[1] or 'Type' $}{% endif %} {$ headings[2] or 'Description' $} {% for property in nonInternalProperties %} - {$ property.name $} - {% if hasTypes %}{% endif %} + + {%- if property.boundTo %}@{$ property.boundTo.type $}({$ property.boundTo.bindingName $}) +{% endif -%}{$ property.name $}{% if property.type %}: {$ property.type | escape $}{% endif -%} + + {%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}Read-only.{% endif %} {% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %} From ff747260fad8c6d369d12048abf2cb73e55268da Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Thu, 20 Sep 2018 12:57:34 +0100 Subject: [PATCH 06/21] build(docs-infra): display inherited members on directives --- aio/src/styles/2-modules/_api-pages.scss | 3 ++- .../templates/api/directive.template.html | 27 ++++++++++++++++++- .../api/includes/directive-overview.html | 12 --------- .../templates/api/lib/memberHelpers.html | 4 +-- 4 files changed, 30 insertions(+), 16 deletions(-) delete mode 100644 aio/tools/transforms/templates/api/includes/directive-overview.html diff --git a/aio/src/styles/2-modules/_api-pages.scss b/aio/src/styles/2-modules/_api-pages.scss index db7cce98da1..1cef682da2c 100644 --- a/aio/src/styles/2-modules/_api-pages.scss +++ b/aio/src/styles/2-modules/_api-pages.scss @@ -104,8 +104,9 @@ .ngmodule-list { list-style: none; padding: 0; + } - .selector-list { + .selector-list, .inherited-members-list { ul { padding: 0; li { diff --git a/aio/tools/transforms/templates/api/directive.template.html b/aio/tools/transforms/templates/api/directive.template.html index e84966307ad..55bb22ec37d 100644 --- a/aio/tools/transforms/templates/api/directive.template.html +++ b/aio/tools/transforms/templates/api/directive.template.html @@ -1,13 +1,37 @@ {% import "lib/memberHelpers.html" as memberHelpers -%} {% extends 'class.template.html' -%} +{% macro renderAncestorMembers(doc, collectionName) %} +{%- for ancestor in doc.extendsClauses %}{% if ancestor.doc %} +{% set nonInternalMembers = ancestor.doc[collectionName] | filterByPropertyValue('internal', undefined) %} +{% if nonInternalMembers.length -%} +
+

Inherited from {$ ancestor.doc.id $}

+ +
+{% endif %} +{$ renderAncestorMembers(ancestor.doc, collectionName) $} +{% endif %}{% endfor -%} +{% endmacro %} + +{% macro renderProperties(doc, heading) %} +{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', heading) $} +{$ renderAncestorMembers(doc, 'properties') $} +{% endmacro %} + {% block overview %}{% endblock %} {% block details -%} {% include "includes/ngmodule.html" %} {% include "includes/selectors.html" %} - {$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $} + {$ renderProperties(doc, 'Properties') $} {% include "includes/export-as.html" %} @@ -22,6 +46,7 @@

Description

{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $} {$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $} {$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $} + {$ renderAncestorMembers(doc, 'methods') $} {% endblock %} {% block endNotes %}{% endblock %} \ No newline at end of file diff --git a/aio/tools/transforms/templates/api/includes/directive-overview.html b/aio/tools/transforms/templates/api/includes/directive-overview.html deleted file mode 100644 index 0946b1b0a6a..00000000000 --- a/aio/tools/transforms/templates/api/includes/directive-overview.html +++ /dev/null @@ -1,12 +0,0 @@ -{% import "lib/memberHelpers.html" as memberHelper -%} - -
-{% for decorator in doc.decorators %} -@{$ 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 %} - {$ memberHelper.renderMemberSyntax(member, 1) $}{% endif %}{% endfor %}{% endif -%} -{$ memberHelper.renderMembers(doc) $} -} - -
diff --git a/aio/tools/transforms/templates/api/lib/memberHelpers.html b/aio/tools/transforms/templates/api/lib/memberHelpers.html index 9628a531619..b984ed69c89 100644 --- a/aio/tools/transforms/templates/api/lib/memberHelpers.html +++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html @@ -168,11 +168,11 @@

{$ headingText $}

{%- endmacro -%} -{%- macro renderProperties(properties, containerClass, propertyClass, headingText, headings) -%} +{%- macro renderProperties(properties, containerClass, propertyClass, headingText, headings, headingLevel = 2) -%} {% set nonInternalProperties = properties | filterByPropertyValue('internal', undefined) %} {% if nonInternalProperties.length -%}
-

{$ headingText $}

+ {$ headingText $} From ac7d6895784c48542f47b9b17f15194e83277f84 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Thu, 20 Sep 2018 12:58:10 +0100 Subject: [PATCH 07/21] build(docs-infra): include directives etc in class descendants lists --- aio/tests/e2e/api.e2e-spec.ts | 14 +++++++++++++- .../rendering/filterByPropertyValue.js | 9 +++++++-- .../rendering/filterByPropertyValue.spec.js | 13 ++++++++++++- .../templates/api/includes/class-overview.html | 2 +- .../templates/api/includes/interface-overview.html | 2 +- .../transforms/templates/api/lib/descendants.html | 12 ++++++------ 6 files changed, 40 insertions(+), 12 deletions(-) diff --git a/aio/tests/e2e/api.e2e-spec.ts b/aio/tests/e2e/api.e2e-spec.ts index 9ff6625eef3..c556ed11e70 100644 --- a/aio/tests/e2e/api.e2e-spec.ts +++ b/aio/tests/e2e/api.e2e-spec.ts @@ -8,7 +8,19 @@ describe('Api pages', function() { it('should show direct and indirect subclasses of a class', () => { const page = new ApiPage('api/forms/AbstractControlDirective'); - expect(page.getDescendants('class')).toEqual(['ControlContainer', 'AbstractFormGroupDirective', 'NgControl']); + expect(page.getDescendants('class')).toEqual([ + 'ControlContainer', + 'AbstractFormGroupDirective', + 'NgModelGroup', + 'FormGroupName', + 'NgForm', + 'FormGroupDirective', + 'FormArrayName', + 'NgControl', + 'NgModel', + 'FormControlDirective', + 'FormControlName' + ]); }); it('should show child interfaces that extend an interface', () => { diff --git a/aio/tools/transforms/angular-base-package/rendering/filterByPropertyValue.js b/aio/tools/transforms/angular-base-package/rendering/filterByPropertyValue.js index 9b3c3b6fcaa..001b4b24b62 100644 --- a/aio/tools/transforms/angular-base-package/rendering/filterByPropertyValue.js +++ b/aio/tools/transforms/angular-base-package/rendering/filterByPropertyValue.js @@ -3,7 +3,12 @@ module.exports = function filterBy() { name: 'filterByPropertyValue', process: function(list, property, value) { if (!list) return list; - return list.filter(item => item[property] === value); + const values = Array.isArray(value) ? value : [value]; + return list.filter(item => values.some(value => compare(item[property], value))); } }; -}; \ No newline at end of file +}; + +function compare(actual, expected) { + return expected instanceof(RegExp) ? expected.test(actual) : actual === expected; +} \ No newline at end of file diff --git a/aio/tools/transforms/angular-base-package/rendering/filterByPropertyValue.spec.js b/aio/tools/transforms/angular-base-package/rendering/filterByPropertyValue.spec.js index d2c5823bb5d..b3874d7931e 100644 --- a/aio/tools/transforms/angular-base-package/rendering/filterByPropertyValue.spec.js +++ b/aio/tools/transforms/angular-base-package/rendering/filterByPropertyValue.spec.js @@ -7,8 +7,19 @@ describe('filterByPropertyValue filter', () => { it('should be called "filterByPropertyValue"', function() { expect(filter.name).toEqual('filterByPropertyValue'); }); - it('should filter out items that do not match the given property value', function() { + it('should filter out items that do not match the given property string value', function() { expect(filter.process([{ a: 1 }, { a: 2 }, { b: 1 }, { a: 1, b: 2 }, { a: null }, { a: undefined }], 'a', 1)) .toEqual([{ a: 1 }, { a: 1, b: 2 }]); }); + + + it('should filter out items that do not match the given property regex value', function() { + expect(filter.process([{ a: '1' }, { a: '12' }, { b: '1' }, { a: 'a' }, { a: '1', b: '2' }, { a: null }, { a: undefined }], 'a', /\d/)) + .toEqual([{ a: '1' }, { a: '12' }, { a: '1', b: '2' }]); + }); + + it('should filter out items that do not match the given array of property regex/string values', function() { + expect(filter.process([{ a: '1' }, { a: '12' }, { b: '1' }, { a: 'a' }, { a: '1', b: '2' }, { a: null }, { a: undefined }], 'a', [/\d/, 'a'])) + .toEqual([{ a: '1' }, { a: '12' }, { a: 'a' }, { a: '1', b: '2' }]); + }); }); \ No newline at end of file diff --git a/aio/tools/transforms/templates/api/includes/class-overview.html b/aio/tools/transforms/templates/api/includes/class-overview.html index 03807862a1e..64f4f388c7e 100644 --- a/aio/tools/transforms/templates/api/includes/class-overview.html +++ b/aio/tools/transforms/templates/api/includes/class-overview.html @@ -6,5 +6,5 @@ {% if doc.isAbstract %}abstract {% endif%}class {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} {{$ memberHelper.renderMembers(doc) $} } -{$ descendants.renderDescendants(doc, 'class', 'Subclasses') $} +{$ descendants.renderDescendants(doc, 'class', 'Subclasses', true, r/class|directive|pipe|decorator/) $} diff --git a/aio/tools/transforms/templates/api/includes/interface-overview.html b/aio/tools/transforms/templates/api/includes/interface-overview.html index 7b2b8d6b063..15df777c8ec 100644 --- a/aio/tools/transforms/templates/api/includes/interface-overview.html +++ b/aio/tools/transforms/templates/api/includes/interface-overview.html @@ -6,5 +6,5 @@ } {$ descendants.renderDescendants(doc, 'interface', 'Child interfaces') $} -{$ descendants.renderDescendants(doc, 'class', 'Class implementations') $} +{$ descendants.renderDescendants(doc, 'class', 'Class implementations', true, r/class|directive|pipe|decorator/) $} \ No newline at end of file diff --git a/aio/tools/transforms/templates/api/lib/descendants.html b/aio/tools/transforms/templates/api/lib/descendants.html index 73b097a1a9e..ac9bd3c6514 100644 --- a/aio/tools/transforms/templates/api/lib/descendants.html +++ b/aio/tools/transforms/templates/api/lib/descendants.html @@ -1,22 +1,22 @@ -{% macro renderDescendantList(descendants, docType, recursed) %} +{% macro renderDescendantList(descendants, descendantType, recursed, docTypeMatcher) %} {% if descendants.length %}
    {% for descendant in descendants %}
  • {$ descendant.name $} - {$ renderDescendantList(descendant.descendants | filterByPropertyValue('docType', docType), docType, recursed) $} + {$ renderDescendantList(descendant.descendants | filterByPropertyValue('docType', docTypeMatcher), docType, recursed, docTypeMatcher) $}
  • {% endfor %}
{% endif %} {% endmacro -%} -{%- macro renderDescendants(doc, docType, title='', recursed=true) %} - {% set descendants = doc.descendants | filterByPropertyValue('docType', docType) %} +{%- macro renderDescendants(doc, descendantType, title='', recursed=true, docTypeMatcher = descendantType) %} + {% set descendants = doc.descendants | filterByPropertyValue('docType', docTypeMatcher) %} {% if descendants.length %} -
+
{% if title %}

{$ title $}

{% endif %} - {$ renderDescendantList(descendants, docType, recursed) $} + {$ renderDescendantList(descendants, descendantType, recursed, docTypeMatcher) $}
{% endif %} {% endmacro %} \ No newline at end of file From fe41985f9e9e04177427d5fc7d6978b693e0bcaf Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Fri, 21 Sep 2018 14:06:57 +0100 Subject: [PATCH 08/21] build(docs-infra): move directive macros into memberHelpers.html --- .../templates/api/directive.template.html | 28 ++-------------- .../templates/api/lib/memberHelpers.html | 33 ++++++++++++++++--- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/aio/tools/transforms/templates/api/directive.template.html b/aio/tools/transforms/templates/api/directive.template.html index 55bb22ec37d..1596da9825c 100644 --- a/aio/tools/transforms/templates/api/directive.template.html +++ b/aio/tools/transforms/templates/api/directive.template.html @@ -1,37 +1,13 @@ {% import "lib/memberHelpers.html" as memberHelpers -%} {% extends 'class.template.html' -%} -{% macro renderAncestorMembers(doc, collectionName) %} -{%- for ancestor in doc.extendsClauses %}{% if ancestor.doc %} -{% set nonInternalMembers = ancestor.doc[collectionName] | filterByPropertyValue('internal', undefined) %} -{% if nonInternalMembers.length -%} -
-

Inherited from {$ ancestor.doc.id $}

- -
-{% endif %} -{$ renderAncestorMembers(ancestor.doc, collectionName) $} -{% endif %}{% endfor -%} -{% endmacro %} - -{% macro renderProperties(doc, heading) %} -{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', heading) $} -{$ renderAncestorMembers(doc, 'properties') $} -{% endmacro %} - {% block overview %}{% endblock %} {% block details -%} {% include "includes/ngmodule.html" %} {% include "includes/selectors.html" %} - {$ renderProperties(doc, 'Properties') $} + {$ memberHelpers.renderDirectiveProperties(doc, 'Properties') $} {% include "includes/export-as.html" %} @@ -46,7 +22,7 @@

Description

{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $} {$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $} {$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $} - {$ renderAncestorMembers(doc, 'methods') $} + {$ memberHelpers.renderDirectiveAncestors(doc, 'methods') $} {% endblock %} {% block endNotes %}{% endblock %} \ No newline at end of file diff --git a/aio/tools/transforms/templates/api/lib/memberHelpers.html b/aio/tools/transforms/templates/api/lib/memberHelpers.html index b984ed69c89..3c7d615bba5 100644 --- a/aio/tools/transforms/templates/api/lib/memberHelpers.html +++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html @@ -28,12 +28,14 @@ {%- endmacro -%} {%- macro renderMemberSyntax(member, truncateLines) -%} + {%- if member.boundTo %}@{$ member.boundTo.type $}({$ member.boundTo.bindingName $}) +{% endif %} {%- if member.accessibility !== 'public' %}{$ member.accessibility $} {% endif -%} {%- if member.isAbstract %}abstract {% endif -%} {%- if member.isStatic %}static {% endif -%} {%- if (member.isGetAccessor or member.isReadonly) and not member.isSetAccessor %}get {% endif -%} {%- if member.isSetAccessor and not member.isGetAccessor %}set {% endif -%} - {$ member.name $}{$ member.typeParameters | escape $}{% if not member.isGetAccessor %}{$ params.paramList(member.parameters, truncateLines) | trim $}{% endif %} + {$ member.name $}{$ member.typeParameters | escape $}{% if not member.isGetAccessor %}{$ params.paramList(member.parameters, truncateLines) | trim $}{% endif %} {%- if member.isOptional %}?{% endif -%} {$ params.returnType(member.type) | trim | truncateCode(truncateLines) $} {%- endmacro -%} @@ -184,9 +186,8 @@

{$ headingText $}

{% for property in nonInternalProperties %}
- + From 562b6d30f2deb08e690c79b456d2fb8879742f4d Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Sep 2018 13:35:54 +0100 Subject: [PATCH 13/21] fixup! build(docs-infra): improve directive API doc templates --- aio/src/styles/2-modules/_code.scss | 1 + .../rendering/hasValues.js | 13 ++++++++++--- .../rendering/hasValues.spec.js | 19 +++++++++++++++---- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/aio/src/styles/2-modules/_code.scss b/aio/src/styles/2-modules/_code.scss index 173f5242742..98749dd37c3 100644 --- a/aio/src/styles/2-modules/_code.scss +++ b/aio/src/styles/2-modules/_code.scss @@ -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. */ diff --git a/aio/tools/transforms/angular-base-package/rendering/hasValues.js b/aio/tools/transforms/angular-base-package/rendering/hasValues.js index d4f82a0a789..c9578adc93c 100644 --- a/aio/tools/transforms/angular-base-package/rendering/hasValues.js +++ b/aio/tools/transforms/angular-base-package/rendering/hasValues.js @@ -8,9 +8,16 @@ module.exports = function hasValues() { }; }; -// Read deeply into an object via a collection of property segments -// E.g. if `obj = { a: { b: { c: 10 }}}` then `readProperty(obj, ['a', 'b', 'c'], 0)` will return `10`; +/** + * 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 index < (propertySegments.length - 1) ? readProperty(value, propertySegments, index + 1) : value; + return !!value && (index === propertySegments.length - 1 || readProperty(value, propertySegments, index + 1)); } diff --git a/aio/tools/transforms/angular-base-package/rendering/hasValues.spec.js b/aio/tools/transforms/angular-base-package/rendering/hasValues.spec.js index 7b057bcafd4..ceec6bd18c7 100644 --- a/aio/tools/transforms/angular-base-package/rendering/hasValues.spec.js +++ b/aio/tools/transforms/angular-base-package/rendering/hasValues.spec.js @@ -7,13 +7,24 @@ 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() { + 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([{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); + 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); expect(filter.process({}, 'a')).toEqual(false); - expect(filter.process([{a: 1}], 'a')).toEqual(true); + expect(filter.process({}, 'a.b')).toEqual(false); + 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: 2}], 'a.b')).toEqual(false); + expect(filter.process([{a: {}}], 'a.b.c')).toEqual(false); }); }); \ No newline at end of file From e6f728fd080b3c4eb91f9fc577e92d4590a9c38b Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Sep 2018 13:36:37 +0100 Subject: [PATCH 14/21] fixup! build(docs-infra): include directives etc in class descendants lists --- aio/tools/transforms/templates/api/lib/descendants.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aio/tools/transforms/templates/api/lib/descendants.html b/aio/tools/transforms/templates/api/lib/descendants.html index ac9bd3c6514..4f78d6212bd 100644 --- a/aio/tools/transforms/templates/api/lib/descendants.html +++ b/aio/tools/transforms/templates/api/lib/descendants.html @@ -11,7 +11,7 @@ {% endif %} {% endmacro -%} -{%- macro renderDescendants(doc, descendantType, title='', recursed=true, docTypeMatcher = descendantType) %} +{%- macro renderDescendants(doc, descendantType, title='', recursed=true, docTypeMatcher=descendantType) %} {% set descendants = doc.descendants | filterByPropertyValue('docType', docTypeMatcher) %} {% if descendants.length %}
From 5e8ebcc79aafa9bf8905efe44208de4dd7effd7e Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Sep 2018 13:38:15 +0100 Subject: [PATCH 15/21] fixup! build(docs-infra): move directive macros into memberHelpers.html --- aio/tools/transforms/templates/api/lib/memberHelpers.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aio/tools/transforms/templates/api/lib/memberHelpers.html b/aio/tools/transforms/templates/api/lib/memberHelpers.html index 3f27429f168..798675dbaa8 100644 --- a/aio/tools/transforms/templates/api/lib/memberHelpers.html +++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html @@ -28,8 +28,9 @@ {%- endmacro -%} {%- macro renderMemberSyntax(member, truncateLines) -%} - {%- if member.boundTo %}@{$ member.boundTo.type $}({$ member.boundTo.bindingName $}) -{% endif %} + {%- if member.boundTo %}@{$ member.boundTo.type $}( + {%- if member.boundTo.propertyName != member.boundTo.bindingName %}'{$ member.boundTo.bindingName $}'{% endif -%} + )
{% endif -%} {%- if member.accessibility !== 'public' %}{$ member.accessibility $} {% endif -%} {%- if member.isAbstract %}abstract {% endif -%} {%- if member.isStatic %}static {% endif -%} From 28dae87429d64e1e35baf7feaf0f234e1767c078 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Sep 2018 13:39:51 +0100 Subject: [PATCH 16/21] build(docs-infra): simplify property syntax rendering --- aio/src/styles/2-modules/_api-pages.scss | 2 +- aio/tools/transforms/templates/api/lib/memberHelpers.html | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/aio/src/styles/2-modules/_api-pages.scss b/aio/src/styles/2-modules/_api-pages.scss index e4d649f00ee..bed79e1dcf1 100644 --- a/aio/src/styles/2-modules/_api-pages.scss +++ b/aio/src/styles/2-modules/_api-pages.scss @@ -96,7 +96,7 @@ } } - .from-constructor, .read-only-property { + .from-constructor, .read-only-property, .write-only-property { font-style: italic; color: $blue; } diff --git a/aio/tools/transforms/templates/api/lib/memberHelpers.html b/aio/tools/transforms/templates/api/lib/memberHelpers.html index 798675dbaa8..cacdc096bcf 100644 --- a/aio/tools/transforms/templates/api/lib/memberHelpers.html +++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html @@ -34,8 +34,6 @@ {%- if member.accessibility !== 'public' %}{$ member.accessibility $} {% endif -%} {%- if member.isAbstract %}abstract {% endif -%} {%- if member.isStatic %}static {% endif -%} - {%- if (member.isGetAccessor or member.isReadonly) and not member.isSetAccessor %}get {% endif -%} - {%- if member.isSetAccessor and not member.isGetAccessor %}set {% endif -%} {$ member.name $}{$ member.typeParameters | escape $}{% if not member.isGetAccessor %}{$ params.paramList(member.parameters, truncateLines) | trim $}{% endif %} {%- if member.isOptional %}?{% endif -%} {$ params.returnType(member.type) | trim | truncateCode(truncateLines) $} @@ -191,8 +189,9 @@

{$ headingText $}

{$ renderMemberSyntax(property) $}
From 779ca39059fff7e4756ad8fe097632df845d037a Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Sep 2018 14:05:38 +0100 Subject: [PATCH 17/21] build(docs-infra): fix formatting of entry point export table Now that `list-table` cells are `pre` formatterd we must be careful of what whitespace appears in text nodes. --- aio/tools/transforms/templates/api/package.template.html | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/aio/tools/transforms/templates/api/package.template.html b/aio/tools/transforms/templates/api/package.template.html index 73525bfeeaa..2dab4b53bd8 100644 --- a/aio/tools/transforms/templates/api/package.template.html +++ b/aio/tools/transforms/templates/api/package.template.html @@ -8,10 +8,7 @@

{$ title $}

- {%- if property.boundTo %}@{$ property.boundTo.type $}({$ property.boundTo.bindingName $}) -{% endif -%}{$ property.name $}{% if property.type %}: {$ property.type | escape $}{% endif -%} - + + {$ renderMemberSyntax(property) $} {%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}Read-only.{% endif %} @@ -201,3 +202,27 @@

{$ headingText $}

{%- endif -%} {%- endmacro -%} + +{% macro renderDirectiveAncestors(doc, collectionName) %} +{%- for ancestor in doc.extendsClauses %}{% if ancestor.doc %} +{% set nonInternalMembers = ancestor.doc[collectionName] | filterByPropertyValue('internal', undefined) %} +{% if nonInternalMembers.length -%} +
+

Inherited from {$ ancestor.doc.id $}

+ +
+{% endif %} +{$ renderDirectiveAncestors(ancestor.doc, collectionName) $} +{% endif %}{% endfor -%} +{% endmacro %} + +{% macro renderDirectiveProperties(doc, heading) %} +{$ renderProperties(doc.properties, 'instance-properties', 'instance-property', heading) $} +{$ renderDirectiveAncestors(doc, 'properties') $} +{% endmacro %} From 4973ddcb29f59e57333580bae58df5d338d92bbd Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Fri, 21 Sep 2018 14:07:51 +0100 Subject: [PATCH 09/21] build(docs-infra): improve directive selector rendering `:not(...)` blocks are now rendered as italic, while the rest of the selector is bold. --- aio/src/styles/2-modules/_api-pages.scss | 11 ++++++++++- .../transforms/templates/api/includes/selectors.html | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/aio/src/styles/2-modules/_api-pages.scss b/aio/src/styles/2-modules/_api-pages.scss index 1cef682da2c..e4d649f00ee 100644 --- a/aio/src/styles/2-modules/_api-pages.scss +++ b/aio/src/styles/2-modules/_api-pages.scss @@ -116,7 +116,16 @@ } } - .property-name { + .selector-list { + li, a { + font-weight: bold; + i { + font-weight: normal; + } + } + } + + .member-name { font-weight: bold; } } diff --git a/aio/tools/transforms/templates/api/includes/selectors.html b/aio/tools/transforms/templates/api/includes/selectors.html index f0787340ddf..63c92ece55d 100644 --- a/aio/tools/transforms/templates/api/includes/selectors.html +++ b/aio/tools/transforms/templates/api/includes/selectors.html @@ -6,7 +6,7 @@

Selectors

{% else %}
    {%- for selector in doc.selectorArray %} -
  • {$ selector $}
  • +
  • {$ selector | replace(r/(:not\([^()]+\))/g, '$1') $}
  • {% endfor %}
{% endif %} From 9bbab42fb66c7f995111f03202d831416c68c08e Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Fri, 21 Sep 2018 14:11:49 +0100 Subject: [PATCH 10/21] build(docs-infra): pluralize NgModule(s) heading as appropriate --- aio/tools/transforms/templates/api/includes/ngmodule.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aio/tools/transforms/templates/api/includes/ngmodule.html b/aio/tools/transforms/templates/api/includes/ngmodule.html index a3421b9bed8..e28304ab55f 100644 --- a/aio/tools/transforms/templates/api/includes/ngmodule.html +++ b/aio/tools/transforms/templates/api/includes/ngmodule.html @@ -1,4 +1,4 @@ -

NgModules

+{% if doc.ngModules.length == 1 %}

NgModule

{% else %}

NgModules

{% endif %}
    {% for ngModule in doc.ngModules %}
  • From d5710f0bc062cdfc0d9fbb5910e782de7299da8b Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Sat, 22 Sep 2018 19:51:53 +0100 Subject: [PATCH 11/21] build(docs-infra): add short description "See more" link If there is additional (non-short) description then add in a link to the short description to take the reader there. --- aio/tools/transforms/templates/api/export-base.template.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aio/tools/transforms/templates/api/export-base.template.html b/aio/tools/transforms/templates/api/export-base.template.html index 94a02eb1a85..9b94d5a312d 100644 --- a/aio/tools/transforms/templates/api/export-base.template.html +++ b/aio/tools/transforms/templates/api/export-base.template.html @@ -1,7 +1,10 @@ {% extends 'base.template.html' -%} {% block body %} -

    {$ doc.shortDescription | marked $}

    +
    + {$ doc.shortDescription | marked $} + {% if doc.description %}

    See more...

    {% endif %} +
    {% include "includes/security-notes.html" %} {% include "includes/deprecation.html" %} {% block overview %}{% endblock %} From 84fcf217036323aa557a12ebd189228956fdced4 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Sep 2018 13:31:52 +0100 Subject: [PATCH 12/21] build(docs-infra): remove unused property table heading --- aio/tools/transforms/templates/api/enum.template.html | 2 +- aio/tools/transforms/templates/api/lib/memberHelpers.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aio/tools/transforms/templates/api/enum.template.html b/aio/tools/transforms/templates/api/enum.template.html index 0f07f88cbc1..93321b4ced5 100644 --- a/aio/tools/transforms/templates/api/enum.template.html +++ b/aio/tools/transforms/templates/api/enum.template.html @@ -10,5 +10,5 @@ {% include "includes/description.html" %} -{$ memberHelpers.renderProperties(doc.properties, 'members', 'member', 'Members', ['Member', 'Value']) $} +{$ memberHelpers.renderProperties(doc.properties, 'members', 'member', 'Members', ['Member']) $} {% endblock %} \ No newline at end of file diff --git a/aio/tools/transforms/templates/api/lib/memberHelpers.html b/aio/tools/transforms/templates/api/lib/memberHelpers.html index 3c7d615bba5..3f27429f168 100644 --- a/aio/tools/transforms/templates/api/lib/memberHelpers.html +++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html @@ -179,7 +179,7 @@

    {$ headingText $}

{$ headings[0] or 'Property' $}{$ headings[2] or 'Description' $}{$ headings[1] or 'Description' $}
- {%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}Read-only.{% endif %} - {% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %} + {%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}Read-only.{% endif %} + {%- if property.isSetAccessor and not property.isGetAccessor %}Write-only.{% endif %} + {% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %} {$ (property.description or property.constructorParamDoc.description) | marked $} {% if property.constructorParamDoc %} Declared in constructor.{% endif %}
{% for item in filteredItems %} - + From a5d96911d6cd06f90f0687b37f01bec909388ca1 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Sep 2018 15:13:55 +0100 Subject: [PATCH 19/21] fixup! build(docs-infra): improve directive API doc templates --- .../rendering/hasValues.spec.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/aio/tools/transforms/angular-base-package/rendering/hasValues.spec.js b/aio/tools/transforms/angular-base-package/rendering/hasValues.spec.js index ceec6bd18c7..c260f5d17ac 100644 --- a/aio/tools/transforms/angular-base-package/rendering/hasValues.spec.js +++ b/aio/tools/transforms/angular-base-package/rendering/hasValues.spec.js @@ -15,11 +15,24 @@ describe('hasValues filter', () => { 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); From d882c07d3e5ea206c465ccc19a02cafee5c6df87 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Fri, 28 Sep 2018 11:28:46 +0100 Subject: [PATCH 20/21] fixup! build(docs-infra): simplify property syntax rendering --- aio/tests/e2e/api.e2e-spec.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/aio/tests/e2e/api.e2e-spec.ts b/aio/tests/e2e/api.e2e-spec.ts index c556ed11e70..b97e89e4f30 100644 --- a/aio/tests/e2e/api.e2e-spec.ts +++ b/aio/tests/e2e/api.e2e-spec.ts @@ -38,14 +38,9 @@ describe('Api pages', function() { expect(page.getOverview('type-alias').getText()).toContain('type HttpEvent'); }); - it('should show readonly properties as getters', () => { - const page = new ApiPage('api/common/http/HttpRequest'); - expect(page.getOverview('class').getText()).toContain('get body: T | null'); - }); - it('should not show parenthesis for getters', () => { const page = new ApiPage('api/core/NgModuleRef'); - expect(page.getOverview('class').getText()).toContain('get injector: Injector'); + expect(page.getOverview('class').getText()).toContain('injector: Injector'); }); it('should show both type and initializer if set', () => { From 97721279fc78a85531001ba5259e1400c37613d0 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Fri, 28 Sep 2018 12:58:21 +0100 Subject: [PATCH 21/21] fix(docs-infra): remove unnecessary margin on short descriptions (This was added in 405d97431fa374afdd5cddc6780f8949ee76a2c6 but it is not clear the reasoning. It looks better to remove it now.) --- aio/src/styles/2-modules/_api-pages.scss | 4 ---- 1 file changed, 4 deletions(-) diff --git a/aio/src/styles/2-modules/_api-pages.scss b/aio/src/styles/2-modules/_api-pages.scss index bed79e1dcf1..97b5056f818 100644 --- a/aio/src/styles/2-modules/_api-pages.scss +++ b/aio/src/styles/2-modules/_api-pages.scss @@ -71,10 +71,6 @@ font-weight: bold; } - .short-description { - margin: 6px 0 0 10px; - } - .parameters-table { margin-top: 0; font-size: 14px;
- {$ item.name $} - {$ item.name $} {% if item.deprecated !== undefined %}{$ ('**Deprecated:** ' + item.deprecated) | marked $}{% endif %} {% if item.shortDescription %}{$ item.shortDescription | marked $}{% endif %} From 921009088bff183fcd8d72de9a5d87ffea3a7160 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Sep 2018 15:13:33 +0100 Subject: [PATCH 18/21] fixup! build(docs-infra): simplify property syntax rendering --- aio/tools/transforms/templates/api/lib/memberHelpers.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aio/tools/transforms/templates/api/lib/memberHelpers.html b/aio/tools/transforms/templates/api/lib/memberHelpers.html index cacdc096bcf..476a77149a9 100644 --- a/aio/tools/transforms/templates/api/lib/memberHelpers.html +++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html @@ -189,9 +189,9 @@

{$ headingText $}

{$ renderMemberSyntax(property) $}
- {%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}Read-only.{% endif %} - {%- if property.isSetAccessor and not property.isGetAccessor %}Write-only.{% endif %} - {% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %} + {%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}Read-only.{% endif %} + {%- if property.isSetAccessor and not property.isGetAccessor %}Write-only.{% endif %} + {% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %} {$ (property.description or property.constructorParamDoc.description) | marked $} {% if property.constructorParamDoc %} Declared in constructor.{% endif %}