diff options
52 files changed, 470 insertions, 74 deletions
@@ -7,6 +7,6 @@ "components-font-awesome": "3.1.0", "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", - "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" } } diff --git a/docs/component-spec/errorDisplaySpec.js b/docs/component-spec/errorDisplaySpec.js new file mode 100644 index 00000000..8122e253 --- /dev/null +++ b/docs/component-spec/errorDisplaySpec.js @@ -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}'); + }); +});
\ No newline at end of file diff --git a/docs/content/error/cacheFactory/iid.ngdoc b/docs/content/error/cacheFactory/iid.ngdoc new file mode 100644 index 00000000..e3f32166 --- /dev/null +++ b/docs/content/error/cacheFactory/iid.ngdoc @@ -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.
\ No newline at end of file diff --git a/docs/content/error/compile/ctreq.ngdoc b/docs/content/error/compile/ctreq.ngdoc new file mode 100644 index 00000000..065533b7 --- /dev/null +++ b/docs/content/error/compile/ctreq.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $compile:ctreq +@fullName Missing Required Controller +@description diff --git a/docs/content/error/compile/iscp.ngdoc b/docs/content/error/compile/iscp.ngdoc new file mode 100644 index 00000000..afdbd4c4 --- /dev/null +++ b/docs/content/error/compile/iscp.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $compile:iscp +@fullName Invalid Isolate Scope +@description diff --git a/docs/content/error/compile/multidir.ngdoc b/docs/content/error/compile/multidir.ngdoc new file mode 100644 index 00000000..4e893c3e --- /dev/null +++ b/docs/content/error/compile/multidir.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $compile:multidir +@fullName Multiple Directive Resource Contention +@description diff --git a/docs/content/error/compile/noass.ngdoc b/docs/content/error/compile/noass.ngdoc new file mode 100644 index 00000000..bb247499 --- /dev/null +++ b/docs/content/error/compile/noass.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $compile:noass +@fullName Non-Assignable Expression +@description diff --git a/docs/content/error/compile/nodomevents.ngdoc b/docs/content/error/compile/nodomevents.ngdoc new file mode 100644 index 00000000..421e896f --- /dev/null +++ b/docs/content/error/compile/nodomevents.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $compile:nodomevents +@fullName Interpolated Event Attributes +@description diff --git a/docs/content/error/compile/tpload.ngdoc b/docs/content/error/compile/tpload.ngdoc new file mode 100644 index 00000000..78826abb --- /dev/null +++ b/docs/content/error/compile/tpload.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $compile:tpload +@fullName Template Loader Error +@description diff --git a/docs/content/error/compile/tplrt.ngdoc b/docs/content/error/compile/tplrt.ngdoc new file mode 100644 index 00000000..4afd88cd --- /dev/null +++ b/docs/content/error/compile/tplrt.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $compile:tplrt +@fullName Invalid Template Root +@description diff --git a/docs/content/error/compile/utrat.ngdoc b/docs/content/error/compile/utrat.ngdoc new file mode 100644 index 00000000..64ffa223 --- /dev/null +++ b/docs/content/error/compile/utrat.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $compile:utrat +@fullName Unterminated Attribute +@description diff --git a/docs/content/error/controller/noscp.ngdoc b/docs/content/error/controller/noscp.ngdoc new file mode 100644 index 00000000..f9e89487 --- /dev/null +++ b/docs/content/error/controller/noscp.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $controller:noscp +@fullName Missing $scope object +@description diff --git a/docs/content/error/httpBackend/noxhr.ngdoc b/docs/content/error/httpBackend/noxhr.ngdoc new file mode 100644 index 00000000..a311620f --- /dev/null +++ b/docs/content/error/httpBackend/noxhr.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $httpBackend:noxhr +@fullName Unsupported XHR +@description diff --git a/docs/content/error/index.ngdoc b/docs/content/error/index.ngdoc new file mode 100644 index 00000000..9512dc9c --- /dev/null +++ b/docs/content/error/index.ngdoc @@ -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 diff --git a/docs/content/error/injector/cdep.ngdoc b/docs/content/error/injector/cdep.ngdoc new file mode 100644 index 00000000..f4a9c909 --- /dev/null +++ b/docs/content/error/injector/cdep.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $injector:cdep +@fullName Circular Dependency +@description diff --git a/docs/content/error/injector/itkn.ngdoc b/docs/content/error/injector/itkn.ngdoc new file mode 100644 index 00000000..fab64696 --- /dev/null +++ b/docs/content/error/injector/itkn.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $injector:itkn +@fullName Bad Injection Token +@description diff --git a/docs/content/error/injector/modulerr.ngdoc b/docs/content/error/injector/modulerr.ngdoc new file mode 100644 index 00000000..5d2aa8f8 --- /dev/null +++ b/docs/content/error/injector/modulerr.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $injector:modulerr +@fullName Module Error +@description diff --git a/docs/content/error/injector/nomod.ngdoc b/docs/content/error/injector/nomod.ngdoc new file mode 100644 index 00000000..6dd4c169 --- /dev/null +++ b/docs/content/error/injector/nomod.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $injector:nomod +@fullName Module Unavailable +@description diff --git a/docs/content/error/injector/pget.ngdoc b/docs/content/error/injector/pget.ngdoc new file mode 100644 index 00000000..3eca8d80 --- /dev/null +++ b/docs/content/error/injector/pget.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $injector:pget +@fullName Provider Missing $get +@description diff --git a/docs/content/error/injector/unpr.ngdoc b/docs/content/error/injector/unpr.ngdoc new file mode 100644 index 00000000..5459711f --- /dev/null +++ b/docs/content/error/injector/unpr.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $injector:unpr +@fullName Unknown Provider +@description diff --git a/docs/content/error/interpolate/interr.ngdoc b/docs/content/error/interpolate/interr.ngdoc new file mode 100644 index 00000000..a36a1d7d --- /dev/null +++ b/docs/content/error/interpolate/interr.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $interpolate:interr +@fullName Interpolation Error +@description diff --git a/docs/content/error/interpolate/noconcat.ngdoc b/docs/content/error/interpolate/noconcat.ngdoc new file mode 100644 index 00000000..f1fd6c46 --- /dev/null +++ b/docs/content/error/interpolate/noconcat.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $interpolate:noconcat +@fullName Multiple Expressions +@description diff --git a/docs/content/error/jqLite/nosel.ngdoc b/docs/content/error/jqLite/nosel.ngdoc new file mode 100644 index 00000000..c776c153 --- /dev/null +++ b/docs/content/error/jqLite/nosel.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name jqLite:nosel +@fullName Unsupported Selector Lookup +@description diff --git a/docs/content/error/jqLite/off_args.ngdoc b/docs/content/error/jqLite/off_args.ngdoc new file mode 100644 index 00000000..88a981e3 --- /dev/null +++ b/docs/content/error/jqLite/off_args.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name jqLite:off_args +@fullName Invalid jqLite#off() parameter +@description diff --git a/docs/content/error/jqLite/on_args.ngdoc b/docs/content/error/jqLite/on_args.ngdoc new file mode 100644 index 00000000..974f20a8 --- /dev/null +++ b/docs/content/error/jqLite/on_args.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name jqLite:on_args +@fullName Invalid jqLite#on() Parameters +@description diff --git a/docs/content/error/location/istart.ngdoc b/docs/content/error/location/istart.ngdoc new file mode 100644 index 00000000..006689e4 --- /dev/null +++ b/docs/content/error/location/istart.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $location:istart +@fullName Invalid URL +@description diff --git a/docs/content/error/location/nohash.ngdoc b/docs/content/error/location/nohash.ngdoc new file mode 100644 index 00000000..81f0d569 --- /dev/null +++ b/docs/content/error/location/nohash.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $location:nohash +@fullName Missing Hash Prefix +@description diff --git a/docs/content/error/location/nopp.ngdoc b/docs/content/error/location/nopp.ngdoc new file mode 100644 index 00000000..3d95b7ff --- /dev/null +++ b/docs/content/error/location/nopp.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $location:nopp +@fullName Missing Path Prefix +@description diff --git a/docs/content/error/ng/areq.ngdoc b/docs/content/error/ng/areq.ngdoc new file mode 100644 index 00000000..ade8a5ba --- /dev/null +++ b/docs/content/error/ng/areq.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ng:areq +@fullName Bad Argument +@description diff --git a/docs/content/error/ng/cpi.ngdoc b/docs/content/error/ng/cpi.ngdoc new file mode 100644 index 00000000..95b30024 --- /dev/null +++ b/docs/content/error/ng/cpi.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ng:cpi +@fullName Bad Copy +@description diff --git a/docs/content/error/ng/cpws.ngdoc b/docs/content/error/ng/cpws.ngdoc new file mode 100644 index 00000000..2f7a9c5b --- /dev/null +++ b/docs/content/error/ng/cpws.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ng:cpws +@fullName Copying Window or Scope +@description diff --git a/docs/content/error/ngModel/noass.ngdoc b/docs/content/error/ngModel/noass.ngdoc new file mode 100644 index 00000000..c9fe6637 --- /dev/null +++ b/docs/content/error/ngModel/noass.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ngModel:noass +@fullName Non-Assignable Expression +@description diff --git a/docs/content/error/ngOptions/iexp.ngdoc b/docs/content/error/ngOptions/iexp.ngdoc new file mode 100644 index 00000000..4fc4b8d2 --- /dev/null +++ b/docs/content/error/ngOptions/iexp.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ngOptions:iexp +@fullName Invalid Expression +@description diff --git a/docs/content/error/ngPattern/noregexp.ngdoc b/docs/content/error/ngPattern/noregexp.ngdoc new file mode 100644 index 00000000..bc2f56d6 --- /dev/null +++ b/docs/content/error/ngPattern/noregexp.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ngPattern:noregexp +@fullName Expected Regular Expression +@description diff --git a/docs/content/error/ngRepeat/dupes.ngdoc b/docs/content/error/ngRepeat/dupes.ngdoc new file mode 100644 index 00000000..eb25ec67 --- /dev/null +++ b/docs/content/error/ngRepeat/dupes.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ngRepeat:dupes +@fullName Duplicate Repeater Key +@description diff --git a/docs/content/error/ngRepeat/iexp.ngdoc b/docs/content/error/ngRepeat/iexp.ngdoc new file mode 100644 index 00000000..18701776 --- /dev/null +++ b/docs/content/error/ngRepeat/iexp.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ngRepeat:iexp +@fullName Invalid Expression +@description diff --git a/docs/content/error/ngRepeat/iidexp.ngdoc b/docs/content/error/ngRepeat/iidexp.ngdoc new file mode 100644 index 00000000..f9aa7c50 --- /dev/null +++ b/docs/content/error/ngRepeat/iidexp.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ngRepeat:iidexp +@fullName Invalid Identifier +@description diff --git a/docs/content/error/ngResource/badargs.ngdoc b/docs/content/error/ngResource/badargs.ngdoc new file mode 100644 index 00000000..9686f7a3 --- /dev/null +++ b/docs/content/error/ngResource/badargs.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ngResource:badargs +@fullName Too Many Arguments +@description diff --git a/docs/content/error/ngSanitize/badparse.ngdoc b/docs/content/error/ngSanitize/badparse.ngdoc new file mode 100644 index 00000000..fd184e14 --- /dev/null +++ b/docs/content/error/ngSanitize/badparse.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name ngSanitize:badparse +@fullName Parsing Error +@description diff --git a/docs/content/error/parse/isecfld.ngdoc b/docs/content/error/parse/isecfld.ngdoc new file mode 100644 index 00000000..7489baf7 --- /dev/null +++ b/docs/content/error/parse/isecfld.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $parse:isecfld +@fullName Referencing constructor Field +@description diff --git a/docs/content/error/parse/isecfn.ngdoc b/docs/content/error/parse/isecfn.ngdoc new file mode 100644 index 00000000..1e932f30 --- /dev/null +++ b/docs/content/error/parse/isecfn.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $parse:isecfn +@fullName Referencing Function Disallowed +@description diff --git a/docs/content/error/parse/lexerr.ngdoc b/docs/content/error/parse/lexerr.ngdoc new file mode 100644 index 00000000..f03cb93b --- /dev/null +++ b/docs/content/error/parse/lexerr.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $parse:lexerr +@fullName Lexer Error +@description diff --git a/docs/content/error/parse/syntax.ngdoc b/docs/content/error/parse/syntax.ngdoc new file mode 100644 index 00000000..122eda21 --- /dev/null +++ b/docs/content/error/parse/syntax.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $parse:syntax +@fullName Syntax Error +@description diff --git a/docs/content/error/parse/ueoe.ngdoc b/docs/content/error/parse/ueoe.ngdoc new file mode 100644 index 00000000..726d15c3 --- /dev/null +++ b/docs/content/error/parse/ueoe.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $parse:ueoe +@fullName Unexpected End of Expression +@description diff --git a/docs/content/error/rootScope/infdig.ngdoc b/docs/content/error/rootScope/infdig.ngdoc new file mode 100644 index 00000000..82bcc075 --- /dev/null +++ b/docs/content/error/rootScope/infdig.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $rootScope:infdig +@fullName Infinite $digest Loop +@description diff --git a/docs/content/error/rootScope/inprog.ngdoc b/docs/content/error/rootScope/inprog.ngdoc new file mode 100644 index 00000000..ce1151d0 --- /dev/null +++ b/docs/content/error/rootScope/inprog.ngdoc @@ -0,0 +1,4 @@ +@ngdoc error +@name $rootScope:inprog +@fullName Action Already In Progress +@description 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 @@ <li><a href="./tutorial/">Tutorial</a></li> <li><a href="./guide/">Developer Guide</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://code.angularjs.org/">Download</a></li> </ul> @@ -263,7 +264,16 @@ </li> </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"> <li class="nav-header module"> <a class="guide" href="{{URL.module}}">module</a> diff --git a/docs/src/templates/js/docs.js b/docs/src/templates/js/docs.js index ddc0405f..a14237fa 100644 --- a/docs/src/templates/js/docs.js +++ b/docs/src/templates/js/docs.js @@ -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) { var urls = {}; @@ -420,6 +449,7 @@ docsApp.serviceFactory.sections = ['NG_PAGES', function sections(NG_PAGES) { tutorial: [], misc: [], cookbook: [], + error: [], getPage: function(sectionId, partialId) { var pages = sections[sectionId]; @@ -463,9 +493,10 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie } }; 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)$/, GLOBALS = /^angular\.([^\.]+)$/, + ERROR = /^([a-zA-Z0-9_$]+:)?([a-zA-Z0-9_$]+)$/, MODULE = /^((?:(?!^angular\.)[^\.])+)$/, MODULE_MOCK = /^angular\.mock\.([^\.]+)$/, MODULE_DIRECTIVE = /^((?:(?!^angular\.)[^\.])+)\.directive:([^\.]+)$/, @@ -529,14 +560,15 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie guide: 'Developer Guide', misc: 'Miscellaneous', tutorial: 'Tutorial', - cookbook: 'Examples' + cookbook: 'Examples', + error: 'Error Reference' }; $scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) { // ignore non-doc links which are used in examples if (DOCS_PATH.test(path)) { var parts = path.split('/'), sectionId = parts[1], - partialId = parts[2], + partialId = parts.slice(2).join('/'), sectionName = SECTION_NAME[sectionId] || sectionId, page = sections.getPage(sectionId, partialId); @@ -624,9 +656,12 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie ***********************************/ function updateSearch() { - var cache = {}, + var moduleCache = {}, + namespaceCache = {}, pages = sections[$location.path().split('/')[1]], modules = $scope.modules = [], + namespaces = $scope.namespaces = [], + globalErrors = $scope.globalErrors = [], otherPages = $scope.pages = [], search = $scope.search, bestMatch = {page: null, rank:0}; @@ -644,7 +679,14 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie if (page.id == 'index') { //skip } 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') { module('ng').types.push(page); } else if (match = id.match(GLOBALS)) { @@ -672,19 +714,20 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie /*************/ function module(name) { - var module = cache[name]; + var module = moduleCache[name]; + if (!module) { - module = cache[name] = { + module = moduleCache[name] = { name: name, url: 'api/' + name, globals: [], directives: [], services: [], service: function(name) { - var service = cache[this.name + ':' + name]; + var service = moduleCache[this.name + ':' + name]; if (!service) { service = {name: name}; - cache[this.name + ':' + name] = service; + moduleCache[this.name + ':' + name] = service; this.services.push(service); } return service; @@ -697,6 +740,20 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie 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) { var ranking = {page: page, rank:0}, keywords = page.keywords, diff --git a/lib/grunt/utils.js b/lib/grunt/utils.js index 964c0317..c5ca4d23 100644 --- a/lib/grunt/utils.js +++ b/lib/grunt/utils.js @@ -154,7 +154,7 @@ module.exports = { '--language_in ECMASCRIPT5_STRICT ' + '--minerr_pass ' + '--minerr_errors ' + errorFileName + ' ' + - '--minerr_url http://docs.angularjs.org/minerr/ ' + + '--minerr_url http://errors.angularjs.org/ ' + '--source_map_format=V3 ' + '--create_source_map ' + mapFile + ' ' + '--js ' + file + ' ' + @@ -233,7 +233,7 @@ module.exports = { //rewrite connect middleware rewrite: function(){ 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$)/, match; |
