diff --git a/aio/tools/transforms/angular-base-package/rendering/truncateCode.js b/aio/tools/transforms/angular-base-package/rendering/truncateCode.js new file mode 100644 index 0000000000..a0ea95b713 --- /dev/null +++ b/aio/tools/transforms/angular-base-package/rendering/truncateCode.js @@ -0,0 +1,49 @@ +module.exports = function() { + return { + name: 'truncateCode', + process: function(str, lines) { + if (lines === undefined) return str; + + const parts = str && str.split && str.split(/\r?\n/); + if (parts && parts.length > lines) { + return balance(parts[0] + '...', ['{', '(', '['], ['}', ')', ']']); + } else { + return str; + } + } + }; +}; + +/** + * Try to balance the brackets by adding closers on to the end of a string + * for every bracket that is left open. + * The chars at each index in the openers and closers should match (i.e openers = ['{', '('], closers = ['}', ')']) + * + * @param {string} str The string to balance + * @param {string[]} openers an array of chars that open a bracket + * @param {string[]} closers an array of chars that close a brack + * @returns the balanced string + */ +function balance(str, openers, closers) { + const stack = []; + + // Add each open bracket to the stack, removing them when there is a matching closer + str.split('').forEach(function(char) { + const closerIndex = closers.indexOf(char); + if (closerIndex !== -1 && stack[stack.length-1] === closerIndex) { + stack.pop(); + } else { + const openerIndex = openers.indexOf(char); + if (openerIndex !== -1) { + stack.push(openerIndex); + } + } + }); + + // Now the stack should contain all the unclosed brackets + while(stack.length) { + str += closers[stack.pop()]; + } + + return str; +} \ No newline at end of file diff --git a/aio/tools/transforms/angular-base-package/rendering/truncateCode.spec.js b/aio/tools/transforms/angular-base-package/rendering/truncateCode.spec.js new file mode 100644 index 0000000000..6e9f3b59c4 --- /dev/null +++ b/aio/tools/transforms/angular-base-package/rendering/truncateCode.spec.js @@ -0,0 +1,35 @@ +var factory = require('./truncateCode'); + +describe('truncateCode filter', function() { + var filter; + + beforeEach(function() { filter = factory(); }); + + it('should be called "truncateCode"', + function() { expect(filter.name).toEqual('truncateCode'); }); + + it('should return the whole string given lines is undefined', function() { + expect(filter.process('some text\n \nmore text\n \n')) + .toEqual('some text\n \nmore text\n \n'); + }); + + it('should return the whole string if less than the given number of lines', function() { + expect(filter.process('this is a pretty long string that only exists on one line', 1)) + .toEqual('this is a pretty long string that only exists on one line'); + + expect(filter.process('this is a pretty long string\nthat exists on two lines', 2)) + .toEqual('this is a pretty long string\nthat exists on two lines'); + }); + + it('should return the specified number of lines and an ellipsis if there are more lines', function() { + expect(filter.process('some text\n \nmore text\n \n', 1)).toEqual('some text...'); + }); + + it('should add closing brackets for all the unclosed opening brackets after truncating', function() { + expect(filter.process('()[]{}\nsecond line', 1)).toEqual('()[]{}...'); + expect(filter.process('([]{}\nsecond line', 1)).toEqual('([]{}...)'); + expect(filter.process('()[{}\nsecond line', 1)).toEqual('()[{}...]'); + expect(filter.process('()[]{\nsecond line', 1)).toEqual('()[]{...}'); + expect(filter.process('([{\nsecond line', 1)).toEqual('([{...}])'); + }); +}); \ No newline at end of file diff --git a/aio/tools/transforms/angular-base-package/rendering/truncateFirstLine.js b/aio/tools/transforms/angular-base-package/rendering/truncateFirstLine.js deleted file mode 100644 index 9070911625..0000000000 --- a/aio/tools/transforms/angular-base-package/rendering/truncateFirstLine.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = function() { - return { - name: 'truncateFirstLine', - process: function(str) { - const parts = str && str.split && str.split(/\r?\n/); - if (parts && parts.length > 1) { - return parts[0] + '...'; - } else { - return str; - } - } - }; -}; \ No newline at end of file diff --git a/aio/tools/transforms/angular-base-package/rendering/truncateFirstLine.spec.js b/aio/tools/transforms/angular-base-package/rendering/truncateFirstLine.spec.js deleted file mode 100644 index c2ad68554f..0000000000 --- a/aio/tools/transforms/angular-base-package/rendering/truncateFirstLine.spec.js +++ /dev/null @@ -1,19 +0,0 @@ -var factory = require('./truncateFirstLine'); - -describe('truncateFirstLine filter', function() { - var filter; - - beforeEach(function() { filter = factory(); }); - - it('should be called "truncateFirstLine"', - function() { expect(filter.name).toEqual('truncateFirstLine'); }); - - it('should return the whole string if only one line', function() { - expect(filter.process('this is a pretty long string that only exists on one line')) - .toEqual('this is a pretty long string that only exists on one line'); - }); - - it('should return the first line and an ellipsis if there is more than one line', function() { - expect(filter.process('some text\n \nmore text\n \n')).toEqual('some text...'); - }); -}); \ 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 24b14d468d..7a4c375e5f 100644 --- a/aio/tools/transforms/templates/api/includes/class-overview.html +++ b/aio/tools/transforms/templates/api/includes/class-overview.html @@ -1,13 +1,13 @@ {% import "lib/memberHelpers.html" as memberHelper -%}
-

Overview

- - {$ doc.docType $} {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} { - {%- if doc.statics.length %}{% for member in doc.statics %}{% if not member.internal %} - {$ memberHelper.renderMember(member, true) $}{% endif %}{% endfor %}{% endif %} - {%- if doc.members.length %}{% for member in doc.members %}{% if not member.internal %} - {$ memberHelper.renderMember(member, true) $}{% endif %}{% endfor %}{% endif %} - } - +

Overview

+ +{$ doc.docType $} {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} { +{%- if doc.statics.length %}{% for member in doc.statics %}{% if not member.internal %} + {$ memberHelper.renderMember(member, 1) $}{% endif %}{% endfor %}{% endif %} +{%- if doc.members.length %}{% for member in doc.members %}{% if not member.internal %} + {$ memberHelper.renderMember(member, 1) $}{% endif %}{% endfor %}{% endif %} +} +
diff --git a/aio/tools/transforms/templates/api/includes/decorator-overview.html b/aio/tools/transforms/templates/api/includes/decorator-overview.html index 66537da102..8b2fe83f4d 100644 --- a/aio/tools/transforms/templates/api/includes/decorator-overview.html +++ b/aio/tools/transforms/templates/api/includes/decorator-overview.html @@ -2,9 +2,9 @@

Metadata Overview

- - @{$ doc.name $}{$ doc.typeParams | escape $}({ {% if doc.members.length %}{% for member in doc.members %}{% if not member.internal %} - {$ memberHelper.renderMember(member) $}{% endif %}{% endfor %}{% endif %} - }) - + +@{$ doc.name $}{$ doc.typeParams | escape $}({ {% if doc.members.length %}{% for member in doc.members %}{% if not member.internal %} + {$ memberHelper.renderMember(member, 1) $}{% endif %}{% endfor %}{% endif %} +}) +
\ No newline at end of file diff --git a/aio/tools/transforms/templates/api/includes/interface-overview.html b/aio/tools/transforms/templates/api/includes/interface-overview.html index 8b3199b7ac..ac4d71299c 100644 --- a/aio/tools/transforms/templates/api/includes/interface-overview.html +++ b/aio/tools/transforms/templates/api/includes/interface-overview.html @@ -1,10 +1,10 @@ {% import "lib/memberHelpers.html" as memberHelper -%}
-

Interface Overview

- - interface {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} { {% if doc.members.length %}{% for member in doc.members %}{% if not member.internal %} - {$ memberHelper.renderMember(member, true) $}{% endif %}{% endfor %}{% endif %} - } - +

Interface Overview

+ +interface {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} { {% if doc.members.length %}{% for member in doc.members %}{% if not member.internal %} + {$ memberHelper.renderMember(member, 1) $}{% endif %}{% endfor %}{% endif %} +} +
\ 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 a6887f98f5..1aa05060c5 100644 --- a/aio/tools/transforms/templates/api/lib/memberHelpers.html +++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html @@ -9,14 +9,14 @@ {% endfor %}{% endif %} {%- endmacro -%} -{%- macro renderMember(member, truncate) -%} +{%- macro renderMember(member, truncateLines) -%} {%- if member.accessibility !== 'public' %}{$ member.accessibility $} {% endif -%} {%- if member.isGetAccessor %}get {% endif -%} {%- if member.isSetAccessor %}set {% endif -%} {%- if member.isStatic %}static {% endif -%} - {$ member.name $}{$ member.typeParameters | escape $}{$ params.paramList(member.parameters, truncate) | trim $} + {$ member.name $}{$ member.typeParameters | escape $}{$ params.paramList(member.parameters, truncateLines) | trim $} {%- if member.isOptional %}?{% endif -%} - {$ params.returnType(member.type) | trim | truncateFirstLine $} + {$ params.returnType(member.type) | trim | truncateCode(truncateLines) $} {%- endmacro -%} {%- macro renderMemberDetail(member, cssClass) -%} diff --git a/aio/tools/transforms/templates/api/lib/paramList.html b/aio/tools/transforms/templates/api/lib/paramList.html index d063dc2a91..3e6b721cf4 100644 --- a/aio/tools/transforms/templates/api/lib/paramList.html +++ b/aio/tools/transforms/templates/api/lib/paramList.html @@ -1,7 +1,7 @@ -{% macro paramList(params, truncate) -%} +{% macro paramList(params, truncateLines) -%} {%- if params -%} ({%- for param in params -%} - {% if truncate %}{$ param | escape | truncateFirstLine $}{% else %}{$ param | escape $}{% endif %}{% if not loop.last %}, {% endif %} + {$ param | escape | truncateCode(truncateLines) $}{% if not loop.last %}, {% endif %} {%- endfor %}) {%- endif %} {%- endmacro -%}