docs(minErr): Build minErr doc site

This commit is contained in:
Ken Sheedlo 2013-07-12 17:42:27 -07:00
parent dca23173e2
commit 4a7b6a4555
52 changed files with 476 additions and 80 deletions

View file

@ -7,6 +7,6 @@
"components-font-awesome": "3.1.0", "components-font-awesome": "3.1.0",
"bootstrap": "https://raw.github.com/twitter/bootstrap/v2.0.2/docs/assets/bootstrap.zip", "bootstrap": "https://raw.github.com/twitter/bootstrap/v2.0.2/docs/assets/bootstrap.zip",
"closure-compiler": "https://closure-compiler.googlecode.com/files/compiler-20130603.zip", "closure-compiler": "https://closure-compiler.googlecode.com/files/compiler-20130603.zip",
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.1.1/assets/ng-closure-runner.zip" "ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.0/assets/ng-closure-runner.zip"
} }
} }

View file

@ -0,0 +1,68 @@
describe("errorDisplay", function () {
var $location, compileHTML;
beforeEach(module('docsApp'));
beforeEach(inject(function ($injector) {
var $rootScope = $injector.get('$rootScope'),
$compile = $injector.get('$compile');
$location = $injector.get('$location');
compileHTML = function (code) {
var elm = angular.element(code);
$compile(elm)($rootScope);
$rootScope.$digest();
return elm;
};
this.addMatchers({
toInterpolateTo: function (expected) {
// Given a compiled DOM node with a minerr-display attribute,
// assert that its interpolated string matches the expected text.
return this.actual.text() === expected;
}
});
}));
it('should interpolate a template with no parameters', function () {
var elm;
spyOn($location, 'search').andReturn({});
elm = compileHTML('<div error-display="This is a test"></div>');
expect(elm).toInterpolateTo('This is a test');
});
it('should interpolate a template with no parameters when search parameters are present', function () {
var elm;
spyOn($location, 'search').andReturn({ p0: 'foobaz' });
elm = compileHTML('<div error-display="This is a test"></div>');
expect(elm).toInterpolateTo('This is a test');
});
it('should correctly interpolate search parameters', function () {
var elm;
spyOn($location, 'search').andReturn({ p0: '42' });
elm = compileHTML('<div error-display="The answer is {0}"></div>');
expect(elm).toInterpolateTo('The answer is 42');
});
it('should interpolate parameters in the specified order', function () {
var elm;
spyOn($location, 'search').andReturn({ p0: 'second', p1: 'first' });
elm = compileHTML('<div error-display="{1} {0}"></div>');
expect(elm).toInterpolateTo('first second');
});
it('should preserve interpolation markers when fewer arguments than needed are provided', function () {
var elm;
spyOn($location, 'search').andReturn({ p0: 'Fooooo' });
elm = compileHTML('<div error-display="This {0} is {1} on {2}"></div>');
expect(elm).toInterpolateTo('This Fooooo is {1} on {2}');
});
});

View file

@ -0,0 +1,7 @@
@ngdoc error
@name $cacheFactory:iid
@fullName Invalid ID
@description
This error occurs when trying to create a new `cacheFactory` object with a
specified cache ID, but the cache ID is already taken.

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $compile:ctreq
@fullName Missing Required Controller
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $compile:iscp
@fullName Invalid Isolate Scope
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $compile:multidir
@fullName Multiple Directive Resource Contention
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $compile:noass
@fullName Non-Assignable Expression
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $compile:nodomevents
@fullName Interpolated Event Attributes
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $compile:tpload
@fullName Template Loader Error
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $compile:tplrt
@fullName Invalid Template Root
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $compile:utrat
@fullName Unterminated Attribute
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $controller:noscp
@fullName Missing $scope object
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $httpBackend:noxhr
@fullName Unsupported XHR
@description

View file

