diff --git a/public/resources/css/module/_api.scss b/public/resources/css/module/_api.scss index 0bcbc76714..7ba17787f9 100644 --- a/public/resources/css/module/_api.scss +++ b/public/resources/css/module/_api.scss @@ -1,5 +1,9 @@ @mixin icon { line-height: 14px; + &.decorator:before { + content: 'A'; + background: $blueberry; + } &.directive:before { content: 'D'; background: #db4437; diff --git a/public/resources/js/directives/api-list.js b/public/resources/js/directives/api-list.js index 5e53ae1dfc..f893b3a748 100644 --- a/public/resources/js/directives/api-list.js +++ b/public/resources/js/directives/api-list.js @@ -28,9 +28,10 @@ angularIO.directive('apiList', function () { $ctrl.apiTypes = [ { cssClass: 'directive', title: 'Directive', matches: ['directive'] }, + { cssClass: 'decorator', title: 'Decorator', matches: ['decorator'] }, { cssClass: 'class', title: 'Class', matches: ['class'] }, { cssClass: 'interface', title: 'Interface', matches: ['interface'] }, - { cssClass: 'function', title: 'function', matches: ['function'] }, + { cssClass: 'function', title: 'Function', matches: ['function'] }, { cssClass: 'const', title: 'Const or Enum', matches: ['const', 'enum'] }, { cssClass: 'var', title: 'Variable', matches: ['var', 'let'] } ]; diff --git a/tools/api-builder/angular.io-package/index.js b/tools/api-builder/angular.io-package/index.js index a0a72dcd29..b0dfa11f86 100644 --- a/tools/api-builder/angular.io-package/index.js +++ b/tools/api-builder/angular.io-package/index.js @@ -92,6 +92,13 @@ module.exports = new Package('angular.io', [basePackage, targetPackage, cheatshe outputPathTemplate:'${moduleDoc.moduleFolder}/${name}-${docType}.jade', }); + + computePathsProcessor.pathTemplates.push({ + docTypes: ['decorator'], + pathTemplate: '${moduleDoc.moduleFolder}/${name}-${docType}.html', + outputPathTemplate:'${moduleDoc.moduleFolder}/${name}-${docType}.jade', + }); + computePathsProcessor.pathTemplates.push({ docTypes: ['jade-data'], pathTemplate: '${originalDoc.moduleFolder}/_data', diff --git a/tools/api-builder/angular.io-package/templates/decorator.template.html b/tools/api-builder/angular.io-package/templates/decorator.template.html new file mode 100644 index 0000000000..5c32e00c79 --- /dev/null +++ b/tools/api-builder/angular.io-package/templates/decorator.template.html @@ -0,0 +1,23 @@ +{% include "lib/githubLinks.html" -%} +{% include "lib/paramList.html" -%} +{% extends 'layout/base.template.html' %} + +{% block body %} +include {$ relativePath(doc.path, '_util-fns') $} +.l-main-section + h2(class="decorator export") + pre.prettyprint + code. + export {$ doc.name $}(options : {@link {$ doc.decoratorType $} {$ doc.decoratorType | escape $}}){$ returnType(doc.returnType) $} + + p.location-badge. + exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} } + defined in {$ githubViewLink(doc) $} + + :marked +{%- if doc.notYetDocumented %} + *Not Yet Documented* +{% else %} +{$ doc.description | indentForMarkdown(4) | trimBlankLines $} +{% endif -%} +{% endblock %} diff --git a/tools/api-builder/docs-package/index.js b/tools/api-builder/docs-package/index.js index 63d3272cd8..c6cb9e88af 100644 --- a/tools/api-builder/docs-package/index.js +++ b/tools/api-builder/docs-package/index.js @@ -19,6 +19,7 @@ module.exports = new Package('angular-v2-docs', [jsdocPackage, nunjucksPackage, .processor(require('./processors/checkUnbalancedBackTicks')) .processor(require('./processors/convertBackticksToCodeBlocks')) .processor(require('./processors/addNotYetDocumentedProperty')) +.processor(require('./processors/createDecoratorDocs')) // Configure the log service .config(function(log) { diff --git a/tools/api-builder/docs-package/processors/createDecoratorDocs.js b/tools/api-builder/docs-package/processors/createDecoratorDocs.js new file mode 100644 index 0000000000..4e3b70dfd5 --- /dev/null +++ b/tools/api-builder/docs-package/processors/createDecoratorDocs.js @@ -0,0 +1,39 @@ +module.exports = function mergeDecoratorDocs() { + return { + $runAfter: ['processing-docs'], + $runBefore: ['docs-processed'], + $process: function(docs) { + docs.forEach(function(doc) { + var makeDecorator = getMakeDecoratorCall(doc); + if (makeDecorator) { + doc.docType = 'decorator'; + doc.decoratorType = makeDecorator.arguments[0].text; + } + }); + } + }; +}; + +function getMakeDecoratorCall(doc, type) { + + var makeDecoratorFnName = 'make' + (type || '')+ 'Decorator'; + + var initializer = doc.exportSymbol && + doc.exportSymbol.valueDeclaration && + doc.exportSymbol.valueDeclaration.initializer; + + if (initializer) { + // There appear to be two forms of initializer: + // export var Injectable: InjectableFactory = makeDecorator(InjectableMetadata); + // and + // export var RouteConfig: (configs: RouteDefinition[]) => ClassDecorator = makeDecorator(RouteConfigAnnotation); + // In the first case, the type assertion `` causes the AST to contain an extra level of expression + // to hold the new type of the expression. + if (initializer.expression && initializer.expression.expression) { + initializer = initializer.expression; + } + if (initializer.expression && initializer.expression.text === makeDecoratorFnName) { + return initializer; + } + } +} \ No newline at end of file diff --git a/tools/api-builder/docs-package/processors/createDecoratorDocs.spec.js b/tools/api-builder/docs-package/processors/createDecoratorDocs.spec.js new file mode 100644 index 0000000000..32d0b6501a --- /dev/null +++ b/tools/api-builder/docs-package/processors/createDecoratorDocs.spec.js @@ -0,0 +1,67 @@ +var mockPackage = require('../mocks/mockPackage'); +var Dgeni = require('dgeni'); + +describe('mergeDecoratorDocs processor', function() { + var dgeni, injector, processor, decoratorDoc, otherDoc; + + beforeEach(function() { + dgeni = new Dgeni([mockPackage()]); + injector = dgeni.configureInjector(); + processor = injector.get('mergeDecoratorDocs'); + + decoratorDoc = { + name: 'X', + docType: 'var', + exportSymbol: { + valueDeclaration: { + initializer: { + expression: { text: 'makeDecorator' }, + arguments: [{ text: 'XMetadata' }] + } + } + } + }; + + decoratorDocWithTypeAssertion = { + name: 'Y', + docType: 'var', + exportSymbol: { + valueDeclaration: { + initializer: { + expression: { + type: {}, + expression: { text: 'makeDecorator' }, + arguments: [{ text: 'YMetadata' }] + } + } + } + } + }; + otherDoc = { + name: 'Y', + docType: 'var', + exportSymbol: { + valueDeclaration: { + initializer: { + expression: { text: 'otherCall' }, + arguments: [{ text: 'param1' }] + } + } + } + }; + }); + + + it('should change the docType of only the docs that are initialied by a call to makeDecorator', function() { + processor.$process([decoratorDoc, decoratorDocWithTypeAssertion, otherDoc]); + expect(decoratorDoc.docType).toEqual('decorator'); + expect(decoratorDocWithTypeAssertion.docType).toEqual('decorator'); + expect(otherDoc.docType).toEqual('var'); + }); + + it('should extract the "type" of the decorator meta data', function() { + processor.$process([decoratorDoc, decoratorDocWithTypeAssertion, otherDoc]); + expect(decoratorDoc.decoratorType).toEqual('XMetadata'); + expect(decoratorDocWithTypeAssertion.decoratorType).toEqual('YMetadata'); + }); +}); \ No newline at end of file diff --git a/tools/api-builder/typescript-package/processors/readTypeScriptModules.js b/tools/api-builder/typescript-package/processors/readTypeScriptModules.js index 55b77ddd6d..3739b7b337 100644 --- a/tools/api-builder/typescript-package/processors/readTypeScriptModules.js +++ b/tools/api-builder/typescript-package/processors/readTypeScriptModules.js @@ -202,6 +202,7 @@ module.exports = function readTypeScriptModules(tsParser, modules, getFileInfo, var exportDoc = { docType: getExportDocType(exportSymbol), + exportSymbol: exportSymbol, name: name, id: moduleDoc.id + '/' + name, typeParams: typeParamString,