From 4a7b6a4555a76b19dd217171fc0ddce6707bca95 Mon Sep 17 00:00:00 2001 From: Ken Sheedlo Date: Fri, 12 Jul 2013 17:42:27 -0700 Subject: docs(minErr): Build minErr doc site --- docs/src/gen-docs.js | 30 +++++++- docs/src/ngdoc.js | 156 +++++++++++++++++++++++++--------------- docs/src/templates/css/docs.css | 9 +++ docs/src/templates/index.html | 12 +++- docs/src/templates/js/docs.js | 75 ++++++++++++++++--- 5 files changed, 211 insertions(+), 71 deletions(-) (limited to 'docs/src') diff --git a/docs/src/gen-docs.js b/docs/src/gen-docs.js index f8ca5548..2e711ab3 100755 --- a/docs/src/gen-docs.js +++ b/docs/src/gen-docs.js @@ -3,7 +3,8 @@ var reader = require('./reader.js'), writer = require('./writer.js'), SiteMap = require('./SiteMap.js').SiteMap, appCache = require('./appCache.js').appCache, - Q = require('qq'); + Q = require('qq'), + errorsJson = require('../../build/errors.json').errors; var start = now(); var docs; @@ -22,10 +23,35 @@ writer.makeDir('build/docs/', true).then(function() { }).then(function generateHtmlDocPartials(docs_) { docs = docs_; ngdoc.merge(docs); - var fileFutures = []; + var fileFutures = [], namespace; + + var isErrorDocPresent = function (search) { + return docs.some(function (doc) { + return doc.ngdoc === 'error' && doc.name === search; + }); + }; + + // Check that each generated error code has a doc file. + Object.keys(errorsJson).forEach(function (prop) { + if (typeof errorsJson[prop] === 'object') { + namespace = errorsJson[prop]; + Object.keys(namespace).forEach(function (code) { + var search = prop + ':' + code; + if (!isErrorDocPresent(search)) { + throw new Error('Missing ngdoc file for error code: ' + search); + } + }); + } else { + if (!isErrorDocPresent(prop)) { + throw new Error('Missing ngdoc file for error code: ' + prop); + } + } + }); + docs.forEach(function(doc){ // this hack is here because on OSX angular.module and angular.Module map to the same file. var id = doc.id.replace('angular.Module', 'angular.IModule'); + fileFutures.push(writer.output('partials/' + doc.section + '/' + id + '.html', doc.html())); }); diff --git a/docs/src/ngdoc.js b/docs/src/ngdoc.js index f5f22ee8..4ad478f4 100644 --- a/docs/src/ngdoc.js +++ b/docs/src/ngdoc.js @@ -13,6 +13,22 @@ var fspath = require('path'); var markdown = new Showdown.converter({ extensions : ['table'] }); var shell = require('shelljs'); var gruntUtil = require('../../lib/grunt/utils.js'); +var errorsJson; + +var lookupMinerrMsg = function (doc) { + var code, namespace; + + if (errorsJson === undefined) { + errorsJson = require('../../build/errors.json').errors; + } + + namespace = doc.getMinerrNamespace(); + code = doc.getMinerrCode(); + if (namespace === undefined) { + return errorsJson[code]; + } + return errorsJson[namespace][code]; +}; exports.trim = trim; exports.metadata = metadata; @@ -98,6 +114,22 @@ Doc.prototype = { return words.join(' '); }, + getMinerrNamespace: function () { + if (this.ngdoc !== 'error') { + throw new Error('Tried to get the minErr namespace, but @ngdoc ' + + this.ngdoc + ' was supplied. It should be @ngdoc error'); + } + return this.name.split(':')[0]; + }, + + getMinerrCode: function () { + if (this.ngdoc !== 'error') { + throw new Error('Tried to get the minErr error code, but @ngdoc ' + + this.ngdoc + ' was supplied. It should be @ngdoc error'); + } + return this.name.split(':')[1]; + }, + /** * Converts relative urls (without section) into absolute * Absolute url means url with section @@ -325,6 +357,7 @@ Doc.prototype = { flush(); this.shortName = this.name.split(/[\.:#]/).pop().trim(); this.id = this.id || // if we have an id just use it + (this.ngdoc === 'error' ? this.name : '') || (((this.file||'').match(/.*(\/|\\)([^(\/|\\)]*)\.ngdoc/)||{})[2]) || // try to extract it from file name this.name; // default to name this.description = this.markdown(this.description); @@ -391,20 +424,33 @@ Doc.prototype = { html: function() { var dom = new DOM(), - self = this; - - dom.h(title(this.name), function() { + self = this, + minerrMsg; + + if (this.section === 'api') { + dom.tag('a', { + href: 'http://github.com/angular/angular.js/tree/v' + + gruntUtil.getVersion().number + '/' + self.file + '#L' + self.line, + class: 'view-source btn btn-action' }, function(dom) { + dom.tag('i', {class:'icon-zoom-in'}, ' '); + dom.text(' View source'); + }); + } + dom.tag('a', { + href: 'http://github.com/angular/angular.js/edit/master/' + self.file, + class: 'improve-docs btn btn-primary' }, function(dom) { + dom.tag('i', {class:'icon-edit'}, ' '); + dom.text(' Improve this doc'); + }); + dom.h(title(this), function() { notice('deprecated', 'Deprecated API', self.deprecated); - dom.tag('a', {href: 'http://github.com/angular/angular.js/edit/master/' + self.file, class: 'improve-docs btn btn-primary'}, function(dom) { - dom.tag('i', {class:'icon-edit'}, ' '); - dom.text(' Improve this doc'); - }); - if (self.section === 'api') { - dom.tag('a', {href: 'http://github.com/angular/angular.js/tree/v' + gruntUtil.getVersion().number + '/' + self.file + '#L' + self.line, class: 'view-source btn btn-action'}, function(dom) { - dom.tag('i', {class:'icon-zoom-in'}, ' '); - dom.text(' View source'); - }); + if (self.ngdoc === 'error') { + minerrMsg = lookupMinerrMsg(self); + dom.tag('pre', { + class:'minerr-errmsg', + 'error-display': minerrMsg + }, minerrMsg); } if (self.ngdoc != 'overview') { dom.h('Description', self.description, dom.html); @@ -763,6 +809,10 @@ Doc.prototype = { dom.html(this.description); }, + html_usage_error: function (dom) { + dom.html(); + }, + html_usage_interface: function(dom){ var self = this; @@ -878,62 +928,50 @@ var GLOBALS = /^angular\.([^\.]+)$/, MODULE_TYPE = /^((?:(?!^angular\.)[^\.])+)\..+\.([A-Z][^\.]+)$/; -function title(text) { - if (!text) return text; +function title(doc) { + if (!doc.name) return doc.name; var match, - module, - type, - name; - - if (text == 'angular.Module') { - module = 'ng'; - name = 'Module'; - type = 'Type'; + text = doc.name; + + var makeTitle = function (name, type, componentType, component) { + // Makes title markup. + // makeTitle('Foo', 'directive', 'module', 'ng') -> + // Foo is a directive in module ng + return function () { + this.tag('code', name); + this.tag('div', function () { + this.tag('span', {class: 'hint'}, function () { + if (type && component) { + this.text(type + ' in ' + componentType + ' '); + this.tag('code', component); + } + }); + }); + }; + }; + + if (doc.ngdoc === 'error') { + return makeTitle(doc.fullName, 'error', 'component', doc.getMinerrNamespace()); + } else if (text == 'angular.Module') { + return makeTitle('Module', 'Type', 'module', 'ng'); } else if (match = text.match(GLOBALS)) { - module = 'ng'; - name = 'angular.' + match[1]; - type = 'API'; + return makeTitle('angular.' + match[1], 'API', 'module', 'ng'); } else if (match = text.match(MODULE)) { - module = match[1]; + return makeTitle('', '', 'module', match[1]); } else if (match = text.match(MODULE_MOCK)) { - module = 'ng'; - name = 'angular.mock.' + match[1]; - type = 'API'; + return makeTitle('angular.mock.' + match[1], 'API', 'module', 'ng'); } else if (match = text.match(MODULE_DIRECTIVE)) { - module = match[1]; - name = match[2]; - type = 'directive'; + return makeTitle(match[2], 'directive', 'module', match[1]); } else if (match = text.match(MODULE_DIRECTIVE_INPUT)) { - module = match[1]; - name = 'input [' + match[2] + ']'; - type = 'directive'; + return makeTitle('input [' + match[2] + ']', 'directive', 'module', match[1]); } else if (match = text.match(MODULE_FILTER)) { - module = match[1]; - name = match[2]; - type = 'filter'; + return makeTitle(match[2], 'filter', 'module', match[1]); } else if (match = text.match(MODULE_SERVICE)) { - module = match[1]; - name = match[2] + (match[3] || ''); - type = 'service'; + return makeTitle(match[2] + (match[3] || ''), 'service', 'module', match[1]); } else if (match = text.match(MODULE_TYPE)) { - module = match[1]; - name = match[2]; - type = 'type'; - } else { - return text; + return makeTitle(match[2], 'type', 'module', match[1]); } - return function() { - this.tag('code', name); - this.tag('span', { class: 'hint'}, function() { - if (type) { - this.text('('); - this.text(type); - this.text(' in module '); - this.tag('code', module); - this.text(')'); - } - }); - }; + return text; } @@ -988,7 +1026,7 @@ function metadata(docs){ pages.push({ section: doc.section, id: doc.id, - name: title(doc.name), + name: title(doc), shortName: shortName, type: doc.ngdoc, keywords:doc.keywords() diff --git a/docs/src/templates/css/docs.css b/docs/src/templates/css/docs.css index f4a86ba5..6b1e6527 100644 --- a/docs/src/templates/css/docs.css +++ b/docs/src/templates/css/docs.css @@ -476,3 +476,12 @@ pre ol li { width:180px; margin-bottom:20px; } + +.minerr-errmsg { + clear: both; + position: relative; + top: 10px; + font-size: 16px; + word-break: normal; + word-wrap: normal; +} \ No newline at end of file diff --git a/docs/src/templates/index.html b/docs/src/templates/index.html index 4bf36838..65e26c99 100644 --- a/docs/src/templates/index.html +++ b/docs/src/templates/index.html @@ -18,7 +18,7 @@ // before the base attribute is added, causing 404 and terribly slow loading of the docs app. (function() { var indexFile = (location.pathname.match(/\/(index[^\.]*\.html)/) || ['', ''])[1], - rUrl = /(#!\/|api|guide|misc|tutorial|cookbook|index[^\.]*\.html).*$/, + rUrl = /(#!\/|api|guide|misc|tutorial|cookbook|error|index[^\.]*\.html).*$/, baseUrl = location.href.replace(rUrl, indexFile), jQuery = /index-jq[^\.]*\.html$/.test(baseUrl), debug = /index[^\.]*-debug\.html$/.test(baseUrl), @@ -150,6 +150,7 @@