@ -0,0 +1,13 @@
@ngdoc overview
@name Error Reference
@description
Use the Error Reference manual to find information about error conditions in
your AngularJS app. Errors thrown in production builds of AngularJS will log
links to this site on the console.
Other useful references for debugging your app include:
- {@link api/ API Reference} for detailed information about specific features
- {@link guide/ Developer Guide} for AngularJS concepts
- {@link tutorial/ Tutorial} for getting started

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $injector:cdep
@fullName Circular Dependency
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $injector:itkn
@fullName Bad Injection Token
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $injector:modulerr
@fullName Module Error
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $injector:nomod
@fullName Module Unavailable
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $injector:pget
@fullName Provider Missing $get
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $injector:unpr
@fullName Unknown Provider
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $interpolate:interr
@fullName Interpolation Error
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $interpolate:noconcat
@fullName Multiple Expressions
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name jqLite:nosel
@fullName Unsupported Selector Lookup
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name jqLite:off_args
@fullName Invalid jqLite#off() parameter
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name jqLite:on_args
@fullName Invalid jqLite#on() Parameters
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $location:istart
@fullName Invalid URL
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $location:nohash
@fullName Missing Hash Prefix
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $location:nopp
@fullName Missing Path Prefix
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ng:areq
@fullName Bad Argument
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ng:cpi
@fullName Bad Copy
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ng:cpws
@fullName Copying Window or Scope
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ngModel:noass
@fullName Non-Assignable Expression
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ngOptions:iexp
@fullName Invalid Expression
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ngPattern:noregexp
@fullName Expected Regular Expression
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ngRepeat:dupes
@fullName Duplicate Repeater Key
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ngRepeat:iexp
@fullName Invalid Expression
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ngRepeat:iidexp
@fullName Invalid Identifier
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ngResource:badargs
@fullName Too Many Arguments
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name ngSanitize:badparse
@fullName Parsing Error
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $parse:isecfld
@fullName Referencing constructor Field
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $parse:isecfn
@fullName Referencing Function Disallowed
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $parse:lexerr
@fullName Lexer Error
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $parse:syntax
@fullName Syntax Error
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $parse:ueoe
@fullName Unexpected End of Expression
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $rootScope:infdig
@fullName Infinite $digest Loop
@description

View file

@ -0,0 +1,4 @@
@ngdoc error
@name $rootScope:inprog
@fullName Action Already In Progress
@description

View file

