From 7e0288cd35040a8f0e3fa879e02ab8e04ed10290 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Thu, 6 Feb 2014 21:17:40 -0500 Subject: [PATCH 001/123] feat($location): parse query parameters delimited by ; or & In accordance with recomendation in http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2.2, the query parameters should support encoding and decoding using & or ; as a delimiter. Angular will consistently encode search queries using either '&' or ';' as the delimiter, with '&' being the default. This can be configured like so: ```js $locationProvider.queryDelimiter(';'); // any other value will be treated as '&' ``` Closes #6140 --- src/Angular.js | 9 ++++-- src/ng/location.js | 33 +++++++++++++++++---- test/ng/locationSpec.js | 63 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index 9811c3637eba..f4054037110b 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -1021,7 +1021,7 @@ function tryDecodeURIComponent(value) { */ function parseKeyValue(/**string*/keyValue) { var obj = {}, key_value, key; - forEach((keyValue || "").split('&'), function(keyValue){ + forEach((keyValue || "").split(/[&;]/), function(keyValue){ if ( keyValue ) { key_value = keyValue.split('='); key = tryDecodeURIComponent(key_value[0]); @@ -1040,8 +1040,11 @@ function parseKeyValue(/**string*/keyValue) { return obj; } -function toKeyValue(obj) { +function toKeyValue(obj, delimiter) { var parts = []; + if (delimiter !== '&' && delimiter !== ';') { + delimiter = '&'; + } forEach(obj, function(value, key) { if (isArray(value)) { forEach(value, function(arrayValue) { @@ -1053,7 +1056,7 @@ function toKeyValue(obj) { (value === true ? '' : '=' + encodeUriQuery(value, true))); } }); - return parts.length ? parts.join('&') : ''; + return parts.length ? parts.join(delimiter) : ''; } diff --git a/src/ng/location.js b/src/ng/location.js index 9ab99cb719fa..20df6a3d8ec2 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -87,7 +87,7 @@ function serverBase(url) { * @param {string} appBase application base URL * @param {string} basePrefix url path prefix */ -function LocationHtml5Url(appBase, basePrefix) { +function LocationHtml5Url(appBase, basePrefix, queryDelimiter) { this.$$html5 = true; basePrefix = basePrefix || ''; var appBaseNoFile = stripFile(appBase); @@ -120,7 +120,7 @@ function LocationHtml5Url(appBase, basePrefix) { * @private */ this.$$compose = function() { - var search = toKeyValue(this.$$search), + var search = toKeyValue(this.$$search, queryDelimiter), hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; @@ -155,7 +155,7 @@ function LocationHtml5Url(appBase, basePrefix) { * @param {string} appBase application base URL * @param {string} hashPrefix hashbang prefix */ -function LocationHashbangUrl(appBase, hashPrefix) { +function LocationHashbangUrl(appBase, hashPrefix, queryDelimiter) { var appBaseNoFile = stripFile(appBase); parseAbsoluteUrl(appBase, this, appBase); @@ -227,7 +227,7 @@ function LocationHashbangUrl(appBase, hashPrefix) { * @private */ this.$$compose = function() { - var search = toKeyValue(this.$$search), + var search = toKeyValue(this.$$search, queryDelimiter), hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; @@ -531,7 +531,8 @@ function locationGetterSetter(property, preprocess) { */ function $LocationProvider(){ var hashPrefix = '', - html5Mode = false; + html5Mode = false, + queryDelimiter = '&'; /** * @ngdoc property @@ -567,6 +568,26 @@ function $LocationProvider(){ } }; + /** + * @ngdoc property + * @name ng.$locationProvider#queryDelimiter + * @methodOf ng.$locationProvider + * @description + * @param {string=} delimiter String to use as a delimiter for query parameters. Must be '&' or + * ';' + * @returns {*} current value if used as getter or itself (chaining) if used as setter + */ + this.queryDelimiter = function(delimiter) { + if (arguments.length > 0) { + if (delimiter !== ';' && delimiter !== '&') { + delimiter = '&'; + } + queryDelimiter = delimiter; + return this; + } + return queryDelimiter; + }; + /** * @ngdoc event * @name ng.$location#$locationChangeStart @@ -611,7 +632,7 @@ function $LocationProvider(){ appBase = stripHash(initialUrl); LocationMode = LocationHashbangUrl; } - $location = new LocationMode(appBase, '#' + hashPrefix); + $location = new LocationMode(appBase, '#' + hashPrefix, queryDelimiter); $location.$$parse($location.$$rewrite(initialUrl)); $rootElement.on('click', function(event) { diff --git a/test/ng/locationSpec.js b/test/ng/locationSpec.js index ff823d306efd..912e753e5de5 100644 --- a/test/ng/locationSpec.js +++ b/test/ng/locationSpec.js @@ -313,6 +313,38 @@ describe('$location', function() { expect(url.search()).toEqual({'i j': '<>#'}); expect(url.hash()).toBe('x <>#'); }); + + + it('should decode query params delimited interchangeably by & and ;', function() { + var url = new LocationHtml5Url('http://host.com/'); + url.$$parse('http://host.com/?foo=1&bar=2;baz=3'); + expect(url.search()).toEqual({ + 'foo': '1', + 'bar': '2', + 'baz': '3' + }); + }); + + + it('should honor configured query param delimiter if ; --- otherwise use &', function() { + url = new LocationHtml5Url('http://host.com/', '#', ';'); + url.$$parse('http://host.com/'); + url.search({ + "foo": "1", + "bar": "2", + "baz": "3" + }); + expect(url.absUrl()).toMatch(/\?foo=1;bar=2;baz=3$/); + + url = new LocationHtml5Url('http://host.com/', '#', '*'); + url.$$parse('http://host.com/'); + url.search({ + "foo": "1", + "bar": "2", + "baz": "3" + }); + expect(url.absUrl()).toMatch(/\?foo=1&bar=2&baz=3$/); + }); }); }); @@ -435,6 +467,17 @@ describe('$location', function() { }); + it('should decode query params delimited interchangeably by & and ;', function() { + var url = new LocationHashbangUrl('http://host.com/', '#'); + url.$$parse('http://host.com/#?foo=1&bar=2;baz=3'); + expect(url.search()).toEqual({ + 'foo': '1', + 'bar': '2', + 'baz': '3' + }); + }); + + it('should return decoded characters for search specified with setter', function() { var locationUrl = new LocationHtml5Url('http://host.com/'); locationUrl.$$parse('http://host.com/') @@ -464,6 +507,26 @@ describe('$location', function() { locationUrl.search({'q': '4/5 6'}); expect(locationUrl.absUrl()).toEqual('http://host.com?q=4%2F5%206'); }); + + it('should honor configured query param delimiter if ; --- otherwise use &', function() { + url = new LocationHashbangUrl('http://host.com/', '#', ';'); + url.$$parse('http://host.com/'); + url.search({ + "foo": "1", + "bar": "2", + "baz": "3" + }); + expect(url.absUrl()).toMatch(/\?foo=1;bar=2;baz=3$/); + + url = new LocationHashbangUrl('http://host.com/', '#', '*'); + url.$$parse('http://host.com/'); + url.search({ + "foo": "1", + "bar": "2", + "baz": "3" + }); + expect(url.absUrl()).toMatch(/\?foo=1&bar=2&baz=3$/); + }); }); }); From b6fe8c7a7a0c3ed660f3dbcb979ff8cd163fc846 Mon Sep 17 00:00:00 2001 From: Julie Date: Thu, 6 Feb 2014 12:45:43 -0800 Subject: [PATCH 002/123] chore(testing): de-flake a ngHref test for navigating away from the Angular page --- src/ng/directive/booleanAttrs.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ng/directive/booleanAttrs.js b/src/ng/directive/booleanAttrs.js index 79199925a15e..6762ab2d1e25 100644 --- a/src/ng/directive/booleanAttrs.js +++ b/src/ng/directive/booleanAttrs.js @@ -59,7 +59,14 @@ element(by.id('link-3')).click(); - expect(browser.driver.getCurrentUrl()).toMatch(/\/123$/); + // At this point, we navigate away from an Angular page, so we need + // to use browser.driver to get the base webdriver. + + browser.wait(function() { + return browser.driver.getCurrentUrl().then(function(url) { + return url.match(/\/123$/); + }); + }, 1000, 'page should navigate to /123'); }); it('should execute ng-click but not reload when href empty string and name specified', function() { From 246783373bd7c519f513ef945af8b9870b34bc9d Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Thu, 6 Feb 2014 17:49:14 -0800 Subject: [PATCH 003/123] chore(build): Update closure i18n integration Use git repo as source and use q-io instead of q-fs --- i18n/README.md | 3 +-- i18n/generate.sh | 7 ++++++- i18n/run-tests.sh | 3 ++- i18n/src/closureSlurper.js | 40 ++++++++++++++++++++++++++------------ i18n/update-closure.sh | 11 ++++++----- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/i18n/README.md b/i18n/README.md index 9bff2adfb915..d06264638bdb 100644 --- a/i18n/README.md +++ b/i18n/README.md @@ -1,11 +1,10 @@ # i18n directory overview: - closure/ - closure files we use for ruleset generation -- locale/ - angular's locale ruleset files - src/ - source files - spec/ - spec files for stuff in src directory - generate.sh - runs src scripts on closure dir and stores output in locale dir -- update-closure.sh - downloads the latest version of closure files from public svn repo +- update-closure.sh - downloads the latest version of closure files from public git repo The closure files (maintained by Shanjian Li (shanjian)) change very rarely, so we don't need to regenerate locale files very often. diff --git a/i18n/generate.sh b/i18n/generate.sh index 3b3f44422790..4c5db4402388 100755 --- a/i18n/generate.sh +++ b/i18n/generate.sh @@ -1,7 +1,12 @@ #!/bin/bash +set -e + BASE_DIR=`dirname $0` cd $BASE_DIR +./run-tests.sh + +node src/closureSlurper.js + -../node_modules/.bin/jasmine-node spec/ --noColor && node src/closureSlurper.js diff --git a/i18n/run-tests.sh b/i18n/run-tests.sh index 68b134011b04..3f710c023a10 100755 --- a/i18n/run-tests.sh +++ b/i18n/run-tests.sh @@ -2,4 +2,5 @@ set -e PARENT_DIR="$(dirname "$0")" -jasmine-node "$PARENT_DIR"/spec/ + +../node_modules/.bin/jasmine-node "$PARENT_DIR"/spec/ diff --git a/i18n/src/closureSlurper.js b/i18n/src/closureSlurper.js index 9f236cf22a9f..02a1d9efec13 100755 --- a/i18n/src/closureSlurper.js +++ b/i18n/src/closureSlurper.js @@ -2,7 +2,7 @@ 'use strict'; var Q = require('q'), - qfs = require('q-fs'), + qfs = require('q-io/fs'), converter = require('./converter.js'), util = require('./util.js'), closureI18nExtractor = require('./closureI18nExtractor.js'), @@ -47,24 +47,40 @@ function extractPlurals() { function writeLocaleFiles() { console.log('Final stage: Writing angular locale files to directory: %j', NG_LOCALE_DIR); - var writePromises = []; + var result = Q.defer(); var localeIds = Object.keys(localeInfo); var num_files = 0; - localeIds.forEach(function(localeID) { + + console.log('Generated %j locale files.', localeIds.length); + loop(); + return result.promise; + + // Need to use a loop and not write the files in parallel, + // as otherwise we will get the error EMFILE, which means + // we have too many open files. + function loop() { + var nextPromise; + if (localeIds.length) { + nextPromise = process(localeIds.pop()) || Q.when(); + nextPromise.then(loop, result.reject); + } else { + result.resolve(num_files); + } + } + + function process(localeID) { var content = closureI18nExtractor.outputLocale(localeInfo, localeID); if (!content) return; var correctedLocaleId = closureI18nExtractor.correctedLocaleId(localeID); var filename = NG_LOCALE_DIR + 'angular-locale_' + correctedLocaleId + '.js' - writePromises.push( - qfs.write(filename, content) - .then(function () { - console.log('Wrote ' + filename); - ++num_files; - })); console.log('Writing ' + filename); - }); - console.log('Generated %j locale files.', localeIds.length); - return Q.all(writePromises).then(function() { return num_files }); + return qfs.write(filename, content) + .then(function () { + console.log('Wrote ' + filename); + ++num_files; + }); + } + } /** diff --git a/i18n/update-closure.sh b/i18n/update-closure.sh index 2ddf88922fad..e8f7cb5c2ce3 100755 --- a/i18n/update-closure.sh +++ b/i18n/update-closure.sh @@ -7,8 +7,9 @@ cd $BASE_DIR set -x # Trace commands as they're executed. -curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/currency.js > closure/currencySymbols.js -curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/datetimesymbols.js > closure/datetimeSymbols.js -curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/datetimesymbolsext.js > closure/datetimeSymbolsExt.js -curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/numberformatsymbols.js > closure/numberSymbols.js -curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/pluralrules.js > closure/pluralRules.js +# use the github repo as it is more up to date than the svn repo +curl https://closure-library.googlecode.com/git/closure/goog/i18n/currency.js > closure/currencySymbols.js +curl https://closure-library.googlecode.com/git/closure/goog/i18n/datetimesymbols.js > closure/datetimeSymbols.js +curl https://closure-library.googlecode.com/git/closure/goog/i18n/datetimesymbolsext.js > closure/datetimeSymbolsExt.js +curl https://closure-library.googlecode.com/git/closure/goog/i18n/numberformatsymbols.js > closure/numberSymbols.js +curl https://closure-library.googlecode.com/git/closure/goog/i18n/pluralrules.js > closure/pluralRules.js From 8c41c4ecc3d12f3a9fe20e56cd98e8cc4b9b0b1d Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Fri, 7 Feb 2014 11:15:00 -0800 Subject: [PATCH 004/123] docs(contributing): add code of conduct --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c90fdccc276d..be2e12abcc8c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,9 @@ We'd love for you to contribute to our source code and to make AngularJS even better than it is today! Here are the guidelines we'd like you to follow: +## Code of Conduct +Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc]. + ## Got a Question or Problem? If you have questions about how to use AngularJS, please direct these to the [Google Group][groups] @@ -258,5 +261,6 @@ You can find out more detailed information about contributing in the [corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html [commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit# [github-pr-helper]: https://chrome.google.com/webstore/detail/github-pr-helper/mokbklfnaddkkbolfldepnkfmanfhpen +[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md [![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/CONTRIBUTING.md?pixel)](https://github.com/igrigorik/ga-beacon) From 85b5a75270b6e92ef8c3df2f56421d7b99296d82 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Fri, 7 Feb 2014 12:14:32 -0800 Subject: [PATCH 005/123] revert: refactor(mocks): simplify the `inject` implementation This reverts commit 64d58a5b5292046adf8b28928950858ab3895fcc. For some weird reason this is causing regressions at Google. I'm not sure why and I'm running out of time to investigate, so I'm taking a safe route here and reverting the commit since it's just a refactoring. --- src/ngMock/angular-mocks.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 1be07a242b46..6b8868f7501d 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -2095,7 +2095,7 @@ if(window.jasmine || window.mocha) { window.inject = angular.mock.inject = function() { var blockFns = Array.prototype.slice.call(arguments, 0); var errorForStack = new Error('Declaration Location'); - return isSpecRunning() ? workFn() : workFn; + return isSpecRunning() ? workFn.call(currentSpec) : workFn; ///////////////////// function workFn() { var modules = currentSpec.$modules || []; @@ -2108,8 +2108,9 @@ if(window.jasmine || window.mocha) { } for(var i = 0, ii = blockFns.length; i < ii; i++) { try { - // jasmine sets this to be the current spec, so we are mimicing that - injector.invoke(blockFns[i] || angular.noop, currentSpec); + /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */ + injector.invoke(blockFns[i] || angular.noop, this); + /* jshint +W040 */ } catch (e) { if (e.stack && errorForStack) { throw new ErrorAddingDeclarationLocationStack(e, errorForStack); From 3e3d17e52f7733d24b1dfc9fc0c8d37729eef434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Fri, 7 Feb 2014 16:49:41 -0500 Subject: [PATCH 006/123] docs(changelog): release notes for 1.2.12 --- CHANGELOG.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e635e9f88bf..643c016a21dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,64 @@ + +# 1.2.12 cauliflower-eradication (2014-02-07) + + +## Bug Fixes + +- **$compile:** retain CSS classes added in cloneAttachFn on asynchronous directives + ([5ed721b9](https://github.com/angular/angular.js/commit/5ed721b9b5e95ae08450e1ae9d5202e7f3f79295), + [#5439](https://github.com/angular/angular.js/issues/5439), [#5617](https://github.com/angular/angular.js/issues/5617)) +- **$http:** + - ignore xhr.responseType setter exception if value is "json" + ([24699ee8](https://github.com/angular/angular.js/commit/24699ee8f04c1f1459be1d36207e654421d58ff0), + [#6115](https://github.com/angular/angular.js/issues/6115), [#6122](https://github.com/angular/angular.js/issues/6122)) + - update httpBackend to use ActiveXObject on IE8 if necessary + ([ef210e5e](https://github.com/angular/angular.js/commit/ef210e5e119db4f5bfc9d2428b19f9b335c4f976), + [#5677](https://github.com/angular/angular.js/issues/5677), [#5679](https://github.com/angular/angular.js/issues/5679)) +- **$locale:** minor grammar amends for the locale `locale_lt` + ([95be253f](https://github.com/angular/angular.js/commit/95be253fe55d35336d425d3d600a36158fc3519d), + [#6164](https://github.com/angular/angular.js/issues/6164)) +- **$q:** make $q.reject support `finally` and `catch` + ([074b0675](https://github.com/angular/angular.js/commit/074b0675a1f97dce07f520f1ae6198ed3c604000), + [#6048](https://github.com/angular/angular.js/issues/6048), [#6076](https://github.com/angular/angular.js/issues/6076)) +- **docs:** clarify doc for "args" in $broadcast and $emit + ([caed2dfe](https://github.com/angular/angular.js/commit/caed2dfe4feeac5d19ecea2dbb1456b7fde21e6d), + [#6047](https://github.com/angular/angular.js/issues/6047)) +- **filterFilter:** don't interpret dots in predicate object fields as paths + ([339a1658](https://github.com/angular/angular.js/commit/339a1658cd9bfa5e322a01c45aa0a1df67e3a842), + [#6005](https://github.com/angular/angular.js/issues/6005), [#6009](https://github.com/angular/angular.js/issues/6009)) +- **http:** make jshint happy + ([6609e3da](https://github.com/angular/angular.js/commit/6609e3da76dd898cfe85f75f23ab2e39fee65fe5)) +- **jqLite:** trim HTML string in jqLite constructor + ([36d37c0e](https://github.com/angular/angular.js/commit/36d37c0e3880c774d20c014ade60d2331beefa15), + [#6053](https://github.com/angular/angular.js/issues/6053)) +- **mocks:** + - rename mock.animate to ngAnimateMock and ensure it contains all test helper code for ngAnimate + ([4224cd51](https://github.com/angular/angular.js/commit/4224cd5182bc93e4a210f75e0a4e4de7f3c544e8), + [#5822](https://github.com/angular/angular.js/issues/5822), [#5917](https://github.com/angular/angular.js/issues/5917)) + - remove usage of $animate.flushNext in favour of queing + ([906fdad0](https://github.com/angular/angular.js/commit/906fdad0f95465842e336e057ea97d0633712189)) + - always call functions injected with `inject` with `this` set to the current spec + ([3bf43903](https://github.com/angular/angular.js/commit/3bf43903397c703aa2e9ba1e1a48dbc9e8286ee2), + [#6102](https://github.com/angular/angular.js/issues/6102)) + - refactor currentSpec to work w/ Jasmine 2 + ([95f0bf9b](https://github.com/angular/angular.js/commit/95f0bf9b526fda8964527c6d4aef1ad50a47f1f3), + [#5662](https://github.com/angular/angular.js/issues/5662)) +- **ngMock:** return false from mock $interval.cancel() when no argument is supplied + ([dd24c783](https://github.com/angular/angular.js/commit/dd24c78373b5d24ecb3b9d19e61e1b3b6c74d155), + [#6103](https://github.com/angular/angular.js/issues/6103)) +- **ngResource:** + - don't filter "$"-prefixed properties from ngResource requests/responses + ([d2e4e499](https://github.com/angular/angular.js/commit/d2e4e499862aeca157dbe7a7422c465e7c79205e), + [#5666](https://github.com/angular/angular.js/issues/5666), [#6080](https://github.com/angular/angular.js/issues/6080), [#6033](https://github.com/angular/angular.js/issues/6033)) + - don't append number to '$' in url param value when encoding URI + ([ce1f1f97](https://github.com/angular/angular.js/commit/ce1f1f97f0ebf77941b2bdaf5e8352d33786524d), + [#6003](https://github.com/angular/angular.js/issues/6003), [#6004](https://github.com/angular/angular.js/issues/6004)) + +## Breaking Changes + +The animation mock module has been renamed from `mock.animate` to `ngAnimateMock`. In addition to the rename, animations will not block within test code even when ngAnimateMock is used. However, all function calls to $animate will be recorded into `$animate.queue` and are available within test code to assert animation calls. In addition, `$animate.triggerReflow()` is now only available when `ngAnimateMock` is used. + + # 1.2.11 cryptocurrency-hyperdeflation (2014-02-03) From 5479787aadd72752d6a8103e76ceb40620788093 Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 7 Feb 2014 14:38:15 -0800 Subject: [PATCH 007/123] chore(release): update cdn version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 828dd45ea00c..bd9afbf556aa 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "angularjs", "branchVersion": "1.2.*", - "cdnVersion": "1.2.11", + "cdnVersion": "1.2.12", "repository": { "type": "git", "url": "https://github.com/angular/angular.js.git" From 018223d24f0da1046db40ae5fe5cca9a89aa1e5d Mon Sep 17 00:00:00 2001 From: Julie Date: Fri, 7 Feb 2014 17:49:47 -0800 Subject: [PATCH 008/123] chore(testing): switch Jenkins to test e2e only on chrome End to end tests will continue to be run on Safari and Firefox on Travis. Closes #6187 --- jenkins_build.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/jenkins_build.sh b/jenkins_build.sh index a6f7849ccecc..2dc69cbceed2 100755 --- a/jenkins_build.sh +++ b/jenkins_build.sh @@ -32,8 +32,6 @@ grunt test:unit --browsers $BROWSERS --reporters=dots,junit --no-colors --no-col # END TO END TESTS # grunt test:ci-protractor -grunt test:ci-protractor --browser safari -grunt test:ci-protractor --browser firefox # Promises/A+ TESTS # grunt test:promises-aplus --no-color From 0147b0985e010c12740130993d0b5ed369e20bb6 Mon Sep 17 00:00:00 2001 From: Julie Date: Thu, 6 Feb 2014 11:03:17 -0800 Subject: [PATCH 009/123] refactor(doc): separate end to end tests into jquery and jqlite files --- docs/src/gen-docs.js | 5 ++++- docs/src/ngdoc.js | 21 +++++---------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/docs/src/gen-docs.js b/docs/src/gen-docs.js index 9fc5f8db4c90..ff8d8311868a 100755 --- a/docs/src/gen-docs.js +++ b/docs/src/gen-docs.js @@ -57,7 +57,10 @@ writer.makeDir('build/docs/', true).then(function() { fileFutures.push(writer.output('partials/' + doc.section + '/' + id + '.html', doc.html())); // If it has a sample Protractor test, output that as well. if (doc.protractorTests.length) { - fileFutures.push(writer.output('ptore2e/' + doc.section + '/' + id + '_test.js', ngdoc.writeProtractorTest(doc))); + fileFutures.push(writer.output('ptore2e/' + doc.section + '/' + id + '.jquery_test.js', + ngdoc.writeProtractorTest(doc, 'index-jq-nocache.html#!/'))); + fileFutures.push(writer.output('ptore2e/' + doc.section + '/' + id + '.jqlite_test.js', + ngdoc.writeProtractorTest(doc, 'index-nocache.html#!/'))); } }); diff --git a/docs/src/ngdoc.js b/docs/src/ngdoc.js index 1e8896d06459..78f968d99793 100644 --- a/docs/src/ngdoc.js +++ b/docs/src/ngdoc.js @@ -1110,28 +1110,17 @@ function scenarios(docs){ } } -function writeProtractorTest(doc){ +function writeProtractorTest(doc, pathPrefix){ var lines = []; lines.push('describe("' + doc.section + '/' + doc.id + '", function() {'); - lines.push(' describe("angular+jqLite", function() {') - lines.push(' beforeEach(function() {'); - lines.push(' browser.get("index-nocache.html#!/' + doc.section + '/' + doc.id + '");'); - lines.push(' });'); - lines.push(''); - doc.protractorTests.forEach(function(test){ - lines.push(indentCode(trim(test), 4)); - lines.push(''); - }); + lines.push(' beforeEach(function() {'); + lines.push(' browser.get("' + pathPrefix + doc.section + '/' + doc.id + '");'); lines.push(' });'); - lines.push(' describe("angular+jQuery", function() {') - lines.push(' beforeEach(function() {'); - lines.push(' browser.get("index-jq-nocache.html#!/' + doc.section + '/' + doc.id + '");'); - lines.push(' });'); + lines.push(''); doc.protractorTests.forEach(function(test){ - lines.push(indentCode(trim(test), 4)); + lines.push(indentCode(trim(test), 0)); lines.push(''); }); - lines.push(' });'); lines.push('});'); lines.push(''); return lines.join('\n'); From 6232b288a9f9455b30668ca74821faa4f523592b Mon Sep 17 00:00:00 2001 From: Julie Date: Thu, 6 Feb 2014 11:29:24 -0800 Subject: [PATCH 010/123] refactor(testing): split travis end to end tests into separate jobs for jquery and jqlite Closes #6159 --- .travis.yml | 9 ++++++--- Gruntfile.js | 2 ++ protractor-conf.js | 5 +++-- protractor-jquery-conf.js | 32 ++++++++++++++++++++++++++++++++ scripts/travis/build.sh | 9 ++++++--- 5 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 protractor-jquery-conf.js diff --git a/.travis.yml b/.travis.yml index 6a24af3fd41b..b94d3b58f2a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,12 @@ node_js: env: matrix: - JOB=unit - - JOB=e2e-chrome - - JOB=e2e-firefox - - JOB=e2e-safari + - JOB=e2e BROWSER=chrome JQVERSION=jqlite + - JOB=e2e BROWSER=firefox JQVERSION=jqlite + - JOB=e2e BROWSER=safari JQVERSION=jqlite + - JOB=e2e BROWSER=chrome JQVERSION=jquery + - JOB=e2e BROWSER=firefox JQVERSION=jquery + - JOB=e2e BROWSER=safari JQVERSION=jquery global: - SAUCE_USERNAME=angular-ci - SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987 diff --git a/Gruntfile.js b/Gruntfile.js index 123a0d72a574..89e461d61190 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -92,6 +92,7 @@ module.exports = function(grunt) { protractor: { normal: 'protractor-conf.js', + jquery: 'protractor-jquery-conf.js', jenkins: 'protractor-jenkins-conf.js' }, @@ -292,6 +293,7 @@ module.exports = function(grunt) { grunt.registerTask('test:docs', 'Run the doc-page tests with Karma', ['package', 'tests:docs']); grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['tests:jqlite', 'tests:jquery', 'tests:modules']); grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'protractor:normal']); + grunt.registerTask('test:jq-protractor', 'Run the end to end tests against jquery with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'protractor:jquery']); grunt.registerTask('test:ci-protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'protractor:jenkins']); grunt.registerTask('test:e2e', 'Alias for test:protractor', ['test:protractor']); grunt.registerTask('test:docgen', ['jasmine_node']); diff --git a/protractor-conf.js b/protractor-conf.js index 9e7179db0521..c21ee68f36eb 100644 --- a/protractor-conf.js +++ b/protractor-conf.js @@ -2,12 +2,13 @@ exports.config = { allScriptsTimeout: 11000, specs: [ - 'build/docs/ptore2e/**/*.js', + 'build/docs/ptore2e/**/*jqlite_test.js', 'test/e2e/docsAppE2E.js' ], capabilities: { - 'browserName': 'chrome' + 'browserName': 'chrome', + 'name': 'Angular E2E: jqlite' }, baseUrl: 'http://localhost:8000/build/docs/', diff --git a/protractor-jquery-conf.js b/protractor-jquery-conf.js new file mode 100644 index 000000000000..6b93994b7206 --- /dev/null +++ b/protractor-jquery-conf.js @@ -0,0 +1,32 @@ +exports.config = { + allScriptsTimeout: 11000, + + specs: [ + 'build/docs/ptore2e/**/*jquery_test.js', + 'test/e2e/docsAppE2E.js' + ], + + capabilities: { + 'browserName': 'chrome', + 'name': 'Angular E2E: jquery' + }, + + baseUrl: 'http://localhost:8000/build/docs/', + + framework: 'jasmine', + + onPrepare: function() { + // Disable animations so e2e tests run more quickly + var disableNgAnimate = function() { + angular.module('disableNgAnimate', []).run(function($animate) { + $animate.enabled(false); + }); + }; + + browser.addMockModule('disableNgAnimate', disableNgAnimate); + }, + + jasmineNodeOpts: { + defaultTimeoutInterval: 30000 + } +}; diff --git a/scripts/travis/build.sh b/scripts/travis/build.sh index b07e2069e8c5..a415c35e48b4 100755 --- a/scripts/travis/build.sh +++ b/scripts/travis/build.sh @@ -3,15 +3,18 @@ set -e export SAUCE_ACCESS_KEY=`echo $SAUCE_ACCESS_KEY | rev` -export BROWSER=${JOB#*-} if [ $JOB = "unit" ]; then grunt ci-checks grunt test:docgen grunt test:promises-aplus grunt test:unit --browsers SL_Chrome,SL_Safari,SL_Firefox,SL_IE_8,SL_IE_9,SL_IE_10,SL_IE_11 --reporters dots -elif [[ $JOB == e2e* ]]; then - grunt test:protractor --sauceUser $SAUCE_USERNAME \ +elif [ $JOB = "e2e" ]; then + export GRUNT_TARGET="test:protractor" + if [ $JQVERSION = "jquery" ]; then + GRUNT_TARGET="test:jq-protractor" + fi + grunt $GRUNT_TARGET --sauceUser $SAUCE_USERNAME \ --sauceKey $SAUCE_ACCESS_KEY \ --capabilities.tunnel-identifier=$TRAVIS_JOB_NUMBER \ --capabilities.build=$TRAVIS_BUILD_NUMBER \ From 51ed28534d239575278b1de7e27ab19a4ca91c0a Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Mon, 10 Feb 2014 15:16:46 +0100 Subject: [PATCH 011/123] docs(guide/scope): fix a typo Signed-off-by: Caitlin Potter Closes #6202 --- docs/content/guide/scope.ngdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/guide/scope.ngdoc b/docs/content/guide/scope.ngdoc index 4e3953289076..3d932fd96aa8 100644 --- a/docs/content/guide/scope.ngdoc +++ b/docs/content/guide/scope.ngdoc @@ -333,7 +333,7 @@ information. Dirty checking the scope for property changes is a common operation in Angular and for this reason the dirty checking function must be efficient. Care should be taken that the dirty checking -function does not do any DOM access, as DOM access is orders of magnitude slower then property +function does not do any DOM access, as DOM access is orders of magnitude slower than property access on JavaScript object. ## Integration with the browser event loop From adff083e73c5ac95a568783e01a00002240cef58 Mon Sep 17 00:00:00 2001 From: Sequoia McDowell Date: Mon, 10 Feb 2014 15:57:27 -0500 Subject: [PATCH 012/123] docs(concepts): Remove pointless `* 1`s Closes #6206 --- docs/content/guide/concepts.ngdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/guide/concepts.ngdoc b/docs/content/guide/concepts.ngdoc index 9581514df7f3..4c8708045b39 100644 --- a/docs/content/guide/concepts.ngdoc +++ b/docs/content/guide/concepts.ngdoc @@ -120,7 +120,7 @@ different currencies and also pay the invoice. return this.convertCurrency(this.qty * this.cost, this.inCurr, outCurr); }; this.convertCurrency = function convertCurrency(amount, inCurr, outCurr) { - return amount * this.usdToForeignRates[outCurr] * 1 / this.usdToForeignRates[inCurr]; + return amount * this.usdToForeignRates[outCurr] / this.usdToForeignRates[inCurr]; }; this.pay = function pay() { window.alert("Thanks!"); @@ -207,7 +207,7 @@ Let's refactor our example and move the currency conversion into a service in an }; function convert(amount, inCurr, outCurr) { - return amount * usdToForeignRates[outCurr] * 1 / usdToForeignRates[inCurr]; + return amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr]; } }); @@ -336,7 +336,7 @@ The following example shows how this is done with Angular: }; function convert(amount, inCurr, outCurr) { - return amount * usdToForeignRates[outCurr] * 1 / usdToForeignRates[inCurr]; + return amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr]; } function refresh() { From ea11fb230c5314118ef278bfdf0505715ccd1889 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Tue, 28 Jan 2014 11:34:01 -0500 Subject: [PATCH 013/123] fix($compile): ensure element transclusion directives are linked with comment element This corrects a complicated compiler issue, described in detail below: Previously, if an element transclusion directive contained an asynchronous directive whose template contained another element transclusion directive, the inner element transclusion directive would be linked with the element, rather than the expected comment node. An example manifestation of this bug would look like so: ```html
``` `my-directive` would be a replace directive, and its template would contain another element transclusion directive, like so: ```html
{{i}}
``` ngIf would be linked with this template content, rather than the comment node, and the template element would be attached to the DOM, rather than the comment. As a result, this caused ng-if to duplicate the template when its expression evaluated to true. Closes #6006 Closes #6101 --- src/ng/compile.js | 12 +++++++--- test/ng/compileSpec.js | 51 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index 63523c04dac6..de65c83e2c2c 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1142,7 +1142,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { templateDirective = previousCompileContext.templateDirective, nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective, hasTranscludeDirective = false, - hasElementTranscludeDirective = false, + hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective, $compileNode = templateAttrs.$$element = jqLite(compileNode), directive, directiveName, @@ -1316,6 +1316,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true; nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn; + previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective; // might be normal or delayed nodeLinkFn depending on if templateUrl is present return nodeLinkFn; @@ -1712,8 +1713,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (beforeTemplateLinkNode !== beforeTemplateCompileNode) { var oldClasses = beforeTemplateLinkNode.className; - // it was cloned therefore we have to clone as well. - linkNode = jqLiteClone(compileNode); + + if (!(previousCompileContext.hasElementTranscludeDirective && + origAsyncDirective.replace)) { + // it was cloned therefore we have to clone as well. + linkNode = jqLiteClone(compileNode); + } + replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode); // Copy in CSS classes from original node diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 085eb6e9d552..60b1024bf97f 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -3972,6 +3972,57 @@ describe('$compile', function() { }); }); + // issue #6006 + it('should link directive with $element as a comment node', function() { + module(function($provide) { + directive('innerAgain', function(log) { + return { + transclude: 'element', + link: function(scope, element, attr, controllers, transclude) { + log('innerAgain:'+lowercase(nodeName_(element))+':'+trim(element[0].data)); + transclude(scope, function(clone) { + element.parent().append(clone); + }); + } + }; + }); + directive('inner', function(log) { + return { + replace: true, + templateUrl: 'inner.html', + link: function(scope, element) { + log('inner:'+lowercase(nodeName_(element))+':'+trim(element[0].data)); + } + }; + }); + directive('outer', function(log) { + return { + transclude: 'element', + link: function(scope, element, attrs, controllers, transclude) { + log('outer:'+lowercase(nodeName_(element))+':'+trim(element[0].data)); + transclude(scope, function(clone) { + element.parent().append(clone); + }); + } + }; + }); + }); + inject(function(log, $compile, $rootScope, $templateCache) { + $templateCache.put('inner.html', '

Content

'); + element = $compile('
')($rootScope); + $rootScope.$digest(); + var child = element.children(); + + expect(log.toArray()).toEqual([ + "outer:#comment:outer:", + "innerAgain:#comment:innerAgain:", + "inner:#comment:innerAgain:"]); + expect(child.length).toBe(1); + expect(child.contents().length).toBe(2); + expect(lowercase(nodeName_(child.contents().eq(0)))).toBe('#comment'); + expect(lowercase(nodeName_(child.contents().eq(1)))).toBe('div'); + }); + }); }); it('should safely create transclude comment node and not break with "-->"', From b61412fb23fa450f336f1eadb54b692386f2da3e Mon Sep 17 00:00:00 2001 From: Mark Miyashita Date: Mon, 10 Feb 2014 02:00:54 -0800 Subject: [PATCH 014/123] docs(faq): add link to MIT license Closes #6197 --- docs/content/misc/faq.ngdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/misc/faq.ngdoc b/docs/content/misc/faq.ngdoc index bfa2616c500a..535464f6aaa5 100644 --- a/docs/content/misc/faq.ngdoc +++ b/docs/content/misc/faq.ngdoc @@ -100,7 +100,7 @@ Watch the July 17, 2012 talk ### How is Angular licensed? -The MIT License. +The {@link https://github.com/angular/angular.js/blob/master/LICENSE MIT License}. ### Can I download and use the Angular logo artwork? From 0c9130bf39f7d98f1145cb5f07841e7aed770b40 Mon Sep 17 00:00:00 2001 From: Sequoia McDowell Date: Mon, 10 Feb 2014 16:01:29 -0500 Subject: [PATCH 015/123] docs(guide/concepts): removing confusing use of hoisting Closes #6207 --- docs/content/guide/concepts.ngdoc | 36 ++++++++++++++++--------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/docs/content/guide/concepts.ngdoc b/docs/content/guide/concepts.ngdoc index 4c8708045b39..d964da7e0bde 100644 --- a/docs/content/guide/concepts.ngdoc +++ b/docs/content/guide/concepts.ngdoc @@ -195,20 +195,20 @@ Let's refactor our example and move the currency conversion into a service in an angular.module('finance2', []) .factory('currencyConverter', function() { - var currencies = ['USD', 'EUR', 'CNY'], - usdToForeignRates = { + var currencies = ['USD', 'EUR', 'CNY']; + var usdToForeignRates = { USD: 1, EUR: 0.74, CNY: 6.09 }; + var convert = function (amount, inCurr, outCurr) { + return amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr]; + } + return { currencies: currencies, convert: convert }; - - function convert(amount, inCurr, outCurr) { - return amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr]; - } }); @@ -325,21 +325,15 @@ The following example shows how this is done with Angular: var YAHOO_FINANCE_URL_PATTERN = 'http://query.yahooapis.com/v1/public/yql?q=select * from '+ 'yahoo.finance.xchange where pair in ("PAIRS")&format=json&'+ - 'env=store://datatables.org/alltableswithkeys&callback=JSON_CALLBACK', - currencies = ['USD', 'EUR', 'CNY'], - usdToForeignRates = {}; - refresh(); - return { - currencies: currencies, - convert: convert, - refresh: refresh - }; + 'env=store://datatables.org/alltableswithkeys&callback=JSON_CALLBACK'; + var currencies = ['USD', 'EUR', 'CNY']; + var usdToForeignRates = {}; - function convert(amount, inCurr, outCurr) { + var convert = function (amount, inCurr, outCurr) { return amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr]; } - function refresh() { + var refresh = function() { var url = YAHOO_FINANCE_URL_PATTERN. replace('PAIRS', 'USD' + currencies.join('","USD')); return $http.jsonp(url).success(function(data) { @@ -351,6 +345,14 @@ The following example shows how this is done with Angular: usdToForeignRates = newUsdToForeignRates; }); } + + refresh(); + + return { + currencies: currencies, + convert: convert, + refresh: refresh + }; }]); From 9d9ff8f200b1c7cd3396641959ad64c65cce7426 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Mon, 10 Feb 2014 16:18:47 -0800 Subject: [PATCH 016/123] style(guide/concepts): remove ws --- docs/content/guide/concepts.ngdoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/content/guide/concepts.ngdoc b/docs/content/guide/concepts.ngdoc index d964da7e0bde..7154da39b299 100644 --- a/docs/content/guide/concepts.ngdoc +++ b/docs/content/guide/concepts.ngdoc @@ -54,18 +54,18 @@ Try out the Live Preview above, and then let's walk through the example and desc This looks like normal HTML, with some new markup. In Angular, a file like this is called a -"{@link templates template}". When Angular starts your application, it parses and +"{@link templates template}". When Angular starts your application, it parses and processes this new markup from the template using the so called "{@link compiler compiler}". The loaded, transformed and rendered DOM is then called the "view". The first kind of new markup are the so called "{@link directive directives}". -They apply special behavior to attributes or elements in the HTML. In the example above we use the +They apply special behavior to attributes or elements in the HTML. In the example above we use the {@link api/ng.directive:ngApp `ng-app`} attribute, which is linked to a directive that automatically initializes our application. Angular also defines a directive for the {@link api/ng.directive:input `input`} -element that adds extra behavior to the element. E.g. it is able to automatically validate that the entered -text is non empty by evaluating the `required` attribute. +element that adds extra behavior to the element. E.g. it is able to automatically validate that the entered +text is non empty by evaluating the `required` attribute. The {@link api/ng.directive:ngModel `ng-model`} directive stores/updates -the value of the input field into/from a variable and shows the validation state of the input field by +the value of the input field into/from a variable and shows the validation state of the input field by adding css classes. In the example we use these css classes to mark an empty input field with a red border.
From d63fb178ef1e952f4668bec26f69a4c54f98b50c Mon Sep 17 00:00:00 2001 From: James Wagoner Date: Mon, 10 Feb 2014 00:17:08 -0800 Subject: [PATCH 017/123] docs(ngSubmit): ngSubmit also works with the `data-action`/`x-action` attributes The documentation states only the "action" attribute triggers this, which is incorrect. When using the attribute "data-action" (as for AJAX control, attempting to bypass the "action" attribute but still make it obvious what its for), Angular thinks this is also classified as "action" and continues with the page submission. Closes #6196 --- src/ng/directive/ngEventDirs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ng/directive/ngEventDirs.js b/src/ng/directive/ngEventDirs.js index f63d3ca1e7bf..45b2d4048a9d 100644 --- a/src/ng/directive/ngEventDirs.js +++ b/src/ng/directive/ngEventDirs.js @@ -298,8 +298,8 @@ forEach( * Enables binding angular expressions to onsubmit events. * * Additionally it prevents the default action (which for form means sending the request to the - * server and reloading the current page) **but only if the form does not contain an `action` - * attribute**. + * server and reloading the current page), but only if the form does not contain `action`, + * `data-action`, or `x-action` attributes. * * @element form * @priority 0 From 333b57c774c8b46899a0ccafda8da8d4ac486536 Mon Sep 17 00:00:00 2001 From: Jeremy Likness Date: Sun, 9 Feb 2014 10:16:16 -0500 Subject: [PATCH 018/123] docs(guide): add new resource links Added a link to 10 reasons to use and online courses for Angular Closes #6194 --- docs/content/guide/index.ngdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/content/guide/index.ngdoc b/docs/content/guide/index.ngdoc index 3fcf1c8ea210..486713b50abb 100644 --- a/docs/content/guide/index.ngdoc +++ b/docs/content/guide/index.ngdoc @@ -13,6 +13,7 @@ Everything you need to know about AngularJS * {@link tutorial/index Official AngularJS Tutorial} * [10 Reasons Why You Should Use AngularJS](http://www.sitepoint.com/10-reasons-use-angularjs/) +* [10 Reasons Why Developers Shold Learn AngularJS](http://wintellect.com/blogs/jlikness/10-reasons-web-developers-should-learn-angularjs) * [Design Principles of AngularJS (video)](https://www.youtube.com/watch?v=HCR7i5F5L8c) * [Fundamentals in 60 Minutes (video)](http://www.youtube.com/watch?v=i9MHigUZKEM) * [For folks with jQuery background](http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background) @@ -113,6 +114,7 @@ This is a short list of libraries with specific support and documentation for wo [Pluralsite (3 courses)](http://www.pluralsight.com/training/Courses/Find?highlight=true&searchTerm=angularjs), [Tuts+](https://tutsplus.com/course/easier-js-apps-with-angular/), [lynda.com](http://www.lynda.com/AngularJS-tutorials/Up-Running-AngularJS/133318-2.html) + [WintellectNOW (4 lessons)](http://www.wintellectnow.com/Course/Detail/mastering-angularjs) * **Paid onsite:** [angularbootcamp.com](http://angularbootcamp.com/) From 1f30d0174a2e3f6b5bbec6e853373dda7fed070d Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Mon, 10 Feb 2014 17:07:43 -0800 Subject: [PATCH 019/123] style(guide): remove ws --- docs/content/guide/index.ngdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/guide/index.ngdoc b/docs/content/guide/index.ngdoc index 486713b50abb..56829d6127bd 100644 --- a/docs/content/guide/index.ngdoc +++ b/docs/content/guide/index.ngdoc @@ -88,7 +88,7 @@ This is a short list of libraries with specific support and documentation for wo * **FireBase:** [AngularFire](http://angularfire.com/), [Realtime Apps with AngularJS and FireBase (video)](http://www.youtube.com/watch?v=C7ZI7z7qnHU) * **Google Cloud Platform: **[with Cloud Endpoints](https://cloud.google.com/resources/articles/angularjs-cloud-endpoints-recipe-for-building-modern-web-applications), [with Go](https://github.com/GoogleCloudPlatform/appengine-angular-gotodos) * **Hood.ie:** [60 Minutes to Awesome](http://www.roberthorvick.com/2013/06/30/todomvc-angularjs-hood-ie-60-minutes-to-awesome/) -* **MEAN Stack: **[Blog post](http://blog.mongodb.org/post/49262866911/the-mean-stack-mongodb-expressjs-angularjs-and), [Setup](http://thecodebarbarian.wordpress.com/2013/07/22/introduction-to-the-mean-stack-part-one-setting-up-your-tools/), [GDL Video](https://developers.google.com/live/shows/913996610) +* **MEAN Stack: **[Blog post](http://blog.mongodb.org/post/49262866911/the-mean-stack-mongodb-expressjs-angularjs-and), [Setup](http://thecodebarbarian.wordpress.com/2013/07/22/introduction-to-the-mean-stack-part-one-setting-up-your-tools/), [GDL Video](https://developers.google.com/live/shows/913996610) * **Rails: **[Tutorial](http://coderberry.me/blog/2013/04/22/angularjs-on-rails-4-part-1/), [AngularJS with Rails4](https://shellycloud.com/blog/2013/10/how-to-integrate-angularjs-with-rails-4), [angularjs-rails](https://github.com/hiravgandhi/angularjs-rails) * **PHP: **[Building a RESTful web service](http://blog.brunoscopelliti.com/building-a-restful-web-service-with-angularjs-and-php-more-power-with-resource), [End to End with Laravel 4 (video)](http://www.youtube.com/watch?v=hqAyiqUs93c) From f1ec06e1ce6f3a11c43a4e4317d184b95368bda9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Reynaud?= Date: Tue, 11 Feb 2014 17:36:50 +0100 Subject: [PATCH 020/123] docs(guide/index): replace "shold" to "should" Replace "shold" to "should" Closes #6216 --- docs/content/guide/index.ngdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/guide/index.ngdoc b/docs/content/guide/index.ngdoc index 56829d6127bd..a851e5b65b2e 100644 --- a/docs/content/guide/index.ngdoc +++ b/docs/content/guide/index.ngdoc @@ -13,7 +13,7 @@ Everything you need to know about AngularJS * {@link tutorial/index Official AngularJS Tutorial} * [10 Reasons Why You Should Use AngularJS](http://www.sitepoint.com/10-reasons-use-angularjs/) -* [10 Reasons Why Developers Shold Learn AngularJS](http://wintellect.com/blogs/jlikness/10-reasons-web-developers-should-learn-angularjs) +* [10 Reasons Why Developers Should Learn AngularJS](http://wintellect.com/blogs/jlikness/10-reasons-web-developers-should-learn-angularjs) * [Design Principles of AngularJS (video)](https://www.youtube.com/watch?v=HCR7i5F5L8c) * [Fundamentals in 60 Minutes (video)](http://www.youtube.com/watch?v=i9MHigUZKEM) * [For folks with jQuery background](http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background) From b58a439d5382baa6a6271a1a8b5d3185830cb45d Mon Sep 17 00:00:00 2001 From: Daniel Tabuenca Date: Fri, 13 Dec 2013 15:20:31 -0800 Subject: [PATCH 021/123] refactor(ngTransclude): use transclusion function passed in to link Since we now pass in the transclusion function directly to the link function, we no longer need the old scheme whereby we saved the transclude function injected into the controller for later use in during linking. Additionally, this change may aid in correcting a memory leak of detached DOM nodes (see #6181 for details). This commit removes the controller and simplifies ngTransclude. Closes #5375 Closes #6181 --- src/ng/directive/ngTransclude.js | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/ng/directive/ngTransclude.js b/src/ng/directive/ngTransclude.js index 295e47a9922c..86b5ff6100b4 100644 --- a/src/ng/directive/ngTransclude.js +++ b/src/ng/directive/ngTransclude.js @@ -56,23 +56,16 @@ * */ var ngTranscludeDirective = ngDirective({ - controller: ['$element', '$transclude', function($element, $transclude) { + link: function($scope, $element, $attrs, controller, $transclude) { if (!$transclude) { throw minErr('ngTransclude')('orphan', - 'Illegal use of ngTransclude directive in the template! ' + - 'No parent directive that requires a transclusion found. ' + - 'Element: {0}', - startingTag($element)); + 'Illegal use of ngTransclude directive in the template! ' + + 'No parent directive that requires a transclusion found. ' + + 'Element: {0}', + startingTag($element)); } - - // remember the transclusion fn but call it during linking so that we don't process transclusion before directives on - // the parent element even when the transclusion replaces the current element. (we can't use priority here because - // that applies only to compile fns and not controllers - this.$transclude = $transclude; - }], - - link: function($scope, $element, $attrs, controller) { - controller.$transclude(function(clone) { + + $transclude(function(clone) { $element.empty(); $element.append(clone); }); From 896250484904732889ee590e95eb092becec9bdc Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Tue, 11 Feb 2014 09:57:04 -0500 Subject: [PATCH 022/123] feat(filterFilter): support deeply nested predicate objects Due to 339a165, it became impossible to filter nested properties of an object using the filterFilter. A proposed solution to this was to enable the use of nested predicate objects. This change enables the use of these nested predicate objects. Example: ```html
``` Or ```js $filter('filter')(items, { address: { country: 'Canuckistan' } }); ``` Closes #6215 Related to #6009 --- src/Angular.js | 3 ++- src/ng/filter/filter.js | 9 +++++++++ test/ng/filter/filterSpec.js | 11 +++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Angular.js b/src/Angular.js index f4054037110b..405e8ae561ab 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -81,6 +81,7 @@ -assertNotHasOwnProperty, -getter, -getBlockElements, + -hasOwnProperty, */ @@ -96,7 +97,7 @@ * @returns {string} Lowercased string. */ var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;}; - +var hasOwnProperty = Object.prototype.hasOwnProperty; /** * @ngdoc function diff --git a/src/ng/filter/filter.js b/src/ng/filter/filter.js index eabe84a7e0b0..2bb0d1743949 100644 --- a/src/ng/filter/filter.js +++ b/src/ng/filter/filter.js @@ -136,6 +136,15 @@ function filterFilter() { }; } else { comparator = function(obj, text) { + if (obj && text && typeof obj === 'object' && typeof text === 'object') { + for (var objKey in obj) { + if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) && + comparator(obj[objKey], text[objKey])) { + return true; + } + } + return false; + } text = (''+text).toLowerCase(); return (''+obj).toLowerCase().indexOf(text) > -1; }; diff --git a/test/ng/filter/filterSpec.js b/test/ng/filter/filterSpec.js index 0bb487042ba3..7679136ac9f9 100644 --- a/test/ng/filter/filterSpec.js +++ b/test/ng/filter/filterSpec.js @@ -70,6 +70,17 @@ describe('Filter: filter', function() { }); + it('should support deep predicate objects', function() { + var items = [{person: {name: 'John'}}, + {person: {name: 'Rita'}}, + {person: {name: 'Billy'}}, + {person: {name: 'Joan'}}]; + expect(filter(items, {person: {name: 'Jo'}}).length).toBe(2); + expect(filter(items, {person: {name: 'Jo'}})).toEqual([ + {person: {name: 'John'}}, {person: {name: 'Joan'}}]); + }); + + it('should match any properties for given "$" property', function() { var items = [{first: 'tom', last: 'hevery'}, {first: 'adam', last: 'hevery', alias: 'tom', done: false}, From 44b62ff0babdc797fdb09ce29152c0090b94ebea Mon Sep 17 00:00:00 2001 From: Evgeniy Tkachenko Date: Fri, 7 Feb 2014 13:40:54 +0300 Subject: [PATCH 023/123] docs(jqLite): link to jQuery.fn.bind/unbind docs rather than jQuery.fn.on/off docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Сorrect link. Closes #6171 --- src/jqLite.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jqLite.js b/src/jqLite.js index f48dd3c03fad..6749b26e7141 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -40,7 +40,7 @@ * - [`after()`](http://api.jquery.com/after/) * - [`append()`](http://api.jquery.com/append/) * - [`attr()`](http://api.jquery.com/attr/) - * - [`bind()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData + * - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData * - [`children()`](http://api.jquery.com/children/) - Does not support selectors * - [`clone()`](http://api.jquery.com/clone/) * - [`contents()`](http://api.jquery.com/contents/) @@ -67,7 +67,7 @@ * - [`text()`](http://api.jquery.com/text/) * - [`toggleClass()`](http://api.jquery.com/toggleClass/) * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers. - * - [`unbind()`](http://api.jquery.com/off/) - Does not support namespaces + * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces * - [`val()`](http://api.jquery.com/val/) * - [`wrap()`](http://api.jquery.com/wrap/) * From d5264f538bc1280deb241b5bbf04ef54cc691d2b Mon Sep 17 00:00:00 2001 From: Jesse Palmer Date: Thu, 30 Jan 2014 22:10:08 -0500 Subject: [PATCH 024/123] docs(core): add closing tag to ngApp directive example added missing closing tag to ngApp example. Closes #6066 --- src/Angular.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Angular.js b/src/Angular.js index 405e8ae561ab..dec397cf485b 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -1135,6 +1135,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
I can add: {{a}} + {{b}} = {{ a+b }} +
angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) { From 1f4224f6b59f8b93957c942d154222c1966a2604 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Thu, 6 Feb 2014 17:06:03 -0500 Subject: [PATCH 025/123] chore(dependencies): upgrade kriskowal/q to version ~1.0.0 CI builds on travis occasionally freak out because of the recursive use of process.nextTick, which has been deprecated in Node relatively recently, to be replaced with setImmediate. Unfortunately, this change does not resolve the issue. However, it does not hurt, either. Closes #6161 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bd9afbf556aa..06ec83634851 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "load-grunt-tasks": "~0.3.0", "bower": "~1.2.2", "jasmine-node": "~1.11.0", - "q": "~0.9.2", + "q": "~1.0.0", "q-io": "~1.10.6", "qq": "~0.3.5", "shelljs": "~0.2.6", From d678a1c732e7cb4cbafad5b59b4fbb6d1b13edf8 Mon Sep 17 00:00:00 2001 From: Jason Schapiro Date: Tue, 11 Feb 2014 00:09:30 -0500 Subject: [PATCH 026/123] docs(tutorial): inject phonecapApp module into unit test When I was reading this doc I was thinking "but what about phonecatApp?" and when I looked in the file from the step-11 branch there it is. Should be reflected in the docs as well Closes #6209 --- docs/content/tutorial/step_11.ngdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/tutorial/step_11.ngdoc b/docs/content/tutorial/step_11.ngdoc index 37b85ba2f57f..4b82367daebf 100644 --- a/docs/content/tutorial/step_11.ngdoc +++ b/docs/content/tutorial/step_11.ngdoc @@ -148,7 +148,7 @@ describe('PhoneCat controllers', function() { }); }); - + beforeEach(module('phonecatApp')); beforeEach(module('phonecatServices')); From 78c21afa6a794e9c493c5de6549245ef2cf250bf Mon Sep 17 00:00:00 2001 From: Mathieu Tricoire Date: Wed, 12 Feb 2014 10:53:52 +0100 Subject: [PATCH 027/123] docs(input): document NgModelController.$isEmpty parameters / return value Closes #6224 --- src/ng/directive/input.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 27813a4686c0..3c09c0848f92 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -1022,6 +1022,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * You can override this for input directives whose concept of being empty is different to the * default. The `checkboxInputType` directive does this because in its case a value of `false` * implies empty. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is empty. */ this.$isEmpty = function(value) { return isUndefined(value) || value === '' || value === null || value !== value; From b126978d54cc2fc77970fac1e427fa2f6d07c57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Reynaud?= Date: Wed, 12 Feb 2014 11:14:25 +0100 Subject: [PATCH 028/123] docs(guide/$location): correct link to HTML5 draft section 5.5 (history api) Previous link url is no longer served, responds with bad link (error 404). This change corrects the URL to point to section 5.5 of the draft. The old URL appears to have been removed from service in 2012. Corrects the link to "History API" Closes #6225 --- docs/content/guide/dev_guide.services.$location.ngdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/guide/dev_guide.services.$location.ngdoc b/docs/content/guide/dev_guide.services.$location.ngdoc index bfd1d5d90999..08fabe33e9e3 100644 --- a/docs/content/guide/dev_guide.services.$location.ngdoc +++ b/docs/content/guide/dev_guide.services.$location.ngdoc @@ -160,7 +160,7 @@ encoded. `$location` service has two configuration modes which control the format of the URL in the browser address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the -HTML5 {@link http://www.w3.org/TR/html5/history.html History API}. Applications use the same API in +HTML5 {@link http://www.w3.org/TR/html5/browsers.html#history History API}. Applications use the same API in both modes and the `$location` service will work with appropriate URL segments and browser APIs to facilitate the browser URL change and history management. From 08cf30ce9712f736c5fe8f3f4adaeecec0a965bc Mon Sep 17 00:00:00 2001 From: James Kyle Date: Wed, 12 Feb 2014 09:39:51 -0500 Subject: [PATCH 029/123] docs(currencyFilter): added missing line break in currency doc ptor test Closes #6229 --- src/ng/filter/filters.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index f655c7a6d8b8..15cc6e33b270 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -40,7 +40,8 @@ return; } element(by.model('amount')).clear(); - element(by.model('amount')).sendKeys('-1234'); expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)'); + element(by.model('amount')).sendKeys('-1234'); + expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)'); expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('(USD$1,234.00)'); }); From d435a513ffb1ab7e729d5da5f4f6908725f58515 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Tue, 14 Jan 2014 13:41:50 -0500 Subject: [PATCH 030/123] docs($location): fix link to $rootScope.Scope.$on Previously missing the methods_ prefix. Closes #5798 --- src/ng/location.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ng/location.js b/src/ng/location.js index 20df6a3d8ec2..e89c026b1d3f 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -595,7 +595,7 @@ function $LocationProvider(){ * @eventType broadcast on root scope * @description * Broadcasted before a URL will change. This change can be prevented by calling - * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more + * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#methods_$on} for more * details about event object. Upon successful change * {@link ng.$location#events_$locationChangeSuccess $locationChangeSuccess} is fired. * From 4f09a517e7fa062b4b49f4394b412f7b4c71d24a Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Tue, 14 Jan 2014 14:40:32 -0500 Subject: [PATCH 031/123] docs($interpolate): fix link to $interpolateProvider#endSymbol The markup here was missing the methods_ prefix and behaved incorrectly. Closes #5802 --- src/ng/interpolate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ng/interpolate.js b/src/ng/interpolate.js index 1a7e50ad4f6d..1c02c40fb4a4 100644 --- a/src/ng/interpolate.js +++ b/src/ng/interpolate.js @@ -227,7 +227,7 @@ function $InterpolateProvider() { * @description * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`. * - * Use {@link ng.$interpolateProvider#endSymbol $interpolateProvider#endSymbol} to change + * Use {@link ng.$interpolateProvider#methods_endSymbol $interpolateProvider#endSymbol} to change * the symbol. * * @returns {string} start symbol. From be20e58ec438c8916b287249c0fd35450d76c019 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Mon, 16 Dec 2013 13:06:16 -0500 Subject: [PATCH 032/123] fix(input): setViewValue on compositionend Because of a4e6d962, model is not updated on input/change between the compositionstart and compositionend events. Unfortunately, the compositionend event does not always happen prior to an input/change event. This changeset calls the listener function to update the model after a compositionend event is received. Closes #6058 Closes #5433 --- src/ng/directive/input.js | 1 + test/ng/directive/inputSpec.js | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 3c09c0848f92..09e07d365e79 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -447,6 +447,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { element.on('compositionend', function() { composing = false; + listener(); }); } diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 668fa0b54a1e..b9f737ac0593 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -509,6 +509,17 @@ describe('input', function() { }); } + it('should update the model on "compositionend"', function() { + compileInput(''); + if (!(msie < 9)) { + browserTrigger(inputElm, 'compositionstart'); + changeInputValueTo('caitp'); + expect(scope.name).toBeUndefined(); + browserTrigger(inputElm, 'compositionend'); + expect(scope.name).toEqual('caitp'); + } + }); + describe('"change" event', function() { function assertBrowserSupportsChangeEvent(inputEventSupported) { // Force browser to report a lack of an 'input' event From f1ac7db599971ad09c032200b1f3429327669545 Mon Sep 17 00:00:00 2001 From: Brian Hall Date: Thu, 13 Feb 2014 09:21:29 -0800 Subject: [PATCH 033/123] docs(logo): change logo to vector format in .eps file Browser: Other Component: docs Regression: no Closes issue #6092 --- images/logo/AngularJS.exports/AngularJS.eps | Bin 63723 -> 555546 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/images/logo/AngularJS.exports/AngularJS.eps b/images/logo/AngularJS.exports/AngularJS.eps index 6911ac253fb002fc12ec43264e9a44ca4e956999..f2f535fe8fc4b2807a14365ccf8be79d30be1fb7 100644 GIT binary patch literal 555546 zcmeFaTXS34u_ow<=@%$M5i?Kois^Par0Fh!ASsG;xP45K#VXmQvPRVLWi$!|1VR)n z5TF54B_4);-punv%#WGJp6~lIb6qwzNUCg~=s9s%C35d|$(5NaGgq!$m;HbK-~Z45 z)&1Gee)j+VkN*L`?dN~~pZ>$o{)fqb_}PE^Z$JClSO3e41_0_A%#dQ43?*8obaynf6 z_W05Ge2L_P#dvrzUm$}pyU(W6%jLy_Ne^B=?DlsE`l}-rc)FMjXWj3H(`i(j%x8zg z3jp2h^|yNcZKOY)U(VS2)A^@gb~o_fla0-8e{Ty}-%VbQmo54IM>{)DHc)8u(Z=pp zU%=<*1%TB8-w#2>@O1qB_~Uqr=27QxKDs;`&n|$_@R!|#>3BGM@^o?`zC0bDPG$$w z39_Hf{xTk20P$aTqsDjR;mLT>{g3<4`hBqTKLXhPv)zF+<`3h=QpL%NN89(2w>NmP zn9MFfB^wiPB!m4=FDKKJA1=?{j&I`UqwVgeoxOhdWp{Xb*4-xcJKfPm_wl36$9rr5 zkPhavi{WIp{L}Ln?8nLMXtG#du<<8@SMSlnY&Zeo{mtF()=qc#J{V6Ljd(!W?S41@ z)O~t&F<##PY6Cx8Tl~GV!{2**{C#i`sayErGjq4Ln7g%QxkpE=ZMAlGSZW79{LNB3 zJ1n)cb959i_x4z3Z;xg6@Wa}Bdn~oL$5MRaZCM2Wl2tUM#ykxoiU-7ST+IVTavYN~x z9sF&$8*bJ*F}IqQ$KUqDQlyW+3CViUsJ1-oG3Kxo>5CpVu2@~t$8^4tI_rP_Hq4pA zH%9SQzDOkN*rW{$;6vZuKpnsicmzO*2WK^`}wI-&Tec zn*5Tk;07Vz|BAIp8)@Qi<{O_38dE6|EJKPyI;_X|W^J+*dyKzXiWKp;@!BwAnaoMH zow*UXvLt_^T|QeM9US!g)Uk~X{xz%E_n*y8%gKK?^|QTg>G|)re(rzu__5{WzmN6v zwYQy19v$v{6Qy>yQDz@y9`7Ea)c$^dXLoOl|4@79$zchb zl7Lo@*cQ_Jd;5g^^s)Urc)Gv4x4m< z?WYI(fc*sUU?8lvupq1oN?$ni%a-#qfS?Tw&%1#~Oa06YQX{dWfk_tSmj+c_WdR;t| z0>g>Y1OD%^Uuan|$~zt4H0)2dTzeEV{7?cZnbc|8sM3DXrUqQ{j3r!JK!tDt1X3Z1 zsi-izy>_CK^~ssk8-U|!>W#z^=r?jUOp7?CK*PO1XtTq5LZ0?X$iD0|B@bf&^hP65 zwx+Q2Y?VLWvakmQ_7j@peFRynXsLUo=r7a;g{D8C#IPsk

Y+pCn7YvU?zTqK)Uc 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

I?7^^y?}u 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

DnbV+)&Zbw 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 literal 63723 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 From 7b510c36ab676def439febdf049a5fd5504adf34 Mon Sep 17 00:00:00 2001 From: Tim Whitbeck Date: Thu, 13 Feb 2014 13:27:42 -0500 Subject: [PATCH 034/123] fix(input): don't apply textInput to textInput shouldn't be applied to file inputs to ease writing of custom file input directives. This change prevents file inputs from instantiating the text input parser/formatter pipelines. Closes #6247 Closes #6231 --- src/ng/directive/input.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 09e07d365e79..d80697a3438c 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -424,7 +424,8 @@ var inputType = { 'hidden': noop, 'button': noop, 'submit': noop, - 'reset': noop + 'reset': noop, + 'file': noop }; // A helper function to call $setValidity and return the value / undefined, From 8100491914897544f312a8a6c4d7a531127ec7c7 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Mon, 2 Dec 2013 15:05:21 -0500 Subject: [PATCH 035/123] fix($compile) support templates with table content root nodes If the first element in a template is a , , , or tag, the HTML compiler will ensure that the template is wrapped in a element so that the table content is not discarded. Closes #2848 Closes #1459 Closes #3647 Closes #3241 --- src/ng/compile.js | 31 +++++++++++--- test/ng/compileSpec.js | 97 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 5 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index de65c83e2c2c..e4bf230ed68b 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -502,7 +502,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { var hasDirectives = {}, Suffix = 'Directive', COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/, - CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/; + CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/, + TABLE_CONTENT_REGEXP = /^<\s*(tr|th|td|tbody)(\s+[^>]*)?>/i; // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes // The assumption is that future DOM event attribute names will begin with @@ -1243,9 +1244,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (directive.replace) { replaceDirective = directive; - $template = jqLite('
' + - trim(directiveValue) + - '
').contents(); + $template = directiveTemplateContents(directiveValue); compileNode = $template[0]; if ($template.length != 1 || compileNode.nodeType !== 1) { @@ -1644,6 +1643,28 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } + function directiveTemplateContents(template) { + var type; + template = trim(template); + if ((type = TABLE_CONTENT_REGEXP.exec(template))) { + type = type[1].toLowerCase(); + var table = jqLite('
' + template + '
'), + tbody = table.children('tbody'), + leaf = /(td|th)/.test(type) && table.find('tr'); + if (tbody.length && type !== 'tbody') { + table = tbody; + } + if (leaf && leaf.length) { + table = leaf; + } + return table.contents(); + } + return jqLite('

').contents(); + } + + function compileTemplateUrl(directives, $compileNode, tAttrs, $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) { var linkQueue = [], @@ -1668,7 +1689,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { content = denormalizeTemplate(content); if (origAsyncDirective.replace) { - $template = jqLite('
' + trim(content) + '
').contents(); + $template = directiveTemplateContents(content); compileNode = $template[0]; if ($template.length != 1 || compileNode.nodeType !== 1) { diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 60b1024bf97f..e9ab15e4b712 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -517,6 +517,22 @@ describe('$compile', function() { expect(element).toBe(attr.$$element); } })); + directive('replaceWithTr', valueFn({ + replace: true, + template: 'TR' + })); + directive('replaceWithTd', valueFn({ + replace: true, + template: 'TD' + })); + directive('replaceWithTh', valueFn({ + replace: true, + template: 'TH' + })); + directive('replaceWithTbody', valueFn({ + replace: true, + template: 'TD' + })); })); @@ -680,6 +696,34 @@ describe('$compile', function() { }).not.toThrow(); }); }); + + it('should support templates with root tags', inject(function($compile, $rootScope) { + expect(function() { + element = $compile('
')($rootScope); + }).not.toThrow(); + expect(nodeName_(element)).toMatch(/tr/i); + })); + + it('should support templates with root tags', inject(function($compile, $rootScope) { + expect(function() { + element = $compile('
')($rootScope); + }).not.toThrow(); + expect(nodeName_(element)).toMatch(/td/i); + })); + + it('should support templates with root tags', inject(function($compile, $rootScope) { + expect(function() { + element = $compile('
')($rootScope); + }).not.toThrow(); + expect(nodeName_(element)).toMatch(/th/i); + })); + + it('should support templates with root tags', inject(function($compile, $rootScope) { + expect(function() { + element = $compile('
')($rootScope); + }).not.toThrow(); + expect(nodeName_(element)).toMatch(/tbody/i); + })); }); @@ -776,6 +820,23 @@ describe('$compile', function() { replace: true, template: 'Hello, {{name}}!' })); + + directive('replaceWithTr', valueFn({ + replace: true, + templateUrl: 'tr.html' + })); + directive('replaceWithTd', valueFn({ + replace: true, + templateUrl: 'td.html' + })); + directive('replaceWithTh', valueFn({ + replace: true, + templateUrl: 'th.html' + })); + directive('replaceWithTbody', valueFn({ + replace: true, + templateUrl: 'tbody.html' + })); } )); @@ -1411,6 +1472,42 @@ describe('$compile', function() { expect(element.html()).toContain('i = 1'); }); }); + + it('should support templates with root tags', inject(function($compile, $rootScope, $templateCache) { + $templateCache.put('tr.html', 'TR'); + expect(function() { + element = $compile('
')($rootScope); + }).not.toThrow(); + $rootScope.$digest(); + expect(nodeName_(element)).toMatch(/tr/i); + })); + + it('should support templates with root tags', inject(function($compile, $rootScope, $templateCache) { + $templateCache.put('td.html', 'TD'); + expect(function() { + element = $compile('
')($rootScope); + }).not.toThrow(); + $rootScope.$digest(); + expect(nodeName_(element)).toMatch(/td/i); + })); + + it('should support templates with root tags', inject(function($compile, $rootScope, $templateCache) { + $templateCache.put('th.html', 'TH'); + expect(function() { + element = $compile('
')($rootScope); + }).not.toThrow(); + $rootScope.$digest(); + expect(nodeName_(element)).toMatch(/th/i); + })); + + it('should support templates with root tags', inject(function($compile, $rootScope, $templateCache) { + $templateCache.put('tbody.html', 'TD'); + expect(function() { + element = $compile('
')($rootScope); + }).not.toThrow(); + $rootScope.$digest(); + expect(nodeName_(element)).toMatch(/tbody/i); + })); }); From b041b2c00e8c5e74c33b87b0cdfaf7cd826b823b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Fri, 14 Feb 2014 00:25:10 -0500 Subject: [PATCH 036/123] chore(jqLite): expose the _data lookup function to angular.element --- src/jqLite.js | 8 ++++++++ test/jqLiteSpec.js | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/jqLite.js b/src/jqLite.js index 6749b26e7141..6056730ac7a8 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -107,6 +107,14 @@ var jqCache = JQLite.cache = {}, ? function(element, type, fn) {element.removeEventListener(type, fn, false); } : function(element, type, fn) {element.detachEvent('on' + type, fn); }); +/* + * !!! This is an undocumented "private" function !!! + */ +var jqData = JQLite._data = function(node) { + //jQuery always returns an object on cache miss + return this.cache[node[this.expando]] || {}; +}; + function jqNextId() { return ++jqId; } diff --git a/test/jqLiteSpec.js b/test/jqLiteSpec.js index a98e94b93e6e..82db95b6551d 100644 --- a/test/jqLiteSpec.js +++ b/test/jqLiteSpec.js @@ -97,6 +97,23 @@ describe('jqLite', function() { }); }); + describe('_data', function() { + it('should provide access to the data present on the element', function() { + var element = jqLite('foo'); + var data = ['value']; + element.data('val', data); + expect(angular.element._data(element[0]).data.val).toBe(data); + dealoc(element); + }); + + it('should provide access to the events present on the element', function() { + var element = jqLite('foo'); + expect(angular.element._data(element[0]).events).toBeUndefined(); + + element.on('click', function() { }); + expect(angular.element._data(element[0]).events.click).toBeDefined(); + }); + }); describe('inheritedData', function() { From a39396749a960288ae383c9d4210496578770109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Thu, 13 Feb 2014 14:59:25 -0500 Subject: [PATCH 037/123] pref($animate): group all asynchronous requests into one shared buffer --- src/ngAnimate/animate.js | 40 ++++++++++++++++++++++++----------- test/ngAnimate/animateSpec.js | 39 +++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index b1ea7d3d0216..99b42f387fde 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -268,6 +268,20 @@ angular.module('ngAnimate', ['ng']) }; }]) + .factory('$$asyncQueueBuffer', ['$timeout', function($timeout) { + var timer, queue = []; + return function(fn) { + $timeout.cancel(timer); + queue.push(fn); + timer = $timeout(function() { + for(var i = 0; i < queue.length; i++) { + queue[i](); + } + queue = []; + }, 0, false); + }; + }]) + .config(['$provide', '$animateProvider', function($provide, $animateProvider) { var noop = angular.noop; var forEach = angular.forEach; @@ -291,9 +305,10 @@ angular.module('ngAnimate', ['ng']) return extractElementNode(elm1) == extractElementNode(elm2); } - $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$timeout', '$rootScope', '$document', - function($delegate, $injector, $sniffer, $rootElement, $timeout, $rootScope, $document) { + $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$$asyncQueueBuffer', '$rootScope', '$document', + function($delegate, $injector, $sniffer, $rootElement, $$asyncQueueBuffer, $rootScope, $document) { + var globalAnimationCounter = 0; $rootElement.data(NG_ANIMATE_STATE, rootAnimateState); // disable animations during bootstrap, but once we bootstrapped, wait again @@ -315,10 +330,6 @@ angular.module('ngAnimate', ['ng']) return classNameFilter.test(className); }; - function async(fn) { - return $timeout(fn, 0, false); - } - function lookup(name) { if (name) { var matches = [], @@ -685,7 +696,6 @@ angular.module('ngAnimate', ['ng']) if(ngAnimateState.running) { //if an animation is currently running on the element then lets take the steps //to cancel that animation and fire any required callbacks - $timeout.cancel(ngAnimateState.closeAnimationTimeout); cleanup(element); cancelAnimations(ngAnimateState.animations); @@ -736,12 +746,15 @@ angular.module('ngAnimate', ['ng']) //parent animations to find and cancel child animations when needed element.addClass(NG_ANIMATE_CLASS_NAME); + var localAnimationCount = globalAnimationCounter++; + element.data(NG_ANIMATE_STATE, { running:true, event:animationEvent, className:className, structural:!isClassBased, animations:animations, + index:localAnimationCount, done:onBeforeAnimationsComplete }); @@ -816,19 +829,19 @@ angular.module('ngAnimate', ['ng']) } function fireBeforeCallbackAsync() { - async(function() { + $$asyncQueueBuffer(function() { fireDOMCallback('before'); }); } function fireAfterCallbackAsync() { - async(function() { + $$asyncQueueBuffer(function() { fireDOMCallback('after'); }); } function fireDoneCallbackAsync() { - async(function() { + $$asyncQueueBuffer(function() { fireDOMCallback('close'); doneCallback && doneCallback(); }); @@ -855,8 +868,11 @@ angular.module('ngAnimate', ['ng']) if(isClassBased) { cleanup(element); } else { - data.closeAnimationTimeout = async(function() { - cleanup(element); + $$asyncQueueBuffer(function() { + var data = element.data(NG_ANIMATE_STATE) || {}; + if(localAnimationCount == data.index) { + cleanup(element); + } }); element.data(NG_ANIMATE_STATE, data); } diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index d626d60eeaaf..41115e42b792 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -2563,8 +2563,9 @@ describe("ngAnimate", function() { }); - it("should disable all child animations on structural animations until the post animation timeout has passed", function() { - var intercepted; + it("should disable all child animations on structural animations until the post animation" + + "timeout has passed as well as all structural animations", function() { + var intercepted, continueAnimation; module(function($animateProvider) { $animateProvider.register('.animated', function() { return { @@ -2578,7 +2579,10 @@ describe("ngAnimate", function() { function ani(type) { return function(element, className, done) { intercepted = type; - (done || className)(); + continueAnimation = function() { + continueAnimation = angular.noop; + (done || className)(); + } } } }); @@ -2595,26 +2599,45 @@ describe("ngAnimate", function() { var child2 = $compile('
...
')($rootScope); var container = $compile('
...
')($rootScope); - jqLite($document[0].body).append($rootElement); + var body = angular.element($document[0].body); + body.append($rootElement); $rootElement.append(container); element.append(child1); element.append(child2); - $animate.move(element, null, container); + $animate.enter(element, container); $rootScope.$digest(); - expect(intercepted).toBe('move'); + expect(intercepted).toBe('enter'); + continueAnimation(); $animate.addClass(child1, 'test'); expect(child1.hasClass('test')).toBe(true); - expect(intercepted).toBe('move'); + expect(element.children().length).toBe(2); + + expect(intercepted).toBe('enter'); $animate.leave(child1); $rootScope.$digest(); + expect(element.children().length).toBe(1); + + expect(intercepted).toBe('enter'); + + $animate.move(element, null, container); + $rootScope.$digest(); + expect(intercepted).toBe('move'); - //reflow has passed + //flush the enter reflow + $timeout.flush(); + + $animate.addClass(child2, 'testing'); + expect(intercepted).toBe('move'); + + continueAnimation(); + + //flush the move reflow $timeout.flush(); $animate.leave(child2); From ad8dd167da7bddae9474bcd15dc98c15398357e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Fri, 14 Feb 2014 00:53:49 -0500 Subject: [PATCH 038/123] pref($animate): only trigger DOM callbacks if registered on the element being animated BREAKING CHANGE: Both the `$animate:before` and `$animate:after` DOM events must be now registered prior to the $animate operation taking place. The `$animate:close` event can be registered anytime afterwards. DOM callbacks used to fired for each and every animation operation that occurs within the $animate service provided in the ngAnimate module. This may end up slowing down an application if 100s of elements are being inserted into the page. Therefore after this change callbacks are only fired if registered on the element being animated. --- src/ngAnimate/animate.js | 34 ++++++++++++++++++++-------------- test/ngAnimate/animateSpec.js | 15 +++++++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index 99b42f387fde..dba8d3fa3cd1 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -627,6 +627,9 @@ angular.module('ngAnimate', ['ng']) return; } + var elementEvents = angular.element._data(node); + elementEvents = elementEvents && elementEvents.events; + var animationLookup = (' ' + classes).replace(/\s+/g,'.'); if (!parentElement) { parentElement = afterElement ? afterElement.parent() : element.parent(); @@ -822,29 +825,32 @@ angular.module('ngAnimate', ['ng']) } function fireDOMCallback(animationPhase) { - element.triggerHandler('$animate:' + animationPhase, { - event : animationEvent, - className : className - }); + var eventName = '$animate:' + animationPhase; + if(elementEvents && elementEvents[eventName] && elementEvents[eventName].length > 0) { + $$asyncQueueBuffer(function() { + element.triggerHandler(eventName, { + event : animationEvent, + className : className + }); + }); + } } function fireBeforeCallbackAsync() { - $$asyncQueueBuffer(function() { - fireDOMCallback('before'); - }); + fireDOMCallback('before'); } function fireAfterCallbackAsync() { - $$asyncQueueBuffer(function() { - fireDOMCallback('after'); - }); + fireDOMCallback('after'); } function fireDoneCallbackAsync() { - $$asyncQueueBuffer(function() { - fireDOMCallback('close'); - doneCallback && doneCallback(); - }); + fireDOMCallback('close'); + if(doneCallback) { + $$asyncQueueBuffer(function() { + doneCallback(); + }); + } } //it is less complicated to use a flag than managing and cancelling diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index 41115e42b792..8da3d1cbfbce 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -1573,6 +1573,21 @@ describe("ngAnimate", function() { expect(steps.shift()).toEqual(['after', 'ng-enter', 'enter']); })); + it('should not fire DOM callbacks on the element being animated unless registered', + inject(function($animate, $rootScope, $compile, $sniffer, $rootElement, $timeout) { + + $animate.enabled(true); + + var element = jqLite('
'); + $rootElement.append(element); + body.append($rootElement); + + $animate.addClass(element, 'class'); + $rootScope.$digest(); + + $timeout.verifyNoPendingTasks(); + })); + it("should fire a done callback when provided with no animation", inject(function($animate, $rootScope, $compile, $sniffer, $rootElement, $timeout) { From b417b09ad05244b244c514a603a8bd8989ba3f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Fri, 14 Feb 2014 04:02:46 -0500 Subject: [PATCH 039/123] fix($animate): ensure $animate doesn't break natural CSS transitions BREAKING CHANGE: ngClass and {{ class }} will now call the `setClass` animation callback instead of addClass / removeClass when both a addClass/removeClass operation is being executed on the element during the animation. Please include the setClass animation callback as well as addClass and removeClass within your JS animations to work with ngClass and {{ class }} directives. Closes #6019 --- css/angular.css | 5 + src/ng/animate.js | 23 ++ src/ng/compile.js | 12 +- src/ngAnimate/animate.js | 491 ++++++++++++++++----------- src/ngMock/angular-mocks.js | 3 +- test/ng/compileSpec.js | 6 +- test/ng/directive/ngClassSpec.js | 10 +- test/ngAnimate/animateSpec.js | 71 +--- test/ngRoute/directive/ngViewSpec.js | 3 +- 9 files changed, 344 insertions(+), 280 deletions(-) diff --git a/css/angular.css b/css/angular.css index b88e61e483e2..2566640ebb2f 100644 --- a/css/angular.css +++ b/css/angular.css @@ -9,3 +9,8 @@ ng\:form { display: block; } + +.ng-animate-block-transitions { + transition:0s all!important; + -webkit-transition:0s all!important; +} diff --git a/src/ng/animate.js b/src/ng/animate.js index fa5b936d7ed5..1961d47be1f3 100644 --- a/src/ng/animate.js +++ b/src/ng/animate.js @@ -222,6 +222,29 @@ var $AnimateProvider = ['$provide', function($provide) { done && $timeout(done, 0, false); }, + /** + * + * @ngdoc function + * @name ng.$animate#setClass + * @methodOf ng.$animate + * @function + * @description Adds and/or removes the given CSS classes to and from the element. + * Once complete, the done() callback will be fired (if provided). + * @param {jQuery/jqLite element} element the element which will it's CSS classes changed + * removed from it + * @param {string} add the CSS classes which will be added to the element + * @param {string} remove the CSS class which will be removed from the element + * @param {function=} done the callback function (if provided) that will be fired after the + * CSS classes have been set on the element + */ + setClass : function(element, add, remove, done) { + forEach(element, function (element) { + jqLiteAddClass(element, add); + jqLiteRemoveClass(element, remove); + }); + done && $timeout(done, 0, false); + }, + enabled : noop }; }]; diff --git a/src/ng/compile.js b/src/ng/compile.js index e4bf230ed68b..ded62ea9a210 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -690,8 +690,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { * @param {string} oldClasses The former CSS className value */ $updateClass : function(newClasses, oldClasses) { - this.$removeClass(tokenDifference(oldClasses, newClasses)); - this.$addClass(tokenDifference(newClasses, oldClasses)); + var toAdd = tokenDifference(newClasses, oldClasses); + var toRemove = tokenDifference(oldClasses, newClasses); + + if(toAdd.length === 0) { + $animate.removeClass(this.$$element, toRemove); + } else if(toRemove.length === 0) { + $animate.addClass(this.$$element, toAdd); + } else { + $animate.setClass(this.$$element, toAdd, toRemove); + } }, /** diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index dba8d3fa3cd1..28a1510a6ef3 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -248,7 +248,9 @@ angular.module('ngAnimate', ['ng']) * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application. * */ - .factory('$$animateReflow', ['$window', '$timeout', function($window, $timeout) { + .factory('$$animateReflow', ['$window', '$timeout', '$document', + function($window, $timeout, $document) { + var bod = $document[0].body; var requestAnimationFrame = $window.requestAnimationFrame || $window.webkitRequestAnimationFrame || function(fn) { @@ -261,7 +263,10 @@ angular.module('ngAnimate', ['ng']) return $timeout.cancel(timer); }; return function(fn) { - var id = requestAnimationFrame(fn); + var id = requestAnimationFrame(function() { + var a = bod.offsetWidth + 1; + fn(); + }); return function() { cancelAnimationFrame(id); }; @@ -301,6 +306,10 @@ angular.module('ngAnimate', ['ng']) } } + function stripCommentsFromElement(element) { + return angular.element(extractElementNode(element)); + } + function isMatchingElement(elm1, elm2) { return extractElementNode(elm1) == extractElementNode(elm2); } @@ -411,6 +420,7 @@ angular.module('ngAnimate', ['ng']) this.enabled(false, element); $delegate.enter(element, parentElement, afterElement); $rootScope.$$postDigest(function() { + element = stripCommentsFromElement(element); performAnimation('enter', 'ng-enter', element, parentElement, afterElement, noop, doneCallback); }); }, @@ -447,6 +457,7 @@ angular.module('ngAnimate', ['ng']) cancelChildAnimations(element); this.enabled(false, element); $rootScope.$$postDigest(function() { + element = stripCommentsFromElement(element); performAnimation('leave', 'ng-leave', element, null, null, function() { $delegate.leave(element); }, doneCallback); @@ -489,6 +500,7 @@ angular.module('ngAnimate', ['ng']) this.enabled(false, element); $delegate.move(element, parentElement, afterElement); $rootScope.$$postDigest(function() { + element = stripCommentsFromElement(element); performAnimation('move', 'ng-move', element, parentElement, afterElement, noop, doneCallback); }); }, @@ -524,6 +536,7 @@ angular.module('ngAnimate', ['ng']) * @param {function()=} doneCallback the callback function that will be called once the animation is complete */ addClass : function(element, className, doneCallback) { + element = stripCommentsFromElement(element); performAnimation('addClass', className, element, null, null, function() { $delegate.addClass(element, className); }, doneCallback); @@ -560,11 +573,34 @@ angular.module('ngAnimate', ['ng']) * @param {function()=} doneCallback the callback function that will be called once the animation is complete */ removeClass : function(element, className, doneCallback) { + element = stripCommentsFromElement(element); performAnimation('removeClass', className, element, null, null, function() { $delegate.removeClass(element, className); }, doneCallback); }, + /** + * + * @ngdoc function + * @name ng.$animate#setClass + * @methodOf ng.$animate + * @function + * @description Adds and/or removes the given CSS classes to and from the element. + * Once complete, the done() callback will be fired (if provided). + * @param {jQuery/jqLite element} element the element which will it's CSS classes changed + * removed from it + * @param {string} add the CSS classes which will be added to the element + * @param {string} remove the CSS class which will be removed from the element + * @param {function=} done the callback function (if provided) that will be fired after the + * CSS classes have been set on the element + */ + setClass : function(element, add, remove, doneCallback) { + element = stripCommentsFromElement(element); + performAnimation('setClass', [add, remove], element, null, null, function() { + $delegate.setClass(element, add, remove); + }, doneCallback); + }, + /** * @ngdoc function * @name ngAnimate.$animate#enabled @@ -611,7 +647,15 @@ angular.module('ngAnimate', ['ng']) and the onComplete callback will be fired once the animation is fully complete. */ function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) { - var currentClassName, classes, node = extractElementNode(element); + + var classNameAdd, classNameRemove, setClassOperation = animationEvent == 'setClass'; + if(setClassOperation) { + classNameAdd = className[0]; + classNameRemove = className[1]; + className = classNameAdd + ' ' + classNameRemove; + } + + var currentClassName, classes, node = element[0]; if(node) { currentClassName = node.className; classes = currentClassName + ' ' + className; @@ -623,7 +667,7 @@ angular.module('ngAnimate', ['ng']) fireDOMOperation(); fireBeforeCallbackAsync(); fireAfterCallbackAsync(); - closeAnimation(); + fireDoneCallbackAsync(); return; } @@ -635,9 +679,15 @@ angular.module('ngAnimate', ['ng']) parentElement = afterElement ? afterElement.parent() : element.parent(); } - var matches = lookup(animationLookup); - var isClassBased = animationEvent == 'addClass' || animationEvent == 'removeClass'; - var ngAnimateState = element.data(NG_ANIMATE_STATE) || {}; + var matches = lookup(animationLookup); + var isClassBased = animationEvent == 'addClass' || + animationEvent == 'removeClass' || + setClassOperation; + var ngAnimateState = element.data(NG_ANIMATE_STATE) || {}; + + var runningAnimations = ngAnimateState.active || {}; + var totalActiveAnimations = ngAnimateState.totalActive || 0; + var lastAnimation = ngAnimateState.last; //skip the animation if animations are disabled, a parent is already being animated, //the element is not currently attached to the document body or then completely close @@ -656,7 +706,7 @@ angular.module('ngAnimate', ['ng']) //only add animations if the currently running animation is not structural //or if there is no animation running at all var allowAnimations = isClassBased ? - !ngAnimateState.disabled && (!ngAnimateState.running || !ngAnimateState.structural) : + !ngAnimateState.disabled && (!lastAnimation || lastAnimation.classBased) : true; if(allowAnimations) { @@ -691,54 +741,48 @@ angular.module('ngAnimate', ['ng']) return; } - var ONE_SPACE = ' '; - //this value will be searched for class-based CSS className lookup. Therefore, - //we prefix and suffix the current className value with spaces to avoid substring - //lookups of className tokens - var futureClassName = ONE_SPACE + currentClassName + ONE_SPACE; - if(ngAnimateState.running) { - //if an animation is currently running on the element then lets take the steps - //to cancel that animation and fire any required callbacks - cleanup(element); - cancelAnimations(ngAnimateState.animations); - - //in the event that the CSS is class is quickly added and removed back - //then we don't want to wait until after the reflow to add/remove the CSS - //class since both class animations may run into a race condition. - //The code below will check to see if that is occurring and will - //immediately remove the former class before the reflow so that the - //animation can snap back to the original animation smoothly - var isFullyClassBasedAnimation = isClassBased && !ngAnimateState.structural; - var isRevertingClassAnimation = isFullyClassBasedAnimation && - ngAnimateState.className == className && - animationEvent != ngAnimateState.event; - - //if the class is removed during the reflow then it will revert the styles temporarily - //back to the base class CSS styling causing a jump-like effect to occur. This check - //here ensures that the domOperation is only performed after the reflow has commenced - if(ngAnimateState.beforeComplete || isRevertingClassAnimation) { - (ngAnimateState.done || noop)(true); - } else if(isFullyClassBasedAnimation) { - //class-based animations will compare element className values after cancelling the - //previous animation to see if the element properties already contain the final CSS - //class and if so then the animation will be skipped. Since the domOperation will - //be performed only after the reflow is complete then our element's className value - //will be invalid. Therefore the same string manipulation that would occur within the - //DOM operation will be performed below so that the class comparison is valid... - futureClassName = ngAnimateState.event == 'removeClass' ? - futureClassName.replace(ONE_SPACE + ngAnimateState.className + ONE_SPACE, ONE_SPACE) : - futureClassName + ngAnimateState.className + ONE_SPACE; + var skipAnimation = false; + if(totalActiveAnimations > 0) { + var animationsToCancel = []; + if(!isClassBased) { + if(animationEvent == 'leave' && runningAnimations['ng-leave']) { + skipAnimation = true; + } else { + //cancel all animations when a structural animation takes place + for(var klass in runningAnimations) { + animationsToCancel.push(runningAnimations[klass]); + cleanup(element, klass); + } + runningAnimations = {}; + totalActiveAnimations = 0; + } + } else if(lastAnimation.event == 'setClass') { + animationsToCancel.push(lastAnimation); + cleanup(element, className); + } + else if(runningAnimations[className]) { + var current = runningAnimations[className]; + if(current.event == animationEvent) { + skipAnimation = true; + } else { + animationsToCancel.push(current); + cleanup(element, className); + } + } + + if(animationsToCancel.length > 0) { + angular.forEach(animationsToCancel, function(operation) { + (operation.done || noop)(true); + cancelAnimations(operation.animations); + }); } } - //There is no point in perform a class-based animation if the element already contains - //(on addClass) or doesn't contain (on removeClass) the className being animated. - //The reason why this is being called after the previous animations are cancelled - //is so that the CSS classes present on the element can be properly examined. - var classNameToken = ONE_SPACE + className + ONE_SPACE; - if((animationEvent == 'addClass' && futureClassName.indexOf(classNameToken) >= 0) || - (animationEvent == 'removeClass' && futureClassName.indexOf(classNameToken) == -1)) { - fireDOMOperation(); + if(isClassBased && !setClassOperation && !skipAnimation) { + skipAnimation = (animationEvent == 'addClass') == element.hasClass(className); //opposite of XOR + } + + if(skipAnimation) { fireBeforeCallbackAsync(); fireAfterCallbackAsync(); fireDoneCallbackAsync(); @@ -750,15 +794,21 @@ angular.module('ngAnimate', ['ng']) element.addClass(NG_ANIMATE_CLASS_NAME); var localAnimationCount = globalAnimationCounter++; + lastAnimation = { + classBased : isClassBased, + event : animationEvent, + animations : animations, + done:onBeforeAnimationsComplete + }; + + totalActiveAnimations++; + runningAnimations[className] = lastAnimation; element.data(NG_ANIMATE_STATE, { - running:true, - event:animationEvent, - className:className, - structural:!isClassBased, - animations:animations, - index:localAnimationCount, - done:onBeforeAnimationsComplete + last : lastAnimation, + active : runningAnimations, + index : localAnimationCount, + totalActive : totalActiveAnimations }); //first we run the before animations and when all of those are complete @@ -766,6 +816,11 @@ angular.module('ngAnimate', ['ng']) invokeRegisteredAnimationFns(animations, 'before', onBeforeAnimationsComplete); function onBeforeAnimationsComplete(cancelled) { + var data = element.data(NG_ANIMATE_STATE); + cancelled = cancelled || + !data || !data.active[className] || + (isClassBased && data.active[className].event != animationEvent); + fireDOMOperation(); if(cancelled === true) { closeAnimation(); @@ -775,11 +830,8 @@ angular.module('ngAnimate', ['ng']) //set the done function to the final done function //so that the DOM event won't be executed twice by accident //if the after animation is cancelled as well - var data = element.data(NG_ANIMATE_STATE); - if(data) { - data.done = closeAnimation; - element.data(NG_ANIMATE_STATE, data); - } + var currentAnimation = data.active[className]; + currentAnimation.done = closeAnimation; invokeRegisteredAnimationFns(animations, 'after', closeAnimation); } @@ -802,9 +854,13 @@ angular.module('ngAnimate', ['ng']) } if(animation[phase]) { - animation[endFnName] = isClassBased ? - animation[phase](element, className, animationPhaseCompleted) : - animation[phase](element, animationPhaseCompleted); + if(setClassOperation) { + animation[endFnName] = animation[phase](element, classNameAdd, classNameRemove, animationPhaseCompleted); + } else { + animation[endFnName] = isClassBased ? + animation[phase](element, className, animationPhaseCompleted) : + animation[phase](element, animationPhaseCompleted); + } } else { animationPhaseCompleted(); } @@ -872,12 +928,12 @@ angular.module('ngAnimate', ['ng']) failing would be when a parent HTML tag has a ng-class attribute causing ALL directives below to skip animations during the digest */ if(isClassBased) { - cleanup(element); + cleanup(element, className); } else { $$asyncQueueBuffer(function() { var data = element.data(NG_ANIMATE_STATE) || {}; if(localAnimationCount == data.index) { - cleanup(element); + cleanup(element, className, animationEvent); } }); element.data(NG_ANIMATE_STATE, data); @@ -893,9 +949,11 @@ angular.module('ngAnimate', ['ng']) forEach(node.querySelectorAll('.' + NG_ANIMATE_CLASS_NAME), function(element) { element = angular.element(element); var data = element.data(NG_ANIMATE_STATE); - if(data) { - cancelAnimations(data.animations); - cleanup(element); + if(data && data.active) { + angular.forEach(data.active, function(operation) { + (operation.done || noop)(true); + cancelAnimations(operation.animations); + }); } }); } @@ -912,15 +970,27 @@ angular.module('ngAnimate', ['ng']) }); } - function cleanup(element) { + function cleanup(element, className) { if(isMatchingElement(element, $rootElement)) { if(!rootAnimateState.disabled) { rootAnimateState.running = false; rootAnimateState.structural = false; } - } else { - element.removeClass(NG_ANIMATE_CLASS_NAME); - element.removeData(NG_ANIMATE_STATE); + } else if(className) { + var data = element.data(NG_ANIMATE_STATE) || {}; + + var removeAnimations = className === true; + if(!removeAnimations) { + if(data.active && data.active[className]) { + data.totalActive--; + delete data.active[className]; + } + } + + if(removeAnimations || !data.totalActive) { + element.removeClass(NG_ANIMATE_CLASS_NAME); + element.removeData(NG_ANIMATE_STATE); + } } } @@ -939,7 +1009,7 @@ angular.module('ngAnimate', ['ng']) var isRoot = isMatchingElement(parentElement, $rootElement); var state = isRoot ? rootAnimateState : parentElement.data(NG_ANIMATE_STATE); - var result = state && (!!state.disabled || !!state.running); + var result = state && (!!state.disabled || state.running || state.totalActive > 0); if(isRoot || result) { return result; } @@ -989,74 +1059,57 @@ angular.module('ngAnimate', ['ng']) var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount'; var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey'; var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data'; + var NG_ANIMATE_BLOCK_CLASS_NAME = 'ng-animate-block-transitions'; var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3; var CLOSING_TIME_BUFFER = 1.5; var ONE_SECOND = 1000; - var animationCounter = 0; var lookupCache = {}; var parentCounter = 0; var animationReflowQueue = []; - var animationElementQueue = []; var cancelAnimationReflow; - var closingAnimationTime = 0; - var timeOut = false; function afterReflow(element, callback) { if(cancelAnimationReflow) { cancelAnimationReflow(); } - animationReflowQueue.push(callback); - - var node = extractElementNode(element); - element = angular.element(node); - animationElementQueue.push(element); - - var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY); - - var stagger = elementData.stagger; - var staggerTime = elementData.itemIndex * (Math.max(stagger.animationDelay, stagger.transitionDelay) || 0); - - var animationTime = (elementData.maxDelay + elementData.maxDuration) * CLOSING_TIME_BUFFER; - closingAnimationTime = Math.max(closingAnimationTime, (staggerTime + animationTime) * ONE_SECOND); - - //by placing a counter we can avoid an accidental - //race condition which may close an animation when - //a follow-up animation is midway in its animation - elementData.animationCount = animationCounter; - cancelAnimationReflow = $$animateReflow(function() { forEach(animationReflowQueue, function(fn) { fn(); }); - //copy the list of elements so that successive - //animations won't conflict if they're added before - //the closing animation timeout has run - var elementQueueSnapshot = []; - var animationCounterSnapshot = animationCounter; - forEach(animationElementQueue, function(elm) { - elementQueueSnapshot.push(elm); - }); - - $timeout(function() { - closeAllAnimations(elementQueueSnapshot, animationCounterSnapshot); - elementQueueSnapshot = null; - }, closingAnimationTime, false); - animationReflowQueue = []; - animationElementQueue = []; cancelAnimationReflow = null; lookupCache = {}; - closingAnimationTime = 0; - animationCounter++; }); } - function closeAllAnimations(elements, count) { + var closingTimer = null; + var closingTimestamp = 0; + var animationElementQueue = []; + function animationCloseHandler(element, totalTime) { + var futureTimestamp = Date.now() + (totalTime * 1000); + if(futureTimestamp <= closingTimestamp) { + return; + } + + $timeout.cancel(closingTimer); + + var node = extractElementNode(element); + element = angular.element(node); + animationElementQueue.push(element); + + closingTimestamp = futureTimestamp; + closingTimer = $timeout(function() { + closeAllAnimations(animationElementQueue); + animationElementQueue = []; + }, totalTime, false); + } + + function closeAllAnimations(elements) { forEach(elements, function(element) { var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY); - if(elementData && elementData.animationCount == count) { + if(elementData) { (elementData.closeAnimationFn || noop)(); } }); @@ -1141,12 +1194,12 @@ angular.module('ngAnimate', ['ng']) return parentID + '-' + extractElementNode(element).className; } - function animateSetup(element, className, calculationDecorator) { + function animateSetup(animationEvent, element, className, calculationDecorator) { var cacheKey = getCacheKey(element); var eventCacheKey = cacheKey + ' ' + className; - var stagger = {}; var itemIndex = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0; + var stagger = {}; if(itemIndex > 0) { var staggerClassName = className + '-stagger'; var staggerCacheKey = cacheKey + ' ' + staggerClassName; @@ -1166,60 +1219,63 @@ angular.module('ngAnimate', ['ng']) element.addClass(className); + var formerData = element.data(NG_ANIMATE_CSS_DATA_KEY) || {}; + var timings = calculationDecorator(function() { return getElementAnimationDetails(element, eventCacheKey); }); - /* there is no point in performing a reflow if the animation - timeout is empty (this would cause a flicker bug normally - in the page. There is also no point in performing an animation - that only has a delay and no duration */ - var maxDelay = Math.max(timings.transitionDelay, timings.animationDelay); - var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration); - if(maxDuration === 0) { + var transitionDuration = timings.transitionDuration; + var animationDuration = timings.animationDuration; + if(transitionDuration === 0 && animationDuration === 0) { element.removeClass(className); return false; } - //temporarily disable the transition so that the enter styles - //don't animate twice (this is here to avoid a bug in Chrome/FF). - var activeClassName = ''; - timings.transitionDuration > 0 ? - blockTransitions(element) : - blockKeyframeAnimations(element); - - forEach(className.split(' '), function(klass, i) { - activeClassName += (i > 0 ? ' ' : '') + klass + '-active'; - }); - element.data(NG_ANIMATE_CSS_DATA_KEY, { - className : className, - activeClassName : activeClassName, - maxDuration : maxDuration, - maxDelay : maxDelay, - classes : className + ' ' + activeClassName, - timings : timings, + running : formerData.running || 0, + itemIndex : itemIndex, stagger : stagger, - itemIndex : itemIndex + timings : timings, + closeAnimationFn : angular.noop }); + //temporarily disable the transition so that the enter styles + //don't animate twice (this is here to avoid a bug in Chrome/FF). + var isCurrentlyAnimating = formerData.running > 0 || animationEvent == 'setClass'; + if(transitionDuration > 0) { + blockTransitions(element, className, isCurrentlyAnimating); + } + if(animationDuration > 0) { + blockKeyframeAnimations(element); + } + return true; } - function blockTransitions(element) { - extractElementNode(element).style[TRANSITION_PROP + PROPERTY_KEY] = 'none'; + function isStructuralAnimation(className) { + return className == 'ng-enter' || className == 'ng-move' || className == 'ng-leave'; + } + + function blockTransitions(element, className, isAnimating) { + if(isStructuralAnimation(className) || !isAnimating) { + extractElementNode(element).style[TRANSITION_PROP + PROPERTY_KEY] = 'none'; + } else { + element.addClass(NG_ANIMATE_BLOCK_CLASS_NAME); + } } function blockKeyframeAnimations(element) { extractElementNode(element).style[ANIMATION_PROP] = 'none 0s'; } - function unblockTransitions(element) { + function unblockTransitions(element, className) { var prop = TRANSITION_PROP + PROPERTY_KEY; var node = extractElementNode(element); if(node.style[prop] && node.style[prop].length > 0) { node.style[prop] = ''; } + element.removeClass(NG_ANIMATE_BLOCK_CLASS_NAME); } function unblockKeyframeAnimations(element) { @@ -1230,22 +1286,28 @@ angular.module('ngAnimate', ['ng']) } } - function animateRun(element, className, activeAnimationComplete) { - var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY); + function animateRun(animationEvent, element, className, activeAnimationComplete) { var node = extractElementNode(element); + var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY); if(node.className.indexOf(className) == -1 || !elementData) { activeAnimationComplete(); return; } - var timings = elementData.timings; + var activeClassName = ''; + forEach(className.split(' '), function(klass, i) { + activeClassName += (i > 0 ? ' ' : '') + klass + '-active'; + }); + var stagger = elementData.stagger; - var maxDuration = elementData.maxDuration; - var activeClassName = elementData.activeClassName; - var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * ONE_SECOND; + var timings = elementData.timings; + var itemIndex = elementData.itemIndex; + var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration); + var maxDelay = Math.max(timings.transitionDelay, timings.animationDelay); + var maxDelayTime = maxDelay * ONE_SECOND; + var startTime = Date.now(); var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT; - var itemIndex = elementData.itemIndex; var style = '', appliedStyles = []; if(timings.transitionDuration > 0) { @@ -1287,6 +1349,13 @@ angular.module('ngAnimate', ['ng']) onEnd(); activeAnimationComplete(); }; + + var staggerTime = itemIndex * (Math.max(stagger.animationDelay, stagger.transitionDelay) || 0); + var animationTime = (maxDelay + maxDuration) * CLOSING_TIME_BUFFER; + var totalTime = (staggerTime + animationTime) * ONE_SECOND; + + elementData.running++; + animationCloseHandler(element, totalTime); return onEnd; // This will automatically be called by $animate so @@ -1333,28 +1402,28 @@ angular.module('ngAnimate', ['ng']) return style; } - function animateBefore(element, className, calculationDecorator) { - if(animateSetup(element, className, calculationDecorator)) { + function animateBefore(animationEvent, element, className, calculationDecorator) { + if(animateSetup(animationEvent, element, className, calculationDecorator)) { return function(cancelled) { cancelled && animateClose(element, className); }; } } - function animateAfter(element, className, afterAnimationComplete) { + function animateAfter(animationEvent, element, className, afterAnimationComplete) { if(element.data(NG_ANIMATE_CSS_DATA_KEY)) { - return animateRun(element, className, afterAnimationComplete); + return animateRun(animationEvent, element, className, afterAnimationComplete); } else { animateClose(element, className); afterAnimationComplete(); } } - function animate(element, className, animationComplete) { + function animate(animationEvent, element, className, animationComplete) { //If the animateSetup function doesn't bother returning a //cancellation function then it means that there is no animation //to perform at all - var preReflowCancellation = animateBefore(element, className); + var preReflowCancellation = animateBefore(animationEvent, element, className); if(!preReflowCancellation) { animationComplete(); return; @@ -1367,12 +1436,12 @@ angular.module('ngAnimate', ['ng']) //happen in the first place var cancel = preReflowCancellation; afterReflow(element, function() { - unblockTransitions(element); + unblockTransitions(element, className); unblockKeyframeAnimations(element); //once the reflow is complete then we point cancel to //the new cancellation function which will remove all of the //animation properties from the active animation - cancel = animateAfter(element, className, animationComplete); + cancel = animateAfter(animationEvent, element, className, animationComplete); }); return function(cancelled) { @@ -1382,54 +1451,59 @@ angular.module('ngAnimate', ['ng']) function animateClose(element, className) { element.removeClass(className); - element.removeData(NG_ANIMATE_CSS_DATA_KEY); + var data = element.data(NG_ANIMATE_CSS_DATA_KEY); + if(data) { + if(data.running) { + data.running--; + } + if(!data.running || data.running === 0) { + element.removeData(NG_ANIMATE_CSS_DATA_KEY); + } + } } return { - allowCancel : function(element, animationEvent, className) { - //always cancel the current animation if it is a - //structural animation - var oldClasses = (element.data(NG_ANIMATE_CSS_DATA_KEY) || {}).classes; - if(!oldClasses || ['enter','leave','move'].indexOf(animationEvent) >= 0) { - return true; - } - - var parentElement = element.parent(); - var clone = angular.element(extractElementNode(element).cloneNode()); - - //make the element super hidden and override any CSS style values - clone.attr('style','position:absolute; top:-9999px; left:-9999px'); - clone.removeAttr('id'); - clone.empty(); - - forEach(oldClasses.split(' '), function(klass) { - clone.removeClass(klass); - }); - - var suffix = animationEvent == 'addClass' ? '-add' : '-remove'; - clone.addClass(suffixClasses(className, suffix)); - parentElement.append(clone); - - var timings = getElementAnimationDetails(clone); - clone.remove(); - - return Math.max(timings.transitionDuration, timings.animationDuration) > 0; - }, - enter : function(element, animationCompleted) { - return animate(element, 'ng-enter', animationCompleted); + return animate('enter', element, 'ng-enter', animationCompleted); }, leave : function(element, animationCompleted) { - return animate(element, 'ng-leave', animationCompleted); + return animate('leave', element, 'ng-leave', animationCompleted); }, move : function(element, animationCompleted) { - return animate(element, 'ng-move', animationCompleted); + return animate('move', element, 'ng-move', animationCompleted); + }, + + beforeSetClass : function(element, add, remove, animationCompleted) { + var className = suffixClasses(remove, '-remove') + ' ' + + suffixClasses(add, '-add'); + var cancellationMethod = animateBefore('setClass', element, className, function(fn) { + /* when classes are removed from an element then the transition style + * that is applied is the transition defined on the element without the + * CSS class being there. This is how CSS3 functions outside of ngAnimate. + * http://plnkr.co/edit/j8OzgTNxHTb4n3zLyjGW?p=preview */ + var klass = element.attr('class'); + element.removeClass(remove); + element.addClass(add); + var timings = fn(); + element.attr('class', klass); + return timings; + }); + + if(cancellationMethod) { + afterReflow(element, function() { + unblockTransitions(element, className); + unblockKeyframeAnimations(element); + animationCompleted(); + }); + return cancellationMethod; + } + animationCompleted(); }, beforeAddClass : function(element, className, animationCompleted) { - var cancellationMethod = animateBefore(element, suffixClasses(className, '-add'), function(fn) { + var cancellationMethod = animateBefore('addClass', element, suffixClasses(className, '-add'), function(fn) { /* when a CSS class is added to an element then the transition style that * is applied is the transition defined on the element when the CSS class @@ -1443,7 +1517,7 @@ angular.module('ngAnimate', ['ng']) if(cancellationMethod) { afterReflow(element, function() { - unblockTransitions(element); + unblockTransitions(element, className); unblockKeyframeAnimations(element); animationCompleted(); }); @@ -1452,12 +1526,19 @@ angular.module('ngAnimate', ['ng']) animationCompleted(); }, + setClass : function(element, add, remove, animationCompleted) { + remove = suffixClasses(remove, '-remove'); + add = suffixClasses(add, '-add'); + var className = remove + ' ' + add; + return animateAfter('setClass', element, className, animationCompleted); + }, + addClass : function(element, className, animationCompleted) { - return animateAfter(element, suffixClasses(className, '-add'), animationCompleted); + return animateAfter('addClass', element, suffixClasses(className, '-add'), animationCompleted); }, beforeRemoveClass : function(element, className, animationCompleted) { - var cancellationMethod = animateBefore(element, suffixClasses(className, '-remove'), function(fn) { + var cancellationMethod = animateBefore('removeClass', element, suffixClasses(className, '-remove'), function(fn) { /* when classes are removed from an element then the transition style * that is applied is the transition defined on the element without the * CSS class being there. This is how CSS3 functions outside of ngAnimate. @@ -1471,7 +1552,7 @@ angular.module('ngAnimate', ['ng']) if(cancellationMethod) { afterReflow(element, function() { - unblockTransitions(element); + unblockTransitions(element, className); unblockKeyframeAnimations(element); animationCompleted(); }); @@ -1481,7 +1562,7 @@ angular.module('ngAnimate', ['ng']) }, removeClass : function(element, className, animationCompleted) { - return animateAfter(element, suffixClasses(className, '-remove'), animationCompleted); + return animateAfter('removeClass', element, suffixClasses(className, '-remove'), animationCompleted); } }; diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 6b8868f7501d..ba79fc881643 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -782,7 +782,8 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng']) } }; - angular.forEach(['enter','leave','move','addClass','removeClass'], function(method) { + angular.forEach( + ['enter','leave','move','addClass','removeClass','setClass'], function(method) { animate[method] = function() { animate.queue.push({ event : method, diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index e9ab15e4b712..98b1650f7706 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -4666,11 +4666,9 @@ describe('$compile', function() { $rootScope.$digest(); data = $animate.queue.shift(); - expect(data.event).toBe('removeClass'); - expect(data.args[1]).toBe('rice'); - data = $animate.queue.shift(); - expect(data.event).toBe('addClass'); + expect(data.event).toBe('setClass'); expect(data.args[1]).toBe('dice'); + expect(data.args[2]).toBe('rice'); expect(element.hasClass('ice')).toBe(true); expect(element.hasClass('dice')).toBe(true); diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js index b162fea6ce71..b11c4766c05b 100644 --- a/test/ng/directive/ngClassSpec.js +++ b/test/ng/directive/ngClassSpec.js @@ -335,8 +335,7 @@ describe('ngClass animations', function() { $rootScope.val = 'two'; $rootScope.$digest(); - expect($animate.queue.shift().event).toBe('removeClass'); - expect($animate.queue.shift().event).toBe('addClass'); + expect($animate.queue.shift().event).toBe('setClass'); expect($animate.queue.length).toBe(0); }); }); @@ -450,12 +449,9 @@ describe('ngClass animations', function() { $rootScope.$digest(); item = $animate.queue.shift(); - expect(item.event).toBe('removeClass'); - expect(item.args[1]).toBe('two'); - - item = $animate.queue.shift(); - expect(item.event).toBe('addClass'); + expect(item.event).toBe('setClass'); expect(item.args[1]).toBe('three'); + expect(item.args[2]).toBe('two'); expect($animate.queue.length).toBe(0); }); diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index 8da3d1cbfbce..d11cfa9ece3d 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -491,7 +491,7 @@ describe("ngAnimate", function() { $animate.triggerReflow(); //this is to verify that the existing style is appended with a semicolon automatically - expect(child.attr('style')).toMatch(/width: 20px;.+?/i); + expect(child.attr('style')).toMatch(/width: 20px;.*?/i); browserTrigger(child,'transitionend', { timeStamp: Date.now() + 1000, elapsedTime: 1 }); } @@ -564,7 +564,7 @@ describe("ngAnimate", function() { }); }); - it("should fire the cancel/end function with the correct flag in the parameters", + it("should not apply a cancellation when addClass is done multiple times", inject(function($animate, $rootScope, $sniffer, $timeout) { element.append(child); @@ -572,7 +572,7 @@ describe("ngAnimate", function() { $animate.addClass(child, 'custom-delay'); $animate.addClass(child, 'custom-long-delay'); - expect(child.hasClass('animation-cancelled')).toBe(true); + expect(child.hasClass('animation-cancelled')).toBe(false); expect(child.hasClass('animation-ended')).toBe(false); $timeout.flush(); @@ -764,7 +764,6 @@ describe("ngAnimate", function() { $animate.addClass(element, 'ng-hide'); expect(element.hasClass('ng-hide-remove')).toBe(false); //added right away - if($sniffer.animations) { //cleanup some pending animations $animate.triggerReflow(); expect(element.hasClass('ng-hide-add')).toBe(true); @@ -1472,6 +1471,8 @@ describe("ngAnimate", function() { expect(flag).toBe(true); expect(element.parent().id).toBe(parent2.id); + + dealoc(element); })); @@ -1620,11 +1621,12 @@ describe("ngAnimate", function() { var element = parent.find('span'); var flag = false; - $animate.removeClass(element, 'ng-hide', function() { + $animate.addClass(element, 'ng-hide', function() { flag = true; }); if($sniffer.transitions) { + $animate.triggerReflow(); browserTrigger(element,'transitionend', { timeStamp: Date.now() + 1000, elapsedTime: 1 }); } $timeout.flush(); @@ -2734,42 +2736,6 @@ describe("ngAnimate", function() { }); - it("should cancel an ongoing class-based animation only if the new class contains transition/animation CSS code", - inject(function($compile, $rootScope, $animate, $sniffer, $timeout) { - - if (!$sniffer.transitions) return; - - ss.addRule('.green-add', '-webkit-transition:1s linear all;' + - 'transition:1s linear all;'); - - ss.addRule('.blue-add', 'background:blue;'); - - ss.addRule('.red-add', '-webkit-transition:1s linear all;' + - 'transition:1s linear all;'); - - ss.addRule('.yellow-add', '-webkit-animation: some_animation 4s linear 1s 2 alternate;' + - 'animation: some_animation 4s linear 1s 2 alternate;'); - - var element = $compile('
')($rootScope); - $rootElement.append(element); - jqLite($document[0].body).append($rootElement); - - $animate.addClass(element, 'green'); - expect(element.hasClass('green-add')).toBe(true); - - $animate.addClass(element, 'blue'); - expect(element.hasClass('blue')).toBe(true); - expect(element.hasClass('green-add')).toBe(true); //not cancelled - - $animate.addClass(element, 'red'); - expect(element.hasClass('green-add')).toBe(false); - expect(element.hasClass('red-add')).toBe(true); - - $animate.addClass(element, 'yellow'); - expect(element.hasClass('red-add')).toBe(false); - expect(element.hasClass('yellow-add')).toBe(true); - })); - it("should cancel and perform the dom operation only after the reflow has run", inject(function($compile, $rootScope, $animate, $sniffer, $timeout) { @@ -2837,7 +2803,7 @@ describe("ngAnimate", function() { $animate.removeClass(element, 'on'); $animate.addClass(element, 'on'); - expect(currentAnimation).toBe(null); + expect(currentAnimation).toBe('addClass'); }); }); @@ -3259,7 +3225,7 @@ describe("ngAnimate", function() { expect(ready).toBe(true); })); - it('should avoid skip animations if the same CSS class is added / removed synchronously before the reflow kicks in', + it('should immediately close the former animation if the same CSS class is added/removed', inject(function($sniffer, $compile, $rootScope, $rootElement, $animate, $timeout) { if (!$sniffer.transitions) return; @@ -3281,28 +3247,15 @@ describe("ngAnimate", function() { signature += 'B'; }); - $timeout.flush(1); - expect(signature).toBe('AB'); - - signature = ''; - $animate.removeClass(element, 'on', function() { - signature += 'A'; - }); - $animate.addClass(element, 'on', function() { - signature += 'B'; - }); - $animate.removeClass(element, 'on', function() { - signature += 'C'; - }); + $animate.triggerReflow(); $timeout.flush(1); - expect(signature).toBe('AB'); + expect(signature).toBe('A'); - $animate.triggerReflow(); browserTrigger(element, 'transitionend', { timeStamp: Date.now(), elapsedTime: 2000 }); $timeout.flush(1); - expect(signature).toBe('ABC'); + expect(signature).toBe('AB'); })); }); }); diff --git a/test/ngRoute/directive/ngViewSpec.js b/test/ngRoute/directive/ngViewSpec.js index 9bcd50b385aa..bf134f82d1c8 100644 --- a/test/ngRoute/directive/ngViewSpec.js +++ b/test/ngRoute/directive/ngViewSpec.js @@ -767,8 +767,7 @@ describe('ngView animations', function() { $rootScope.klass = 'boring'; $rootScope.$digest(); - expect($animate.queue.shift().event).toBe('removeClass'); - expect($animate.queue.shift().event).toBe('addClass'); + expect($animate.queue.shift().event).toBe('setClass'); expect(item.hasClass('classy')).toBe(false); expect(item.hasClass('boring')).toBe(true); From e0a6e9c257f8eab2edfac921ea4d2797307e5065 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Fri, 14 Feb 2014 15:53:57 -0800 Subject: [PATCH 040/123] style(animate): remove ws --- src/ngAnimate/animate.js | 2 +- test/ngAnimate/animateSpec.js | 42 +++++++++++++++++------------------ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index 28a1510a6ef3..0ecb65156094 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -1375,7 +1375,7 @@ angular.module('ngAnimate', ['ng']) event.stopPropagation(); var ev = event.originalEvent || event; var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now(); - + /* Firefox (or possibly just Gecko) likes to not round values up * when a ms measurement is used for the animation */ var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES)); diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index d11cfa9ece3d..b732d7b501da 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -482,7 +482,7 @@ describe("ngAnimate", function() { element.append(child); child.attr('style', 'width: 20px'); - + $animate.addClass(child, 'ng-hide'); $animate.leave(child); $rootScope.$digest(); @@ -490,11 +490,11 @@ describe("ngAnimate", function() { if($sniffer.transitions) { $animate.triggerReflow(); - //this is to verify that the existing style is appended with a semicolon automatically + //this is to verify that the existing style is appended with a semicolon automatically expect(child.attr('style')).toMatch(/width: 20px;.*?/i); browserTrigger(child,'transitionend', { timeStamp: Date.now() + 1000, elapsedTime: 1 }); } - + expect(child.attr('style')).toMatch(/width: 20px/i); })); @@ -523,7 +523,7 @@ describe("ngAnimate", function() { var completed = false; $animate.enter(child, element, null, function() { - completed = true; + completed = true; }); $rootScope.$digest(); @@ -783,19 +783,19 @@ describe("ngAnimate", function() { $animate.enabled(true); ss.addRule('.real-animation.ng-enter, .real-animation.ng-leave, .real-animation-fake.ng-enter, .real-animation-fake.ng-leave', - '-webkit-animation:1s my_animation;' + + '-webkit-animation:1s my_animation;' + 'animation:1s my_animation;'); ss.addRule('.real-animation.ng-enter-stagger, .real-animation.ng-leave-stagger', '-webkit-animation-delay:0.1s;' + '-webkit-animation-duration:0s;' + - 'animation-delay:0.1s;' + + 'animation-delay:0.1s;' + 'animation-duration:0s;'); ss.addRule('.fake-animation.ng-enter-stagger, .fake-animation.ng-leave-stagger', '-webkit-animation-delay:0.1s;' + '-webkit-animation-duration:1s;' + - 'animation-delay:0.1s;' + + 'animation-delay:0.1s;' + 'animation-duration:1s;'); var container = $compile(html('
'))($rootScope); @@ -850,7 +850,7 @@ describe("ngAnimate", function() { $animate.enabled(true); ss.addRule('.stagger-animation.ng-enter, .stagger-animation.ng-leave', - '-webkit-animation:my_animation 1s 1s, your_animation 1s 2s;' + + '-webkit-animation:my_animation 1s 1s, your_animation 1s 2s;' + 'animation:my_animation 1s 1s, your_animation 1s 2s;'); ss.addRule('.stagger-animation.ng-enter-stagger, .stagger-animation.ng-leave-stagger', @@ -1074,19 +1074,19 @@ describe("ngAnimate", function() { $animate.enabled(true); ss.addRule('.real-animation.ng-enter, .real-animation.ng-leave, .real-animation-fake.ng-enter, .real-animation-fake.ng-leave', - '-webkit-transition:1s linear all;' + + '-webkit-transition:1s linear all;' + 'transition:1s linear all;'); ss.addRule('.real-animation.ng-enter-stagger, .real-animation.ng-leave-stagger', '-webkit-transition-delay:0.1s;' + '-webkit-transition-duration:0s;' + - 'transition-delay:0.1s;' + + 'transition-delay:0.1s;' + 'transition-duration:0s;'); ss.addRule('.fake-animation.ng-enter-stagger, .fake-animation.ng-leave-stagger', '-webkit-transition-delay:0.1s;' + '-webkit-transition-duration:1s;' + - 'transition-delay:0.1s;' + + 'transition-delay:0.1s;' + 'transition-duration:1s;'); var container = $compile(html('
'))($rootScope); @@ -1142,7 +1142,7 @@ describe("ngAnimate", function() { $animate.enabled(true); ss.addRule('.stagger-animation.ng-enter, .ani.ng-leave', - '-webkit-transition:1s linear color 2s, 3s linear font-size 4s;' + + '-webkit-transition:1s linear color 2s, 3s linear font-size 4s;' + 'transition:1s linear color 2s, 3s linear font-size 4s;'); ss.addRule('.stagger-animation.ng-enter-stagger, .ani.ng-leave-stagger', @@ -1234,7 +1234,7 @@ describe("ngAnimate", function() { it("should not allow the closing animation to close off a successive animation midway", inject(function($animate, $rootScope, $compile, $sniffer, $timeout) { - + if (!$sniffer.transitions) return; ss.addRule('.some-class-add', '-webkit-transition:5s linear all;' + @@ -1272,9 +1272,9 @@ describe("ngAnimate", function() { $animate.enabled(true); ss.addRule('.stagger-animation.ng-enter, .stagger-animation.ng-leave', - '-webkit-animation:my_animation 1s 1s, your_animation 1s 2s;' + + '-webkit-animation:my_animation 1s 1s, your_animation 1s 2s;' + 'animation:my_animation 1s 1s, your_animation 1s 2s;' + - '-webkit-transition:1s linear all 1s;' + + '-webkit-transition:1s linear all 1s;' + 'transition:1s linear all 1s;'); ss.addRule('.stagger-animation.ng-enter-stagger, .stagger-animation.ng-leave-stagger', @@ -1544,7 +1544,7 @@ describe("ngAnimate", function() { expect(steps.shift()).toEqual(['close', 'klass', 'addClass']); expect(steps.shift()).toEqual(['done', 'klass', 'addClass']); - })); + })); it('should fire the DOM callbacks even if no animation is rendered', inject(function($animate, $rootScope, $compile, $sniffer, $rootElement, $timeout) { @@ -1572,7 +1572,7 @@ describe("ngAnimate", function() { expect(steps.shift()).toEqual(['before', 'ng-enter', 'enter']); expect(steps.shift()).toEqual(['after', 'ng-enter', 'enter']); - })); + })); it('should not fire DOM callbacks on the element being animated unless registered', inject(function($animate, $rootScope, $compile, $sniffer, $rootElement, $timeout) { @@ -2551,7 +2551,7 @@ describe("ngAnimate", function() { } }); }); - + inject(function($compile, $rootScope, $animate, $timeout, $rootElement) { $animate.enabled(true); @@ -2832,7 +2832,7 @@ describe("ngAnimate", function() { it('should perform pre and post animations', function() { - var steps = []; + var steps = []; module(function($animateProvider) { $animateProvider.register('.class-animate', function() { return { @@ -2861,7 +2861,7 @@ describe("ngAnimate", function() { it('should treat the leave event always as a before event and discard the beforeLeave function', function() { - var parentID, steps = []; + var parentID, steps = []; module(function($animateProvider) { $animateProvider.register('.animate', function() { return { @@ -3080,7 +3080,7 @@ describe("ngAnimate", function() { var element = $compile('
' + '
' + + ' class="special">
' + '
')($rootScope); ss.addRule('.special', '-webkit-transition:1s linear all;' + From 211facca6aaf28e758b05a7a57d97bbe3077fd0e Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Fri, 14 Feb 2014 13:29:51 -0800 Subject: [PATCH 041/123] docs(changelog): release notes for 1.2.13 --- CHANGELOG.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 643c016a21dd..777fedb1a0b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,58 @@ + +# 1.2.13 romantic-transclusion (2014-02-14) + + +## Bug Fixes + +- **$animate:** ensure $animate doesn't break natural CSS transitions + ([4f84f6b3](https://github.com/angular/angular.js/commit/4f84f6b3e4210ae1eb14728a46d43dd961700a0c), + [#6019](https://github.com/angular/angular.js/issues/6019)) +- **$compile:** + - ensure element transclusion directives are linked with comment element + ([e7338d3f](https://github.com/angular/angular.js/commit/e7338d3f27e8824196136a18e1c3e0fcf51a0e28), + [#6006](https://github.com/angular/angular.js/issues/6006), [#6101](https://github.com/angular/angular.js/issues/6101)) + - support templates with table content root nodes + ([e7338d3f](https://github.com/angular/angular.js/commit/31c450bcee53d0a3827b7e0a611e9013b2496506), + [#2848](https://github.com/angular/angular.js/issues/2848), [#1459](https://github.com/angular/angular.js/issues/1459), [#3647](https://github.com/angular/angular.js/issues/3647), [#3241](https://github.com/angular/angular.js/issues/3241)) +- **input:** + - don't apply textInput to `` + ([a9fcb0d0](https://github.com/angular/angular.js/commit/a9fcb0d0fc6456f80501b8820d02b04d7c15b6d6), + [#6247](https://github.com/angular/angular.js/issues/6247), [#6231](https://github.com/angular/angular.js/issues/6231)) + - setViewValue on compositionend + ([2b730271](https://github.com/angular/angular.js/commit/2b7302713674506fdbcdc396c38f18dcb90dee8c), + [#6058](https://github.com/angular/angular.js/issues/6058), [#5433](https://github.com/angular/angular.js/issues/5433)) + + +## Features + +- **filterFilter:** support deeply nested predicate objects + ([b4eed8ad](https://github.com/angular/angular.js/commit/b4eed8ad94ce9719540462c1ee969dfd3c6b2355), + [#6215](https://github.com/angular/angular.js/issues/6215)) + + +## Breaking Changes + +- **$animate:** + - due to [4f84f6b3](https://github.com/angular/angular.js/commit/4f84f6b3e4210ae1eb14728a46d43dd961700a0c), + ngClass and {{ class }} will now call the `setClass` + animation callback instead of addClass / removeClass when both a + addClass/removeClass operation is being executed on the element during the animation. + + Please include the setClass animation callback as well as addClass and removeClass within + your JS animations to work with ngClass and {{ class }} directives. + + + - due to [cf5e463a](https://github.com/angular/angular.js/commit/cf5e463abd2c23f62e9c2e6361e6c53048c8910e), + Both the `$animate:before` and `$animate:after` DOM events must be now + registered prior to the $animate operation taking place. The `$animate:close` event + can be registered anytime afterwards. + + DOM callbacks used to fired for each and every animation operation that occurs within the + $animate service provided in the ngAnimate module. This may end up slowing down an + application if 100s of elements are being inserted into the page. Therefore after this + change callbacks are only fired if registered on the element being animated. + + # 1.2.12 cauliflower-eradication (2014-02-07) From 037da43d2aee2e698feb6e156dbcac8ecdc218ca Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 14 Feb 2014 17:30:52 -0800 Subject: [PATCH 042/123] chore(release): update cdn version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06ec83634851..df99ab391a4f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "angularjs", "branchVersion": "1.2.*", - "cdnVersion": "1.2.12", + "cdnVersion": "1.2.13", "repository": { "type": "git", "url": "https://github.com/angular/angular.js.git" From 8fdfb88667f45a71f28ceeeb67b5acf0275ae2f0 Mon Sep 17 00:00:00 2001 From: Sergei Z Date: Fri, 14 Feb 2014 13:54:41 +0200 Subject: [PATCH 043/123] fix(numberFilter): convert all non-finite/non-numbers/non-numeric strings to the empty string The previous code for filtering out non-finite numbers was broken, as it would convert `null` to `0`, as well as arrays. This change fixes this by converting null/undefined/NaN/Infinity/any object to the empty string. Closes #6188 Closes #6261 --- src/ng/filter/filters.js | 2 +- test/ng/filter/filtersSpec.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index 15cc6e33b270..b8cc655c3630 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -118,7 +118,7 @@ function numberFilter($locale) { var DECIMAL_SEP = '.'; function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { - if (isNaN(number) || !isFinite(number)) return ''; + if (number == null || !isFinite(number) || isObject(number)) return ''; var isNegative = number < 0; number = Math.abs(number); diff --git a/test/ng/filter/filtersSpec.js b/test/ng/filter/filtersSpec.js index 2d648b652984..66e3139709f2 100644 --- a/test/ng/filter/filtersSpec.js +++ b/test/ng/filter/filtersSpec.js @@ -128,6 +128,11 @@ describe('filters', function() { expect(number(1234)).toEqual('1,234'); expect(number(1234.5678)).toEqual('1,234.568'); expect(number(Number.NaN)).toEqual(''); + expect(number(null)).toEqual(''); + expect(number({})).toEqual(''); + expect(number([])).toEqual(''); + expect(number(+Infinity)).toEqual(''); + expect(number(-Infinity)).toEqual(''); expect(number("1234.5678")).toEqual('1,234.568'); expect(number(1/0)).toEqual(""); expect(number(1, 2)).toEqual("1.00"); From ce39290e715931a9ccbae5bc5e330d45d9df41ba Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 6 Feb 2014 13:33:42 +0000 Subject: [PATCH 044/123] docs(bike-shed-migration): Add missing module tag The generator is able to imply the module from the containing folder for most files but these are in the ng module but are stored at the root folder. --- src/Angular.js | 22 ++++++++++++++++++++++ src/AngularPublic.js | 1 + src/jqLite.js | 1 + src/loader.js | 15 +++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/src/Angular.js b/src/Angular.js index dec397cf485b..723a513c421c 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -90,6 +90,7 @@ /** * @ngdoc function * @name angular.lowercase + * @module ng * @function * * @description Converts the specified string to lowercase. @@ -102,6 +103,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; /** * @ngdoc function * @name angular.uppercase + * @module ng * @function * * @description Converts the specified string to uppercase. @@ -185,6 +187,7 @@ function isArrayLike(obj) { /** * @ngdoc function * @name angular.forEach + * @module ng * @function * * @description @@ -313,6 +316,7 @@ function setHashKey(obj, h) { /** * @ngdoc function * @name angular.extend + * @module ng * @function * * @description @@ -349,6 +353,7 @@ function inherit(parent, extra) { /** * @ngdoc function * @name angular.noop + * @module ng * @function * * @description @@ -368,6 +373,7 @@ noop.$inject = []; /** * @ngdoc function * @name angular.identity + * @module ng * @function * * @description @@ -389,6 +395,7 @@ function valueFn(value) {return function() {return value;};} /** * @ngdoc function * @name angular.isUndefined + * @module ng * @function * * @description @@ -403,6 +410,7 @@ function isUndefined(value){return typeof value === 'undefined';} /** * @ngdoc function * @name angular.isDefined + * @module ng * @function * * @description @@ -417,6 +425,7 @@ function isDefined(value){return typeof value !== 'undefined';} /** * @ngdoc function * @name angular.isObject + * @module ng * @function * * @description @@ -432,6 +441,7 @@ function isObject(value){return value != null && typeof value === 'object';} /** * @ngdoc function * @name angular.isString + * @module ng * @function * * @description @@ -446,6 +456,7 @@ function isString(value){return typeof value === 'string';} /** * @ngdoc function * @name angular.isNumber + * @module ng * @function * * @description @@ -460,6 +471,7 @@ function isNumber(value){return typeof value === 'number';} /** * @ngdoc function * @name angular.isDate + * @module ng * @function * * @description @@ -476,6 +488,7 @@ function isDate(value){ /** * @ngdoc function * @name angular.isArray + * @module ng * @function * * @description @@ -492,6 +505,7 @@ function isArray(value) { /** * @ngdoc function * @name angular.isFunction + * @module ng * @function * * @description @@ -560,6 +574,7 @@ var trim = (function() { /** * @ngdoc function * @name angular.isElement + * @module ng * @function * * @description @@ -670,6 +685,7 @@ function isLeafNode (node) { /** * @ngdoc function * @name angular.copy + * @module ng * @function * * @description @@ -785,6 +801,7 @@ function shallowCopy(src, dst) { /** * @ngdoc function * @name angular.equals + * @module ng * @function * * @description @@ -871,6 +888,7 @@ function sliceArgs(args, startIndex) { /** * @ngdoc function * @name angular.bind + * @module ng * @function * * @description @@ -926,6 +944,7 @@ function toJsonReplacer(key, value) { /** * @ngdoc function * @name angular.toJson + * @module ng * @function * * @description @@ -945,6 +964,7 @@ function toJson(obj, pretty) { /** * @ngdoc function * @name angular.fromJson + * @module ng * @function * * @description @@ -1104,6 +1124,7 @@ function encodeUriQuery(val, pctEncodeSpaces) { /** * @ngdoc directive * @name ng.directive:ngApp + * @module ng * * @element ANY * @param {angular.Module} ngApp an optional application @@ -1193,6 +1214,7 @@ function angularInit(element, bootstrap) { /** * @ngdoc function * @name angular.bootstrap + * @module ng * @description * Use this function to manually start up angular application. * diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 14fe25aec20a..ed57b1946d6f 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -79,6 +79,7 @@ /** * @ngdoc property * @name angular.version + * @module ng * @description * An object that contains information about the current AngularJS version. This object has the * following properties: diff --git a/src/jqLite.js b/src/jqLite.js index 6056730ac7a8..ae525b888bcf 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -15,6 +15,7 @@ /** * @ngdoc function * @name angular.element + * @module ng * @function * * @description diff --git a/src/loader.js b/src/loader.js index 787fcbfa6a77..d41ff5939b18 100644 --- a/src/loader.js +++ b/src/loader.js @@ -3,6 +3,7 @@ /** * @ngdoc interface * @name angular.Module + * @module ng * @description * * Interface for configuring angular {@link angular.module modules}. @@ -29,6 +30,7 @@ function setupModuleLoader(window) { /** * @ngdoc function * @name angular.module + * @module ng * @description * * The `angular.module` is a global place for creating, registering and retrieving Angular @@ -111,6 +113,7 @@ function setupModuleLoader(window) { /** * @ngdoc property * @name angular.Module#requires + * @module ng * @propertyOf angular.Module * @returns {Array.} List of module names which must be loaded before this module. * @description @@ -122,6 +125,7 @@ function setupModuleLoader(window) { /** * @ngdoc property * @name angular.Module#name + * @module ng * @propertyOf angular.Module * @returns {string} Name of the module. * @description @@ -132,6 +136,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#provider + * @module ng * @methodOf angular.Module * @param {string} name service name * @param {Function} providerType Construction function for creating new instance of the @@ -144,6 +149,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#factory + * @module ng * @methodOf angular.Module * @param {string} name service name * @param {Function} providerFunction Function for creating new instance of the service. @@ -155,6 +161,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#service + * @module ng * @methodOf angular.Module * @param {string} name service name * @param {Function} constructor A constructor function that will be instantiated. @@ -166,6 +173,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#value + * @module ng * @methodOf angular.Module * @param {string} name service name * @param {*} object Service instance object. @@ -177,6 +185,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#constant + * @module ng * @methodOf angular.Module * @param {string} name constant name * @param {*} object Constant value. @@ -189,6 +198,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#animation + * @module ng * @methodOf angular.Module * @param {string} name animation name * @param {Function} animationFactory Factory function for creating new instance of an @@ -223,6 +233,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#filter + * @module ng * @methodOf angular.Module * @param {string} name Filter name. * @param {Function} filterFactory Factory function for creating new instance of filter. @@ -234,6 +245,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#controller + * @module ng * @methodOf angular.Module * @param {string|Object} name Controller name, or an object map of controllers where the * keys are the names and the values are the constructors. @@ -246,6 +258,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#directive + * @module ng * @methodOf angular.Module * @param {string|Object} name Directive name, or an object map of directives where the * keys are the names and the values are the factories. @@ -259,6 +272,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#config + * @module ng * @methodOf angular.Module * @param {Function} configFn Execute this function on module load. Useful for service * configuration. @@ -270,6 +284,7 @@ function setupModuleLoader(window) { /** * @ngdoc method * @name angular.Module#run + * @module ng * @methodOf angular.Module * @param {Function} initializationFn Execute this function after injector creation. * Useful for application initialization. From f02e35dce728f6bec4a1e1cbcc05a0191261b382 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 6 Feb 2014 13:33:42 +0000 Subject: [PATCH 045/123] docs(bike-shed-migration): fix up links outside the domain It is safer to use markdown style links and save jsdoc style links for internal links and code references --- docs/content/api/index.ngdoc | 6 +- docs/content/error/sce/iequirks.ngdoc | 4 +- docs/content/error/sce/insecurl.ngdoc | 6 +- docs/content/guide/bootstrap.ngdoc | 2 +- docs/content/guide/controller.ngdoc | 138 +++++++++--------- .../content/guide/dev_guide.e2e-testing.ngdoc | 6 +- .../guide/dev_guide.services.$location.ngdoc | 18 +-- ...guide.services.injecting_controllers.ngdoc | 2 +- ...uide.services.understanding_services.ngdoc | 2 +- .../guide/dev_guide.unit-testing.ngdoc | 7 +- docs/content/guide/di.ngdoc | 14 +- docs/content/guide/directive.ngdoc | 6 +- docs/content/guide/filter.ngdoc | 2 +- docs/content/guide/i18n.ngdoc | 26 ++-- docs/content/guide/introduction.ngdoc | 4 +- docs/content/misc/contribute.ngdoc | 21 ++- docs/content/misc/faq.ngdoc | 14 +- docs/content/misc/started.ngdoc | 16 +- docs/content/tutorial/step_00.ngdoc | 3 +- docs/content/tutorial/step_01.ngdoc | 3 +- docs/content/tutorial/step_02.ngdoc | 14 +- docs/content/tutorial/step_03.ngdoc | 7 +- docs/content/tutorial/step_04.ngdoc | 6 +- docs/content/tutorial/step_05.ngdoc | 7 +- docs/content/tutorial/step_06.ngdoc | 8 +- docs/content/tutorial/step_07.ngdoc | 13 +- docs/content/tutorial/step_08.ngdoc | 8 +- docs/content/tutorial/step_09.ngdoc | 4 +- docs/content/tutorial/step_10.ngdoc | 8 +- docs/content/tutorial/step_11.ngdoc | 12 +- docs/content/tutorial/step_12.ngdoc | 12 +- docs/content/tutorial/the_end.ngdoc | 5 +- 32 files changed, 181 insertions(+), 223 deletions(-) diff --git a/docs/content/api/index.ngdoc b/docs/content/api/index.ngdoc index c563cc4347f1..4e2e03fecff6 100644 --- a/docs/content/api/index.ngdoc +++ b/docs/content/api/index.ngdoc @@ -32,9 +32,9 @@ This module is provided by default and contains the core components of AngularJS

Some examples include: - {@link ng.directive:ngClick ngClick}, - {@link ng.directive:ngInclude ngInclude}, - {@link ng.directive:ngRepeat ngRepeat}, + {@link directive:ngClick ngClick}, + {@link directive:ngInclude ngInclude}, + {@link directive:ngRepeat ngRepeat}, etc…

diff --git a/docs/content/error/sce/iequirks.ngdoc b/docs/content/error/sce/iequirks.ngdoc index b63e540bebde..8713630b845b 100644 --- a/docs/content/error/sce/iequirks.ngdoc +++ b/docs/content/error/sce/iequirks.ngdoc @@ -6,7 +6,9 @@ This error occurs when you are using AngularJS with {@link api/ng.$sce Strict Contextual Escaping (SCE)} mode enabled (the default) on IE8 or lower in quirks mode. In this mode, IE8 allows one to execute arbitrary javascript by the use of the `expression()` syntax and is not supported. -Refer {@link http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx MSDN Blogs > IEBlog > Ending Expressions} to learn more about them. +Refer +[MSDN Blogs > IEBlog > Ending Expressions](http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx) +to learn more about them. To resolve this error please specify the proper doctype at the top of your main html document: diff --git a/docs/content/error/sce/insecurl.ngdoc b/docs/content/error/sce/insecurl.ngdoc index e7c610108beb..c8cc7a4cfa20 100644 --- a/docs/content/error/sce/insecurl.ngdoc +++ b/docs/content/error/sce/insecurl.ngdoc @@ -19,8 +19,8 @@ api/ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelist}/ {@link api/ng.$sceDelegateProvider#methods_resourceUrlBlacklist blacklist} or wrap the URL with a call to {@link api/ng.$sce#methods_trustAsResourceUrl $sce.trustAsResourceUrl}. -**Note**: The browser's {@link -https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest Same Origin -Policy} and {@link http://www.w3.org/TR/cors/ Cross-Origin Resource Sharing (CORS)} policy apply +**Note**: The browser's [Same Origin +Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest) and +[Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/) policy apply that may further restrict whether the template is successfully loaded. (e.g. neither cross-domain requests won't work on all browsers nor `file://` requests on some browsers) diff --git a/docs/content/guide/bootstrap.ngdoc b/docs/content/guide/bootstrap.ngdoc index 5b83f9b349a6..058ae46d2612 100644 --- a/docs/content/guide/bootstrap.ngdoc +++ b/docs/content/guide/bootstrap.ngdoc @@ -25,7 +25,7 @@ initialization. * Place the `script` tag at the bottom of the page. Placing script tags at the end of the page improves app load time because the HTML loading is not blocked by loading of the `angular.js` - script. You can get the latest bits from {@link http://code.angularjs.org}. Please don't link + script. You can get the latest bits from http://code.angularjs.org. Please don't link your production code to this URL, as it will expose a security hole on your site. For experimental development linking to our site is fine. * Choose: `angular-[version].js` for a human-readable file, suitable for development and diff --git a/docs/content/guide/controller.ngdoc b/docs/content/guide/controller.ngdoc index a5878fb752e4..77e0ac50de80 100644 --- a/docs/content/guide/controller.ngdoc +++ b/docs/content/guide/controller.ngdoc @@ -28,36 +28,36 @@ is registered. The following example shows a very simple constructor function for a Controller, `GreetingCtrl`, which attaches a `greeting` property containing the string `'Hola!'` to the `$scope`: -
+```
     function GreetingCtrl($scope) {
         $scope.greeting = 'Hola!';
     }
-
+``` Once the Controller has been attached to the DOM, the `greeting` property can be data-bound to the template: -
-    
- {{ greeting }} -
-
+``` +
+ {{ greeting }} +
+``` **NOTE**: Although Angular allows you to create Controller functions in the global scope, this is not recommended. In a real application you should use the `.controller` method of your {@link module Angular Module} for your application as follows: -
-    var myApp = angular.module('myApp',[]);
+```
+var myApp = angular.module('myApp',[]);
 
-    myApp.controller('GreetingCtrl', ['$scope', function($scope) {
-        $scope.greeting = 'Hola!';
-    }]);
-
+myApp.controller('GreetingCtrl', ['$scope', function($scope) { + $scope.greeting = 'Hola!'; +}]); +``` We have used an **inline injection annotation** to explicitly specify the dependency of the Controller on the `$scope` service provided by Angular. See the guide on -{@link http://docs.angularjs.org/guide/di Dependency Injection} for more information. +[Dependency Injection](http://docs.angularjs.org/guide/di) for more information. # Adding Behavior to a Scope Object @@ -68,22 +68,22 @@ then available to be called from the template/view. The following example uses a Controller to add a method to the scope, which doubles a number: -
-    var myApp = angular.module('myApp',[]);
+```
+var myApp = angular.module('myApp',[]);
 
-    myApp.controller('DoubleCtrl', ['$scope', function($scope) {
-        $scope.double = function(value) { return value * 2; };
-    }]);
-
+myApp.controller('DoubleCtrl', ['$scope', function($scope) { + $scope.double = function(value) { return value * 2; }; +}]); +``` Once the Controller has been attached to the DOM, the `double` method can be invoked in an Angular expression in the template: -
-    
- Two times equals {{ double(num) }} -
-
+``` +
+ Two times equals {{ double(num) }} +
+``` As discussed in the {@link concepts Concepts} section of this guide, any objects (or primitives) assigned to the scope become model properties. Any methods assigned to @@ -134,30 +134,30 @@ The message in our template contains a binding to the `spice` model, which by de string "very". Depending on which button is clicked, the `spice` model is set to `chili` or `jalapeño`, and the message is automatically updated by data-binding. - - + +

The food is {{spice}} spicy!

- -
-
+
+ + var myApp = angular.module('spicyApp1', []); + + myApp.controller('SpicyCtrl', ['$scope', function($scope){ + $scope.spice = 'very'; + + $scope.chiliSpicy = function() { + $scope.spice = 'chili'; + }; + + $scope.jalapenoSpicy = function() { + $scope.spice = 'jalapeño'; + }; + }]); + + Things to notice in the example above: @@ -175,15 +175,16 @@ its children). Controller methods can also take arguments, as demonstrated in the following variation of the previous example. - - + +

The food is {{spice}} spicy!

- -
-
+ + Notice that the `SpicyCtrl` Controller now defines just one method called `spicy`, which takes one argument called `spice`. The template then refers to this Controller method and passes in a string @@ -209,11 +209,11 @@ It is common to attach Controllers at different levels of the DOM hierarchy. Si {@link api/ng.directive:ngController ng-controller} directive creates a new child scope, we get a hierarchy of scopes that inherit from each other. The `$scope` that each Controller receives will have access to properties and methods defined by Controllers higher up the hierarchy. -See {@link https://github.com/angular/angular.js/wiki/Understanding-Scopes Understanding Scopes} for +See [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes) for more information about scope inheritance. - - + +

Good {{timeOfDay}}, {{name}}!

@@ -227,13 +227,14 @@ more information about scope inheritance.
- - -
-
+ + Notice how we nested three `ng-controller` directives in our template. This will result in four scopes being created for our view: @@ -270,7 +270,7 @@ Although there are many ways to test a Controller, one of the best conventions, involves injecting the {@link api/ng.$rootScope $rootScope} and {@link api/ng.$controller $controller}: **Controller Definition:** -
+```
     var myApp = angular.module('myApp',[]);
 
     myApp.controller('MyController', function($scope) {
@@ -279,10 +279,10 @@ involves injecting the {@link api/ng.$rootScope $rootScope} and {@link api/ng.$c
                        {"name":"habanero", "spiceness":"LAVA HOT!!"}];
       $scope.spice = "habanero";
     });
-
+``` **Controller Test:** -
+```
 describe('myController function', function() {
 
   describe('myController', function() {
@@ -304,13 +304,13 @@ describe('myController function', function() {
     });
   });
 });
-
+``` If you need to test a nested Controller you need to create the same scope hierarchy in your test that exists in the DOM: -
+```
 describe('state', function() {
     var mainScope, childScope, grandChildScope;
 
@@ -334,7 +334,7 @@ describe('state', function() {
         expect(grandChildScope.name).toBe('Gingerbreak Baby');
     });
 });
-
+``` diff --git a/docs/content/guide/dev_guide.e2e-testing.ngdoc b/docs/content/guide/dev_guide.e2e-testing.ngdoc index ce4e586c07d8..e0d3f61dc983 100644 --- a/docs/content/guide/dev_guide.e2e-testing.ngdoc +++ b/docs/content/guide/dev_guide.e2e-testing.ngdoc @@ -55,7 +55,7 @@ the only button on the page, and then it verifies that there are 10 items listed The API section below lists the available commands and expectations for the Runner. # API -Source: {@link https://github.com/angular/angular.js/blob/master/src/ngScenario/dsl.js} +Source: https://github.com/angular/angular.js/blob/master/src/ngScenario/dsl.js ## pause() Pauses the execution of the tests until you call `resume()` in the console (or click the resume @@ -188,7 +188,7 @@ Executes the `method` passing in `key` and `value` on the element matching the g Matchers are used in combination with the `expect(...)` function as described above and can be negated with `not()`. For instance: `expect(element('h1').text()).not().toEqual('Error')`. -Source: {@link https://github.com/angular/angular.js/blob/master/src/ngScenario/matchers.js} +Source: https://github.com/angular/angular.js/blob/master/src/ngScenario/matchers.js
 // value and Object comparison following the rules of angular.equals().
@@ -222,7 +222,7 @@ expect(value).toBeGreaterThan(expected)
 
# Example -See the {@link https://github.com/angular/angular-seed angular-seed} project for more examples. +See the [angular-seed](https://github.com/angular/angular-seed) project for more examples. ## Conditional actions with element(...).query(fn) diff --git a/docs/content/guide/dev_guide.services.$location.ngdoc b/docs/content/guide/dev_guide.services.$location.ngdoc index 08fabe33e9e3..04bf23eb0f9b 100644 --- a/docs/content/guide/dev_guide.services.$location.ngdoc +++ b/docs/content/guide/dev_guide.services.$location.ngdoc @@ -4,8 +4,7 @@ # What does it do? -The `$location` service parses the URL in the browser address bar (based on the {@link -https://developer.mozilla.org/en/window.location window.location}) and makes the URL available to +The `$location` service parses the URL in the browser address bar (based on the [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL available to your application. Changes to the URL in the address bar are reflected into $location service and changes to $location are reflected into the browser address bar. @@ -145,7 +144,7 @@ unless `replace()` is called again. ### Setters and character encoding You can pass special characters to `$location` service and it will encode them according to rules -specified in {@link http://www.ietf.org/rfc/rfc3986.txt RFC 3986}. When you access the methods: +specified in [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt). When you access the methods: - All values that are passed to `$location` setter methods, `path()`, `search()`, `hash()`, are encoded. @@ -160,7 +159,7 @@ encoded. `$location` service has two configuration modes which control the format of the URL in the browser address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the -HTML5 {@link http://www.w3.org/TR/html5/browsers.html#history History API}. Applications use the same API in +HTML5 [History API](http://www.w3.org/TR/html5/history.html). Applications use the same API in both modes and the `$location` service will work with appropriate URL segments and browser APIs to facilitate the browser URL change and history management. @@ -242,8 +241,8 @@ your document: This will cause crawler bot to request links with `_escaped_fragment_` param so that your server can recognize the crawler and serve a HTML snapshots. For more information about this technique, -see {@link http://code.google.com/web/ajaxcrawling/docs/specification.html Making AJAX Applications -Crawlable}. +see [Making AJAX Applications +Crawlable](http://code.google.com/web/ajaxcrawling/docs/specification.html). ## HTML5 mode @@ -346,8 +345,8 @@ meta tag to the HEAD section of your document: This statement causes a crawler to request links with an empty `_escaped_fragment_` parameter so that your server can recognize the crawler and serve it HTML snapshots. For more information about this -technique, see {@link http://code.google.com/web/ajaxcrawling/docs/specification.html Making AJAX -Applications Crawlable}. +technique, see [Making AJAX +Applications Crawlable](http://code.google.com/web/ajaxcrawling/docs/specification.html). ### Relative links @@ -625,8 +624,7 @@ then uses the information it obtains to compose hashbang URLs (such as ## Two-way binding to $location -The Angular's compiler currently does not support two-way binding for methods (see {@link -https://github.com/angular/angular.js/issues/404 issue}). If you should require two-way binding +The Angular's compiler currently does not support two-way binding for methods (see [issue](https://github.com/angular/angular.js/issues/404)). If you should require two-way binding to the $location object (using {@link api/ng.directive:input.text ngModel} directive on an input field), you will need to specify an extra model property (e.g. `locationPath`) with two watchers which push $location updates in both directions. For diff --git a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc index 3dce76721ad7..b24dec6e6917 100644 --- a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc +++ b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc @@ -105,7 +105,7 @@ function myController($scope, notify) { -However, if you plan to {@link http://en.wikipedia.org/wiki/Minification_(programming) minify} your +However, if you plan to [minify](http://en.wikipedia.org/wiki/Minification_(programming)) your code, your variable names will get renamed in which case you will still need to explicitly specify dependencies with the `$inject` property. diff --git a/docs/content/guide/dev_guide.services.understanding_services.ngdoc b/docs/content/guide/dev_guide.services.understanding_services.ngdoc index aebd2fa569ef..bb02f5413237 100644 --- a/docs/content/guide/dev_guide.services.understanding_services.ngdoc +++ b/docs/content/guide/dev_guide.services.understanding_services.ngdoc @@ -18,7 +18,7 @@ care of the rest. The Angular injector subsystem is in charge of service instant of dependencies, and provision of dependencies to components as requested. Angular injects dependencies using -{@link http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/ "constructor" injection}. +["constructor" injection](http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/). The dependency is passed to the component's factory/constructor function. Because JavaScript is a dynamically typed language, Angular's dependency injection subsystem cannot use static types to identify service dependencies. For this reason a component must, explicitly, define its dependencies by using one of the diff --git a/docs/content/guide/dev_guide.unit-testing.ngdoc b/docs/content/guide/dev_guide.unit-testing.ngdoc index e73dc2d68e31..16c1c99e30fa 100644 --- a/docs/content/guide/dev_guide.unit-testing.ngdoc +++ b/docs/content/guide/dev_guide.unit-testing.ngdoc @@ -97,9 +97,8 @@ function MyClass() { While no new dependency instance is created, it is fundamentally the same as `new` in that no way exists to intercept the call to `global.xhr` for testing purposes, other then through monkey patching. The basic issue for testing is that a global variable needs to be mutated in -order to replace it with call to a mock method. For further explanation of why this is bad see: {@link -http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/ Brittle Global -State & Singletons} +order to replace it with call to a mock method. For further explanation of why this is bad see: [Brittle Global +State & Singletons](http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/) The class above is hard to test since we have to change the global state:
@@ -336,5 +335,5 @@ replaced the content and "lidless, wreathed in flame, 2 times" is present.
 
 
 ## Sample project
-See the {@link https://github.com/angular/angular-seed angular-seed} project for an example.
+See the [angular-seed](https://github.com/angular/angular-seed) project for an example.
 
diff --git a/docs/content/guide/di.ngdoc b/docs/content/guide/di.ngdoc
index b305dd6bcf14..1714e2aa4a52 100644
--- a/docs/content/guide/di.ngdoc
+++ b/docs/content/guide/di.ngdoc
@@ -7,10 +7,10 @@
 Dependency Injection (DI) is a software design pattern that deals with how code gets hold of its
 dependencies.
 
-For in-depth discussion about DI, see {@link http://en.wikipedia.org/wiki/Dependency_injection
-Dependency Injection} at Wikipedia, {@link http://martinfowler.com/articles/injection.html
-Inversion of Control} by Martin Fowler, or read about DI in your favorite software design pattern
-book.
+For in-depth discussion about DI, see
+[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) at Wikipedia,
+[Inversion of Control](http://martinfowler.com/articles/injection.html) by Martin Fowler,
+or read about DI in your favorite software design pattern book.
 
 ## DI in a nutshell
 
@@ -80,8 +80,7 @@ Here is an example of using the injector service:
 
Asking for dependencies solves the issue of hard coding, but it also means that the injector needs -to be passed throughout the application. Passing the injector breaks the {@link -http://en.wikipedia.org/wiki/Law_of_Demeter Law of Demeter}. To remedy this, we turn the +to be passed throughout the application. Passing the injector breaks the [Law of Demeter](http://en.wikipedia.org/wiki/Law_of_Demeter). To remedy this, we turn the dependency lookup responsibility to the injector by declaring the dependencies as in this example:
@@ -133,8 +132,7 @@ function declaration and extracting the parameter names. In the above example `$
 `greeter` are two services which need to be injected into the function.
 
 While straightforward, this method will not work with JavaScript minifiers/obfuscators as they
-rename the method parameter names. This makes this way of annotating only useful for {@link
-http://www.pretotyping.org/ pretotyping}, and demo applications.
+rename the method parameter names. This makes this way of annotating only useful for [pretotyping](http://www.pretotyping.org/), and demo applications.
 
 ### `$inject` Annotation
 
diff --git a/docs/content/guide/directive.ngdoc b/docs/content/guide/directive.ngdoc
index 704dd48357c5..39ada01d83c4 100644
--- a/docs/content/guide/directive.ngdoc
+++ b/docs/content/guide/directive.ngdoc
@@ -32,7 +32,7 @@ When Angular {@link guide/bootstrap bootstraps} your application, the
 For AngularJS, "compilation" means attaching event listeners to the HTML to make it interactive.
 The reason we use the term "compile" is that the recursive process of attaching directives
 mirrors the process of compiling source code in
-{@link http://en.wikipedia.org/wiki/Compiled_languages compiled programming languages}.
+[compiled programming languages](http://en.wikipedia.org/wiki/Compiled_languages).
 
 
 
@@ -55,9 +55,9 @@ The following also **matches** `ngModel`:
 
 Angular **normalizes** an element's tag and attribute name to determine which elements match which
 directives. We typically refer to directives by their case-sensitive
-{@link http://en.wikipedia.org/wiki/CamelCase camelCase} **normalized** name (e.g. `ngModel`).
+[camelCase](http://en.wikipedia.org/wiki/CamelCase) **normalized** name (e.g. `ngModel`).
 However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case
-forms, typically using {@link http://en.wikipedia.org/wiki/Letter_case#Computers dash-delimited}
+forms, typically using [dash-delimited](http://en.wikipedia.org/wiki/Letter_case#Computers)
 attributes on DOM elements (e.g. `ng-model`).
 
 The **normalization** process is as follows:
diff --git a/docs/content/guide/filter.ngdoc b/docs/content/guide/filter.ngdoc
index 30e488339da4..d156009a3edb 100644
--- a/docs/content/guide/filter.ngdoc
+++ b/docs/content/guide/filter.ngdoc
@@ -123,4 +123,4 @@ text upper-case.
 
 ## Testing custom filters
 
-See the {@link http://docs.angularjs.org/tutorial/step_09#test phonecat tutorial} for an example.
+See the [phonecat tutorial](http://docs.angularjs.org/tutorial/step_09#test) for an example.
diff --git a/docs/content/guide/i18n.ngdoc b/docs/content/guide/i18n.ngdoc
index 992458932526..f8e2189dad03 100644
--- a/docs/content/guide/i18n.ngdoc
+++ b/docs/content/guide/i18n.ngdoc
@@ -16,10 +16,10 @@ abstracted bits.
 
 **What level of support for i18n/l10n is currently in Angular?**
 
-Currently, Angular supports i18n/l10n for {@link
-http://docs.angularjs.org/#!/api/ng.filter:date datetime}, {@link
-http://docs.angularjs.org/#!/api/ng.filter:number number} and {@link
-http://docs.angularjs.org/#!/api/ng.filter:currency currency} filters.
+Currently, Angular supports i18n/l10n for
+[datetime](http://docs.angularjs.org/#!/api/ng.filter:date),
+[number](http://docs.angularjs.org/#!/api/ng.filter:number) and
+[currency](http://docs.angularjs.org/#!/api/ng.filter:currency) filters.
 
 Additionally, Angular supports localizable pluralization support provided by the {@link
 api/ng.directive:ngPluralize ngPluralize directive}.
@@ -28,8 +28,8 @@ All localizable Angular components depend on locale-specific rule sets managed b
 api/ng.$locale $locale service}.
 
 For readers who want to jump straight into examples, we have a few web pages that showcase how to
-use Angular filters with various locale rule sets. You can find these examples either on {@link
-https://github.com/angular/angular.js/tree/master/i18n/e2e Github} or in the i18n/e2e folder of
+use Angular filters with various locale rule sets. You can find these examples either on
+[Github](https://github.com/angular/angular.js/tree/master/i18n/e2e) or in the i18n/e2e folder of
 Angular development package.
 
 **What is a locale id?**
@@ -37,13 +37,13 @@ Angular development package.
 A locale is a specific geographical, political, or cultural region. The most commonly used locale
 ID consists of two parts: language code and country code. For example, en-US, en-AU, zh-CN are all
 valid locale IDs that have both language codes and country codes. Because specifying a country code
-in locale ID is optional,  locale IDs such as en, zh,  and sk are also valid. See the {@link
-http://userguide.icu-project.org/locale ICU } website for more information about using locale IDs.
+in locale ID is optional,  locale IDs such as en, zh,  and sk are also valid. See the
+[ICU ](http://userguide.icu-project.org/locale) website for more information about using locale IDs.
 
 **Supported locales in Angular**
 Angular separates number and datetime format rule sets into different files, each file for a
-particular locale. You can find a list of currently supported locales {@link
-https://github.com/angular/angular.js/tree/master/src/ngLocale here}
+particular locale. You can find a list of currently supported locales
+[here](https://github.com/angular/angular.js/tree/master/src/ngLocale)
 # Providing locale rules to Angular
 
 There are two approaches to providing locale rules to Angular:
@@ -90,7 +90,7 @@ because an extra script needs to be loaded.
 
 **Currency symbol "gotcha"**
 
-Angular's {@link http://docs.angularjs.org/#!/api/ng.filter:currency currency filter} allows
+Angular's [currency filter](http://docs.angularjs.org/#!/api/ng.filter:currency) allows
 you to use the default currency symbol from the {@link api/ng.$locale locale service},
 or you can provide the filter with a custom currency symbol. If your app will be used only in one
 locale, it is fine to rely on the default currency symbol. However, if you anticipate that viewers
@@ -103,8 +103,8 @@ containing currency filter: `{{ 1000 | currency }}`, and your app is currently i
 browser will specify the locale as ja, and the balance of '¥1000.00' will be shown instead. This
 will really upset your client.
 
-In this case, you need to override the default currency symbol by providing the {@link
-http://docs.angularjs.org/#!/api/ng.filter:currency currency filter} with a currency symbol as
+In this case, you need to override the default currency symbol by providing the
+[currency filter](http://docs.angularjs.org/#!/api/ng.filter:currency) with a currency symbol as
 a parameter when you configure the filter, for example, {{ 1000 | currency:"USD$"}}. This way,
 Angular will always show a balance of 'USD$1000' and disregard any locale changes.
 
diff --git a/docs/content/guide/introduction.ngdoc b/docs/content/guide/introduction.ngdoc
index 92b9b20f194f..2e83890d2f03 100644
--- a/docs/content/guide/introduction.ngdoc
+++ b/docs/content/guide/introduction.ngdoc
@@ -101,8 +101,8 @@ Angular frees you from the following pains:
     overall flow of the application rather than all of the implementation details.
   * **Writing tons of initialization code just to get started:** Typically you need to write a lot
     of plumbing just to get a basic "Hello World" AJAX app working. With Angular you can bootstrap
-    your app easily using services, which are auto-injected into your application in a {@link
-    http://code.google.com/p/google-guice/ Guice}-like dependency-injection style. This allows you
+    your app easily using services, which are auto-injected into your application in a
+    [Guice](http://code.google.com/p/google-guice/)-like dependency-injection style. This allows you
     to get started developing features quickly. As a bonus, you get full control over the
     initialization process in automated tests.
 
diff --git a/docs/content/misc/contribute.ngdoc b/docs/content/misc/contribute.ngdoc
index bd94f6301855..0e4958704a02 100644
--- a/docs/content/misc/contribute.ngdoc
+++ b/docs/content/misc/contribute.ngdoc
@@ -23,24 +23,24 @@ for how to contribute your own code to AngularJS.
 Before you can build AngularJS, you must install and configure the following dependencies on your
 machine:
 
-* {@link http://git-scm.com/ Git}: The {@link https://help.github.com/articles/set-up-git Github Guide to
-Installing Git} is a good source of information.
+* [Git](http://git-scm.com/): The [Github Guide to
+Installing Git](https://help.github.com/articles/set-up-git) is a good source of information.
 
-* {@link http://nodejs.org Node.js}: We use Node to generate the documentation, run a
+* [Node.js](http://nodejs.org): We use Node to generate the documentation, run a
 development web server, run tests, and generate distributable files. Depending on your system, you can install Node either from source or as a
 pre-packaged bundle.
 
-* {@link http://www.java.com Java}: We minify JavaScript using our
-{@link https://developers.google.com/closure/ Closure Tools} jar. Make sure you have Java (version 6 or higher) installed
-and included in your {@link http://docs.oracle.com/javase/tutorial/essential/environment/paths.html PATH} variable.
+* [Java](http://www.java.com): We minify JavaScript using our
+[Closure Tools](https://developers.google.com/closure/) jar. Make sure you have Java (version 6 or higher) installed
+and included in your [PATH](http://docs.oracle.com/javase/tutorial/essential/environment/paths.html) variable.
 
-* {@link http://gruntjs.com Grunt}: We use Grunt as our build system. Install the grunt command-line tool globally with:
+* [Grunt](http://gruntjs.com): We use Grunt as our build system. Install the grunt command-line tool globally with:
 
   ```shell
   npm install -g grunt-cli
   ```
 
-* {@link http://bower.io/ Bower}: We use Bower to manage client-side packages for the docs. Install the `bower` command-line tool globally with:
+* [Bower](http://bower.io/): We use Bower to manage client-side packages for the docs. Install the `bower` command-line tool globally with:
 
   ```shell
   npm install -g bower
@@ -51,9 +51,8 @@ Bower globally.
 
 ## Forking Angular on Github
 
-To create a Github account, follow the instructions {@link https://github.com/signup/free here}.
-Afterwards, go ahead and {@link http://help.github.com/forking fork} the {@link
-https://github.com/angular/angular.js main AngularJS repository}.
+To create a Github account, follow the instructions [here](https://github.com/signup/free).
+Afterwards, go ahead and [fork](http://help.github.com/forking) the [main AngularJS repository](https://github.com/angular/angular.js).
 
 
 ## Building AngularJS
diff --git a/docs/content/misc/faq.ngdoc b/docs/content/misc/faq.ngdoc
index 535464f6aaa5..18beca127bf3 100644
--- a/docs/content/misc/faq.ngdoc
+++ b/docs/content/misc/faq.ngdoc
@@ -72,12 +72,12 @@ The size of the file is < 36KB compressed and minified.
 
 ### Can I use the open-source Closure Library with Angular?
 
-Yes, you can use widgets from the {@link http://code.google.com/closure/library Closure Library}
+Yes, you can use widgets from the [Closure Library](http://code.google.com/closure/library)
 in Angular.
 
 ### Does Angular use the jQuery library?
 
-Yes, Angular can use {@link http://jquery.com/ jQuery} if it's present in your app when the
+Yes, Angular can use [jQuery](http://jquery.com/) if it's present in your app when the
 application is being bootstrapped. If jQuery is not present in your script path, Angular falls back
 to its own implementation of the subset of jQuery that we call {@link api/angular.element  jQLite}.
 
@@ -95,7 +95,7 @@ framework, provides mocks for many heavy dependencies (server-side communication
 ### How can I learn more about Angular?
 
 Watch the July 17, 2012 talk
-"{@link http://www.youtube.com/watch?v=1CpiB3Wk25U AngularJS Intro + Dependency Injection}".
+"[AngularJS Intro + Dependency Injection](http://www.youtube.com/watch?v=1CpiB3Wk25U)".
 
 
 ### How is Angular licensed?
@@ -104,10 +104,8 @@ The {@link https://github.com/angular/angular.js/blob/master/LICENSE MIT License
 
 ### Can I download and use the Angular logo artwork?
 
-Yes! You can find design files in our github repository, under "{@link https://github.com/angular/angular.js/tree/master/images/logo
-angular.js/images/logo}"
-The logo design is licensed under a "{@link http://creativecommons.org/licenses/by-sa/3.0/
-Creative Commons Attribution-ShareAlike 3.0 Unported License}". If you have some other use in mind, contact us.
+Yes! You can find design files in our github repository, under "[angular.js/images/logo](https://github.com/angular/angular.js/tree/master/images/logo)"
+The logo design is licensed under a "[Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/)". If you have some other use in mind, contact us.
 
 ### How can I get some AngularJS schwag?
 
@@ -119,7 +117,7 @@ they'll waive the setup costs, and you can order any quantity you need.
 For orders of 250 stickers or more within Canada or the United States, contact Tom Witting (or anyone in sales) via email at tom@stickergiant.com, and tell him you want to order some AngularJS
 stickers just like the ones in job #42711. You'll have to give them your own info for billing and shipping.
 
-As long as the design stays exactly the same, {@link http://www.stickergiant.com StickerGiant} will give you a reorder discount.
+As long as the design stays exactly the same, [StickerGiant](http://www.stickergiant.com) will give you a reorder discount.
 
 For a smaller order, or for other countries, we suggest downloading the logo artwork and making your own.
 
diff --git a/docs/content/misc/started.ngdoc b/docs/content/misc/started.ngdoc
index f078aebe4656..a6301fa7fc89 100644
--- a/docs/content/misc/started.ngdoc
+++ b/docs/content/misc/started.ngdoc
@@ -10,7 +10,7 @@ becoming an Angular expert.
 1. Do the {@link tutorial/ AngularJS Tutorial}.
Walk end-to-end through building an application complete with tests on top of a node.js web server. Covers every major AngularJS feature and show you how to set up your development environment. -1. Download or clone the {@link https://github.com/angular/angular-seed Seed App project template}.
Gives you a +1. Download or clone the [Seed App project template](https://github.com/angular/angular-seed).
Gives you a starter app with a directory layout, test harness, and scripts to begin building your application. @@ -20,18 +20,18 @@ becoming an Angular expert. If you haven’t had a chance to watch the videos from the homepage, please check out: -* {@link http://www.youtube.com/watch?v=WuiHuZq_cg4&list=PL173F1A311439C05D&context=C48ac877ADvjVQa1PpcFONnl4Q5x8hqvT6tRBTE-m0-Ym47jO3PEE%3D Introduction to AngularJS} -* {@link http://www.youtube.com/watch?v=Yg-R1gchccg&list=PL173F1A311439C05D&context=C48ac877ADvjVQa1PpcFONnl4Q5x8hqvT6tRBTE-m0-Ym47jO3PEE%3D Creating Directives} -* {@link http://www.youtube.com/watch?v=IRelx4-ISbs&list=PL173F1A311439C05D&context=C48ac877ADvjVQa1PpcFONnl4Q5x8hqvT6tRBTE-m0-Ym47jO3PEE%3D Communicating with Servers} +* [Introduction to AngularJS](http://www.youtube.com/watch?v=WuiHuZq_cg4&list=PL173F1A311439C05D&context=C48ac877ADvjVQa1PpcFONnl4Q5x8hqvT6tRBTE-m0-Ym47jO3PEE%3D) +* [Creating Directives](http://www.youtube.com/watch?v=Yg-R1gchccg&list=PL173F1A311439C05D&context=C48ac877ADvjVQa1PpcFONnl4Q5x8hqvT6tRBTE-m0-Ym47jO3PEE%3D) +* [Communicating with Servers](http://www.youtube.com/watch?v=IRelx4-ISbs&list=PL173F1A311439C05D&context=C48ac877ADvjVQa1PpcFONnl4Q5x8hqvT6tRBTE-m0-Ym47jO3PEE%3D) -And visit our {@link http://www.youtube.com/user/angularjs YouTube channel} for more AngularJS video presentations and +And visit our [YouTube channel](http://www.youtube.com/user/angularjs) for more AngularJS video presentations and tutorials. ##Subscribe -* Subscribe to the {@link http://groups.google.com/forum/?fromgroups#!forum/angular mailing list}. Ask questions here! -* Follow us on {@link https://twitter.com/intent/follow?original_referer=http%3A%2F%2Fangularjs.org%2F®ion=follow_link&screen_name=angularjs&source=followbutton&variant=2.0 Twitter} -* Add us to your circles on {@link https://plus.google.com/110323587230527980117/posts Google+} +* Subscribe to the [mailing list](http://groups.google.com/forum/?fromgroups#!forum/angular). Ask questions here! +* Follow us on [Twitter](https://twitter.com/intent/follow?original_referer=http%3A%2F%2Fangularjs.org%2F®ion=follow_link&screen_name=angularjs&source=followbutton&variant=2.0) +* Add us to your circles on [Google+](https://plus.google.com/110323587230527980117/posts) ##Read more diff --git a/docs/content/tutorial/step_00.ngdoc b/docs/content/tutorial/step_00.ngdoc index 7e2a6a8bb9ea..e1fb89f222d6 100644 --- a/docs/content/tutorial/step_00.ngdoc +++ b/docs/content/tutorial/step_00.ngdoc @@ -169,8 +169,7 @@ and one static binding, and our model is empty. That will soon change! ## What are all these files in my working directory? -Most of the files in your working directory come from the {@link -https://github.com/angular/angular-seed angular-seed project} which is typically used to bootstrap +Most of the files in your working directory come from the [angular-seed project](https://github.com/angular/angular-seed) which is typically used to bootstrap new Angular projects. The seed project includes the latest Angular libraries, test libraries, scripts and a simple example app, all pre-configured for developing a typical web app. diff --git a/docs/content/tutorial/step_01.ngdoc b/docs/content/tutorial/step_01.ngdoc index 82a2e83ea28d..5c310dce42f6 100644 --- a/docs/content/tutorial/step_01.ngdoc +++ b/docs/content/tutorial/step_01.ngdoc @@ -17,8 +17,7 @@ In this step you will add some basic information about two cell phones to an HTM The page now contains a list with information about two phones. -The most important changes are listed below. You can see the full diff on {@link -https://github.com/angular/angular-phonecat/compare/step-0...step-1 GitHub}: +The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-0...step-1): __`app/index.html`:__
diff --git a/docs/content/tutorial/step_02.ngdoc b/docs/content/tutorial/step_02.ngdoc
index 5710ddaaab12..42bd42cf4e32 100644
--- a/docs/content/tutorial/step_02.ngdoc
+++ b/docs/content/tutorial/step_02.ngdoc
@@ -9,8 +9,8 @@ Now it's time to make the web page dynamic — with AngularJS. We'll also add a
 code for the controller we are going to add.
 
 There are many ways to structure the code for an application. For Angular apps, we encourage the
-use of {@link http://en.wikipedia.org/wiki/Model–View–Controller the Model-View-Controller (MVC)
-design pattern} to decouple the code and to separate concerns. With that in mind, let's use a
+use of [the Model-View-Controller (MVC)
+design pattern](http://en.wikipedia.org/wiki/Model–View–Controller) to decouple the code and to separate concerns. With that in mind, let's use a
 little Angular and JavaScript to add model, view, and controller components to our app.
 
 
@@ -19,8 +19,7 @@ little Angular and JavaScript to add model, view, and controller components to o
 
 The app now contains a list with three phones.
 
-The most important changes are listed below. You can see the full diff on {@link
-https://github.com/angular/angular-phonecat/compare/step-1...step-2 GitHub}:
+The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-1...step-2):
 
 
 ## View and Template
@@ -179,12 +178,9 @@ is available to be injected.
 ### Writing and Running Tests
 Angular developers prefer the syntax of Jasmine's Behavior-driven Development  (BDD) framework when
 writing tests. Although Angular does not require you to use Jasmine, we wrote all of the tests in
-this tutorial in Jasmine. You can learn about Jasmine on the {@link
-http://pivotal.github.com/jasmine/ Jasmine home page} and at the {@link
-http://pivotal.github.io/jasmine/ Jasmine docs}.
+this tutorial in Jasmine. You can learn about Jasmine on the [Jasmine home page](http://pivotal.github.com/jasmine/) and at the [Jasmine docs](http://pivotal.github.io/jasmine/).
 
-The angular-seed project is pre-configured to run all unit tests using {@link
-http://karma-runner.github.io/ Karma}. Ensure that the necessary karma plugins are installed.
+The angular-seed project is pre-configured to run all unit tests using [Karma](http://karma-runner.github.io/). Ensure that the necessary karma plugins are installed.
 You can do this by issuing `npm install` into your terminal.
 
 
diff --git a/docs/content/tutorial/step_03.ngdoc b/docs/content/tutorial/step_03.ngdoc
index 686f0854c25b..599be30916e4 100644
--- a/docs/content/tutorial/step_03.ngdoc
+++ b/docs/content/tutorial/step_03.ngdoc
@@ -18,8 +18,7 @@ The app now has a search box. Notice that the phone list on the page changes dep
 user types into the search box.
 
 The most important differences between Steps 2 and 3 are listed below. You can see the full diff on
-{@link https://github.com/angular/angular-phonecat/compare/step-2...step-3
- GitHub}:
+[GitHub](https://github.com/angular/angular-phonecat/compare/step-2...step-3):
 
 
 ## Controller
@@ -117,10 +116,10 @@ test runner}.
 
 To run the end-to-end test, open one of the following in a new browser tab:
 
-* node.js users: {@link http://localhost:8000/test/e2e/runner.html}
+* node.js users: http://localhost:8000/test/e2e/runner.html
 * users with other http servers:
 `http://localhost:[port-number]/[context-path]/test/e2e/runner.html`
-* casual reader: {@link http://angular.github.com/angular-phonecat/step-3/test/e2e/runner.html}
+* casual reader: http://angular.github.com/angular-phonecat/step-3/test/e2e/runner.html
 
 Previously we've seen how Karma can be used to execute unit tests. Well, it can also run the
 end-to-end tests! Use `./scripts/e2e-test.sh` script for that. End-to-end tests are slow, so unlike
diff --git a/docs/content/tutorial/step_04.ngdoc b/docs/content/tutorial/step_04.ngdoc
index 26e292262016..a27195f1af49 100644
--- a/docs/content/tutorial/step_04.ngdoc
+++ b/docs/content/tutorial/step_04.ngdoc
@@ -17,7 +17,7 @@ You should see that in addition to the search box, the app displays a drop down
 users to control the order in which the phones are listed.
 
 The most important differences between Steps 3 and 4 are listed below. You can see the full diff on
-{@link https://github.com/angular/angular-phonecat/compare/step-3...step-4 GitHub}:
+[GitHub](https://github.com/angular/angular-phonecat/compare/step-3...step-4):
 
 
 ## Template
@@ -168,9 +168,7 @@ __`test/e2e/scenarios.js`:__
 The end-to-end test verifies that the ordering mechanism of the select box is working correctly.
 
 You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
-`runner.html` to see the tests run, or you can see them running on {@link
-http://angular.github.com/angular-phonecat/step-4/test/e2e/runner.html
-Angular's server}.
+`runner.html` to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-4/test/e2e/runner.html).
 
 # Experiments
 
diff --git a/docs/content/tutorial/step_05.ngdoc b/docs/content/tutorial/step_05.ngdoc
index ae7fd8fe08e4..568412e87c66 100644
--- a/docs/content/tutorial/step_05.ngdoc
+++ b/docs/content/tutorial/step_05.ngdoc
@@ -16,9 +16,7 @@ injection (DI)} to provide the service to the `PhoneListCtrl` controller.
 
 You should now see a list of 20 phones.
 
-The most important changes are listed below. You can see the full diff on {@link
-https://github.com/angular/angular-phonecat/compare/step-4...step-5
-GitHub}:
+The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-4...step-5):
 
 ## Data
 
@@ -108,8 +106,7 @@ properties are considered private, and should not be accessed or modified.
 ### A Note on Minification
 
 Since Angular infers the controller's dependencies from the names of arguments to the controller's
-constructor function, if you were to {@link http://en.wikipedia.org/wiki/Minification_(programming)
-minify} the JavaScript code for `PhoneListCtrl` controller, all of its function arguments would be
+constructor function, if you were to [minify](http://en.wikipedia.org/wiki/Minification_(programming)) the JavaScript code for `PhoneListCtrl` controller, all of its function arguments would be
 minified as well, and the dependency injector would not be able to identify services correctly.
 
 There are two ways to overcome issues caused by minification:
diff --git a/docs/content/tutorial/step_06.ngdoc b/docs/content/tutorial/step_06.ngdoc
index eaf0ad3cbbf7..68981f45fe56 100644
--- a/docs/content/tutorial/step_06.ngdoc
+++ b/docs/content/tutorial/step_06.ngdoc
@@ -15,9 +15,7 @@ about the phones in the catalog.
 
 You should now see links and images of the phones in the list.
 
-The most important changes are listed below. You can see the full diff on {@link
-https://github.com/angular/angular-phonecat/compare/step-5...step-6
-GitHub}:
+The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-5...step-6):
 
 
 ## Data
@@ -85,9 +83,7 @@ We added a new end-to-end test to verify that the app is generating correct link
 views that we will implement in the upcoming steps.
 
 You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
-runner to see the tests run, or you can see them running on {@link
-http://angular.github.com/angular-phonecat/step-6/test/e2e/runner.html
-Angular's server}.
+runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-6/test/e2e/runner.html).
 
 
 # Experiments
diff --git a/docs/content/tutorial/step_07.ngdoc b/docs/content/tutorial/step_07.ngdoc
index 0f6b83ed8538..77408b4e45a1 100644
--- a/docs/content/tutorial/step_07.ngdoc
+++ b/docs/content/tutorial/step_07.ngdoc
@@ -17,9 +17,7 @@ and the same phone list appears in the browser. When you click on a phone link t
 detail page is displayed.
 
 
-The most important changes are listed below. You can see the full diff on {@link
-https://github.com/angular/angular-phonecat/compare/step-6...step-7
-GitHub}.
+The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-6...step-7).
 
 
 ## Multiple Views, Routing and Layout Template
@@ -39,8 +37,7 @@ Application routes in Angular are declared via the
 {@link api/ngRoute.$routeProvider $routeProvider}, which is the provider of the
 {@link api/ngRoute.$route $route service}. This service makes it easy to wire together
 controllers, view templates, and the current
-URL location in the browser. Using this feature we can implement {@link
-http://en.wikipedia.org/wiki/Deep_linking deep linking}, which lets us utilize the browser's
+URL location in the browser. Using this feature we can implement [deep linking](http://en.wikipedia.org/wiki/Deep_linking), which lets us utilize the browser's
 history (back and forward navigation) and bookmarks.
 
 
@@ -107,7 +104,7 @@ module `phonecatControllers`. By listing these two modules as dependencies of `p
 can use the directives and services they provide.
 
 Thus using the `config` API we request the `$routeProvider` to be injected into our config function
-and use the {@link api/ngRoute.$routeProvider#methods_when `$routeProvider.when`} API to define our routes.
+and use the {@link api/ngRoute.$routeProvider#when `$routeProvider.when`} API to define our routes.
 
 Our application routes are defined as follows:
 
@@ -278,9 +275,7 @@ to various URLs and verify that the correct view was rendered.
 
 
 You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
-runner to see the tests run, or you can see them running on {@link
-http://angular.github.com/angular-phonecat/step-7/test/e2e/runner.html
-Angular's server}.
+runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-7/test/e2e/runner.html).
 
 
 # Experiments
diff --git a/docs/content/tutorial/step_08.ngdoc b/docs/content/tutorial/step_08.ngdoc
index 968c9addfad0..ee10e8ee20c9 100644
--- a/docs/content/tutorial/step_08.ngdoc
+++ b/docs/content/tutorial/step_08.ngdoc
@@ -18,9 +18,7 @@ is displayed.
 To implement the phone details view we will use {@link api/ng.$http $http} to fetch
 our data, and we'll flesh out the `phone-detail.html` view template.
 
-The most important changes are listed below. You can see the full diff on {@link
-https://github.com/angular/angular-phonecat/compare/step-7...step-8
-GitHub}:
+The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-7...step-8):
 
 ## Data
 
@@ -175,9 +173,7 @@ __`test/e2e/scenarios.js`:__
 
 
 You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
-runner to see the tests run, or you can see them running on {@link
-http://angular.github.com/angular-phonecat/step-8/test/e2e/runner.html
-Angular's server}.
+runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-8/test/e2e/runner.html).
 
 
 # Experiments
diff --git a/docs/content/tutorial/step_09.ngdoc b/docs/content/tutorial/step_09.ngdoc
index 8f3cb5b9191f..894c6f96afbd 100644
--- a/docs/content/tutorial/step_09.ngdoc
+++ b/docs/content/tutorial/step_09.ngdoc
@@ -17,9 +17,7 @@ In the previous step, the details page displayed either "true" or "false" to ind
 certain phone features were present or not. We have used a custom filter to convert those text
 strings into glyphs: ✓ for "true", and ✘ for "false". Let's see what the filter code looks like.
 
-The most important changes are listed below. You can see the full diff on {@link
-https://github.com/angular/angular-phonecat/compare/step-8...step-9
-GitHub}:
+The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-8...step-9):
 
 
 ## Custom Filter
diff --git a/docs/content/tutorial/step_10.ngdoc b/docs/content/tutorial/step_10.ngdoc
index ede1a4aafc05..d1ed37f73227 100644
--- a/docs/content/tutorial/step_10.ngdoc
+++ b/docs/content/tutorial/step_10.ngdoc
@@ -15,9 +15,7 @@ The phone details view displays one large image of the current phone and several
 images. It would be great if we could replace the large image with any of the thumbnails just by
 clicking on the desired thumbnail image. Let's have a look at how we can do this with Angular.
 
-The most important changes are listed below. You can see the full diff on {@link
-https://github.com/angular/angular-phonecat/compare/step-9...step-10
-GitHub}:
+The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-9...step-10):
 
 
 ## Controller
@@ -104,9 +102,7 @@ __`test/e2e/scenarios.js`:__
 
You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test -runner to see the tests run, or you can see them running on {@link -http://angular.github.com/angular-phonecat/step-10/test/e2e/runner.html -Angular's server}. +runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-10/test/e2e/runner.html). # Experiments diff --git a/docs/content/tutorial/step_11.ngdoc b/docs/content/tutorial/step_11.ngdoc index 4b82367daebf..9a549516e67f 100644 --- a/docs/content/tutorial/step_11.ngdoc +++ b/docs/content/tutorial/step_11.ngdoc @@ -11,14 +11,11 @@ In this step, you will improve the way our app fetches data.
-The next improvement we will make to our app is to define a custom service that represents a {@link -http://en.wikipedia.org/wiki/Representational_State_Transfer RESTful} client. Using this client we +The next improvement we will make to our app is to define a custom service that represents a [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) client. Using this client we can make XHR requests for data in an easier way, without having to deal with the lower-level {@link api/ng.$http $http} API, HTTP methods and URLs. -The most important changes are listed below. You can see the full diff on {@link -https://github.com/angular/angular-phonecat/compare/step-10...step-11 -GitHub}: +The most important changes are listed below. You can see the full diff on [GitHub](https://github.com/angular/angular-phonecat/compare/step-10...step-11): ## Template @@ -55,7 +52,7 @@ controller's constructor in that both can declare dependencies via function argu service declared a dependency on the `$resource` service. The {@link api/ngResource.$resource `$resource`} service makes it easy to create a -{@link http://en.wikipedia.org/wiki/Representational_State_Transfer RESTful} client with just a few +[RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) client with just a few lines of code. This client can then be used in our application, instead of the lower-level {@link api/ng.$http $http} service. @@ -130,8 +127,7 @@ service correctly. The {@link api/ngResource.$resource $resource} service augments the response object with methods for updating and deleting the resource. If we were to use the standard `toEqual` matcher, our tests would fail because the test values would not match the responses exactly. To -solve the problem, we use a newly-defined `toEqualData` {@link -https://github.com/pivotal/jasmine/wiki/Matchers Jasmine matcher}. When the +solve the problem, we use a newly-defined `toEqualData` [Jasmine matcher](https://github.com/pivotal/jasmine/wiki/Matchers). When the `toEqualData` matcher compares two objects, it takes only object properties into account and ignores methods. diff --git a/docs/content/tutorial/step_12.ngdoc b/docs/content/tutorial/step_12.ngdoc index b611e0725557..a444f4fb062f 100644 --- a/docs/content/tutorial/step_12.ngdoc +++ b/docs/content/tutorial/step_12.ngdoc @@ -22,7 +22,7 @@ then the animation will run in between the standard DOM operation that is being the given time (e.g. inserting and removing nodes on ngRepeat or adding and removing classes on ngClass). The most important changes are listed below. You can see the full diff on -{@link https://github.com/angular/angular-phonecat/compare/step-11...step-12 GitHub}: +[GitHub](https://github.com/angular/angular-phonecat/compare/step-11...step-12): ## How Animations work with `ngAnimate` @@ -183,8 +183,8 @@ around and collapsing the items before removing them from the list. There's also a nice fade-in and fade-out effect that also occurs at the same time. All of this is handled by the CSS transition declarations at the top of the example code above. -Although most modern browsers have good support for {@link http://caniuse.com/#feat=css-transitions CSS transitions} -and {@link http://caniuse.com/#feat=css-animation CSS animations}, IE9 and earlier do not. +Although most modern browsers have good support for [CSS transitions](http://caniuse.com/#feat=css-transitions) +and [CSS animations](http://caniuse.com/#feat=css-animation), IE9 and earlier do not. If you want animations that are backwards-compatible with older browsers, consider using JavaScript-based animations, which are described in detail below. @@ -284,7 +284,7 @@ loaded the ng-view directive will create a copy of itself, download the template ensures that all views are contained within a single HTML element which allows for easy animation control. For more on CSS animations, see the -{@link http://docs.webplatform.org/wiki/css/properties/animations Web Platform documentation}. +[Web Platform documentation](http://docs.webplatform.org/wiki/css/properties/animations). ## Animating `ngClass` with JavaScript @@ -394,10 +394,10 @@ phonecatAnimations.animation('.phone', function() { });
-Note that we're using {@link http://jquery.com/ jQuery} to implement the animation. jQuery +Note that we're using [jQuery](http://jquery.com/) to implement the animation. jQuery isn't required to do JavaScript animations with AngularJS, but we're going to use it because writing your own JavaScript animation library is beyond the scope of this tutorial. For more on -`jQuery.animate`, see the {@link http://api.jquery.com/animate/ jQuery documentation}. +`jQuery.animate`, see the [jQuery documentation](http://api.jquery.com/animate/). The `addClass` and `removeClass` callback functions are called whenever an a class is added or removed on the element that contains the class we registered, which is in this case `.phone`. When the `.active` diff --git a/docs/content/tutorial/the_end.ngdoc b/docs/content/tutorial/the_end.ngdoc index 3a5fb9f8d05c..46bbcbba1fe9 100644 --- a/docs/content/tutorial/the_end.ngdoc +++ b/docs/content/tutorial/the_end.ngdoc @@ -9,11 +9,10 @@ For more details and examples of the Angular concepts we touched on in this tuto {@link guide/ Developer Guide}. When you are ready to start developing a project using Angular, we recommend that you bootstrap -your development with the {@link https://github.com/angular/angular-seed angular-seed} project. +your development with the [angular-seed](https://github.com/angular/angular-seed) project. We hope this tutorial was useful to you and that you learned enough about Angular to make you want to learn more. We especially hope you are inspired to go out and develop Angular web apps of your own, and that you might be interested in {@link misc/contribute contributing} to Angular. -If you have questions or feedback or just want to say "hi", please post a message at {@link -https://groups.google.com/forum/#!forum/angular}. +If you have questions or feedback or just want to say "hi", please post a message at (https://groups.google.com/forum/#!forum/angular). From 490a9c33d806375a66c6094a26dd4aef105a1d76 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 6 Feb 2014 13:33:42 +0000 Subject: [PATCH 046/123] docs(bike-shed-migration): change tutorial doctype and add @step tag --- docs/content/tutorial/index.ngdoc | 5 +++-- docs/content/tutorial/step_00.ngdoc | 5 +++-- docs/content/tutorial/step_01.ngdoc | 5 +++-- docs/content/tutorial/step_02.ngdoc | 5 +++-- docs/content/tutorial/step_03.ngdoc | 5 +++-- docs/content/tutorial/step_04.ngdoc | 5 +++-- docs/content/tutorial/step_05.ngdoc | 5 +++-- docs/content/tutorial/step_06.ngdoc | 5 +++-- docs/content/tutorial/step_07.ngdoc | 5 +++-- docs/content/tutorial/step_08.ngdoc | 5 +++-- docs/content/tutorial/step_09.ngdoc | 4 ++-- docs/content/tutorial/step_10.ngdoc | 5 +++-- docs/content/tutorial/step_11.ngdoc | 4 ++-- docs/content/tutorial/step_12.ngdoc | 5 +++-- docs/content/tutorial/the_end.ngdoc | 5 +++-- 15 files changed, 43 insertions(+), 30 deletions(-) diff --git a/docs/content/tutorial/index.ngdoc b/docs/content/tutorial/index.ngdoc index 5b7c971693f0..2a833bb4e49c 100644 --- a/docs/content/tutorial/index.ngdoc +++ b/docs/content/tutorial/index.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: Index +@ngdoc tutorial +@name Index +@step -1 @description A great way to get introduced to AngularJS is to work through this tutorial, which walks you through diff --git a/docs/content/tutorial/step_00.ngdoc b/docs/content/tutorial/step_00.ngdoc index e1fb89f222d6..b6ea975cc1c5 100644 --- a/docs/content/tutorial/step_00.ngdoc +++ b/docs/content/tutorial/step_00.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 0 - Bootstrapping +@ngdoc tutorial +@name 0 - Bootstrapping +@step 0 @description
    diff --git a/docs/content/tutorial/step_01.ngdoc b/docs/content/tutorial/step_01.ngdoc index 5c310dce42f6..540484d35cdd 100644 --- a/docs/content/tutorial/step_01.ngdoc +++ b/docs/content/tutorial/step_01.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 1 - Static Template +@ngdoc tutorial +@name 1 - Static Template +@step 1 @description
      diff --git a/docs/content/tutorial/step_02.ngdoc b/docs/content/tutorial/step_02.ngdoc index 42bd42cf4e32..99180b4b5312 100644 --- a/docs/content/tutorial/step_02.ngdoc +++ b/docs/content/tutorial/step_02.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 2 - Angular Templates +@ngdoc tutorial +@name 2 - Angular Templates +@step 2 @description
        diff --git a/docs/content/tutorial/step_03.ngdoc b/docs/content/tutorial/step_03.ngdoc index 599be30916e4..d7c7508672f8 100644 --- a/docs/content/tutorial/step_03.ngdoc +++ b/docs/content/tutorial/step_03.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 3 - Filtering Repeaters +@ngdoc tutorial +@name 3 - Filtering Repeaters +@step 3 @description
          diff --git a/docs/content/tutorial/step_04.ngdoc b/docs/content/tutorial/step_04.ngdoc index a27195f1af49..612619a40349 100644 --- a/docs/content/tutorial/step_04.ngdoc +++ b/docs/content/tutorial/step_04.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 4 - Two-way Data Binding +@ngdoc tutorial +@name 4 - Two-way Data Binding +@step 4 @description
            diff --git a/docs/content/tutorial/step_05.ngdoc b/docs/content/tutorial/step_05.ngdoc index 568412e87c66..e32739a14512 100644 --- a/docs/content/tutorial/step_05.ngdoc +++ b/docs/content/tutorial/step_05.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 5 - XHRs & Dependency Injection +@ngdoc tutorial +@name 5 - XHRs & Dependency Injection +@step 5 @description
              diff --git a/docs/content/tutorial/step_06.ngdoc b/docs/content/tutorial/step_06.ngdoc index 68981f45fe56..09052e8f3773 100644 --- a/docs/content/tutorial/step_06.ngdoc +++ b/docs/content/tutorial/step_06.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 6 - Templating Links & Images +@ngdoc tutorial +@name 6 - Templating Links & Images +@step 6 @description
                diff --git a/docs/content/tutorial/step_07.ngdoc b/docs/content/tutorial/step_07.ngdoc index 77408b4e45a1..2f752f6ae66f 100644 --- a/docs/content/tutorial/step_07.ngdoc +++ b/docs/content/tutorial/step_07.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 7 - Routing & Multiple Views +@ngdoc tutorial +@name 7 - Routing & Multiple Views +@step 7 @description
                  diff --git a/docs/content/tutorial/step_08.ngdoc b/docs/content/tutorial/step_08.ngdoc index ee10e8ee20c9..7ba6d36ae378 100644 --- a/docs/content/tutorial/step_08.ngdoc +++ b/docs/content/tutorial/step_08.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 8 - More Templating +@ngdoc tutorial +@name 8 - More Templating +@step 8 @description
                    diff --git a/docs/content/tutorial/step_09.ngdoc b/docs/content/tutorial/step_09.ngdoc index 894c6f96afbd..8d23af3e44fe 100644 --- a/docs/content/tutorial/step_09.ngdoc +++ b/docs/content/tutorial/step_09.ngdoc @@ -1,5 +1,5 @@ -@ngdoc overview -@name Tutorial: 9 - Filters +@ngdoc tutorial +@name 9 - Filters @description
                      diff --git a/docs/content/tutorial/step_10.ngdoc b/docs/content/tutorial/step_10.ngdoc index d1ed37f73227..640977e6f37e 100644 --- a/docs/content/tutorial/step_10.ngdoc +++ b/docs/content/tutorial/step_10.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 10 - Event Handlers +@ngdoc tutorial +@name 10 - Event Handlers +@step 10 @description
                        diff --git a/docs/content/tutorial/step_11.ngdoc b/docs/content/tutorial/step_11.ngdoc index 9a549516e67f..ffd342edebf8 100644 --- a/docs/content/tutorial/step_11.ngdoc +++ b/docs/content/tutorial/step_11.ngdoc @@ -1,5 +1,5 @@ -@ngdoc overview -@name Tutorial: 11 - REST and Custom Services +@ngdoc tutorial +@name 11 - REST and Custom Services @description
                          diff --git a/docs/content/tutorial/step_12.ngdoc b/docs/content/tutorial/step_12.ngdoc index a444f4fb062f..1323fb2f0382 100644 --- a/docs/content/tutorial/step_12.ngdoc +++ b/docs/content/tutorial/step_12.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: 12 - Applying Animations +@ngdoc tutorial +@name 12 - Applying Animations +@step 12 @description
                            diff --git a/docs/content/tutorial/the_end.ngdoc b/docs/content/tutorial/the_end.ngdoc index 46bbcbba1fe9..0c7a899eb375 100644 --- a/docs/content/tutorial/the_end.ngdoc +++ b/docs/content/tutorial/the_end.ngdoc @@ -1,5 +1,6 @@ -@ngdoc overview -@name Tutorial: The End +@ngdoc tutorial +@name The End +@step 99 @description Our application is now complete. Feel free to experiment with the code further, and jump back to From 6f581d3688060d0c8fdc2e37d48845843eb37f48 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 6 Feb 2014 13:33:42 +0000 Subject: [PATCH 047/123] docs(bike-shed-migration): move ng module doc into Angular.js --- docs/content/api/ng.ngdoc | 11 ----------- src/Angular.js | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 11 deletions(-) delete mode 100644 docs/content/api/ng.ngdoc diff --git a/docs/content/api/ng.ngdoc b/docs/content/api/ng.ngdoc deleted file mode 100644 index 0acaf528d552..000000000000 --- a/docs/content/api/ng.ngdoc +++ /dev/null @@ -1,11 +0,0 @@ -@ngdoc overview -@name ng -@description - -# ng (core module) -The ng module is loaded by default when an AngularJS application is started. The module itself -contains the essential components for an AngularJS application to function. The table below -lists a high level breakdown of each of the services/factories, filters, directives and testing -components available within this core module. - -
                            diff --git a/src/Angular.js b/src/Angular.js index 723a513c421c..8d8a0cf8c0f5 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -87,6 +87,20 @@ //////////////////////////////////// +/** + * @ngdoc module + * @name ng + * @description + * + * # ng (core module) + * The ng module is loaded by default when an AngularJS application is started. The module itself + * contains the essential components for an AngularJS application to function. The table below + * lists a high level breakdown of each of the services/factories, filters, directives and testing + * components available within this core module. + * + *
                            + */ + /** * @ngdoc function * @name angular.lowercase From 0e4a4d573b40ea7bbe05be316a0a03558e02f780 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 6 Feb 2014 13:33:42 +0000 Subject: [PATCH 048/123] docs(bike-shed-migration): convert doctype and names --- src/Angular.js | 7 +- src/AngularPublic.js | 2 +- src/auto/injector.js | 95 ++++++++--------- src/loader.js | 25 ++--- src/ng/anchorScroll.js | 5 +- src/ng/animate.js | 43 ++++---- src/ng/browser.js | 23 ++-- src/ng/cacheFactory.js | 14 ++- src/ng/compile.js | 55 ++++------ src/ng/controller.js | 15 ++- src/ng/directive/a.js | 2 +- src/ng/directive/booleanAttrs.js | 16 +-- src/ng/directive/form.js | 33 +++--- src/ng/directive/input.js | 65 ++++++------ src/ng/directive/ngBind.js | 6 +- src/ng/directive/ngClass.js | 6 +- src/ng/directive/ngCloak.js | 2 +- src/ng/directive/ngController.js | 2 +- src/ng/directive/ngCsp.js | 2 +- src/ng/directive/ngEventDirs.js | 34 +++--- src/ng/directive/ngIf.js | 2 +- src/ng/directive/ngInclude.js | 6 +- src/ng/directive/ngInit.js | 2 +- src/ng/directive/ngNonBindable.js | 2 +- src/ng/directive/ngPluralize.js | 2 +- src/ng/directive/ngRepeat.js | 2 +- src/ng/directive/ngShowHide.js | 4 +- src/ng/directive/ngStyle.js | 2 +- src/ng/directive/ngSwitch.js | 2 +- src/ng/directive/ngTransclude.js | 2 +- src/ng/directive/script.js | 2 +- src/ng/directive/select.js | 2 +- src/ng/document.js | 4 +- src/ng/exceptionHandler.js | 4 +- src/ng/filter.js | 16 ++- src/ng/filter/filter.js | 2 +- src/ng/filter/filters.js | 12 +-- src/ng/filter/limitTo.js | 4 +- src/ng/filter/orderBy.js | 4 +- src/ng/http.js | 25 ++--- src/ng/httpBackend.js | 4 +- src/ng/interpolate.js | 20 ++-- src/ng/interval.js | 9 +- src/ng/locale.js | 4 +- src/ng/location.js | 45 +++----- src/ng/log.js | 26 ++--- src/ng/parse.js | 16 ++- src/ng/q.js | 14 +-- src/ng/rootElement.js | 6 +- src/ng/rootScope.js | 78 ++++++-------- src/ng/sce.js | 92 ++++++---------- src/ng/sniffer.js | 2 +- src/ng/timeout.js | 9 +- src/ng/window.js | 4 +- src/ngAnimate/animate.js | 40 +++---- src/ngCookies/cookies.js | 19 ++-- src/ngMock/angular-mocks.js | 169 ++++++++++++------------------ src/ngResource/resource.js | 6 +- src/ngRoute/directive/ngView.js | 5 +- src/ngRoute/route.js | 33 +++--- src/ngRoute/routeParams.js | 4 +- src/ngSanitize/filter/linky.js | 2 +- src/ngSanitize/sanitize.js | 4 +- src/ngTouch/directive/ngClick.js | 2 +- src/ngTouch/directive/ngSwipe.js | 4 +- src/ngTouch/swipe.js | 7 +- src/ngTouch/touch.js | 2 +- 67 files changed, 500 insertions(+), 679 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index 8d8a0cf8c0f5..a6150e888517 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -90,6 +90,7 @@ /** * @ngdoc module * @name ng + * @module ng * @description * * # ng (core module) @@ -1137,7 +1138,7 @@ function encodeUriQuery(val, pctEncodeSpaces) { /** * @ngdoc directive - * @name ng.directive:ngApp + * @name ngApp * @module ng * * @element ANY @@ -1156,7 +1157,7 @@ function encodeUriQuery(val, pctEncodeSpaces) { * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other. * * You can specify an **AngularJS module** to be used as the root module for the application. This - * module will be loaded into the {@link AUTO.$injector} when the application is bootstrapped and + * module will be loaded into the {@link auto.$injector} when the application is bootstrapped and * should contain the application code needed or have dependencies on other modules that will * contain the code. See {@link angular.module} for more information. * @@ -1242,7 +1243,7 @@ function angularInit(element, bootstrap) { * Each item in the array should be the name of a predefined module or a (DI annotated) * function that will be invoked by the injector as a run block. * See: {@link angular.module modules} - * @returns {AUTO.$injector} Returns the newly created injector for this app. + * @returns {auto.$injector} Returns the newly created injector for this app. */ function bootstrap(element, modules) { var doBootstrap = function() { diff --git a/src/AngularPublic.js b/src/AngularPublic.js index ed57b1946d6f..98a5094a5db3 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -77,7 +77,7 @@ /** - * @ngdoc property + * @ngdoc object * @name angular.version * @module ng * @description diff --git a/src/auto/injector.js b/src/auto/injector.js index ee87b51e3b77..977b57742000 100644 --- a/src/auto/injector.js +++ b/src/auto/injector.js @@ -12,7 +12,7 @@ * @param {Array.} modules A list of module functions or their aliases. See * {@link angular.module}. The `ng` module must be explicitly added. - * @returns {function()} Injector function. See {@link AUTO.$injector $injector}. + * @returns {function()} Injector function. See {@link auto.$injector $injector}. * * @example * Typical usage @@ -53,11 +53,11 @@ /** - * @ngdoc overview - * @name AUTO + * @ngdoc module + * @name auto * @description * - * Implicit module which gets automatically added to each {@link AUTO.$injector $injector}. + * Implicit module which gets automatically added to each {@link auto.$injector $injector}. */ var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; @@ -98,14 +98,14 @@ function annotate(fn) { /////////////////////////////////////// /** - * @ngdoc object - * @name AUTO.$injector + * @ngdoc service + * @name $injector * @function * * @description * * `$injector` is used to retrieve object instances as defined by - * {@link AUTO.$provide provider}, instantiate types, invoke methods, + * {@link auto.$provide provider}, instantiate types, invoke methods, * and load modules. * * The following always holds true: @@ -151,8 +151,7 @@ function annotate(fn) { /** * @ngdoc method - * @name AUTO.$injector#get - * @methodOf AUTO.$injector + * @name $injector#get * * @description * Return an instance of the service. @@ -163,8 +162,7 @@ function annotate(fn) { /** * @ngdoc method - * @name AUTO.$injector#invoke - * @methodOf AUTO.$injector + * @name $injector#invoke * * @description * Invoke the method and supply the method arguments from the `$injector`. @@ -179,8 +177,7 @@ function annotate(fn) { /** * @ngdoc method - * @name AUTO.$injector#has - * @methodOf AUTO.$injector + * @name $injector#has * * @description * Allows the user to query if the particular service exist. @@ -191,8 +188,7 @@ function annotate(fn) { /** * @ngdoc method - * @name AUTO.$injector#instantiate - * @methodOf AUTO.$injector + * @name $injector#instantiate * @description * Create a new instance of JS type. The method takes a constructor function invokes the new * operator and supplies all of the arguments to the constructor function as specified by the @@ -206,8 +202,7 @@ function annotate(fn) { /** * @ngdoc method - * @name AUTO.$injector#annotate - * @methodOf AUTO.$injector + * @name $injector#annotate * * @description * Returns an array of service names which the function is requesting for injection. This API is @@ -290,12 +285,12 @@ function annotate(fn) { /** * @ngdoc object - * @name AUTO.$provide + * @name $provide * * @description * - * The {@link AUTO.$provide $provide} service has a number of methods for registering components - * with the {@link AUTO.$injector $injector}. Many of these functions are also exposed on + * The {@link auto.$provide $provide} service has a number of methods for registering components + * with the {@link auto.$injector $injector}. Many of these functions are also exposed on * {@link angular.Module}. * * An Angular **service** is a singleton object created by a **service factory**. These **service @@ -303,25 +298,25 @@ function annotate(fn) { * The **service providers** are constructor functions. When instantiated they must contain a * property called `$get`, which holds the **service factory** function. * - * When you request a service, the {@link AUTO.$injector $injector} is responsible for finding the + * When you request a service, the {@link auto.$injector $injector} is responsible for finding the * correct **service provider**, instantiating it and then calling its `$get` **service factory** * function to get the instance of the **service**. * * Often services have no configuration options and there is no need to add methods to the service * provider. The provider will be no more than a constructor function with a `$get` property. For - * these cases the {@link AUTO.$provide $provide} service has additional helper methods to register + * these cases the {@link auto.$provide $provide} service has additional helper methods to register * services without specifying a provider. * - * * {@link AUTO.$provide#methods_provider provider(provider)} - registers a **service provider** with the - * {@link AUTO.$injector $injector} - * * {@link AUTO.$provide#methods_constant constant(obj)} - registers a value/object that can be accessed by + * * {@link auto.$provide#methods_provider provider(provider)} - registers a **service provider** with the + * {@link auto.$injector $injector} + * * {@link auto.$provide#methods_constant constant(obj)} - registers a value/object that can be accessed by * providers and services. - * * {@link AUTO.$provide#methods_value value(obj)} - registers a value/object that can only be accessed by + * * {@link auto.$provide#methods_value value(obj)} - registers a value/object that can only be accessed by * services, not providers. - * * {@link AUTO.$provide#methods_factory factory(fn)} - registers a service **factory function**, `fn`, + * * {@link auto.$provide#methods_factory factory(fn)} - registers a service **factory function**, `fn`, * that will be wrapped in a **service provider** object, whose `$get` property will contain the * given factory function. - * * {@link AUTO.$provide#methods_service service(class)} - registers a **constructor function**, `class` that + * * {@link auto.$provide#methods_service service(class)} - registers a **constructor function**, `class` that * that will be wrapped in a **service provider** object, whose `$get` property will instantiate * a new object using the given constructor function. * @@ -330,11 +325,10 @@ function annotate(fn) { /** * @ngdoc method - * @name AUTO.$provide#provider - * @methodOf AUTO.$provide + * @name $provide#provider * @description * - * Register a **provider function** with the {@link AUTO.$injector $injector}. Provider functions + * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions * are constructor functions, whose instances are responsible for "providing" a factory for a * service. * @@ -354,16 +348,16 @@ function annotate(fn) { * @param {(Object|function())} provider If the provider is: * * - `Object`: then it should have a `$get` method. The `$get` method will be invoked using - * {@link AUTO.$injector#invoke $injector.invoke()} when an instance needs to be created. + * {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created. * - `Constructor`: a new instance of the provider will be created using - * {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as `object`. + * {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`. * * @returns {Object} registered provider instance * @example * * The following example shows how to create a simple event tracking service and register it using - * {@link AUTO.$provide#methods_provider $provide.provider()}. + * {@link auto.$provide#methods_provider $provide.provider()}. * *
                              *  // Define the eventTracker provider
                            @@ -427,14 +421,13 @@ function annotate(fn) {
                             
                             /**
                              * @ngdoc method
                            - * @name AUTO.$provide#factory
                            - * @methodOf AUTO.$provide
                            + * @name $provide#factory
                              * @description
                              *
                              * Register a **service factory**, which will be called to return the service instance.
                              * This is short for registering a service where its provider consists of only a `$get` property,
                              * which is the given service factory function.
                            - * You should use {@link AUTO.$provide#factory $provide.factory(getFn)} if you do not need to
                            + * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to
                              * configure your service in a provider.
                              *
                              * @param {string} name The name of the instance.
                            @@ -462,8 +455,7 @@ function annotate(fn) {
                             
                             /**
                              * @ngdoc method
                            - * @name AUTO.$provide#service
                            - * @methodOf AUTO.$provide
                            + * @name $provide#service
                              * @description
                              *
                              * Register a **service constructor**, which will be invoked with `new` to create the service
                            @@ -471,7 +463,7 @@ function annotate(fn) {
                              * This is short for registering a service where its provider's `$get` property is the service
                              * constructor function that will be used to instantiate the service instance.
                              *
                            - * You should use {@link AUTO.$provide#methods_service $provide.service(class)} if you define your service
                            + * You should use {@link auto.$provide#methods_service $provide.service(class)} if you define your service
                              * as a type/class.
                              *
                              * @param {string} name The name of the instance.
                            @@ -480,7 +472,7 @@ function annotate(fn) {
                              *
                              * @example
                              * Here is an example of registering a service using
                            - * {@link AUTO.$provide#methods_service $provide.service(class)}.
                            + * {@link auto.$provide#methods_service $provide.service(class)}.
                              * 
                              *   var Ping = function($http) {
                              *     this.$http = $http;
                            @@ -504,11 +496,10 @@ function annotate(fn) {
                             
                             /**
                              * @ngdoc method
                            - * @name AUTO.$provide#value
                            - * @methodOf AUTO.$provide
                            + * @name $provide#value
                              * @description
                              *
                            - * Register a **value service** with the {@link AUTO.$injector $injector}, such as a string, a
                            + * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a
                              * number, an array, an object or a function.  This is short for registering a service where its
                              * provider's `$get` property is a factory function that takes no arguments and returns the **value
                              * service**.
                            @@ -516,7 +507,7 @@ function annotate(fn) {
                              * Value services are similar to constant services, except that they cannot be injected into a
                              * module configuration function (see {@link angular.Module#config}) but they can be overridden by
                              * an Angular
                            - * {@link AUTO.$provide#decorator decorator}.
                            + * {@link auto.$provide#decorator decorator}.
                              *
                              * @param {string} name The name of the instance.
                              * @param {*} value The value.
                            @@ -538,14 +529,13 @@ function annotate(fn) {
                             
                             /**
                              * @ngdoc method
                            - * @name AUTO.$provide#constant
                            - * @methodOf AUTO.$provide
                            + * @name $provide#constant
                              * @description
                              *
                              * Register a **constant service**, such as a string, a number, an array, an object or a function,
                            - * with the {@link AUTO.$injector $injector}. Unlike {@link AUTO.$provide#value value} it can be
                            + * with the {@link auto.$injector $injector}. Unlike {@link auto.$provide#value value} it can be
                              * injected into a module configuration function (see {@link angular.Module#config}) and it cannot
                            - * be overridden by an Angular {@link AUTO.$provide#decorator decorator}.
                            + * be overridden by an Angular {@link auto.$provide#decorator decorator}.
                              *
                              * @param {string} name The name of the constant.
                              * @param {*} value The constant value.
                            @@ -567,11 +557,10 @@ function annotate(fn) {
                             
                             /**
                              * @ngdoc method
                            - * @name AUTO.$provide#decorator
                            - * @methodOf AUTO.$provide
                            + * @name $provide#decorator
                              * @description
                              *
                            - * Register a **service decorator** with the {@link AUTO.$injector $injector}. A service decorator
                            + * Register a **service decorator** with the {@link auto.$injector $injector}. A service decorator
                              * intercepts the creation of a service, allowing it to override or modify the behaviour of the
                              * service. The object returned by the decorator may be the original service, or a new service
                              * object which replaces or wraps and delegates to the original service.
                            @@ -579,7 +568,7 @@ function annotate(fn) {
                              * @param {string} name The name of the service to decorate.
                              * @param {function()} decorator This function will be invoked when the service needs to be
                              *    instantiated and should return the decorated service instance. The function is called using
                            - *    the {@link AUTO.$injector#invoke injector.invoke} method and is therefore fully injectable.
                            + *    the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.
                              *    Local injection arguments:
                              *
                              *    * `$delegate` - The original service instance, which can be monkey patched, configured,
                            diff --git a/src/loader.js b/src/loader.js
                            index d41ff5939b18..7184cb47a111 100644
                            --- a/src/loader.js
                            +++ b/src/loader.js
                            @@ -1,7 +1,7 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc interface
                            + * @ngdoc type
                              * @name angular.Module
                              * @module ng
                              * @description
                            @@ -45,7 +45,7 @@ function setupModuleLoader(window) {
                                  * # Module
                                  *
                                  * A module is a collection of services, directives, filters, and configuration information.
                            -     * `angular.module` is used to configure the {@link AUTO.$injector $injector}.
                            +     * `angular.module` is used to configure the {@link auto.$injector $injector}.
                                  *
                                  * 
                                  * // Create a new module
                            @@ -137,12 +137,11 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#provider
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string} name service name
                                        * @param {Function} providerType Construction function for creating new instance of the
                                        *                                service.
                                        * @description
                            -           * See {@link AUTO.$provide#provider $provide.provider()}.
                            +           * See {@link auto.$provide#provider $provide.provider()}.
                                        */
                                       provider: invokeLater('$provide', 'provider'),
                             
                            @@ -150,11 +149,10 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#factory
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string} name service name
                                        * @param {Function} providerFunction Function for creating new instance of the service.
                                        * @description
                            -           * See {@link AUTO.$provide#factory $provide.factory()}.
                            +           * See {@link auto.$provide#factory $provide.factory()}.
                                        */
                                       factory: invokeLater('$provide', 'factory'),
                             
                            @@ -162,11 +160,10 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#service
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string} name service name
                                        * @param {Function} constructor A constructor function that will be instantiated.
                                        * @description
                            -           * See {@link AUTO.$provide#service $provide.service()}.
                            +           * See {@link auto.$provide#service $provide.service()}.
                                        */
                                       service: invokeLater('$provide', 'service'),
                             
                            @@ -174,11 +171,10 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#value
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string} name service name
                                        * @param {*} object Service instance object.
                                        * @description
                            -           * See {@link AUTO.$provide#value $provide.value()}.
                            +           * See {@link auto.$provide#value $provide.value()}.
                                        */
                                       value: invokeLater('$provide', 'value'),
                             
                            @@ -186,12 +182,11 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#constant
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string} name constant name
                                        * @param {*} object Constant value.
                                        * @description
                                        * Because the constant are fixed, they get applied before other provide methods.
                            -           * See {@link AUTO.$provide#constant $provide.constant()}.
                            +           * See {@link auto.$provide#constant $provide.constant()}.
                                        */
                                       constant: invokeLater('$provide', 'constant', 'unshift'),
                             
                            @@ -199,7 +194,6 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#animation
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string} name animation name
                                        * @param {Function} animationFactory Factory function for creating new instance of an
                                        *                                    animation.
                            @@ -234,7 +228,6 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#filter
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string} name Filter name.
                                        * @param {Function} filterFactory Factory function for creating new instance of filter.
                                        * @description
                            @@ -246,7 +239,6 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#controller
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string|Object} name Controller name, or an object map of controllers where the
                                        *    keys are the names and the values are the constructors.
                                        * @param {Function} constructor Controller constructor function.
                            @@ -259,7 +251,6 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#directive
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {string|Object} name Directive name, or an object map of directives where the
                                        *    keys are the names and the values are the factories.
                                        * @param {Function} directiveFactory Factory function for creating new instance of
                            @@ -273,7 +264,6 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#config
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {Function} configFn Execute this function on module load. Useful for service
                                        *    configuration.
                                        * @description
                            @@ -285,7 +275,6 @@ function setupModuleLoader(window) {
                                        * @ngdoc method
                                        * @name angular.Module#run
                                        * @module ng
                            -           * @methodOf angular.Module
                                        * @param {Function} initializationFn Execute this function after injector creation.
                                        *    Useful for application initialization.
                                        * @description
                            diff --git a/src/ng/anchorScroll.js b/src/ng/anchorScroll.js
                            index 4cef2bdf830b..4cb9a2756e0c 100644
                            --- a/src/ng/anchorScroll.js
                            +++ b/src/ng/anchorScroll.js
                            @@ -1,8 +1,9 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.$anchorScroll
                            + * @ngdoc service
                            + * @name $anchorScroll
                            + * @kind function
                              * @requires $window
                              * @requires $location
                              * @requires $rootScope
                            diff --git a/src/ng/animate.js b/src/ng/animate.js
                            index 1961d47be1f3..11a287e69839 100644
                            --- a/src/ng/animate.js
                            +++ b/src/ng/animate.js
                            @@ -3,8 +3,8 @@
                             var $animateMinErr = minErr('$animate');
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$animateProvider
                            + * @ngdoc provider
                            + * @name $animateProvider
                              *
                              * @description
                              * Default implementation of $animate that doesn't perform any animations, instead just
                            @@ -22,9 +22,8 @@ var $AnimateProvider = ['$provide', function($provide) {
                             
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.$animateProvider#register
                            -   * @methodOf ng.$animateProvider
                            +   * @ngdoc method
                            +   * @name $animateProvider#register
                                *
                                * @description
                                * Registers a new injectable animation factory function. The factory function produces the
                            @@ -62,9 +61,8 @@ var $AnimateProvider = ['$provide', function($provide) {
                               };
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.$animateProvider#classNameFilter
                            -   * @methodOf ng.$animateProvider
                            +   * @ngdoc method
                            +   * @name $animateProvider#classNameFilter
                                *
                                * @description
                                * Sets and/or returns the CSS class regular expression that is checked when performing
                            @@ -87,8 +85,8 @@ var $AnimateProvider = ['$provide', function($provide) {
                             
                                 /**
                                  *
                            -     * @ngdoc object
                            -     * @name ng.$animate
                            +     * @ngdoc service
                            +     * @name $animate
                                  * @description The $animate service provides rudimentary DOM manipulation functions to
                                  * insert, remove and move elements within the DOM, as well as adding and removing classes.
                                  * This service is the core service used by the ngAnimate $animator service which provides
                            @@ -106,9 +104,8 @@ var $AnimateProvider = ['$provide', function($provide) {
                             
                                   /**
                                    *
                            -       * @ngdoc function
                            -       * @name ng.$animate#enter
                            -       * @methodOf ng.$animate
                            +       * @ngdoc method
                            +       * @name $animate#enter
                                    * @function
                                    * @description Inserts the element into the DOM either after the `after` element or within
                                    *   the `parent` element. Once complete, the done() callback will be fired (if provided).
                            @@ -134,9 +131,8 @@ var $AnimateProvider = ['$provide', function($provide) {
                             
                                   /**
                                    *
                            -       * @ngdoc function
                            -       * @name ng.$animate#leave
                            -       * @methodOf ng.$animate
                            +       * @ngdoc method
                            +       * @name $animate#leave
                                    * @function
                                    * @description Removes the element from the DOM. Once complete, the done() callback will be
                                    *   fired (if provided).
                            @@ -151,9 +147,8 @@ var $AnimateProvider = ['$provide', function($provide) {
                             
                                   /**
                                    *
                            -       * @ngdoc function
                            -       * @name ng.$animate#move
                            -       * @methodOf ng.$animate
                            +       * @ngdoc method
                            +       * @name $animate#move
                                    * @function
                                    * @description Moves the position of the provided element within the DOM to be placed
                                    * either after the `after` element or inside of the `parent` element. Once complete, the
                            @@ -176,9 +171,8 @@ var $AnimateProvider = ['$provide', function($provide) {
                             
                                   /**
                                    *
                            -       * @ngdoc function
                            -       * @name ng.$animate#addClass
                            -       * @methodOf ng.$animate
                            +       * @ngdoc method
                            +       * @name $animate#addClass
                                    * @function
                                    * @description Adds the provided className CSS class value to the provided element. Once
                                    * complete, the done() callback will be fired (if provided).
                            @@ -200,9 +194,8 @@ var $AnimateProvider = ['$provide', function($provide) {
                             
                                   /**
                                    *
                            -       * @ngdoc function
                            -       * @name ng.$animate#removeClass
                            -       * @methodOf ng.$animate
                            +       * @ngdoc method
                            +       * @name $animate#removeClass
                                    * @function
                                    * @description Removes the provided className CSS class value from the provided element.
                                    * Once complete, the done() callback will be fired (if provided).
                            diff --git a/src/ng/browser.js b/src/ng/browser.js
                            index 73606fe7c2d8..52a0b9794e6b 100644
                            --- a/src/ng/browser.js
                            +++ b/src/ng/browser.js
                            @@ -3,7 +3,7 @@
                             /**
                              * ! This is a private undocumented service !
                              *
                            - * @name ng.$browser
                            + * @name $browser
                              * @requires $log
                              * @description
                              * This object has two goals:
                            @@ -87,8 +87,7 @@ function Browser(window, document, $log, $sniffer) {
                                   pollTimeout;
                             
                               /**
                            -   * @name ng.$browser#addPollFn
                            -   * @methodOf ng.$browser
                            +   * @name $browser#addPollFn
                                *
                                * @param {function()} fn Poll function to add
                                *
                            @@ -128,8 +127,7 @@ function Browser(window, document, $log, $sniffer) {
                                   newLocation = null;
                             
                               /**
                            -   * @name ng.$browser#url
                            -   * @methodOf ng.$browser
                            +   * @name $browser#url
                                *
                                * @description
                                * GETTER:
                            @@ -195,8 +193,7 @@ function Browser(window, document, $log, $sniffer) {
                               }
                             
                               /**
                            -   * @name ng.$browser#onUrlChange
                            -   * @methodOf ng.$browser
                            +   * @name $browser#onUrlChange
                                * @TODO(vojta): refactor to use node's syntax for events
                                *
                                * @description
                            @@ -242,8 +239,7 @@ function Browser(window, document, $log, $sniffer) {
                               //////////////////////////////////////////////////////////////
                             
                               /**
                            -   * @name ng.$browser#baseHref
                            -   * @methodOf ng.$browser
                            +   * @name $browser#baseHref
                                *
                                * @description
                                * Returns current 
                            @@ -264,8 +260,7 @@ function Browser(window, document, $log, $sniffer) {
                               var cookiePath = self.baseHref();
                             
                               /**
                            -   * @name ng.$browser#cookies
                            -   * @methodOf ng.$browser
                            +   * @name $browser#cookies
                                *
                                * @param {string=} name Cookie name
                                * @param {string=} value Cookie value
                            @@ -334,8 +329,7 @@ function Browser(window, document, $log, $sniffer) {
                             
                             
                               /**
                            -   * @name ng.$browser#defer
                            -   * @methodOf ng.$browser
                            +   * @name $browser#defer
                                * @param {function()} fn A function, who's execution should be deferred.
                                * @param {number=} [delay=0] of milliseconds to defer the function execution.
                                * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`.
                            @@ -361,8 +355,7 @@ function Browser(window, document, $log, $sniffer) {
                             
                             
                               /**
                            -   * @name ng.$browser#defer.cancel
                            -   * @methodOf ng.$browser.defer
                            +   * @name $browser#defer.cancel
                                *
                                * @description
                                * Cancels a deferred task identified with `deferId`.
                            diff --git a/src/ng/cacheFactory.js b/src/ng/cacheFactory.js
                            index 0e887c81e11b..32d179b4b3a6 100644
                            --- a/src/ng/cacheFactory.js
                            +++ b/src/ng/cacheFactory.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$cacheFactory
                            + * @ngdoc service
                            + * @name $cacheFactory
                              *
                              * @description
                              * Factory that constructs cache objects and gives access to them.
                            @@ -156,8 +156,7 @@ function $CacheFactoryProvider() {
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$cacheFactory#info
                            -   * @methodOf ng.$cacheFactory
                            +   * @name $cacheFactory#info
                                *
                                * @description
                                * Get information about all the of the caches that have been created
                            @@ -175,8 +174,7 @@ function $CacheFactoryProvider() {
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$cacheFactory#get
                            -   * @methodOf ng.$cacheFactory
                            +   * @name $cacheFactory#get
                                *
                                * @description
                                * Get access to a cache object by the `cacheId` used when it was created.
                            @@ -194,8 +192,8 @@ function $CacheFactoryProvider() {
                             }
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$templateCache
                            + * @ngdoc service
                            + * @name $templateCache
                              *
                              * @description
                              * The first time a template is used, it is loaded in the template cache for quick retrieval. You
                            diff --git a/src/ng/compile.js b/src/ng/compile.js
                            index ded62ea9a210..219f99aebb89 100644
                            --- a/src/ng/compile.js
                            +++ b/src/ng/compile.js
                            @@ -19,8 +19,8 @@
                             
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.$compile
                            + * @ngdoc service
                            + * @name $compile
                              * @function
                              *
                              * @description
                            @@ -491,8 +491,8 @@
                             var $compileMinErr = minErr('$compile');
                             
                             /**
                            - * @ngdoc service
                            - * @name ng.$compileProvider
                            + * @ngdoc provider
                            + * @name $compileProvider
                              * @function
                              *
                              * @description
                            @@ -511,9 +511,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
                               var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.$compileProvider#directive
                            -   * @methodOf ng.$compileProvider
                            +   * @ngdoc method
                            +   * @name $compileProvider#directive
                                * @function
                                *
                                * @description
                            @@ -565,9 +564,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
                             
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.$compileProvider#aHrefSanitizationWhitelist
                            -   * @methodOf ng.$compileProvider
                            +   * @ngdoc method
                            +   * @name $compileProvider#aHrefSanitizationWhitelist
                                * @function
                                *
                                * @description
                            @@ -596,9 +594,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
                             
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.$compileProvider#imgSrcSanitizationWhitelist
                            -   * @methodOf ng.$compileProvider
                            +   * @ngdoc method
                            +   * @name $compileProvider#imgSrcSanitizationWhitelist
                                * @function
                                *
                                * @description
                            @@ -641,9 +638,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
                             
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$compile.directive.Attributes#$addClass
                            -       * @methodOf ng.$compile.directive.Attributes
                            +       * @ngdoc method
                            +       * @name $compile.directive.Attributes#$addClass
                                    * @function
                                    *
                                    * @description
                            @@ -659,9 +655,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
                                   },
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$compile.directive.Attributes#$removeClass
                            -       * @methodOf ng.$compile.directive.Attributes
                            +       * @ngdoc method
                            +       * @name $compile.directive.Attributes#$removeClass
                                    * @function
                                    *
                                    * @description
                            @@ -677,9 +672,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
                                   },
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$compile.directive.Attributes#$updateClass
                            -       * @methodOf ng.$compile.directive.Attributes
                            +       * @ngdoc method
                            +       * @name $compile.directive.Attributes#$updateClass
                                    * @function
                                    *
                                    * @description
                            @@ -766,9 +760,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
                             
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$compile.directive.Attributes#$observe
                            -       * @methodOf ng.$compile.directive.Attributes
                            +       * @ngdoc method
                            +       * @name $compile.directive.Attributes#$observe
                                    * @function
                                    *
                                    * @description
                            @@ -1969,8 +1962,8 @@ function directiveNormalize(name) {
                             }
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$compile.directive.Attributes
                            + * @ngdoc type
                            + * @name $compile.directive.Attributes
                              *
                              * @description
                              * A shared object between directive compile / linking functions which contains normalized DOM
                            @@ -1982,17 +1975,15 @@ function directiveNormalize(name) {
                             
                             /**
                              * @ngdoc property
                            - * @name ng.$compile.directive.Attributes#$attr
                            - * @propertyOf ng.$compile.directive.Attributes
                            + * @name $compile.directive.Attributes#$attr
                              * @returns {object} A map of DOM element attribute names to the normalized name. This is
                              *                   needed to do reverse lookup from normalized name back to actual name.
                              */
                             
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.$compile.directive.Attributes#$set
                            - * @methodOf ng.$compile.directive.Attributes
                            + * @ngdoc method
                            + * @name $compile.directive.Attributes#$set
                              * @function
                              *
                              * @description
                            diff --git a/src/ng/controller.js b/src/ng/controller.js
                            index 938fbfbe82fc..1a610b9c62b8 100644
                            --- a/src/ng/controller.js
                            +++ b/src/ng/controller.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$controllerProvider
                            + * @ngdoc provider
                            + * @name $controllerProvider
                              * @description
                              * The {@link ng.$controller $controller service} is used by Angular to create new
                              * controllers.
                            @@ -16,9 +16,8 @@ function $ControllerProvider() {
                             
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.$controllerProvider#register
                            -   * @methodOf ng.$controllerProvider
                            +   * @ngdoc method
                            +   * @name $controllerProvider#register
                                * @param {string|Object} name Controller name, or an object map of controllers where the keys are
                                *    the names and the values are the constructors.
                                * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI
                            @@ -37,8 +36,8 @@ function $ControllerProvider() {
                               this.$get = ['$injector', '$window', function($injector, $window) {
                             
                                 /**
                            -     * @ngdoc function
                            -     * @name ng.$controller
                            +     * @ngdoc service
                            +     * @name $controller
                                  * @requires $injector
                                  *
                                  * @param {Function|string} constructor If called with a function then it's considered to be the
                            @@ -55,7 +54,7 @@ function $ControllerProvider() {
                                  * @description
                                  * `$controller` service is responsible for instantiating controllers.
                                  *
                            -     * It's just a simple call to {@link AUTO.$injector $injector}, but extracted into
                            +     * It's just a simple call to {@link auto.$injector $injector}, but extracted into
                                  * a service, so that one can override this service with {@link https://gist.github.com/1649788
                                  * BC version}.
                                  */
                            diff --git a/src/ng/directive/a.js b/src/ng/directive/a.js
                            index 9887cba535ce..850d7d6d3093 100644
                            --- a/src/ng/directive/a.js
                            +++ b/src/ng/directive/a.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:a
                            + * @name a
                              * @restrict E
                              *
                              * @description
                            diff --git a/src/ng/directive/booleanAttrs.js b/src/ng/directive/booleanAttrs.js
                            index 6762ab2d1e25..d2ba61df3ffe 100644
                            --- a/src/ng/directive/booleanAttrs.js
                            +++ b/src/ng/directive/booleanAttrs.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngHref
                            + * @name ngHref
                              * @restrict A
                              * @priority 99
                              *
                            @@ -95,7 +95,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngSrc
                            + * @name ngSrc
                              * @restrict A
                              * @priority 99
                              *
                            @@ -121,7 +121,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngSrcset
                            + * @name ngSrcset
                              * @restrict A
                              * @priority 99
                              *
                            @@ -147,7 +147,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngDisabled
                            + * @name ngDisabled
                              * @restrict A
                              * @priority 100
                              *
                            @@ -191,7 +191,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngChecked
                            + * @name ngChecked
                              * @restrict A
                              * @priority 100
                              *
                            @@ -226,7 +226,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngReadonly
                            + * @name ngReadonly
                              * @restrict A
                              * @priority 100
                              *
                            @@ -261,7 +261,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngSelected
                            + * @name ngSelected
                              * @restrict A
                              * @priority 100
                              *
                            @@ -299,7 +299,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngOpen
                            + * @name ngOpen
                              * @restrict A
                              * @priority 100
                              *
                            diff --git a/src/ng/directive/form.js b/src/ng/directive/form.js
                            index 86776ae7589f..310347307c46 100644
                            --- a/src/ng/directive/form.js
                            +++ b/src/ng/directive/form.js
                            @@ -10,8 +10,8 @@ var nullFormCtrl = {
                             };
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.directive:form.FormController
                            + * @ngdoc type
                            + * @name form.FormController
                              *
                              * @property {boolean} $pristine True if user has not interacted with the form yet.
                              * @property {boolean} $dirty True if user has already interacted with the form.
                            @@ -76,9 +76,8 @@ function FormController(element, attrs) {
                               }
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:form.FormController#$addControl
                            -   * @methodOf ng.directive:form.FormController
                            +   * @ngdoc method
                            +   * @name form.FormController#$addControl
                                *
                                * @description
                                * Register a control with the form.
                            @@ -97,9 +96,8 @@ function FormController(element, attrs) {
                               };
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:form.FormController#$removeControl
                            -   * @methodOf ng.directive:form.FormController
                            +   * @ngdoc method
                            +   * @name form.FormController#$removeControl
                                *
                                * @description
                                * Deregister a control from the form.
                            @@ -118,9 +116,8 @@ function FormController(element, attrs) {
                               };
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:form.FormController#$setValidity
                            -   * @methodOf ng.directive:form.FormController
                            +   * @ngdoc method
                            +   * @name form.FormController#$setValidity
                                *
                                * @description
                                * Sets the validity of a form control.
                            @@ -166,9 +163,8 @@ function FormController(element, attrs) {
                               };
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:form.FormController#$setDirty
                            -   * @methodOf ng.directive:form.FormController
                            +   * @ngdoc method
                            +   * @name form.FormController#$setDirty
                                *
                                * @description
                                * Sets the form to a dirty state.
                            @@ -184,9 +180,8 @@ function FormController(element, attrs) {
                               };
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:form.FormController#$setPristine
                            -   * @methodOf ng.directive:form.FormController
                            +   * @ngdoc method
                            +   * @name form.FormController#$setPristine
                                *
                                * @description
                                * Sets the form to its pristine state.
                            @@ -211,7 +206,7 @@ function FormController(element, attrs) {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngForm
                            + * @name ngForm
                              * @restrict EAC
                              *
                              * @description
                            @@ -226,7 +221,7 @@ function FormController(element, attrs) {
                             
                              /**
                              * @ngdoc directive
                            - * @name ng.directive:form
                            + * @name form
                              * @restrict E
                              *
                              * @description
                            diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js
                            index d80697a3438c..ced501671632 100644
                            --- a/src/ng/directive/input.js
                            +++ b/src/ng/directive/input.js
                            @@ -15,8 +15,8 @@ var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
                             var inputType = {
                             
                               /**
                            -   * @ngdoc inputType
                            -   * @name ng.directive:input.text
                            +   * @ngdoc input
                            +   * @name input[text]
                                *
                                * @description
                                * Standard HTML text input with angular data binding.
                            @@ -93,8 +93,8 @@ var inputType = {
                             
                             
                               /**
                            -   * @ngdoc inputType
                            -   * @name ng.directive:input.number
                            +   * @ngdoc input
                            +   * @name input[number]
                                *
                                * @description
                                * Text input with number validation and transformation. Sets the `number` validation
                            @@ -170,8 +170,8 @@ var inputType = {
                             
                             
                               /**
                            -   * @ngdoc inputType
                            -   * @name ng.directive:input.url
                            +   * @ngdoc input
                            +   * @name input[url]
                                *
                                * @description
                                * Text input with URL validation. Sets the `url` validation error key if the content is not a
                            @@ -246,8 +246,8 @@ var inputType = {
                             
                             
                               /**
                            -   * @ngdoc inputType
                            -   * @name ng.directive:input.email
                            +   * @ngdoc input
                            +   * @name input[email]
                                *
                                * @description
                                * Text input with email validation. Sets the `email` validation error key if not a valid email
                            @@ -321,8 +321,8 @@ var inputType = {
                             
                             
                               /**
                            -   * @ngdoc inputType
                            -   * @name ng.directive:input.radio
                            +   * @ngdoc input
                            +   * @name input[radio]
                                *
                                * @description
                                * HTML radio button.
                            @@ -372,8 +372,8 @@ var inputType = {
                             
                             
                               /**
                            -   * @ngdoc inputType
                            -   * @name ng.directive:input.checkbox
                            +   * @ngdoc input
                            +   * @name input[checkbox]
                                *
                                * @description
                                * HTML checkbox.
                            @@ -690,7 +690,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:textarea
                            + * @name textarea
                              * @restrict E
                              *
                              * @description
                            @@ -718,7 +718,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:input
                            + * @name input
                              * @restrict E
                              *
                              * @description
                            @@ -845,8 +845,8 @@ var VALID_CLASS = 'ng-valid',
                                 DIRTY_CLASS = 'ng-dirty';
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.directive:ngModel.NgModelController
                            + * @ngdoc type
                            + * @name ngModel.NgModelController
                              *
                              * @property {string} $viewValue Actual string value in the view.
                              * @property {*} $modelValue The value in the model, that the control is bound to.
                            @@ -1000,9 +1000,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
                               }
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:ngModel.NgModelController#$render
                            -   * @methodOf ng.directive:ngModel.NgModelController
                            +   * @ngdoc method
                            +   * @name ngModel.NgModelController#$render
                                *
                                * @description
                                * Called when the view needs to be updated. It is expected that the user of the ng-model
                            @@ -1011,9 +1010,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
                               this.$render = noop;
                             
                               /**
                            -   * @ngdoc function
                            -   * @name { ng.directive:ngModel.NgModelController#$isEmpty
                            -   * @methodOf ng.directive:ngModel.NgModelController
                            +   * @ngdoc method
                            +   * @name ngModel.NgModelController#$isEmpty
                                *
                                * @description
                                * This is called when we need to determine if the value of the input is empty.
                            @@ -1050,9 +1048,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
                               }
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:ngModel.NgModelController#$setValidity
                            -   * @methodOf ng.directive:ngModel.NgModelController
                            +   * @ngdoc method
                            +   * @name ngModel.NgModelController#$setValidity
                                *
                                * @description
                                * Change the validity state, and notifies the form when the control changes validity. (i.e. it
                            @@ -1094,9 +1091,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
                               };
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:ngModel.NgModelController#$setPristine
                            -   * @methodOf ng.directive:ngModel.NgModelController
                            +   * @ngdoc method
                            +   * @name ngModel.NgModelController#$setPristine
                                *
                                * @description
                                * Sets the control to its pristine state.
                            @@ -1111,9 +1107,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
                               };
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.directive:ngModel.NgModelController#$setViewValue
                            -   * @methodOf ng.directive:ngModel.NgModelController
                            +   * @ngdoc method
                            +   * @name ngModel.NgModelController#$setViewValue
                                *
                                * @description
                                * Update the view value.
                            @@ -1190,7 +1185,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngModel
                            + * @name ngModel
                              *
                              * @element input
                              *
                            @@ -1251,7 +1246,7 @@ var ngModelDirective = function() {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngChange
                            + * @name ngChange
                              *
                              * @description
                              * Evaluate the given expression when the user changes the input.
                            @@ -1347,7 +1342,7 @@ var requiredDirective = function() {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngList
                            + * @name ngList
                              *
                              * @description
                              * Text input that converts between a delimited string and an array of strings. The delimiter
                            @@ -1442,7 +1437,7 @@ var ngListDirective = function() {
                             var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngValue
                            + * @name ngValue
                              *
                              * @description
                              * Binds the given expression to the value of `input[select]` or `input[radio]`, so
                            diff --git a/src/ng/directive/ngBind.js b/src/ng/directive/ngBind.js
                            index 5d0e300926f4..82bbfab202b0 100644
                            --- a/src/ng/directive/ngBind.js
                            +++ b/src/ng/directive/ngBind.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngBind
                            + * @name ngBind
                              * @restrict AC
                              *
                              * @description
                            @@ -64,7 +64,7 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngBindTemplate
                            + * @name ngBindTemplate
                              *
                              * @description
                              * The `ngBindTemplate` directive specifies that the element
                            @@ -126,7 +126,7 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngBindHtml
                            + * @name ngBindHtml
                              *
                              * @description
                              * Creates a binding that will innerHTML the result of evaluating the `expression` into the current
                            diff --git a/src/ng/directive/ngClass.js b/src/ng/directive/ngClass.js
                            index 3f3ee4eb4331..17ace582bca1 100644
                            --- a/src/ng/directive/ngClass.js
                            +++ b/src/ng/directive/ngClass.js
                            @@ -64,7 +64,7 @@ function classDirective(name, selector) {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngClass
                            + * @name ngClass
                              * @restrict AC
                              *
                              * @description
                            @@ -198,7 +198,7 @@ var ngClassDirective = classDirective('', true);
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngClassOdd
                            + * @name ngClassOdd
                              * @restrict AC
                              *
                              * @description
                            @@ -246,7 +246,7 @@ var ngClassOddDirective = classDirective('Odd', 0);
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngClassEven
                            + * @name ngClassEven
                              * @restrict AC
                              *
                              * @description
                            diff --git a/src/ng/directive/ngCloak.js b/src/ng/directive/ngCloak.js
                            index 220c964dce0e..0ef5090f3037 100644
                            --- a/src/ng/directive/ngCloak.js
                            +++ b/src/ng/directive/ngCloak.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngCloak
                            + * @name ngCloak
                              * @restrict AC
                              *
                              * @description
                            diff --git a/src/ng/directive/ngController.js b/src/ng/directive/ngController.js
                            index 7149d090d5b9..6d294cc915a9 100644
                            --- a/src/ng/directive/ngController.js
                            +++ b/src/ng/directive/ngController.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngController
                            + * @name ngController
                              *
                              * @description
                              * The `ngController` directive attaches a controller class to the view. This is a key aspect of how angular
                            diff --git a/src/ng/directive/ngCsp.js b/src/ng/directive/ngCsp.js
                            index fc90d46ac9a1..9dc93f81c7cf 100644
                            --- a/src/ng/directive/ngCsp.js
                            +++ b/src/ng/directive/ngCsp.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngCsp
                            + * @name ngCsp
                              *
                              * @element html
                              * @description
                            diff --git a/src/ng/directive/ngEventDirs.js b/src/ng/directive/ngEventDirs.js
                            index 45b2d4048a9d..156acce18555 100644
                            --- a/src/ng/directive/ngEventDirs.js
                            +++ b/src/ng/directive/ngEventDirs.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngClick
                            + * @name ngClick
                              *
                              * @description
                              * The ngClick directive allows you to specify custom behavior when
                            @@ -60,7 +60,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngDblclick
                            + * @name ngDblclick
                              *
                              * @description
                              * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.
                            @@ -84,7 +84,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngMousedown
                            + * @name ngMousedown
                              *
                              * @description
                              * The ngMousedown directive allows you to specify custom behavior on mousedown event.
                            @@ -108,7 +108,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngMouseup
                            + * @name ngMouseup
                              *
                              * @description
                              * Specify custom behavior on mouseup event.
                            @@ -131,7 +131,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngMouseover
                            + * @name ngMouseover
                              *
                              * @description
                              * Specify custom behavior on mouseover event.
                            @@ -155,7 +155,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngMouseenter
                            + * @name ngMouseenter
                              *
                              * @description
                              * Specify custom behavior on mouseenter event.
                            @@ -179,7 +179,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngMouseleave
                            + * @name ngMouseleave
                              *
                              * @description
                              * Specify custom behavior on mouseleave event.
                            @@ -203,7 +203,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngMousemove
                            + * @name ngMousemove
                              *
                              * @description
                              * Specify custom behavior on mousemove event.
                            @@ -227,7 +227,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngKeydown
                            + * @name ngKeydown
                              *
                              * @description
                              * Specify custom behavior on keydown event.
                            @@ -249,7 +249,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngKeyup
                            + * @name ngKeyup
                              *
                              * @description
                              * Specify custom behavior on keyup event.
                            @@ -271,7 +271,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngKeypress
                            + * @name ngKeypress
                              *
                              * @description
                              * Specify custom behavior on keypress event.
                            @@ -292,7 +292,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngSubmit
                            + * @name ngSubmit
                              *
                              * @description
                              * Enables binding angular expressions to onsubmit events.
                            @@ -346,7 +346,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngFocus
                            + * @name ngFocus
                              *
                              * @description
                              * Specify custom behavior on focus event.
                            @@ -362,7 +362,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngBlur
                            + * @name ngBlur
                              *
                              * @description
                              * Specify custom behavior on blur event.
                            @@ -378,7 +378,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngCopy
                            + * @name ngCopy
                              *
                              * @description
                              * Specify custom behavior on copy event.
                            @@ -399,7 +399,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngCut
                            + * @name ngCut
                              *
                              * @description
                              * Specify custom behavior on cut event.
                            @@ -420,7 +420,7 @@ forEach(
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngPaste
                            + * @name ngPaste
                              *
                              * @description
                              * Specify custom behavior on paste event.
                            diff --git a/src/ng/directive/ngIf.js b/src/ng/directive/ngIf.js
                            index e132f13b02eb..9adb70804a51 100644
                            --- a/src/ng/directive/ngIf.js
                            +++ b/src/ng/directive/ngIf.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngIf
                            + * @name ngIf
                              * @restrict A
                              *
                              * @description
                            diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js
                            index b559b5765b37..47bf742f30f8 100644
                            --- a/src/ng/directive/ngInclude.js
                            +++ b/src/ng/directive/ngInclude.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngInclude
                            + * @name ngInclude
                              * @restrict ECA
                              *
                              * @description
                            @@ -145,7 +145,7 @@
                             
                             /**
                              * @ngdoc event
                            - * @name ng.directive:ngInclude#$includeContentRequested
                            + * @name ngInclude#$includeContentRequested
                              * @eventOf ng.directive:ngInclude
                              * @eventType emit on the scope ngInclude was declared in
                              * @description
                            @@ -155,7 +155,7 @@
                             
                             /**
                              * @ngdoc event
                            - * @name ng.directive:ngInclude#$includeContentLoaded
                            + * @name ngInclude#$includeContentLoaded
                              * @eventOf ng.directive:ngInclude
                              * @eventType emit on the current ngInclude scope
                              * @description
                            diff --git a/src/ng/directive/ngInit.js b/src/ng/directive/ngInit.js
                            index d5a1e24521d4..8dd05c9bccb5 100644
                            --- a/src/ng/directive/ngInit.js
                            +++ b/src/ng/directive/ngInit.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngInit
                            + * @name ngInit
                              * @restrict AC
                              *
                              * @description
                            diff --git a/src/ng/directive/ngNonBindable.js b/src/ng/directive/ngNonBindable.js
                            index 160733762b09..cf98f53139df 100644
                            --- a/src/ng/directive/ngNonBindable.js
                            +++ b/src/ng/directive/ngNonBindable.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngNonBindable
                            + * @name ngNonBindable
                              * @restrict AC
                              * @priority 1000
                              *
                            diff --git a/src/ng/directive/ngPluralize.js b/src/ng/directive/ngPluralize.js
                            index 58af4515ce28..a33735e9e0f4 100644
                            --- a/src/ng/directive/ngPluralize.js
                            +++ b/src/ng/directive/ngPluralize.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngPluralize
                            + * @name ngPluralize
                              * @restrict EA
                              *
                              * @description
                            diff --git a/src/ng/directive/ngRepeat.js b/src/ng/directive/ngRepeat.js
                            index e819877c26c0..f83bb88f449e 100644
                            --- a/src/ng/directive/ngRepeat.js
                            +++ b/src/ng/directive/ngRepeat.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngRepeat
                            + * @name ngRepeat
                              *
                              * @description
                              * The `ngRepeat` directive instantiates a template once per item from a collection. Each template
                            diff --git a/src/ng/directive/ngShowHide.js b/src/ng/directive/ngShowHide.js
                            index ba33bb1a69de..c4754bee38df 100644
                            --- a/src/ng/directive/ngShowHide.js
                            +++ b/src/ng/directive/ngShowHide.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngShow
                            + * @name ngShow
                              *
                              * @description
                              * The `ngShow` directive shows or hides the given HTML element based on the expression
                            @@ -159,7 +159,7 @@ var ngShowDirective = ['$animate', function($animate) {
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngHide
                            + * @name ngHide
                              *
                              * @description
                              * The `ngHide` directive shows or hides the given HTML element based on the expression
                            diff --git a/src/ng/directive/ngStyle.js b/src/ng/directive/ngStyle.js
                            index 05dcfab1394d..1722ca77f928 100644
                            --- a/src/ng/directive/ngStyle.js
                            +++ b/src/ng/directive/ngStyle.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngStyle
                            + * @name ngStyle
                              * @restrict AC
                              *
                              * @description
                            diff --git a/src/ng/directive/ngSwitch.js b/src/ng/directive/ngSwitch.js
                            index 97029d412356..0c9d476099ce 100644
                            --- a/src/ng/directive/ngSwitch.js
                            +++ b/src/ng/directive/ngSwitch.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngSwitch
                            + * @name ngSwitch
                              * @restrict EA
                              *
                              * @description
                            diff --git a/src/ng/directive/ngTransclude.js b/src/ng/directive/ngTransclude.js
                            index 86b5ff6100b4..95606b65aef2 100644
                            --- a/src/ng/directive/ngTransclude.js
                            +++ b/src/ng/directive/ngTransclude.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:ngTransclude
                            + * @name ngTransclude
                              * @restrict AC
                              *
                              * @description
                            diff --git a/src/ng/directive/script.js b/src/ng/directive/script.js
                            index e86285ae5743..229f35423af1 100644
                            --- a/src/ng/directive/script.js
                            +++ b/src/ng/directive/script.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:script
                            + * @name script
                              * @restrict E
                              *
                              * @description
                            diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js
                            index c4498f81e2d6..0b01e6126543 100644
                            --- a/src/ng/directive/select.js
                            +++ b/src/ng/directive/select.js
                            @@ -3,7 +3,7 @@
                             var ngOptionsMinErr = minErr('ngOptions');
                             /**
                              * @ngdoc directive
                            - * @name ng.directive:select
                            + * @name select
                              * @restrict E
                              *
                              * @description
                            diff --git a/src/ng/document.js b/src/ng/document.js
                            index 570f9360faa1..cc7604773d61 100644
                            --- a/src/ng/document.js
                            +++ b/src/ng/document.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$document
                            + * @ngdoc service
                            + * @name $document
                              * @requires $window
                              *
                              * @description
                            diff --git a/src/ng/exceptionHandler.js b/src/ng/exceptionHandler.js
                            index c3795bb7b516..13f775ef933a 100644
                            --- a/src/ng/exceptionHandler.js
                            +++ b/src/ng/exceptionHandler.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.$exceptionHandler
                            + * @ngdoc service
                            + * @name $exceptionHandler
                              * @requires $log
                              *
                              * @description
                            diff --git a/src/ng/filter.js b/src/ng/filter.js
                            index 15180edb4ffd..8e4254e24603 100644
                            --- a/src/ng/filter.js
                            +++ b/src/ng/filter.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$filterProvider
                            + * @ngdoc provider
                            + * @name $filterProvider
                              * @description
                              *
                              * Filters are just functions which transform input to an output. However filters need to be
                            @@ -51,8 +51,7 @@
                              */
                             /**
                              * @ngdoc method
                            - * @name ng.$filterProvider#register
                            - * @methodOf ng.$filterProvider
                            + * @name $filterProvider#register
                              * @description
                              * Register filter factory function.
                              *
                            @@ -62,8 +61,8 @@
                             
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.$filter
                            + * @ngdoc service
                            + * @name $filter
                              * @function
                              * @description
                              * Filters are used for formatting data displayed to the user.
                            @@ -80,9 +79,8 @@ function $FilterProvider($provide) {
                               var suffix = 'Filter';
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.$controllerProvider#register
                            -   * @methodOf ng.$controllerProvider
                            +   * @ngdoc method
                            +   * @name $controllerProvider#register
                                * @param {string|Object} name Name of the filter function, or an object map of filters where
                                *    the keys are the filter names and the values are the filter factories.
                                * @returns {Object} Registered filter instance, or if a map of filters was provided then a map
                            diff --git a/src/ng/filter/filter.js b/src/ng/filter/filter.js
                            index 2bb0d1743949..a7ac1d0af6be 100644
                            --- a/src/ng/filter/filter.js
                            +++ b/src/ng/filter/filter.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc filter
                            - * @name ng.filter:filter
                            + * @name filter
                              * @function
                              *
                              * @description
                            diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js
                            index b8cc655c3630..85bf120f974a 100644
                            --- a/src/ng/filter/filters.js
                            +++ b/src/ng/filter/filters.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc filter
                            - * @name ng.filter:currency
                            + * @name currency
                              * @function
                              *
                              * @description
                            @@ -59,7 +59,7 @@ function currencyFilter($locale) {
                             
                             /**
                              * @ngdoc filter
                            - * @name ng.filter:number
                            + * @name number
                              * @function
                              *
                              * @description
                            @@ -271,7 +271,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
                             
                             /**
                              * @ngdoc filter
                            - * @name ng.filter:date
                            + * @name date
                              * @function
                              *
                              * @description
                            @@ -428,7 +428,7 @@ function dateFilter($locale) {
                             
                             /**
                              * @ngdoc filter
                            - * @name ng.filter:json
                            + * @name json
                              * @function
                              *
                              * @description
                            @@ -463,7 +463,7 @@ function jsonFilter() {
                             
                             /**
                              * @ngdoc filter
                            - * @name ng.filter:lowercase
                            + * @name lowercase
                              * @function
                              * @description
                              * Converts string to lowercase.
                            @@ -474,7 +474,7 @@ var lowercaseFilter = valueFn(lowercase);
                             
                             /**
                              * @ngdoc filter
                            - * @name ng.filter:uppercase
                            + * @name uppercase
                              * @function
                              * @description
                              * Converts string to uppercase.
                            diff --git a/src/ng/filter/limitTo.js b/src/ng/filter/limitTo.js
                            index bb1756f2c86b..264cba1c4fc5 100644
                            --- a/src/ng/filter/limitTo.js
                            +++ b/src/ng/filter/limitTo.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.filter:limitTo
                            + * @ngdoc filter
                            + * @name limitTo
                              * @function
                              *
                              * @description
                            diff --git a/src/ng/filter/orderBy.js b/src/ng/filter/orderBy.js
                            index 4127f9020b3e..3e06ac95c1a3 100644
                            --- a/src/ng/filter/orderBy.js
                            +++ b/src/ng/filter/orderBy.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.filter:orderBy
                            + * @ngdoc filter
                            + * @name orderBy
                              * @function
                              *
                              * @description
                            diff --git a/src/ng/http.js b/src/ng/http.js
                            index 57dc71721d10..aa8c4071eb17 100644
                            --- a/src/ng/http.js
                            +++ b/src/ng/http.js
                            @@ -171,8 +171,9 @@ function $HttpProvider() {
                             
                             
                                 /**
                            -     * @ngdoc function
                            -     * @name ng.$http
                            +     * @ngdoc service
                            +     * @kind function
                            +     * @name $http
                                  * @requires $httpBackend
                                  * @requires $browser
                                  * @requires $cacheFactory
                            @@ -797,8 +798,7 @@ function $HttpProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$http#get
                            -     * @methodOf ng.$http
                            +     * @name $http#get
                                  *
                                  * @description
                                  * Shortcut method to perform `GET` request.
                            @@ -810,8 +810,7 @@ function $HttpProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$http#delete
                            -     * @methodOf ng.$http
                            +     * @name $http#delete
                                  *
                                  * @description
                                  * Shortcut method to perform `DELETE` request.
                            @@ -823,8 +822,7 @@ function $HttpProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$http#head
                            -     * @methodOf ng.$http
                            +     * @name $http#head
                                  *
                                  * @description
                                  * Shortcut method to perform `HEAD` request.
                            @@ -836,8 +834,7 @@ function $HttpProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$http#jsonp
                            -     * @methodOf ng.$http
                            +     * @name $http#jsonp
                                  *
                                  * @description
                                  * Shortcut method to perform `JSONP` request.
                            @@ -851,8 +848,7 @@ function $HttpProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$http#post
                            -     * @methodOf ng.$http
                            +     * @name $http#post
                                  *
                                  * @description
                                  * Shortcut method to perform `POST` request.
                            @@ -865,8 +861,7 @@ function $HttpProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$http#put
                            -     * @methodOf ng.$http
                            +     * @name $http#put
                                  *
                                  * @description
                                  * Shortcut method to perform `PUT` request.
                            @@ -880,7 +875,7 @@ function $HttpProvider() {
                             
                                     /**
                                      * @ngdoc property
                            -         * @name ng.$http#defaults
                            +         * @name $http#defaults
                                      * @propertyOf ng.$http
                                      *
                                      * @description
                            diff --git a/src/ng/httpBackend.js b/src/ng/httpBackend.js
                            index efe72060facb..415cd19f8f74 100644
                            --- a/src/ng/httpBackend.js
                            +++ b/src/ng/httpBackend.js
                            @@ -15,8 +15,8 @@ function createXhr(method) {
                             }
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$httpBackend
                            + * @ngdoc service
                            + * @name $httpBackend
                              * @requires $browser
                              * @requires $window
                              * @requires $document
                            diff --git a/src/ng/interpolate.js b/src/ng/interpolate.js
                            index 1c02c40fb4a4..0665fd250a46 100644
                            --- a/src/ng/interpolate.js
                            +++ b/src/ng/interpolate.js
                            @@ -3,8 +3,8 @@
                             var $interpolateMinErr = minErr('$interpolate');
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$interpolateProvider
                            + * @ngdoc provider
                            + * @name $interpolateProvider
                              * @function
                              *
                              * @description
                            @@ -44,8 +44,7 @@ function $InterpolateProvider() {
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$interpolateProvider#startSymbol
                            -   * @methodOf ng.$interpolateProvider
                            +   * @name $interpolateProvider#startSymbol
                                * @description
                                * Symbol to denote start of expression in the interpolated string. Defaults to `{{`.
                                *
                            @@ -63,8 +62,7 @@ function $InterpolateProvider() {
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$interpolateProvider#endSymbol
                            -   * @methodOf ng.$interpolateProvider
                            +   * @name $interpolateProvider#endSymbol
                                * @description
                                * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
                                *
                            @@ -86,8 +84,8 @@ function $InterpolateProvider() {
                                     endSymbolLength = endSymbol.length;
                             
                                 /**
                            -     * @ngdoc function
                            -     * @name ng.$interpolate
                            +     * @ngdoc service
                            +     * @name $interpolate
                                  * @function
                                  *
                                  * @requires $parse
                            @@ -205,8 +203,7 @@ function $InterpolateProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$interpolate#startSymbol
                            -     * @methodOf ng.$interpolate
                            +     * @name $interpolate#startSymbol
                                  * @description
                                  * Symbol to denote the start of expression in the interpolated string. Defaults to `{{`.
                                  *
                            @@ -222,8 +219,7 @@ function $InterpolateProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$interpolate#endSymbol
                            -     * @methodOf ng.$interpolate
                            +     * @name $interpolate#endSymbol
                                  * @description
                                  * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
                                  *
                            diff --git a/src/ng/interval.js b/src/ng/interval.js
                            index cd823f591537..d528ebe12030 100644
                            --- a/src/ng/interval.js
                            +++ b/src/ng/interval.js
                            @@ -8,8 +8,8 @@ function $IntervalProvider() {
                             
                             
                                  /**
                            -      * @ngdoc function
                            -      * @name ng.$interval
                            +      * @ngdoc service
                            +      * @name $interval
                                   *
                                   * @description
                                   * Angular's wrapper for `window.setInterval`. The `fn` function is executed every `delay`
                            @@ -162,9 +162,8 @@ function $IntervalProvider() {
                             
                             
                                  /**
                            -      * @ngdoc function
                            -      * @name ng.$interval#cancel
                            -      * @methodOf ng.$interval
                            +      * @ngdoc method
                            +      * @name $interval#cancel
                                   *
                                   * @description
                                   * Cancels a task associated with the `promise`.
                            diff --git a/src/ng/locale.js b/src/ng/locale.js
                            index 23df4275fd06..b498f47dd93d 100644
                            --- a/src/ng/locale.js
                            +++ b/src/ng/locale.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$locale
                            + * @ngdoc service
                            + * @name $locale
                              *
                              * @description
                              * $locale service provides localization rules for various Angular components. As of right now the
                            diff --git a/src/ng/location.js b/src/ng/location.js
                            index e89c026b1d3f..48cc7a1ed011 100644
                            --- a/src/ng/location.js
                            +++ b/src/ng/location.js
                            @@ -289,8 +289,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#absUrl
                            -   * @methodOf ng.$location
                            +   * @name $location#absUrl
                                *
                                * @description
                                * This method is getter only.
                            @@ -304,8 +303,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#url
                            -   * @methodOf ng.$location
                            +   * @name $location#url
                                *
                                * @description
                                * This method is getter / setter.
                            @@ -332,8 +330,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#protocol
                            -   * @methodOf ng.$location
                            +   * @name $location#protocol
                                *
                                * @description
                                * This method is getter only.
                            @@ -346,8 +343,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#host
                            -   * @methodOf ng.$location
                            +   * @name $location#host
                                *
                                * @description
                                * This method is getter only.
                            @@ -360,8 +356,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#port
                            -   * @methodOf ng.$location
                            +   * @name $location#port
                                *
                                * @description
                                * This method is getter only.
                            @@ -374,8 +369,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#path
                            -   * @methodOf ng.$location
                            +   * @name $location#path
                                *
                                * @description
                                * This method is getter / setter.
                            @@ -396,8 +390,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#search
                            -   * @methodOf ng.$location
                            +   * @name $location#search
                                *
                                * @description
                                * This method is getter / setter.
                            @@ -444,8 +437,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#hash
                            -   * @methodOf ng.$location
                            +   * @name $location#hash
                                *
                                * @description
                                * This method is getter / setter.
                            @@ -461,8 +453,7 @@ LocationHashbangInHtml5Url.prototype =
                             
                               /**
                                * @ngdoc method
                            -   * @name ng.$location#replace
                            -   * @methodOf ng.$location
                            +   * @name $location#replace
                                *
                                * @description
                                * If called, all changes to $location during current `$digest` will be replacing current history
                            @@ -495,8 +486,8 @@ function locationGetterSetter(property, preprocess) {
                             
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$location
                            + * @ngdoc service
                            + * @name $location
                              *
                              * @requires $browser
                              * @requires $sniffer
                            @@ -525,7 +516,7 @@ function locationGetterSetter(property, preprocess) {
                             
                             /**
                              * @ngdoc object
                            - * @name ng.$locationProvider
                            + * @name $locationProvider
                              * @description
                              * Use the `$locationProvider` to configure how the application deep linking paths are stored.
                              */
                            @@ -536,8 +527,7 @@ function $LocationProvider(){
                             
                               /**
                                * @ngdoc property
                            -   * @name ng.$locationProvider#hashPrefix
                            -   * @methodOf ng.$locationProvider
                            +   * @name $locationProvider#hashPrefix
                                * @description
                                * @param {string=} prefix Prefix for hash part (containing path and search)
                                * @returns {*} current value if used as getter or itself (chaining) if used as setter
                            @@ -553,8 +543,7 @@ function $LocationProvider(){
                             
                               /**
                                * @ngdoc property
                            -   * @name ng.$locationProvider#html5Mode
                            -   * @methodOf ng.$locationProvider
                            +   * @name $locationProvider#html5Mode
                                * @description
                                * @param {boolean=} mode Use HTML5 strategy if available.
                                * @returns {*} current value if used as getter or itself (chaining) if used as setter
                            @@ -590,8 +579,7 @@ function $LocationProvider(){
                             
                               /**
                                * @ngdoc event
                            -   * @name ng.$location#$locationChangeStart
                            -   * @eventOf ng.$location
                            +   * @name $location#$locationChangeStart
                                * @eventType broadcast on root scope
                                * @description
                                * Broadcasted before a URL will change. This change can be prevented by calling
                            @@ -606,8 +594,7 @@ function $LocationProvider(){
                             
                               /**
                                * @ngdoc event
                            -   * @name ng.$location#$locationChangeSuccess
                            -   * @eventOf ng.$location
                            +   * @name $location#$locationChangeSuccess
                                * @eventType broadcast on root scope
                                * @description
                                * Broadcasted after a URL was changed.
                            diff --git a/src/ng/log.js b/src/ng/log.js
                            index 31e87a23fab5..e228701b599b 100644
                            --- a/src/ng/log.js
                            +++ b/src/ng/log.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$log
                            + * @ngdoc service
                            + * @name $log
                              * @requires $window
                              *
                              * @description
                            @@ -37,8 +37,8 @@
                              */
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$logProvider
                            + * @ngdoc provider
                            + * @name $logProvider
                              * @description
                              * Use the `$logProvider` to configure how the application logs messages
                              */
                            @@ -48,8 +48,7 @@ function $LogProvider(){
                               
                               /**
                                * @ngdoc property
                            -   * @name ng.$logProvider#debugEnabled
                            -   * @methodOf ng.$logProvider
                            +   * @name $logProvider#debugEnabled
                                * @description
                                * @param {boolean=} flag enable or disable debug level messages
                                * @returns {*} current value if used as getter or itself (chaining) if used as setter
                            @@ -67,8 +66,7 @@ function $LogProvider(){
                                 return {
                                   /**
                                    * @ngdoc method
                            -       * @name ng.$log#log
                            -       * @methodOf ng.$log
                            +       * @name $log#log
                                    *
                                    * @description
                                    * Write a log message
                            @@ -77,8 +75,7 @@ function $LogProvider(){
                             
                                   /**
                                    * @ngdoc method
                            -       * @name ng.$log#info
                            -       * @methodOf ng.$log
                            +       * @name $log#info
                                    *
                                    * @description
                                    * Write an information message
                            @@ -87,8 +84,7 @@ function $LogProvider(){
                             
                                   /**
                                    * @ngdoc method
                            -       * @name ng.$log#warn
                            -       * @methodOf ng.$log
                            +       * @name $log#warn
                                    *
                                    * @description
                                    * Write a warning message
                            @@ -97,8 +93,7 @@ function $LogProvider(){
                             
                                   /**
                                    * @ngdoc method
                            -       * @name ng.$log#error
                            -       * @methodOf ng.$log
                            +       * @name $log#error
                                    *
                                    * @description
                                    * Write an error message
                            @@ -107,8 +102,7 @@ function $LogProvider(){
                                   
                                   /**
                                    * @ngdoc method
                            -       * @name ng.$log#debug
                            -       * @methodOf ng.$log
                            +       * @name $log#debug
                                    * 
                                    * @description
                                    * Write a debug message
                            diff --git a/src/ng/parse.js b/src/ng/parse.js
                            index b5adf7e94b23..f84c8fa77d9e 100644
                            --- a/src/ng/parse.js
                            +++ b/src/ng/parse.js
                            @@ -1083,9 +1083,9 @@ function getterFn(path, options, fullExp) {
                             ///////////////////////////////////
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.$parse
                            - * @function
                            + * @ngdoc service
                            + * @name $parse
                            + * @kind function
                              *
                              * @description
                              *
                            @@ -1124,8 +1124,8 @@ function getterFn(path, options, fullExp) {
                             
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$parseProvider
                            + * @ngdoc provider
                            + * @name $parseProvider
                              * @function
                              *
                              * @description
                            @@ -1146,8 +1146,7 @@ function $ParseProvider() {
                                * @deprecated Promise unwrapping via $parse is deprecated and will be removed in the future.
                                *
                                * @ngdoc method
                            -   * @name ng.$parseProvider#unwrapPromises
                            -   * @methodOf ng.$parseProvider
                            +   * @name $parseProvider#unwrapPromises
                                * @description
                                *
                                * **This feature is deprecated, see deprecation notes below for more info**
                            @@ -1201,8 +1200,7 @@ function $ParseProvider() {
                                * @deprecated Promise unwrapping via $parse is deprecated and will be removed in the future.
                                *
                                * @ngdoc method
                            -   * @name ng.$parseProvider#logPromiseWarnings
                            -   * @methodOf ng.$parseProvider
                            +   * @name $parseProvider#logPromiseWarnings
                                * @description
                                *
                                * Controls whether Angular should log a warning on any encounter of a promise in an expression.
                            diff --git a/src/ng/q.js b/src/ng/q.js
                            index d080734603ad..38a63f53c7d5 100644
                            --- a/src/ng/q.js
                            +++ b/src/ng/q.js
                            @@ -2,7 +2,7 @@
                             
                             /**
                              * @ngdoc service
                            - * @name ng.$q
                            + * @name $q
                              * @requires $rootScope
                              *
                              * @description
                            @@ -190,8 +190,7 @@ function qFactory(nextTick, exceptionHandler) {
                             
                               /**
                                * @ngdoc
                            -   * @name ng.$q#defer
                            -   * @methodOf ng.$q
                            +   * @name $q#defer
                                * @description
                                * Creates a `Deferred` object which represents a task which will finish in the future.
                                *
                            @@ -346,8 +345,7 @@ function qFactory(nextTick, exceptionHandler) {
                             
                               /**
                                * @ngdoc
                            -   * @name ng.$q#reject
                            -   * @methodOf ng.$q
                            +   * @name $q#reject
                                * @description
                                * Creates a promise that is resolved as rejected with the specified `reason`. This api should be
                                * used to forward rejection in a chain of promises. If you are dealing with the last promise in
                            @@ -405,8 +403,7 @@ function qFactory(nextTick, exceptionHandler) {
                             
                               /**
                                * @ngdoc
                            -   * @name ng.$q#when
                            -   * @methodOf ng.$q
                            +   * @name $q#when
                                * @description
                                * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
                                * This is useful when you are dealing with an object that might or might not be a promise, or if
                            @@ -476,8 +473,7 @@ function qFactory(nextTick, exceptionHandler) {
                             
                               /**
                                * @ngdoc
                            -   * @name ng.$q#all
                            -   * @methodOf ng.$q
                            +   * @name $q#all
                                * @description
                                * Combines multiple promises into a single promise that is resolved when all of the input
                                * promises are resolved.
                            diff --git a/src/ng/rootElement.js b/src/ng/rootElement.js
                            index 9385050e6e2e..09fb8ddb0470 100644
                            --- a/src/ng/rootElement.js
                            +++ b/src/ng/rootElement.js
                            @@ -1,14 +1,14 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc overview
                            - * @name ng.$rootElement
                            + * @ngdoc service
                            + * @name $rootElement
                              *
                              * @description
                              * The root element of Angular application. This is either the element where {@link
                              * ng.directive:ngApp ngApp} was declared or the element passed into
                              * {@link angular.bootstrap}. The element represent the root element of application. It is also the
                            - * location where the applications {@link AUTO.$injector $injector} service gets
                            + * location where the applications {@link auto.$injector $injector} service gets
                              * published, it can be retrieved using `$rootElement.injector()`.
                              */
                             
                            diff --git a/src/ng/rootScope.js b/src/ng/rootScope.js
                            index c90d28a6cf24..d5be52b0f996 100644
                            --- a/src/ng/rootScope.js
                            +++ b/src/ng/rootScope.js
                            @@ -27,17 +27,16 @@
                             
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$rootScopeProvider
                            + * @ngdoc provider
                            + * @name $rootScopeProvider
                              * @description
                              *
                              * Provider for the $rootScope service.
                              */
                             
                             /**
                            - * @ngdoc function
                            - * @name ng.$rootScopeProvider#digestTtl
                            - * @methodOf ng.$rootScopeProvider
                            + * @ngdoc method
                            + * @name $rootScopeProvider#digestTtl
                              * @description
                              *
                              * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and
                            @@ -58,8 +57,8 @@
                             
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$rootScope
                            + * @ngdoc service
                            + * @name $rootScope
                              * @description
                              *
                              * Every application has a single root {@link ng.$rootScope.Scope scope}.
                            @@ -84,12 +83,12 @@ function $RootScopeProvider(){
                                   function( $injector,   $exceptionHandler,   $parse,   $browser) {
                             
                                 /**
                            -     * @ngdoc function
                            -     * @name ng.$rootScope.Scope
                            +     * @ngdoc type
                            +     * @name $rootScope.Scope
                                  *
                                  * @description
                                  * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the
                            -     * {@link AUTO.$injector $injector}. Child scopes are created using the
                            +     * {@link auto.$injector $injector}. Child scopes are created using the
                                  * {@link ng.$rootScope.Scope#methods_$new $new()} method. (Most scopes are created automatically when
                                  * compiled HTML template is executed.)
                                  *
                            @@ -139,7 +138,7 @@ function $RootScopeProvider(){
                             
                                 /**
                                  * @ngdoc property
                            -     * @name ng.$rootScope.Scope#$id
                            +     * @name $rootScope.Scope#$id
                                  * @propertyOf ng.$rootScope.Scope
                                  * @returns {number} Unique scope ID (monotonically increasing alphanumeric sequence) useful for
                                  *   debugging.
                            @@ -149,9 +148,8 @@ function $RootScopeProvider(){
                                 Scope.prototype = {
                                   constructor: Scope,
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$new
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$new
                                    * @function
                                    *
                                    * @description
                            @@ -207,9 +205,8 @@ function $RootScopeProvider(){
                                   },
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$watch
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$watch
                                    * @function
                                    *
                                    * @description
                            @@ -359,9 +356,8 @@ function $RootScopeProvider(){
                             
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$watchCollection
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$watchCollection
                                    * @function
                                    *
                                    * @description
                            @@ -499,9 +495,8 @@ function $RootScopeProvider(){
                                   },
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$digest
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$digest
                                    * @function
                                    *
                                    * @description
                            @@ -656,7 +651,7 @@ function $RootScopeProvider(){
                             
                                   /**
                                    * @ngdoc event
                            -       * @name ng.$rootScope.Scope#$destroy
                            +       * @name $rootScope.Scope#$destroy
                                    * @eventOf ng.$rootScope.Scope
                                    * @eventType broadcast on scope being destroyed
                                    *
                            @@ -668,9 +663,8 @@ function $RootScopeProvider(){
                                    */
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$destroy
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$destroy
                                    * @function
                                    *
                                    * @description
                            @@ -713,9 +707,8 @@ function $RootScopeProvider(){
                                   },
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$eval
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$eval
                                    * @function
                                    *
                                    * @description
                            @@ -746,9 +739,8 @@ function $RootScopeProvider(){
                                   },
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$evalAsync
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$evalAsync
                                    * @function
                                    *
                                    * @description
                            @@ -794,9 +786,8 @@ function $RootScopeProvider(){
                                   },
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$apply
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$apply
                                    * @function
                                    *
                                    * @description
                            @@ -857,9 +848,8 @@ function $RootScopeProvider(){
                                   },
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$on
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$on
                                    * @function
                                    *
                                    * @description
                            @@ -907,9 +897,8 @@ function $RootScopeProvider(){
                             
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$emit
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$emit
                                    * @function
                                    *
                                    * @description
                            @@ -976,9 +965,8 @@ function $RootScopeProvider(){
                             
                             
                                   /**
                            -       * @ngdoc function
                            -       * @name ng.$rootScope.Scope#$broadcast
                            -       * @methodOf ng.$rootScope.Scope
                            +       * @ngdoc method
                            +       * @name $rootScope.Scope#$broadcast
                                    * @function
                                    *
                                    * @description
                            diff --git a/src/ng/sce.js b/src/ng/sce.js
                            index a7d616a5a41b..d52a3a16c02c 100644
                            --- a/src/ng/sce.js
                            +++ b/src/ng/sce.js
                            @@ -64,7 +64,7 @@ function adjustMatchers(matchers) {
                             
                             /**
                              * @ngdoc service
                            - * @name ng.$sceDelegate
                            + * @name $sceDelegate
                              * @function
                              *
                              * @description
                            @@ -90,8 +90,8 @@ function adjustMatchers(matchers) {
                              */
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$sceDelegateProvider
                            + * @ngdoc provider
                            + * @name $sceDelegateProvider
                              * @description
                              *
                              * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
                            @@ -135,9 +135,8 @@ function $SceDelegateProvider() {
                                   resourceUrlBlacklist = [];
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.sceDelegateProvider#resourceUrlWhitelist
                            -   * @methodOf ng.$sceDelegateProvider
                            +   * @ngdoc method
                            +   * @name sceDelegateProvider#resourceUrlWhitelist
                                * @function
                                *
                                * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
                            @@ -165,9 +164,8 @@ function $SceDelegateProvider() {
                               };
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.sceDelegateProvider#resourceUrlBlacklist
                            -   * @methodOf ng.$sceDelegateProvider
                            +   * @ngdoc method
                            +   * @name sceDelegateProvider#resourceUrlBlacklist
                                * @function
                                *
                                * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
                            @@ -270,8 +268,7 @@ function $SceDelegateProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sceDelegate#trustAs
                            -     * @methodOf ng.$sceDelegate
                            +     * @name $sceDelegate#trustAs
                                  *
                                  * @description
                                  * Returns an object that is trusted by angular for use in specified strict
                            @@ -308,8 +305,7 @@ function $SceDelegateProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sceDelegate#valueOf
                            -     * @methodOf ng.$sceDelegate
                            +     * @name $sceDelegate#valueOf
                                  *
                                  * @description
                                  * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#methods_trustAs
                            @@ -335,8 +331,7 @@ function $SceDelegateProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sceDelegate#getTrusted
                            -     * @methodOf ng.$sceDelegate
                            +     * @name $sceDelegate#getTrusted
                                  *
                                  * @description
                                  * Takes the result of a {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`} call and
                            @@ -382,8 +377,8 @@ function $SceDelegateProvider() {
                             
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$sceProvider
                            + * @ngdoc provider
                            + * @name $sceProvider
                              * @description
                              *
                              * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service.
                            @@ -397,7 +392,7 @@ function $SceDelegateProvider() {
                             
                             /**
                              * @ngdoc service
                            - * @name ng.$sce
                            + * @name $sce
                              * @function
                              *
                              * @description
                            @@ -667,9 +662,8 @@ function $SceProvider() {
                               var enabled = true;
                             
                               /**
                            -   * @ngdoc function
                            -   * @name ng.sceProvider#enabled
                            -   * @methodOf ng.$sceProvider
                            +   * @ngdoc method
                            +   * @name sceProvider#enabled
                                * @function
                                *
                                * @param {boolean=} value If provided, then enables/disables SCE.
                            @@ -746,9 +740,8 @@ function $SceProvider() {
                                 var sce = copy(SCE_CONTEXTS);
                             
                                 /**
                            -     * @ngdoc function
                            -     * @name ng.sce#isEnabled
                            -     * @methodOf ng.$sce
                            +     * @ngdoc method
                            +     * @name sce#isEnabled
                                  * @function
                                  *
                                  * @return {Boolean} true if SCE is enabled, false otherwise.  If you want to set the value, you
                            @@ -771,8 +764,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#parse
                            -     * @methodOf ng.$sce
                            +     * @name $sce#parse
                                  *
                                  * @description
                                  * Converts Angular {@link guide/expression expression} into a function.  This is like {@link
                            @@ -802,8 +794,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#trustAs
                            -     * @methodOf ng.$sce
                            +     * @name $sce#trustAs
                                  *
                                  * @description
                                  * Delegates to {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}.  As such,
                            @@ -822,8 +813,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#trustAsHtml
                            -     * @methodOf ng.$sce
                            +     * @name $sce#trustAsHtml
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.trustAsHtml(value)` →
                            @@ -838,8 +828,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#trustAsUrl
                            -     * @methodOf ng.$sce
                            +     * @name $sce#trustAsUrl
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.trustAsUrl(value)` →
                            @@ -854,8 +843,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#trustAsResourceUrl
                            -     * @methodOf ng.$sce
                            +     * @name $sce#trustAsResourceUrl
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.trustAsResourceUrl(value)` →
                            @@ -870,8 +858,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#trustAsJs
                            -     * @methodOf ng.$sce
                            +     * @name $sce#trustAsJs
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.trustAsJs(value)` →
                            @@ -886,8 +873,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#getTrusted
                            -     * @methodOf ng.$sce
                            +     * @name $sce#getTrusted
                                  *
                                  * @description
                                  * Delegates to {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted`}.  As such,
                            @@ -905,8 +891,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#getTrustedHtml
                            -     * @methodOf ng.$sce
                            +     * @name $sce#getTrustedHtml
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.getTrustedHtml(value)` →
                            @@ -918,8 +903,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#getTrustedCss
                            -     * @methodOf ng.$sce
                            +     * @name $sce#getTrustedCss
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.getTrustedCss(value)` →
                            @@ -931,8 +915,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#getTrustedUrl
                            -     * @methodOf ng.$sce
                            +     * @name $sce#getTrustedUrl
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.getTrustedUrl(value)` →
                            @@ -944,8 +927,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#getTrustedResourceUrl
                            -     * @methodOf ng.$sce
                            +     * @name $sce#getTrustedResourceUrl
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.getTrustedResourceUrl(value)` →
                            @@ -957,8 +939,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#getTrustedJs
                            -     * @methodOf ng.$sce
                            +     * @name $sce#getTrustedJs
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.getTrustedJs(value)` →
                            @@ -970,8 +951,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#parseAsHtml
                            -     * @methodOf ng.$sce
                            +     * @name $sce#parseAsHtml
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.parseAsHtml(expression string)` →
                            @@ -988,8 +968,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#parseAsCss
                            -     * @methodOf ng.$sce
                            +     * @name $sce#parseAsCss
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.parseAsCss(value)` →
                            @@ -1006,8 +985,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#parseAsUrl
                            -     * @methodOf ng.$sce
                            +     * @name $sce#parseAsUrl
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.parseAsUrl(value)` →
                            @@ -1024,8 +1002,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#parseAsResourceUrl
                            -     * @methodOf ng.$sce
                            +     * @name $sce#parseAsResourceUrl
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.parseAsResourceUrl(value)` →
                            @@ -1042,8 +1019,7 @@ function $SceProvider() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ng.$sce#parseAsJs
                            -     * @methodOf ng.$sce
                            +     * @name $sce#parseAsJs
                                  *
                                  * @description
                                  * Shorthand method.  `$sce.parseAsJs(value)` →
                            diff --git a/src/ng/sniffer.js b/src/ng/sniffer.js
                            index 52acc8702d29..c225ab8c1ff2 100644
                            --- a/src/ng/sniffer.js
                            +++ b/src/ng/sniffer.js
                            @@ -3,7 +3,7 @@
                             /**
                              * !!! This is an undocumented "private" service !!!
                              *
                            - * @name ng.$sniffer
                            + * @name $sniffer
                              * @requires $window
                              * @requires $document
                              *
                            diff --git a/src/ng/timeout.js b/src/ng/timeout.js
                            index 511a0a05d4fe..ff87c93b8cd2 100644
                            --- a/src/ng/timeout.js
                            +++ b/src/ng/timeout.js
                            @@ -8,8 +8,8 @@ function $TimeoutProvider() {
                             
                             
                                  /**
                            -      * @ngdoc function
                            -      * @name ng.$timeout
                            +      * @ngdoc service
                            +      * @name $timeout
                                   * @requires $browser
                                   *
                                   * @description
                            @@ -61,9 +61,8 @@ function $TimeoutProvider() {
                             
                             
                                  /**
                            -      * @ngdoc function
                            -      * @name ng.$timeout#cancel
                            -      * @methodOf ng.$timeout
                            +      * @ngdoc method
                            +      * @name $timeout#cancel
                                   *
                                   * @description
                                   * Cancels a task associated with the `promise`. As a result of this, the promise will be
                            diff --git a/src/ng/window.js b/src/ng/window.js
                            index 4f0717afa489..94f8b8843776 100644
                            --- a/src/ng/window.js
                            +++ b/src/ng/window.js
                            @@ -1,8 +1,8 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc object
                            - * @name ng.$window
                            + * @ngdoc service
                            + * @name $window
                              *
                              * @description
                              * A reference to the browser's `window` object. While `window`
                            diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js
                            index 0ecb65156094..c257921bb084 100644
                            --- a/src/ngAnimate/animate.js
                            +++ b/src/ngAnimate/animate.js
                            @@ -2,7 +2,7 @@
                             /* jshint maxlen: false */
                             
                             /**
                            - * @ngdoc overview
                            + * @ngdoc module
                              * @name ngAnimate
                              * @description
                              *
                            @@ -235,8 +235,8 @@
                             angular.module('ngAnimate', ['ng'])
                             
                               /**
                            -   * @ngdoc object
                            -   * @name ngAnimate.$animateProvider
                            +   * @ngdoc provider
                            +   * @name $animateProvider
                                * @description
                                *
                                * The `$animateProvider` allows developers to register JavaScript animation event handlers directly inside of a module.
                            @@ -367,8 +367,8 @@ angular.module('ngAnimate', ['ng'])
                                   }
                             
                                   /**
                            -       * @ngdoc object
                            -       * @name ngAnimate.$animate
                            +       * @ngdoc service
                            +       * @name $animate
                                    * @function
                                    *
                                    * @description
                            @@ -387,9 +387,8 @@ angular.module('ngAnimate', ['ng'])
                                    */
                                   return {
                                     /**
                            -         * @ngdoc function
                            -         * @name ngAnimate.$animate#enter
                            -         * @methodOf ngAnimate.$animate
                            +         * @ngdoc method
                            +         * @name $animate#enter
                                      * @function
                                      *
                                      * @description
                            @@ -426,9 +425,8 @@ angular.module('ngAnimate', ['ng'])
                                     },
                             
                                     /**
                            -         * @ngdoc function
                            -         * @name ngAnimate.$animate#leave
                            -         * @methodOf ngAnimate.$animate
                            +         * @ngdoc method
                            +         * @name $animate#leave
                                      * @function
                                      *
                                      * @description
                            @@ -465,9 +463,8 @@ angular.module('ngAnimate', ['ng'])
                                     },
                             
                                     /**
                            -         * @ngdoc function
                            -         * @name ngAnimate.$animate#move
                            -         * @methodOf ngAnimate.$animate
                            +         * @ngdoc method
                            +         * @name $animate#move
                                      * @function
                                      *
                                      * @description
                            @@ -506,9 +503,8 @@ angular.module('ngAnimate', ['ng'])
                                     },
                             
                                     /**
                            -         * @ngdoc function
                            -         * @name ngAnimate.$animate#addClass
                            -         * @methodOf ngAnimate.$animate
                            +         * @ngdoc method
                            +         * @name $animate#addClass
                                      *
                                      * @description
                                      * Triggers a custom animation event based off the className variable and then attaches the className value to the element as a CSS class.
                            @@ -543,9 +539,8 @@ angular.module('ngAnimate', ['ng'])
                                     },
                             
                                     /**
                            -         * @ngdoc function
                            -         * @name ngAnimate.$animate#removeClass
                            -         * @methodOf ngAnimate.$animate
                            +         * @ngdoc method
                            +         * @name $animate#removeClass
                                      *
                                      * @description
                                      * Triggers a custom animation event based off the className variable and then removes the CSS class provided by the className value
                            @@ -602,9 +597,8 @@ angular.module('ngAnimate', ['ng'])
                                     },
                             
                                     /**
                            -         * @ngdoc function
                            -         * @name ngAnimate.$animate#enabled
                            -         * @methodOf ngAnimate.$animate
                            +         * @ngdoc method
                            +         * @name $animate#enabled
                                      * @function
                                      *
                                      * @param {boolean=} value If provided then set the animation on or off.
                            diff --git a/src/ngCookies/cookies.js b/src/ngCookies/cookies.js
                            index 94964bf8f1d4..ffa124c0b546 100644
                            --- a/src/ngCookies/cookies.js
                            +++ b/src/ngCookies/cookies.js
                            @@ -1,7 +1,7 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc overview
                            + * @ngdoc module
                              * @name ngCookies
                              * @description
                              *
                            @@ -20,8 +20,8 @@
                             
                             angular.module('ngCookies', ['ng']).
                               /**
                            -   * @ngdoc object
                            -   * @name ngCookies.$cookies
                            +   * @ngdoc service
                            +   * @name $cookies
                                * @requires $browser
                                *
                                * @description
                            @@ -129,8 +129,8 @@ angular.module('ngCookies', ['ng']).
                             
                             
                               /**
                            -   * @ngdoc object
                            -   * @name ngCookies.$cookieStore
                            +   * @ngdoc service
                            +   * @name $cookieStore
                                * @requires $cookies
                                *
                                * @description
                            @@ -147,8 +147,7 @@ angular.module('ngCookies', ['ng']).
                                   return {
                                     /**
                                      * @ngdoc method
                            -         * @name ngCookies.$cookieStore#get
                            -         * @methodOf ngCookies.$cookieStore
                            +         * @name $cookieStore#get
                                      *
                                      * @description
                                      * Returns the value of given cookie key
                            @@ -163,8 +162,7 @@ angular.module('ngCookies', ['ng']).
                             
                                     /**
                                      * @ngdoc method
                            -         * @name ngCookies.$cookieStore#put
                            -         * @methodOf ngCookies.$cookieStore
                            +         * @name $cookieStore#put
                                      *
                                      * @description
                                      * Sets a value for given cookie key
                            @@ -178,8 +176,7 @@ angular.module('ngCookies', ['ng']).
                             
                                     /**
                                      * @ngdoc method
                            -         * @name ngCookies.$cookieStore#remove
                            -         * @methodOf ngCookies.$cookieStore
                            +         * @name $cookieStore#remove
                                      *
                                      * @description
                                      * Remove given cookie
                            diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js
                            index ba79fc881643..1c276f2929f8 100644
                            --- a/src/ngMock/angular-mocks.js
                            +++ b/src/ngMock/angular-mocks.js
                            @@ -1,7 +1,7 @@
                             'use strict';
                             
                             /**
                            - * @ngdoc overview
                            + * @ngdoc object
                              * @name angular.mock
                              * @description
                              *
                            @@ -12,7 +12,7 @@ angular.mock = {};
                             /**
                              * ! This is a private undocumented service !
                              *
                            - * @name ngMock.$browser
                            + * @name $browser
                              *
                              * @description
                              * This service is a mock implementation of {@link ng.$browser}. It provides fake
                            @@ -70,8 +70,7 @@ angular.mock.$Browser = function() {
                             
                             
                               /**
                            -   * @name ngMock.$browser#defer.now
                            -   * @propertyOf ngMock.$browser
                            +   * @name $browser#defer.now
                                *
                                * @description
                                * Current milliseconds mock time.
                            @@ -96,8 +95,7 @@ angular.mock.$Browser = function() {
                             
                             
                               /**
                            -   * @name ngMock.$browser#defer.flush
                            -   * @methodOf ngMock.$browser
                            +   * @name $browser#defer.flush
                                *
                                * @description
                                * Flushes all pending requests and executes the defer callbacks.
                            @@ -128,8 +126,7 @@ angular.mock.$Browser = function() {
                             angular.mock.$Browser.prototype = {
                             
                             /**
                            -  * @name ngMock.$browser#poll
                            -  * @methodOf ngMock.$browser
                            +  * @name $browser#poll
                               *
                               * @description
                               * run all fns in pollFns
                            @@ -180,8 +177,8 @@ angular.mock.$Browser.prototype = {
                             
                             
                             /**
                            - * @ngdoc object
                            - * @name ngMock.$exceptionHandlerProvider
                            + * @ngdoc provider
                            + * @name $exceptionHandlerProvider
                              *
                              * @description
                              * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors
                            @@ -189,8 +186,8 @@ angular.mock.$Browser.prototype = {
                              */
                             
                             /**
                            - * @ngdoc object
                            - * @name ngMock.$exceptionHandler
                            + * @ngdoc service
                            + * @name $exceptionHandler
                              *
                              * @description
                              * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed
                            @@ -227,8 +224,7 @@ angular.mock.$ExceptionHandlerProvider = function() {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$exceptionHandlerProvider#mode
                            -   * @methodOf ngMock.$exceptionHandlerProvider
                            +   * @name $exceptionHandlerProvider#mode
                                *
                                * @description
                                * Sets the logging mode.
                            @@ -278,7 +274,7 @@ angular.mock.$ExceptionHandlerProvider = function() {
                             
                             /**
                              * @ngdoc service
                            - * @name ngMock.$log
                            + * @name $log
                              *
                              * @description
                              * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays
                            @@ -317,8 +313,7 @@ angular.mock.$LogProvider = function() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ngMock.$log#reset
                            -     * @methodOf ngMock.$log
                            +     * @name $log#reset
                                  *
                                  * @description
                                  * Reset all of the logging arrays to empty.
                            @@ -326,8 +321,7 @@ angular.mock.$LogProvider = function() {
                                 $log.reset = function () {
                                   /**
                                    * @ngdoc property
                            -       * @name ngMock.$log#log.logs
                            -       * @propertyOf ngMock.$log
                            +       * @name $log#log.logs
                                    *
                                    * @description
                                    * Array of messages logged using {@link ngMock.$log#log}.
                            @@ -341,8 +335,7 @@ angular.mock.$LogProvider = function() {
                                   $log.log.logs = [];
                                   /**
                                    * @ngdoc property
                            -       * @name ngMock.$log#info.logs
                            -       * @propertyOf ngMock.$log
                            +       * @name $log#info.logs
                                    *
                                    * @description
                                    * Array of messages logged using {@link ngMock.$log#info}.
                            @@ -356,8 +349,7 @@ angular.mock.$LogProvider = function() {
                                   $log.info.logs = [];
                                   /**
                                    * @ngdoc property
                            -       * @name ngMock.$log#warn.logs
                            -       * @propertyOf ngMock.$log
                            +       * @name $log#warn.logs
                                    *
                                    * @description
                                    * Array of messages logged using {@link ngMock.$log#warn}.
                            @@ -371,8 +363,7 @@ angular.mock.$LogProvider = function() {
                                   $log.warn.logs = [];
                                   /**
                                    * @ngdoc property
                            -       * @name ngMock.$log#error.logs
                            -       * @propertyOf ngMock.$log
                            +       * @name $log#error.logs
                                    *
                                    * @description
                                    * Array of messages logged using {@link ngMock.$log#error}.
                            @@ -386,8 +377,7 @@ angular.mock.$LogProvider = function() {
                                   $log.error.logs = [];
                                     /**
                                    * @ngdoc property
                            -       * @name ngMock.$log#debug.logs
                            -       * @propertyOf ngMock.$log
                            +       * @name $log#debug.logs
                                    *
                                    * @description
                                    * Array of messages logged using {@link ngMock.$log#debug}.
                            @@ -403,8 +393,7 @@ angular.mock.$LogProvider = function() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ngMock.$log#assertEmpty
                            -     * @methodOf ngMock.$log
                            +     * @name $log#assertEmpty
                                  *
                                  * @description
                                  * Assert that the all of the logging methods have no logged messages. If messages present, an
                            @@ -436,7 +425,7 @@ angular.mock.$LogProvider = function() {
                             
                             /**
                              * @ngdoc service
                            - * @name ngMock.$interval
                            + * @name $interval
                              *
                              * @description
                              * Mock implementation of the $interval service.
                            @@ -522,8 +511,7 @@ angular.mock.$IntervalProvider = function() {
                             
                                 /**
                                  * @ngdoc method
                            -     * @name ngMock.$interval#flush
                            -     * @methodOf ngMock.$interval
                            +     * @name $interval#flush
                                  * @description
                                  *
                                  * Runs interval tasks scheduled to be run in the next `millis` milliseconds.
                            @@ -594,7 +582,7 @@ function padNumber(num, digits, trim) {
                             
                             
                             /**
                            - * @ngdoc object
                            + * @ngdoc type
                              * @name angular.mock.TzDate
                              * @description
                              *
                            @@ -871,8 +859,8 @@ angular.mock.dump = function(object) {
                             };
                             
                             /**
                            - * @ngdoc object
                            - * @name ngMock.$httpBackend
                            + * @ngdoc service
                            + * @name $httpBackend
                              * @description
                              * Fake HTTP backend implementation suitable for unit testing applications that use the
                              * {@link ng.$http $http service}.
                            @@ -1174,8 +1162,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#when
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#when
                                * @description
                                * Creates a new backend definition.
                                *
                            @@ -1214,8 +1201,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#whenGET
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#whenGET
                                * @description
                                * Creates a new backend definition for GET requests. For more info see `when()`.
                                *
                            @@ -1227,8 +1213,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#whenHEAD
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#whenHEAD
                                * @description
                                * Creates a new backend definition for HEAD requests. For more info see `when()`.
                                *
                            @@ -1240,8 +1225,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#whenDELETE
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#whenDELETE
                                * @description
                                * Creates a new backend definition for DELETE requests. For more info see `when()`.
                                *
                            @@ -1253,8 +1237,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#whenPOST
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#whenPOST
                                * @description
                                * Creates a new backend definition for POST requests. For more info see `when()`.
                                *
                            @@ -1268,8 +1251,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#whenPUT
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#whenPUT
                                * @description
                                * Creates a new backend definition for PUT requests.  For more info see `when()`.
                                *
                            @@ -1283,8 +1265,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#whenJSONP
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#whenJSONP
                                * @description
                                * Creates a new backend definition for JSONP requests. For more info see `when()`.
                                *
                            @@ -1297,8 +1278,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#expect
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#expect
                                * @description
                                * Creates a new request expectation.
                                *
                            @@ -1331,8 +1311,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#expectGET
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#expectGET
                                * @description
                                * Creates a new request expectation for GET requests. For more info see `expect()`.
                                *
                            @@ -1344,8 +1323,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#expectHEAD
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#expectHEAD
                                * @description
                                * Creates a new request expectation for HEAD requests. For more info see `expect()`.
                                *
                            @@ -1357,8 +1335,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#expectDELETE
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#expectDELETE
                                * @description
                                * Creates a new request expectation for DELETE requests. For more info see `expect()`.
                                *
                            @@ -1370,8 +1347,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#expectPOST
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#expectPOST
                                * @description
                                * Creates a new request expectation for POST requests. For more info see `expect()`.
                                *
                            @@ -1386,8 +1362,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#expectPUT
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#expectPUT
                                * @description
                                * Creates a new request expectation for PUT requests. For more info see `expect()`.
                                *
                            @@ -1402,8 +1377,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#expectPATCH
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#expectPATCH
                                * @description
                                * Creates a new request expectation for PATCH requests. For more info see `expect()`.
                                *
                            @@ -1418,8 +1392,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#expectJSONP
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#expectJSONP
                                * @description
                                * Creates a new request expectation for JSONP requests. For more info see `expect()`.
                                *
                            @@ -1432,8 +1405,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#flush
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#flush
                                * @description
                                * Flushes all pending requests using the trained responses.
                                *
                            @@ -1461,8 +1433,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#verifyNoOutstandingExpectation
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#verifyNoOutstandingExpectation
                                * @description
                                * Verifies that all of the requests defined via the `expect` api were made. If any of the
                                * requests were not made, verifyNoOutstandingExpectation throws an exception.
                            @@ -1484,8 +1455,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#verifyNoOutstandingRequest
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#verifyNoOutstandingRequest
                                * @description
                                * Verifies that there are no outstanding requests that need to be flushed.
                                *
                            @@ -1505,8 +1475,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$httpBackend#resetExpectations
                            -   * @methodOf ngMock.$httpBackend
                            +   * @name $httpBackend#resetExpectations
                                * @description
                                * Resets all request expectations, but preserves all backend definitions. Typically, you would
                                * call resetExpectations during a multiple-phase test when you want to reuse the same instance of
                            @@ -1629,8 +1598,8 @@ function MockXhr() {
                             
                             
                             /**
                            - * @ngdoc function
                            - * @name ngMock.$timeout
                            + * @ngdoc service
                            + * @name $timeout
                              * @description
                              *
                              * This service is just a simple decorator for {@link ng.$timeout $timeout} service
                            @@ -1641,8 +1610,7 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$timeout#flush
                            -   * @methodOf ngMock.$timeout
                            +   * @name $timeout#flush
                                * @description
                                *
                                * Flushes the queue of pending tasks.
                            @@ -1655,8 +1623,7 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
                             
                               /**
                                * @ngdoc method
                            -   * @name ngMock.$timeout#verifyNoPendingTasks
                            -   * @methodOf ngMock.$timeout
                            +   * @name $timeout#verifyNoPendingTasks
                                * @description
                                *
                                * Verifies that there are no pending tasks that need to be flushed.
                            @@ -1690,7 +1657,7 @@ angular.mock.$RootElementProvider = function() {
                             };
                             
                             /**
                            - * @ngdoc overview
                            + * @ngdoc module
                              * @name ngMock
                              * @description
                              *
                            @@ -1717,8 +1684,9 @@ angular.module('ngMock', ['ng']).provider({
                             }]);
                             
                             /**
                            - * @ngdoc overview
                            + * @ngdoc module
                              * @name ngMockE2E
                            + * @module ngMockE2E
                              * @description
                              *
                              * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing.
                            @@ -1730,8 +1698,9 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             }]);
                             
                             /**
                            - * @ngdoc object
                            - * @name ngMockE2E.$httpBackend
                            + * @ngdoc service
                            + * @name $httpBackend
                            + * @module ngMockE2E
                              * @description
                              * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of
                              * applications that use the {@link ng.$http $http service}.
                            @@ -1779,8 +1748,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             
                             /**
                              * @ngdoc method
                            - * @name ngMockE2E.$httpBackend#when
                            - * @methodOf ngMockE2E.$httpBackend
                            + * @name $httpBackend#when
                            + * @module ngMockE2E
                              * @description
                              * Creates a new backend definition.
                              *
                            @@ -1804,8 +1773,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             
                             /**
                              * @ngdoc method
                            - * @name ngMockE2E.$httpBackend#whenGET
                            - * @methodOf ngMockE2E.$httpBackend
                            + * @name $httpBackend#whenGET
                            + * @module ngMockE2E
                              * @description
                              * Creates a new backend definition for GET requests. For more info see `when()`.
                              *
                            @@ -1817,8 +1786,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             
                             /**
                              * @ngdoc method
                            - * @name ngMockE2E.$httpBackend#whenHEAD
                            - * @methodOf ngMockE2E.$httpBackend
                            + * @name $httpBackend#whenHEAD
                            + * @module ngMockE2E
                              * @description
                              * Creates a new backend definition for HEAD requests. For more info see `when()`.
                              *
                            @@ -1830,8 +1799,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             
                             /**
                              * @ngdoc method
                            - * @name ngMockE2E.$httpBackend#whenDELETE
                            - * @methodOf ngMockE2E.$httpBackend
                            + * @name $httpBackend#whenDELETE
                            + * @module ngMockE2E
                              * @description
                              * Creates a new backend definition for DELETE requests. For more info see `when()`.
                              *
                            @@ -1843,8 +1812,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             
                             /**
                              * @ngdoc method
                            - * @name ngMockE2E.$httpBackend#whenPOST
                            - * @methodOf ngMockE2E.$httpBackend
                            + * @name $httpBackend#whenPOST
                            + * @module ngMockE2E
                              * @description
                              * Creates a new backend definition for POST requests. For more info see `when()`.
                              *
                            @@ -1857,8 +1826,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             
                             /**
                              * @ngdoc method
                            - * @name ngMockE2E.$httpBackend#whenPUT
                            - * @methodOf ngMockE2E.$httpBackend
                            + * @name $httpBackend#whenPUT
                            + * @module ngMockE2E
                              * @description
                              * Creates a new backend definition for PUT requests.  For more info see `when()`.
                              *
                            @@ -1871,8 +1840,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             
                             /**
                              * @ngdoc method
                            - * @name ngMockE2E.$httpBackend#whenPATCH
                            - * @methodOf ngMockE2E.$httpBackend
                            + * @name $httpBackend#whenPATCH
                            + * @module ngMockE2E
                              * @description
                              * Creates a new backend definition for PATCH requests.  For more info see `when()`.
                              *
                            @@ -1885,8 +1854,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
                             
                             /**
                              * @ngdoc method
                            - * @name ngMockE2E.$httpBackend#whenJSONP
                            - * @methodOf ngMockE2E.$httpBackend
                            + * @name $httpBackend#whenJSONP
                            + * @module ngMockE2E
                              * @description
                              * Creates a new backend definition for JSONP requests. For more info see `when()`.
                              *
                            @@ -2003,7 +1972,7 @@ if(window.jasmine || window.mocha) {
                                * *NOTE*: This function is also published on window for easy access.
                            * * The inject function wraps a function into an injectable function. The inject() creates new - * instance of {@link AUTO.$injector $injector} per test, which is then used for + * instance of {@link auto.$injector $injector} per test, which is then used for * resolving references. * * diff --git a/src/ngResource/resource.js b/src/ngResource/resource.js index 1ab31bf55609..a75aab617046 100644 --- a/src/ngResource/resource.js +++ b/src/ngResource/resource.js @@ -44,7 +44,7 @@ function shallowClearAndCopy(src, dst) { } /** - * @ngdoc overview + * @ngdoc module * @name ngResource * @description * @@ -61,8 +61,8 @@ function shallowClearAndCopy(src, dst) { */ /** - * @ngdoc object - * @name ngResource.$resource + * @ngdoc service + * @name $resource * @requires $http * * @description diff --git a/src/ngRoute/directive/ngView.js b/src/ngRoute/directive/ngView.js index a88d205d2ce1..f61fb121a448 100644 --- a/src/ngRoute/directive/ngView.js +++ b/src/ngRoute/directive/ngView.js @@ -6,7 +6,7 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory); /** * @ngdoc directive - * @name ngRoute.directive:ngView + * @name ngView * @restrict ECA * * @description @@ -172,8 +172,7 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory); /** * @ngdoc event - * @name ngRoute.directive:ngView#$viewContentLoaded - * @eventOf ngRoute.directive:ngView + * @name ngView#$viewContentLoaded * @eventType emit on the current ngView scope * @description * Emitted every time the ngView content is reloaded. diff --git a/src/ngRoute/route.js b/src/ngRoute/route.js index 51404fbc509b..c313d2174dc8 100644 --- a/src/ngRoute/route.js +++ b/src/ngRoute/route.js @@ -1,7 +1,7 @@ 'use strict'; /** - * @ngdoc overview + * @ngdoc module * @name ngRoute * @description * @@ -21,8 +21,8 @@ var ngRouteModule = angular.module('ngRoute', ['ng']). provider('$route', $RouteProvider); /** - * @ngdoc object - * @name ngRoute.$routeProvider + * @ngdoc provider + * @name $routeProvider * @function * * @description @@ -44,8 +44,7 @@ function $RouteProvider(){ /** * @ngdoc method - * @name ngRoute.$routeProvider#when - * @methodOf ngRoute.$routeProvider + * @name $routeProvider#when * * @param {string} path Route path (matched against `$location.path`). If `$location.path` * contains redundant trailing slash or is missing one, the route will still match and the @@ -107,7 +106,7 @@ function $RouteProvider(){ * * - `key` – `{string}`: a name of a dependency to be injected into the controller. * - `factory` - `{string|function}`: If `string` then it is an alias for a service. - * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected} + * Otherwise if function, then it is {@link api/auto.$injector#invoke injected} * and the return value is treated as the dependency. If the result is a promise, it is * resolved before its value is injected into the controller. Be aware that * `ngRoute.$routeParams` will still refer to the previous route within these resolve @@ -207,8 +206,7 @@ function $RouteProvider(){ /** * @ngdoc method - * @name ngRoute.$routeProvider#otherwise - * @methodOf ngRoute.$routeProvider + * @name $routeProvider#otherwise * * @description * Sets route definition that will be used on route change when no other route definition @@ -234,8 +232,8 @@ function $RouteProvider(){ function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) { /** - * @ngdoc object - * @name ngRoute.$route + * @ngdoc service + * @name $route * @requires $location * @requires $routeParams * @@ -365,8 +363,7 @@ function $RouteProvider(){ /** * @ngdoc event - * @name ngRoute.$route#$routeChangeStart - * @eventOf ngRoute.$route + * @name $route#$routeChangeStart * @eventType broadcast on root scope * @description * Broadcasted before a route change. At this point the route services starts @@ -382,8 +379,7 @@ function $RouteProvider(){ /** * @ngdoc event - * @name ngRoute.$route#$routeChangeSuccess - * @eventOf ngRoute.$route + * @name $route#$routeChangeSuccess * @eventType broadcast on root scope * @description * Broadcasted after a route dependencies are resolved. @@ -398,8 +394,7 @@ function $RouteProvider(){ /** * @ngdoc event - * @name ngRoute.$route#$routeChangeError - * @eventOf ngRoute.$route + * @name $route#$routeChangeError * @eventType broadcast on root scope * @description * Broadcasted if any of the resolve promises are rejected. @@ -412,8 +407,7 @@ function $RouteProvider(){ /** * @ngdoc event - * @name ngRoute.$route#$routeUpdate - * @eventOf ngRoute.$route + * @name $route#$routeUpdate * @eventType broadcast on root scope * @description * @@ -427,8 +421,7 @@ function $RouteProvider(){ /** * @ngdoc method - * @name ngRoute.$route#reload - * @methodOf ngRoute.$route + * @name $route#reload * * @description * Causes `$route` service to reload the current route even if diff --git a/src/ngRoute/routeParams.js b/src/ngRoute/routeParams.js index e7b9da7a411b..977a26bc12c6 100644 --- a/src/ngRoute/routeParams.js +++ b/src/ngRoute/routeParams.js @@ -4,8 +4,8 @@ ngRouteModule.provider('$routeParams', $RouteParamsProvider); /** - * @ngdoc object - * @name ngRoute.$routeParams + * @ngdoc service + * @name $routeParams * @requires $route * * @description diff --git a/src/ngSanitize/filter/linky.js b/src/ngSanitize/filter/linky.js index da96ad2fa542..43019f335ccc 100644 --- a/src/ngSanitize/filter/linky.js +++ b/src/ngSanitize/filter/linky.js @@ -4,7 +4,7 @@ /** * @ngdoc filter - * @name ngSanitize.filter:linky + * @name linky * @function * * @description diff --git a/src/ngSanitize/sanitize.js b/src/ngSanitize/sanitize.js index 1b6cb94ef9e5..6b1e99ea744c 100644 --- a/src/ngSanitize/sanitize.js +++ b/src/ngSanitize/sanitize.js @@ -3,7 +3,7 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize'); /** - * @ngdoc overview + * @ngdoc module * @name ngSanitize * @description * @@ -37,7 +37,7 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize'); /** * @ngdoc service - * @name ngSanitize.$sanitize + * @name $sanitize * @function * * @description diff --git a/src/ngTouch/directive/ngClick.js b/src/ngTouch/directive/ngClick.js index 10ae3efc07bb..c2eaac5c5e44 100644 --- a/src/ngTouch/directive/ngClick.js +++ b/src/ngTouch/directive/ngClick.js @@ -4,7 +4,7 @@ /** * @ngdoc directive - * @name ngTouch.directive:ngClick + * @name ngClick * * @description * A more powerful replacement for the default ngClick designed to be used on touchscreen diff --git a/src/ngTouch/directive/ngSwipe.js b/src/ngTouch/directive/ngSwipe.js index bda37fe91e15..7f60d22861c4 100644 --- a/src/ngTouch/directive/ngSwipe.js +++ b/src/ngTouch/directive/ngSwipe.js @@ -4,7 +4,7 @@ /** * @ngdoc directive - * @name ngTouch.directive:ngSwipeLeft + * @name ngSwipeLeft * * @description * Specify custom behavior when an element is swiped to the left on a touchscreen device. @@ -34,7 +34,7 @@ /** * @ngdoc directive - * @name ngTouch.directive:ngSwipeRight + * @name ngSwipeRight * * @description * Specify custom behavior when an element is swiped to the right on a touchscreen device. diff --git a/src/ngTouch/swipe.js b/src/ngTouch/swipe.js index afdf43845906..ea79a96c37ec 100644 --- a/src/ngTouch/swipe.js +++ b/src/ngTouch/swipe.js @@ -3,8 +3,8 @@ /* global ngTouch: false */ /** - * @ngdoc object - * @name ngTouch.$swipe + * @ngdoc service + * @name $swipe * * @description * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe @@ -41,8 +41,7 @@ ngTouch.factory('$swipe', [function() { return { /** * @ngdoc method - * @name ngTouch.$swipe#bind - * @methodOf ngTouch.$swipe + * @name $swipe#bind * * @description * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an diff --git a/src/ngTouch/touch.js b/src/ngTouch/touch.js index f885307d3b24..052cbdd38c97 100644 --- a/src/ngTouch/touch.js +++ b/src/ngTouch/touch.js @@ -1,7 +1,7 @@ 'use strict'; /** - * @ngdoc overview + * @ngdoc module * @name ngTouch * @description * From 3a586e044edd1c6bd8fe53e6ba3aae1f7649a3d4 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Thu, 6 Feb 2014 14:02:18 +0000 Subject: [PATCH 049/123] docs(all): convert
                            /
                            snippets to GFM snippets --- docs/content/guide/animations.ngdoc | 40 +++++------ docs/content/guide/bootstrap.ngdoc | 12 ++-- docs/content/guide/compiler.ngdoc | 28 ++++---- docs/content/guide/controller.ngdoc | 44 ++++++------ .../content/guide/dev_guide.e2e-testing.ngdoc | 20 +++--- .../guide/dev_guide.services.$location.ngdoc | 40 +++++++---- ...dev_guide.services.creating_services.ngdoc | 14 ++-- ...guide.services.injecting_controllers.ngdoc | 4 +- ...guide.services.managing_dependencies.ngdoc | 16 ++--- .../dev_guide.services.testing_services.ngdoc | 4 +- .../guide/dev_guide.unit-testing.ngdoc | 68 ++++++++++--------- docs/content/guide/di.ngdoc | 45 ++++++------ docs/content/guide/i18n.ngdoc | 4 +- docs/content/guide/ie.ngdoc | 31 +++++---- docs/content/guide/module.ngdoc | 22 +++--- docs/content/guide/scope.ngdoc | 4 +- docs/content/guide/templates.ngdoc | 4 +- docs/content/tutorial/step_00.ngdoc | 5 +- docs/content/tutorial/step_01.ngdoc | 5 +- docs/content/tutorial/step_02.ngdoc | 20 +++--- docs/content/tutorial/step_03.ngdoc | 14 ++-- docs/content/tutorial/step_04.ngdoc | 20 +++--- docs/content/tutorial/step_05.ngdoc | 44 +++++++----- docs/content/tutorial/step_06.ngdoc | 15 ++-- docs/content/tutorial/step_07.ngdoc | 34 ++++++---- docs/content/tutorial/step_08.ngdoc | 25 ++++--- docs/content/tutorial/step_09.ngdoc | 25 ++++--- docs/content/tutorial/step_10.ngdoc | 15 ++-- docs/content/tutorial/step_11.ngdoc | 25 ++++--- docs/content/tutorial/step_12.ngdoc | 59 +++++++++------- src/Angular.js | 12 ++-- src/auto/injector.js | 60 ++++++++-------- src/loader.js | 12 ++-- src/ng/animate.js | 4 +- src/ng/cacheFactory.js | 20 +++--- src/ng/compile.js | 28 ++++---- src/ng/directive/booleanAttrs.js | 28 ++++---- src/ng/directive/input.js | 4 +- src/ng/directive/ngCloak.js | 4 +- src/ng/directive/ngCsp.js | 4 +- src/ng/directive/ngPluralize.js | 8 +-- src/ng/directive/ngRepeat.js | 8 +-- src/ng/directive/ngShowHide.js | 24 +++---- src/ng/exceptionHandler.js | 4 +- src/ng/filter.js | 8 +-- src/ng/http.js | 24 +++---- src/ng/interpolate.js | 4 +- src/ng/parse.js | 4 +- src/ng/q.js | 16 ++--- src/ng/rootScope.js | 28 ++++---- src/ngAnimate/animate.js | 24 +++---- src/ngMock/angular-mocks.js | 52 +++++++------- src/ngResource/resource.js | 20 +++--- src/ngRoute/routeParams.js | 4 +- 54 files changed, 594 insertions(+), 516 deletions(-) diff --git a/docs/content/guide/animations.ngdoc b/docs/content/guide/animations.ngdoc index 1178d774e6e6..a9dd6ac6505e 100644 --- a/docs/content/guide/animations.ngdoc +++ b/docs/content/guide/animations.ngdoc @@ -64,11 +64,11 @@ You may also want to setup a separate CSS file for defining CSS-based animations Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class attached to a HTML element within your website, you can apply animations to it. Lets say for example that we have an HTML template with a repeater in it like so: -
                            +```html
                             
                            {{ item.id }}
                            -
                            +``` As you can see, the `.repeated-item` class is present on the element that will be repeated and this class will be used as a reference within our application's CSS and/or JavaScript animation code to tell AngularJS to perform an animation. @@ -80,13 +80,13 @@ it will apply a `ng-move` class name. Taking a look at the following CSS code, we can see some transition and keyframe animation code set for each of those events that occur when ngRepeat triggers them: -
                            -/*
                            +```css
                            +/*
                               We're using CSS transitions for when
                               the enter and move events are triggered
                               for the element that has the .repeated-item
                               class
                            -*/
                            +*/
                             .repeated-item.ng-enter, .repeated-item.ng-move {
                               -webkit-transition:0.5s linear all;
                               -moz-transition:0.5s linear all;
                            @@ -95,22 +95,22 @@ occur when ngRepeat triggers them:
                               opacity:0;
                             }
                             
                            -/*
                            +/*
                              The ng-enter-active and ng-move-active
                              are where the transition destination properties
                              are set so that the animation knows what to
                              animate.
                            -*/
                            +*/
                             .repeated-item.ng-enter.ng-enter-active,
                             .repeated-item.ng-move.ng-move-active {
                               opacity:1;
                             }
                             
                            -/*
                            +/*
                               We're using CSS keyframe animations for when
                               the leave event is triggered for the element
                               that has the .repeated-item class
                            -*/
                            +*/
                             .repeated-item.ng-leave {
                               -webkit-animation:0.5s my_animation;
                               -moz-animation:0.5s my_animation;
                            @@ -118,34 +118,34 @@ occur when ngRepeat triggers them:
                               animation:0.5s my_animation;
                             }
                             
                            -@keyframes my_animation {
                            +@keyframes my_animation {
                               from { opacity:1; }
                               to { opacity:0; }
                             }
                             
                            -/*
                            +/*
                               Unfortunately each browser vendor requires
                               its own definition of keyframe animation code...
                            -*/
                            -@-webkit-keyframes my_animation {
                            +*/
                            +@-webkit-keyframes my_animation {
                               from { opacity:1; }
                               to { opacity:0; }
                             }
                             
                            -@-moz-keyframes my_animation {
                            +@-moz-keyframes my_animation {
                               from { opacity:1; }
                               to { opacity:0; }
                             }
                             
                            -@-o-keyframes my_animation {
                            +@-o-keyframes my_animation {
                               from { opacity:1; }
                               to { opacity:0; }
                             }
                            -
                            +``` The same approach to animation can be used using JavaScript code (**jQuery is used within to perform animations**): -
                            +```js
                             myModule.animation('.repeated-item', function() {
                               return {
                                 enter : function(element, done) {
                            @@ -199,7 +199,7 @@ myModule.animation('.repeated-item', function() {
                                 removeClass : function(element, className, done) {}
                               }
                             });
                            -
                            +``` With these generated CSS class names present on the element at the time, AngularJS automatically figures out whether to perform a CSS and/or JavaScript animation. If both CSS and JavaScript animation @@ -268,7 +268,7 @@ For a full breakdown of the steps involved during each animation event, refer to Animations within custom directives can also be established by injecting `$animate` directly into your directive and making calls to it when needed. -
                            +```js
                             myModule.directive('my-directive', ['$animate', function($animate) {
                               return function(element, scope, attrs) {
                                 element.bind('click', function() {
                            @@ -280,7 +280,7 @@ myModule.directive('my-directive', ['$animate', function($animate) {
                                 });
                               };
                             }]);
                            -
                            +``` ## More about animations diff --git a/docs/content/guide/bootstrap.ngdoc b/docs/content/guide/bootstrap.ngdoc index 058ae46d2612..d5098a233ede 100644 --- a/docs/content/guide/bootstrap.ngdoc +++ b/docs/content/guide/bootstrap.ngdoc @@ -13,7 +13,7 @@ This example shows the recommended path for integrating Angular with what we cal initialization. -
                            +```html
                             
                             
                               
                            @@ -21,7 +21,7 @@ initialization.
                                 
                               
                             
                            -
                            +``` @@ -86,7 +86,7 @@ or the need to perform an operation before Angular compiles a page. Here is an example of manually initializing Angular: -
                            +```html
                             
                             
                               
                            @@ -100,7 +100,7 @@ Here is an example of manually initializing Angular:
                                 
                               
                             
                            -
                            +``` Note that we have provided the name of our application module to be loaded into the injector as the second parameter of the {@link api/angular.bootstrap} function. Notice that `angular.bootstrap` will not create modules diff --git a/docs/content/guide/compiler.ngdoc b/docs/content/guide/compiler.ngdoc index 4440ace62c2a..8defadcf1763 100644 --- a/docs/content/guide/compiler.ngdoc +++ b/docs/content/guide/compiler.ngdoc @@ -60,12 +60,12 @@ during the compilation process. The directives can be placed in element names, a names, as well as comments. Here are some equivalent examples of invoking the {@link api/ng.directive:ngBind `ng-bind`} directive. -
                            +```html
                               
                               
                               
                               
                            -
                            +``` A directive is just a function which executes when the compiler encounters it in the DOM. See {@link api/ng.$compileProvider#methods_directive directive API} for in-depth documentation on how @@ -187,7 +187,7 @@ a model on the compiled scope will be reflected in the DOM. Below is the corresponding code using the `$compile` service. This should help give you an idea of what Angular does internally. -
                            +```js
                               var $compile = ...; // injected into your code
                               var scope = ...;
                               var parent = ...; // DOM element where the compiled template can be appended
                            @@ -205,7 +205,7 @@ This should help give you an idea of what Angular does internally.
                               
                               // Step 4: Append to DOM (optional)
                               parent.appendChild(element);
                            -
                            +``` ### The difference between Compile and Link @@ -229,14 +229,14 @@ moved to the compile function for performance reasons. To understand, let's look at a real-world example with `ngRepeat`: -
                            +```html
                             Hello {{user}}, you have these actions:
                             
                            • {{action.description}}
                            -
                            +``` When the above example is compiled, the compiler visits every node and looks for directives. @@ -295,7 +295,7 @@ One of the most common use cases for directives is to create reusable components Below is a pseudo code showing how a simplified dialog component may work. -
                            +```html
                             
                            @@ -306,7 +306,7 @@ Below is a pseudo code showing how a simplified dialog component may work. Body goes here: {{username}} is {{title}}.
                            -
                            +``` Clicking on the "show" button will open the dialog. The dialog will have a title, which is data bound to `username`, and it will also have a body which we would like to transclude @@ -314,7 +314,7 @@ into the dialog. Here is an example of what the template definition for the `dialog` widget may look like. -
                            +```html
                             

                            {{title}}

                            @@ -323,7 +323,7 @@ Here is an example of what the template definition for the `dialog` widget may l
                            -
                            +``` This will not render properly, unless we do some scope magic. @@ -334,14 +334,14 @@ the `onOk` and `onCancel` functions to be present in the scope. This limits the widget. To solve the mapping issue we use the `locals` to create local variables which the template expects as follows: -
                            +```js
                               scope: {
                                 title: '@',             // the title uses the data-binding from the parent scope
                                 onOk: '&',              // create a delegate onOk function
                                 onCancel: '&',          // create a delegate onCancel function
                                 visible: '='            // set up visible to accept data-binding
                               }
                            -
                            +``` Creating local properties on widget scope creates two problems: @@ -367,7 +367,7 @@ surprise. Therefore the final directive definition looks something like this: -
                            +```js
                             transclude: true,
                             scope: {
                                 title: '@',             // the title uses the data-binding from the parent scope
                            @@ -377,5 +377,5 @@ scope: {
                             },
                             restrict: 'E',
                             replace: true
                            -
                            +``` diff --git a/docs/content/guide/controller.ngdoc b/docs/content/guide/controller.ngdoc index 77e0ac50de80..01f5299f72f3 100644 --- a/docs/content/guide/controller.ngdoc +++ b/docs/content/guide/controller.ngdoc @@ -28,7 +28,7 @@ is registered. The following example shows a very simple constructor function for a Controller, `GreetingCtrl`, which attaches a `greeting` property containing the string `'Hola!'` to the `$scope`: -``` +```js function GreetingCtrl($scope) { $scope.greeting = 'Hola!'; } @@ -37,22 +37,22 @@ which attaches a `greeting` property containing the string `'Hola!'` to the `$sc Once the Controller has been attached to the DOM, the `greeting` property can be data-bound to the template: -``` -
                            - {{ greeting }} -
                            +```js +
                            + {{ greeting }} +
                            ``` **NOTE**: Although Angular allows you to create Controller functions in the global scope, this is not recommended. In a real application you should use the `.controller` method of your {@link module Angular Module} for your application as follows: -``` -var myApp = angular.module('myApp',[]); +```js + var myApp = angular.module('myApp',[]); -myApp.controller('GreetingCtrl', ['$scope', function($scope) { - $scope.greeting = 'Hola!'; -}]); + myApp.controller('GreetingCtrl', ['$scope', function($scope) { + $scope.greeting = 'Hola!'; + }]); ``` We have used an **inline injection annotation** to explicitly specify the dependency @@ -68,21 +68,21 @@ then available to be called from the template/view. The following example uses a Controller to add a method to the scope, which doubles a number: -``` -var myApp = angular.module('myApp',[]); +```js + var myApp = angular.module('myApp',[]); -myApp.controller('DoubleCtrl', ['$scope', function($scope) { - $scope.double = function(value) { return value * 2; }; -}]); + myApp.controller('DoubleCtrl', ['$scope', function($scope) { + $scope.double = function(value) { return value * 2; }; + }]); ``` Once the Controller has been attached to the DOM, the `double` method can be invoked in an Angular expression in the template: -``` -
                            - Two times equals {{ double(num) }} -
                            +```js +
                            + Two times equals {{ double(num) }} +
                            ``` As discussed in the {@link concepts Concepts} section of this guide, any @@ -270,7 +270,7 @@ Although there are many ways to test a Controller, one of the best conventions, involves injecting the {@link api/ng.$rootScope $rootScope} and {@link api/ng.$controller $controller}: **Controller Definition:** -``` +```js var myApp = angular.module('myApp',[]); myApp.controller('MyController', function($scope) { @@ -282,7 +282,7 @@ involves injecting the {@link api/ng.$rootScope $rootScope} and {@link api/ng.$c ``` **Controller Test:** -``` +```js describe('myController function', function() { describe('myController', function() { @@ -310,7 +310,7 @@ describe('myController function', function() { If you need to test a nested Controller you need to create the same scope hierarchy in your test that exists in the DOM: -``` +```js describe('state', function() { var mainScope, childScope, grandChildScope; diff --git a/docs/content/guide/dev_guide.e2e-testing.ngdoc b/docs/content/guide/dev_guide.e2e-testing.ngdoc index e0d3f61dc983..d72cb9b3db33 100644 --- a/docs/content/guide/dev_guide.e2e-testing.ngdoc +++ b/docs/content/guide/dev_guide.e2e-testing.ngdoc @@ -31,7 +31,7 @@ In addition to the above elements, scenarios may also contain helper functions t code in the `it` blocks. Here is an example of a simple scenario: -
                            +```js
                             describe('Buzz Client', function() {
                             it('should filter results', function() {
                               input('user').enter('jacksparrow');
                            @@ -41,7 +41,7 @@ it('should filter results', function() {
                               expect(repeater('ul li').count()).toEqual(1);
                             });
                             });
                            -
                            +``` Note that [`input('user')`](https://github.com/angular/angular.js/blob/master/docs/content/guide/dev_guide.e2e-testing.ngdoc#L119) @@ -190,7 +190,7 @@ be negated with `not()`. For instance: `expect(element('h1').text()).not().toEqu Source: https://github.com/angular/angular.js/blob/master/src/ngScenario/matchers.js -
                            +```js
                             // value and Object comparison following the rules of angular.equals().
                             expect(value).toEqual(value)
                             
                            @@ -219,7 +219,7 @@ expect(value).toContain(expected)
                             // number comparison using < and >
                             expect(value).toBeLessThan(expected)
                             expect(value).toBeGreaterThan(expected)
                            -
                            +``` # Example See the [angular-seed](https://github.com/angular/angular-seed) project for more examples. @@ -239,7 +239,7 @@ Imagine the application to be structured into two views: 2. a *detail view* which shows the entries' details and contains a delete button. When clicking the delete button, the user is redirected back to the *overview page*. -
                            +```js
                             beforeEach(function () {
                               var deleteEntry = function () {
                                 browser().navigateTo('/entries');
                            @@ -276,24 +276,24 @@ beforeEach(function () {
                               // start deleting entries
                               deleteEntry();
                             });
                            -
                            +``` In order to understand what is happening, we should emphasize that ngScenario calls are not immediately executed, but queued (in ngScenario terms, we would be talking about adding future actions). If we had only one entry in our table, then the following future actions would be queued: -
                            +```js
                             // delete entry 1
                             browser().navigateTo('/entries');
                             element('table tbody').query(function (tbody, done) { ... });
                             element('table tbody a');
                             element('.btn-danger').click();
                            -
                            +``` For two entries, ngScenario would have to work on the following queue: -
                            +```js
                             // delete entry 1
                             browser().navigateTo('/entries');
                             element('table tbody').query(function (tbody, done) { ... });
                            @@ -306,7 +306,7 @@ element('.btn-danger').click();
                                 element('table tbody').query(function (tbody, done) { ... });
                                 element('table tbody a');
                                 element('.btn-danger').click();
                            -
                            +``` # Caveats diff --git a/docs/content/guide/dev_guide.services.$location.ngdoc b/docs/content/guide/dev_guide.services.$location.ngdoc index 04bf23eb0f9b..8f7a596a94db 100644 --- a/docs/content/guide/dev_guide.services.$location.ngdoc +++ b/docs/content/guide/dev_guide.services.$location.ngdoc @@ -100,25 +100,28 @@ To configure the `$location` service, retrieve the default: `""` ### Example configuration -
                            +```js
                             $locationProvider.html5Mode(true).hashPrefix('!');
                            -
                            +``` ## Getter and setter methods `$location` service provides getter methods for read-only parts of the URL (absUrl, protocol, host, port) and getter / setter methods for url, path, search, hash: -
                            +```js
                             // get the current path
                             $location.path();
                             
                             // change the path
                             $location.path('/newValue')
                            -
                            +``` All of the setter methods return the same `$location` object to allow chaining. For example, to change multiple segments in one go, chain setters like this: -
                            $location.path('/newValue').search({key: value});
                            + +```js +$location.path('/newValue').search({key: value}); +``` ## Replace method @@ -127,11 +130,12 @@ time the $location service is synced with the browser, the last history record s instead of creating a new one. This is useful when you want to implement redirection, which would otherwise break the back button (navigating back would retrigger the redirection). To change the current URL without creating a new browser history record you can call: -
                            +
                            +```js
                               $location.path('/someNewPath');
                               $location.replace();
                               // or you can chain these as: $location.path('/someNewPath').replace();
                            -
                            +``` Note that the setters don't update `window.location` immediately. Instead, the `$location` service is aware of the {@link api/ng.$rootScope.Scope scope} life-cycle and coalesces multiple `$location` @@ -209,7 +213,7 @@ In this mode, `$location` uses Hashbang URLs in all browsers. ### Example -
                            +```js
                             it('should show example', inject(
                               function($locationProvider) {
                                 $locationProvider.html5Mode(false);
                            @@ -231,13 +235,16 @@ it('should show example', inject(
                                 $location.absUrl() == 'http://example.com/base/index.html#!/new?x=y'
                               }
                             ));
                            -
                            +``` ### Crawling your app To allow indexing of your AJAX application, you have to add special meta tag in the head section of your document: -
                            + +```html + +``` This will cause crawler bot to request links with `_escaped_fragment_` param so that your server can recognize the crawler and serve a HTML snapshots. For more information about this technique, @@ -258,7 +265,7 @@ having to worry about whether the browser displaying your app supports the histo ### Example -
                            +```js
                             it('should show example', inject(
                               function($locationProvider) {
                                 $locationProvider.html5Mode(true);
                            @@ -293,7 +300,7 @@ it('should show example', inject(
                                 $location.absUrl() == 'http://example.com/#!/foo/bar?x=y'
                               }
                             ));
                            -
                            +``` ### Fallback for legacy browsers @@ -341,7 +348,10 @@ to entry point of your application (e.g. index.html) If you want your AJAX application to be indexed by web crawlers, you will need to add the following meta tag to the HEAD section of your document: -
                            + +```html + +``` This statement causes a crawler to request links with an empty `_escaped_fragment_` parameter so that your server can recognize the crawler and serve it HTML snapshots. For more information about this @@ -525,7 +535,7 @@ hashPrefix. When using `$location` service during testing, you are outside of the angular's {@link api/ng.$rootScope.Scope scope} life-cycle. This means it's your responsibility to call `scope.$apply()`. -
                            +```js
                             describe('serviceUnderTest', function() {
                               beforeEach(module(function($provide) {
                                 $provide.factory('serviceUnderTest', function($location){
                            @@ -541,7 +551,7 @@ describe('serviceUnderTest', function() {
                             
                               }));
                             });
                            -
                            +``` # Migrating from earlier AngularJS releases diff --git a/docs/content/guide/dev_guide.services.creating_services.ngdoc b/docs/content/guide/dev_guide.services.creating_services.ngdoc index bdcf42adb6e7..c6210cc1dcb2 100644 --- a/docs/content/guide/dev_guide.services.creating_services.ngdoc +++ b/docs/content/guide/dev_guide.services.creating_services.ngdoc @@ -22,17 +22,19 @@ by using the {@link api/AUTO.$provide $provide} service in the module configurat function. The following pseudo-code shows both approaches: Using the angular.Module api: -
                            +
                            +```js
                             var myModule = angular.module('myModule', []);
                             myModule.factory('serviceId', function() {
                               var shinyNewServiceInstance;
                               //factory function body that constructs shinyNewServiceInstance
                               return shinyNewServiceInstance;
                             });
                            -
                            +``` Using the $provide service: -
                            +
                            +```js
                             angular.module('myModule', [], function($provide) {
                               $provide.factory('serviceId', function() {
                                 var shinyNewServiceInstance;
                            @@ -40,7 +42,7 @@ angular.module('myModule', [], function($provide) {
                                 return shinyNewServiceInstance;
                               });
                             });
                            -
                            +``` Note that you are not registering a service instance, but rather a factory function that will create this instance when called. @@ -58,7 +60,7 @@ Following is an example of a very simple service. This service depends on the `$ stores all notifications; after the third one, the service displays all of the notifications by window alert. -
                            +```js
                             angular.module('myModule', [], function($provide) {
                               $provide.factory('notify', ['$window', function(win) {
                                 var msgs = [];
                            @@ -71,7 +73,7 @@ angular.module('myModule', [], function($provide) {
                                 };
                               }]);
                             });
                            -
                            +``` # Instantiating Angular Services diff --git a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc index b24dec6e6917..312342b8e7e5 100644 --- a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc +++ b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc @@ -13,7 +13,7 @@ IDs matters: the order of the services in the array will be used when calling th with injected parameters. The names of parameters in factory function don't matter, but by convention they match the service IDs, which has added benefits discussed below. -
                            +```js
                             function myController($loc, $log) {
                               this.firstMethod = function() {
                                 // use $location service
                            @@ -26,7 +26,7 @@ function myController($loc, $log) {
                             }
                             // which services to inject ?
                             myController.$inject = ['$location', '$log'];
                            -
                            +``` diff --git a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc index 6dafc3f76de9..726a8bbe9c00 100644 --- a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc +++ b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc @@ -12,37 +12,37 @@ dropped (see "Inferring `$inject`" but note that that is currently an experiment Using the array notation: -
                            +```js
                             function myModuleCfgFn($provide) {
                               $provide.factory('myService', ['dep1', 'dep2', function(dep1, dep2) {}]);
                             }
                            -
                            +``` Using the $inject property: -
                            +```js
                             function myModuleCfgFn($provide) {
                               var myServiceFactory = function(dep1, dep2) {};
                               myServiceFactory.$inject = ['dep1', 'dep2'];
                               $provide.factory('myService', myServiceFactory);
                             }
                            -
                            +``` Using DI inference (incompatible with minifiers): -
                            +```js
                             function myModuleCfgFn($provide) {
                               $provide.factory('myService', function(dep1, dep2) {});
                             }
                            -
                            +``` Here is an example of two services, one of which depends on the other and both of which depend on other services that are provided by the Angular framework: -
                            +```js
                             /**
                              * batchLog service allows for messages to be queued in memory and flushed
                              * to the console.log every 50 seconds.
                            @@ -83,7 +83,7 @@ of which depend on other services that are provided by the Angular framework:
                             
                               // get the main service to kick off the application
                               angular.injector([batchLogModule]).get('routeTemplateMonitor');
                            -
                            +``` Things to notice in this example: diff --git a/docs/content/guide/dev_guide.services.testing_services.ngdoc b/docs/content/guide/dev_guide.services.testing_services.ngdoc index 6e0bbacebdc6..49f10c5a483e 100644 --- a/docs/content/guide/dev_guide.services.testing_services.ngdoc +++ b/docs/content/guide/dev_guide.services.testing_services.ngdoc @@ -6,7 +6,7 @@ The following is a unit test for the 'notify' service in the 'Dependencies' exam dev_guide.services.creating_services Creating Angular Services}. The unit test example uses Jasmine spy (mock) instead of a real browser alert. -
                            +```js
                             var mock, notify;
                             
                             beforeEach(function() {
                            @@ -47,7 +47,7 @@ it('should clear messages after alert', function() {
                               expect(mock.alert.callCount).toEqual(2);
                               expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]);
                             });
                            -
                            +``` ## Related Topics diff --git a/docs/content/guide/dev_guide.unit-testing.ngdoc b/docs/content/guide/dev_guide.unit-testing.ngdoc index 16c1c99e30fa..28779182f560 100644 --- a/docs/content/guide/dev_guide.unit-testing.ngdoc +++ b/docs/content/guide/dev_guide.unit-testing.ngdoc @@ -52,7 +52,7 @@ While there is nothing wrong with the `new` operator fundamentally, a problem ar on a constructor. This permanently binds the call site to the type. For example, lets say that we try to instantiate an `XHR` that will retrieve data from the server. -
                            +```js
                             function MyClass() {
                               this.doWork = function() {
                                 var xhr = new XHR();
                            @@ -61,7 +61,7 @@ function MyClass() {
                                 xhr.send();
                               }
                             }
                            -
                            +``` A problem surfaces in tests when we would like to instantiate a `MockXHR` that would allow us to return fake data and simulate network failures. By calling `new XHR()` we are @@ -69,20 +69,21 @@ permanently bound to the actual XHR and there is no way to replace it. Yes, we patch, but that is a bad idea for many reasons which are outside the scope of this document. Here's an example of how the class above becomes hard to test when resorting to monkey patching: -
                            +
                            +```js
                             var oldXHR = XHR;
                             XHR = function MockXHR() {};
                             var myClass = new MyClass();
                             myClass.doWork();
                             // assert that MockXHR got called with the right arguments
                             XHR = oldXHR; // if you forget this bad things will happen
                            -
                            +``` ### Global look-up: Another way to approach the problem is to look for the service in a well-known location. -
                            +```js
                             function MyClass() {
                               this.doWork = function() {
                                 global.xhr({
                            @@ -92,7 +93,7 @@ function MyClass() {
                                 })
                               }
                             }
                            -
                            +``` While no new dependency instance is created, it is fundamentally the same as `new` in that no way exists to intercept the call to `global.xhr` for testing purposes, other then @@ -101,14 +102,15 @@ order to replace it with call to a mock method. For further explanation of why t State & Singletons](http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/) The class above is hard to test since we have to change the global state: -
                            +
                            +```js
                             var oldXHR = global.xhr;
                             global.xhr = function mockXHR() {};
                             var myClass = new MyClass();
                             myClass.doWork();
                             // assert that mockXHR got called with the right arguments
                             global.xhr = oldXHR; // if you forget this bad things will happen
                            -
                            +``` ### Service Registry: @@ -116,7 +118,7 @@ global.xhr = oldXHR; // if you forget this bad things will happen It may seem that this can be solved by having a registry of all the services and then having the tests replace the services as needed. -
                            +```js
                             function MyClass() {
                               var serviceRegistry = ????;
                               this.doWork = function() {
                            @@ -127,7 +129,7 @@ function MyClass() {
                                   complete:function(response){ ... }
                                 })
                             }
                            -
                            +``` However, where does the serviceRegistry come from? If it is: * `new`-ed up, the test has no chance to reset the services for testing. @@ -135,20 +137,21 @@ However, where does the serviceRegistry come from? If it is: only one global variable exists to be reset). The class above is hard to test since we have to change the global state: -
                            +
                            +```js
                             var oldServiceLocator = global.serviceLocator;
                             global.serviceLocator.set('xhr', function mockXHR() {});
                             var myClass = new MyClass();
                             myClass.doWork();
                             // assert that mockXHR got called with the right arguments
                             global.serviceLocator = oldServiceLocator; // if you forget this bad things will happen
                            -
                            +``` ### Passing in Dependencies: Last, the dependency can be passed in. -
                            +```js
                             function MyClass(xhr) {
                               this.doWork = function() {
                                 xhr({
                            @@ -157,7 +160,7 @@ function MyClass(xhr) {
                                   complete:function(response){ ... }
                                 })
                             }
                            -
                            +``` This is the preferred method since the code makes no assumptions about the origin of `xhr` and cares instead about whoever created the class responsible for passing it in. Since the creator of the @@ -165,12 +168,13 @@ class should be different code than the user of the class, it separates the resp creation from the logic. This is dependency-injection in a nutshell. The class above is testable, since in the test we can write: -
                            +
                            +```js
                             function xhrMock(args) {...}
                             var myClass = new MyClass(xhrMock);
                             myClass.doWork();
                             // assert that xhrMock got called with the right arguments
                            -
                            +``` Notice that no global variables were harmed in the writing of this test. @@ -182,7 +186,7 @@ What makes each application unique is its logic, and the logic is what we would for your application contains DOM manipulation, it will be hard to test. See the example below: -
                            +```js
                             function PasswordCtrl() {
                               // get references to DOM elements
                               var msg = $('.ex1 span');
                            @@ -205,12 +209,12 @@ function PasswordCtrl() {
                                  .text(strength);
                               }
                             }
                            -
                            +``` The code above is problematic from a testability point of view since it requires your test to have the right kind of DOM present when the code executes. The test would look like this: -
                            +```js
                             var input = $('');
                             var span = $('');
                             $('body').html('
                            ') @@ -222,12 +226,12 @@ input.val('abc'); pc.grade(); expect(span.text()).toEqual('weak'); $('body').empty(); -
                            +``` In angular the controllers are strictly separated from the DOM manipulation logic and this results in a much easier testability story as the following example shows: -
                            +```js
                             function PasswordCtrl($scope) {
                               $scope.password = '';
                               $scope.grade = function() {
                            @@ -241,17 +245,17 @@ function PasswordCtrl($scope) {
                                 }
                               };
                             }
                            -
                            +``` and the test is straight forward: -
                            +```js
                             var $scope = {};
                             var pc = $controller('PasswordCtrl', { $scope: $scope });
                             $scope.password = 'abc';
                             $scope.grade();
                             expect($scope.strength).toEqual('weak');
                            -
                            +``` Notice that the test is not only much shorter, it is also easier to follow what is happening. We say that such a test tells a story, rather then asserting random bits which don't seem to be related. @@ -261,7 +265,7 @@ that such a test tells a story, rather then asserting random bits which don't se format. They are important because they remove the formatting responsibility from the application logic, further simplifying the application logic. -
                            +```js
                             myModule.filter('length', function() {
                               return function(text){
                                 return (''+(text||'')).length;
                            @@ -271,7 +275,7 @@ myModule.filter('length', function() {
                             var length = $filter('length');
                             expect(length(null)).toEqual(0);
                             expect(length('abc')).toEqual(3);
                            -
                            +``` ## Directives Directives in angular are responsible for encapsulating complex functionality within custom HTML tags, @@ -282,13 +286,13 @@ you create with directives may be used throughout your application and in many d Let's start with an angular app with no dependencies. -
                            +```js
                             var app = angular.module('myApp', []);
                            -
                            +``` Now we can add a directive to our app. -
                            +```js
                             app.directive('aGreatEye', function () {
                                 return {
                                     restrict: 'E',
                            @@ -296,13 +300,13 @@ app.directive('aGreatEye', function () {
                                     template: '

                            lidless, wreathed in flame, {{1 + 1}} times

                            ' }; }); -
                            +``` This directive is used as a tag ``. It replaces the entire tag with the template `

                            lidless, wreathed in flame, {{1 + 1}} times

                            `. Now we are going to write a jasmine unit test to verify this functionality. Note that the expression `{{1 + 1}}` times will also be evaluated in the rendered content. -
                            +```js
                             describe('Unit testing great quotes', function() {
                                 var $compile;
                                 var $rootScope;
                            @@ -327,7 +331,7 @@ describe('Unit testing great quotes', function() {
                                     expect(element.html()).toContain("lidless, wreathed in flame, 2 times");
                                 });
                             });
                            -
                            +``` We inject the $compile service and $rootScope before each jasmine test. The $compile service is used to render the aGreatEye directive. After rendering the directive we ensure that the directive has diff --git a/docs/content/guide/di.ngdoc b/docs/content/guide/di.ngdoc index 1714e2aa4a52..dde41dcb901c 100644 --- a/docs/content/guide/di.ngdoc +++ b/docs/content/guide/di.ngdoc @@ -31,7 +31,7 @@ for test isolation. The third option is the most viable, since it removes the responsibility of locating the dependency from the component. The dependency is simply handed to the component. -
                            +```js
                               function SomeClass(greeter) {
                                 this.greeter = greeter;
                               }
                            @@ -39,7 +39,7 @@ dependency from the component. The dependency is simply handed to the component.
                               SomeClass.prototype.doSomething = function(name) {
                                 this.greeter.greet(name);
                               }
                            -
                            +``` In the above example `SomeClass` is not concerned with locating the `greeter` dependency, it is simply handed the `greeter` at runtime. @@ -55,7 +55,7 @@ construction and lookup of dependencies. Here is an example of using the injector service: -
                            +```js
                               // Provide the wiring information in a module
                               angular.module('myModule', []).
                               
                            @@ -77,19 +77,20 @@ Here is an example of using the injector service:
                               
                               // Request any dependency from the injector
                               var greeter = injector.get('greeter');
                            -
                            +``` Asking for dependencies solves the issue of hard coding, but it also means that the injector needs to be passed throughout the application. Passing the injector breaks the [Law of Demeter](http://en.wikipedia.org/wiki/Law_of_Demeter). To remedy this, we turn the dependency lookup responsibility to the injector by declaring the dependencies as in this example: -
                            +```html
                               
                               
                            -
                            -
                            +```
                            +  
                            +```js
                               // And this controller definition
                               function MyController($scope, greeter) {
                                 $scope.sayHello = function() {
                            @@ -99,7 +100,7 @@ dependency lookup responsibility to the injector by declaring the dependencies a
                               
                               // The 'ng-controller' directive does this behind the scenes
                               injector.instantiate(MyController);
                            -
                            +``` Notice that by having the `ng-controller` instantiate the class, it can satisfy all of the dependencies of `MyController` without the controller ever knowing about the injector. This is @@ -121,11 +122,11 @@ information. These can be used interchangeably as you see fit and are equivalent The simplest way to get hold of the dependencies, is to assume that the function parameter names are the names of the dependencies. -
                            +```js
                               function MyController($scope, greeter) {
                                 ...
                               }
                            -
                            +``` Given a function the injector can infer the names of the service to inject by examining the function declaration and extracting the parameter names. In the above example `$scope`, and @@ -140,12 +141,12 @@ To allow the minifers to rename the function parameters and still be able to inj the function needs to be annotated with the `$inject` property. The `$inject` property is an array of service names to inject. -
                            +```js
                               var MyController = function(renamed$scope, renamedGreeter) {
                                 ...
                               }
                               MyController['$inject'] = ['$scope', 'greeter'];
                            -
                            +``` In this scenario the ordering of the values in the '$inject' array must match the ordering of the arguments to inject. Using above code snippet as an example, '$scope' will be injected into 'renamed$scope' and 'greeter' into 'renamedGreeter'. @@ -162,15 +163,15 @@ directives. For example: -
                            +```js
                               someModule.factory('greeter', function($window) {
                                 ...
                               });
                            -
                            +``` Results in code bloat due to needing a temporary variable: -
                            +```js
                               var greeterFactory = function(renamed$window) {
                                 ...
                               };
                            @@ -178,15 +179,15 @@ Results in code bloat due to needing a temporary variable:
                               greeterFactory.$inject = ['$window'];
                               
                               someModule.factory('greeter', greeterFactory);
                            -
                            +``` For this reason the third annotation style is provided as well. -
                            +```js
                               someModule.factory('greeter', ['$window', function(renamed$window) {
                                 ...
                               }]);
                            -
                            +``` Keep in mind that all of the annotation styles are equivalent and can be used anywhere in Angular where injection is supported. @@ -200,7 +201,7 @@ DI is pervasive throughout Angular. It is typically used in controllers and fact Controllers are classes which are responsible for application behavior. The recommended way of declaring controllers is using the array notation: -
                            +```js
                               someModule.controller('MyController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {
                                 ...
                                 $scope.aMethod = function() {
                            @@ -208,7 +209,7 @@ declaring controllers is using the array notation:
                                 }
                                 ...
                               }]);
                            -
                            +``` This avoids the creation of global functions for controllers and also protects against minification. @@ -219,7 +220,7 @@ Factory methods are responsible for creating most objects in Angular. Examples a services, and filters. The factory methods are registered with the module, and the recommended way of declaring factories is: -
                            +```js
                               angular.module('myModule', []).
                                 config(['depProvider', function(depProvider){
                                   ...
                            @@ -236,4 +237,4 @@ of declaring factories is:
                                 run(['depService', function(depService) {
                                   ...
                                 }]);
                            -
                            +``` diff --git a/docs/content/guide/i18n.ngdoc b/docs/content/guide/i18n.ngdoc index f8e2189dad03..159958f86491 100644 --- a/docs/content/guide/i18n.ngdoc +++ b/docs/content/guide/i18n.ngdoc @@ -66,7 +66,7 @@ starts, Angular is automatically pre-configured with localization rules for the You can also include the locale specific js file in the index.html page. For example, if one client requires German locale, you would serve index_de-de.html which will look something like this: -
                            +```html
                             
                              
                             ….
                            @@ -75,7 +75,7 @@ requires German locale, you would serve index_de-de.html which will look somethi
                             ….
                              
                             
                            -
                            +``` **Comparison of the two approaches** Both approaches described above requires you to prepare different index.html pages or js files for diff --git a/docs/content/guide/ie.ngdoc b/docs/content/guide/ie.ngdoc index 334161cbeeec..7a1c828c41cc 100644 --- a/docs/content/guide/ie.ngdoc +++ b/docs/content/guide/ie.ngdoc @@ -26,7 +26,8 @@ To make your Angular application work on IE please make sure that: 1. You polyfill JSON.stringify for IE7 and below. You can use [JSON2](https://github.com/douglascrockford/JSON-js) or [JSON3](http://bestiejs.github.com/json3/) polyfills for this. -
                            +     
                            +		 ```html
                                    
                                    
                                      
                            @@ -38,21 +39,23 @@ To make your Angular application work on IE please make sure that:
                                        ...
                                      
                                    
                            -     
                            + ``` 2. add `id="ng-app"` to the root element in conjunction with `ng-app` attribute -
                            +     
                            +		 ```html
                                    
                                    
                                      ...
                                    
                            -     
                            + ``` 3. you **do not** use custom element tags such as `` (use the attribute version `
                            ` instead), or 4. if you **do use** custom element tags, then you must take these steps to make IE 8 and below happy: -
                            +     
                            +		 ```html
                                    
                                    
                                      
                            @@ -73,7 +76,7 @@ To make your Angular application work on IE please make sure that:
                                        ...
                                      
                                    
                            -     
                            + ``` The **important** parts are: @@ -112,37 +115,37 @@ attribute names. So this requires no special handling in IE: `
                            +```html some text -
                            +``` It should parse into the following DOM: -
                            +```
                             #document
                               +- HTML
                                  +- BODY
                                     +- mytag
                                        +- #text: some text
                            -
                            +``` The expected behavior is that the `BODY` element has a child element `mytag`, which in turn has the text `some text`. But this is not what IE does (if the above fixes are not included): -
                            +```
                             #document
                               +- HTML
                                  +- BODY
                                     +- mytag
                                     +- #text: some text
                                     +- /mytag
                            -
                            +``` In IE, the behavior is that the `BODY` element has three children: @@ -162,7 +165,7 @@ In IE, the behavior is that the `BODY` element has three children: To make CSS selectors work with custom elements, the custom element name must be pre-created with `document.createElement('my-tag')` regardless of XML namespace. -
                            +```html
                               
                                 
                                   
                              
                            @@ -36,7 +36,7 @@ with {@link expression expressions}:
                                
                              
                             ...
                            -
                            +``` The syntax for using filters in Angular templates is as follows: @@ -70,7 +73,8 @@ Let's employ the filter in the phone details template: __`app/partials/phone-detail.html`:__ -
                            +
                            +```html
                             ...
                                 
                            Infrared
                            @@ -79,7 +83,7 @@ __`app/partials/phone-detail.html`:__
                            {{phone.connectivity.gps | checkmark}}
                            ... -
                            +``` ## Test @@ -87,7 +91,8 @@ __`app/partials/phone-detail.html`:__ Filters, like any other component, should be tested and these tests are very easy to write. __`test/unit/filtersSpec.js`:__ -
                            +
                            +```js
                             describe('filter', function() {
                             
                               beforeEach(module('phonecatFilters'));
                            @@ -101,7 +106,7 @@ describe('filter', function() {
                                 }));
                               });
                             });
                            -
                            +``` We must call `beforeEach(module('phonecatFilters'))` before any of our filter tests execute. This call loads our `phonecatFilters` module into the injector diff --git a/docs/content/tutorial/step_10.ngdoc b/docs/content/tutorial/step_10.ngdoc index 640977e6f37e..b16ceaabc348 100644 --- a/docs/content/tutorial/step_10.ngdoc +++ b/docs/content/tutorial/step_10.ngdoc @@ -22,7 +22,8 @@ The most important changes are listed below. You can see the full diff on [GitHu ## Controller __`app/js/controllers.js`:__ -
                            +
                            +```js
                             ...
                             var phonecatControllers = angular.module('phonecatControllers',[]);
                             
                            @@ -37,7 +38,7 @@ phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$h
                                   $scope.mainImageUrl = imageUrl;
                                 }
                               }]);
                            -
                            +``` In the `PhoneDetailCtrl` controller, we created the `mainImageUrl` model property and set its default value to the first phone image URL. @@ -48,7 +49,8 @@ We also created a `setImage` event handler function that will change the value o ## Template __`app/partials/phone-detail.html`:__ -
                            +
                            +```html
                             
                             
                             ...
                            @@ -59,7 +61,7 @@ __`app/partials/phone-detail.html`:__
                               
                             
                             ...
                            -
                            +``` We bound the `ngSrc` directive of the large image to the `mainImageUrl` property. @@ -80,7 +82,8 @@ to the first phone image by default. The second test clicks on several thumbnail verifies that the main image changed appropriately. __`test/e2e/scenarios.js`:__ -
                            +
                            +```js
                             ...
                               describe('Phone detail view', function() {
                             
                            @@ -100,7 +103,7 @@ __`test/e2e/scenarios.js`:__
                                 });
                               });
                             });
                            -
                            +``` You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-10/test/e2e/runner.html). diff --git a/docs/content/tutorial/step_11.ngdoc b/docs/content/tutorial/step_11.ngdoc index ffd342edebf8..b3308cc619f1 100644 --- a/docs/content/tutorial/step_11.ngdoc +++ b/docs/content/tutorial/step_11.ngdoc @@ -25,17 +25,19 @@ template. Additionally, we also need to load the `angular-resource.js` file, whi `ngResource` module and in it the `$resource` service, that we'll soon use: __`app/index.html`.__ -
                            +
                            +```html
                             ...
                               
                               
                             ...
                            -
                            +``` ## Service __`app/js/services.js`.__ -
                            +
                            +```js
                             var phonecatServices = angular.module('phonecatServices', ['ngResource']);
                             
                             phonecatServices.factory('Phone', ['$resource',
                            @@ -44,7 +46,7 @@ phonecatServices.factory('Phone', ['$resource',
                                   query: {method:'GET', params:{phoneId:'phones'}, isArray:true}
                                 });
                               }]);
                            -
                            +``` We used the module API to register a custom service using a factory function. We passed in the name of the service - 'Phone' - and the factory function. The factory function is similar to a @@ -57,11 +59,12 @@ lines of code. This client can then be used in our application, instead of the l api/ng.$http $http} service. __`app/js/app.js`.__ -
                            +
                            +```js
                             ...
                             angular.module('phonecatApp', ['ngRoute', 'phonecatControllers','phonecatFilters', 'phonecatServices']).
                             ...
                            -
                            +``` We need to add the 'phonecatServices' module dependency to 'phonecatApp' module's requires array. @@ -75,7 +78,8 @@ use than `$http` for interacting with data sources exposed as RESTful resources. now to understand what the code in our controllers is doing. __`app/js/controllers.js`.__ -
                            +
                            +```js
                             ...
                             
                             phonecatApp.controller('PhoneListCtrl', ['$scope', 'Phone', function($scope, Phone) {
                            @@ -92,7 +96,7 @@ phonecatApp.controller('PhoneDetailCtrl', ['$scope', '$routeParams', 'Phone', fu
                                 $scope.mainImageUrl = imageUrl;
                               }
                             }]);
                            -
                            +``` Notice how in `PhoneListCtrl` we replaced: @@ -133,7 +137,8 @@ ignores methods. __`test/unit/controllersSpec.js`:__ -
                            +
                            +```js
                             describe('PhoneCat controllers', function() {
                             
                               beforeEach(function(){
                            @@ -204,7 +209,7 @@ describe('PhoneCat controllers', function() {
                                 });
                               });
                             });
                            -
                            +``` You should now see the following output in the Karma tab: diff --git a/docs/content/tutorial/step_12.ngdoc b/docs/content/tutorial/step_12.ngdoc index 1323fb2f0382..3e823a1064dc 100644 --- a/docs/content/tutorial/step_12.ngdoc +++ b/docs/content/tutorial/step_12.ngdoc @@ -41,7 +41,8 @@ as the `angular-animate.js` file. The animation module, known as `ngAnimate`, is Here's what needs to changed in the index file: __`app/index.html`.__ -
                            +
                            +```html
                             ...
                               
                               
                            @@ -55,7 +56,7 @@ __`app/index.html`.__
                               
                               
                             ...
                            -
                            +```
                            **Important:** Be sure to use jQuery version `1.10.x`. AngularJS does not yet support jQuery `2.x`. @@ -68,17 +69,19 @@ with `ngResource`. ## Module & Animations __`app/js/animations.js`.__ -
                            +
                            +```js
                             angular.module('phonecatAnimations', ['ngAnimate']).
                               // ...
                               // this module will later be used to define animations
                               // ...
                            -
                            +``` And now let's attach this module to our application module... __`app/js/app.js`.__ -
                            +
                            +```js
                             // ...
                             angular.module('phonecat', [
                               'ngRoute',
                            @@ -89,7 +92,7 @@ angular.module('phonecat', [
                               'phonecatServices',
                             ]).
                             // ...
                            -
                            +``` Now, the phonecat module is animation aware. Let's make some animations! @@ -100,7 +103,8 @@ We'll start off by adding CSS transition animations to our `ngRepeat` directive First let's add an extra CSS class to our repeated element so that we can hook into it with our CSS animation code. __`app/partials/phone-list.html`.__ -
                            +
                            +```html
                             
                             
                            -
                            +``` Just like with the thumbnails, we're using a repeater to display **all** the profile images as a list, however we're not animating any repeat-related animations. Instead, we're keeping our eye on the ng-class directive since whenever @@ -340,7 +348,8 @@ You may be thinking that we're just going to create another CSS-enabled animatio Although we could do that, let's take the opportunity to learn how to create JavaScript-enabled animations with the `animation()` module method. __`app/js/animations.js`.__ -
                            +
                            +```js
                             var phonecatAnimations = angular.module('phonecatAnimations', ['ngAnimate']);
                             
                             phonecatAnimations.animation('.phone', function() {
                            @@ -393,7 +402,7 @@ phonecatAnimations.animation('.phone', function() {
                                 removeClass: animateDown
                               };
                             });
                            -
                            +``` Note that we're using [jQuery](http://jquery.com/) to implement the animation. jQuery isn't required to do JavaScript animations with AngularJS, but we're going to use it because writing diff --git a/src/Angular.js b/src/Angular.js index a6150e888517..8c4c8d6088f2 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -214,14 +214,14 @@ function isArrayLike(obj) { * It is worth noting that `.forEach` does not iterate over inherited properties because it filters * using the `hasOwnProperty` method. * -
                            +   ```js
                                  var values = {name: 'misko', gender: 'male'};
                                  var log = [];
                                  angular.forEach(values, function(value, key){
                                    this.push(key + ': ' + value);
                                  }, log);
                                  expect(log).toEqual(['name: misko', 'gender: male']);
                            -   
                            + ``` * * @param {Object|Array} obj Object to iterate over. * @param {Function} iterator Iterator function. @@ -374,12 +374,12 @@ function inherit(parent, extra) { * @description * A function that performs no operations. This function can be useful when writing code in the * functional style. -
                            +   ```js
                                  function foo(callback) {
                                    var result = calculateResult();
                                    (callback || angular.noop)(result);
                                  }
                            -   
                            + ``` */ function noop() {} noop.$inject = []; @@ -395,11 +395,11 @@ noop.$inject = []; * A function that returns its first argument. This function is useful when writing code in the * functional style. * -
                            +   ```js
                                  function transformer(transformationFn, value) {
                                    return (transformationFn || angular.identity)(value);
                                  };
                            -   
                            + ``` */ function identity($) {return $;} identity.$inject = []; diff --git a/src/auto/injector.js b/src/auto/injector.js index 977b57742000..dcfa2cc3b129 100644 --- a/src/auto/injector.js +++ b/src/auto/injector.js @@ -16,7 +16,7 @@ * * @example * Typical usage - *
                            + * ```js
                              *   // create an injector
                              *   var $injector = angular.injector(['ng']);
                              *
                            @@ -26,7 +26,7 @@
                              *     $compile($document)($rootScope);
                              *     $rootScope.$digest();
                              *   });
                            - * 
                            + * ``` * * Sometimes you want to get access to the injector of a currently running Angular app * from outside Angular. Perhaps, you want to inject and compile some markup after the @@ -40,7 +40,7 @@ * directive is added to the end of the document body by JQuery. We then compile and link * it into the current AngularJS scope. * - *
                            + * ```js
                              * var $div = $('
                            {{content.label}}
                            '); * $(document.body).append($div); * @@ -48,7 +48,7 @@ * var scope = angular.element($div).scope(); * $compile($div)(scope); * }); - *
                            + * ``` */ @@ -110,20 +110,20 @@ function annotate(fn) { * * The following always holds true: * - *
                            + * ```js
                              *   var $injector = angular.injector();
                              *   expect($injector.get('$injector')).toBe($injector);
                              *   expect($injector.invoke(function($injector){
                              *     return $injector;
                              *   }).toBe($injector);
                            - * 
                            + * ``` * * # Injection Function Annotation * * JavaScript does not have annotations, and annotations are needed for dependency injection. The * following are all valid ways of annotating function with injection arguments and are equivalent. * - *
                            + * ```js
                              *   // inferred (only works if code not minified/obfuscated)
                              *   $injector.invoke(function(serviceA){});
                              *
                            @@ -134,7 +134,7 @@ function annotate(fn) {
                              *
                              *   // inline
                              *   $injector.invoke(['serviceA', function(serviceA){}]);
                            - * 
                            + * ``` * * ## Inference * @@ -215,7 +215,7 @@ function annotate(fn) { * The simplest form is to extract the dependencies from the arguments of the function. This is done * by converting the function into a string using `toString()` method and extracting the argument * names. - *
                            + * ```js
                              *   // Given
                              *   function MyController($scope, $route) {
                              *     // ...
                            @@ -223,7 +223,7 @@ function annotate(fn) {
                              *
                              *   // Then
                              *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
                            - * 
                            + * ``` * * This method does not work with code minification / obfuscation. For this reason the following * annotation strategies are supported. @@ -232,7 +232,7 @@ function annotate(fn) { * * If a function has an `$inject` property and its value is an array of strings, then the strings * represent names of services to be injected into the function. - *
                            + * ```js
                              *   // Given
                              *   var MyController = function(obfuscatedScope, obfuscatedRoute) {
                              *     // ...
                            @@ -242,7 +242,7 @@ function annotate(fn) {
                              *
                              *   // Then
                              *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
                            - * 
                            + * ``` * * # The array notation * @@ -250,7 +250,7 @@ function annotate(fn) { * is very inconvenient. In these situations using the array notation to specify the dependencies in * a way that survives minification is a better choice: * - *
                            + * ```js
                              *   // We wish to write this (not minification / obfuscation safe)
                              *   injector.invoke(function($compile, $rootScope) {
                              *     // ...
                            @@ -272,7 +272,7 @@ function annotate(fn) {
                              *   expect(injector.annotate(
                              *      ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])
                              *    ).toEqual(['$compile', '$rootScope']);
                            - * 
                            + * ``` * * @param {function|Array.} fn Function for which dependent service names need to * be retrieved as described above. @@ -359,7 +359,7 @@ function annotate(fn) { * The following example shows how to create a simple event tracking service and register it using * {@link auto.$provide#methods_provider $provide.provider()}. * - *
                            + * ```js
                              *  // Define the eventTracker provider
                              *  function EventTrackerProvider() {
                              *    var trackingUrl = '/track';
                            @@ -416,7 +416,7 @@ function annotate(fn) {
                              *      expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });
                              *    }));
                              *  });
                            - * 
                            + * ``` */ /** @@ -437,19 +437,19 @@ function annotate(fn) { * * @example * Here is an example of registering a service - *
                            + * ```js
                              *   $provide.factory('ping', ['$http', function($http) {
                              *     return function ping() {
                              *       return $http.send('/ping');
                              *     };
                              *   }]);
                            - * 
                            + * ``` * You would then inject and use this service like this: - *
                            + * ```js
                              *   someModule.controller('Ctrl', ['ping', function(ping) {
                              *     ping();
                              *   }]);
                            - * 
                            + * ``` */ @@ -473,7 +473,7 @@ function annotate(fn) { * @example * Here is an example of registering a service using * {@link auto.$provide#methods_service $provide.service(class)}. - *
                            + * ```js
                              *   var Ping = function($http) {
                              *     this.$http = $http;
                              *   };
                            @@ -484,13 +484,13 @@ function annotate(fn) {
                              *     return this.$http.get('/ping');
                              *   };
                              *   $provide.service('ping', Ping);
                            - * 
                            + * ``` * You would then inject and use this service like this: - *
                            + * ```js
                              *   someModule.controller('Ctrl', ['ping', function(ping) {
                              *     ping.send();
                              *   }]);
                            - * 
                            + * ``` */ @@ -515,7 +515,7 @@ function annotate(fn) { * * @example * Here are some examples of creating value services. - *
                            + * ```js
                              *   $provide.value('ADMIN_USER', 'admin');
                              *
                              *   $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
                            @@ -523,7 +523,7 @@ function annotate(fn) {
                              *   $provide.value('halfOf', function(value) {
                              *     return value / 2;
                              *   });
                            - * 
                            + * ``` */ @@ -543,7 +543,7 @@ function annotate(fn) { * * @example * Here a some examples of creating constants: - *
                            + * ```js
                              *   $provide.constant('SHARD_HEIGHT', 306);
                              *
                              *   $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);
                            @@ -551,7 +551,7 @@ function annotate(fn) {
                              *   $provide.constant('double', function(value) {
                              *     return value * 2;
                              *   });
                            - * 
                            + * ``` */ @@ -577,12 +577,12 @@ function annotate(fn) { * @example * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting * calls to {@link ng.$log#error $log.warn()}. - *
                            + * ```js
                              *   $provide.decorator('$log', ['$delegate', function($delegate) {
                              *     $delegate.warn = $delegate.error;
                              *     return $delegate;
                              *   }]);
                            - * 
                            + * ``` */ diff --git a/src/loader.js b/src/loader.js index 7184cb47a111..cdb092f5cbc9 100644 --- a/src/loader.js +++ b/src/loader.js @@ -47,7 +47,7 @@ function setupModuleLoader(window) { * A module is a collection of services, directives, filters, and configuration information. * `angular.module` is used to configure the {@link auto.$injector $injector}. * - *
                            +     * ```js
                                  * // Create a new module
                                  * var myModule = angular.module('myModule', []);
                                  *
                            @@ -59,13 +59,13 @@ function setupModuleLoader(window) {
                                  *   // Configure existing providers
                                  *   $locationProvider.hashPrefix('!');
                                  * });
                            -     * 
                            + * ``` * * Then you can create an injector and load your modules like this: * - *
                            +     * ```js
                                  * var injector = angular.injector(['ng', 'MyModule'])
                            -     * 
                            + * ``` * * However it's more likely that you'll just use * {@link ng.directive:ngApp ngApp} or @@ -205,7 +205,7 @@ function setupModuleLoader(window) { * Defines an animation hook that can be later used with * {@link ngAnimate.$animate $animate} service and directives that use this service. * - *
                            +           * ```js
                                        * module.animation('.animation-name', function($inject1, $inject2) {
                                        *   return {
                                        *     eventName : function(element, done) {
                            @@ -217,7 +217,7 @@ function setupModuleLoader(window) {
                                        *     }
                                        *   }
                                        * })
                            -           * 
                            + * ``` * * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and * {@link ngAnimate ngAnimate module} for more information. diff --git a/src/ng/animate.js b/src/ng/animate.js index 11a287e69839..55eb0a3faf49 100644 --- a/src/ng/animate.js +++ b/src/ng/animate.js @@ -36,7 +36,7 @@ var $AnimateProvider = ['$provide', function($provide) { * triggered. * * - *
                            +   * ```js
                                *   return {
                                  *     eventFn : function(element, done) {
                                  *       //code to run the animation
                            @@ -46,7 +46,7 @@ var $AnimateProvider = ['$provide', function($provide) {
                                  *       }
                                  *     }
                                  *   }
                            -   *
                            + * ``` * * @param {string} name The name of the animation. * @param {function} factory The factory function that will be executed to return the animation diff --git a/src/ng/cacheFactory.js b/src/ng/cacheFactory.js index 32d179b4b3a6..9371ca58a1ce 100644 --- a/src/ng/cacheFactory.js +++ b/src/ng/cacheFactory.js @@ -7,7 +7,7 @@ * @description * Factory that constructs cache objects and gives access to them. * - *
                            + * ```js
                              * 
                              *  var cache = $cacheFactory('cacheId');
                              *  expect($cacheFactory.get('cacheId')).toBe(cache);
                            @@ -19,7 +19,7 @@
                              *  // We've specified no options on creation
                              *  expect(cache.info()).toEqual({id: 'cacheId', size: 2}); 
                              * 
                            - * 
                            + * ``` * * * @param {string} cacheId Name or id of the newly created cache. @@ -201,7 +201,7 @@ function $CacheFactoryProvider() { * `$templateCache` service directly. * * Adding via the `script` tag: - *
                            + * ```html
                              * 
                              * 
                              * 
                            - 
                            - 
                            + 
                            + 
                              */
                             function copy(source, destination){
                               if (isWindow(source) || isScope(source)) {
                            diff --git a/src/ng/compile.js b/src/ng/compile.js
                            index dd8d001cc7d4..31c8006ea517 100644
                            --- a/src/ng/compile.js
                            +++ b/src/ng/compile.js
                            @@ -383,8 +383,8 @@
                              * to illustrate how `$compile` works.
                              * 
                            * - - + + Load inlined template
                            -
                            - + + it('should load template defined inside script tag', function() { element(by.css('#tpl-link')).click(); expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/); }); - -
                            + + */ var scriptDirective = ['$templateCache', function($templateCache) { return { diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js index 0b01e6126543..faa9c7a700a3 100644 --- a/src/ng/directive/select.js +++ b/src/ng/directive/select.js @@ -72,8 +72,8 @@ var ngOptionsMinErr = minErr('ngOptions'); * `value` variable (e.g. `value.propertyName`). * * @example - - + + - - + + */ factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) { var cookies = {}, diff --git a/src/ngSanitize/filter/linky.js b/src/ngSanitize/filter/linky.js index 43019f335ccc..666cd9d59b27 100644 --- a/src/ngSanitize/filter/linky.js +++ b/src/ngSanitize/filter/linky.js @@ -21,8 +21,8 @@ * * @example - - + + \n'; + } + + function makeCssLinkTag(src) { + return '\n'; + } + }; +}) + + +.factory('openPlunkr', function(templateMerge, formPostData, prepareEditorAssetTags, prepareDefaultAppModule) { + return function(content) { + var hasRouting = false; + angular.forEach(content.deps, function(file) { + hasRouting = hasRouting || file.name == 'angular-route.js'; + }); + var indexHtmlContent = '\n' + + '\n' + + ' \n' + + '{{scriptDeps}}'; + + if(hasRouting) { + indexHtmlContent += '\n'; + } + + indexHtmlContent += '\n' + + ' \n\n' + + '{{indexContents}}\n\n' + + ' \n' + + '\n'; + + indexProp = { + module: content.module, + scriptDeps: prepareEditorAssetTags(content, { includeLocalFiles : true }), + indexContents: content.html[0].content + }; + + var allFiles = [].concat(content.js, content.css, content.html, content.json); + + if(!content.module) { + var moduleData = prepareDefaultAppModule(content); + indexProp.module = moduleData.module; + + var found = false; + angular.forEach(content.js, function(file) { + if(file.name == 'script.js') { + file.content = moduleData.script + file.content; + found = true; + } + }); + if(!found) { + indexProp.scriptDeps += '\n'; + allFiles.push({ + name : 'script.js', + content : moduleData.script + }); + } + } + + var postData = {}; + + angular.forEach(allFiles, function(file, index) { + if (file.content && file.name != 'index.html') { + postData['files[' + file.name + ']'] = file.content; + } + }); + + postData['files[index.html]'] = templateMerge(indexHtmlContent, indexProp); + postData['tags[]'] = "angularjs"; + + postData.private = true; + postData.description = 'AngularJS Example Plunkr'; + + formPostData('http://plnkr.co/edit/?p=preview', postData); + }; +}) + +.factory('openJsFiddle', function(templateMerge, formPostData, prepareEditorAssetTags, prepareDefaultAppModule) { + var HTML = '
                            \n{{html:2}}
                            ', + CSS = ' \n' + + '{{head:0}}\n') - : ('\n') ) + - '\n'); - }); - } -}; - -exports.Example.prototype.toHtmlEmbed = function() { - var out = []; - out.push('
                            '); - out.push('
                            '); - return out.join(''); -}; - diff --git a/docs/src/gen-docs.js b/docs/src/gen-docs.js deleted file mode 100755 index ff8d8311868a..000000000000 --- a/docs/src/gen-docs.js +++ /dev/null @@ -1,150 +0,0 @@ -var reader = require('./reader.js'), - ngdoc = require('./ngdoc.js'), - writer = require('./writer.js'), - SiteMap = require('./SiteMap.js').SiteMap, - appCache = require('./appCache.js').appCache, - Q = require('qq'), - errorsJson = require('../../build/errors.json').errors; - -var start = now(); -var docs; - -writer.makeDir('build/docs/', true).then(function() { - return writer.makeDir('build/docs/partials/'); -}).then(function() { - return writer.makeDir('build/docs/components/'); -}).then(function() { - return writer.makeDir('build/docs/components/bootstrap'); -}).then(function() { - return writer.makeDir('build/docs/components/font-awesome'); -}).then(function() { - return writer.makeDir('build/docs/e2etests'); -}).then(function() { - console.log('Generating AngularJS Reference Documentation...'); - return reader.collect(); -}).then(function generateHtmlDocPartials(docs_) { - docs = docs_; - ngdoc.merge(docs); - 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())); - // If it has a sample Protractor test, output that as well. - if (doc.protractorTests.length) { - fileFutures.push(writer.output('ptore2e/' + doc.section + '/' + id + '.jquery_test.js', - ngdoc.writeProtractorTest(doc, 'index-jq-nocache.html#!/'))); - fileFutures.push(writer.output('ptore2e/' + doc.section + '/' + id + '.jqlite_test.js', - ngdoc.writeProtractorTest(doc, 'index-nocache.html#!/'))); - } - }); - - ngdoc.checkBrokenLinks(docs); - - writeTheRest(fileFutures); - - return Q.deep(fileFutures); -}).then(function generateManifestFile() { - return appCache('build/docs/').then(function(list) { - writer.output('appcache-offline.manifest', list); - }); -}).then(function printStats() { - console.log('DONE. Generated ' + docs.length + ' pages in ' + (now()-start) + 'ms.' ); -}).done(); - - -function writeTheRest(writesFuture) { - var metadata = ngdoc.metadata(docs); - var versions = ngdoc.ngVersions(); - var currentVersion = ngdoc.ngCurrentVersion(); - - writesFuture.push(writer.symlink('../../docs/content/notes', 'build/docs/notes', 'directory')); - writesFuture.push(writer.symlinkTemplate('css', 'directory')); - writesFuture.push(writer.symlink('../../docs/img', 'build/docs/img', 'directory')); - writesFuture.push(writer.symlinkTemplate('js', 'directory')); - - var manifest = 'manifest="/build/docs/appcache.manifest"'; - - writesFuture.push(writer.copyDir('bower_components/components-font-awesome/css', 'components/font-awesome/css')); - writesFuture.push(writer.copyDir('bower_components/components-font-awesome/font', 'components/font-awesome/font')); - writesFuture.push(writer.copyDir('bower_components/bootstrap', 'components/bootstrap')); - - writesFuture.push(writer.copy('node_modules/marked/lib/marked.js', 'components/marked.js')); - writesFuture.push(writer.copy('bower_components/lunr.js/lunr.js', 'components/lunr.js')); - writesFuture.push(writer.copy('bower_components/lunr.js/lunr.min.js', 'components/lunr.min.js')); - writesFuture.push(writer.copy('bower_components/jquery/jquery.js', 'components/jquery.js')); - writesFuture.push(writer.copy('bower_components/jquery/jquery.min.js', 'components/jquery.min.js')); - writesFuture.push(writer.copy('bower_components/google-code-prettify/src/prettify.js', 'components/google-code-prettify.js')); - writesFuture.push(writer.copy('docs/components/angular-bootstrap/bootstrap.js', 'components/angular-bootstrap.js')); - writesFuture.push(writer.copy('docs/components/angular-bootstrap/bootstrap-prettify.js', 'components/angular-bootstrap-prettify.js')); - - writesFuture.push(writer.copy('docs/src/templates/index.html', 'index.html', - writer.replace, {'doc:manifest': ''})); //manifest //TODO(i): enable - - writesFuture.push(writer.copy('docs/src/templates/index.html', 'index-nocache.html', - writer.replace, {'doc:manifest': ''})); - - - writesFuture.push(writer.copy('docs/src/templates/index.html', 'index-jq.html', - writer.replace, {'doc:manifest': ''})); - - writesFuture.push(writer.copy('docs/src/templates/index.html', 'index-jq-nocache.html', - writer.replace, {'doc:manifest': ''})); - - - writesFuture.push(writer.copy('docs/src/templates/index.html', 'index-debug.html', - writer.replace, {'doc:manifest': ''})); - - writesFuture.push(writer.copy('docs/src/templates/index.html', 'index-jq-debug.html', - writer.replace, {'doc:manifest': ''})); - - writesFuture.push(writer.symlinkTemplate('offline.html')); - - writesFuture.push(writer.copyTemplate('docs-scenario.html')); // will be rewritten, don't symlink - writesFuture.push(writer.output('docs-scenario.js', ngdoc.scenarios(docs))); - - writesFuture.push(writer.output('docs-data.js',[ - "angular.module('docsData', [])", - ".value('NG_PAGES'," + JSON.stringify(metadata).replace(/{/g, '\n{') + ")", - ".value('NG_VERSION'," + JSON.stringify(currentVersion) + ")", - ".value('NG_VERSIONS'," + JSON.stringify(versions) + ");" - ])); - writesFuture.push(writer.output('sitemap.xml', new SiteMap(docs).render())); - - writesFuture.push(writer.output('robots.txt', 'Sitemap: http://docs.angularjs.org/sitemap.xml\n')); - writesFuture.push(writer.output('appcache.manifest',appCache())); - writesFuture.push(writer.copyTemplate('.htaccess')); // will be rewritten, don't symlink - - writesFuture.push(writer.symlinkTemplate('favicon.ico')); -} - - -function now() { return new Date().getTime(); } - -function noop() {}; - diff --git a/docs/src/ngdoc.js b/docs/src/ngdoc.js deleted file mode 100644 index 78f968d99793..000000000000 --- a/docs/src/ngdoc.js +++ /dev/null @@ -1,1435 +0,0 @@ -/** - * All parsing/transformation code goes here. All code here should be sync to ease testing. - */ -var DOM = require('./dom.js').DOM; -var htmlEscape = require('./dom.js').htmlEscape; -var Example = require('./example.js').Example; -var NEW_LINE = /\n\r?/; -var globalID = 0; -var fs = require('fs'); -var fspath = require('path'); -var shell = require('shelljs'); -var gruntUtil = require('../../lib/grunt/utils.js'); -var errorsJson; -var marked = require('marked'); -marked.setOptions({ - gfm: true, - tables: true -}); - -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; -exports.scenarios = scenarios; -exports.writeProtractorTest = writeProtractorTest; -exports.merge = merge; -exports.checkBrokenLinks = checkBrokenLinks; -exports.Doc = Doc; - -exports.ngVersions = function() { - var versions = [], regex = /^v([1-9]\d*(?:\.\d+\S+)+)$/; //only fetch >= 1.0.0 versions - shell.exec('git tag', {silent: true}).output.split(/\s*\n\s*/) - .forEach(function(line) { - var matches = regex.exec(line); - if(matches && matches.length > 0) { - versions.push(matches[1]); - } - }); - - //match the future version of AngularJS that is set in the package.json file - return expandVersions(sortVersionsNaturally(versions), exports.ngCurrentVersion().full); - - function expandVersions(versions, latestVersion) { - var RC_VERSION = /rc\d/; - //copy the array to avoid changing the versions param data - //the latest version is not on the git tags list, but - //docs.angularjs.org will always point to master as of 1.2 - versions = versions.concat([latestVersion]); - - var firstUnstable, expanded = []; - for(var i=versions.length-1;i>=0;i--) { - var version = versions[i], - split = version.split('.'), - isMaster = version == latestVersion, - isStable = split[1] % 2 === 0 && !RC_VERSION.test(version); - - var title = 'AngularJS - v' + version; - - var docsPath = version < '1.0.2' ? 'docs-' + version : 'docs'; - - var url = isMaster ? - 'http://docs.angularjs.org' : - 'http://code.angularjs.org/' + version + '/' + docsPath; - - expanded.push({ - version : version, - stable : isStable, - title : title, - group : (isStable ? 'Stable' : 'Unstable'), - url : url - }); - }; - - return expanded; - }; - - function sortVersionsNaturally(versions) { - var versionMap = {}, - NON_RC_RELEASE_NUMBER = 999; - for(var i = versions.length - 1; i >= 0; i--) { - var version = versions[i]; - var split = version.split(/\.|rc/); - var baseVersion = split[0] + '.' + split[1] + '.' + split[2]; - - //create a map of RC versions for each version - //this way each RC version can be sorted in "natural" order - versionMap[baseVersion] = versionMap[baseVersion] || []; - - //NON_RC_RELEASE_NUMBER is used to signal the non-RC version for the release and - //it will always appear at the top of the list since the number is so high! - versionMap[baseVersion].push( - version == baseVersion ? NON_RC_RELEASE_NUMBER : parseInt(version.match(/rc\.?(\d+)/)[1])); - }; - - //flatten the map so that the RC versions occur in a natural sorted order - //and the official non-RC version shows up at the top of the list of sorted - //RC versions! - var angularVersions = []; - sortedKeys(versionMap).forEach(function(key) { - var versions = versionMap[key]; - - //basic numerical sort - versions.sort(function(a,b) { - return a - b; - }); - - versions.forEach(function(v) { - angularVersions.push(v == NON_RC_RELEASE_NUMBER ? key : key + 'rc' + v); - }); - }); - - return angularVersions; - }; - - function sortedKeys(obj) { - var keys = []; - for(var key in obj) { - keys.push(key); - }; - keys.sort(true); - return keys; - }; -}; - -exports.ngCurrentVersion = function() { - return gruntUtil.getVersion(); -}; - -var BOOLEAN_ATTR = {}; -['multiple', 'selected', 'checked', 'disabled', 'readOnly', 'required'].forEach(function(value) { - BOOLEAN_ATTR[value] = true; -}); - -////////////////////////////////////////////////////////// -function Doc(text, file, line) { - if (typeof text == 'object') { - for ( var key in text) { - this[key] = text[key]; - } - } else { - this.text = text; - this.file = file; - this.line = line; - } - this.scenarios = this.scenarios || []; - this.protractorTests = this.protractorTests || []; - this.requires = this.requires || []; - this.param = this.param || []; - this.properties = this.properties || []; - this.methods = this.methods || []; - this.events = this.events || []; - this.links = this.links || []; - this.anchors = this.anchors || []; -} -Doc.METADATA_IGNORE = (function() { - var words = fs.readFileSync(__dirname + '/ignore.words', 'utf8'); - return words.toString().split(/[,\s\n\r]+/gm); -})(); - - -Doc.prototype = { - keywords: function keywords() { - var keywords = {}; - var words = []; - Doc.METADATA_IGNORE.forEach(function(ignore){ keywords[ignore] = true; }); - - function extractWords(text) { - var tokens = text.toLowerCase().split(/[\.\s,`'"#]+/mg); - tokens.forEach(function(key){ - var match = key.match(/^((ng:|[\$_a-z])[\w\-_]+)/); - if (match){ - key = match[1]; - if (!keywords[key]) { - keywords[key] = true; - words.push(key); - } - } - }); - } - - extractWords(this.text); - this.properties.forEach(function(prop) { - extractWords(prop.text || prop.description || ''); - }); - this.methods.forEach(function(method) { - extractWords(method.text || method.description || ''); - }); - if (this.ngdoc === 'error') { - words.push(this.getMinerrNamespace()); - words.push(this.getMinerrCode()); - } - words.sort(); - return words.join(' '); - }, - - shortDescription : function() { - if (!this.description) return this.description; - var text = this.description.split("\n")[0]; - text = text.replace(/<.+?\/?>/g, ''); - text = text.replace(/{/g,'{'); - text = text.replace(/}/g,'}'); - return text; - }, - - 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 - * - * @example - * - if the link is inside any api doc: - * angular.widget -> api/angular.widget - * - * - if the link is inside any guid doc: - * intro -> guide/intro - * - * @param {string} url Absolute or relative url - * @returns {string} Absolute url - */ - convertUrlToAbsolute: function(url) { - var hashIdx = url.indexOf('#'); - - // Lowercase hash parts of the links, - // so that we can keep correct API names even when the urls are lowercased. - if (hashIdx !== -1) { - url = url.substr(0, hashIdx) + url.substr(hashIdx).toLowerCase(); - } - - if (url.substr(-1) == '/') return url + 'index'; - if (url.match(/\//)) return url; - return this.section + '/' + url; - }, - - markdown: function(text) { - if (!text) return text; - - var self = this, - IS_URL = /^(https?:\/\/|ftps?:\/\/|mailto:|\.|\/)/, - IS_ANGULAR = /^(api\/)?(angular|ng|AUTO)\./, - IS_HASH = /^#/, - parts = trim(text).split(/([\s\S]*?<\/pre>|[\s\S]*?<\/doc:example>|]*>[\s\S]*?<\/example>)/), - seq = 0, - placeholderMap = {}; - - function placeholder(text) { - var id = 'REPLACEME' + (seq++); - placeholderMap[id] = text; - return id; - } - - function extractInlineDocCode(text, tag) { - if(tag == 'all') { - //use a greedy operator to match the last tag - regex = /\/\/([.\s\S]+)\/\/<\/docs>/im; - } - else { - //use a non-greedy operator to match the next tag - regex = new RegExp("\/\/([.\\s\\S]+?)\/\/<\/docs>","im"); - } - var matches = regex.exec(text.toString()); - return matches && matches.length > 1 ? matches[1] : ""; - } - - parts.forEach(function(text, i) { - parts[i] = (text || ''). - replace(/([\s\S]*?)<\/example>/gmi, - function(_, module, deps, animations, content) { - - var example = new Example(self.scenarios, self.protractorTests); - if(animations) { - example.enableAnimations(); - example.addDeps('angular-animate.js'); - } - - example.setModule(module); - example.addDeps(deps); - content.replace(/([\s\S]*?)<\/file>/gmi, function(_, name, content) { - example.addSource(name, content); - }); - content.replace(//gmi, function(_, file, tag, name) { - if(fs.existsSync(file)) { - var content = fs.readFileSync(file, 'utf8'); - if(content && content.length > 0) { - if(tag && tag.length > 0) { - content = extractInlineDocCode(content, tag); - } - name = name && name.length > 0 ? name : fspath.basename(file); - example.addSource(name, content); - } - } - return ''; - }) - return placeholder(example.toHtml()); - }). - replace(/(?:\*\s+)?/i, function(_, file, tag) { - if(fs.existsSync(file)) { - var content = fs.readFileSync(file, 'utf8'); - if(tag && tag.length > 0) { - content = extractInlineDocCode(content, tag); - } - return content; - } - }). - replace(/^]*)?>([\s\S]*)<\/doc:example>/mi, function(_, attrs, content) { - var html, script, scenario, - example = new Example(self.scenarios, self.protractorTests); - - example.setModule((attrs||'module=""').match(/^\s*module=["'](.*)["']\s*$/)[1]); - content. - replace(/]*)?>([\s\S]*)<\/doc:source>/mi, function(_, attrs, content) { - example.addSource('index.html', content. - replace(/ - - - - diff --git a/docs/src/templates/favicon.ico b/docs/src/templates/favicon.ico deleted file mode 100644 index fe24a63a6ba4c4b4fb0e960abb60e51dc9097d43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmZuxZAep57(QaqUkSemBP}6IGixM-R$2;?eQEiH)}M%sFz|;4MNX|WiYN&)b(!;H z6Y*nt*TibqTMgRG)HS!ek&a*=1h9&ehx^|5d7kq==bVdB5WYh~ z5Pn9Zl1&JOBZT5`;1tgM&*K3h{B8XO04Pv69FAiQqf%+L-x}R+cT}L7K)Hp5g#({H zs)ujg7~xW4RgiVK6Q0-0+&Z1^>C)0tWFQR5EiNv`j*gB=t1D>k=&rAj6sm=NVV@x` zw2hCPj4lwp82qEx>mRPHtc3aV7>%aNIw8HBkub*N2zEW5@azt2gMusxh+8R_*=)Y< z8=bRvJutLfX4G3b|p{YRzFR?!H&x@}p?E$;po?|kZ?qnve^}WB- z4mRsN9Ew)M*>nl7U3gmR!xE0m1>G<`JzX|FKGB*SHR01IKAcZw@!XtnuR;$E^#jn_ zB7;5QtJ(ygeY^|so_h9fSglM7om_(_976-Yz&vAx!9fa&&aBlY_#=rOpwVb3X$NB# zL~g_vWg3C__e!);o8Sd8VxX1ul+kDuzL7I*^-Y>1J_;gMx#WE_a1pONsV9-NO$>#n zBv32t<%SgRXIPfK>)nHR-y~wL8ac%ns>*5ZLYf+~Q@=oRY&%@ak;0? - - - - - - - - - - - AngularJS - - - - -
                            - -
                            - -
                            -
                            -
                            - -
                            -
                            -
                            - -
                            -
                            -
                            - -
                            -
                            - - - -
                            - -
                            - -
                            -
                            -
                            -
                            - -
                            -
                            - - - - - - -
                            -
                            -
                            -
                            - - - -
                            Loading...
                            - -
                            -
                            -
                            -
                            - - - - - - - -
                            - - - diff --git a/docs/src/templates/js/docs.js b/docs/src/templates/js/docs.js deleted file mode 100644 index dad57aa55e80..000000000000 --- a/docs/src/templates/js/docs.js +++ /dev/null @@ -1,933 +0,0 @@ -var docsApp = { - controller: {}, - directive: {}, - serviceFactory: {}, - filter: {} -}; - -docsApp.controller.DocsVersionsCtrl = ['$scope', '$rootScope', '$window', 'NG_VERSIONS', 'NG_VERSION', function($scope, $rootScope, $window, NG_VERSIONS, NG_VERSION) { - $scope.docs_versions = NG_VERSIONS; - $scope.docs_version = NG_VERSIONS[0]; - - $scope.jumpToDocsVersion = function(version) { - var currentPagePath = ''; - - // preserve URL path when switching between doc versions - if (angular.isObject($rootScope.currentPage) && $rootScope.currentPage.section && $rootScope.currentPage.id) { - currentPagePath = '/' + $rootScope.currentPage.section + '/' + $rootScope.currentPage.id; - } - - $window.location = version.url + currentPagePath; - }; -}]; - -docsApp.controller.DocsNavigationCtrl = ['$scope', '$location', 'docsSearch', function($scope, $location, docsSearch) { - function clearResults() { - $scope.results = []; - $scope.colClassName = null; - $scope.hasResults = false; - } - - $scope.search = function(q) { - var MIN_SEARCH_LENGTH = 3; - if(q.length >= MIN_SEARCH_LENGTH) { - var results = docsSearch(q); - var totalSections = 0; - for(var i in results) { - ++totalSections; - } - if(totalSections > 0) { - $scope.colClassName = 'cols-' + totalSections; - } - $scope.hasResults = totalSections > 0; - $scope.results = results; - } - else { - clearResults(); - } - if(!$scope.$$phase) $scope.$apply(); - }; - $scope.submit = function() { - var result; - for(var i in $scope.results) { - result = $scope.results[i][0]; - if(result) { - break; - } - } - if(result) { - $location.path(result.url); - $scope.hideResults(); - } - }; - $scope.hideResults = function() { - clearResults(); - $scope.q = ''; - }; -}]; - -docsApp.serviceFactory.lunrSearch = function() { - return function(properties) { - if (window.RUNNING_IN_NG_TEST_RUNNER) return null; - - var engine = lunr(properties); - return { - store : function(values) { - engine.add(values); - }, - search : function(q) { - return engine.search(q); - } - }; - }; -}; - -docsApp.serviceFactory.docsSearch = ['$rootScope','lunrSearch', 'NG_PAGES', - function($rootScope, lunrSearch, NG_PAGES) { - if (window.RUNNING_IN_NG_TEST_RUNNER) { - return null; - } - - var index = lunrSearch(function() { - this.ref('id'); - this.field('title', {boost: 50}); - this.field('description', { boost : 20 }); - }); - - angular.forEach(NG_PAGES, function(page, i) { - var title = page.shortName; - if(title.charAt(0) == 'n' && title.charAt(1) == 'g') { - title = title + ' ' + title.charAt(2).toLowerCase() + title.substr(3); - } - index.store({ - id: i, - title: title, - description: page.keywords - }); - }); - - return function(q) { - var results = {}; - angular.forEach(index.search(q), function(result) { - var item = NG_PAGES[result.ref]; - var section = item.section; - results[section] = results[section] || []; - if(results[section].length < 15) { - results[section].push(item); - } - }); - return results; - }; -}]; - -docsApp.directive.focused = function($timeout) { - return function(scope, element, attrs) { - element[0].focus(); - element.on('focus', function() { - scope.$apply(attrs.focused + '=true'); - }); - element.on('blur', function() { - // have to use $timeout, so that we close the drop-down after the user clicks, - // otherwise when the user clicks we process the closing before we process the click. - $timeout(function() { - scope.$eval(attrs.focused + '=false'); - }); - }); - scope.$eval(attrs.focused + '=true'); - }; -}; - -docsApp.directive.docsSearchInput = ['$document',function($document) { - return function(scope, element, attrs) { - var ESCAPE_KEY_KEYCODE = 27, - FORWARD_SLASH_KEYCODE = 191; - angular.element($document[0].body).bind('keydown', function(event) { - if(event.keyCode == FORWARD_SLASH_KEYCODE && document.activeElement) { - var activeElement = document.activeElement; - var activeTagName = activeElement.nodeName.toLowerCase(); - var hasInputFocus = activeTagName == 'input' || activeTagName == 'select' || - activeTagName == 'option' || activeTagName == 'textarea' || - activeElement.hasAttribute('contenteditable'); - if(!hasInputFocus) { - event.stopPropagation(); - event.preventDefault(); - - var input = element[0]; - input.focus(); - } - } - }); - - element.bind('keydown', function(event) { - if(event.keyCode == ESCAPE_KEY_KEYCODE) { - event.stopPropagation(); - event.preventDefault(); - scope.$apply(function() { - scope.hideResults(); - }); - } - }); - }; -}]; - - -docsApp.directive.code = function() { - return { restrict:'E', terminal: true }; -}; - - -docsApp.directive.sourceEdit = function(getEmbeddedTemplate) { - return { - template: '
                            ' + - '' + - ' Edit' + - '' + - '' + - '
                            ', - scope: true, - controller: function($scope, $attrs, openJsFiddle, openPlunkr) { - var sources = { - module: $attrs.sourceEdit, - deps: read($attrs.sourceEditDeps), - html: read($attrs.sourceEditHtml), - css: read($attrs.sourceEditCss), - js: read($attrs.sourceEditJs), - json: read($attrs.sourceEditJson), - unit: read($attrs.sourceEditUnit), - scenario: read($attrs.sourceEditScenario) - }; - $scope.fiddle = function(e) { - e.stopPropagation(); - openJsFiddle(sources); - }; - $scope.plunkr = function(e) { - e.stopPropagation(); - openPlunkr(sources); - }; - } - }; - - function read(text) { - var files = []; - angular.forEach(text ? text.split(' ') : [], function(refId) { - // refId is index.html-343, so we need to strip the unique ID when exporting the name - files.push({name: refId.replace(/-\d+$/, ''), content: getEmbeddedTemplate(refId)}); - }); - return files; - } -}; - -docsApp.directive.docModuleComponents = function() { - return { - template: '
                            ' + - '

                            Module Components

                            ' + - '
                            ' + - '

                            {{ section.title }}

                            ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - '
                            NameDescription
                            {{ component.shortName }}{{ component.shortDescription }}
                            ' + - '
                            ' + - '
                            ', - scope : { - module : '@docModuleComponents' - }, - controller : ['$scope', '$anchorScroll', '$timeout', 'sections', - function($scope, $anchorScroll, $timeout, sections) { - var validTypes = ['property','function','directive','service','object','filter']; - var components = {}; - angular.forEach(sections.api, function(item) { - if(item.moduleName == $scope.module) { - var type = item.type; - if(type == 'object') type = 'service'; - if(validTypes.indexOf(type) >= 0) { - components[type] = components[type] || { - title : type, - type : type, - components : [] - }; - components[type].components.push(item); - } - } - }); - $scope.components = components; - $timeout($anchorScroll, 0, false); - }] - }; -}; - -docsApp.directive.docTutorialNav = function(templateMerge) { - var pages = [ - '', - 'step_00', 'step_01', 'step_02', 'step_03', 'step_04', - 'step_05', 'step_06', 'step_07', 'step_08', 'step_09', - 'step_10', 'step_11', 'step_12', 'the_end' - ]; - return { - compile: function(element, attrs) { - var seq = 1 * attrs.docTutorialNav, - props = { - seq: seq, - prev: pages[seq], - next: pages[2 + seq], - diffLo: seq ? (seq - 1): '0~1', - diffHi: seq - }; - - element.addClass('btn-group'); - element.addClass('tutorial-nav'); - element.append(templateMerge( - '
                          • Previous
                          • \n' + - '
                          • Live Demo
                          • \n' + - '
                          • Code Diff
                          • \n' + - '
                          • Next
                          • ', props)); - } - }; -}; - - -docsApp.directive.docTutorialReset = function() { - function tab(name, command, id, step) { - return '' + - '
                            \n' + - '
                              \n' + - '
                            1. Reset the workspace to step ' + step + '.

                              ' + - '
                              ' + command + '
                            2. \n' + - '
                            3. Refresh your browser or check the app out on Angular\'s server.

                            4. \n' + - '
                            \n' + - '
                            \n'; - } - - return { - compile: function(element, attrs) { - var step = attrs.docTutorialReset; - element.html( - '\n' + - '
                            \n' + - tab('Git on Mac/Linux', 'git checkout -f step-' + step, 'gitUnix', step) + - tab('Git on Windows', 'git checkout -f step-' + step, 'gitWin', step) + - '
                            \n'); - } - }; -}; - - -docsApp.filter.errorLink = ['$sanitize', function ($sanitize) { - var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/g, - MAILTO_REGEXP = /^mailto:/, - STACK_TRACE_REGEXP = /:\d+:\d+$/; - - var truncate = function (text, nchars) { - if (text.length > nchars) { - return text.substr(0, nchars - 3) + '...'; - } - return text; - }; - - return function (text, target) { - var targetHtml = target ? ' target="' + target + '"' : ''; - - if (!text) return text; - - return $sanitize(text.replace(LINKY_URL_REGEXP, function (url) { - if (STACK_TRACE_REGEXP.test(url)) { - return url; - } - - // if we did not match ftp/http/mailto then assume mailto - if (!/^((ftp|https?):\/\/|mailto:)/.test(url)) url = 'mailto:' + url; - - return '' + - truncate(url.replace(MAILTO_REGEXP, ''), 60) + - ''; - })); - }; -}]; - - -docsApp.directive.errorDisplay = ['$location', 'errorLinkFilter', function ($location, errorLinkFilter) { - 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; angular.isDefined(search['p'+i]); i++) { - formatArgs.push(search['p'+i]); - } - element.html(errorLinkFilter(interpolate.apply(null, formatArgs), '_blank')); - } - }; -}]; - - -/** - * backToTop Directive - * @param {Function} $anchorScroll - * - * @description Ensure that the browser scrolls when the anchor is clicked - */ -docsApp.directive.backToTop = ['$anchorScroll', function($anchorScroll) { - return function link(scope, element) { - element.on('click', function(event) { - scope.$apply($anchorScroll); - }); - }; -}]; - - -docsApp.serviceFactory.angularUrls = function($document) { - var urls = {}; - - angular.forEach($document.find('script'), function(script) { - var match = script.src.match(/^.*\/(angular[^\/]*\.js)$/); - if (match) { - urls[match[1].replace(/(\-\d.*)?(\.min)?\.js$/, '.js')] = match[0]; - } - }); - - return urls; -}; - - -docsApp.serviceFactory.formPostData = function($document) { - return function(url, fields) { - var form = angular.element('
                            '); - angular.forEach(fields, function(value, name) { - var input = angular.element(''); - input.attr('value', value); - form.append(input); - }); - $document.find('body').append(form); - form[0].submit(); - form.remove(); - }; -}; - - -docsApp.serviceFactory.prepareDefaultAppModule = function() { - return function(content) { - var deps = []; - angular.forEach(content.deps, function(file) { - if(file.name == 'angular-animate.js') { - deps.push('ngAnimate'); - } - }); - - var moduleName = 'App'; - return { - module : moduleName, - script : "angular.module('" + moduleName + "', [" + - (deps.length ? "'" + deps.join("','") + "'" : "") + "]);\n\n" - }; - }; -}; - -docsApp.serviceFactory.prepareEditorAssetTags = function(angularUrls) { - return function(content, options) { - options = options || {}; - var includeLocalFiles = options.includeLocalFiles; - var html = makeScriptTag(angularUrls['angular.js']); - - var allFiles = [].concat(content.js, content.css, content.html, content.json); - angular.forEach(content.deps, function(file) { - if (file.name !== 'angular.js') { - var isLocal = false; - for(var i=0;i\n'; - }; - - function makeCssLinkTag(src) { - return '\n'; - }; - }; -}; - - -docsApp.serviceFactory.openPlunkr = function(templateMerge, formPostData, prepareEditorAssetTags, prepareDefaultAppModule) { - return function(content) { - var hasRouting = false; - angular.forEach(content.deps, function(file) { - hasRouting = hasRouting || file.name == 'angular-route.js'; - }); - var indexHtmlContent = '\n' + - '\n' + - ' \n' + - '{{scriptDeps}}'; - - if(hasRouting) { - indexHtmlContent += '\n'; - } - - indexHtmlContent += '\n' + - ' \n\n' + - '{{indexContents}}\n\n' + - ' \n' + - '\n'; - - indexProp = { - module: content.module, - scriptDeps: prepareEditorAssetTags(content, { includeLocalFiles : true }), - indexContents: content.html[0].content - }; - - var allFiles = [].concat(content.js, content.css, content.html, content.json); - - if(!content.module) { - var moduleData = prepareDefaultAppModule(content); - indexProp.module = moduleData.module; - - var found = false; - angular.forEach(content.js, function(file) { - if(file.name == 'script.js') { - file.content = moduleData.script + file.content; - found = true; - } - }); - if(!found) { - indexProp.scriptDeps += '\n'; - allFiles.push({ - name : 'script.js', - content : moduleData.script - }); - } - }; - - var postData = {}; - - angular.forEach(allFiles, function(file, index) { - if (file.content && file.name != 'index.html') { - postData['files[' + file.name + ']'] = file.content; - } - }); - - postData['files[index.html]'] = templateMerge(indexHtmlContent, indexProp); - postData['tags[]'] = "angularjs"; - - postData.private = true; - postData.description = 'AngularJS Example Plunkr'; - - formPostData('http://plnkr.co/edit/?p=preview', postData); - }; -}; - -docsApp.serviceFactory.openJsFiddle = function(templateMerge, formPostData, prepareEditorAssetTags, prepareDefaultAppModule) { - var HTML = '
                            \n{{html:2}}
                            ', - CSS = ' \n' + - '{{head:0}} - - -
                            -
                            + + +
                            +
                            + Name: +
                            + E-mail:
                            + Gender: male + female
                            + + +
                            +
                            + + + + +
                            +
                            @@ -130,54 +130,54 @@ This allows us to extend the above example with these features: - SAVE button is enabled only if form has some changes and is valid - custom error messages for `user.email` and `user.agree` - - -
                            -
                            - Name: -
                            - E-mail: -
                            -
                            Invalid: - Tell us your email. - This is not a valid email. + + +
                            + + Name: +
                            + E-mail: +
                            +
                            Invalid: + Tell us your email. + This is not a valid email. +
                            + + Gender: male + female
                            + + + I agree:
                            +
                            Please agree and sign.
                            + + + +
                            +
                            - Gender: male - female
                            - - - I agree:
                            -
                            Please agree and sign.
                            - - - - -
                            + + function Controller($scope) { + $scope.master = {}; - - - + $scope.reset(); + } + + @@ -209,72 +209,72 @@ In the following example we create two directives. Note that we can't use input type `number` here as HTML5 browsers would not allow the user to type what it would consider an invalid number such as `1,2`. - - -
                            -
                            -
                            - Size (integer 0 - 10): - {{size}}
                            - This is not valid integer! - - The value must be in range 0 to 10! -
                            - -
                            - Length (float): - - {{length}}
                            - - This is not a valid float number! + + +
                            + +
                            + Size (integer 0 - 10): + {{size}}
                            + This is not valid integer! + + The value must be in range 0 to 10! +
                            + +
                            + Length (float): + + {{length}}
                            + + This is not a valid float number! +
                            +
                            - -
                            - - - - + + + + var app = angular.module('form-example1', []); + + var INTEGER_REGEXP = /^\-?\d+$/; + app.directive('integer', function() { + return { + require: 'ngModel', + link: function(scope, elm, attrs, ctrl) { + ctrl.$parsers.unshift(function(viewValue) { + if (INTEGER_REGEXP.test(viewValue)) { + // it is valid + ctrl.$setValidity('integer', true); + return viewValue; + } else { + // it is invalid, return undefined (no model update) + ctrl.$setValidity('integer', false); + return undefined; + } + }); + } + }; + }); + + var FLOAT_REGEXP = /^\-?\d+((\.|\,)\d+)?$/; + app.directive('smartFloat', function() { + return { + require: 'ngModel', + link: function(scope, elm, attrs, ctrl) { + ctrl.$parsers.unshift(function(viewValue) { + if (FLOAT_REGEXP.test(viewValue)) { + ctrl.$setValidity('float', true); + return parseFloat(viewValue.replace(',', '.')); + } else { + ctrl.$setValidity('float', false); + return undefined; + } + }); + } + }; + }); + + # Implementing custom form controls (using `ngModel`) @@ -290,40 +290,40 @@ See {@link guide/directive $compileProvider.directive} for more info. The following example shows how to add two-way data-binding to contentEditable elements. - - - - -
                            Some
                            -
                            model = {{content}}
                            - - -
                            -
                            + + + + + angular.module('form-example2', []).directive('contenteditable', function() { + return { + require: 'ngModel', + link: function(scope, elm, attrs, ctrl) { + // view -> model + elm.on('blur', function() { + scope.$apply(function() { + ctrl.$setViewValue(elm.html()); + }); + }); + + // model -> view + ctrl.$render = function() { + elm.html(ctrl.$viewValue); + }; + + // load init value from DOM + ctrl.$setViewValue(elm.html()); + } + }; + }); + + diff --git a/docs/content/guide/ie.ngdoc b/docs/content/guide/ie.ngdoc index d66fd0b430b8..f4e442b70e86 100644 --- a/docs/content/guide/ie.ngdoc +++ b/docs/content/guide/ie.ngdoc @@ -27,7 +27,7 @@ To make your Angular application work on IE please make sure that: [JSON2](https://github.com/douglascrockford/JSON-js) or [JSON3](http://bestiejs.github.com/json3/) polyfills for this. - ```html + ```html @@ -43,7 +43,7 @@ To make your Angular application work on IE please make sure that: 2. add `id="ng-app"` to the root element in conjunction with `ng-app` attribute - ```html + ```html ... @@ -55,7 +55,7 @@ To make your Angular application work on IE please make sure that: 4. if you **do use** custom element tags, then you must take these steps to make IE 8 and below happy: - ```html + ```html diff --git a/docs/content/guide/module.ngdoc b/docs/content/guide/module.ngdoc index ad5fde132196..747209c2c524 100644 --- a/docs/content/guide/module.ngdoc +++ b/docs/content/guide/module.ngdoc @@ -26,26 +26,26 @@ Important things to notice: * Notice the reference to the `myApp` module in the ``, it is what bootstraps the app using your module. - - - + +
                            {{ 'World' | greet }}
                            -
                            -
                            + + + + // declare a module + var myAppModule = angular.module('myApp', []); + + // configure the module. + // in this example we will create a greeting filter + myAppModule.filter('greet', function() { + return function(name) { + return 'Hello, ' + name + '!'; + }; + }); + + @@ -67,49 +67,50 @@ that are relevant to tests. The above is only a suggestion, so feel free to tailor it to your needs. - - - -
                            - {{ greeting }}! -
                            -
                            -
                            + // A Controller for your app + var XmplController = function($scope, greeter, user) { + $scope.greeting = greeter.greet(user.name); + }; + + From e2c47dee3c313af514e3a501ee5f904b09daf669 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sun, 16 Feb 2014 18:16:11 +0000 Subject: [PATCH 095/123] docs(indexPage.template): fix top-nav links to work on localhost --- docs/config/templates/indexPage.template.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/config/templates/indexPage.template.html b/docs/config/templates/indexPage.template.html index 0fa266f7722c..4aa13cb96d7a 100644 --- a/docs/config/templates/indexPage.template.html +++ b/docs/config/templates/indexPage.template.html @@ -109,11 +109,11 @@ Develop From 495586eed52be7adefb703c53c0f5a2837ed9b8f Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sun, 16 Feb 2014 18:23:38 +0000 Subject: [PATCH 096/123] chore(travis): disable Safari and JQuery e2e tests on Travis There are no real JQuery tests at this point anyway and the Safari that we are getting from SauceLabs seems to be a flakey Windows 2000 version that is not necessarily providing accurate results. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b94d3b58f2a5..f605270ba500 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,10 @@ env: - JOB=unit - JOB=e2e BROWSER=chrome JQVERSION=jqlite - JOB=e2e BROWSER=firefox JQVERSION=jqlite - - JOB=e2e BROWSER=safari JQVERSION=jqlite - - JOB=e2e BROWSER=chrome JQVERSION=jquery - - JOB=e2e BROWSER=firefox JQVERSION=jquery - - JOB=e2e BROWSER=safari JQVERSION=jquery +# - JOB=e2e BROWSER=safari JQVERSION=jqlite +# - JOB=e2e BROWSER=chrome JQVERSION=jquery +# - JOB=e2e BROWSER=firefox JQVERSION=jquery +# - JOB=e2e BROWSER=safari JQVERSION=jquery global: - SAUCE_USERNAME=angular-ci - SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987 From 68706aa4bf3c02b53d92d8258590275bcb9f6612 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sun, 16 Feb 2014 22:02:31 +0000 Subject: [PATCH 097/123] chore(errors): rename folders to match namespaces --- docs/content/error/{animate => $animate}/notcsel.ngdoc | 0 docs/content/error/{cacheFactory => $cacheFactory}/iid.ngdoc | 0 docs/content/error/{compile => $compile}/ctreq.ngdoc | 0 docs/content/error/{compile => $compile}/iscp.ngdoc | 0 docs/content/error/{compile => $compile}/multidir.ngdoc | 0 docs/content/error/{compile => $compile}/nodomevents.ngdoc | 0 docs/content/error/{compile => $compile}/nonassign.ngdoc | 0 docs/content/error/{compile => $compile}/selmulti.ngdoc | 0 docs/content/error/{compile => $compile}/tpload.ngdoc | 0 docs/content/error/{compile => $compile}/tplrt.ngdoc | 0 docs/content/error/{compile => $compile}/uterdir.ngdoc | 0 docs/content/error/{controller => $controller}/noscp.ngdoc | 0 docs/content/error/{httpBackend => $httpBackend}/noxhr.ngdoc | 0 docs/content/error/{injector => $injector}/cdep.ngdoc | 0 docs/content/error/{injector => $injector}/itkn.ngdoc | 0 docs/content/error/{injector => $injector}/modulerr.ngdoc | 0 docs/content/error/{injector => $injector}/nomod.ngdoc | 0 docs/content/error/{injector => $injector}/pget.ngdoc | 0 docs/content/error/{injector => $injector}/unpr.ngdoc | 0 docs/content/error/{interpolate => $interpolate}/interr.ngdoc | 0 docs/content/error/{interpolate => $interpolate}/noconcat.ngdoc | 0 docs/content/error/{location => $location}/ihshprfx.ngdoc | 0 docs/content/error/{location => $location}/ipthprfx.ngdoc | 0 docs/content/error/{location => $location}/isrcharg.ngdoc | 0 docs/content/error/{parse => $parse}/isecdom.ngdoc | 0 docs/content/error/{parse => $parse}/isecfld.ngdoc | 0 docs/content/error/{parse => $parse}/isecfn.ngdoc | 0 docs/content/error/{parse => $parse}/isecwindow.ngdoc | 0 docs/content/error/{parse => $parse}/lexerr.ngdoc | 0 docs/content/error/{parse => $parse}/syntax.ngdoc | 0 docs/content/error/{parse => $parse}/ueoe.ngdoc | 0 docs/content/error/{resource => $resource}/badargs.ngdoc | 0 docs/content/error/{resource => $resource}/badcfg.ngdoc | 0 docs/content/error/{resource => $resource}/badmember.ngdoc | 0 docs/content/error/{resource => $resource}/badname.ngdoc | 0 docs/content/error/{rootScope => $rootScope}/infdig.ngdoc | 0 docs/content/error/{rootScope => $rootScope}/inprog.ngdoc | 0 docs/content/error/{sanitize => $sanitize}/badparse.ngdoc | 0 docs/content/error/{sce => $sce}/icontext.ngdoc | 0 docs/content/error/{sce => $sce}/iequirks.ngdoc | 0 docs/content/error/{sce => $sce}/imatcher.ngdoc | 0 docs/content/error/{sce => $sce}/insecurl.ngdoc | 0 docs/content/error/{sce => $sce}/itype.ngdoc | 0 docs/content/error/{sce => $sce}/iwcard.ngdoc | 0 docs/content/error/{sce => $sce}/unsafe.ngdoc | 0 45 files changed, 0 insertions(+), 0 deletions(-) rename docs/content/error/{animate => $animate}/notcsel.ngdoc (100%) rename docs/content/error/{cacheFactory => $cacheFactory}/iid.ngdoc (100%) rename docs/content/error/{compile => $compile}/ctreq.ngdoc (100%) rename docs/content/error/{compile => $compile}/iscp.ngdoc (100%) rename docs/content/error/{compile => $compile}/multidir.ngdoc (100%) rename docs/content/error/{compile => $compile}/nodomevents.ngdoc (100%) rename docs/content/error/{compile => $compile}/nonassign.ngdoc (100%) rename docs/content/error/{compile => $compile}/selmulti.ngdoc (100%) rename docs/content/error/{compile => $compile}/tpload.ngdoc (100%) rename docs/content/error/{compile => $compile}/tplrt.ngdoc (100%) rename docs/content/error/{compile => $compile}/uterdir.ngdoc (100%) rename docs/content/error/{controller => $controller}/noscp.ngdoc (100%) rename docs/content/error/{httpBackend => $httpBackend}/noxhr.ngdoc (100%) rename docs/content/error/{injector => $injector}/cdep.ngdoc (100%) rename docs/content/error/{injector => $injector}/itkn.ngdoc (100%) rename docs/content/error/{injector => $injector}/modulerr.ngdoc (100%) rename docs/content/error/{injector => $injector}/nomod.ngdoc (100%) rename docs/content/error/{injector => $injector}/pget.ngdoc (100%) rename docs/content/error/{injector => $injector}/unpr.ngdoc (100%) rename docs/content/error/{interpolate => $interpolate}/interr.ngdoc (100%) rename docs/content/error/{interpolate => $interpolate}/noconcat.ngdoc (100%) rename docs/content/error/{location => $location}/ihshprfx.ngdoc (100%) rename docs/content/error/{location => $location}/ipthprfx.ngdoc (100%) rename docs/content/error/{location => $location}/isrcharg.ngdoc (100%) rename docs/content/error/{parse => $parse}/isecdom.ngdoc (100%) rename docs/content/error/{parse => $parse}/isecfld.ngdoc (100%) rename docs/content/error/{parse => $parse}/isecfn.ngdoc (100%) rename docs/content/error/{parse => $parse}/isecwindow.ngdoc (100%) rename docs/content/error/{parse => $parse}/lexerr.ngdoc (100%) rename docs/content/error/{parse => $parse}/syntax.ngdoc (100%) rename docs/content/error/{parse => $parse}/ueoe.ngdoc (100%) rename docs/content/error/{resource => $resource}/badargs.ngdoc (100%) rename docs/content/error/{resource => $resource}/badcfg.ngdoc (100%) rename docs/content/error/{resource => $resource}/badmember.ngdoc (100%) rename docs/content/error/{resource => $resource}/badname.ngdoc (100%) rename docs/content/error/{rootScope => $rootScope}/infdig.ngdoc (100%) rename docs/content/error/{rootScope => $rootScope}/inprog.ngdoc (100%) rename docs/content/error/{sanitize => $sanitize}/badparse.ngdoc (100%) rename docs/content/error/{sce => $sce}/icontext.ngdoc (100%) rename docs/content/error/{sce => $sce}/iequirks.ngdoc (100%) rename docs/content/error/{sce => $sce}/imatcher.ngdoc (100%) rename docs/content/error/{sce => $sce}/insecurl.ngdoc (100%) rename docs/content/error/{sce => $sce}/itype.ngdoc (100%) rename docs/content/error/{sce => $sce}/iwcard.ngdoc (100%) rename docs/content/error/{sce => $sce}/unsafe.ngdoc (100%) diff --git a/docs/content/error/animate/notcsel.ngdoc b/docs/content/error/$animate/notcsel.ngdoc similarity index 100% rename from docs/content/error/animate/notcsel.ngdoc rename to docs/content/error/$animate/notcsel.ngdoc diff --git a/docs/content/error/cacheFactory/iid.ngdoc b/docs/content/error/$cacheFactory/iid.ngdoc similarity index 100% rename from docs/content/error/cacheFactory/iid.ngdoc rename to docs/content/error/$cacheFactory/iid.ngdoc diff --git a/docs/content/error/compile/ctreq.ngdoc b/docs/content/error/$compile/ctreq.ngdoc similarity index 100% rename from docs/content/error/compile/ctreq.ngdoc rename to docs/content/error/$compile/ctreq.ngdoc diff --git a/docs/content/error/compile/iscp.ngdoc b/docs/content/error/$compile/iscp.ngdoc similarity index 100% rename from docs/content/error/compile/iscp.ngdoc rename to docs/content/error/$compile/iscp.ngdoc diff --git a/docs/content/error/compile/multidir.ngdoc b/docs/content/error/$compile/multidir.ngdoc similarity index 100% rename from docs/content/error/compile/multidir.ngdoc rename to docs/content/error/$compile/multidir.ngdoc diff --git a/docs/content/error/compile/nodomevents.ngdoc b/docs/content/error/$compile/nodomevents.ngdoc similarity index 100% rename from docs/content/error/compile/nodomevents.ngdoc rename to docs/content/error/$compile/nodomevents.ngdoc diff --git a/docs/content/error/compile/nonassign.ngdoc b/docs/content/error/$compile/nonassign.ngdoc similarity index 100% rename from docs/content/error/compile/nonassign.ngdoc rename to docs/content/error/$compile/nonassign.ngdoc diff --git a/docs/content/error/compile/selmulti.ngdoc b/docs/content/error/$compile/selmulti.ngdoc similarity index 100% rename from docs/content/error/compile/selmulti.ngdoc rename to docs/content/error/$compile/selmulti.ngdoc diff --git a/docs/content/error/compile/tpload.ngdoc b/docs/content/error/$compile/tpload.ngdoc similarity index 100% rename from docs/content/error/compile/tpload.ngdoc rename to docs/content/error/$compile/tpload.ngdoc diff --git a/docs/content/error/compile/tplrt.ngdoc b/docs/content/error/$compile/tplrt.ngdoc similarity index 100% rename from docs/content/error/compile/tplrt.ngdoc rename to docs/content/error/$compile/tplrt.ngdoc diff --git a/docs/content/error/compile/uterdir.ngdoc b/docs/content/error/$compile/uterdir.ngdoc similarity index 100% rename from docs/content/error/compile/uterdir.ngdoc rename to docs/content/error/$compile/uterdir.ngdoc diff --git a/docs/content/error/controller/noscp.ngdoc b/docs/content/error/$controller/noscp.ngdoc similarity index 100% rename from docs/content/error/controller/noscp.ngdoc rename to docs/content/error/$controller/noscp.ngdoc diff --git a/docs/content/error/httpBackend/noxhr.ngdoc b/docs/content/error/$httpBackend/noxhr.ngdoc similarity index 100% rename from docs/content/error/httpBackend/noxhr.ngdoc rename to docs/content/error/$httpBackend/noxhr.ngdoc diff --git a/docs/content/error/injector/cdep.ngdoc b/docs/content/error/$injector/cdep.ngdoc similarity index 100% rename from docs/content/error/injector/cdep.ngdoc rename to docs/content/error/$injector/cdep.ngdoc diff --git a/docs/content/error/injector/itkn.ngdoc b/docs/content/error/$injector/itkn.ngdoc similarity index 100% rename from docs/content/error/injector/itkn.ngdoc rename to docs/content/error/$injector/itkn.ngdoc diff --git a/docs/content/error/injector/modulerr.ngdoc b/docs/content/error/$injector/modulerr.ngdoc similarity index 100% rename from docs/content/error/injector/modulerr.ngdoc rename to docs/content/error/$injector/modulerr.ngdoc diff --git a/docs/content/error/injector/nomod.ngdoc b/docs/content/error/$injector/nomod.ngdoc similarity index 100% rename from docs/content/error/injector/nomod.ngdoc rename to docs/content/error/$injector/nomod.ngdoc diff --git a/docs/content/error/injector/pget.ngdoc b/docs/content/error/$injector/pget.ngdoc similarity index 100% rename from docs/content/error/injector/pget.ngdoc rename to docs/content/error/$injector/pget.ngdoc diff --git a/docs/content/error/injector/unpr.ngdoc b/docs/content/error/$injector/unpr.ngdoc similarity index 100% rename from docs/content/error/injector/unpr.ngdoc rename to docs/content/error/$injector/unpr.ngdoc diff --git a/docs/content/error/interpolate/interr.ngdoc b/docs/content/error/$interpolate/interr.ngdoc similarity index 100% rename from docs/content/error/interpolate/interr.ngdoc rename to docs/content/error/$interpolate/interr.ngdoc diff --git a/docs/content/error/interpolate/noconcat.ngdoc b/docs/content/error/$interpolate/noconcat.ngdoc similarity index 100% rename from docs/content/error/interpolate/noconcat.ngdoc rename to docs/content/error/$interpolate/noconcat.ngdoc diff --git a/docs/content/error/location/ihshprfx.ngdoc b/docs/content/error/$location/ihshprfx.ngdoc similarity index 100% rename from docs/content/error/location/ihshprfx.ngdoc rename to docs/content/error/$location/ihshprfx.ngdoc diff --git a/docs/content/error/location/ipthprfx.ngdoc b/docs/content/error/$location/ipthprfx.ngdoc similarity index 100% rename from docs/content/error/location/ipthprfx.ngdoc rename to docs/content/error/$location/ipthprfx.ngdoc diff --git a/docs/content/error/location/isrcharg.ngdoc b/docs/content/error/$location/isrcharg.ngdoc similarity index 100% rename from docs/content/error/location/isrcharg.ngdoc rename to docs/content/error/$location/isrcharg.ngdoc diff --git a/docs/content/error/parse/isecdom.ngdoc b/docs/content/error/$parse/isecdom.ngdoc similarity index 100% rename from docs/content/error/parse/isecdom.ngdoc rename to docs/content/error/$parse/isecdom.ngdoc diff --git a/docs/content/error/parse/isecfld.ngdoc b/docs/content/error/$parse/isecfld.ngdoc similarity index 100% rename from docs/content/error/parse/isecfld.ngdoc rename to docs/content/error/$parse/isecfld.ngdoc diff --git a/docs/content/error/parse/isecfn.ngdoc b/docs/content/error/$parse/isecfn.ngdoc similarity index 100% rename from docs/content/error/parse/isecfn.ngdoc rename to docs/content/error/$parse/isecfn.ngdoc diff --git a/docs/content/error/parse/isecwindow.ngdoc b/docs/content/error/$parse/isecwindow.ngdoc similarity index 100% rename from docs/content/error/parse/isecwindow.ngdoc rename to docs/content/error/$parse/isecwindow.ngdoc diff --git a/docs/content/error/parse/lexerr.ngdoc b/docs/content/error/$parse/lexerr.ngdoc similarity index 100% rename from docs/content/error/parse/lexerr.ngdoc rename to docs/content/error/$parse/lexerr.ngdoc diff --git a/docs/content/error/parse/syntax.ngdoc b/docs/content/error/$parse/syntax.ngdoc similarity index 100% rename from docs/content/error/parse/syntax.ngdoc rename to docs/content/error/$parse/syntax.ngdoc diff --git a/docs/content/error/parse/ueoe.ngdoc b/docs/content/error/$parse/ueoe.ngdoc similarity index 100% rename from docs/content/error/parse/ueoe.ngdoc rename to docs/content/error/$parse/ueoe.ngdoc diff --git a/docs/content/error/resource/badargs.ngdoc b/docs/content/error/$resource/badargs.ngdoc similarity index 100% rename from docs/content/error/resource/badargs.ngdoc rename to docs/content/error/$resource/badargs.ngdoc diff --git a/docs/content/error/resource/badcfg.ngdoc b/docs/content/error/$resource/badcfg.ngdoc similarity index 100% rename from docs/content/error/resource/badcfg.ngdoc rename to docs/content/error/$resource/badcfg.ngdoc diff --git a/docs/content/error/resource/badmember.ngdoc b/docs/content/error/$resource/badmember.ngdoc similarity index 100% rename from docs/content/error/resource/badmember.ngdoc rename to docs/content/error/$resource/badmember.ngdoc diff --git a/docs/content/error/resource/badname.ngdoc b/docs/content/error/$resource/badname.ngdoc similarity index 100% rename from docs/content/error/resource/badname.ngdoc rename to docs/content/error/$resource/badname.ngdoc diff --git a/docs/content/error/rootScope/infdig.ngdoc b/docs/content/error/$rootScope/infdig.ngdoc similarity index 100% rename from docs/content/error/rootScope/infdig.ngdoc rename to docs/content/error/$rootScope/infdig.ngdoc diff --git a/docs/content/error/rootScope/inprog.ngdoc b/docs/content/error/$rootScope/inprog.ngdoc similarity index 100% rename from docs/content/error/rootScope/inprog.ngdoc rename to docs/content/error/$rootScope/inprog.ngdoc diff --git a/docs/content/error/sanitize/badparse.ngdoc b/docs/content/error/$sanitize/badparse.ngdoc similarity index 100% rename from docs/content/error/sanitize/badparse.ngdoc rename to docs/content/error/$sanitize/badparse.ngdoc diff --git a/docs/content/error/sce/icontext.ngdoc b/docs/content/error/$sce/icontext.ngdoc similarity index 100% rename from docs/content/error/sce/icontext.ngdoc rename to docs/content/error/$sce/icontext.ngdoc diff --git a/docs/content/error/sce/iequirks.ngdoc b/docs/content/error/$sce/iequirks.ngdoc similarity index 100% rename from docs/content/error/sce/iequirks.ngdoc rename to docs/content/error/$sce/iequirks.ngdoc diff --git a/docs/content/error/sce/imatcher.ngdoc b/docs/content/error/$sce/imatcher.ngdoc similarity index 100% rename from docs/content/error/sce/imatcher.ngdoc rename to docs/content/error/$sce/imatcher.ngdoc diff --git a/docs/content/error/sce/insecurl.ngdoc b/docs/content/error/$sce/insecurl.ngdoc similarity index 100% rename from docs/content/error/sce/insecurl.ngdoc rename to docs/content/error/$sce/insecurl.ngdoc diff --git a/docs/content/error/sce/itype.ngdoc b/docs/content/error/$sce/itype.ngdoc similarity index 100% rename from docs/content/error/sce/itype.ngdoc rename to docs/content/error/$sce/itype.ngdoc diff --git a/docs/content/error/sce/iwcard.ngdoc b/docs/content/error/$sce/iwcard.ngdoc similarity index 100% rename from docs/content/error/sce/iwcard.ngdoc rename to docs/content/error/$sce/iwcard.ngdoc diff --git a/docs/content/error/sce/unsafe.ngdoc b/docs/content/error/$sce/unsafe.ngdoc similarity index 100% rename from docs/content/error/sce/unsafe.ngdoc rename to docs/content/error/$sce/unsafe.ngdoc From 216a8f8715bc68bf3bc7479de0acc527a768e8bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Sun, 16 Feb 2014 18:54:52 -0500 Subject: [PATCH 098/123] docs(design): ui-fixes for examples, layout and API components --- docs/app/assets/css/docs.css | 217 ++++++++++++++---- .../assets/js/angular-bootstrap/bootstrap.js | 50 ++++ docs/app/src/examples.js | 2 +- docs/app/src/tutorials.js | 2 +- docs/config/templates/indexPage.template.html | 46 ++-- 5 files changed, 245 insertions(+), 72 deletions(-) diff --git a/docs/app/assets/css/docs.css b/docs/app/assets/css/docs.css index 2d667602f7f8..26e6b3359dd0 100644 --- a/docs/app/assets/css/docs.css +++ b/docs/app/assets/css/docs.css @@ -1,16 +1,21 @@ -body { +html, body { position:relative; + height:100%; } -body:before { - content:""; - position:absolute; + +.header-fixed { + position:fixed; + z-index:1000; top:0; - background:#eee; - height:120px; left:0; right:0; } +.docs-navbar-primary { + border-radius:0!important; + margin-bottom:0!important; +} + /* Logo */ /*.dropdown-menu { display:none; @@ -112,8 +117,8 @@ h1,h2,h3,h4,h5,h6 { } .nav-breadcrumb { - padding:0 0 20px; - margin:4px 0 20px; + margin:4px 0; + padding:0; } .nav-breadcrumb-entry { @@ -184,7 +189,8 @@ pre { } .api-profile-description > p:first-child { - font-size:20px; + margin:15px 0; + font-size:18px; } p > code, @@ -259,13 +265,6 @@ iframe.example { border: 1px solid black; } -.search-results-container { - padding-bottom:1em; - border-top:1px solid #111; - background:#181818; - box-shadow:inset 0 0 10px #111; -} - .search-results-frame { clear:both; display:table; @@ -276,6 +275,13 @@ iframe.example { display:none; } +.search-results-container { + padding-bottom:1em; + border-top:1px solid #111; + background:#181818; + box-shadow:inset 0 0 10px #111; +} + .search-results-container .search-results-group { vertical-align:top; padding:10px 10px; @@ -305,35 +311,29 @@ iframe.example { } .search-close { - color:maroon; - position:absolute; - bottom:-20px; - left:50%; - margin-left:-25px; - height:50px; - width:50px; - color:white; - font-size:1.5em; - text-align:center; - background:#333; - box-shadow:inset 0 0 5px #000; - border-radius:50px; -} - -.search-close-icon { - margin-top:14px; + position: absolute; + bottom: 0; + left: 50%; + margin-left: -100px; + color: white; + text-align: center; + padding: 5px; + background: #333; + border-top-right-radius: 5px; + border-top-left-radius: 5px; + width: 200px; + box-shadow:0 0 10px #111; } .variables-matrix { - border-collapse:separate; - border-radius:5px; border:1px solid #ddd; width:100%; + margin:10px 0; } .variables-matrix td, .variables-matrix th { - padding:0 10px; + padding:10px; } .variables-matrix td { @@ -345,14 +345,25 @@ iframe.example { border-left:1px solid #eee; } -.main-body-grid { - margin-top:50px; - position:relative; - min-height:100%; +.variables-matrix tr:nth-child(even) td { + background:#f5f5f5; } -.main-body-grid > .grid-right { - margin-left:270px; + +.variables-matrix th { + background:#f1f1f1; +} + +.sup-header { + padding-top:10px; + padding-bottom:5px; + background:rgba(240,240,240,0.88); + box-shadow:0 0 5px #999; +} + +.main-body-grid { + margin-top:120px; position:relative; + min-height:800px; } .main-body-grid > .grid-left, @@ -362,23 +373,26 @@ iframe.example { .main-body-grid > .grid-left { position:fixed; - top:50px; - width:260px; + top:120px; + padding-bottom:250px; height:100%; overflow:auto; } -.version-picker { - margin-bottom:30px; +.main-header-grid > .grid-left, +.main-body-grid > .grid-left { + width:260px; } -.improve-docs { - position:absolute; - top:20px; - right:20px; +.main-header-grid > .grid-right, +.main-body-grid > .grid-right { + margin-left:270px; + position:relative; } - +.main-header-grid > .grid-left { + float:left; +} .variables-matrix td { vertical-align:top; @@ -392,16 +406,29 @@ iframe.example { .variables-matrix .type-hint { text-align:center; min-width:60px; + margin:1px 5px; } .type-hint + .type-hint { margin-top:5px; } +.type-hint-expression { + background:purple; +} + +.type-hint-date { + background:pink; +} + .type-hint-string { background:#3a87ad; } +.type-hint-function { + background:green; +} + .type-hint-object { background:#999; } @@ -417,3 +444,91 @@ iframe.example { .type-hint-number { background:rgb(189, 63, 66); } + +.runnable-example-frame { + width:100%; + height:300px; + border: 1px solid #ddd; + border-radius:5px; +} + +.runnable-example-tabs { + margin-top:10px; + margin-bottom:20px; +} + +.tutorial-nav { + display:block; +} + +h1 + ul, h1 + ul > li, +h2 + ul, h2 + ul > li, +ul.tutorial-nav, ul.tutorial-nav > li, +.usage > ul, .usage > ul > li, +ul.methods, ul.methods > li, +ul.events, ul.events > li { + list-style:none; + padding:0; +} + +h2 { + border-top:1px solid #eee; + margin-top:30px; + padding-top:30px; +} + +.improve-docs { + float:right; +} + +.btn { + color:#428bca; + position: relative; + width: auto; + display: inline-block; + margin: 0 0 2px; + overflow: hidden; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 4px; + font-family: "Open Sans"; + font-weight: 600; + height: auto; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #f2f2f2)); + background-image: -webkit-linear-gradient(#ffffff, #f2f2f2); + background-image: -moz-linear-gradient(#ffffff, #f2f2f2); + background-image: -o-linear-gradient(#ffffff, #f2f2f2); + background-image: linear-gradient(#ffffff, #f2f2f2); +} + +.btn + .btn { + margin-left:10px; +} + +.btn:hover { + color:black!important; + border: 1px solid #ddd!important; + background:white!important; +} + +.view-source { + margin-right:10px; + padding-right:10px; + border-right:1px solid #999; +} + +.return-arguments, +.return-arguments th, +.return-arguments th + th, +.return-arguments td, +.return-arguments td + td { + border-radius:0; + border:0; +} + +.return-arguments td:first-child { + width:100px; +} diff --git a/docs/app/assets/js/angular-bootstrap/bootstrap.js b/docs/app/assets/js/angular-bootstrap/bootstrap.js index b9b5e38278f5..643b5a50ba95 100644 --- a/docs/app/assets/js/angular-bootstrap/bootstrap.js +++ b/docs/app/assets/js/angular-bootstrap/bootstrap.js @@ -2,6 +2,56 @@ var directive = {}; +directive.runnableExample = ['$templateCache', '$document', function($templateCache, $document) { + var exampleClassNameSelector = '.runnable-example-file'; + var doc = $document[0]; + var tpl = + ''; + + return { + restrict: 'C', + controller : ['$scope', function($scope) { + $scope.setTab = function(index) { + var tab = $scope.tabs[index]; + $scope.activeTabIndex = index; + $scope.$broadcast('tabChange', index, tab); + }; + }], + compile : function(element) { + element.html(tpl + element.html()); + return function(scope, element) { + var tabs = [], now = Date.now(); + angular.forEach(doc.querySelectorAll(exampleClassNameSelector), + function(child, index) { + + tabs.push(child.getAttribute('name')); + }); + + if(tabs.length > 0) { + scope.tabs = tabs; + scope.$on('tabChange', function(e, index, title) { + var elements = doc.querySelectorAll(exampleClassNameSelector); + angular.forEach(elements, function(child) { + child.style.display = 'none'; + }); + var selected = elements[index]; + selected.style.display = 'block'; + }); + scope.setTab(0); + } + } + } + }; +}]; + directive.dropdownToggle = ['$document', '$location', '$window', function ($document, $location, $window) { diff --git a/docs/app/src/examples.js b/docs/app/src/examples.js index 44dd98f16a78..0ad981c957ea 100644 --- a/docs/app/src/examples.js +++ b/docs/app/src/examples.js @@ -263,4 +263,4 @@ angular.module('examples', []) css: templateMerge(CSS, prop) }); }; -}); \ No newline at end of file +}); diff --git a/docs/app/src/tutorials.js b/docs/app/src/tutorials.js index a978daeddb8a..2f46494c55d3 100644 --- a/docs/app/src/tutorials.js +++ b/docs/app/src/tutorials.js @@ -55,4 +55,4 @@ angular.module('tutorials', []) '
                            \n'); } }; -}); \ No newline at end of file +}); diff --git a/docs/config/templates/indexPage.template.html b/docs/config/templates/indexPage.template.html index 4aa13cb96d7a..2e8003fd6f69 100644 --- a/docs/config/templates/indexPage.template.html +++ b/docs/config/templates/indexPage.template.html @@ -77,8 +77,8 @@ -
                            -