Compare commits

...

103 Commits

Author SHA1 Message Date
Martin Staffa c3c5c5eea2 docs(changelog): add changes for 1.6.9 2018-02-02 11:19:32 +01:00
Peter Bacon Darwin 4cc7701700 docs(*): ensure naming is correct for Angular(JS) versions
This was originally done on the master branch in
commit 03043839d5,
but never back-ported to 1.6.x.

That wasn't a big deal because docs.angularjs.org
served the master snapshot docs. However, now we
serve the 1.6.x snapshot docs, and it looks strange
that the official docs have the wrong branding :).
2018-02-02 11:10:17 +01:00
Dmitriy 5dc07667de feat(input): add drop event support (#16420) 2018-01-28 11:27:43 +00:00
Martin Staffa 212e5132ab chore(docs.angularjs.org): actually fix deployment
When a file is symlinked, relative paths obviously aren't correct anymore.
This error was masked because Travis didn't fail the job when Firebase
couldn't find the public folder.
To fix, we copy the file and adjust the folder path
2018-01-25 19:35:04 +01:00
Martin Staffa 00162655e7 docs(*): fix headings, links, and wordings 2018-01-25 19:31:40 +01:00
Martin Staffa 09f1325065 chore(docs.angularjs.org): fix firebase deploy
Travis looks for the firebase.json in the repo root,
but we moved each firebase project in its own sub-folder.
To fix, we create a symlink before deployment.
2018-01-22 17:19:55 +01:00
Martin Staffa c01dad694d chore(code.angularjs.org): don't use trailing slashes, and don't set headers after response was sent 2018-01-22 16:00:39 +01:00
Martin Staffa c4586513d1 chore(code.angularjs.org): don't gzip the zip file before uploading 2018-01-22 16:00:39 +01:00
Martin Staffa 7a1270cf4b chore(errors.angularjs.org): add project with redirects to docs.angularjs.org 2018-01-22 16:00:39 +01:00
Martin Staffa 559e93c7ce chore(docs.angularjs.org): move project in separate folder
Firebase projects should be in their own folder, because the firebase-tools
search for projects in the parent folder, which makes it more difficult to create
new projects.
2018-01-22 16:00:38 +01:00
Pete Bacon Darwin 9d058de04b fix(ngMessages): prevent memory leak from messages that are never attached
Closes #16389
Closes #16404
Closes #16406
2018-01-17 16:05:07 +01:00
Martin Staffa 1d826e2f1e fix(ngTransclude): remove terminal: true
This was introduced in commit 2adaff083f,
but made obsolete in 41f3269bfb.

Fixes #16411
Closes #16412
2018-01-17 16:05:07 +01:00
Martin Staffa 5789094546 docs(ngRepeat): improve info about tracking
- deduplicate info between docs section and arguments
- don't draw too much attention to track by $index  ...
- ... but highlight its drawbacks
- add example to show how tracking affects collection updates
- clarify duplicates support for specific tracking expressions

Closes #16332
Closes #16334 
Closes #16397
2018-01-17 16:05:07 +01:00
Martin Staffa cf92c33a32 docs(*): clarify module API and dependency injection rules
Closes #16363
Closes #16395
2018-01-17 16:05:07 +01:00
Martin Staffa 5d8f5a8be7 chore(code.angularjs.org): resolve gcs file stream on 'finish'
'response' is called before the data transfer is complete.
2018-01-17 16:05:07 +01:00
Martin Staffa 74a2808487 chore(docs.angularjs.org): copy unminified angular files
e2e tests use the unminified files even in production deployment
2018-01-17 16:05:07 +01:00
Deb Saunders 9ba181b80f docs(guide/External Resources): remove link to deprecated content
Content at URL is deprecated.

Closes #16403
2018-01-17 16:05:07 +01:00
Frederik Prijck 44c16b5b51 docs(guide/Animations): fix minor typos
Closes #16409
2018-01-17 16:05:07 +01:00
Manuel Darveau 70a42fcaee docs(guide/Using $location): fix typo
Closes #16408
2018-01-17 16:05:07 +01:00
Martin Staffa 3bd62d2d59 chore(node): add karma launchers for Edge, IE, and Safari
That makes it easier to run the tests with these browsers locally.

Closes #16407
2018-01-17 16:05:07 +01:00
Peter Bacon Darwin b9ef6585e1 fix($sanitize): sanitize xml:base attributes
On Firefox there is a XSS vulnerability if a malicious attacker
can write into the `xml:base` attribute on an SVG anchor.

Thanks to Masato Kinugawa at Cure23
2018-01-17 16:05:07 +01:00
Martin Staffa e06b4fb62c chore(travis): test on 2 latest Safari versions 2018-01-17 16:05:07 +01:00
Martin Staffa 9204a1a153 test(*): fix tests for Safari 10+
The mocksSpec change is due to the following issue in Safari 10+ strict mode:
In the following code, Safari will not use the name of the enclosing function (testCaller)
in the stack, but rather list the anonymous function that is called to inject:

```
function testCaller() {
  return inject(function() {
    throw new Error();
  });
}
var throwErrorFromInjectCallback = testCaller();
```

Naming the anonymous function allows us to check for it in the test.
2018-01-17 16:05:07 +01:00
Martin Staffa f4d49f3769 docs(guide/Controllers): fix headings; re-order info 2018-01-10 13:01:33 +01:00
Martin Staffa d5c35b44d7 chore(node): update semver
Closes #16396
2018-01-10 12:58:52 +01:00
Martin Staffa 551375c736 docs(vendor): add readme 2018-01-08 13:03:36 +01:00
Martin Staffa 17691790e9 refactor(getVersion.js): remove unused parameters
The parameters have been unused since we moved most of the bower
package dependencies to npm
2018-01-08 13:03:24 +01:00
Michał Gołębiowski-Owczarek e47dead052 chore(*): get rid of Bower in favor of Yarn aliases & checked-in packages
Bower was used to install multiple versions of jQuery which is now handled
using Yarn aliases. The remaining two packages, closure-compiler and
ng-closure-compiler were installed from zip files which is not supported by Yarn
(see https://github.com/yarnpkg/yarn/issues/1483); the first of them exists
on npm as the google-closure-compiler but only versions newer than we used are
published and they don't work with ng-closure-compiler so - instead - both were
checked in to the repository.

Fixes #16268
Fixes #14961
Ref yarnpkg/yarn#1483
2018-01-08 13:03:20 +01:00
Martin Staffa 1a2532601b chore(node): update karma to 2.0.0
Also reduce karma log level on Travis to INFO.
Before, the log level was DEBUG, but it seems that
prior to karma 2.0.0, the debug messages were not outoput on Karma,
so this simply restores the status quo (and prevents cluttering the log).
2018-01-08 10:43:12 +01:00
Martin Staffa cb862aaaa0 chore(node): update jasmine to 2.8.0, and adjust tests 2018-01-08 10:43:11 +01:00
Martin Staffa fa2034c167 test($sanitize): skip nextSibling clobber test on Edge 16
In some circumstances, Edge 16 will not throw on clobbered
elements, because the nextSibling property is null. The exact
cause is currently unknown.
2018-01-08 10:43:10 +01:00
Martin Staffa 750b43b6f6 chore(*): update copyright year
Closes #16386
2018-01-05 21:07:32 +01:00
Martin Staffa 048f5e3ab8 docs(DEVELOPERS.md): improve testing section 2018-01-05 21:07:26 +01:00
Sergey Kryvets 13c566cc03 docs(developers.md): update node version as specified in package.json
Closes #16384
2018-01-05 21:07:19 +01:00
Georgii Dolzhykov 45834eac09 docs(ngModel.NgModelController): correct description for $viewChangeListeners
It was misleading.

Closes #16382
2018-01-05 21:07:13 +01:00
Georgios Kalpakas 3673909896 feat(currencyFilter): trim whitespace around an empty currency symbol
In most locales, this won't make a difference (since they do not have
whitespace around their currency symbols). In locales where there is a
whitespace separating the currency symbol from the number, it makes
sense to also remove such whitespace if the user specified an empty
currency symbol (indicating they just want the number).

Fixes #15018
Closes #15085

Closes #15105
2017-12-19 11:32:05 +02:00
Martin Staffa 8302981a08 docs(CHANGELOG.md): add changes for 1.6.8 2017-12-18 15:17:56 +01:00
Martin Staffa d2a7b5162f docs(*): add browserTrigger docs; update references to scenario runner 2017-12-18 15:06:21 +01:00
Jason Bedard 2ecd85b989 test($rootScope): test recursive event broadcast and emit 2017-12-18 15:06:20 +01:00
Peter Bacon Darwin 2bdf712687 fix($location): always decode special chars in $location.url(value)
The original fix for #16312 included changing how `$location.url(value)`
decoded the special characters passed to it as a setter.
This broke a number of use cases (mostly involving the ui-router).

Further analysis appears to show that we can solve #16312, to prevent
urls being rewritten with decoded values, without modifying the
behaviour of `$location.url`.

This commit reverts changes to `$location.url(value)` so that encoded
chars will once again be decoded and passed to `$location.path(value)`.
In particular it will convert encoded forward slashes, which changes how
the path is updated, since e.g. `a/b/%2Fc%2Fd` will become `a/b/c/d`.
While this is arguably not "correct", it appears that there are too many
use cases relying upon this behaviour.
2017-12-11 19:41:38 +00:00
John Hampton 0de02973c1 docs(ng-model-options): remove extra quotes in example
Remove unnecessary quotes around attribute directive name in the docs example.  This syntax is incorrect.

Closes #16362
2017-12-11 10:57:46 +02:00
Martin Staffa 55516da2df fix(ngModelController): allow $overrideModelOptions to set updateOn
Also adds more docs about "default" events and how to override
ngModelController options.

Closes #16351
Closes #16364
2017-12-08 11:11:42 +01:00
Michał Gołębiowski-Owczarek e8adbf8d5a chore(*): bump Yarn in Jenkins init-node script
Without it Jenkins builds are broken.

Closes #16365
2017-12-07 20:28:02 +01:00
Michał Gołębiowski-Owczarek c169c60535 build(*): update Node from 6 to 8, update Yarn
Angular (2+) switched to Node 8 and so should we.

Closes #16360
Ref angular/angular#20807
Ref angular/angular#20832
2017-12-07 19:27:40 +01:00
Jason Bedard 0b6ec6b3ab refactor($rootScope): consistently use noop as the default $watch listener
Closes #16343
2017-12-07 11:14:29 +01:00
Martin Staffa d2511cfac0 chore(travis): fix deployment condition to include tagged commits
Tagged commits are not considered to belong to any branch.

Closes #16346
2017-12-07 11:13:09 +01:00
jugglinmike 155efa421b docs(ngNonBindable): document effect on the element's directives
The phrase "contents of the current DOM element" may be interpreted either as
inclusive of the DOM element's attributes or as exclusive of the attributes.
This situation concerns markup such as:

    <div ng-non-bindable ng-controller="MyController"></div>

In practice, AngularJS does not compile or bind attribute values for elements
which specify the `ng-non-bindable` directive. Extend the documentation to
definitely describe this behavior.

Closes #16338
2017-12-07 11:13:09 +01:00
Francesco Pipita f33d95cfcf feat($parse): add a hidden interface to retrieve an expression's AST
This PR adds a new private method to the `$parse` service, `$$getAst`,
which takes an Angular expression as its only argument and returns
the computed AST. This feature is not meant to be part of the public
API and might be subject to changes, so use it with caution.

Closes #16253

Closes #16260
2017-11-30 16:33:19 +02:00
Peter Bacon Darwin 57b626a673 fix($location): decode non-component special chars in Hashbang URLS
Fixes https://github.com/angular/angular.js/pull/16316#issuecomment-347527097
2017-11-30 13:23:16 +00:00
Martin Staffa b168aef861 docs(CHANGELOG.md): add changes for 1.6.7 2017-11-24 18:44:04 +01:00
Jason Bedard 6c4d2707b7 refactor($rootScope): simplify $emit stopPropagation handling
See https://github.com/angular/angular.js/pull/16293#discussion_r147960028

Closes #16339
2017-11-24 09:27:31 +01:00
Jason Bedard 9c95f6d5e0 perf(jqLite): avoid setting class attribute when not changed 2017-11-23 18:44:54 +01:00
Jason Bedard cab9ebfd5a perf(jqLite): avoid repeated add/removeAttribute in jqLiteRemoveClass
Fixes #16078
Closes #16131
2017-11-23 18:44:46 +01:00
Michał Gołębiowski-Owczarek 8a739fb4fa chore(*): normalize Vojta's email in .mailmap correctly
Closes #16340
2017-11-22 13:25:58 +01:00
Denys B c4003fd034 fix($compile): sanitize special chars in directive name
This fixes regression bug
when directive name with preceeding special char
in HTML markup does not match the registered name.
(introduced in https://github.com/angular/angular.js/commit/73050cdda04675bfa6705dc841ddbbb6919eb048)

Closes #16314
Closes #16278
2017-11-17 12:39:59 +01:00
kirk ab856d8ae3 docs(linky): mark "target" param as optional
This argument is optional in practice, and it is not provided in many of the examples in the
documentation. Its optional presence is handled here:
https://github.com/angular/angular.js/blob/f876ab71913e17e9126baad19ab795f28b61bfe6/src/ngSanitize/filter/linky.js#L185

Closes #16330
2017-11-17 12:39:52 +01:00
Frederik Prijck 83e6eef68e docs(*): remove usage of global grunt-cli
Previously, the `DEVELOPERS.md` and `CONTRIBUTING.md` files
refered to global `grunt-cli` by default.

This commit ensures the local `grunt-cli` is used by default
and mentiones the possibility to still use the global `grunt-cli`.
2017-11-17 12:39:45 +01:00
Martin Staffa 87270cb79f docs(*): update CONTRIBUTING.md and create DEVELOPERS.md
CONTRIBUTING.md
- focus on basic info about issues and pull requests for new contributors
- move development heavy info to DEVELOPERS.md + add links
- remove outdated info

DEVELOPERS.md
- contains info about project setup, coding rules, and commit message guidelines from CONTRIBUTING.md
- add and update info about writing docs from Wiki
- add info about development setup from docs contribute.md
- add info about running tests on Saucelabs / Browserstack

Closes #7303
Closes #9444
Closes #16297
2017-11-17 12:39:21 +01:00
Peter Bacon Darwin e06ebfdbb5 fix($location): do not decode forward slashes in the path in HTML5 mode
Closes #16312
2017-11-03 11:04:16 +00:00
Peter Bacon Darwin ddeb1df15a fix(sanitizeUri): sanitize URIs that contain IDEOGRAPHIC SPACE chars
Browsers mutate attributes values such as `&#12288;javascript:alert(1)`
when they are written to the DOM via `innerHTML` in various vendor specific
ways.

In Chrome (<62), this mutation removed the preceding "whitespace" resulting
in a value that could end up being executed as JavaScript.

Here is an example of what could happen:
https://plnkr.co/edit/Y6EsbsuDgd18YTn1oARu?p=preview
If you run that in Chrome 61 you will get a dialog box pop up.

There is background here:
http://www.nds.rub.de/media/emma/veroeffentlichungen/2013/12/10/mXSS-CCS13.pdf

The sanitizer has a bit of code that triggers this mutation on an inert piece
of DOM, before we try to sanitize it:
https://github.com/angular/angular.js/blob/817ac567/src/ngSanitize/sanitize.js#L406-L417

Chrome 62 does not appear to mutate this particular string any more, instead
it just leaves the "whitespace" in place. This probably means that Chrome 62
is no longer vulnerable to this specific attack vector; but there may be
other mutating strings that we haven't found, which are vulnerable.

Since we are leaving the mXSS check in place, the sanitizer should still
be immune to any strings that try to utilise this attack vector.

This commit uses `trim()` to remove the IDEOGRAPHIC SPACE "whitespace"
before sanitizing, which allows us to expose this mXSS test to all browsers
rather than just Chrome.

Closes #16288
2017-11-03 10:14:59 +00:00
Jason Bedard 358a69fa8b fix($rootScope): fix potential memory leak when removing scope listeners
When removing listeners they are removed from the array but the array size
is not changed until the event is fired again. If the event is never fired
but listeners are added/removed then the array will continue growing.

By changing the listener removal to `delete` the array entry instead of setting
it to `null` browsers can potentially deallocate the memory for the entry.

Fixes #16135
Closes #16161
2017-10-27 20:51:34 -07:00
Jason Bedard 417aefd45d test($rootScope): test removal of event listeners during event broadcast 2017-10-27 20:51:34 -07:00
Martin Staffa 6ad4c8d1b4 chore(travis): tighten up deploy conditions 2017-10-26 14:30:28 +02:00
Martin Staffa 3ef612afa0 chore(travis): deploy to docs and code when distTag=latest
We now deploy to code.angularjs.org and docs.angularjs.org
when we are on the branch which has distTag=latest set in the
package.json, i.e. the stable branch.

Previously, we deployed to docs only when distTag=latest and
the commit was tagged, and to code only on the master branch.
2017-10-25 18:14:43 +02:00
Martin Staffa cc8486f994 chore(doc-gen, docs-app): generate "stable snapshot" for distTag=latest
The "stable snapshot" is the current state of the branch that has
distTag=latest, i.e. a preview of the next patch version of the stable branch.
2017-10-25 18:14:43 +02:00
Martin Staffa b990fa91cd chore(travis): split unit test jobs into 'core' and 'jquery'
"unit-core" consists of code+jqlite, module test, and promise A+ tests.
"unit-jquery" is code+jquery
"docs-app" includes unit and e2e tests

Splitting the unit tests into more than one job makes it faster
to rerun jobs that fail because Safari or Edge cannot complete the
suite, which seemingly happens on random.

Closes #16292
2017-10-25 18:14:43 +02:00
Sagir Khan 17f7d8c5c8 docs(tutorial/step_14): replace broken web platform docs link
Replace broken [webplatform-animations][1] link with [mdn-animations][2].

The original link returns a 404. The closest match that works is
https://webplatform.github.io/docs/css/properties/animation. However,
the notice at the top of the page reads:

> The WebPlatform project, supported by various stewards between 2012
> and 2015, has been discontinued.

The CSS animations guide on MDN web docs is not only current, but also
more comprehensive.

[1]: https://docs.webplatform.org/wiki/css/properties/animations
[2]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations

Closes #16294
2017-10-23 11:48:11 +03:00
Martin Staffa 1e8dd0e65c chore(travis): remove unnessecary addons
The "Trusty" build environment on Travis includes these addons,
see https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements

Closes  #16286
2017-10-19 17:42:29 +02:00
Martin Staffa b1a18ef381 chore(travis): unit-test latest & latest-1 Chrome, FF, Edge
Previously, we used fixed versions that became outdated quickly for
FF and Chrome.

Safari 10/11 is not included because during the latest test there were 
failures, see https://github.com/angular/angular.js/pull/15717

Jasmine is fixed to 2.5.2 because 2.6.0+ is not compatible with the suite:
https://github.com/angular/angular.js/pull/15927#issuecomment-309206419

Closes #15927
2017-10-19 17:42:25 +02:00
Martin Staffa 3470ab5696 chore(doc-gen): add directive names that aren't params to usage section
When a directive can be used as an attribute or CSS class, but doesn't take 
a value, its name is not included in the parameters, which previously meant 
that the directive name was missing from the Attribute / CSS Class usage 
section of the docs.

This commit adds the name to the Usage section when it is missing
from the parameters.

Closes #14045
Closes #16265
2017-10-19 17:41:24 +02:00
Martin Staffa 5d39a118df chore(node): update karma-sauce-launcher
Related to #14961
Closes #16281
2017-10-17 14:43:44 +02:00
Martin Staffa 421a5856f8 docs(select.SelectController): fix example
Closes #16271
Closes #16275
2017-10-13 18:02:43 +02:00
Martin Staffa 85f40a15fb chore($resource): remove undocumented API
This code has been in the $resource service since 2010, but was
never documented and can therefore be removed. It'll save precious bytes!

Shout-out to @gkalpak for finding this

Closes #16267
2017-10-13 18:02:42 +02:00
Martin Staffa b919a2737e test(docs-app): access provider that is the same in 1.6 and master 2017-10-11 18:40:40 +02:00
Dmitriy a675ea0343 feat($sanitize, $compileProvider, linky): add support for the "sftp" protocol in links
Add support for the sftp protocol in the linky filter and the "aHrefSanitizationWhitelist" that is used by $sanitize and can be configured in the $compileProvider.

Closes #16102
2017-10-11 17:37:56 +02:00
Martin Staffa 8fb8d52664 docs(ngPattern): add option of specifying literal RegExp
Closes #15929
2017-10-11 17:37:53 +02:00
Martin Staffa d60d904747 docs(ngInit): clarify when it's okay to use ngInit
Closes #10489
2017-10-11 17:36:26 +02:00
Martin Staffa 62afb6204c docs(*): add / correct @-tags; fix headlines; add info
- add / correct `@param`, `@restrict`, `@element`, `@priorìty` to directives
- use `@animations` instead of manual headings
- fix more incorrect h1 headings
- fix incorrectly indented `<examples>`
- add some info to $templateCache and $templateRequest
2017-10-11 17:35:58 +02:00
Martin Staffa 1eaf4ab414 docs(*): fix heading levels; use @example instead of headings
This ensures the doc-gen creates correct headlines and
table of contents entries.
2017-10-11 17:34:18 +02:00
Martin Staffa 1de5d181da chore(doc-gen): improve headings for events and examples
The "Events" heading now gets an id (which makes them show in
the table of contents, and their "Parameters" use a heading with
a lower priority (previously it was the same as "Events" itself).

The "@example" tag now generates the heading "Example" if there's
only one, or "Examples" if there are multiple.
2017-10-11 17:34:06 +02:00
Martin Staffa 73088bb7ee refactor(api-pages.scenario.js): remove misleading describe block 2017-10-11 17:33:59 +02:00
Martin Staffa 898140edb7 docs(*): fix heading levels and general clean-up
- docs pages should only have one h1
- docs pages shouldn't skip a h* in the hierarchy
- manual table of contents are no longer necesary
- references to the doc-module-components directive are obsolete
2017-10-11 17:33:34 +02:00
Martin Staffa dab60352e5 chore(docs-app): add table of contents to individual pages 2017-10-11 17:29:13 +02:00
Michał Gołębiowski-Owczarek df4955fe78 chore(*): add a Git .mailmap with my new name
In this way:
* my past contributions are mapped correctly
* other people's distinct entries are collapsed into one

Closes #16254
2017-10-04 23:25:28 +02:00
Martin Staffa 14519488ce feat(ngModel.NgModelController): expose $processModelValue to run model -> view pipeline
Closes #3407
Closes #10764
Closes #16237
2017-09-29 13:13:55 +02:00
Peter Bacon Darwin 569e906a58 fix(http): do not allow encoded callback params in jsonp requests 2017-09-24 14:58:17 +01:00
George Kalpakas 18b8a63a3c chore(doc-gen): fix script paths in plnkr for examples with deps
Closes #16238
2017-09-22 23:30:25 +03:00
Craig Leyshan 6e78fee732 feat($injector): ability to load new modules after bootstrapping
The new method `$injector.loadNewModules(modules)` will add each of the
injectables to the injector and execute all of the config and run blocks
for each module passed to the method.

* The application developer is responsible for loading the code containing
the modules.
* Modules cannot be unloaded.
* Previously loaded modules will not be reloaded.
* Previously compiled HTML will not be affected by newly loaded directives,
filters and components.
2017-09-21 13:54:32 +01:00
ImgBotApp 6a99eaf1c8 docs(*): optimize images
\docs\app\assets\img\AngularJS-small.png (1.82%)
\docs\img\One_Way_Data_Binding.png (12.15%)
\docs\img\guide\di_sequence_final.png (19.05%)
\docs\app\assets\img\bullet.png (13.68%)
\images\docs\Diagrams.svg\image1.png (1.73%)
\docs\img\angular_parts.png (30.41%)
\images\docs\tutorial\tutorial_06.svg\image15.png (1.55%)
\docs\img\Two_Way_Data_Binding.png (11.59%)
\docs\img\guide\concepts-databinding2.png (7.54%)
\images\docs\Diagrams.svg\image4.png (1.89%)
\images\docs\Diagrams.svg\image2.png (1.93%)
\images\docs\Diagrams.graffle\image9.png (2.12%)
\docs\img\guide\concepts-module-injector.png (2.41%)
\docs\img\guide\hero-detail.png (41.79%)
\images\docs\tutorial\tutorial_09.graffle\image9.png (7.86%)
\images\docs\Diagrams.svg\image9.png (2.12%)
\images\docs\guide\concepts.graffle\image4.png (10.43%)
\docs\img\guide\scenario_runner.png (37.15%)
\docs\img\guide\concepts-directive.png (1.05%)
\docs\img\guide\concepts-databinding1.png (8.75%)
\images\docs\guide\concepts.graffle\image1.png (9%)
\images\docs\tutorial\tutorial_09.svg\image9.png (15.35%)
\docs\img\form_data_flow.png (6.68%)
\docs\img\guide\heroes-list.png (40.81%)
\images\docs\guide\concepts.graffle\image5.png (12.02%)
\docs\img\guide\simple_scope_final.png (0.51%)
\docs\img\guide\concepts-startup.png (3.22%)
\docs\img\tutorial\tutorial_12.png (10.49%)
\images\docs\guide\concepts.svg\image4.png (10.43%)
\images\docs\Diagrams.graffle\image4.png (1.89%)
\docs\img\tutorial\tutorial_05.png (11.11%)
\docs\img\tutorial\catalog_screen.png (0.46%)
\images\docs\tutorial\tutorial_10.graffle\image10.png (5.73%)
\images\docs\tutorial\simple_scope.graffle\image7.png (43.81%)
\images\docs\guide\simple_scope.graffle\image7.png (43.81%)
\images\docs\tutorial\tutorial_02.graffle\image11.png (0.19%)
\docs\img\guide\crisis-list.png (39.68%)
\docs\img\guide\concepts-runtime.png (2.48%)
\images\docs\guide\concepts.svg\image5.png (12.02%)
\docs\img\guide\concepts-view.png (2.98%)
\images\docs\tutorial\tutorial_02.svg\image11.png (28.1%)
\docs\img\tutorial\tutorial_00.png (10.99%)
\docs\img\tutorial\tutorial_06.png (11.3%)
\docs\img\guide\crisis-detail.png (38.86%)
\docs\img\guide\concepts-scope-watch-strategies.png (7.59%)
\images\docs\guide\simple_scope.svg\image7.png (43.81%)
\docs\img\tutorial\tutorial_09.png (10.7%)
\images\docs\tutorial\tutorial_12.svg\image10.png (25.88%)
\images\docs\tutorial\tutorial_10.svg\image10.png (25.88%)
\images\logo\AngularJS.exports\AngularJS-large.png (3.86%)
\images\docs\Diagrams.graffle\image1.png (1.73%)
\images\docs\tutorial\tutorial_03.svg\image11.png (28.1%)
\docs\img\tutorial\tutorial_10.png (10.44%)
\images\docs\tutorial\tutorial_proto.graffle\image7.png (43.81%)
\images\docs\tutorial\simple_scope.svg\image7.png (43.81%)
\images\logo\AngularJS.exports\AngularJS-small.png (3.64%)
\images\docs\tutorial\tutorial_proto.svg\image7.png (43.81%)
\docs\img\tutorial\tutorial_02.png (10.91%)
\images\docs\tutorial\tutorial_05.graffle\image13.png (10.92%)
\images\logo\AngularJS-Shield.exports\AngularJS-Shield-large.png (5.3%)
\docs\img\tutorial\tutorial_03.png (10.77%)
\images\docs\tutorial\tutorial_05.svg\image13.png (3.46%)
\images\logo\AngularJS.graffle\image1.png (0.55%)
\images\docs\Diagrams.graffle\image2.png (1.93%)
\images\docs\tutorial\tutorial_12.graffle\image10.png (5.73%)
\images\logo\AngularJS-Shield.exports\AngularJS-Shield-huge.png (2.99%)
\images\docs\tutorial\tutorial_06.graffle\image15.png (16.51%)
\images\logo\AngularJS.graffle\image2.png (5.21%)
\docs\img\guide\hashbang_vs_regular_url.jpg (32.92%)
\images\logo\AngularJS-Shield.exports\AngularJS-Shield-medium.png (6.18%)
\images\logo\AngularJS-Shield.exports\AngularJS-Shield-small.png (6.58%)
\images\logo\AngularJS.exports\AngularJS-medium.png (3.37%)
\images\logo\AngularJS.exports\AngularJS-huge.png (3.56%)

Closes #16222
2017-09-21 13:48:52 +01:00
Michał Gołębiowski-Owczarek c94e44b9f8 docs(*): don't hide results for middle-clicks
Middle-clicking opens a link in a new tab; it shouldn't close the results list
as the user may want to open more of those links.

Closes #16233
2017-09-21 14:31:48 +02:00
Michał Gołębiowski-Owczarek bbca6b0893 chore(jqLite): fix $destroy describe block titles 2017-09-20 14:03:04 +02:00
Marcin Wosinek 1555a4911a fix(ngMock): pass unexpected request failures in $httpBackend to the error handler
Closes #16150
Closes #15855
2017-09-18 21:31:20 +01:00
Fengwei Wang dbba98b9ae docs(guide/bootstrap): fix typo ('There a few things' --> 'There are a few things')
Closes #16221
2017-09-11 14:37:15 +03:00
melbourne2991 3e2cb6c15c docs(input[checkbox]): fix @param type for ngChange
Closes #16219
2017-09-07 15:49:49 +03:00
Martin Staffa 1391e99c7f fix(ngAnimate): don't close transitions when child transitions close
Previously, non-angular CSS transitions / animations on child elements
would trigger the ngAnimate [transition|animation]end listener and
could close a running animation prematurely.

Closes #16210
2017-09-06 16:22:13 +02:00
Martin Staffa 7a5f06d55d fix(ngMock.browserTrigger): add 'bubbles' to Transition/Animation Event
When the event objects are created synthetically, the bubbles property is set to false
if not explicitly defined
2017-09-06 16:22:07 +02:00
Yonatan Kra bf78beeb6d docs(guide/expression): add clarification for RegExp literal in ngPattern expression
The `ngPattern` expression does accept a RegExp created with literal notation,
hence it should be mentioned as an exception to the
"No RegExp Creation With Literal Notation" rule.

Closes #16206
2017-09-05 15:55:48 +03:00
frederikprijck 2e892e4072 docs(*): replace master/slave with leader/follower
Previously, the docs made use of `master/slave`, which is offensive.

This commit removes the usage of these terms and replace them with `leader/follower`.
2017-08-28 10:11:40 +01:00
Martin Staffa 8f88ea57dc chore(docs.angularjs.org): fix docs deploy for source file changes
Since the embedded examples in the docs app now include the local source files instead
of CDN files, we need to include the source files into the folder that is deployed
to Firebase hosting
2017-08-24 11:02:17 +02:00
Martin Staffa 24b0b516b6 chore(doc-gen): include source files from code.angularjs.org for production plnkr examples 2017-08-24 11:02:17 +02:00
Martin Staffa 1fcf5949d2 revert: chore(docs-app): load example files based on active deployment
This reverts commit d91a6bdbc6.

The runnable examples cannot rely on the CDN for loading the common files,
because the CDN push does not happen at the same time as the docs are generated,
which means the doc examples are non-functional for an unforeseeable time.
2017-08-24 11:02:17 +02:00
Oscar Busk 46ccaee9be docs($compileProvider): add more info on debugInfoEnabled()
Add more info on what `debugInfoEnabled()` affects.

Closes #16154
2017-08-23 22:11:37 +03:00
Oscar Busk 86c9990813 docs(guide/production): add more info on debugInfoEnabled()
Add bullet mentioning how placeholder comments are affected.

Closes #16155
2017-08-23 19:00:32 +03:00
358 changed files with 6911 additions and 3483 deletions
+1 -1
View File
@@ -1,4 +1,3 @@
bower_components/**
build/**
docs/bower_components/**
docs/app/assets/js/angular-bootstrap/**
@@ -9,3 +8,4 @@ src/angular.bind.js
src/ngParseExt/ucd.js
i18n/closure/**
tmp/**
vendor/**
+29 -19
View File
@@ -1,27 +1,37 @@
***Note*: for support questions, please use one of these channels: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question. This repository's issues are reserved for feature requests and bug reports.**
<!--
IF YOU DON'T FILL OUT THE FOLLOWING INFORMATION WE MIGHT CLOSE YOUR ISSUE WITHOUT INVESTIGATION
-->
**Do you want to request a *feature* or report a *bug*?**
<!--
- For *SUPPORT QUESTIONS*, use one of the
[support channels](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question).
- Before submitting, please **SEARCH GITHUB** for a similar issue or PR. -->
**I'm submitting a ...**
<!-- (check one with "x") -->
- [ ] bug report
- [ ] feature request
- [ ] other <!--(Please do not submit support requests here - see above)-->
**Current behavior:**
<!-- Describe how the bug manifests / how the current features are insufficient. -->
**What is the current behavior?**
**Expected / new behavior:**
<!-- Describe what the behavior would be without the bug / how the feature would improve AngularJS -->
**Minimal reproduction of the problem with instructions:**
<!--
If the current behavior is a bug or you can illustrate your feature request better with an example,
please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:yBpEi4).
-->
**AngularJS version:** 1.x.y
<!-- Check whether this is still an issue in the most recent stable or in the snapshot AngularJS
version (https://code.angularjs.org/snapshot/) -->
**If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).**
**Browser:** [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
<!-- All browsers where this could be reproduced (and Operating System if relevant) -->
**What is the expected behavior?**
**What is the motivation / use case for changing the behavior?**
**Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.**
**Other information (e.g. stacktraces, related issues, suggestions how to fix)**
**Anything else:**
<!-- e.g. stacktraces, related issues, suggestions how to fix -->
+4 -3
View File
@@ -1,3 +1,4 @@
<!-- General PR submission guidelines https://github.com/angular/angular.js/CONTRIBUTING.md#submit-pr -->
**What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)**
@@ -15,9 +16,9 @@
**Please check if the PR fulfills these requirements**
- [ ] The commit message follows our guidelines: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
- [ ] The commit message follows our [guidelines](../DEVELOPERS.md#commits)
- [ ] Fix/Feature: [Docs](../DEVELOPERS.md#documentation) have been added/updated
- [ ] Fix/Feature: Tests have been added; existing tests pass
**Other information**:
+1 -3
View File
@@ -10,7 +10,6 @@ performance/temp*.html
*.swp
angular.js.tmproj
node_modules/
bower_components/
angular.xcodeproj
.idea
*.iml
@@ -19,7 +18,6 @@ angular.xcodeproj
libpeerconnection.log
npm-debug.log
/tmp/
/scripts/bower/bower-*
.vscode
*.log
*.stackdump
*.stackdump
+29
View File
@@ -0,0 +1,29 @@
Andres Ornelas <aornelas@google.com>
Caitlin Potter <caitpotter88@gmail.com>
Caitlin Potter <caitpotter88@gmail.com> <snowball@defpixel.com>
Di Peng <pengdi@google.com>
Di Peng <pengdi@google.com> <pengdi@go.wustl.edu>
Georgios Kalpakas <kalpakas.g@gmail.com>
Georgios Kalpakas <kalpakas.g@gmail.com> <g.kalpakas@hotmail.com>
Julie Ralph <ju.ralph@gmail.com>
Lucas Galfaso <lgalfaso@gmail.com>
Martin Staffa <mjstaffa@gmail.com>
Martin Staffa <mjstaffa@gmail.com> <mjstaffa@googlemail.com>
Matias Niemelä <matias@yearofmoo.com>
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Misko Hevery <misko@hevery.com>
Misko Hevery <misko@hevery.com> <misko@google.com>
Igor Minar <igor@angularjs.org>
Igor Minar <igor@angularjs.org> <iiminar@gmail.com>
Igor Minar <igor@angularjs.org> <iminar@google.com>
Igor Minar <igor@angularjs.org> <iminar@dhcp-172-19-37-154.mtv.corp.google.com>
Pawel Kozlowski <pkozlowski.opensource@gmail.com>
Peter Bacon Darwin <pete@bacondarwin.com>
Rodric Haddad <rody@rodyhaddad.com>
Shahar Talmi <shahar.talmi@gmail.com>
Shahar Talmi <shahar.talmi@gmail.com> <shahart@wix.com>
Shyam Seshadri <shyamseshadri@google.com>
Shyam Seshadri <shyamseshadri@google.com> <shyamseshadri@gmail.com>
Vojta Jina <vojta.jina@gmail.com>
Vojta Jina <vojta.jina@gmail.com> <vojta@gemin-i.org>
Vojta Jina <vojta.jina@gmail.com> <vojta@google.com>
+1 -1
View File
@@ -1 +1 @@
6
8
+31 -30
View File
@@ -1,12 +1,10 @@
language: node_js
sudo: false
node_js:
- '6'
- '8'
cache:
yarn: true
directories:
- bower_components
branches:
except:
@@ -15,33 +13,24 @@ branches:
env:
matrix:
- JOB=ci-checks
- JOB=unit BROWSER_PROVIDER=saucelabs
- JOB=docs-e2e BROWSER_PROVIDER=saucelabs
- JOB=unit-core BROWSER_PROVIDER=saucelabs
- JOB=unit-jquery BROWSER_PROVIDER=saucelabs
- JOB=docs-app BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs
global:
# node 4 likes the G++ v4.8 compiler
# see https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements
- CXX=g++-4.8
- SAUCE_USERNAME=angular-ci
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
- LOGS_DIR=/tmp/angular-build/logs
- BROWSER_PROVIDER_READY_FILE=/tmp/browsersprovider-tunnel-ready
- secure: oTBjhnOKhs0qDSKTf7fE4f6DYiNDPycvB7qfSF5QRIbJK/LK/J4UtFwetXuXj79HhUZG9qnoT+5e7lPaiaMlpsIKn9ann7ffqFWN1E8TMtpJF+AGigx3djYElwfgf5nEnFUFhwjFzvbfpZNnxVGgX5YbIZpe/WUbHkP4ffU0Wks=
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 0.27.5
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.3.2
- export PATH="$HOME/.yarn/bin:$PATH"
before_script:
- du -sh ./node_modules ./bower_components/ || true
- du -sh ./node_modules || true
- "./scripts/travis/before_build.sh"
script:
@@ -63,41 +52,53 @@ notifications:
jobs:
include:
- stage: deploy
# Don't deploy from PRs. Only deploy from our default branches, or if commit is tagged.
# This is a Travis-specific boolean language: https://docs.travis-ci.com/user/conditional-builds-stages-jobs#Specifying-conditions
# The deployment logic for pushed branches is further defined in scripts\travis\build.sh
if: type != pull_request and (branch =~ ^(v1\.\d+\.x|master)$ or tag IS present)
env:
- JOB=deploy
before_script: skip
script:
- "./scripts/travis/build.sh"
# Export the variables into the current process
- . ./scripts/travis/build.sh
- "echo DEPLOY_DOCS: $DEPLOY_DOCS, DEPLOY_CODE: $DEPLOY_CODE"
after_script: skip
# Work around the 10min Travis timeout so the code.angularjs firebase+gcs code deploy can complete
# Only run the keep_alive once (before_deploy is run for each provider)
before_deploy: |
function keep_alive() {
while true; do
echo -en "\a"
sleep 5
done
}
keep_alive &
if ! [ "$BEFORE_DEPLOY_RUN" ]; then
export BEFORE_DEPLOY_RUN=1;
function keep_alive() {
while true; do
echo -en "\a"
sleep 10
done
}
keep_alive &
fi
deploy:
- provider: firebase
# the upload folder for firebase is configured in /firebase.json
skip_cleanup: true
project: docs-angularjs-org-9p2
token:
secure: $FIREBASE_TOKEN
on:
repo: angular/angular.js
all_branches: true
# deploy a new docs version when the commit is tagged on the "latest" npm version
condition: $TRAVIS_TAG != '' && $( jq ".distTag" "package.json" | tr -d "\"[:space:]" ) = latest
condition: "$DEPLOY_DOCS == true"
- provider: gcs
skip_cleanup: true
access_key_id: GOOGLDB7W2J3LFHICF3R
secret_access_key:
secure: tHIFdSq55qkyZf9zT/3+VkhUrTvOTMuswxXU3KyWaBrSieZqG0UnUDyNm+n3lSfX95zEl/+rJAWbfvhVSxZi13ndOtvRF+MdI1cvow2JynP0aDSiPffEvVrZOmihD6mt2SlMfhskr5FTduQ69kZG6DfLcve1PPDaIwnbOv3phb8=
bucket: code-angularjs-org-338b8.appspot.com
local-dir: upload
local-dir: uploadCode
detect_encoding: true # detects gzip compression
on:
repo: angular/angular.js
all_branches: true
# upload the build when the commit is tagged or the branch is "master"
condition: $TRAVIS_TAG != '' || ($TRAVIS_PULL_REQUEST = false && $TRAVIS_BRANCH = master)
condition: "$DEPLOY_CODE == true"
+105
View File
@@ -1,3 +1,108 @@
<a name="1.6.9"></a>
# 1.6.9 fiery-basilisk (2018-02-02)
## Bug Fixes
- **input:** add `drop` event support for IE
([5dc076](https://github.com/angular/angular.js/commit/5dc07667de00c5e85fd69c5b7b7fe4fb5fd65a77))
- **ngMessages:** prevent memory leak from messages that are never attached
([9d058d](https://github.com/angular/angular.js/commit/9d058de04bb78694b83179e9b97bc40214eca01a),
[#16389](https://github.com/angular/angular.js/issues/16389),
[#16404](https://github.com/angular/angular.js/issues/16404),
[#16406](https://github.com/angular/angular.js/issues/16406))
- **ngTransclude:** remove terminal: true
([1d826e](https://github.com/angular/angular.js/commit/1d826e2f1e941d14c3c56d7a0249f5796ba11f85),
[#16411](https://github.com/angular/angular.js/issues/16411),
[#16412](https://github.com/angular/angular.js/issues/16412))
- **$sanitize:** sanitize `xml:base` attributes
([b9ef65](https://github.com/angular/angular.js/commit/b9ef6585e10477fbbf912a971fe0b390bca692a6))
## New Features
- **currencyFilter:** trim whitespace around an empty currency symbol
([367390](https://github.com/angular/angular.js/commit/3673909896efb6ff47546caf7fc61549f193e043),
[#15018](https://github.com/angular/angular.js/issues/15018),
[#15085](https://github.com/angular/angular.js/issues/15085),
[#15105](https://github.com/angular/angular.js/issues/15105))
<a name="1.6.8"></a>
# 1.6.8 beneficial-tincture (2017-12-18)
## Bug Fixes
- **$location:**
- always decode special chars in `$location.url(value)`
([2bdf71](https://github.com/angular/angular.js/commit/2bdf7126878c87474bb7588ce093d0a3c57b0026))
- decode non-component special chars in Hashbang URLS
([57b626](https://github.com/angular/angular.js/commit/57b626a673b7530399d3377dfe770165bec35f8a))
- **ngModelController:** allow $overrideModelOptions to set updateOn
([55516d](https://github.com/angular/angular.js/commit/55516da2dfc7c5798dce24e9fa930c5ac90c900c),
[#16351](https://github.com/angular/angular.js/issues/16351),
[#16364](https://github.com/angular/angular.js/issues/16364))
## New Features
- **$parse:** add a hidden interface to retrieve an expression's AST
([f33d95](https://github.com/angular/angular.js/commit/f33d95cfcff6fd0270f92a142df8794cca2013ad),
[#16253](https://github.com/angular/angular.js/issues/16253),
[#16260](https://github.com/angular/angular.js/issues/16260))
<a name="1.6.7"></a>
# 1.6.7 imperial-backstroke (2017-11-24)
## Bug Fixes
- **$compile:** sanitize special chars in directive name
([c4003f](https://github.com/angular/angular.js/commit/c4003fd03489f876b646f06838f4edb576bacf6f),
[#16314](https://github.com/angular/angular.js/issues/16314),
[#16278](https://github.com/angular/angular.js/issues/16278))
- **$location:** do not decode forward slashes in the path in HTML5 mode
([e06ebf](https://github.com/angular/angular.js/commit/e06ebfdbb558544602fe9da4d7d98045a965f468),
[#16312](https://github.com/angular/angular.js/issues/16312))
- **sanitizeUri:** sanitize URIs that contain IDEOGRAPHIC SPACE chars
([ddeb1d](https://github.com/angular/angular.js/commit/ddeb1df15a23de93eb95dbe202e83e93673e1c4e),
[#16288](https://github.com/angular/angular.js/issues/16288))
- **$rootScope:** fix potential memory leak when removing scope listeners
([358a69](https://github.com/angular/angular.js/commit/358a69fa8b89b251ee44e523458d6c7f40b92b2d),
[#16135](https://github.com/angular/angular.js/issues/16135),
[#16161](https://github.com/angular/angular.js/issues/16161))
- **http:** do not allow encoded callback params in jsonp requests
([569e90](https://github.com/angular/angular.js/commit/569e906a5818271416ad0b749be2f58dc34938bd))
- **ngMock:** pass unexpected request failures in `$httpBackend` to the error handler
([1555a4](https://github.com/angular/angular.js/commit/1555a4911ad5360c145c0ddc8ec6c4bf9a381c13),
[#16150](https://github.com/angular/angular.js/issues/16150),
[#15855](https://github.com/angular/angular.js/issues/15855))
- **ngAnimate:** don't close transitions when child transitions close
([1391e9](https://github.com/angular/angular.js/commit/1391e99c7f73795180b792af21ad4402f96e225d),
[#16210](https://github.com/angular/angular.js/issues/16210))
- **ngMock.browserTrigger:** add 'bubbles' to Transition/Animation Event
([7a5f06](https://github.com/angular/angular.js/commit/7a5f06d55d123a39bb7b030667fb1ab672939598))
## New Features
- **$sanitize, $compileProvider, linky:** add support for the "sftp" protocol in links
([a675ea](https://github.com/angular/angular.js/commit/a675ea034366fbb0fcf0d73fed65216aa99bce11),
[#16102](https://github.com/angular/angular.js/issues/16102))
- **ngModel.NgModelController:** expose $processModelValue to run model -> view pipeline
([145194](https://github.com/angular/angular.js/commit/14519488ce9218aa891d34e89fc3271fd4ed0f04),
[#3407](https://github.com/angular/angular.js/issues/3407),
[#10764](https://github.com/angular/angular.js/issues/10764),
[#16237](https://github.com/angular/angular.js/issues/16237))
- **$injector:** ability to load new modules after bootstrapping
([6e78fe](https://github.com/angular/angular.js/commit/6e78fee73258bb0ae36414f9db2e8734273e481b))
## Performance Improvements
- **jqLite:**
- avoid setting class attribute when not changed
([9c95f6](https://github.com/angular/angular.js/commit/9c95f6d5e00ee7e054aabb3e363f5bfb3b7b4103))
- avoid repeated add/removeAttribute in jqLiteRemoveClass
([cab9eb](https://github.com/angular/angular.js/commit/cab9ebfd5a02e897f802bf6321b8471e4843c5d3),
[#16078](https://github.com/angular/angular.js/issues/16078),
[#16131](https://github.com/angular/angular.js/issues/16131))
<a name="1.6.6"></a>
# 1.6.6 interdimensional-cable (2017-08-18)
+116 -186
View File
@@ -3,85 +3,102 @@
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](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Coding Rules](#rules)
- [Commit Message Guidelines](#commit)
- [Signing the CLA](#cla)
- [Further Info](#info)
* [Code of Conduct](#coc)
* [Questions and Problems](#question)
* [Issues and Bugs](#issue)
* [Feature Requests](#feature)
* [Improving Documentation](#docs)
* [Issue Submission Guidelines](#submit)
* [Pull Request Submission Guidelines](#submit-pr)
* [Signing the CLA](#cla)
## <a name="coc"></a> Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc].
Help us keep AngularJS open and inclusive. Please read and follow our [Code of Conduct][coc].
## <a name="question"></a> Got a Question or Problem?
## <a name="requests"></a> Questions, Bugs, Features
If you have questions about how to use AngularJS, please direct these to the [Google Group][groups]
discussion list or [StackOverflow][stackoverflow]. We are also available on [IRC][irc] and
[Gitter][gitter].
### <a name="question"></a> Got a Question or Problem?
## <a name="issue"></a> Found an Issue?
Do not open issues for general support questions as we want to keep GitHub issues for bug reports
and feature requests. You've got much better chances of getting your question answered on dedicated
support platforms, the best being [Stack Overflow][stackoverflow].
If you find a bug in the source code or a mistake in the documentation, you can help us by
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
with a fix.
Stack Overflow is a much better place to ask questions since:
- there are thousands of people willing to help on Stack Overflow
- questions and answers stay available for public viewing so your question / answer might help
someone else
- Stack Overflow's voting system assures that the best answers are prominently visible.
To save your and our time, we will systematically close all issues that are requests for general
support and redirect people to the section you are reading right now.
Other channels for support are:
- the [Google Group][groups] discussion list
- the [AngularJS IRC][irc]
- the [AngularJS Gitter][gitter]
### <a name="issue"></a> Found an Issue or Bug?
If you find a bug in the source code, you can help us by submitting an issue to our
[GitHub Repository][github]. Even better, you can submit a Pull Request with a fix.
**Please see the [Submission Guidelines](#submit) below.**
**Special Note for Localization Issues:** AngularJS uses the [Google Closure I18N library] to
generate its own I18N files (the ngLocale module). This means that any changes to these files
would be lost the next time that we import the library.
**Localization Issues:** Angular.js uses the [Google Closure I18N library] to generate
its own I18N files (the ngLocale module). This means that any changes to these files would be lost
the next time that we import the library.
Since the Closure library i18n data is itself auto-generated from the data of the
[Common Locale Data Repository (CLDR)] project, errors in the data should
be reported there. See also the [Closure guide to i18n changes].
**Please see the [Submission Guidelines](#submit) below.**
### <a name="feature"></a> Missing a Feature?
## <a name="feature"></a> Want a Feature?
You can request a new feature by submitting an issue to our [GitHub Repository][github-issues].
You can request a new feature by submitting an issue to our [GitHub Repository][github]. If you
would like to implement a new feature then consider what kind of change it is:
If you would like to implement a new feature then consider what kind of change it is:
* **Major Changes** that you wish to contribute to the project should be discussed first on our
[dev mailing list][angular-dev] or [IRC][irc] so that we can better coordinate our efforts,
prevent duplication of work, and help you to craft the change so that it is successfully accepted
into the project.
* **Small Changes** can be crafted and submitted to the [GitHub Repository][github] as a Pull
Request.
* **Major Changes** that you wish to contribute to the project should be discussed first in an
[GitHub issue][github-issues] that clearly outlines the changes and benefits of the feature.
* **Small Changes** can directly be crafted and submitted to the [GitHub Repository][github]
as a Pull Request. See the section about [Pull Request Submission Guidelines](#submit-pr), and
for detailed information the [core development documentation][developers].
### <a name="docs"></a> Want a Doc Fix?
## <a name="docs"></a> Want a Doc Fix?
Should you have a suggestion for the documentation, you can open an issue and outline the problem
or improvement you have - however, creating the doc fix yourself is much better!
If you want to help improve the docs, it's a good idea to let others know what you're working on to
minimize duplication of effort. Create a new issue (or comment on a related existing one) to let
others know what you're working on.
If you're making a small change (typo, phrasing) don't worry about filing an issue first. Use the
friendly blue "Improve this doc" button at the top right of the doc page to fork the repository
in-place and make a quick change on the fly. The commit message is preformatted to the right type
and scope, so you only have to add the description.
For large fixes, please build and test the documentation before submitting the PR to be sure you
haven't accidentally introduced any layout or formatting issues. You should also make sure that your
commit message starts with "docs" and follows the **[Commit Message Guidelines](#commit)** outlined
below.
commit message follows the **[Commit Message Guidelines][developers.commits]**.
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue
"Improve this doc" button at the top right of the doc page to fork the repository in-place and make
a quick change on the fly. When naming the commit, it is advised to follow the commit message
guidelines below, by starting the commit message with **docs** and referencing the filename. Since
this is not obvious and some changes are made on the fly, this is not strictly necessary and we will
understand if this isn't done the first few times.
## <a name="submit"></a> Submission Guidelines
### Submitting an Issue
## <a name="submit"></a> Issue Submission Guidelines
Before you submit your issue search the archive, maybe your question was already answered.
If your issue appears to be a bug, and hasn't been reported, open a new issue. Help us to maximize
the effort we can spend fixing issues and adding new features, by not reporting duplicate issues.
Providing the following information will increase the chances of your issue being dealt with
quickly:
The "[new issue][github-new-issue]" form contains a number of prompts that you should fill out to
make it easier to understand and categorize the issue.
In general, providing the following information will increase the chances of your issue being dealt
with quickly:
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
* **Motivation for or Use Case** - explain why this is a bug for you
* **Angular Version(s)** - is it a regression?
* **AngularJS Version(s)** - is it a regression?
* **Browsers and Operating System** - is this a problem with all browsers or only specific ones?
* **Reproduce the Error** - provide a live example (using [Plunker][plunker] or
[JSFiddle][jsfiddle]) or an unambiguous set of steps.
@@ -89,41 +106,43 @@ quickly:
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit)
Here is a great example of a well defined issue: https://github.com/angular/angular.js/issues/5069
Here is a great example of a well defined issue: https://github.com/angular/angular.js/issues/5069.
**If you get help, help others. Good karma rulez!**
### Submitting a Pull Request
## <a name="submit-pr"></a> Pull Request Submission Guidelines
Before you submit your pull request consider the following guidelines:
* Search [GitHub](https://github.com/angular/angular.js/pulls) for an open or closed Pull Request
that relates to your submission. You don't want to duplicate effort.
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending pull
requests. We cannot accept code without this.
* Create the [development environment][developers.setup]
* Make your changes in a new git branch:
```shell
git checkout -b my-fix-branch master
```
* Create your patch, **including appropriate test cases**.
* Follow our [Coding Rules](#rules).
* Run the full Angular test suite, as described in the [developer documentation][dev-doc],
and ensure that all tests pass.
* Create your patch commit, **including appropriate test cases**.
* Follow our [Coding Rules][developers.rules].
* If the changes affect public APIs, change or add relevant [documentation][developers.documentation].
* Run the AngularJS [unit][developers.tests-unit] and [E2E test][developers.tests-e2e] suites, and ensure that all tests
pass. It is generally sufficient to run the tests only on Chrome, as our Travis integration will
run the tests on all supported browsers.
* Run `yarn grunt eslint` to check that you have followed the automatically enforced coding rules
* Commit your changes using a descriptive commit message that follows our
[commit message conventions](#commit) and passes our commit message presubmit hook
(`validate-commit-msg.js`). Adherence to the [commit message conventions](#commit) is required,
because release notes are automatically generated from these messages.
[commit message conventions][developers.commits]. Adherence to the
[commit message conventions][developers.commits] is required, because release notes are
automatically generated from these messages.
```shell
git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
* Build your changes locally to ensure all the tests pass:
* Before creating the Pull Request, package and run all tests a last time:
```shell
grunt test
yarn grunt test
```
* Push your branch to GitHub:
@@ -132,24 +151,29 @@ Before you submit your pull request consider the following guidelines:
git push origin my-fix-branch
```
In GitHub, send a pull request to `angular:master`.
If we suggest changes, then:
* In GitHub, send a pull request to `angular.js:master`. This will trigger the check of the
[Contributor License Agreement](#cla) and the Travis integration.
* Make the required updates.
* Re-run the Angular test suite to ensure tests are still passing.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
* If you find that the Travis integration has failed, look into the logs on Travis to find out
if your changes caused test failures, the commit message was malformed etc. If you find that the
tests failed or times out for unrelated reasons, you can ping a team member so that the build can be
restarted.
If the PR gets too outdated we may ask you to rebase and force push to update the PR:
* If we suggest changes, then:
```shell
git rebase master -i
git push origin my-fix-branch -f
```
* Make the required updates.
* Re-run the AngularJS test suite to ensure tests are still passing.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
You can also amend the initial commits and force push them to the branch.
_WARNING: Squashing or reverting commits and force-pushing thereafter may remove GitHub comments
on code that were previously made by you or others in your commits. Avoid any form of rebasing
unless necessary._
```shell
git rebase master -i
git push origin my-fix-branch -f
```
This is generally easier to follow, but seperate commits are useful if the Pull Request contains
iterations that might be interesting to see side-by-side.
That's it! Thank you for your contribution!
@@ -182,135 +206,41 @@ from the main (upstream) repository:
git pull --ff upstream master
```
## <a name="rules"></a> Coding Rules
## <a name="cla"></a> Signing the Contributor License Agreement (CLA)
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more [specs][unit-testing].
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
out the existing ngdocs and see [this wiki page][ngDocs].
* With the exceptions listed below, we follow the rules contained in
[Google's JavaScript Style Guide][js-style-guide]:
* **Do not use namespaces**: Instead, wrap the entire angular code base in an anonymous closure and
export our API explicitly rather than implicitly.
* Wrap all code at **100 characters**.
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
inheritance only when absolutely necessary.
* We **love functions and closures** and, whenever possible, prefer them over objects.
* To write concise code that can be better minified, we **use aliases internally** that map to the
external API. See our existing code to see what we mean.
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal API
that is used throughout AngularJS. The best guidance is to do what makes the most sense.
## <a name="commit"></a> Git Commit Guidelines
We have very precise rules over how our git commit messages can be formatted. This leads to **more
readable messages** that are easy to follow when looking through the **project history**. But also,
we use the git commit messages to **generate the AngularJS change log**.
The commit message formatting can be added using a typical git workflow or through the use of a CLI
wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `yarn run commit`
in your terminal after staging your changes in git.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:
```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The **header** is mandatory and the **scope** of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
### Type
Must be one of the following:
* **feat**: A new feature
* **fix**: A bug fix
* **docs**: Documentation only changes
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing or correcting existing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation
### Scope
The scope could be anything specifying place of the commit change. For example `$location`,
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
You can use `*` when the change affects more than a single scope.
### Subject
The subject contains succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
[reference GitHub issues that this commit closes][closing-issues].
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
The rest of the commit message is then used for this.
A detailed explanation can be found in this [document][commit-message-format].
## <a name="cla"></a> Signing the CLA
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
Upon submmitting a Pull Request, a friendly bot will ask you to sign our CLA if you haven't done
so before. Unfortunately, this is necessary for documentation changes, too.
It's a quick process, we promise!
* For individuals we have a [simple click-through form][individual-cla].
* For corporations we'll need you to
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
## <a name="info"></a> Further Information
You can find out more detailed information about contributing in the
[AngularJS documentation][contributing].
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
[angular-dev]: https://groups.google.com/forum/?fromgroups#!forum/angular-dev
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[contribute]: http://docs.angularjs.org/misc/contribute
[contributing]: http://docs.angularjs.org/misc/contribute
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[dev-doc]: https://docs.angularjs.org/guide
[developers]: DEVELOPERS.md
[developers.commits]: DEVELOPERS.md#commits
[developers.documentation]: DEVELOPERS.md#documentation
[developers.rules]: DEVELOPERS.md#rules
[developers.setup]: DEVELOPERS.md#setup
[developers.tests-e2e]: DEVELOPERS.md#e2e-tests
[developers.tests-unit]: DEVELOPERS.md#unit-tests
[github-issues]: https://github.com/angular/angular.js/issues
[github-new-issue]: https://github.com/angular/angular.js/issues/new
[github]: https://github.com/angular/angular.js
[gitter]: https://gitter.im/angular/angular.js
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
[groups]: https://groups.google.com/forum/?fromgroups#!forum/angular
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
[irc]: http://webchat.freenode.net/?channels=angularjs&uio=d4
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
[jsfiddle]: http://jsfiddle.net/
[list]: https://groups.google.com/forum/?fromgroups#!forum/angular
[ngDocs]: https://github.com/angular/angular.js/wiki/Writing-AngularJS-Documentation
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
[plunker]: http://plnkr.co/edit
[stackoverflow]: http://stackoverflow.com/questions/tagged/angularjs
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/CONTRIBUTING.md?pixel)](https://github.com/igrigorik/ga-beacon)
+489
View File
@@ -0,0 +1,489 @@
# Developing AngularJS
* [Development Setup](#setup)
* [Running Tests](#tests)
* [Coding Rules](#rules)
* [Commit Message Guidelines](#commits)
* [Writing Documentation](#documentation)
## <a name="setup"> Development Setup
This document describes how to set up your development environment to build and test AngularJS, and
explains the basic mechanics of using `git`, `node`, `yarn` and `grunt`.
### Installing Dependencies
Before you can build AngularJS, you must install and configure the following dependencies on your
machine:
* [Git](http://git-scm.com/): The [Github Guide to
Installing Git][git-setup] is a good source of information.
* [Node.js v8.x (LTS)](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.
We recommend using [nvm](https://github.com/creationix/nvm) (or
[nvm-windows](https://github.com/coreybutler/nvm-windows))
to manage and install Node.js, which makes it easy to change the version of Node.js per project.
* [Yarn](https://yarnpkg.com): We use Yarn to install our Node.js module dependencies
(rather than using npm). See the detailed [installation instructions][yarn-install].
* [Java](http://www.java.com): We minify JavaScript using
[Closure Tools](https://developers.google.com/closure/), which require Java (version 7 or higher)
to be installed and included in your
[PATH](http://docs.oracle.com/javase/tutorial/essential/environment/paths.html) variable.
* [Grunt](http://gruntjs.com): We use Grunt as our build system. We're using it as a local dependency,
but you can also add the grunt command-line tool globally (with `yarn global add grunt-cli`), which allows
you to leave out the `yarn` prefix for all our grunt commands.
### Forking AngularJS on Github
To contribute code to AngularJS, you must have a GitHub account so you can push code to your own
fork of AngularJS and open Pull Requests in the [GitHub Repository][github].
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][github].
### Building AngularJS
To build AngularJS, you clone the source code repository and use Grunt to generate the non-minified
and minified AngularJS files:
```shell
# Clone your Github repository:
git clone https://github.com/<github username>/angular.js.git
# Go to the AngularJS directory:
cd angular.js
# Add the main AngularJS repository as an upstream remote to your repository:
git remote add upstream "https://github.com/angular/angular.js.git"
# Install JavaScript dependencies:
yarn install
# Build AngularJS:
yarn grunt package
```
**Note:** If you're using Windows, you must use an elevated command prompt (right click, run as
Administrator). This is because `yarn grunt package` creates some symbolic links.
The build output is in the `build` directory. It consists of the following files and
directories:
* `angular-<version>.zip` — The complete zip file, containing all of the release build
artifacts.
* `angular.js` / `angular.min.js` — The regular and minified core AngularJS script file.
* `angular-*.js` / `angular-*.min.js` — All other AngularJS module script files.
* `docs/` — A directory that contains a standalone version of the docs
(same as served in `docs.angularjs.org`).
### <a name="local-server"></a> Running a Local Development Web Server
To debug code, run end-to-end tests, and serve the docs, it is often useful to have a local
HTTP server. For this purpose, we have made available a local web server based on Node.js.
1. To start the web server, run:
```shell
yarn grunt webserver
```
2. To access the local server, enter the following URL into your web browser:
```text
http://localhost:8000/
```
By default, it serves the contents of the AngularJS project directory.
3. To access the locally served docs, visit this URL:
```text
http://localhost:8000/build/docs/
```
## <a name="tests"> Running Tests
### <a name="unit-tests"></a> Running the Unit Test Suite
We write unit and integration tests with Jasmine and execute them with Karma. To run all of the
tests once on Chrome run:
```shell
yarn grunt test:unit
```
To run the tests on other browsers use the command line flag:
```shell
yarn grunt test:unit --browsers=Chrome,Firefox
```
**Note:** there should be _no spaces between browsers_. `Chrome, Firefox` is INVALID.
If you have a Saucelabs or Browserstack account, you can also run the unit tests on these services
via our pre-defined customLaunchers. See the [karma config file](/karma-shared.conf.js) for all pre-configured browsers.
For example, to run the whole unit test suite on selected browsers:
```shell
# Browserstack
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_10
# Saucelabs
yarn grunt test:unit --browsers=SL_Chrome,SL_Firefox,SL_Safari,SL_IE_9,SL_IE_10,SL_IE_11,SL_EDGE,SL_iOS_10
```
Running these commands requires you to set up [Karma Browserstack][karma-browserstack] or
[Karma-Saucelabs][karma-saucelabs], respectively.
During development, however, it's more productive to continuously run unit tests every time the
source or test files change. To execute tests in this mode run:
1. To start the Karma server, capture Chrome browser and run unit tests, run:
```shell
yarn grunt autotest
```
2. To capture more browsers, open this URL in the desired browser (URL might be different if you
have multiple instance of Karma running, read Karma's console output for the correct URL):
```text
http://localhost:9876/
```
3. To re-run tests just change any source or test file.
To learn more about all of the preconfigured Grunt tasks run:
```shell
yarn grunt --help
```
### <a name="e2e-tests"></a> Running the End-to-end Test Suite
AngularJS's end to end tests are run with Protractor. Simply run:
```shell
yarn grunt test:e2e
```
This will start the webserver and run the tests on Chrome.
## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more [specs][unit-testing].
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
out the existing source code and see the section about [writing documentation](#documentation)
* With the exceptions listed below, we follow the rules contained in
[Google's JavaScript Style Guide][js-style-guide]:
* **Do not use namespaces**: Instead, wrap the entire AngularJS code base in an anonymous
closure and export our API explicitly rather than implicitly.
* Wrap all code at **100 characters**.
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
inheritance only when absolutely necessary.
* We **love functions and closures** and, whenever possible, prefer them over objects.
* To write concise code that can be better minified, we **use aliases internally** that map to
the external API. See our existing code to see what we mean.
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal
API that is used throughout AngularJS. The best guidance is to do what makes the most sense.
### Specific topics
#### Provider configuration
When adding configuration (options) to [providers][docs.provider], we follow a special pattern.
- for each option, add a `method` that ...
- works as a getter and returns the current value when called without argument
- works as a setter and returns itself for chaining when called with argument
- for boolean options, uses the naming scheme `<option>Enabled([enabled])`
- non-primitive options (e.g. objects) should be copied or the properties assigned explicitly to a
new object so that the configuration cannot be changed during runtime.
For a boolean config example, see [`$compileProvider#debugInfoEnabled`][code.debugInfoEnabled]
For an object config example, see [`$location.html5Mode`][code.html5Mode]
#### Throwing errors
User-facing errors should be thrown with [`minErr`][code.minErr], a special error function that provides
errors ids, templated error messages, and adds a link to a detailed error description.
The `$compile:badrestrict` error is a good example for a well-defined `minErr`:
[code][code.badrestrict] and [description][docs.badrestrict].
## <a name="commits"></a> Git Commit Guidelines
We have very precise rules over how our git commit messages can be formatted. This leads to **more
readable messages** that are easy to follow when looking through the **project history**. But also,
we use the git commit messages to **generate the AngularJS change log**.
The commit message formatting can be added using a typical git workflow or through the use of a CLI
wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `yarn run commit`
in your terminal after staging your changes in git.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:
```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The **header** is mandatory and the **scope** of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header
of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit
being reverted.
A commit with this format is automatically created by the [`git revert`][git-revert] command.
### Type
Must be one of the following:
* **feat**: A new feature
* **fix**: A bug fix
* **docs**: Documentation only changes
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing or correcting existing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation
### Scope
The scope could be anything specifying place of the commit change. For example `$location`,
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
You can use `*` when the change affects more than a single scope.
### Subject
The subject contains succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
[reference GitHub issues that this commit closes][closing-issues].
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
The rest of the commit message is then used for this.
A detailed explanation can be found in this [document][commit-message-format].
## <a name="documentation"></a> Writing Documentation
The AngularJS project uses a form of [jsdoc](http://usejsdoc.org/) called ngdoc for all of its code
documentation.
This means that all the docs are stored inline in the source code and so are kept in sync as it
changes.
There is also extra content (the developer guide, error pages, the tutorial,
and misceallenous pages) that live inside the AngularJS repository as markdown files.
This means that since we generate the documentation from the source code, we can easily provide
version-specific documentation by simply checking out a version of AngularJS and running the build.
Extracting the source code documentation, processing and building the docs is handled by the
documentation generation tool [Dgeni][dgeni].
### Building and viewing the docs locally
The docs can be built from scratch using grunt:
```shell
yarn grunt docs
```
This defers the doc-building task to `gulp`.
Note that the docs app is using the local build files to run. This means you might first have to run
the build:
```shell
yarn grunt build
```
(This is also necessary if you are making changes to minErrors).
To view the docs, see [Running a Local Development Web Server](#local-server).
### Writing jsdoc
The ngdoc utility has basic support for many of the standard jsdoc directives. But in particular it
is interested in the following block tags:
* `@name name` - the name of the ngdoc document
* `@param {type} name description` - describes a parameter of a function
* `@returns {type} description` - describes what a function returns
* `@requires` - normally indicates that a JavaScript module is required; in an Angular service it is
used to describe what other services this service relies on
* `@property` - describes a property of an object
* `@description` - used to provide a description of a component in markdown
* `@link` - specifies a link to a URL or a type in the API reference.
Links to the API have the following structure:
* the module namespace, followed by `.` (optional, default `ng`)
* the `@ngdoc` type (see below), followed by `:` (optional, automatically inferred)
* the name
* the method, property, or anchor (optional)
* the display name
For example: `{@link ng.type:$rootScope.Scope#$new Scope.$new()}`.
* `@example` - specifies an example. This can be a simple code block, or a
[runnable example](#the-example-tag).
* `@deprecated` - specifies that the following code is deprecated and should not be used.
In The AngularJS docs, there are two specific patterns which can be used to further describe
the deprecation: `sinceVersion="<version>"` and `removeVersion="<version>"`
The `type` in `@param` and `@returns` must be wrapped in `{}` curly braces, e.g. `{Object|Array}`.
Parameters can be made optional by *either* appending a `=` to the type, e.g. `{Object=}`, *or* by
putting the `[name]` in square brackets.
Default values are only possible with the second syntax by appending `=<value>` to the parameter
name, e.g. `@param {boolean} [ownPropsOnly=false]`.
Descriptions can contain markdown formatting.
#### AngularJS-specific jsdoc directives
In addition to the standard jsdoc tags, there are a number that are specific to the Angular
code-base:
* `@ngdoc` - specifies the type of thing being documented. See below for more detail.
* `@eventType emit|broadcast` - specifies whether the event is emitted or broadcast
* `@usage` - shows how to use a `function` or `directive`. Is usually automatically generated.
* `@knownIssue` - adds info about known quirks, problems, or limitations with the API, and possibly,
workarounds. This section is not for bugs.
The following are specific to directives:
* `@animations` - specifies the animations a directive supports
* `@multiElement` - specifies if a directive can span over multiple elements
* `@priority` - specifies a directive's priority
* `@restrict` - is extracted to show the usage of a directive. For example, for [E]lement,
[A]ttribute, and [C]lass, use `@restrict ECA`
* `@scope` - specifies that a directive will create a new scope
### The `@ngdoc` Directive
This directive helps to specify the template used to render the item being documented. For instance,
a directive would have different properties to a filter and so would be documented differently. The
commonly used types are:
* `overview` - a general page (guide, api index)
* `provider` - AngularJS provider, such as `$compileProvider` or `$httpProvider`.
* `service` - injectable AngularJS service, such as `$compile` or `$http`.
* `object` - well defined object (often exposed as a service)
* `function` - function that will be available to other methods (such as a helper function within
the ng module)
* `method` - method on an object/service/controller
* `property` - property on an object/service/controller
* `event` - AngularJS event that will propagate through the `$scope` tree.
* `directive` - AngularJS directive
* `filter` - AngularJS filter
* `error` - minErr error description
### General documentation with Markdown
Any text in tags can contain markdown syntax for formatting. Generally, you can use any markdown
feature.
#### Headings
Only use *h2* headings and lower, as the page title is set in *h1*. Also make sure you follow the
heading hierarchy. This ensures correct table of contents are created.
#### Code blocks
In line code can be specified by enclosing the code in back-ticks (\`).
A block of multi-line code can be enclosed in triple back-ticks (\`\`\`) but it is formatted better
if it is enclosed in &lt;pre&gt;...&lt;/pre&gt; tags and the code lines themselves are indented.
### Writing runnable (live) examples and e2e tests
It is possible to embed examples in the documentation along with appropriate e2e tests. These
examples and scenarios will be converted to runnable code within the documentation. So it is
important that they work correctly. To ensure this, all these e2e scenarios are run as part of the
automated Travis tests.
If you are adding an example with an e2e test, you should [run the test locally](#e2e-tests) first
to ensure it passes. You can change `it(...)` to `fit(...)` to run only your test,
but make sure you change it back to `it(...)` before committing.
#### The `<example>` tag
This tag identifies a block of HTML that will define a runnable example. It can take the following
attributes:
* `animations` - if set to `true` then this example uses ngAnimate.
* `deps` - Semicolon-separated list of additional angular module files to be loaded,
e.g. `angular-animate.js`
* `name` - every example should have a name. It should start with the component, e.g directive name,
and not contain whitespace
* `module` - the name of the app module as defined in the example's JavaScript
Within this tag we provide `<file>` tags that specify what files contain the example code.
```
<example
module="angularAppModule"
name="exampleName"
deps="angular-animate.js;angular-route.js"
animations="true">
...
<file name="index.html">...</file>
<file name="script.js">...</file>
<file name="animations.css">...</file>
<file name="protractor.js">...</file>
...
</example>
```
You can see an example of a well-defined example [in the `ngRepeat` documentation][code.ngRepeat-example].
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
[code.badrestrict]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/ng/compile.js#L1107-L1110
[code.debugInfoEnabled]: https://github.com/angular/angular.js/blob/32fbb2e78f53d765fbb170f7cf99e42e072d363b/src/ng/compile.js#L1378-L1413
[code.html5Mode]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/ng/location.js#L752-L797
[code.minErr]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/minErr.js#L53-L113
[code.ngRepeat-example]: https://github.com/angular/angular.js/blob/0822d34b10ea0371c260c80a1486a4d508ea5a91/src/ng/directive/ngRepeat.js#L249-L340
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[dgeni]: https://github.com/angular/dgeni
[docs.badrestrict]: docs/content/error/$compile/badrestrict.ngdoc
[docs.provider]: https://code.angularjs.org/snapshot/docs/api/auto/service/$provide#provider
[git-revert]: https://git-scm.com/docs/git-revert
[git-setup]: https://help.github.com/articles/set-up-git
[github-issues]: https://github.com/angular/angular.js/issues
[github]: https://github.com/angular/angular.js
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
[yarn-install]: https://yarnpkg.com/en/docs/install
+54 -8
View File
@@ -63,7 +63,11 @@ module.exports = function(grunt) {
NG_VERSION.cdn = versionInfo.cdnVersion;
var dist = 'angular-' + NG_VERSION.full;
var deployVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.full;
var deployVersion = NG_VERSION.full;
if (NG_VERSION.isSnapshot) {
deployVersion = NG_VERSION.distTag === 'latest' ? 'snapshot-stable' : 'snapshot';
}
if (versionInfo.cdnVersion == null) {
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?\n' +
@@ -312,7 +316,40 @@ module.exports = function(grunt) {
copy: {
i18n: {
files: [
{ src: 'src/ngLocale/**', dest: 'build/i18n/', expand: true, flatten: true }
{
src: 'src/ngLocale/**',
dest: 'build/i18n/',
expand: true,
flatten: true
}
]
},
deployFirebaseCode: {
files: [
// the zip file should not be compressed again.
{
src: 'build/*.zip',
dest: 'uploadCode/' + deployVersion + '/',
expand: true,
flatten: true
}
]
},
deployFirebaseDocs: {
files: [
// The source files are needed by the embedded examples in the docs app.
{
src: 'build/angular*.{js,js.map,min.js}',
dest: 'uploadDocs/',
expand: true,
flatten: true
},
{
cwd: 'build/docs',
src: '**',
dest: 'uploadDocs/',
expand: true
}
]
}
},
@@ -327,18 +364,22 @@ module.exports = function(grunt) {
dot: true,
dest: dist + '/'
},
firebaseCodeDeploy: {
deployFirebaseCode: {
options: {
mode: 'gzip'
},
src: ['**'],
src: ['**', '!*.zip'],
cwd: 'build',
expand: true,
dest: 'upload/' + deployVersion + '/'
dest: 'uploadCode/' + deployVersion + '/'
}
},
shell: {
// Travis expects the firebase.json in the repository root, but we have it in a sub-folder
'symlink-firebase-docs': {
command: 'ln -s ./scripts/docs.angularjs.org-firebase/firebase.json ./firebase.json'
},
'install-node-dependencies': {
command: 'yarn'
},
@@ -413,14 +454,12 @@ module.exports = function(grunt) {
'shell:promises-aplus-tests'
]);
grunt.registerTask('minify', [
'bower',
'clean',
'build',
'minall'
]);
grunt.registerTask('webserver', ['connect:devserver']);
grunt.registerTask('package', [
'bower',
'validate-angular-files',
'clean',
'buildall',
@@ -428,7 +467,7 @@ module.exports = function(grunt) {
'collect-errors',
'write',
'docs',
'copy',
'copy:i18n',
'compress:build'
]);
grunt.registerTask('ci-checks', [
@@ -436,6 +475,13 @@ module.exports = function(grunt) {
'merge-conflict',
'eslint'
]);
grunt.registerTask('prepareFirebaseDeploy', [
'package',
'compress:deployFirebaseCode',
'copy:deployFirebaseCode',
'firebaseDocsJsonForTravis',
'copy:deployFirebaseDocs'
]);
grunt.registerTask('default', ['package']);
};
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
Copyright (c) 2010-2018 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+1 -1
View File
@@ -7,7 +7,7 @@ in its `contrib/externs` directory.
The definitions contain externs for use with the Closure compiler (aka
JSCompiler). Passing these files to the --externs parameter of a compiler
pass allows using type annotations for AngularJS objects. For example,
Angular's $scope objects can be annotated as:
AngularJS's $scope objects can be annotated as:
```js
/** @type {angular.Scope} */
var scope = $scope;
+16 -24
View File
@@ -16,35 +16,27 @@ piece of cake. Best of all? It makes development fun!
* Tutorial: https://docs.angularjs.org/tutorial
* API Docs: https://docs.angularjs.org/api
* Developer Guide: https://docs.angularjs.org/guide
* Contribution guidelines: [CONTRIBUTING.md](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
* Contribution guidelines: [CONTRIBUTING.md](CONTRIBUTING.md)
* Core Development: [DEVELOPERS.md](DEVELOPERS.md)
* Dashboard: https://dashboard.angularjs.org
##### Looking for Angular 2? Go here: https://github.com/angular/angular
##### Looking for the new Angular? Go here: https://github.com/angular/angular
Building AngularJS
---------
[Once you have set up your environment](https://docs.angularjs.org/misc/contribute), just run:
Documentation
--------------------
Go to https://docs.angularjs.org
grunt package
Running tests
-------------
To execute all unit tests, use:
grunt test:unit
To execute end-to-end (e2e) tests, use:
grunt package
grunt test:e2e
To learn more about the grunt tasks, run `grunt --help`
Contribute & Develop
Contribute
--------------------
We've set up a separate document for our [contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
We've set up a separate document for our
[contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
Develop
--------------------
We've set up a separate document for
[developers](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md).
[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/README.md?pixel)](https://github.com/igrigorik/ga-beacon)
@@ -80,7 +72,7 @@ HTML is also used to determine the wiring of the app. Special attributes in the
to load the app, which components or controllers to use for each element, etc. We specify "what"
gets loaded, but not "how". This declarative approach greatly simplifies app development in a sort
of WYSIWYG way. Rather than spending time on how the program flows and orchestrating the various
moving parts, we simply define what we want and Angular will take care of the dependencies.
moving parts, we simply define what we want and AngularJS will take care of the dependencies.
#### Data Handling made simple
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties
+4 -4
View File
@@ -1,6 +1,6 @@
# Triage new issues/PRs on github
This document shows the steps the Angular team is using to triage issues.
This document shows the steps the AngularJS team is using to triage issues.
The labels are used later on for [planning releases](#assigning-work).
@@ -45,12 +45,12 @@ This process based on the idea of minimizing user pain
1. Label `frequency: *` How often does this issue come up? How many developers does this affect? Chose just one of the following:
* low - obscure issue affecting a handful of developers
* moderate - impacts a common usage pattern
* high - impacts most or all Angular apps
* high - impacts most or all AngularJS apps
1. Label `severity: *` - How bad is the issue? Chose just one of the following:
* security issue
* regression
* memory leak
* broken expected use - it's hard or impossible for a developer using Angular to accomplish something that Angular should be able to do
* broken expected use - it's hard or impossible for a developer using AngularJS to accomplish something that AngularJS should be able to do
* confusing - unexpected or inconsistent behavior; hard-to-debug
* inconvenience - causes ugly/boilerplate code in apps
1. Label `component: *`
@@ -95,7 +95,7 @@ You can mention him in the relevant thread like this: `@btford`.
> Thanks for submitting this issue!
> Unfortunately, we don't think this functionality belongs in core.
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or to the npm repository.
> The good news is that you could easily implement this as a third-party module and publish it to the npm registry.
## Assigning Work
+4 -4
View File
@@ -190,7 +190,7 @@ var angularFiles = {
],
'karma': [
'bower_components/jquery/dist/jquery.js',
'node_modules/jquery/dist/jquery.js',
'test/jquery_remove.js',
'@angularSrc',
'@angularSrcModules',
@@ -228,7 +228,7 @@ var angularFiles = {
],
'karmaJquery': [
'bower_components/jquery/dist/jquery.js',
'node_modules/jquery/dist/jquery.js',
'test/jquery_alias.js',
'@angularSrc',
'@angularSrcModules',
@@ -248,8 +248,8 @@ var angularFiles = {
angularFiles['karmaJquery' + jQueryVersion] = []
.concat(angularFiles.karmaJquery)
.map(function(path) {
if (path.startsWith('bower_components/jquery')) {
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
if (path.startsWith('node_modules/jquery')) {
return path.replace(/^node_modules\/jquery/, 'node_modules/jquery-' + jQueryVersion);
}
return path;
});
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
-11
View File
@@ -1,11 +0,0 @@
{
"name": "angularjs",
"license": "MIT",
"devDependencies": {
"jquery": "3.2.1",
"jquery-2.2": "jquery#2.2.4",
"jquery-2.1": "jquery#2.1.4",
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.4/assets/ng-closure-runner.zip"
}
}
+29
View File
@@ -905,6 +905,35 @@ iframe[name="example-anchoringExample"] {
background-color: inherit;
}
toc-container {
display: block;
margin: 15px 10px;
}
toc-container b {
text-transform: uppercase;
}
toc-container .btn {
padding: 3px 6px;
font-size: 13px;
margin-left: 5px;
}
toc-container > div > toc-tree ul {
list-style: none;
padding-left: 15px;
padding-bottom: 2px;
}
toc-container > div > toc-tree > ul {
padding-left: 0;
}
toc-container > div > toc-tree > ul > li > toc-tree > ul > li toc-tree > ul li {
font-size: 13px;
}
@media handheld and (max-width:800px), screen and (max-device-width:800px), screen and (max-width:800px) {
.navbar {
min-height: auto;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 183 B

+30 -33
View File
@@ -1,51 +1,48 @@
'use strict';
describe('doc.angularjs.org', function() {
describe('API pages', function() {
describe('API pages', function() {
it('should display links to code on GitHub', function() {
browser.get('build/docs/index.html#!/api/ng/service/$http');
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
it('should display links to code on GitHub', function() {
browser.get('build/docs/index.html#!/api/ng/service/$http');
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
browser.get('build/docs/index.html#!/api/ng/service/$http');
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
});
browser.get('build/docs/index.html#!/api/ng/service/$http');
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
});
it('should change the page content when clicking a link to a service', function() {
browser.get('build/docs/index.html');
it('should change the page content when clicking a link to a service', function() {
browser.get('build/docs/index.html');
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
ngBindLink.click();
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
ngBindLink.click();
var mainHeader = element(by.css('.main-body h1 '));
expect(mainHeader.getText()).toEqual('ngClick');
});
var mainHeader = element(by.css('.main-body h1 '));
expect(mainHeader.getText()).toEqual('ngClick');
});
it('should show the functioning input directive example', function() {
browser.get('build/docs/index.html#!/api/ng/directive/input');
it('should show the functioning input directive example', function() {
browser.get('build/docs/index.html#!/api/ng/directive/input');
// Ensure that the page is loaded before trying to switch frames.
browser.waitForAngular();
// Ensure that the page is loaded before trying to switch frames.
browser.waitForAngular();
browser.switchTo().frame('example-input-directive');
browser.switchTo().frame('example-input-directive');
var nameInput = element(by.model('user.name'));
nameInput.sendKeys('!!!');
var nameInput = element(by.model('user.name'));
nameInput.sendKeys('!!!');
var code = element.all(by.css('tt')).first();
expect(code.getText()).toContain('guest!!!');
});
var code = element.all(by.css('tt')).first();
expect(code.getText()).toContain('guest!!!');
});
it('should trim indentation from code blocks', function() {
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
it('should trim indentation from code blocks', function() {
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
var codeBlocks = element.all(by.css('pre > code.lang-js'));
codeBlocks.each(function(codeBlock) {
var firstSpan = codeBlock.all(by.css('span')).first();
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
});
var codeBlocks = element.all(by.css('pre > code.lang-js'));
codeBlocks.each(function(codeBlock) {
var firstSpan = codeBlock.all(by.css('span')).first();
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
});
});
});
@@ -0,0 +1,58 @@
'use strict';
describe('directives', function() {
describe('parameter section', function() {
it('should show the directive name only if it is a param (attribute) with a value', function() {
browser.get('build/docs/index.html#!/api/ng/directive/ngInclude');
expect(getParamNames().getText()).toContain('ngInclude | src');
browser.get('build/docs/index.html#!/api/ngRoute/directive/ngView');
expect(getParamNames().getText()).not.toContain('ngView');
});
});
describe('usage section', function() {
it('should show the directive name if it is a param (attribute) with a value', function() {
browser.get('build/docs/index.html#!/api/ng/directive/ngInclude');
expect(getUsageAs('element', 'ng-include').isPresent()).toBe(true);
expect(getUsageAs('attribute', 'ng-include').isPresent()).toBe(true);
expect(getUsageAs('CSS class', 'ng-include').isPresent()).toBe(true);
});
it('should show the directive name if it is a void param (attribute)', function() {
browser.get('build/docs/index.html#!/api/ngRoute/directive/ngView');
expect(getUsageAs('element', 'ng-view').isPresent()).toBe(true);
expect(getUsageAs('attribute', 'ng-view').isPresent()).toBe(true);
expect(getUsageAs('CSS class', 'ng-view').isPresent()).toBe(true);
});
});
});
function getParamNames() {
var argsSection = element(by.className('input-arguments'));
var paramNames = argsSection.all(by.css('tr td:nth-child(1)'));
return paramNames;
}
// Based on the type of directive usage, the directive name will show up in the code block
// with a specific class
var typeClassMap = {
element: 'tag',
attribute: 'atn',
'CSS class': 'atv'
};
function getUsageAs(type, directiveName) {
var usage = element(by.className('usage'));
var as = usage.element(by.cssContainingText('li', 'as ' + type));
return as.element(by.cssContainingText('span.' + typeClassMap[type], directiveName));
}
+19
View File
@@ -49,6 +49,25 @@ describe('docs.angularjs.org', function() {
});
it('should include the files for the embedded examples from the same domain', function() {
browser.get('build/docs/index-production.html#!api/ng/directive/ngClick');
var origin = browser.executeScript('return document.location.origin;');
var exampleIFrame = element(by.name('example-ng-click'));
// This is technically an implementation detail, but if this changes, then there's a good
// chance the deployment process changed
expect(exampleIFrame.getAttribute('src')).toContain('examples/example-ng-click/index.html');
browser.switchTo().frame('example-ng-click');
var scriptEl = element(by.tagName('script'));
// Ensure the included file is from the same domain
expect(scriptEl.getAttribute('src')).toContain(origin);
});
it('should be resilient to trailing slashes', function() {
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/');
+130
View File
@@ -0,0 +1,130 @@
'use strict';
/**
* This scenario checks the presence of the table of contents for a sample of pages - API and guide.
* The expectations are kept vague so that they can be easily adjusted when the docs change.
*/
describe('table of contents', function() {
it('on provider pages', function() {
browser.get('build/docs/index.html#!/api/ng/provider/$interpolateProvider');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Methods');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(3);
expect(match[1].all(by.css('li')).count()).toBe(2);
});
});
it('on service pages', function() {
browser.get('build/docs/index.html#!/api/ng/service/$controller');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Usage');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(3);
expect(match[2].all(by.css('li')).count()).toBe(2);
});
});
it('on directive pages', function() {
browser.get('build/docs/index.html#!/api/ng/directive/input');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Usage');
expect(text.join('')).toContain('Directive Info');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(4);
expect(match[2].all(by.css('li')).count()).toBe(1);
});
});
it('on function pages', function() {
browser.get('build/docs/index.html#!/api/ng/function/angular.bind');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Usage');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(2);
expect(match[1].all(by.css('li')).count()).toBe(2);
});
});
it('on type pages', function() {
browser.get('build/docs/index.html#!/api/ng/type/ModelOptions');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Methods');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(2);
expect(match[1].all(by.css('li')).count()).toBe(2);
});
});
it('on filter pages', function() {
browser.get('build/docs/index.html#!/api/ng/filter/date');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Usage');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(3);
expect(match[1].all(by.css('li')).count()).toBe(2);
});
});
it('on guide pages', function() {
browser.get('build/docs/index.html#!/guide/services');
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(5);
expect(match[1].all(by.css('li')).count()).toBe(3);
});
});
});
-1
View File
@@ -14,7 +14,6 @@ angular.module('docsApp', [
'search',
'tutorials',
'versions',
'deployment',
'ui.bootstrap.dropdown'
])
+132 -2
View File
@@ -1,7 +1,8 @@
'use strict';
angular.module('directives', [])
var directivesModule = angular.module('directives', []);
directivesModule
/**
* backToTop Directive
* @param {Function} $anchorScroll
@@ -47,4 +48,133 @@ angular.module('directives', [])
}
}
};
});
})
.directive('tocCollector', ['$rootScope', function($rootScope) {
return {
controller: ['$element', function($element) {
/* eslint-disable no-invalid-this */
var ctrl = this;
$rootScope.$on('$includeContentRequested', function() {
ctrl.hs = [];
ctrl.root = [];
});
this.hs = [];
this.root = [];
this.element = $element;
this.register = function(h) {
var previousLevel;
for (var i = ctrl.hs.length - 1; i >= 0; i--) {
if (ctrl.hs[i].level === (h.level - 1)) {
previousLevel = ctrl.hs[i];
break;
}
}
if (previousLevel) {
previousLevel.children.push(h);
} else {
this.root.push(h);
}
ctrl.hs.push(h);
/* eslint-enable no-invalid-this */
};
}]
};
}])
.component('tocTree', {
template: '<ul>' +
'<li ng-repeat="item in $ctrl.items">' +
'<a ng-href="#{{item.fragment}}">{{item.title}}</a>' +
'<toc-tree ng-if="::item.children.length > 0" items="item.children"></toc-tree>' +
'</li>' +
'</ul>',
bindings: {
items: '<'
}
})
.directive('tocContainer', function() {
return {
scope: true,
restrict: 'E',
require: {
tocContainer: '',
tocCollector: '^^'
},
controller: function() {
this.showToc = true;
this.items = [];
},
controllerAs: '$ctrl',
link: function(scope, element, attrs, ctrls) {
ctrls.tocContainer.items = ctrls.tocCollector.root;
},
template: '<div ng-if="::$ctrl.items.length > 1">' +
'<b>Contents</b>' +
'<button class="btn" ng-click="$ctrl.showToc = !$ctrl.showToc">{{$ctrl.showToc ? \'Hide\' : \'Show\'}}</button><br>' +
'<toc-tree items="$ctrl.items" ng-show="$ctrl.showToc"></toc-tree>' +
'</div>'
};
})
.directive('header', function() {
return {
restrict: 'E',
controller: ['$element', function($element) {
// eslint-disable-next-line no-invalid-this
this.element = $element;
}]
};
})
.directive('h1', ['$compile', function($compile) {
return {
restrict: 'E',
require: {
tocCollector: '^^?',
header: '^^?'
},
link: function(scope, element, attrs, ctrls) {
if (!ctrls.tocCollector) return;
var tocContainer = angular.element('<toc-container></toc-container>');
var containerElement = ctrls.header ? ctrls.header.element : element;
containerElement.after(tocContainer);
$compile(tocContainer)(scope);
}
};
}]);
for (var i = 2; i <= 5; i++) {
registerHDirective(i);
}
function registerHDirective(i) {
directivesModule.directive('h' + i, function() {
return {
restrict: 'E',
require: {
'tocCollector': '^^?'
},
link: function(scope, element, attrs, ctrls) {
var toc = ctrls.tocCollector;
if (!toc || !attrs.id) return;
toc.register({
level: i,
fragment: attrs.id,
title: element.text(),
children: []
});
}
};
});
}
+1 -7
View File
@@ -18,13 +18,7 @@ angular.module('examples', [])
return {
restrict: 'C',
scope : true,
controller : ['$scope', 'DEPLOYMENT', function($scope, DEPLOYMENT) {
var exampleIndexFile = (DEPLOYMENT === 'default' ? 'index' : 'index-' + DEPLOYMENT) + '.html';
$scope.getExampleIndex = function(basePath) {
return basePath + '/' + exampleIndexFile;
};
controller : ['$scope', function($scope) {
$scope.setTab = function(index) {
var tab = $scope.tabs[index];
$scope.activeTabIndex = index;
+6
View File
@@ -67,6 +67,12 @@ angular.module('search', [])
clearResults();
$scope.q = '';
};
$scope.handleResultClicked = function($event) {
if ($event.which === 1 && !$event.ctrlKey && !$event.metaKey) {
$scope.hideResults();
}
};
}])
+8 -2
View File
@@ -12,10 +12,16 @@ angular.module('versions', ['currentVersionData', 'allVersionsData'])
/** @this VersionPickerController */
function VersionPickerController($location, $window, CURRENT_NG_VERSION, ALL_NG_VERSIONS) {
var versionStr = CURRENT_NG_VERSION.isSnapshot ? 'snapshot' : CURRENT_NG_VERSION.version;
var versionStr = CURRENT_NG_VERSION.version;
if (CURRENT_NG_VERSION.isSnapshot) {
versionStr = CURRENT_NG_VERSION.distTag === 'latest' ? 'snapshot-stable' : 'snapshot';
}
this.versions = ALL_NG_VERSIONS;
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) { return value.version.version === versionStr; });
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) {
return value.version.version === versionStr;
});
this.jumpToDocsVersion = function(value) {
var currentPagePath = $location.path().replace(/\/$/, '');
+32 -22
View File
@@ -1,40 +1,50 @@
'use strict';
describe('code', function() {
var prettyPrintOne, oldPP;
describe('directives', function() {
var compile, scope;
var any = jasmine.any;
beforeEach(module('directives'));
beforeEach(inject(function($rootScope, $compile) {
// Provide stub for pretty print function
oldPP = window.prettyPrintOne;
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
beforeEach(module(function($compileProvider) {
$compileProvider.debugInfoEnabled(false);
}));
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope.$new();
compile = $compile;
}));
afterEach(function() {
window.prettyPrintOne = oldPP;
});
describe('code', function() {
var prettyPrintOne, oldPP;
var any = jasmine.any;
beforeEach(function() {
// Provide stub for pretty print function
oldPP = window.prettyPrintOne;
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
});
afterEach(function() {
window.prettyPrintOne = oldPP;
});
it('should pretty print innerHTML', function() {
compile('<code>var x;</code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
it('should pretty print innerHTML', function() {
compile('<code>var x;</code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
});
it('should allow language declaration', function() {
compile('<code class="lang-javascript"></code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
});
it('supports allow line numbers', function() {
compile('<code class="linenum"></code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
});
});
it('should allow language declaration', function() {
compile('<code class="lang-javascript"></code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
});
it('supports allow line numbers', function() {
compile('<code class="linenum"></code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
});
});
+1 -11
View File
@@ -112,10 +112,6 @@ module.exports = new Package('angularjs', [
docTypes: ['indexPage'],
pathTemplate: '.',
outputPathTemplate: '${id}.html'
}, {
docTypes: ['deploymentData'],
pathTemplate: '.',
outputPathTemplate: 'js/${id}.js'
});
computePathsProcessor.pathTemplates.push({
@@ -129,14 +125,8 @@ module.exports = new Package('angularjs', [
outputPathTemplate: 'partials/${area}/${moduleName}/${groupType}.html'
});
computePathsProcessor.pathTemplates.push({
docTypes: ['example'],
pathTemplate: 'examples/${example.id}',
outputPathTemplate: 'examples/${example.id}/index${deploymentQualifier}.html'
});
computeIdsProcessor.idTemplates.push({
docTypes: ['overview', 'tutorial', 'e2e-test', 'indexPage', 'deploymentData'],
docTypes: ['overview', 'tutorial', 'e2e-test', 'indexPage'],
getId: function(doc) { return doc.fileInfo.baseName; },
getAliases: function(doc) { return [doc.id]; }
});
-10
View File
@@ -35,17 +35,7 @@ module.exports = function generateIndexPagesProcessor() {
indexDoc.id = 'index' + (deployment.name === 'default' ? '' : '-' + deployment.name);
var deploymentDoc = {
docType: 'deploymentData',
id: 'deployment-data-' + deployment.name,
template: 'angular-service.template.js',
ngModuleName: 'deployment',
serviceName: 'DEPLOYMENT',
serviceValue: deployment.name
};
docs.push(indexDoc);
docs.push(deploymentDoc);
});
}
};
+30 -1
View File
@@ -55,6 +55,9 @@ module.exports = function generateVersionDocProcessor(gitData) {
if (missesCurrentVersion) versions.push(currentVersion.version);
// Get the stable release with the highest version
var highestStableRelease = versions.reverse().find(semverIsStable);
versions = versions
.filter(function(versionStr) {
return blacklist.indexOf(versionStr) === -1;
@@ -82,7 +85,21 @@ module.exports = function generateVersionDocProcessor(gitData) {
var latest = sortObject(latestMap, reverse(semver.compare))
.map(function(version) { return makeOption(version, 'Latest'); });
return [makeOption({version: 'snapshot'}, 'Latest', 'master')]
// Generate master and stable snapshots
var snapshots = [
makeOption(
{version: 'snapshot'},
'Latest',
'master-snapshot'
),
makeOption(
{version: 'snapshot-stable'},
'Latest',
createSnapshotStableLabel(highestStableRelease)
)
];
return snapshots
.concat(latest)
.concat(versions);
}
@@ -112,6 +129,18 @@ module.exports = function generateVersionDocProcessor(gitData) {
function sortObject(obj, cmp) {
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
}
// https://github.com/kaelzhang/node-semver-stable/blob/34dd29842409295d49889d45871bec55a992b7f6/index.js#L25
function semverIsStable(version) {
var semverObj = semver.parse(version);
return semverObj === null ? false : !semverObj.prerelease.length;
}
function createSnapshotStableLabel(version) {
var label = 'v' + version.replace(/.$/, 'x') + '-snapshot';
return label;
}
}
};
};
@@ -26,7 +26,6 @@ module.exports = function debugDeployment(getVersion) {
'js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/deployment-data-debug.js',
'js/docs.js'
],
stylesheets: [
@@ -26,7 +26,6 @@ module.exports = function defaultDeployment(getVersion) {
'js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/deployment-data-default.js',
'js/docs.min.js'
],
stylesheets: [
-1
View File
@@ -30,7 +30,6 @@ module.exports = function jqueryDeployment(getVersion) {
'js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/deployment-data-jquery.js',
'js/docs.min.js'
],
stylesheets: [
+12 -12
View File
@@ -7,24 +7,25 @@ var angularCodeUrl = '//code.angularjs.org/';
var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;
// The plnkr examples must use the code.angularjs.org repo for the snapshot,
// and the cdn for the tagged version and, if the build is not tagged, the currentVersion.
//
// The currentVersion may not be available on the cdn (e.g. if built locally, or hasn't been pushed
// yet). This will lead to a 404, but this is preferable to loading a version with which the example
// might not work (possibly in subtle ways).
var examplesCdnUrl = versionInfo.currentVersion.isSnapshot ?
(angularCodeUrl + 'snapshot') :
(googleCdnUrl + (versionInfo.currentVersion.version || versionInfo.currentVersion));
// The "examplesDependencyPath" here applies to the examples when they are opened in plnkr.co.
// The embedded examples instead always include the files from the *default* deployment,
// to ensure that the source files are always available.
// The plnkr examples must always use the code.angularjs.org source files.
// We cannot rely on the CDN files here, because they are not deployed by the time
// docs.angularjs.org and code.angularjs.org need them.
var versionPath = versionInfo.currentVersion.isSnapshot ?
'snapshot' :
(versionInfo.currentVersion.version || versionInfo.currentVersion.version);
var examplesDependencyPath = angularCodeUrl + versionPath + '/';
module.exports = function productionDeployment(getVersion) {
return {
name: 'production',
examples: {
commonFiles: {
scripts: [examplesCdnUrl + '/angular.min.js']
scripts: [examplesDependencyPath + 'angular.min.js']
},
dependencyPath: examplesCdnUrl + '/'
dependencyPath: examplesDependencyPath
},
scripts: [
cdnUrl + '/angular.min.js',
@@ -43,7 +44,6 @@ module.exports = function productionDeployment(getVersion) {
'https://code.angularjs.org/snapshot/docs/js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/deployment-data-production.js',
'js/docs.min.js'
],
stylesheets: [
+5 -6
View File
@@ -4,14 +4,13 @@ var path = require('canonical-path');
/**
* dgService getVersion
* @description
* Find the current version of the bower component (or node module)
* Find the current version of the node module
*/
module.exports = function getVersion(readFilesProcessor) {
var basePath = readFilesProcessor.basePath;
var sourceFolder = path.resolve(readFilesProcessor.basePath, 'node_modules');
var packageFile = 'package.json';
return function(component, sourceFolder, packageFile) {
sourceFolder = path.resolve(basePath, sourceFolder || 'node_modules');
packageFile = packageFile || 'package.json';
return require(path.join(sourceFolder,component,packageFile)).version;
return function(component) {
return require(path.join(sourceFolder, component, packageFile)).version;
};
};
@@ -9,7 +9,7 @@
<pre class="minerr-errmsg" error-display="{$ doc.formattedErrorMessage $}">{$ doc.formattedErrorMessage $}</pre>
</div>
<h2>Description</h2>
<h2 id="description">Description</h2>
<div class="description">
{$ doc.description | marked $}
</div>
@@ -108,6 +108,7 @@
<li><a href="misc/contribute">Contribute</a></li>
<li><a href="https://github.com/angular/angular-seed">Seed App project template</a></li>
<li><a href="https://github.com/angular/angular.js">GitHub</a></li>
<li><a href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md">Changelog</a></li>
<li><a href="http://code.angularjs.org/">Download</a></li>
</ul>
</li>
@@ -132,7 +133,7 @@
<div ng-repeat="(key, value) in results track by key" class="search-results-group" ng-class="colClassName + ' col-group-' + key" ng-show="value.length > 0">
<h4 class="search-results-group-heading">{{ key }}</h4>
<ul class="search-results">
<li ng-repeat="item in value" class="search-result"><a ng-click="hideResults()" ng-href="{{ item.path }}">{{ item.name }}</a></li>
<li ng-repeat="item in value" class="search-result"><a ng-click="handleResultClicked($event)" ng-href="{{ item.path }}">{{ item.name }}</a></li>
</ul>
</div>
</div>
@@ -198,7 +199,7 @@
</div>
<div class="grid-right">
<div id="loading" ng-show="loading">Loading...</div>
<div ng-hide="loading" ng-include="partialPath" autoscroll></div>
<div ng-hide="loading" ng-include="partialPath" toc-collector autoscroll></div>
</div>
</div>
</section>
@@ -208,10 +209,10 @@
<p class="pull-right"><a back-to-top>Back to top</a></p>
<p>
Super-powered by Google ©2010-2017
Super-powered by Google ©2010-2018
(<a id="version"
ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
ng-bind-template="v{{version}}" title="Changelog of this version of Angular JS">
ng-bind-template="v{{version}}" title="Changelog of this version of AngularJS">
</a>)
</p>
<p>
@@ -18,7 +18,7 @@
</div>
{% endfor %}
<iframe class="runnable-example-frame" ng-src="{{getExampleIndex('{$ doc.example.deployments.default.path $}')}}" name="{$ doc.example.id $}"></iframe>
<iframe class="runnable-example-frame" src="{$ doc.example.deployments.default.outputPath $}" name="{$ doc.example.id $}"></iframe>
</div>
</div>
@@ -23,6 +23,7 @@
{% block description %}
<div class="api-profile-description">
<h2 id="overview">Overview</h2>
{$ doc.description | marked $}
</div>
{% endblock %}
@@ -51,7 +52,7 @@
{% block examples %}
{%- if doc.examples %}
<h2 id="example">Examples</h2>
<h2 id="examples">{$ "Examples" if doc.examples | length > 1 else "Example" $}</h2>
{%- for example in doc.examples -%}
{$ example | marked $}
{%- endfor -%}
@@ -2,7 +2,7 @@
{% extends "api/api.template.html" %}
{% block additional %}
<h2>Directive Info</h2>
<h2 id="{$ doc.name $}-info">Directive Info</h2>
<ul>
{% if doc.scope %}<li>This directive creates new scope.</li>{% endif %}
<li>This directive executes at priority level {$ doc.priority $}.</li>
@@ -29,10 +29,23 @@
</li>
{% endif -%}
{% set hasNameAsParam = false %}
{# when a directive's name is not a parameter (i.e. doesn't take a value),
add the directive name to the list of attributes and/or css classes #}
{%- for param in doc.params %}
{% set hasNameAsParam = true if param.name === doc.name else hasNameAsParam %}
{%- endfor %}
{%- if doc.restrict.attribute -%}
<li>as attribute:
{% code %}
<{$ doc.element $}
{%- if not hasNameAsParam %}
{$ lib.directiveParam(doc.name, {}, '', '') $}
{%- endif -%}
{%- for param in doc.params %}
{$ lib.directiveParam(param.name, param.type, '="', '"') $}
{%- endfor %}>
@@ -43,10 +56,14 @@
{% endif -%}
{%- if doc.restrict.cssClass -%}
<li>as CSS class:
{% code %}
{% set sep = joiner(' ') %}
<{$ doc.element $} class="
{%- if not hasNameAsParam -%}
{$ sep() $}{$ lib.directiveParam(doc.name, {}, '', '') $}
{%- endif -%}
{%- for param in doc.params -%}
{$ sep() $}{$ lib.directiveParam(param.name, param.type, ': ', ';') $}
{%- endfor %}"> ... </{$ doc.element $}>
@@ -2,7 +2,7 @@
{% extends "api/api.template.html" %}
{% block additional %}
<h2>Usage</h2>
<h2 id="usage">Usage</h2>
<h3>In HTML Template Binding</h3>
{% if doc.usage %}
{$ doc.usage | code $}
@@ -8,7 +8,7 @@
{$ x.deprecatedBlock(doc) $}
<h2>Installation</h2>
<h2 id="module-installation">Installation</h2>
{% if doc.installation or doc.installation == '' %}
{$ doc.installation | marked $}
{% else %}
@@ -76,7 +76,7 @@
{% if doc.componentGroups.length %}
<div class="component-breakdown">
<h2>Module Components</h2>
<h2 id="module-components">Module Components</h2>
{% for componentGroup in doc.componentGroups %}
<div>
<h3 class="component-heading" id="{$ componentGroup.groupType | dashCase $}">{$ componentGroup.groupType | title $}</h3>
@@ -98,7 +98,7 @@
{% endif %}
{% if doc.usage %}
<h2>Usage</h2>
<h2 id="module-usage">Usage</h2>
{$ doc.usage | marked $}
{% endif %}
@@ -2,11 +2,11 @@
{% import "lib/deprecated.html" as x -%}
{%- if doc.events %}
<h2>Events</h2>
<h2 id="events">Events</h2>
<ul class="events">
{%- for event in doc.events %}
<li id="{$ event.name $}">
<h3>{$ event.name $}</h3>
<h3 id="event-{$ event.name $}">{$ event.name $}</h3>
<div>{$ event.description | marked $}</div>
{$ x.deprecatedBlock(event) $}
@@ -27,7 +27,7 @@
{% endif -%}
{%- if event.params %}
<section class="api-section">
<h3>Parameters</h3>
<h4>Parameters</h4>
{$ lib.paramTable(event.params) $}
</section>
{%- endif -%}
@@ -2,11 +2,11 @@
{% import "lib/deprecated.html" as x -%}
{%- if doc.methods %}
<h2>Methods</h2>
<h2 id="{$ doc.name $}-methods">Methods</h2>
<ul class="methods">
{%- for method in doc.methods %}
<li id="{$ method.name $}">
<h3>{$ lib.functionSyntax(method) $}</h3>
<li>
<h3 id="{$ method.name $}">{$ lib.functionSyntax(method) $}</h3>
<div>{$ method.description | marked $}</div>
{$ x.deprecatedBlock(method) $}
@@ -27,7 +27,7 @@
{% endif %}
{%- if method.examples %}
<h4 id="{$ doc.name $}.{$ method.name $}-examples">Examples</h4>
<h4 id="{$ doc.name $}.{$ method.name $}-examples">{$ "Examples" if method.examples | length > 1 else "Example" $}</h4>
{%- for example in method.examples -%}
{$ example | marked $}
{%- endfor -%}
@@ -1,7 +1,7 @@
{% import "lib/macros.html" as lib -%}
{%- if doc.params %}
<section class="api-section">
<h3>Arguments</h3>
<h3 id="{$ doc.name $}-arguments">Arguments</h3>
{$ lib.paramTable(doc.params) $}
</section>
{%- endif -%}
@@ -2,11 +2,11 @@
{% import "lib/deprecated.html" as x -%}
{%- if doc.properties %}
<h2>Properties</h2>
<h2 id="{$ doc.name $}-properties">Properties</h2>
<ul class="properties">
{%- for property in doc.properties %}
<li id="{$ property.name $}">
<h3>{$ property.name | code $}</h3>
<li>
<h3 id="{$ property.name $}">{$ property.name | code $}</h3>
{$ lib.typeInfo(property) $}
{$ x.deprecatedBlock(property) $}
</li>
@@ -1,5 +1,5 @@
{% import "lib/macros.html" as lib -%}
{% if doc.returns -%}
<h3>Returns</h3>
<h3 id="{$ doc.name $}-returns">Returns</h3>
{$ lib.typeInfo(doc.returns) $}
{%- endif %}
+5 -5
View File
@@ -11,14 +11,14 @@ These components are {@link guide/directive directives}, {@link guide/services s
There is also a {@link guide/index guide} with articles on various topics, and a list of external resources.
<div class="alert alert-info">
**Angular Prefixes `$` and `$$`**:
**AngularJS Prefixes `$` and `$$`**:
To prevent accidental name collisions with your code,
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
AngularJS prefixes names of public objects with `$` and names of private objects with `$$`.
Please do not use the `$` or `$$` prefix in your code.
</div>
## Angular Modules
## AngularJS Modules
## {@link ng ng (core module)}
@@ -83,7 +83,7 @@ This module is provided by default and contains the core components of AngularJS
</td>
<td>
<p>
The core global API functions are attached to the angular object. These core functions are useful for low level JavaScript operations within your application.
The core global API functions are attached to the `angular` object. These core functions are useful for low level JavaScript operations within your application.
</p>
<p>
Some examples include:
@@ -130,7 +130,7 @@ Use ngRoute to enable URL routing to your application. The ngRoute module suppor
## {@link ngAnimate ngAnimate}
Use ngAnimate to enable animation features within your application. Various core ng directives will provide
Use ngAnimate to enable animation features within your application. Various core AngularJS directives will provide
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
or JavaScript callbacks.
+1 -1
View File
@@ -5,7 +5,7 @@
This error occurs when the application's model becomes unstable because some `$onChanges` hooks are causing updates which then trigger
further calls to `$onChanges` that can never complete.
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
For example, the situation can occur by setting up a `$onChanges()` hook which triggers an event on the component, which subsequently
triggers the component's bound inputs to be updated:
+1 -1
View File
@@ -11,7 +11,7 @@ value is `JSON_CALLBACK`.
parameter is specified in the configuration object (or in the defaults) via the `jsonpCallbackParam`
property. You must not provide your own parameter with this name in the configuratio of the request.
In previous versions of Angular, you specified where to add the callback parameter value via the
In previous versions of AngularJS, you specified where to add the callback parameter value via the
`JSON_CALLBACK` placeholder. This is no longer allowed.
To resolve this error, remove any parameters that have the same name as the `jsonpCallbackParam`;
+1 -1
View File
@@ -15,7 +15,7 @@ In AngularJS `1.2.0` and later, `ngRoute` has been moved to its own module.
If you are getting this error after upgrading to `1.2.x` or later, be sure that you've
installed {@link ngRoute `ngRoute`}.
### Monkey-patching Angular's `ng` module
### Monkey-patching AngularJS's `ng` module
This error can also occur if you have tried to add your own components to the `ng` module.
This has never been supported and from `1.3.0` it will actually trigger this error.
@@ -3,4 +3,4 @@
@fullName Expecting end operator
@description
The Angular expression is missing the corresponding closing operator.
The AngularJS expression is missing the corresponding closing operator.
@@ -8,4 +8,4 @@ extension in your interpolation expression. The different choices have to be un
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -9,4 +9,4 @@ bug mentioning the exact version of AngularJS used and we will fix it!
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -14,4 +14,4 @@ future commit and the github issue will help gauge urgency.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
+2 -2
View File
@@ -4,9 +4,9 @@
@description
You must specify the MessageFormat function that you're using right after the
comma following the Angular expression. Currently, the supported functions are
comma following the AngularJS expression. Currently, the supported functions are
"plural" and "select" (for gender selections.)
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -8,4 +8,4 @@ extension keyword in the extended interpolation syntax.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -8,4 +8,4 @@ brace to mark the end of the message.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -9,4 +9,4 @@ braces.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -10,4 +10,4 @@ extensions require that you provide a message for the selection "other".
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -9,4 +9,4 @@ unsupported or invalid.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
+1 -1
View File
@@ -7,4 +7,4 @@ You have attempted to use a MessageFormat extension in your interpolation expres
Read more about secure contexts at {@link ng.$sce Strict Contextual Escaping
(SCE)} and about the MessageFormat extensions at {@link
guide/i18n#MessageFormat Angular i18n MessageFormat}.
guide/i18n#MessageFormat AngularJS i18n MessageFormat}.
@@ -3,4 +3,4 @@
@fullName Unterminated string literal
@description
The string literal was not terminated in your Angular expression.
The string literal was not terminated in your AngularJS expression.
+1 -1
View File
@@ -40,7 +40,7 @@ URL of the subcontext:
</head>
```
Before Angular 1.3 we didn't have this hard requirement and it was easy to write apps that worked
Before AngularJS 1.3 we didn't have this hard requirement and it was easy to write apps that worked
when deployed in the root context but were broken when moved to a sub-context because in the
sub-context all absolute urls would resolve to the root context of the app. To prevent this,
use relative URLs throughout your app:
+1 -1
View File
@@ -7,4 +7,4 @@ Occurs when an expression has a lexical error, for example a malformed number (0
The error message contains a more precise error.
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and fix the expression's syntax.
+1 -1
View File
@@ -6,4 +6,4 @@
Occurs when there is a syntax error in an expression. These errors are thrown while compiling the expression.
The error message contains a more precise description of the error, including the location (column) in the expression where the error occurred.
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and fix the expression's syntax.
+1 -1
View File
@@ -8,5 +8,5 @@ Occurs when an expression is missing tokens at the end of the expression.
For example, forgetting to close a bracket or failing to properly escape quotes in an expression
will trigger this error.
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and
fix the expression's syntax.
+2 -2
View File
@@ -4,7 +4,7 @@
@description
This error occurs when the application's model becomes unstable and each `$digest` cycle triggers a state change and subsequent `$digest` cycle.
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
For example, the situation can occur by setting up a watch on a path and subsequently updating the same path when the value changes.
@@ -26,7 +26,7 @@ $scope.getUsers = function() {
};
```
Since `getUsers()` returns a new array, Angular determines that the model is different on each `$digest`
Since `getUsers()` returns a new array, AngularJS determines that the model is different on each `$digest`
cycle, resulting in the error. The solution is to return the same array object if the elements have
not changed:
+16 -16
View File
@@ -10,17 +10,17 @@ the error.
## Background
Angular uses a dirty-checking digest mechanism to monitor and update values of the scope during
AngularJS uses a dirty-checking digest mechanism to monitor and update values of the scope during
the processing of your application. The digest works by checking all the values that are being
watched against their previous value and running any watch handlers that have been defined for those
values that have changed.
This digest mechanism is triggered by calling `$digest` on a scope object. Normally you do not need
to trigger a digest manually, because every external action that can trigger changes in your
application, such as mouse events, timeouts or server responses, wrap the Angular application code
application, such as mouse events, timeouts or server responses, wrap the AngularJS application code
in a block of code that will run `$digest` when the code completes.
You wrap Angular code in a block that will be followed by a `$digest` by calling `$apply` on a scope
You wrap AngularJS code in a block that will be followed by a `$digest` by calling `$apply` on a scope
object. So, in pseudo-code, the process looks like this:
```
@@ -45,20 +45,20 @@ $apply = function(fn) {
## Digest Phases
Angular keeps track of what phase of processing we are in, the relevant ones being `$apply` and
AngularJS keeps track of what phase of processing we are in, the relevant ones being `$apply` and
`$digest`. Trying to reenter a `$digest` or `$apply` while one of them is already in progress is
typically a sign of programming error that needs to be fixed. So Angular will throw this error when
typically a sign of programming error that needs to be fixed. So AngularJS will throw this error when
that occurs.
In most situations it should be well defined whether a piece of code will be run inside an `$apply`,
in which case you should not be calling `$apply` or `$digest`, or it will be run outside, in which
case you should wrap any code that will be interacting with Angular scope or services, in a call to
case you should wrap any code that will be interacting with AngularJS scope or services, in a call to
`$apply`.
As an example, all Controller code should expect to be run within Angular, so it should have no need
As an example, all Controller code should expect to be run within AngularJS, so it should have no need
to call `$apply` or `$digest`. Conversely, code that is being trigger directly as a call back to
some external event, from the DOM or 3rd party library, should expect that it is never called from
within Angular, and so any Angular application code that it calls should first be wrapped in a call
within AngularJS, and so any AngularJS application code that it calls should first be wrapped in a call
to $apply.
## Common Causes
@@ -84,8 +84,8 @@ function MyController($scope, thirdPartyComponent) {
}
```
We expect that our callback will be called asynchronously, and so from outside Angular. Therefore, we
correctly wrap our application code that interacts with Angular in a call to `$apply`.
We expect that our callback will be called asynchronously, and so from outside AngularJS. Therefore, we
correctly wrap our application code that interacts with AngularJS in a call to `$apply`.
The problem comes if `getData()` decides to call the callback handler synchronously; perhaps it has
the data already cached in memory and so it immediately calls the callback to return the data,
@@ -116,7 +116,7 @@ that the code will be called in a single `$apply` block.
### Triggering Events Programmatically
The other situation that often leads to this error is when you trigger code (such as a DOM event)
programmatically (from within Angular), which is normally called by an external trigger.
programmatically (from within AngularJS), which is normally called by an external trigger.
For example, consider a directive that will set focus on an input control when a value in the scope
is true:
@@ -161,7 +161,7 @@ In this second scenario, we are already inside a `$digest` when the ngFocus dire
call to `$apply()`, causing this error to be thrown.
It is possible to workaround this problem by moving the call to set the focus outside of the digest,
by using `$timeout(fn, 0, false)`, where the `false` value tells Angular not to wrap this `fn` in an
by using `$timeout(fn, 0, false)`, where the `false` value tells AngularJS not to wrap this `fn` in an
`$apply` block:
```
@@ -203,7 +203,7 @@ Once you have identified this call you work your way up the stack to see what th
called from within an `$apply`/`$digest`. It may be a simple oversight or maybe it fits with the
sync/async scenario described earlier.
* If the second call was made inside an Angular directive then it is likely that it matches the second
* If the second call was made inside an AngularJS directive then it is likely that it matches the second
programmatic event trigger scenario described earlier. In this case you may need to look further up
the tree to what triggered the event in the first place.
@@ -259,11 +259,11 @@ $get.g.$apply angular.js:12742 <--- $apply
q angular.js:320
```
We can see (even though the Angular code is minified) that there were two calls to `$apply`, first
We can see (even though the AngularJS code is minified) that there were two calls to `$apply`, first
on line `19833`, then on line `12738` of `angular.js`.
It is this second call that caused the error. If we look at the angular.js code, we can see that
this call is made by an Angular directive.
this call is made by an AngularJS directive.
```
var ngEventDirectives = {};
@@ -308,5 +308,5 @@ We can now see that the second `$apply` was caused by us programmatically trigge
`$timeout` as described above.
## Further Reading
To learn more about Angular processing model please check out the
To learn more about AngularJS processing model please check out the
{@link guide/concepts concepts doc} as well as the {@link ng.$rootScope.Scope api} doc.
+1 -1
View File
@@ -7,4 +7,4 @@ This error occurs when `$sanitize` sanitizer determines that `document.implement
This api is necessary for safe parsing of HTML strings into DOM trees and without it the sanitizer can't sanitize the input.
The api is present in all supported browsers including IE 9.0, so the presence of this error usually indicates that Angular's `$sanitize` is being used on an unsupported platform.
The api is present in all supported browsers including IE 9.0, so the presence of this error usually indicates that AngularJS's `$sanitize` is being used on an unsupported platform.
+2 -2
View File
@@ -5,10 +5,10 @@
AngularJS' {@link ng.$sce Strict Contextual Escaping (SCE)} mode (enabled by default) has blocked loading a resource from an insecure URL.
Typically, this would occur if you're attempting to load an Angular template from an untrusted source.
Typically, this would occur if you're attempting to load an AngularJS template from an untrusted source.
It's also possible that a custom directive threw this error for a similar reason.
Angular only loads templates from trusted URLs (by calling {@link ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl} on the template URL).
AngularJS only loads templates from trusted URLs (by calling {@link ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl} on the template URL).
By default, only URLs that belong to the same origin are trusted. These are urls with the same domain, protocol and port as the application document.
+2 -2
View File
@@ -5,10 +5,10 @@
The value provided for use in a specific context was not found to be safe/trusted for use.
Angular's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
AngularJS's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
(enabled by default), requires bindings in certain
contexts to result in a value that is trusted as safe for use in such a context. (e.g. loading an
Angular template from a URL requires that the URL is one considered safe for loading resources.)
AngularJS template from a URL requires that the URL is one considered safe for loading resources.)
This helps prevent XSS and other security issues. Read more at
{@link ng.$sce Strict Contextual Escaping (SCE)}
+6 -3
View File
@@ -3,9 +3,12 @@
@fullName Unsupported Selector Lookup
@description
In order to keep Angular small, Angular implements only a subset of the selectors in {@link angular.element#angular-s-jqlite jqLite}.
In order to keep AngularJS small, AngularJS implements only a subset of the selectors in
{@link angular.element#angularjs-s-jqlite jqLite}.
This error occurs when a jqLite instance is invoked with a selector other than this subset.
In order to resolve this error, rewrite your code to only use tag name selectors and manually traverse the DOM using the APIs provided by jqLite.
In order to resolve this error, rewrite your code to only use tag name selectors and manually
traverse the DOM using the APIs provided by jqLite.
Alternatively, you can include a full version of jQuery, which Angular will automatically use and that will make all selectors available.
Alternatively, you can include a full version of jQuery, which AngularJS will automatically use
and that will make all selectors available.
+2 -2
View File
@@ -3,7 +3,7 @@
@fullName Testability Not Found
@description
Angular's testability helper, getTestability, requires a root element to be
passed in. This helps differentiate between different Angular apps on the same
AngularJS's testability helper, getTestability, requires a root element to be
passed in. This helps differentiate between different AngularJS apps on the same
page. This error is thrown when no injector is found for root element. It is
often because the root element is outside of the ng-app.
+1 -1
View File
@@ -5,7 +5,7 @@
All date-related inputs like `<input type="date">` require the model to be a `Date` object.
If the model is something else, this error will be thrown.
Angular does not set validation errors on the `<input>` in this case
AngularJS does not set validation errors on the `<input>` in this case
as those errors are shown to the user, but the erroneous state was
caused by incorrect application logic and not by the user.
+1 -1
View File
@@ -7,7 +7,7 @@ The `input[number]` and `input[range]` directives require the model to be a `num
If the model is something else, this error will be thrown.
Angular does not set validation errors on the `<input>` in this case
AngularJS does not set validation errors on the `<input>` in this case
as this error is caused by incorrect application logic and not by bad input from the user.
If your model does not contain actual numbers then it is up to the application developer
+9 -9
View File
@@ -48,7 +48,7 @@ changes to `$location` are reflected into the browser address bar.
</tr>
<tr>
<td class="head">integration with angular application life-cycle</td>
<td class="head">integration with AngularJS application life-cycle</td>
<td>none</td>
<td>knows about all internal life-cycle phases, integrates with {@link ng.$rootScope.Scope#$watch $watch}, ...</td>
</tr>
@@ -224,7 +224,7 @@ facilitate the browser URL change and history management.
## Hashbang mode (default mode)
In this mode, `$location` uses Hashbang URLs in all browsers.
Angular also does not intercept and rewrite links in this mode. I.e. links work
AngularJS also does not intercept and rewrite links in this mode. I.e. links work
as expected and also perform full page reloads when other parts of the url
than the hash fragment was changed.
@@ -267,7 +267,7 @@ having to worry about whether the browser displaying your app supports the histo
- Opening a regular URL in a legacy browser -> redirects to a hashbang URL
- Opening hashbang URL in a modern browser -> rewrites to a regular URL
Note that in this mode, Angular intercepts all links (subject to the "Html link rewriting" rules below)
Note that in this mode, AngularJS intercepts all links (subject to the "Html link rewriting" rules below)
and updates the url in a way that never performs a full page reload.
@@ -363,7 +363,7 @@ Note that [attribute name normalization](guide/directive#normalization) does not
### Relative links
Be sure to check all relative links, images, scripts etc. Angular requires you to specify the url
Be sure to check all relative links, images, scripts etc. AngularJS requires you to specify the url
base in the head of your main html file (`<base href="/my-base/index.html">`) unless `html5Mode.requireBase`
is set to `false` in the html5Mode definition object passed to `$locationProvider.html5Mode()`. With
that, relative urls will always be resolved to this base url, even if the initial url of the
@@ -378,7 +378,7 @@ to anchors on the same page without needing to know on which page the user curre
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
to entry point of your application (e.g. index.html). Requiring a `<base>` tag is also important for
this case, as it allows Angular to differentiate between the part of the url that is the application
this case, as it allows AngularJS to differentiate between the part of the url that is the application
base and the path that should be handled by the application.
### Base href constraints
@@ -391,7 +391,7 @@ called `/base`). The URL `/base` is actually outside the application (it refers
in the root `/` folder).
If you wish to be able to navigate to the application via a URL such as `/base` then you should ensure that
you server is setup to redirect such requests to `/base/`.
your server is setup to redirect such requests to `/base/`.
See https://github.com/angular/angular.js/issues/14018 for more information.
@@ -728,14 +728,14 @@ use a lower level API, {@link ng.$window $window.location.href}.
## Using $location outside of the scope life-cycle
`$location` knows about Angular's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
`$location` knows about AngularJS's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
the browser it updates the `$location` and calls `$apply` so that all
{@link ng.$rootScope.Scope#$watch $watchers} /
{@link ng.$compile.directive.Attributes#$observe $observers} are notified.
When you change the `$location` inside the `$digest` phase everything is ok; `$location` will
propagate this change into browser and will notify all the {@link ng.$rootScope.Scope#$watch $watchers} /
{@link ng.$compile.directive.Attributes#$observe $observers}.
When you want to change the `$location` from outside Angular (for example, through a DOM Event or
When you want to change the `$location` from outside AngularJS (for example, through a DOM Event or
during testing) - you must call `$apply` to propagate the changes.
## $location.path() and ! or / prefixes
@@ -787,7 +787,7 @@ describe('serviceUnderTest', function() {
# Migrating from earlier AngularJS releases
In earlier releases of Angular, `$location` used `hashPath` or `hashSearch` to process path and
In earlier releases of AngularJS, `$location` used `hashPath` or `hashSearch` to process path and
search methods. With this release, the `$location` service processes path and search methods and
then uses the information it obtains to compose hashbang URLs (such as
`http://server.com/#!/path?search=a`), when necessary.
+4 -4
View File
@@ -6,7 +6,7 @@
# Accessibility with ngAria
The goal of ngAria is to improve Angular's default accessibility by enabling common
The goal of ngAria is to improve AngularJS's default accessibility by enabling common
[ARIA](http://www.w3.org/TR/wai-aria/) attributes that convey state or semantic information for
assistive technologies used by persons with disabilities.
@@ -109,11 +109,11 @@ attributes (if they have not been explicitly specified by the developer):
function isEmpty(value) {
return !value;
}
function render() {
elem[ctrl.$viewValue ? 'addClass' : 'removeClass']('checked');
}
function toggleCheckbox() {
ctrl.$setViewValue(!ctrl.$viewValue);
ctrl.$render();
@@ -420,7 +420,7 @@ tell ngAria to ignore the attribute globally.
## Common Accessibility Patterns
Accessibility best practices that apply to web apps in general also apply to Angular.
Accessibility best practices that apply to web apps in general also apply to AngularJS.
* **Text alternatives**: Add alternate text content to make visual information accessible using
[these W3C guidelines](http://www.w3.org/TR/html-alt-techniques/). The appropriate technique
+4 -4
View File
@@ -66,7 +66,7 @@ You may also want to setup a separate CSS file for defining CSS-based animations
## How they work
Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class
attached to a HTML element within your application, you can apply animations to it. Lets say for
attached to an HTML element within your application, you can apply animations to it. Let's say for
example that we have an HTML template with a repeater like so:
```html
@@ -232,8 +232,8 @@ triggered:
| {@link ng.directive:ngClass#animations ngClassEven / ngClassOdd} | add and remove |
| {@link ng.directive:ngHide#animations ngHide} | add and remove (the `ng-hide` class) |
| {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) |
| {@link ng.directive:ngModel#animation-hooks ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
| {@link ng.directive:form#animation-hooks form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
| {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
| {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
| {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) |
For a full breakdown of the steps involved during each animation event, refer to the
@@ -467,7 +467,7 @@ You can also use one of the other
strategies to disable animations}.
## Enable animations outside of the application DOM tree: {@link ng.$animate#pin $animate.pin()}
### Enable animations for elements outside of the AngularJS application DOM tree: {@link ng.$animate#pin $animate.pin()}
Before animating, `ngAnimate` checks if the animated element is inside the application DOM tree. If
not, no animation is run. Usually, this is not a problem since most apps use the `html` or `body`
+11 -11
View File
@@ -5,13 +5,13 @@
# Bootstrap
This page explains the Angular initialization process and how you can manually initialize Angular
This page explains the AngularJS initialization process and how you can manually initialize AngularJS
if necessary.
## Angular `<script>` Tag
## AngularJS `<script>` Tag
This example shows the recommended path for integrating Angular with what we call automatic
This example shows the recommended path for integrating AngularJS with what we call automatic
initialization.
@@ -35,7 +35,7 @@ initialization.
* Choose: `angular-[version].min.js` for a compressed and obfuscated file, suitable for use in
production.
2. Place `ng-app` to the root of your application, typically on the `<html>` tag if you want
angular to auto-bootstrap your application.
AngularJS to auto-bootstrap your application.
<html ng-app>
@@ -51,16 +51,16 @@ initialization.
<img class="pull-right" style="padding-left: 3em;" src="img/guide/concepts-startup.png">
Angular initializes automatically upon `DOMContentLoaded` event or when the `angular.js` script is
evaluated if at that time `document.readyState` is set to `'complete'`. At this point Angular looks
AngularJS initializes automatically upon `DOMContentLoaded` event or when the `angular.js` script is
evaluated if at that time `document.readyState` is set to `'complete'`. At this point AngularJS looks
for the {@link ng.directive:ngApp `ngApp`} directive which designates your application root.
If the {@link ng.directive:ngApp `ngApp`} directive is found then Angular will:
If the {@link ng.directive:ngApp `ngApp`} directive is found then AngularJS will:
* load the {@link guide/module module} associated with the directive.
* create the application {@link auto.$injector injector}
* compile the DOM treating the {@link ng.directive:ngApp
`ngApp`} directive as the root of the compilation. This allows you to tell it to treat only a
portion of the DOM as an Angular application.
portion of the DOM as an AngularJS application.
```html
@@ -96,9 +96,9 @@ for more.
If you need to have more control over the initialization process, you can use a manual
bootstrapping method instead. Examples of when you'd need to do this include using script loaders
or the need to perform an operation before Angular compiles a page.
or the need to perform an operation before AngularJS compiles a page.
Here is an example of manually initializing Angular:
Here is an example of manually initializing AngularJS:
```html
<!doctype html>
@@ -144,7 +144,7 @@ This is the sequence that your code should follow:
## Things to keep in mind
There a few things to keep in mind regardless of automatic or manual bootstrapping:
There are a few things to keep in mind regardless of automatic or manual bootstrapping:
- While it's possible to bootstrap more than one AngularJS application per page, we don't actively
test against this scenario. It's possible that you'll run into problems, especially with complex apps, so
+10 -10
View File
@@ -10,15 +10,15 @@
If you're just getting started, we recommend the {@link tutorial/ tutorial} first.
If you just want to create custom directives, we recommend the {@link guide/directive directives guide}.
If you want a deeper look into Angular's compilation process, you're in the right place.
If you want a deeper look into AngularJS's compilation process, you're in the right place.
</div>
## Overview
Angular's {@link ng.$compile HTML compiler} allows the developer to teach the
AngularJS's {@link ng.$compile HTML compiler} allows the developer to teach the
browser new HTML syntax. The compiler allows you to attach behavior to any HTML element or attribute
and even create new HTML elements or attributes with custom behavior. Angular calls these behavior
and even create new HTML elements or attributes with custom behavior. AngularJS calls these behavior
extensions {@link ng.$compileProvider#directive directives}.
HTML has a lot of constructs for formatting the HTML for static documents in a declarative fashion.
@@ -31,7 +31,7 @@ However, the declarative language is also limited, as it does not allow you to t
syntax. For example, there is no easy way to get the browser to align the text at 1/3 the position
instead of 1/2. What is needed is a way to teach the browser new HTML syntax.
Angular comes pre-bundled with common directives which are useful for building any app. We also
AngularJS comes pre-bundled with common directives which are useful for building any app. We also
expect that you will create directives that are specific to your app. These extensions become a
Domain Specific Language for building your application.
@@ -41,7 +41,7 @@ involved.
## Compiler
Compiler is an Angular service which traverses the DOM looking for attributes. The compilation
Compiler is an AngularJS service which traverses the DOM looking for attributes. The compilation
process happens in two phases.
1. **Compile:** traverse the DOM and collect all of the directives. The result is a linking
@@ -142,16 +142,16 @@ This means that any changes to the data need to be re-merged with the template a
3. managing the whole update process
4. lack of behavior expressiveness
Angular is different. The Angular compiler consumes the DOM, not string templates.
AngularJS is different. The AngularJS compiler consumes the DOM, not string templates.
The result is a linking function, which when combined with a scope model results in a live view. The
view and scope model bindings are transparent. The developer does not need to make any special calls to update
the view. And because `innerHTML` is not used, you won't accidentally clobber user input.
Furthermore, Angular directives can contain not just text bindings, but behavioral constructs as
Furthermore, AngularJS directives can contain not just text bindings, but behavioral constructs as
well.
<img src="img/Two_Way_Data_Binding.png">
The Angular approach produces a stable DOM. The DOM element instance bound to a model
The AngularJS approach produces a stable DOM. The DOM element instance bound to a model
item instance does not change for the lifetime of the binding. This means that the code can get
hold of the elements and register event handlers and know that the reference will not be destroyed
by template data merge.
@@ -160,7 +160,7 @@ by template data merge.
## How directives are compiled
It's important to note that Angular operates on DOM nodes rather than strings. Usually, you don't
It's important to note that AngularJS operates on DOM nodes rather than strings. Usually, you don't
notice this restriction because when a page loads, the web browser parses HTML into the DOM automatically.
HTML compilation happens in three phases:
@@ -186,7 +186,7 @@ The result of this is a live binding between the scope and the DOM. So at this p
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.
This should help give you an idea of what AngularJS does internally.
```js
var $compile = ...; // injected into your code
+34 -35
View File
@@ -10,11 +10,10 @@
We are investigating backporting the new Angular Router to AngularJS, but alternatively, use the {@link ngRoute} module or community developed projects (e.g. [ui-router](https://github.com/angular-ui/ui-router)).
</div>
This guide describes the new Component Router for AngularJS 1.5.
This guide describes the Component Router for AngularJS.
<div class="alert alert-info">
If you are looking for information about the default router for AngularJS have a look at the {@link ngRoute} module.
If you are looking for information about the Component Router for the new Angular then
check out the [Angular Router Guide](https://angular.io/docs/ts/latest/guide/router.html).
</div>
@@ -28,7 +27,7 @@ Here is a table of the main concepts used in the Component Router.
| Router | Displays the Routing Components for the active Route. Manages navigation from one component to the next. |
| RootRouter | The top level Router that interacts with the current URL location |
| RouteConfig | Configures a Router with RouteDefinitions, each mapping a URL path to a component. |
| Routing Component | An Angular component with a RouteConfig and an associated Router. |
| Routing Component | An AngularJS component with a RouteConfig and an associated Router. |
| RouteDefinition | Defines how the router should navigate to a component based on a URL pattern. |
| ngOutlet | The directive (`<ng-outlet>`) that marks where the router should display a view. |
| ngLink | The directive (`ng-link="..."`) for binding a clickable HTML element to a route, via a Link Parameters Array. |
@@ -138,7 +137,7 @@ The result is that we end up with a hierarchy of **Routing Components** rendered
![Component Hierarchy](img/guide/component-hierarchy.svg)
# Example Heroes App
## Example Heroes App
You can see the complete application running below.
@@ -459,12 +458,12 @@ You can see the complete application running below.
</example>
# Getting Started
### Getting Started
In the following sections we will step through building this application. The finished application has views
to display list and detail views of Heroes and Crises.
## Install the libraries
#### Install the libraries
It is easier to use [Yarn](https://yarnpkg.com) or [npm](https://www.npmjs.com) to install the
**Component Router** module. For this guide we will also install AngularJS itself via Yarn:
@@ -475,9 +474,9 @@ yarn add angular@1.5.x @angular/router@0.2.0
```
## Load the scripts
#### Load the scripts
Just like any Angular application, we load the JavaScript files into our `index.html`:
Just like any AngularJS application, we load the JavaScript files into our `index.html`:
```html
<script src="/node_modules/angular/angular.js"></script>
@@ -494,7 +493,7 @@ You also need to include ES6 shims for browsers that do not support ES6 code (In
<script src="https://unpkg.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
```
## Create the `app` module
#### Create the `app` module
In the app.js file, create the main application module `app` which depends on the `ngComponentRouter`
module, which is provided by the **Component Router** script.
@@ -528,7 +527,7 @@ Configure the top level routed `App` Component.
Create a very simple App Component to test that the application is working.
We are using the Angular 1.5 {@link $compileProvider#component `.component()`} helper method to create
We are using the AngularJS {@link $compileProvider#component `.component()`} helper method to create
all the **Components** in our application. It is perfectly suited to this task.
```js
@@ -547,9 +546,9 @@ must have a base URL.
...
```
## Bootstrap AngularJS
#### Bootstrap AngularJS
Bootstrap the Angular application and add the top level App Component.
Bootstrap the AngularJS application and add the top level App Component.
```html
<body ng-app="app">
@@ -559,7 +558,7 @@ Bootstrap the Angular application and add the top level App Component.
```
# Implementing the AppComponent
### Implementing the AppComponent
In the previous section we have created a single top level **App Component**. Let's now create some more
**Routing Components** and wire up **Route Config** for those. We start with a Heroes Feature, which
@@ -577,7 +576,7 @@ We are going to have a `Heroes` Component for the Heroes feature of our applicat
and `HeroDetail` **Components** that will actually display the two different views.
## App Component
#### App Component
Configure the **App Component** with a template and **Route Config**:
@@ -598,7 +597,7 @@ Configure the **App Component** with a template and **Route Config**:
The **App Component** has an `<ng-outlet>` directive in its template. This is where the child **Components**
of this view will be rendered.
### ngLink
#### ngLink
We have used the `ng-link` directive to create a link to navigate to the Heroes Component. By using this
directive we don't need to know what the actual URL will be. We can let the Router generate that for us.
@@ -607,7 +606,7 @@ We have included a link to the Crisis Center but have not included the `ng-link`
implemented the CrisisCenter component.
### Non-terminal Routes
#### Non-terminal Routes
We need to tell the **Router** that the `Heroes` **Route Definition** is **non-terminal**, that it should
continue to match **Routes** in its child **Components**. We do this by adding a **continuation ellipsis
@@ -616,16 +615,16 @@ Without the **continuation ellipsis** the `HeroList` **Route** will never be mat
stop at the `Heroes` **Routing Component** and not try to match the rest of the URL.
## Heroes Feature
### Heroes Feature
Now we can implement our Heroes Feature which consists of three **Components**: `Heroes`, `HeroList` and
`HeroDetail`. The `Heroes` **Routing Component** simply provides a template containing the {@link ngOutlet}
directive and a **Route Config** that defines a set of child **Routes** which delegate through to the
`HeroList` and `HeroDetail` **Components**.
## HeroesComponent
### HeroesComponent
Create a new file `heroes.js`, which defines a new Angular module for the **Components** of this feature
Create a new file `heroes.js`, which defines a new AngularJS module for the **Components** of this feature
and registers the Heroes **Component**.
```js
@@ -651,20 +650,20 @@ and also to add the module as a dependency of the `app` module:
angular.module('app', ['ngComponentRouter', 'heroes'])
```
### Use As Default
#### Use As Default
The `useAsDefault` property on the `HeroList` **Route Definition**, indicates that if no other **Route
Definition** matches the URL, then this **Route Definition** should be used by default.
### Route Parameters
#### Route Parameters
The `HeroDetail` Route has a named parameter (`id`), indicated by prefixing the URL segment with a colon,
as part of its `path` property. The **Router** will match anything in this segment and make that value
available to the HeroDetail **Component**.
### Terminal Routes
#### Terminal Routes
Both the Routes in the `HeroesComponent` are terminal, i.e. their routes do not end with `...`. This is
because the `HeroList` and `HeroDetail` will not contain any child routes.
### Route Names
#### Route Names
**What is the difference between the `name` and `component` properties on a Route Definition?**
The `component` property in a **Route Definition** defines the **Component** directive that will be rendered
@@ -676,7 +675,7 @@ The `name` property is used to reference the **Route Definition** when generatin
that has the `name` property of `"Heroes"`.
## HeroList Component
### HeroList Component
The HeroList **Component** is the first component in the application that actually contains significant
functionality. It loads up a list of heroes from a `heroService` and displays them using `ng-repeat`.
@@ -705,7 +704,7 @@ The template iterates through each `hero` object of the array in the `$ctrl.hero
the `$ctrl` property on the scope of the template.*
## HeroService
### HeroService
Our HeroService simulates requesting a list of heroes from a server. In a real application this would be
making an actual server request, perhaps over HTTP.
@@ -735,7 +734,7 @@ Note that both the `getHeroes()` and `getHero(id)` methods return a promise for
in real-life we would have to wait for the server to respond with the data.
## Router Lifecycle Hooks
### Router Lifecycle Hooks
**How do I know when my Component is active?**
@@ -780,7 +779,7 @@ By returning a promise for the list of heroes from `$routerOnActivate()` we can
Route until the heroes have arrived successfully. This is similar to how a `resolve` works in {@link ngRoute}.
## Route Parameters
### Route Parameters
**How do I access parameters for the current route?**
@@ -811,11 +810,11 @@ by the **Router**. In this code it is used to identify a specific Hero to retrie
This hero is then attached to the **Component** so that it can be accessed in the template.
## Access to the Current Router
### Access to the Current Router
**How do I get hold of the current router for my component?**
Each component has its own Router. Unlike in Angular 2, we cannot use the dependency injector to get hold of a component's Router.
Each component has its own Router. Unlike in the new Angular, we cannot use the dependency injector to get hold of a component's Router.
We can only inject the `$rootRouter`. Instead we use the fact that the `ng-outlet` directive binds the current router to a `$router`
attribute on our component.
@@ -882,7 +881,7 @@ Other options for generating this navigation are:
```
this form gives you the possibility of caching the instruction, but is more verbose.
### Absolute vs Relative Navigation
#### Absolute vs Relative Navigation
**Why not use `$rootRouter` to do the navigation?**
@@ -894,7 +893,7 @@ to the `HeroListComponent` with the `$rootRouter`, we would have to provide a co
`['App','Heroes','HeroList']`.
## Extra Parameters
### Extra Parameters
We can also pass additional optional parameters to routes, which get encoded into the URL and are again
available to the `$routerOnActivate(next, previous)` hook. If we pass the current `id` from the
@@ -936,7 +935,7 @@ Finally, we can use this information to highlight the current hero in the templa
</div>
```
## Crisis Center
### Crisis Center
Let's implement the Crisis Center feature, which displays a list if crises that need to be dealt with by a hero.
The detailed crisis view has an additional feature where it blocks you from navigating if you have not saved
@@ -951,7 +950,7 @@ changes to the crisis being edited.
![Crisis Detail View](img/guide/crisis-detail.png)
## Crisis Feature
### Crisis Feature
This feature is very similar to the Heroes feature. It contains the following **Components**:
@@ -962,7 +961,7 @@ This feature is very similar to the Heroes feature. It contains the following **
CrisisService and CrisisListComponent are basically the same as HeroService and HeroListComponent
respectively.
## Navigation Control Hooks
### Navigation Control Hooks
**How do I prevent navigation from occurring?**
@@ -979,7 +978,7 @@ can complete, all the **Components** must agree that they can be deactivated or
The **Router** will call the `$routerCanDeactivate` and `$canActivate` hooks, if they are provided. If any
of the hooks resolve to `false` then the navigation is cancelled.
### Dialog Box Service
#### Dialog Box Service
We can implement a very simple dialog box that will prompt the user whether they are happy to lose changes they
have made. The result of the prompt is a promise that can be used in a `$routerCanDeactivate` hook.
+11 -11
View File
@@ -5,17 +5,17 @@
# Understanding Components
In Angular, a Component is a special kind of {@link guide/directive directive} that uses a simpler
In AngularJS, a Component is a special kind of {@link guide/directive directive} that uses a simpler
configuration which is suitable for a component-based application structure.
This makes it easier to write an app in a way that's similar to using Web Components or using Angular
2's style of application architecture.
This makes it easier to write an app in a way that's similar to using Web Components or using the new Angular's
style of application architecture.
Advantages of Components:
- simpler configuration than plain directives
- promote sane defaults and best practices
- optimized for component-based architecture
- writing component directives will make it easier to upgrade to Angular 2
- writing component directives will make it easier to upgrade to Angular
When not to use Components:
@@ -25,7 +25,7 @@ When not to use Components:
## Creating and configuring a Component
Components can be registered using the `.component()` method of an Angular module (returned by {@link module `angular.module()`}). The method takes two arguments:
Components can be registered using the `.component()` method of an AngularJS module (returned by {@link module `angular.module()`}). The method takes two arguments:
* The name of the Component (as string).
* The Component config object. (Note that, unlike the `.directive()` method, this method does **not** take a factory function.)
@@ -90,14 +90,14 @@ a component-based architecture. But what makes a component beyond the options th
the component helper has?
- **Components only control their own View and Data:**
Components should never modify any data or DOM that is out of their own scope. Normally, in Angular
Components should never modify any data or DOM that is out of their own scope. Normally, in AngularJS
it is possible to modify data anywhere in the application through scope inheritance and watches. This
is practical, but can also lead to problems when it is not clear which part of the application is
responsible for modifying the data. That is why component directives use an isolate scope, so a whole
class of scope manipulation is not possible.
- **Components have a well-defined public API - Inputs and Outputs:**
However, scope isolation only goes so far, because Angular uses two-way binding. So if you pass
However, scope isolation only goes so far, because AngularJS uses two-way binding. So if you pass
an object to a component like this - `bindings: {item: '='}`, and modify one of its properties, the
change will be reflected in the parent component. For components however, only the component that owns
the data should modify it, to make it easy to reason about what data is changed, and when. For that reason,
@@ -158,7 +158,7 @@ of the component. The following hook methods can be implemented:
changes. Any actions that you wish to take in response to the changes that you detect must be
invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
be detected by AngularJS's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
if detecting changes, you must store the previous value(s) for comparison to the current values.
* `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
external resources, watches and event handlers.
@@ -167,8 +167,8 @@ of the component. The following hook methods can be implemented:
Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
they are waiting for their template to load asynchronously and their own compilation and linking has been
suspended until that occurs.
This hook can be considered analogous to the `ngAfterViewInit` and `ngAfterContentInit` hooks in Angular 2.
Since the compilation process is rather different in Angular 1 there is no direct mapping and care should
This hook can be considered analogous to the `ngAfterViewInit` and `ngAfterContentInit` hooks in Angular.
Since the compilation process is rather different in AngularJS there is no direct mapping and care should
be taken when upgrading.
By implementing these methods, your component can hook into its lifecycle.
@@ -445,7 +445,7 @@ angular.module('docsTabsExample', [])
</example>
# Unit-testing Component Controllers
## Unit-testing Component Controllers
The easiest way to unit-test a component controller is by using the
{@link ngMock.$componentController $componentController} that is included in {@link ngMock}. The
+22 -22
View File
@@ -54,20 +54,20 @@ Try out the Live Preview above, and then let's walk through the example and desc
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-databinding1.png">
This looks like normal HTML, with some new markup. In Angular, a file like this is called a
<a name="template">{@link templates template}</a>. When Angular starts your application, it parses and
This looks like normal HTML, with some new markup. In AngularJS, a file like this is called a
<a name="template">{@link templates template}</a>. When AngularJS starts your application, it parses and
processes this new markup from the template using the <a name="compiler">{@link compiler compiler}</a>.
The loaded, transformed and rendered DOM is then called the <a name="view"></a>*view*.
The first kind of new markup are the <a name="directive">{@link directive directives}</a>.
They apply special behavior to attributes or elements in the HTML. In the example above we use the
{@link 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 ng.directive:input `input`}
initializes our application. AngularJS also defines a directive for the {@link ng.directive:input `input`}
element that adds extra behavior to the element. The {@link ng.directive:ngModel `ng-model`} directive
stores/updates the value of the input field into/from a variable.
<div class="alert alert-info">
**Custom directives to access the DOM**: In Angular, the only place where an application should access the DOM is
**Custom directives to access the DOM**: In AngularJS, the only place where an application should access the DOM is
within directives. This is important because artifacts that access the DOM are hard to test.
If you need to access the DOM directly you should write a custom directive for this. The
{@link directive directives guide} explains how to do this.
@@ -76,12 +76,12 @@ stores/updates the value of the input field into/from a variable.
The second kind of new markup are the double curly braces `{{ expression | filter }}`:
When the compiler encounters this markup, it will replace it with the evaluated value of the markup.
An <a name="expression">{@link expression expression}</a> in a template is a JavaScript-like code snippet that allows
Angular to read and write variables. Note that those variables are not global variables.
AngularJS to read and write variables. Note that those variables are not global variables.
Just like variables in a JavaScript function live in a scope,
Angular provides a <a name="scope">{@link scope scope}</a> for the variables accessible to expressions.
AngularJS provides a <a name="scope">{@link scope scope}</a> for the variables accessible to expressions.
The values that are stored in variables on the scope are referred to as the <a name="model"></a>*model*
in the rest of the documentation.
Applied to the example above, the markup directs Angular to "take the data we got from the input widgets
Applied to the example above, the markup directs AngularJS to "take the data we got from the input widgets
and multiply them together".
The example above also contains a <a name="filter">{@link guide/filter filter}</a>.
@@ -89,7 +89,7 @@ A filter formats the value of an expression for display to the user.
In the example above, the filter {@link ng.filter:currency `currency`} formats a number
into an output that looks like money.
The important thing in the example is that Angular provides _live_ bindings:
The important thing in the example is that AngularJS provides _live_ bindings:
Whenever the input values change, the value of the expressions are automatically
recalculated and the DOM is updated with their values.
The concept behind this is <a name="databinding">{@link databinding two-way data binding}</a>.
@@ -157,9 +157,9 @@ expressions and directives.
Besides the new file that contains the controller code, we also added an
{@link ng.directive:ngController `ng-controller`} directive to the HTML.
This directive tells Angular that the new `InvoiceController` is responsible for the element with the directive
This directive tells AngularJS that the new `InvoiceController` is responsible for the element with the directive
and all of the element's children.
The syntax `InvoiceController as invoice` tells Angular to instantiate the controller
The syntax `InvoiceController as invoice` tells AngularJS to instantiate the controller
and save it in the variable `invoice` in the current scope.
We also changed all expressions in the page to read and write variables within that
@@ -260,22 +260,22 @@ get a hold of the now separated function?
This is where <a name="di">{@link di Dependency Injection}</a> comes into play.
Dependency Injection (DI) is a software design pattern that
deals with how objects and functions get created and how they get a hold of their dependencies.
Everything within Angular (directives, filters, controllers,
services, ...) is created and wired using dependency injection. Within Angular,
Everything within AngularJS (directives, filters, controllers,
services, ...) is created and wired using dependency injection. Within AngularJS,
the DI container is called the <a name="injector">{@link di injector}</a>.
To use DI, there needs to be a place where all the things that should work together are registered.
In Angular, this is the purpose of the <a name="module">{@link module modules}</a>.
When Angular starts, it will use the configuration of the module with the name defined by the `ng-app` directive,
In AngularJS, this is the purpose of the <a name="module">{@link module modules}</a>.
When AngularJS starts, it will use the configuration of the module with the name defined by the `ng-app` directive,
including the configuration of all modules that this module depends on.
In the example above:
The template contains the directive `ng-app="invoice2"`. This tells Angular
The template contains the directive `ng-app="invoice2"`. This tells AngularJS
to use the `invoice2` module as the main module for the application.
The code snippet `angular.module('invoice2', ['finance2'])` specifies that the `invoice2` module depends on the
`finance2` module. By this, Angular uses the `InvoiceController` as well as the `currencyConverter` service.
`finance2` module. By this, AngularJS uses the `InvoiceController` as well as the `currencyConverter` service.
Now that Angular knows of all the parts of the application, it needs to create them.
Now that AngularJS knows of all the parts of the application, it needs to create them.
In the previous section we saw that controllers are created using a constructor function.
For services, there are multiple ways to specify how they are created
(see the {@link services service guide}).
@@ -284,24 +284,24 @@ In the example above, we are using an anonymous function as the factory function
This function should return the `currencyConverter` service instance.
Back to the initial question: How does the `InvoiceController` get a reference to the `currencyConverter` function?
In Angular, this is done by simply defining arguments on the constructor function. With this, the injector
In AngularJS, this is done by simply defining arguments on the constructor function. With this, the injector
is able to create the objects in the right order and pass the previously created objects into the
factories of the objects that depend on them.
In our example, the `InvoiceController` has an argument named `currencyConverter`. By this, Angular knows about the
In our example, the `InvoiceController` has an argument named `currencyConverter`. By this, AngularJS knows about the
dependency between the controller and the service and calls the controller with the service instance as argument.
The last thing that changed in the example between the previous section and this section is that we
now pass an array to the `module.controller` function, instead of a plain function. The array first
contains the names of the service dependencies that the controller needs. The last entry
in the array is the controller constructor function.
Angular uses this array syntax to define the dependencies so that the DI also works after minifying
AngularJS uses this array syntax to define the dependencies so that the DI also works after minifying
the code, which will most probably rename the argument name of the controller constructor function
to something shorter like `a`.
## Accessing the backend
Let's finish our example by fetching the exchange rates from the [Fixer.io](http://fixer.io) exchange rate API.
The following example shows how this is done with Angular:
The following example shows how this is done with AngularJS:
<example name="guide-concepts-3" ng-app-included="true">
<file name="invoice3.js">
@@ -371,7 +371,7 @@ The following example shows how this is done with Angular:
What changed?
Our `currencyConverter` service of the `finance` module now uses the {@link ng.$http `$http`}, a
built-in service provided by Angular for accessing a server backend. `$http` is a wrapper around
built-in service provided by AngularJS for accessing a server backend. `$http` is a wrapper around
[`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
and [JSONP](http://en.wikipedia.org/wiki/JSONP) transports.
+33 -35
View File
@@ -5,16 +5,21 @@
# Understanding Controllers
In Angular, a Controller is defined by a JavaScript **constructor function** that is used to augment the
{@link scope Angular Scope}.
In AngularJS, a Controller is defined by a JavaScript **constructor function** that is used to augment the
{@link scope AngularJS Scope}.
When a Controller is attached to the DOM via the {@link ng.directive:ngController ng-controller}
directive, Angular will instantiate a new Controller object, using the specified Controller's
**constructor function**. A new **child scope** will be created and made available as an injectable
parameter to the Controller's constructor function as `$scope`.
Controllers can be attached to the DOM in different ways. For each of them, AngularJS will
instantiate a new Controller object, using the specified Controller's **constructor function**:
- the {@link ng.directive:ngController ngController} directive. A new **child scope** will be
created and made available as an injectable parameter to the Controller's constructor function
as `$scope`.
- a route controller in a {@link ngRoute.$routeProvider $route definition}.
- the controller of a {@link guide/directive regular directive}, or a
{@link guide/component component directive}.
If the controller has been attached using the `controller as` syntax then the controller instance will
be assigned to a property on the new scope.
be assigned to a property on the scope.
Use controllers to:
@@ -24,18 +29,27 @@ Use controllers to:
Do not use controllers to:
- Manipulate DOM — Controllers should contain only business logic.
Putting any presentation logic into Controllers significantly affects its testability. Angular
Putting any presentation logic into Controllers significantly affects its testability. AngularJS
has {@link databinding databinding} for most cases and {@link guide/directive directives} to
encapsulate manual DOM manipulation.
- Format input — Use {@link forms angular form controls} instead.
- Filter output — Use {@link guide/filter angular filters} instead.
- Share code or state across controllers — Use {@link services angular
- Format input — Use {@link forms AngularJS form controls} instead.
- Filter output — Use {@link guide/filter AngularJS filters} instead.
- Share code or state across controllers — Use {@link services AngularJS
services} instead.
- Manage the life-cycle of other components (for example, to create service instances).
In general, a Controller shouldn't try to do too much. It should contain only the business logic
needed for a single view.
The most common way to keep Controllers slim is by encapsulating work that doesn't belong to
controllers into services and then using these services in Controllers via dependency injection.
This is discussed in the {@link di Dependency Injection} and {@link services
Services} sections of this guide.
## Setting up the initial state of a `$scope` object
Typically, when you create an application you need to set up the initial state for the Angular
Typically, when you create an application you need to set up the initial state for the AngularJS
`$scope`. You set up the initial state of a scope by attaching properties to the `$scope` object.
The properties contain the **view model** (the model that will be presented by the view). All the
`$scope` properties will be available to the {@link templates template} at the point in the DOM where the Controller
@@ -52,13 +66,13 @@ myApp.controller('GreetingController', ['$scope', function($scope) {
}]);
```
We create an {@link module Angular Module}, `myApp`, for our application. Then we add the controller's
We create an {@link module AngularJS Module}, `myApp`, for our application. Then we add the controller's
constructor function to the module using the `.controller()` method. This keeps the controller's
constructor function out of the global scope.
<div class="alert alert-info">
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
of the Controller on the `$scope` service provided by AngularJS. See the guide on
{@link guide/di Dependency Injection} for more information.
</div>
@@ -88,7 +102,7 @@ myApp.controller('DoubleController', ['$scope', function($scope) {
}]);
```
Once the Controller has been attached to the DOM, the `double` method can be invoked in an Angular
Once the Controller has been attached to the DOM, the `double` method can be invoked in an AngularJS
expression in the template:
```js
@@ -99,29 +113,13 @@ expression in the template:
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
the scope are available in the template/view, and can be invoked via angular expressions
the scope are available in the template/view, and can be invoked via AngularJS expressions
and `ng` event handler directives (e.g. {@link ng.directive:ngClick ngClick}).
## Using Controllers Correctly
In general, a Controller shouldn't try to do too much. It should contain only the business logic
needed for a single view.
The most common way to keep Controllers slim is by encapsulating work that doesn't belong to
controllers into services and then using these services in Controllers via dependency injection.
This is discussed in the {@link di Dependency Injection} and {@link services
Services} sections of this guide.
# Associating Controllers with Angular Scope Objects
You can associate Controllers with scope objects implicitly via the {@link ng.directive:ngController ngController
directive} or {@link ngRoute.$route $route service}.
## Simple Spicy Controller Example
To illustrate further how Controller components work in Angular, let's create a little app with the
To illustrate further how Controller components work in AngularJS, let's create a little app with the
following components:
- A {@link templates template} with two buttons and a simple message
@@ -159,7 +157,7 @@ string "very". Depending on which button is clicked, the `spice` model is set to
Things to notice in the example above:
- The `ng-controller` directive is used to (implicitly) create a scope for our template, and the
- The `ngController` directive is used to (implicitly) create a scope for our template, and the
scope is augmented (managed) by the `SpicyController` Controller.
- `SpicyController` is just a plain JavaScript function. As an (optional) naming convention the name
starts with capital letter and ends with "Controller".
@@ -262,7 +260,7 @@ Inheritance works with methods in the same way as it does with properties. So in
examples, all of the properties could be replaced with methods that return string values.
# Testing Controllers
## Testing Controllers
Although there are many ways to test a Controller, one of the best conventions, shown below,
involves injecting the {@link ng.$rootScope $rootScope} and {@link ng.$controller $controller}:
+10 -10
View File
@@ -4,38 +4,38 @@
@description
Angular sets these CSS classes. It is up to your application to provide useful styling.
AngularJS sets these CSS classes. It is up to your application to provide useful styling.
# CSS classes used by angular
# CSS classes used by AngularJS
* `ng-scope`
- **Usage:** angular applies this class to any element for which a new {@link $rootScope scope}
- **Usage:** AngularJS applies this class to any element for which a new {@link $rootScope scope}
is defined. (see {@link guide/scope scope} guide for more information about scopes)
* `ng-isolate-scope`
- **Usage:** angular applies this class to any element for which a new
- **Usage:** AngularJS applies this class to any element for which a new
{@link guide/directive#isolating-the-scope-of-a-directive isolate scope} is defined.
* `ng-binding`
- **Usage:** angular applies this class to any element that is attached to a data binding, via `ng-bind` or
- **Usage:** AngularJS applies this class to any element that is attached to a data binding, via `ng-bind` or
`{{}}` curly braces, for example. (see {@link guide/databinding databinding} guide)
* `ng-invalid`, `ng-valid`
- **Usage:** angular applies this class to a form control widget element if that element's input does
- **Usage:** AngularJS applies this class to a form control widget element if that element's input does
not pass validation. (see {@link ng.directive:input input} directive)
* `ng-pristine`, `ng-dirty`
- **Usage:** angular {@link ng.directive:ngModel ngModel} directive applies `ng-pristine` class
- **Usage:** AngularJS {@link ng.directive:ngModel ngModel} directive applies `ng-pristine` class
to a new form control widget which did not have user interaction. Once the user interacts with
the form control, the class is changed to `ng-dirty`.
* `ng-touched`, `ng-untouched`
- **Usage:** angular {@link ng.directive:ngModel ngModel} directive applies `ng-untouched` class
- **Usage:** AngularJS {@link ng.directive:ngModel ngModel} directive applies `ng-untouched` class
to a new form control widget which has not been blurred. Once the user blurs the form control,
the class is changed to `ng-touched`.
## Related Topics
* {@link guide/templates Angular Templates}
* {@link guide/forms Angular Forms}
* {@link guide/templates AngularJS Templates}
* {@link guide/forms AngularJS Forms}
+6 -6
View File
@@ -5,8 +5,8 @@
# Data Binding
Data-binding in Angular apps is the automatic synchronization of data between the model and view
components. The way that Angular implements data-binding lets you treat the model as the
Data-binding in AngularJS apps is the automatic synchronization of data between the model and view
components. The way that AngularJS implements data-binding lets you treat the model as the
single-source-of-truth in your application. The view is a projection of the model at all times.
When the model changes, the view reflects the change, and vice versa.
@@ -19,10 +19,10 @@ or related sections of the view are NOT automatically reflected in the view. Wor
that the user makes to the view are not reflected in the model. This means that the developer has
to write code that constantly syncs the view with the model and the model with the view.
## Data Binding in Angular Templates
## Data Binding in AngularJS Templates
<img class="right" src="img/Two_Way_Data_Binding.png"/><br />
Angular templates work differently. First the template (which is the uncompiled HTML along with
AngularJS templates work differently. First the template (which is the uncompiled HTML along with
any additional markup or directives) is compiled on the browser. The compilation step produces a
live view. Any changes to the view are immediately reflected in the model, and any changes in
the model are propagated to the view. The model is the single-source-of-truth for the application
@@ -36,5 +36,5 @@ isolation without the view and the related DOM/browser dependency.
## Related Topics
* {@link scope Angular Scopes}
* {@link templates Angular Templates}
* {@link scope AngularJS Scopes}
* {@link templates AngularJS Templates}
+1 -1
View File
@@ -13,7 +13,7 @@
## What are decorators?
Decorators are a design pattern that is used to separate modification or *decoration* of a class without modifying the
original source code. In Angular, decorators are functions that allow a service, directive or filter to be modified
original source code. In AngularJS, decorators are functions that allow a service, directive or filter to be modified
prior to its usage.
## How to use decorators
+32 -24
View File
@@ -8,32 +8,40 @@
Dependency Injection (DI) is a software design pattern that deals with how components get hold of
their dependencies.
The Angular injector subsystem is in charge of creating components, resolving their dependencies,
The AngularJS injector subsystem is in charge of creating components, resolving their dependencies,
and providing them to other components as requested.
## Using Dependency Injection
DI is pervasive throughout Angular. You can use it when defining components or when providing `run`
and `config` blocks for a module.
Dependency Injection is pervasive throughout AngularJS. You can use it when defining components
or when providing `run` and `config` blocks for a module.
- Components such as services, directives, filters, and animations are defined by an injectable
factory method or constructor function. These components can be injected with "service" and "value"
components as dependencies.
- {@link angular.Module#service Services}, {@link angular.Module#directive directives},
{@link angular.Module#filter filters}, and {@link angular.Module#animation animations} are
defined by an injectable factory method or constructor function, and can be injected with
"services", "values", and "constants" as dependencies.
- Controllers are defined by a constructor function, which can be injected with any of the "service"
and "value" components as dependencies, but they can also be provided with special dependencies. See
{@link di#controllers Controllers} below for a list of these special dependencies.
- {@link ng.$controller Controllers} are defined by a constructor function, which can be injected
with any of the "service" and "value" as dependencies, but they can also be provided with
"special dependencies". See {@link di#controllers Controllers} below for a list of these
special dependencies.
- The `run` method accepts a function, which can be injected with "service", "value" and "constant"
components as dependencies. Note that you cannot inject "providers" into `run` blocks.
- The {@link angular.Module#run `run`} method accepts a function, which can be injected with
"services", "values" and, "constants" as dependencies. Note that you cannot inject "providers"
into `run` blocks.
- The `config` method accepts a function, which can be injected with "provider" and "constant"
components as dependencies. Note that you cannot inject "service" or "value" components into
configuration.
- The {@link angular.Module#config `config`} method accepts a function, which can be injected with
"providers" and "constants" as dependencies. Note that you cannot inject "services" or
"values" into configuration.
See {@link module#module-loading-dependencies Modules} for more details about `run` and `config`
blocks.
- The {@link angular.Module#provider `provider`} method can only be injected with other "providers".
However, only those that have been **registered beforehand** can be injected. This is different
from services, where the order of registration does not matter.
See {@link module#module-loading Modules} for more details about `run` and `config`
blocks and {@link guide/providers Providers} for more information about the different provider
types.
### Factory Methods
@@ -100,7 +108,7 @@ Moreover, additional dependencies are made available to Controllers:
## Dependency Annotation
Angular invokes certain functions (like service factories and controllers) via the injector.
AngularJS invokes certain functions (like service factories and controllers) via the injector.
You need to annotate these functions so that the injector knows what services to inject into
the function. There are three ways of annotating your code with service name information:
@@ -204,11 +212,11 @@ angular.module('myApp', [])
// $rootScope is implicitly injected
})
.run(['willBreak', function(willBreak) {
// Angular will throw when this runs
// AngularJS will throw when this runs
}]);
```
When the `willBreak` service is instantiated, Angular will throw an error because of strict mode.
When the `willBreak` service is instantiated, AngularJS will throw an error because of strict mode.
This is useful when using a tool like [ng-annotate](https://github.com/olov/ng-annotate) to
ensure that all of your application components have annotations.
@@ -225,7 +233,7 @@ angular.bootstrap(document, ['myApp'], {
## Why Dependency Injection?
This section motivates and explains Angular's use of DI. For how to use DI, see above.
This section motivates and explains AngularJS's use of DI. For how to use DI, see above.
For in-depth discussion about DI, see
[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) at Wikipedia,
@@ -264,7 +272,7 @@ code that constructs `SomeClass`.
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-module-injector.png">
To manage the responsibility of dependency creation, each Angular application has an {@link
To manage the responsibility of dependency creation, each AngularJS application has an {@link
angular.injector injector}. The injector is a
[service locator](http://en.wikipedia.org/wiki/Service_locator_pattern) that is responsible for
construction and lookup of dependencies.
@@ -290,7 +298,7 @@ myModule.factory('greeter', function($window) {
```
Create a new injector that can provide components defined in our `myModule` module and request our
`greeter` service from the injector. (This is usually done automatically by angular bootstrap).
`greeter` service from the injector. (This is usually done automatically by AngularJS bootstrap).
```js
var injector = angular.injector(['ng', 'myModule']);
@@ -317,7 +325,7 @@ function MyController($scope, greeter) {
}
```
When Angular compiles the HTML, it processes the `ng-controller` directive, which in turn
When AngularJS compiles the HTML, it processes the `ng-controller` directive, which in turn
asks the injector to create an instance of the controller and its dependencies.
```js
@@ -332,6 +340,6 @@ This is the best outcome. The application code simply declares the dependencies
having to deal with the injector. This setup does not break the Law of Demeter.
<div class="alert alert-info">
**Note:** Angular uses
**Note:** AngularJS uses
[**constructor injection**](http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/).
</div>
+10 -10
View File
@@ -24,9 +24,9 @@ name, comment or CSS class) that tell AngularJS's **HTML compiler** ({@link ng.$
to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform
the DOM element and its children.
Angular comes with a set of these directives built-in, like `ngBind`, `ngModel`, and `ngClass`.
Much like you create controllers and services, you can create your own directives for Angular to use.
When Angular {@link guide/bootstrap bootstraps} your application, the
AngularJS comes with a set of these directives built-in, like `ngBind`, `ngModel`, and `ngClass`.
Much like you create controllers and services, you can create your own directives for AngularJS to use.
When AngularJS {@link guide/bootstrap bootstraps} your application, the
{@link guide/compiler HTML compiler} traverses the DOM matching directives against the DOM elements.
<div class="alert alert-info">
@@ -41,7 +41,7 @@ mirrors the process of compiling source code in
## Matching Directives
Before we can write a directive, we need to know how Angular's {@link guide/compiler HTML compiler}
Before we can write a directive, we need to know how AngularJS's {@link guide/compiler HTML compiler}
determines when to use a given directive.
Similar to the terminology used when an [element **matches** a selector](https://developer.mozilla.org/en-US/docs/Web/API/Element.matches), we say an element **matches** a
@@ -67,7 +67,7 @@ And the following `<person>` element **matches** the `person` directive:
### Normalization
Angular **normalizes** an element's tag and attribute name to determine which elements match which
AngularJS **normalizes** an element's tag and attribute name to determine which elements match which
directives. We typically refer to directives by their case-sensitive
[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
@@ -178,7 +178,7 @@ and compilation process.
directive names. For instance, if you created a `<carousel>` directive, it would be problematic if HTML7
introduced the same element. A two or three letter prefix (e.g. `btfCarousel`) works well. Similarly, do
not prefix your own directives with `ng` or they might conflict with directives included in a future
version of Angular.
version of AngularJS.
</div>
For the following examples, we'll use the prefix `my` (e.g. `myCustomer`).
@@ -257,7 +257,7 @@ using `templateUrl` instead:
</example>
`templateUrl` can also be a function which returns the URL of an HTML template to be loaded and
used for the directive. Angular will call the `templateUrl` function with two parameters: the
used for the directive. AngularJS will call the `templateUrl` function with two parameters: the
element that the directive was called on, and an `attr` object associated with that element.
<div class="alert alert-warning">
@@ -544,7 +544,7 @@ directive logic will be put.
`link` takes a function with the following signature,
`function link(scope, element, attrs, controller, transcludeFn) { ... }`, where:
* `scope` is an Angular scope object.
* `scope` is an AngularJS scope object.
* `element` is the jqLite-wrapped element that this directive matches.
* `attrs` is a hash object with key-value pairs of normalized attribute names and their
corresponding attribute values.
@@ -614,7 +614,7 @@ function.
We register an event `element.on('$destroy', ...)`. What fires this `$destroy` event?
There are a few special events that AngularJS emits. When a DOM node that has been compiled
with Angular's compiler is destroyed, it emits a `$destroy` event. Similarly, when an AngularJS
with AngularJS's compiler is destroyed, it emits a `$destroy` event. Similarly, when an AngularJS
scope is destroyed, it broadcasts a `$destroy` event to listening scopes.
By listening to this event, you can remove event listeners that might cause memory leaks.
@@ -977,7 +977,7 @@ controllers using `require`.
Otherwise use `link`.
</div>
### Summary
## Summary
Here we've seen the main use cases for directives. Each of these samples acts as a good starting
point for creating your own directives.
+4 -4
View File
@@ -7,8 +7,8 @@
<div class="alert alert-danger">
**Note:** In the past, end-to-end testing could be done with a deprecated tool called
[Angular Scenario Runner](http://code.angularjs.org/1.2.16/docs/guide/e2e-testing). That tool
is now in maintenance mode.
[AngularJS Scenario Runner](http://code.angularjs.org/1.2.16/docs/guide/e2e-testing). That tool
is now in maintenance mode, and will be removed in version 1.7.0.
</div>
As applications grow in size and complexity, it becomes unrealistic to rely on manual testing to
@@ -19,7 +19,7 @@ these problems.
We have built [Protractor](https://github.com/angular/protractor), an end
to end test runner which simulates user interactions that will help you verify the health of your
Angular application.
AngularJS application.
## Using Protractor
@@ -76,7 +76,7 @@ filter the list of items.
## Example
See the [angular-seed](https://github.com/angular/angular-seed) project for more examples, or look
at the embedded examples in the Angular documentation (For example, {@link $http $http}
at the embedded examples in the AngularJS documentation (For example, {@link $http $http}
has an end-to-end test in the example under the `protractor.js` tag).
## Caveats
+17 -16
View File
@@ -3,13 +3,13 @@
@sortOrder 270
@description
# Angular Expressions
# AngularJS Expressions
Angular expressions are JavaScript-like code snippets that are mainly placed in
AngularJS expressions are JavaScript-like code snippets that are mainly placed in
interpolation bindings such as `<span title="{{ attrBinding }}">{{ textBinding }}</span>`,
but also used directly in directive attributes such as `ng-click="functionExpression()"`.
For example, these are valid expressions in Angular:
For example, these are valid expressions in AngularJS:
* `1+2`
* `a+b`
@@ -17,37 +17,38 @@ For example, these are valid expressions in Angular:
* `items[index]`
## Angular Expressions vs. JavaScript Expressions
## AngularJS Expressions vs. JavaScript Expressions
Angular expressions are like JavaScript expressions with the following differences:
AngularJS expressions are like JavaScript expressions with the following differences:
* **Context:** JavaScript expressions are evaluated against the global `window`.
In Angular, expressions are evaluated against a {@link ng.$rootScope.Scope `scope`} object.
In AngularJS, expressions are evaluated against a {@link ng.$rootScope.Scope `scope`} object.
* **Forgiving:** In JavaScript, trying to evaluate undefined properties generates `ReferenceError`
or `TypeError`. In Angular, expression evaluation is forgiving to `undefined` and `null`.
or `TypeError`. In AngularJS, expression evaluation is forgiving to `undefined` and `null`.
* **Filters:** You can use {@link guide/filter filters} within expressions to format data before
displaying it.
* **No Control Flow Statements:** You cannot use the following in an Angular expression:
* **No Control Flow Statements:** You cannot use the following in an AngularJS expression:
conditionals, loops, or exceptions.
* **No Function Declarations:** You cannot declare functions in an Angular expression,
* **No Function Declarations:** You cannot declare functions in an AngularJS expression,
even inside `ng-init` directive.
* **No RegExp Creation With Literal Notation:** You cannot create regular expressions
in an Angular expression.
in an AngularJS expression. An exception to this rule is {@link ngPattern `ng-pattern`} which
accepts valid RegExp.
* **No Object Creation With New Operator:** You cannot use `new` operator in an Angular expression.
* **No Object Creation With New Operator:** You cannot use `new` operator in an AngularJS expression.
* **No Bitwise, Comma, And Void Operators:** You cannot use
[Bitwise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators),
`,` or `void` operators in an Angular expression.
`,` or `void` operators in an AngularJS expression.
If you want to run more complex JavaScript code, you should make it a controller method and call
the method from your view. If you want to `eval()` an Angular expression yourself, use the
the method from your view. If you want to `eval()` an AngularJS expression yourself, use the
{@link ng.$rootScope.Scope#$eval `$eval()`} method.
## Example
@@ -110,10 +111,10 @@ You can try evaluating different expressions here:
## Context
Angular does not use JavaScript's `eval()` to evaluate expressions. Instead Angular's
AngularJS does not use JavaScript's `eval()` to evaluate expressions. Instead AngularJS's
{@link ng.$parse $parse} service processes these expressions.
Angular expressions do not have direct access to global variables like `window`, `document` or `location`.
AngularJS expressions do not have direct access to global variables like `window`, `document` or `location`.
This restriction is intentional. It prevents accidental access to the global state a common source of subtle bugs.
Instead use services like `$window` and `$location` in functions on controllers, which are then called from expressions.
@@ -180,7 +181,7 @@ Similarly, invoking a function `a.b.c()` on `undefined` or `null` simply returns
## No Control Flow Statements
Apart from the ternary operator (`a ? b : c`), you cannot write a control flow statement in an
expression. The reason behind this is core to the Angular philosophy that application logic should
expression. The reason behind this is core to the AngularJS philosophy that application logic should
be in controllers, not the views. If you need a real conditional, loop, or to throw from a view
expression, delegate to a JavaScript method instead.
+14 -14
View File
@@ -3,9 +3,9 @@
@sortOrder 150
@description
# External Angular 1 Resources
# External AngularJS Resources
This is a collection of external, 3rd party resources for learning and developing Angular.
This is a collection of external, 3rd party resources for learning and developing AngularJS.
## Articles, Videos, and Projects
@@ -21,7 +21,7 @@ This is a collection of external, 3rd party resources for learning and developin
#### Application Structure & Style Guides
* [Angular Styleguide](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md)
* [AngularJS Styleguide](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md)
* [Architecture, file structure, components, one-way dataflow and best practices](https://github.com/toddmotto/angular-styleguide)
* [When to use directives, controllers or services](http://kirkbushell.me/when-to-use-directives-controllers-or-services-in-angular/)
* [Service vs Factory](http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html)
@@ -32,8 +32,8 @@ This is a collection of external, 3rd party resources for learning and developin
#### Mobile
* [Angular on Mobile Guide](http://www.ng-newsletter.com/posts/angular-on-mobile.html)
* [Angular and Cordova](http://devgirl.org/2013/06/10/quick-start-guide-phonegap-and-angularjs/)
* [AngularJS on Mobile Guide](http://www.ng-newsletter.com/posts/angular-on-mobile.html)
* [AngularJS and Cordova](http://devgirl.org/2013/06/10/quick-start-guide-phonegap-and-angularjs/)
* [Ionic Framework](http://ionicframework.com/)
#### Deployment
@@ -48,7 +48,7 @@ This is a collection of external, 3rd party resources for learning and developin
* **Django:** [Tutorial](http://blog.mourafiq.com/post/55034504632/end-to-end-web-app-with-django-rest-framework), [Integrating AngularJS with Django](http://django-angular.readthedocs.org/en/latest/integration.html), [Getting Started with Django Rest Framework and AngularJS](http://blog.kevinastone.com/getting-started-with-django-rest-framework-and-angularjs.html)
* **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/developers/articles/angularjs-cloud-endpoints-recipe-for-building-modern-web-applications/), [with Go](https://github.com/GoogleCloudPlatform/appengine-angular-gotodos)
* **Google Cloud Platform:** [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)
* **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)
@@ -75,12 +75,12 @@ This is a collection of external, 3rd party resources for learning and developin
* **Getting Started:** [Comparison of the options for starting a new project](http://www.dancancro.com/comparison-of-angularjs-application-starters/)
* **Debugging:** [Batarang](https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en)
* **Editor support:** [Webstorm](http://plugins.jetbrains.com/plugin/6971) (and [video](http://www.youtube.com/watch?v=LJOyrSh1kDU)), [Sublime Text](https://github.com/angular-ui/AngularJS-sublime-package), [Visual Studio](http://madskristensen.net/post/angularjs-intellisense-in-visual-studio-2012), [Atom](https://github.com/angular-ui/AngularJS-Atom), [Vim](https://github.com/burnettk/vim-angular)
* **Workflow:** [Yeoman.io](https://github.com/yeoman/generator-angular) and [Angular Yeoman Tutorial](http://www.sitepoint.com/kickstart-your-angularjs-development-with-yeoman-grunt-and-bower/)
* **Workflow:** [Yeoman.io](https://github.com/yeoman/generator-angular) and [AngularJS Yeoman Tutorial](http://www.sitepoint.com/kickstart-your-angularjs-development-with-yeoman-grunt-and-bower/)
## Complementary Libraries
This is a list of libraries that enhance Angular, add common UI components or integrate with other libraries.
You can find a larger list of Angular external libraries at [ngmodules.org](http://ngmodules.org/).
This is a list of libraries that enhance AngularJS, add common UI components or integrate with other libraries.
You can find a larger list of AngularJS external libraries at [ngmodules.org](http://ngmodules.org/).
* **Advanced Routing:** [UI-Router](https://github.com/angular-ui/ui-router)
* **Authentication:** [Http Auth Interceptor](https://github.com/witoldsz/angular-http-auth)
@@ -98,21 +98,21 @@ You can find a larger list of Angular external libraries at [ngmodules.org](http
- Data Modeling [JS-Data-Angular](https://github.com/js-data/js-data-angular)
* **Fileupload:**
- [ng-file-upload](https://github.com/danialfarid/ng-file-upload)
- [blueimp-fileupload for Angular](https://blueimp.github.io/jQuery-File-Upload/angularjs.html)
- [blueimp-fileupload for AngularJS](https://blueimp.github.io/jQuery-File-Upload/angularjs.html)
* **General UI Libraries:**
- [Angular Material](https://material.angularjs.org/latest/)
- [Angular UI Bootstrap](http://angular-ui.github.io/)
- [AngularJS Material](https://material.angularjs.org/latest/)
- [AngularJS UI Bootstrap](http://angular-ui.github.io/)
- [AngularStrap for Bootstrap 3](http://mgcrea.github.io/angular-strap/)
- [KendoUI](http://kendo-labs.github.io/angular-kendo/#/)
- [Wijmo](http://wijmo.com/tag/angularjs-2/)
* **Specific UI Elements:**
- [ngInfiniteScroll](https://sroze.github.io/ngInfiniteScroll/)
- [ngTable](https://github.com/esvit/ng-table)
- [Angular UI Grid](http://angular-ui.github.io/grid)
- [AngularJS UI Grid](http://angular-ui.github.io/grid)
- [Toaster Notifications](https://github.com/jirikavi/AngularJS-Toaster)
- [textAngular Rich Text Editor / contenteditable](http://textangular.com/) (Rich Text Editor /
binding to contenteditable)
- [Angular UI Map (Google Maps)](https://github.com/angular-ui/ui-map)
- [AngularJS UI Map (Google Maps)](https://github.com/angular-ui/ui-map)
## General Learning Resources
+5 -5
View File
@@ -6,7 +6,7 @@
# Filters
Filters format the value of an expression for display to the user. They can be used in view
templates, controllers or services. Angular comes with a collection of
templates, controllers or services. AngularJS comes with a collection of
[built-in filters](api/ng/filter), but it is easy to define your own as well.
The underlying API is the {@link ng.$filterProvider}.
@@ -44,7 +44,7 @@ as inputs. Filters that receive [Objects](https://developer.mozilla.org/en-US/do
as input are executed on each `$digest`, as it would be too costly to track if the inputs have changed.
2. Filters that are marked as `$stateful` are also executed on each $digest.
See {@link guide/filter#stateful-filters Stateful filters} for more information. Note that no Angular
See {@link guide/filter#stateful-filters Stateful filters} for more information. Note that no AngularJS
core filters are $stateful.
@@ -110,12 +110,12 @@ function.
The filter function should be a [pure function](http://en.wikipedia.org/wiki/Pure_function), which
means that it should always return the same result given the same input arguments and should not affect
external state, for example, other Angular services. Angular relies on this contract and will by default
external state, for example, other AngularJS services. AngularJS relies on this contract and will by default
execute a filter only when the inputs to the function change.
{@link guide/filter#stateful-filters Stateful filters} are possible, but less performant.
<div class="alert alert-warning">
**Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
**Note:** Filter names must be valid AngularJS {@link expression} identifiers, such as `uppercase` or `orderBy`.
Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
(`myapp_subsection_filterx`).
@@ -162,7 +162,7 @@ text upper-case.
### Stateful filters
It is strongly discouraged to write filters that are stateful, because the execution of those can't
be optimized by Angular, which often leads to performance issues. Many stateful filters can be
be optimized by AngularJS, which often leads to performance issues. Many stateful filters can be
converted into stateless filters just by exposing the hidden state as a model and turning it into an
argument for the filter.

Some files were not shown because too many files have changed in this diff Show More