@ -3,7 +3,8 @@ var reader = require('./reader.js'),
writer = require('./writer.js'), writer = require('./writer.js'),
SiteMap = require('./SiteMap.js').SiteMap, SiteMap = require('./SiteMap.js').SiteMap,
appCache = require('./appCache.js').appCache, appCache = require('./appCache.js').appCache,
Q = require('qq'); Q = require('qq'),
errorsJson = require('../../build/errors.json').errors;
var start = now(); var start = now();
var docs; var docs;
@ -22,10 +23,35 @@ writer.makeDir('build/docs/', true).then(function() {
}).then(function generateHtmlDocPartials(docs_) { }).then(function generateHtmlDocPartials(docs_) {
docs = docs_; docs = docs_;
ngdoc.merge(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){ docs.forEach(function(doc){
// this hack is here because on OSX angular.module and angular.Module map to the same file. // 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'); var id = doc.id.replace('angular.Module', 'angular.IModule');
fileFutures.push(writer.output('partials/' + doc.section + '/' + id + '.html', doc.html())); fileFutures.push(writer.output('partials/' + doc.section + '/' + id + '.html', doc.html()));
}); });

View file

@ -13,6 +13,22 @@ var fspath = require('path');
var markdown = new Showdown.converter({ extensions : ['table'] }); var markdown = new Showdown.converter({ extensions : ['table'] });
var shell = require('shelljs'); var shell = require('shelljs');
var gruntUtil = require('../../lib/grunt/utils.js'); 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.trim = trim;
exports.metadata = metadata; exports.metadata = metadata;
@ -98,6 +114,22 @@ Doc.prototype = {
return words.join(' '); 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 * Converts relative urls (without section) into absolute
* Absolute url means url with section * Absolute url means url with section
@ -325,6 +357,7 @@ Doc.prototype = {
flush(); flush();
this.shortName = this.name.split(/[\.:#]/).pop().trim(); this.shortName = this.name.split(/[\.:#]/).pop().trim();
this.id = this.id || // if we have an id just use it 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.file||'').match(/.*(\/|\\)([^(\/|\\)]*)\.ngdoc/)||{})[2]) || // try to extract it from file name
this.name; // default to name this.name; // default to name
this.description = this.markdown(this.description); this.description = this.markdown(this.description);
@ -391,20 +424,33 @@ Doc.prototype = {
html: function() { html: function() {
var dom = new DOM(), var dom = new DOM(),
self = this; self = this,
minerrMsg;
dom.h(title(this.name), function() { 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); 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) { if (self.ngdoc === 'error') {
dom.tag('i', {class:'icon-edit'}, ' '); minerrMsg = lookupMinerrMsg(self);
dom.text(' Improve this doc'); dom.tag('pre', {
}); class:'minerr-errmsg',
if (self.section === 'api') { 'error-display': minerrMsg
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) { }, minerrMsg);
dom.tag('i', {class:'icon-zoom-in'}, ' ');
dom.text(' View source');
});
} }
if (self.ngdoc != 'overview') { if (self.ngdoc != 'overview') {
dom.h('Description', self.description, dom.html); dom.h('Description', self.description, dom.html);
@ -763,6 +809,10 @@ Doc.prototype = {
dom.html(this.description); dom.html(this.description);
}, },
html_usage_error: function (dom) {
dom.html();
},
html_usage_interface: function(dom){ html_usage_interface: function(dom){
var self = this; var self = this;
@ -878,62 +928,50 @@ var GLOBALS = /^angular\.([^\.]+)$/,
MODULE_TYPE = /^((?:(?!^angular\.)[^\.])+)\..+\.([A-Z][^\.]+)$/; MODULE_TYPE = /^((?:(?!^angular\.)[^\.])+)\..+\.([A-Z][^\.]+)$/;
function title(text) { function title(doc) {
if (!text) return text; if (!doc.name) return doc.name;
var match, var match,
module, text = doc.name;
type,
name;
if (text == 'angular.Module') { var makeTitle = function (name, type, componentType, component) {
module = 'ng'; // Makes title markup.
name = 'Module'; // makeTitle('Foo', 'directive', 'module', 'ng') ->
type = 'Type'; // Foo is a directive in module ng
} else if (match = text.match(GLOBALS)) { return function () {
module = 'ng'; this.tag('code', name);
name = 'angular.' + match[1]; this.tag('div', function () {
type = 'API'; this.tag('span', {class: 'hint'}, function () {
} else if (match = text.match(MODULE)) { if (type && component) {
module = match[1]; this.text(type + ' in ' + componentType + ' ');
} else if (match = text.match(MODULE_MOCK)) { this.tag('code', component);
module = 'ng'; }
name = 'angular.mock.' + match[1]; });
type = 'API'; });
} else if (match = text.match(MODULE_DIRECTIVE)) { };
module = match[1];
name = match[2];
type = 'directive';
} else if (match = text.match(MODULE_DIRECTIVE_INPUT)) {
module = match[1];
name = 'input [' + match[2] + ']';
type = 'directive';
} else if (match = text.match(MODULE_FILTER)) {
module = match[1];
name = match[2];
type = 'filter';
} else if (match = text.match(MODULE_SERVICE)) {
module = match[1];
name = match[2] + (match[3] || '');
type = 'service';
} else if (match = text.match(MODULE_TYPE)) {
module = match[1];
name = match[2];
type = 'type';
} else {
return text;
}
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(')');
}
});
}; };
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)) {
return makeTitle('angular.' + match[1], 'API', 'module', 'ng');
} else if (match = text.match(MODULE)) {
return makeTitle('', '', 'module', match[1]);
} else if (match = text.match(MODULE_MOCK)) {
return makeTitle('angular.mock.' + match[1], 'API', 'module', 'ng');
} else if (match = text.match(MODULE_DIRECTIVE)) {
return makeTitle(match[2], 'directive', 'module', match[1]);
} else if (match = text.match(MODULE_DIRECTIVE_INPUT)) {
return makeTitle('input [' + match[2] + ']', 'directive', 'module', match[1]);
} else if (match = text.match(MODULE_FILTER)) {
return makeTitle(match[2], 'filter', 'module', match[1]);
} else if (match = text.match(MODULE_SERVICE)) {
return makeTitle(match[2] + (match[3] || ''), 'service', 'module', match[1]);
} else if (match = text.match(MODULE_TYPE)) {
return makeTitle(match[2], 'type', 'module', match[1]);
}
return text;
} }
@ -988,7 +1026,7 @@ function metadata(docs){
pages.push({ pages.push({
section: doc.section, section: doc.section,
id: doc.id, id: doc.id,
name: title(doc.name), name: title(doc),
shortName: shortName, shortName: shortName,
type: doc.ngdoc, type: doc.ngdoc,
keywords:doc.keywords() keywords:doc.keywords()

View file

@ -476,3 +476,12 @@ pre ol li {
width:180px; width:180px;
margin-bottom:20px; margin-bottom:20px;
} }
.minerr-errmsg {
clear: both;
position: relative;
top: 10px;
font-size: 16px;
word-break: normal;
word-wrap: normal;
}

View file

@ -18,7 +18,7 @@
// before the base attribute is added, causing 404 and terribly slow loading of the docs app. // before the base attribute is added, causing 404 and terribly slow loading of the docs app.
(function() { (function() {
var indexFile = (location.pathname.match(/\/(index[^\.]*\.html)/) || ['', ''])[1], 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), baseUrl = location.href.replace(rUrl, indexFile),
jQuery = /index-jq[^\.]*\.html$/.test(baseUrl), jQuery = /index-jq[^\.]*\.html$/.test(baseUrl),
debug = /index[^\.]*-debug\.html$/.test(baseUrl), debug = /index[^\.]*-debug\.html$/.test(baseUrl),
@ -150,6 +150,7 @@
<li><a href="./tutorial/">Tutorial</a></li> <li><a href="./tutorial/">Tutorial</a></li>
<li><a href="./guide/">Developer Guide</a></li> <li><a href="./guide/">Developer Guide</a></li>
<li><a href="./api/">API Reference</a></li> <li><a href="./api/">API Reference</a></li>
<li><a href="./error/">Error Reference</a></li>
<li><a href="http://docs.angularjs.org/misc/contribute">Contribute</a></li> <li><a href="http://docs.angularjs.org/misc/contribute">Contribute</a></li>
<li><a href="http://code.angularjs.org/">Download</a></li> <li><a href="http://code.angularjs.org/">Download</a></li>
</ul> </ul>
@ -263,6 +264,15 @@
</li> </li>
</ul> </ul>
<ul class="nav nav-list well api-list-item" ng-repeat="namespace in namespaces track by namespace.url">
<li class="nav-header module">
<a class="code" href="{{namespace.url}}">{{namespace.name}}</a>
</li>
<li ng-repeat="page in namespace.errors track by page.url" ng-class="navClass(page)" ng-animate="'expand'" class="api-list-item">
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
</li>
</ul>
<ul class="nav nav-list well api-list-item" ng-repeat="module in modules track by module.url"> <ul class="nav nav-list well api-list-item" ng-repeat="module in modules track by module.url">
<li class="nav-header module"> <li class="nav-header module">

View file

@ -299,6 +299,35 @@ docsApp.directive.docTutorialReset = function() {
}; };
docsApp.directive.errorDisplay = ['$location', function ($location) {
var interpolate = function (formatString) {
var formatArgs = arguments;
return formatString.replace(/\{\d+\}/g, function (match) {
// Drop the braces and use the unary plus to convert to an integer.
// The index will be off by one because of the formatString.
var index = +match.slice(1, -1);
if (index + 1 >= formatArgs.length) {
return match;
}
return formatArgs[index+1];
});
};
return {
link: function (scope, element, attrs) {
var search = $location.search(),
formatArgs = [attrs.errorDisplay],
i;
for (i = 0; search['p'+i]; i++) {
formatArgs.push(search['p'+i]);
}
element.text(interpolate.apply(null, formatArgs));
}
};
}];
docsApp.serviceFactory.angularUrls = function($document) { docsApp.serviceFactory.angularUrls = function($document) {
var urls = {}; var urls = {};
@ -420,6 +449,7 @@ docsApp.serviceFactory.sections = ['NG_PAGES', function sections(NG_PAGES) {
tutorial: [], tutorial: [],
misc: [], misc: [],
cookbook: [], cookbook: [],
error: [],
getPage: function(sectionId, partialId) { getPage: function(sectionId, partialId) {
var pages = sections[sectionId]; var pages = sections[sectionId];
@ -463,9 +493,10 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie
} }
}; };
var OFFLINE_COOKIE_NAME = 'ng-offline', var OFFLINE_COOKIE_NAME = 'ng-offline',
DOCS_PATH = /^\/(api)|(guide)|(cookbook)|(misc)|(tutorial)/, DOCS_PATH = /^\/(api)|(guide)|(cookbook)|(misc)|(tutorial)|(error)/,
INDEX_PATH = /^(\/|\/index[^\.]*.html)$/, INDEX_PATH = /^(\/|\/index[^\.]*.html)$/,
GLOBALS = /^angular\.([^\.]+)$/, GLOBALS = /^angular\.([^\.]+)$/,
ERROR = /^([a-zA-Z0-9_$]+:)?([a-zA-Z0-9_$]+)$/,
MODULE = /^((?:(?!^angular\.)[^\.])+)$/, MODULE = /^((?:(?!^angular\.)[^\.])+)$/,
MODULE_MOCK = /^angular\.mock\.([^\.]+)$/, MODULE_MOCK = /^angular\.mock\.([^\.]+)$/,
MODULE_DIRECTIVE = /^((?:(?!^angular\.)[^\.])+)\.directive:([^\.]+)$/, MODULE_DIRECTIVE = /^((?:(?!^angular\.)[^\.])+)\.directive:([^\.]+)$/,
@ -529,14 +560,15 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie
guide: 'Developer Guide', guide: 'Developer Guide',
misc: 'Miscellaneous', misc: 'Miscellaneous',
tutorial: 'Tutorial', tutorial: 'Tutorial',
cookbook: 'Examples' cookbook: 'Examples',
error: 'Error Reference'
}; };
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) { $scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
// ignore non-doc links which are used in examples // ignore non-doc links which are used in examples
if (DOCS_PATH.test(path)) { if (DOCS_PATH.test(path)) {
var parts = path.split('/'), var parts = path.split('/'),
sectionId = parts[1], sectionId = parts[1],
partialId = parts[2], partialId = parts.slice(2).join('/'),
sectionName = SECTION_NAME[sectionId] || sectionId, sectionName = SECTION_NAME[sectionId] || sectionId,
page = sections.getPage(sectionId, partialId); page = sections.getPage(sectionId, partialId);
@ -624,9 +656,12 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie
***********************************/ ***********************************/
function updateSearch() { function updateSearch() {
var cache = {}, var moduleCache = {},
namespaceCache = {},
pages = sections[$location.path().split('/')[1]], pages = sections[$location.path().split('/')[1]],
modules = $scope.modules = [], modules = $scope.modules = [],
namespaces = $scope.namespaces = [],
globalErrors = $scope.globalErrors = [],
otherPages = $scope.pages = [], otherPages = $scope.pages = [],
search = $scope.search, search = $scope.search,
bestMatch = {page: null, rank:0}; bestMatch = {page: null, rank:0};
@ -644,7 +679,14 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie
if (page.id == 'index') { if (page.id == 'index') {
//skip //skip
} else if (page.section != 'api') { } else if (page.section != 'api') {
otherPages.push(page); if (page.section === 'error') {
match = id.match(ERROR);
if (match[1] !== undefined) {
namespace(match[1].replace(/:/g, '')).errors.push(page);
} else {
globalErrors.push(page);
}
}
} else if (id == 'angular.Module') { } else if (id == 'angular.Module') {
module('ng').types.push(page); module('ng').types.push(page);
} else if (match = id.match(GLOBALS)) { } else if (match = id.match(GLOBALS)) {
@ -672,19 +714,20 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie
/*************/ /*************/
function module(name) { function module(name) {
var module = cache[name]; var module = moduleCache[name];
if (!module) { if (!module) {
module = cache[name] = { module = moduleCache[name] = {
name: name, name: name,
url: 'api/' + name, url: 'api/' + name,
globals: [], globals: [],
directives: [], directives: [],
services: [], services: [],
service: function(name) { service: function(name) {
var service = cache[this.name + ':' + name]; var service = moduleCache[this.name + ':' + name];
if (!service) { if (!service) {
service = {name: name}; service = {name: name};
cache[this.name + ':' + name] = service; moduleCache[this.name + ':' + name] = service;
this.services.push(service); this.services.push(service);
} }
return service; return service;
@ -697,6 +740,20 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie
return module; return module;
} }
function namespace(name) {
var namespace = namespaceCache[name];
if (!namespace) {
namespace = namespaceCache[name] = {
name: name,
url: 'error/' + name,
errors: []
};
namespaces.push(namespace);
}
return namespace;
}
function rank(page, terms) { function rank(page, terms) {
var ranking = {page: page, rank:0}, var ranking = {page: page, rank:0},
keywords = page.keywords, keywords = page.keywords,

View file

@ -154,7 +154,7 @@ module.exports = {
'--language_in ECMASCRIPT5_STRICT ' + '--language_in ECMASCRIPT5_STRICT ' +
'--minerr_pass ' + '--minerr_pass ' +
'--minerr_errors ' + errorFileName + ' ' + '--minerr_errors ' + errorFileName + ' ' +
'--minerr_url http://docs.angularjs.org/minerr/ ' + '--minerr_url http://errors.angularjs.org/ ' +
'--source_map_format=V3 ' + '--source_map_format=V3 ' +
'--create_source_map ' + mapFile + ' ' + '--create_source_map ' + mapFile + ' ' +
'--js ' + file + ' ' + '--js ' + file + ' ' +
@ -233,7 +233,7 @@ module.exports = {
//rewrite connect middleware //rewrite connect middleware
rewrite: function(){ rewrite: function(){
return function(req, res, next){ return function(req, res, next){
var REWRITE = /\/(guide|api|cookbook|misc|tutorial).*$/, var REWRITE = /\/(guide|api|cookbook|misc|tutorial|error).*$/,
IGNORED = /(\.(css|js|png|jpg)$|partials\/.*\.html$)/, IGNORED = /(\.(css|js|png|jpg)$|partials\/.*\.html$)/,
match; match;