Compare commits

...

1037 Commits

Author SHA1 Message Date
Peter Bacon Darwin 22b669407c docs(CHANGELOG.md): add release notes for v1.5.8 2016-07-22 16:01:46 +01:00
Georgios Kalpakas 99a063f9cb docs(CHANGELOG.md): add release notes for v1.2.30 2016-07-22 15:45:08 +01:00
Georgios Kalpakas 27db9f018e test($anchorScroll): add e2e tests
Fixes #9535
Closes #9583

Closes #14932
2016-07-20 11:45:09 +03:00
Brad 2ed2399d49 docs($httpParamSerializer): fix typo (remove superfluous quote)
Closes #14934
2016-07-20 10:48:32 +03:00
Georgios Kalpakas 9d2de344f5 refactor($http): clean up code
Closes #14921
2016-07-19 23:25:11 +03:00
Georgios Kalpakas 9c0659ca27 refactor($http): move functions together and order alphabetically
Closes #14921
2016-07-19 23:10:39 +03:00
Georgios Kalpakas 3b9963c54a refactor(test/e2e): make file/directory names consistent 2016-07-19 21:46:34 +03:00
Georgios Kalpakas 26db937377 test($resource): add some tests wrt handling response errors
The test currently fail on master, but should pass on 1.5.x.
A subsequent commit will fix the regressions on master.

(This commit should be backportable to 1.5.x.)

Related to #14837.
2016-07-18 14:55:55 +01:00
Georgios Kalpakas 1d0e582b3f chore(protractor): use directConnect locally to speed up tests
Closes #14919
2016-07-18 10:03:41 +01:00
Georgios Kalpakas a6b58019e1 refactor(test/e2e): remove explicit call to waitForAngular()
Protractor automatically calls `waitForAngular()`, before every WebDriver action.

Closes #14920
2016-07-18 10:03:40 +01:00
Georgios Kalpakas 38fd896b74 refactor(test/e2e): restore consistency across tests (just because) 2016-07-18 10:03:40 +01:00
Georgios Kalpakas f96d553822 docs(guide): fix links to tutorial steps 2016-07-15 20:07:10 +03:00
John (J5) Palmieri f4149b70bc doc(guide/Animations): point to $animate.pin() to enable animation for elements outside an Angular app
Add a section inside of the ngAnimate documentation to point to $animate.pin().
It was not clear in the documentation why animations were being disabled inside of
modals and popup menus. This documentation explains in what situations elements may
be dynamically placed outside of the application DOM and points to the API documentation
on how to enable animations for these types of elements.

Related #14907
Closes #14918
2016-07-15 18:07:37 +02:00
Martin Staffa 8a8c94c3d5 docs(ngSelected): note that it doesn't interact with ngModel
Related #14916
Related #14876
2016-07-15 17:49:22 +02:00
Michał Gołębiowski d9de526059 test(jQuery): Run tests with jQuery 3
(cherry-picked from 859b1e300c)

Closes #14874
2016-07-13 10:13:58 +02:00
Georgios Kalpakas 0318761f7a refactor($animate): avoid unnecessary lookup
Closes #14902
2016-07-12 22:32:38 +03:00
Ronan Connolly 74f7b57823 docs(guide/unit-testing): add missing heading
Closes #14901
2016-07-12 18:31:30 +03:00
Steve Berube 995ccfc9f6 docs(guide/animations): use the arguments of enabled() in correct order
Closes #14900
2016-07-12 17:52:05 +03:00
Georgios Kalpakas 72c244564a chore(Jenkins): fix e2e tests on Jenkins
Follow-up to c72e13f and a82a8a5.

Closes #14889
2016-07-11 13:37:43 +03:00
Georgios Kalpakas 4bfe7e8663 docs(guide/module): remove newline in the middle of sentence 2016-07-10 14:13:33 +03:00
Oliver Salzburg 63fe144397 docs($http): fix default $http cache name
The name of the cache is the string "$http", not the symbol itself.

Closes #14885
2016-07-09 10:23:30 +03:00
Martin Staffa 0f551e6109 chore(protractor): use jasmine2 as framework 2016-07-08 11:30:10 +02:00
Martin Staffa 541f4ba21f chore(package.json): update jasmine-reporters to 2.2.0 2016-07-08 11:30:08 +02:00
Georgios Kalpakas 6e7d04ddb2 docs(guide/component): improve tests
Fixes #14739
2016-07-06 13:40:47 +03:00
Jack 06fb391687 docs(guide/directive): remove confusing best practice
Prior to this point, the docs do not mention returning a postLink function, and all the examples use
the definition object form. So, this message is confusing to new readers who may misinterpret
"returning a function" as returning the factory function mentioned in the previous section.

Since this page is only a "gentle introduction" to directives, and using the definition object is a
best practice, it is best to just remove the message altogether.

Closes #14871
2016-07-06 12:07:15 +03:00
Georgios Kalpakas 203dd4d1e3 docs(tutorial): fix typo in images (phoneList --> phoneDetail)
Fixes #14858

Closes #14868
2016-07-05 21:52:37 +03:00
Georgios Kalpakas c991f93817 docs(guide/interpolation): add known issue (do not change the content of interpolated strings)
Closes #12813

Closes #14825
2016-07-05 00:11:26 +03:00
Peter Bacon Darwin 52ddc13bee chore(package.json): update dgeni-packages dependency to 0.14.0 2016-07-04 21:31:47 +01:00
Igor Zhukov 1645924d49 fix(copy): fix handling of typed subarrays
Previously, it would return a copy of the whole original typed array, not its slice.
Now, the `byteOffset` and `length` are also preserved.

Fixes #14842

Closes #14845
2016-07-04 23:24:16 +03:00
Georgios Kalpakas 6bee655679 docs(copy): mention ignoring non-enumerable properties
This also improves the example a bit:
- better code formatting
- initialization of `form` to an empty object
- avoid using `email`, which doesn't get coppied when invalid (and might confuse users)

Fixes #14853
2016-07-04 10:16:08 +03:00
David Rodenas Pico acd455181d perf($compile): wrap try/catch of collect comment directives into a function to avoid V8 deopt
Closes #14848
2016-07-04 08:56:52 +03:00
jfisher446 a89b6e27a9 docs(tutorial/step_04): fix syntactic error (add missing 'a')
Closes #14860
2016-07-04 08:43:16 +03:00
mmuppa 46d559dc8d docs(misc/Develop): using https:// works more widely than git@
Closes #14838
2016-07-01 11:18:33 +01:00
Peter Bacon Darwin 26212fb204 docs(guide): tweaks to the index and external resources guides
Closes #14843
2016-07-01 11:18:33 +01:00
Martin Staffa 244cfc7cd5 docs(guide): create new page for external resources
The official and external resources  have been split into two different guide sections. Official stays at the index, external gets its own page.

The external resources have also been reorganized and updated, but
I haven't checked if all material is still relevant.
2016-07-01 11:18:33 +01:00
Jeff Andrews c6074dc34c fix(ngMocks): allow ErrorAddingDeclarationLocationStack to be recognized as an Error
Change `ErrorAddingDeclarationLocationStack`'s prototype so test frameworks (such as Jasmine 2.x)
are able to recognize it as `Error`.

Fixes #13821

Closes #14344
2016-06-29 13:44:45 +03:00
atenhar 4930ef2bfe docs(tutorial/step_03): fix grammar and typos
Closes #14834
2016-06-28 11:08:41 +03:00
Georgios Kalpakas 1778d347cd fix($jsonpCallbacks): do not overwrite callbacks added by other apps
Closes #14824
2016-06-27 15:18:40 +03:00
Georgios Kalpakas 4724d56c93 fix($injector): fix class detection RegExp
Mentioned in https://github.com/angular/angular.js/pull/14531#discussion_r61410683.

Closes #14533
2016-06-27 13:35:50 +03:00
Georgios Kalpakas 70fcffc375 test($resource): make test for function as param more explicit
Related to aa8d783.

Closes #14820
2016-06-27 11:54:29 +03:00
Georgios Kalpakas 181e44019e fix($animate): do not get affected by custom, enumerable properties on Object.prototype
Fixes #14804

Closes #14830
2016-06-27 11:50:31 +03:00
Liran Tal 5ce859bcdd docs(guide/filter): add link to list of built-in filters
Closes #14828
2016-06-26 20:28:40 +03:00
Deplay fb994e4d90 refactor(jqLite): remove unused code in jqLiteBuildFragment()
Closes #14822
2016-06-25 22:09:43 +03:00
GARCIA Guillaume 55f26fc246 docs(*): correct bower version separator (@ --> #)
Closes #14819
2016-06-25 21:56:58 +03:00
Martin Staffa 1161002857 docs(ngReadonly): note input type restrictions
Closes #14816
2016-06-23 12:02:01 +02:00
Martin Staffa 7ccfe92bed fix(ngAnimate): allow removal of class that is scheduled to be added with requestAnimationFrame
Also affects the reverse case, adding a class that is scheduled to be removed with rAF.

The following case can happen when ngClass updates an element's classes in very quick order in the following way:

- First animation adds class "a"
- A digest passes, but "a" is not yet added to the element
- Second animation adds class "b"
- No digest passes, and "a" is still not added to the element,
  because requestAnimationFrame hasn't been flushed yet
- Third animation removes class "a"
- the third animation gets merged into the second animation

Before this change:

- Because the element doesn't have class "a" yet, ngAnimate
resolves that it cannot remove class "a". However,
the first animation is still running, and finally adds "a"

After this change:

- ngAnimate reacts to the temporary class "add-a", which indicates
that "a" is about to be added and decides that "a" can be removed
after all.

This is a very rare case where setting the element's class
is not fast enough, and subsequent animations operate on incorrect assumptions.

"In the wild", this is caused by rapidly updating ngClass,
which uses inidvidual addClass and removeClass calls when both operations happen in a single digest.

Fixes #14582
PR  (#14760)
2016-06-23 12:01:57 +02:00
Chirayu Krishnappa a126fcfee3 feat($resource): pass the resource to a dynamic param functions
Closes #4899
2016-06-22 12:22:16 +01:00
Peter Bacon Darwin f22af2b874 docs($http): fix a dangling link 2016-06-22 11:19:22 +01:00
Peter Bacon Darwin 2ca4170903 docs($compile): reorganize the life-cycle hooks docs
Closes #14811
2016-06-22 11:19:21 +01:00
Peter Bacon Darwin fd57df1235 docs($compile): add additional runnable examples for the $doCheck hook
Closes #14811
2016-06-22 11:19:21 +01:00
Peter Bacon Darwin 3010ed4ee5 fix($compile): ensure $doCheck hooks can be defined in the controller constructor
Closes #14811
2016-06-22 11:19:21 +01:00
Zach Bjornson de59ca7107 feat($compile): backport $doCheck
Backuport ngDoCheck from Angular 2.

Closes #14656
2016-06-22 11:19:21 +01:00
Peter Bacon Darwin fa3214cfb8 refact($http): use the $jsonpCallbacks service
Use the built-in service to handling callbacks to `$http.jsonp` requests.

Closes #3073
Closes #14795
2016-06-21 19:10:13 +01:00
Peter Bacon Darwin a8cacfe938 feat($jsonpCallbacks): new service to abstract how JSONP callbacks are handled
You can now override this service if you have specific requirements about
the behaviour and formatting of the JSON_CALLBACK that is sent to the server
for `$http.jsonp` requests.

Closes #14795
2016-06-21 19:08:28 +01:00
Lucas Galfasó 1a387ba5dd fix($timeout): make $flush handle new $timeouts added in $timeout callbacks
If a $timeout handler calls $timeout itself, this new $timeout should be
added to the mock deferred queue with a "now" time based on when the original
handler was triggered.

Previously it was being added with a now time of when the `$timeout.flush`
method was originally called.

Closes #5420
Closes #14686
2016-06-20 10:01:19 -07:00
Georgios Kalpakas 98e4a220fe fix(modules): allow modules to be loaded in any order when using angular-loader
Some modules used to assume that the angular helpers would always be available when their script was
executed. This could be a problem when using `angular-loader` and the module file happened to get
loaded before the core `angular.js` file.
This commit fixes the issue by delaying the access to angular helpers, until they are guaranteed to
be available.

Affected modules:
- `ngAnimate`
- `ngMessageFormat`
- `ngMessages`
- `ngRoute`
- `ngSanitize`

Fixes #9140

Closes #14794
2016-06-18 00:20:56 +03:00
Georgios Kalpakas 9001ae2822 docs(misc/downloading): mention ngMessageFormat 2016-06-18 00:20:54 +03:00
Peter Bacon Darwin c405f88bbc fix(ngTransclude): ensure that fallback content is compiled and linked correctly
Closes #14787
2016-06-17 10:59:51 +01:00
Daniel Herman 159a68ec7b fix(ngTransclude): only compile fallback content if necessary
If the instance of the directive does provide transcluded content, then the fallback
content should not be compiled and linked as it will never be used.

If the instance of the directive does not provide transcluded content, then the
transcluded scope that was created for this non-existent content is never used,
so it should be destroy in order to clean up unwanted memory use and digests.

Fixes #14768
Fixes #14765
Closes #14775
2016-06-17 10:52:57 +01:00
Yihang Ho b9a56d588f feat($q): implement $q.race
Implement $q.race. $q.race takes in an array or hash of promises and
returns a promise that resolves or rejects as soon as one of those promises
resolves or rejects, with the value or reason from that promise.

Closes #12929
Closes #14757
2016-06-17 10:21:31 +01:00
Abdulkader f797f83cd6 feat($swipe): add pointer support
Add pointer events to $swipe to support IE11 on touch devices

Closes #14061
Closes #14791
2016-06-17 09:52:43 +01:00
Georgios Kalpakas 6df970eb3c docs($resource): clarify how a @-prefix param is used 2016-06-17 00:45:34 +03:00
Georgios Kalpakas f88b4be92f docs(angular.mock.dump): remove incorrect statement
Fixes #14790
2016-06-17 00:26:43 +03:00
Roman Rodych a7bcc01581 refactor(input[number]): remove redandant second argument to parseFloat()
Closes #14793
2016-06-16 22:19:08 +03:00
Martin Staffa 40ed8094d1 chore(changelog.js): don't add empty breaking change section 2016-06-16 14:38:53 +02:00
Martin Staffa 1a722f7b19 docs($compile): add link to transcludeFn description
Closes #14764
2016-06-16 14:16:59 +02:00
Martin Staffa 4991207c7c chore(version-info): make online build compatible with Windows
Since we cannot write to dev/null on Windows, don't write to a file at all, but simply use stdout and extract the output from --write-out from the process response. Credit to @petebacondarwin for the idea.

The commit also avoids a premature error when no cdnVersion could be found online, and improves the log wrt the origin of the versions.

PR (#14780)
2016-06-16 14:16:59 +02:00
Georgios Kalpakas 33514ec384 feat(filterFilter): allow overwriting the special $ property name
Previously, the special property name that would match against any
property was hard-coded to `$`.
With this commit, the user can specify an arbitrary property name,
by passing a 4th argument to `filterFilter()`. E.g.:

```js
var items = [{foo: 'bar'}, {baz: 'qux'}];
var expr  =  {'%': 'bar'};

console.log(filterFilter(items, expr, null, '%'));   // [{foo: 'bar'}]
```

Fixes #13313
PR (#13356)
2016-06-16 14:15:55 +02:00
Georgios Kalpakas 28bd20ed30 docs($interpolate): fix heading 2016-06-16 14:15:55 +02:00
Martin Staffa c3bfd7f59d fix(ngOptions): don't duplicate groups with falsy values
Previously, ngOptions would fail to remove optgroups with falsy values when the options were changed / removed.

Related #14781 
PR (#14784)
2016-06-16 14:15:54 +02:00
Georgios Kalpakas 553cccdb85 docs(CHANGELOG.md): add release notes for v1.5.7 2016-06-16 14:15:06 +02:00
Martin Staffa c7dd2c24f4 docs(guide/filters): clarify when filters are executed
Closes #14590
PR  (#14758)
2016-06-16 14:13:01 +02:00
Peter Bacon Darwin fbf5aebda2 chore(version-info): add offline-build support
Previously it was slow and problematic to run builds if you were not connected
to the internet because the build scripts make requests to github and the
Google CDN to find out version information.

You can now disable these requests by setting the NG1_BUILD_NO_REMOTE_VERSION_REQUESTS
environment variable to a non-empty value

Closes #14769
2016-06-15 10:32:31 +01:00
Peter Bacon Darwin ab35c16ccf chore(app.scenario): test docs app against production libraries
We have had issues where the docs application has gone down because
our build included invalid URLs to the production angular libraries.

This change runs a subset of the docs e2e tests directly against these
production libraries to ensure that they are accessible. If not then these
tests will fail and the CI build will abort, preventing the docs app from
being updated.

Closes #14769
2016-06-15 10:32:18 +01:00
Peter Bacon Darwin 37b6a71678 chore(Gruntfile): kill the build if the CDN version was not found
Closes #14769
2016-06-15 10:32:07 +01:00
Martin Staffa e79ebff223 docs(changelog.md): add 1.5.0-beta.0 entry
This was a preparation release for the 1.5.x branch,
which only contains one fix over the previous 1.4.6
release.
2016-06-15 11:22:03 +02:00
Wesley Cho 36b38e1355 docs($q): add note about optional arguments for promise.then()
- Add note about optional arguments in the promise.then api

Closes #8562
PR (#14754)
2016-06-15 11:21:58 +02:00
Wesley Cho 3168d95793 docs(guide): add notes about using ngAttr for IE
- Add note about using the value attribute for the progress tag with IE in the IE compat / interpolation guide
- Add note about placeholder attribute in textarea to the ie compat guide

Closes #7218
PR (#14753)
2016-06-15 11:21:39 +02:00
Geoffrey Bauduin 538c63f057 docs($exceptionHandler): add missing end bracket in example
PR  (#14756)
2016-06-15 11:21:21 +02:00
Wesley Cho a9a1461351 docs(ngOpen): add note about browser compatibility
- Add note about browser compatibility and recommend ng-show/ng-hide

Closes ##7337
PR (#14752)
2016-06-15 11:21:11 +02:00
Peter Bacon Darwin 29190f9318 revert: chore(version-info): disable remote requests when offline
This reverts commit aa38ded59d, which
caused the docs to build incorrectly causing the docs website to crash.
2016-06-14 20:44:12 +01:00
Peter Bacon Darwin ca7d2b3b3f docs(ngMessageFormat): fix e2e test in example 2016-06-14 20:41:23 +01:00
Peter Bacon Darwin 81676f8323 style(ngMessageFormat): fix jscs whitespace error 2016-06-14 20:41:23 +01:00
Martin Staffa 6f9d07d9c7 chore(docsApp): don't display module components if none exist
Some modules (ngMessageFormat, ngParseExt) don't have their own api surface
because they integrate with core services ($interpolate and $parse respectively).

Closes #14770
2016-06-14 20:41:23 +01:00
Martin Staffa 5201b8146a docs(ngMessageFormat): move docs for $$messageFormat to module namespace.
This is a private service that should not be documented.
The docs have been moved to the ngMessageFormat module namespace.

Closes #14770
2016-06-14 20:41:23 +01:00
Martin Staffa 6aa83d04b7 docs(ngMessageFormat): add more examples
Closes #14770
2016-06-14 20:41:23 +01:00
Igor Minar cfbe1a701a revert: fix($timeout): make $flush handle new $timeouts added in $timeout callbacks
This reverts commit 1e5d36d4b0.

Breaks tests at google, needs more investigation.
2016-06-14 08:08:25 -07:00
Pete Bacon Darwin aa38ded59d chore(version-info): disable remote requests when offline
When the internet is not accessible build scripts are unnecessarily slow
because of failed attempts to download git tag and CDN version information
from remote servers.

This commit does a synchronous check of internet connectivity before attempting
any remote requests.

Closes #14759
2016-06-13 15:58:21 +01:00
Wesley Cho b03957f004 feat(limitTo): add support for array-like objects
Fixes #14657

Closes #14694
2016-06-10 21:14:04 +03:00
Martin Staffa 56f33af890 fix(ngMessages): create new scope for ngMessage, clean it up correctly
Previously, ngMessage elements used the same scope as ngMessages. When ngMessage
has interpolation in the textContent, then removing the message would not remove
the watcher from the scope - it would only be removed when the whole ngMessages
element was removed.

This commit changes the ngMessage transclude function to create a new child scope
instead, which can be destroyed safely when the message element is removed and
the message is detached

Fixes #14307
PR (#14308)
2016-06-10 14:49:08 +02:00
CarlosMiguelDesarrollo 41bea59eb7 chore(ngAnimate): delete an unused conditional statement
Delete a conditional statement that appears to have only been for debugging.
It is marked with a TODO tag to be deleted.

Closes #14282
2016-06-10 12:27:24 +01:00
Georgios Kalpakas 6d0dcca6f1 fix($routeProvider): do not deep-copy route definition objects
Deep-copying route definition objects can break specific custom implementations of `$sce` (used to
trust a `templateUrl` as RESOURCE_URL). The purpose of copying route definition objects was to guard
against the user's modifying the route definition object after route registration, while still
capturing inherited properties.
As suggested by @IgorMinar in https://github.com/angular/angular.js/pull/14699#discussion_r66480539,
we can achieve both _and_ support custom `$sce` implementations, by shallow-copying instead.

This is an alternative implementation for #14699, which avoids the breaking change.

Fixes #14478
Closes #14699

Closes #14750
2016-06-10 14:09:40 +03:00
mirabilos f423dc6b51 fix(input[email]): improve email address validation
**Limit size of local-part and total path size in eMail addresses**

RFC 5321 §4.5.3.1.1 ⇒ local-part can have up to 64 octets
RFC 5321 §4.5.3.1.3 ⇒ path “including the punctuation and
element separators” can have up to 256 octets
RFC 5321 §4.1.2 specifies path as ‘<’ + mailbox¹ + ‘>’ in
the best case, leaving us 254 octets

The limitation of the total path size to 254 octets leaves
at most 252 octets (one local-part, one ‘@’) for the domain,
which means we don’t need to explicitly check the domain
size any more (removing the assertion after the ‘@’).

① RFC 821/5321 “mailbox” is the same as RFC 822 “addr-spec”

**Optimise eMail address regex for speed**

There is no need to make it case-insensitive; the local-part
already catches the entire range, and the host part is easily
done. Furthermore, this makes the regex locale-independent,
avoiding issues with e.g. turkish case conversions.

cf. http://www.mirbsd.org/cvs.cgi/contrib/hosted/tg/mailfrom.php?rev=HEAD

**Limit eMail address total host part length**

RFC 1035 §2.3.4 imposes a maximum length for any DNS object;
RFC 5321 §2.3.5 references this (and requires FQDNs, but there
have been cases where a TLD had an MX RR and thus eMail addresses
like “localpart@tld” are valid).

Credits: Natureshadow <d.george@tarent.de>

**Limit eMail address individual host part length**

A “label” (each of the things between the dots (‘.’) after the ‘@’ in
the eMail address) MUST NOT be longer than 63 characters.

cf. http://www.mirbsd.org/cvs.cgi/contrib/hosted/tg/mailfrom.php?rev=HEAD
and RFC 1035 §2.3.4

**Fix eMail address local-part validation**

A period (‘.’) may not begin or end a local-part

cf. http://www.mirbsd.org/cvs.cgi/contrib/hosted/tg/mailfrom.php?rev=HEAD
and RFC 822 / 5321

Closes #14719
2016-06-10 10:46:21 +01:00
Georgios Kalpakas 9fca87ca5b docs(misc/downloading): update content - include missing modules
Closes #14746
2016-06-10 10:41:25 +01:00
Martin Staffa ebbaa4ac5e fix($compile): don't add merged attributes twice to $attrs
In replace directives, attribute values from the template are added twice
to the replaced element when both the replaced element and the template
element have the attribute. This does not affect the DOM, as it normalizes
duplicate values. The values are however duplicated in the $attrs object
that is available to directive link functions.

Fixes #8159
Closes #14737
2016-06-09 16:27:13 +01:00
J. Roberto Vidal 617137231e docs($resource): document Resource#toJSON
Document the `toJSON` method of `Resource` instances as part of its public API.

See #14637
Closes #14725
2016-06-09 16:00:59 +01:00
Stepan Suvorov 71b966ace7 docs(misc/downloading): update Angular version in example
Closes #14741
2016-06-09 11:17:37 +03:00
Stepan Suvorov 488d5b4288 updated version of angular for script src 2016-06-09 11:17:36 +03:00
Georgios Kalpakas 01b8772cca feat(ngMessagesInclude): don't break on empty (or whitespace-only) templates
Fixes #12941

Closes #14726
2016-06-07 23:22:15 +03:00
Georgios Kalpakas 05ac0ba926 style(ngMessages): fix indentation 2016-06-07 23:20:28 +03:00
mirabilos 399e872228 docs(guide/Security): warn about $http.jsonp()
Warn users about security issues with JSONP that are *not* mitigated by AngularJS

Closes #14727
2016-06-07 18:34:48 +01:00
Stephen Fluin 3115408be7 docs(guide/Component Router): improving comms 2016-06-07 16:33:20 +01:00
Martin Staffa aea39e9fdc docs(changelog, guide/migration): mention rare BC for ngInclude
See https://github.com/angular/angular.js/issues/13555#issuecomment-165118890
for detailed explanation.

Closes #13555
2016-06-07 10:43:40 +02:00
Georgios Kalpakas 51f6752cec style(ngMocks): remove unnecessary jsHint comment 2016-06-07 11:19:11 +03:00
Georgios Kalpakas db58801a55 fix(ngMock#$controller): properly assign bindings to all types of controllers (e.g. class-based)
The decorated version of `$controller` is able to assign bindings to a controller instance prior to
instantiation, emulating the behavior of `$compile` with directive controllers.

There are cases, that the actual controller instance is different than the pre-populated one (e.g.
when the controller constructor function returns a value or when the controller is an ES2015 Class).
While `$compile` accounts for such situation, by re-asigning the bindings after the controller has
been instantiated, `ngMock`'s `$controller` didn't.

This commit fixes it, by re-applying the bindings if the actual controller instance is different
than the original one (similar to how `$compile` would do it).

Fixes #14437

Closes #14439
2016-06-07 11:18:34 +03:00
Georgios Kalpakas 2e33d170be feat(orderBy): add support for custom comparators
Add an optional, 4th argument (`comparator`) for specifying a custom comparator function, used to
compare the values returned by the predicates. Omitting the argument, falls back to the default,
built-in comparator. The 3rd argument (`reverse`) can still be used for controlling the sorting
order (i.e. ascending/descending).

Additionally, the documentation has been expanded to cover the algorithm used by the built-in
comparator and a few more unit and e2e tests (unrelated to the change) have been added.

Helps with #12572 (maybe this is as close as we want to get).

Fixes #13238
Fixes #14455

Closes #5123
Closes #8112
Closes #10368

Closes #14468
2016-06-07 00:32:19 +03:00
Peter Bacon Darwin cc6dcb4bc2 fix($parse): allow arguments to contain filter chains
Thanks to @esarbanis for the original PR that got out-dated due to the
big $parse overhaul.

Closes #4175
Closes #4168
Closes #14720
2016-06-06 15:20:50 +01:00
Guillaume Salles 294d6793fd fix($location) : initialize $$absUrl to empty string
Initialize `$$absUrl` to an empty string, in order to avoid exception, when base href
and current location have different domains.

Fixes #11091
Fixes #13565

Closes #14488
2016-06-06 15:52:28 +03:00
Peter Bacon Darwin cefcc46e1b docs(tutorial/step-9): fix typo 2016-06-06 13:38:17 +01:00
Martin Staffa c10dba144e docs(ngComponentRouter): add deprecation notice and better install notes
Yes, that contradicts itself.

Closes #14655
Closes #14717
2016-06-06 13:30:31 +01:00
Peter Bacon Darwin f05ffd9bf1 test(browserTrigger): fix typo in eventData property 2016-06-06 13:28:17 +01:00
Peter Bacon Darwin e208d81293 test(browserTrigger): allow event bubbling
In some browsers, events don't bubble when they are dispatched on node inside
a detached tree. When this is the case, the bubbling is made manually.
This may be convenient when unit testing directives, for example.

Closes #5178
2016-06-06 11:57:23 +01:00
Peter Bacon Darwin b51fca1a2b test(browserTrigger): support key events
Support for key events like keypress, keyup or keydown.

Closes #8688
2016-06-06 11:57:21 +01:00
Andrew Schmadel 6685043ad4 fix(ngMockE2E): allow $httpBackend.passThrough() to work when ngMock is loaded
Allow $httpBackend.passThrough() to work normally when ngMock is loaded
concurrently with ngMockE2E, as is typically the case when writing tests with
angular.mock.module()

Fixes #1434
Closes #13124
2016-06-06 11:30:50 +01:00
Martin Staffa f176a2dbb7 docs(angular.element): note restrictions of addClass and removeClass
Closes #12851
Closes #12793
2016-06-03 21:50:00 +02:00
Georgios Kalpakas 3a366bd42b docs($exceptionHandler): include better example
The previous example overwrote the `$exceptionHandler` in order to re-throw the error. This is not
recommended, since it would leave the application in an inconsistent state and prevent proper
clean-up.
The new example simulates logging the error both to the backend and the console.

Fixes #14704
2016-06-03 21:34:48 +03:00
Georgios Kalpakas 1c5db02638 refactor($resource): explicitly set $resourceProvider.defaults.cancellable to false
Previously, it was just `undefined` and had the same behavior (since we only check for falsy-ness).
Just making it explicit, that this property is also available on `defaults` and is "not true" by
default.

Closes #14711
2016-06-03 20:15:45 +03:00
Georgios Kalpakas ffd5308d86 docs($resourceProvider): improve wording and formatting
Closes #11910
2016-06-03 20:15:02 +03:00
Yiling Lu aed9de9d37 docs($resourceProvider): provide info and example for configuring $resourceProvider 2016-06-03 20:14:37 +03:00
Wesley Cho aab6825e85 docs($animate): detail options object
- Document options object used in various $animate methods

Fixes #12645
PR: #14700
2016-06-03 13:28:44 +02:00
Martin Staffa c4fad6ad61 fix(ngSanitize): call attribute setter in linky for all links
Fixes #14707 
PR: #14710
2016-06-03 13:22:24 +02:00
ZachLamb 2a7c37cf01 docs(tutorial/step_04): fix type (JacaScript --> JavaScript)
Closes #14661
2016-06-01 11:08:42 +03:00
Peter Bacon Darwin 194c3adfed docs(CHANGELOG): fix typo 2016-05-27 22:34:51 +01:00
Martin Staffa 371957d9d5 docs(changelog): update with changes for 1.5.6 2016-05-27 17:59:43 +02:00
Lucas Galfasó 1e5d36d4b0 fix($timeout): make $flush handle new $timeouts added in $timeout callbacks
If a $timeout handler calls $timeout itself, this new $timeout should be
added to the mock deferred queue with a "now" time based on when the original
handler was triggered.

Previously it was being added with a now time of when the `$timeout.flush`
method was originally called.

Closes #5420
Closes #14686
2016-05-27 16:19:54 +01:00
Peter Bacon Darwin 3749c85829 fix($compile): cope with $onChanges hooks throwing
Previously, if one of these hooks threw an error, then the compilation
was terminated unceremoniously. In particular any other `$onChanges`
hooks that had been scheduled were not executed, nor was the queue cleaned
up properly.

Closes #14444
Closes #14463
2016-05-27 16:14:51 +01:00
Martin Staffa 886b59d317 chore(angularFiles): add missing files
ngMessageFormat test files were missing from angularTest
ngMessages and ngAnimate were missing from karmaModules.

This change highlighted a number of problems in the tests and code,
which are now fixed.

Closes #14314
Closes #14669
2016-05-27 16:13:31 +01:00
Victor Oliveira da Silva 2048b6df24 docs(ngRepeat): fix typo
Closes #14681
2016-05-26 22:22:57 +03:00
Georgii Dolzhykov 5ec0a50d39 chore(package.json): remove unused grunt-jasmine-node
Closes #14363
2016-05-26 01:43:24 +03:00
Peter Bacon Darwin 60689afe1c docs(tutorial/step-9): fix typo in inline link 2016-05-25 17:00:13 +01:00
Hadrien Tulipe 881fddaaba docs(ngAnimateMock): document how to require mocked service in tests
Closes #14668
Closes #14670
2016-05-25 16:57:37 +01:00
Robin Böhm fda338e8e2 refactor(ngMock): use exactly equal in browserTrigger
Closes #6763
2016-05-25 15:32:48 +02:00
David Goldberg 05c8d88126 style(src/Angular.js): make comment formatting consistent
Corrected formatting errors on lines 258, 695, 696, 1096, 1219, 1451, and 1536 by adding periods at the end of single line comments that were missing them in order to be consistent with the formatting found in the file.

Capitalized the first letter in the first word of the comments on lines 695, 696, 1096, to be consistent with the formatting of the rest of the file.

Added a space after the // in the comment on line 1536 to be consistent with the formatting of the file.
2016-05-25 15:17:20 +02:00
Martin Staffa aa57f57ccb docs(angular.element): note restriction in toggleClass 2016-05-25 15:12:08 +02:00
thorn0 51b78f61f9 perf($rootScope): make queues more efficient
By using a pointer to the current start of the queue and only clearing
up the queue storage later, we save lots of time that was spent manipulating
arrays with `slice`

Closes #14545
2016-05-25 13:22:12 +01:00
Ajay 739100e8a8 docs($provide): document decorator method
Closes #14562
2016-05-25 13:16:55 +01:00
Peter Briers 20e0c7f966 docs(ngAnimate): remove unnecessary transition prefixes
We can remove the vendor-prefixing from our docs, since all major browsers
support these properties, without prefixes.

Closes #14586
2016-05-25 12:38:46 +01:00
Jacob Reid f34e3413c7 docs(tutorial): fix typos
Closes #14662
Closes #14663
Closes #14664
2016-05-25 12:18:15 +01:00
Peter Bacon Darwin 4d28598b3d refactor(*): faster check for a string starting with a substring
Thanks to @spamdaemon for the original PR to make this improvement.

In naive tests on Chrome I got the following results:

```
             Matches   Misses
indexOf      33ms      1494ms
lastIndexOf  11ms      11ms
```

Closes #3711
2016-05-24 19:10:29 +01:00
Peter Bacon Darwin 16d6e89f3b refactor($route): consolidate route locals processing into a single handler 2016-05-24 19:02:09 +01:00
Peter Bacon Darwin 6e220ab612 refactor($route): move resolving locals into its own function 2016-05-24 19:02:09 +01:00
Peter Bacon Darwin ce14e4a6b7 refactor($route): move getting the template into its own function 2016-05-24 19:02:09 +01:00
Georgios Kalpakas b5dbc9834a docs(tutorial): update to use v1.5.x and best practices
This is a major re-structuring of the tutorial app's codebase, aiming at applying established best
practices (in terms of file naming/layout and code organization) and utilizing several new features
and enhancements (most notably components) introduced in recent versions of Angular (especially
v1.5).

Apart from the overall changes, two new chapters were introduced: one on components and one on code
organization.

--
In the process, several other things were (incidentally) taken care of, including:

* Dependencies were upgraded to latest versions.
* Animations were polished.
* Outdated links were updated.
* The app's base URL was changed to `/` (instead of `/app/`).

BTW, this has been tested with the following versions of Node (on Windows 10) and everything worked
fine:

* 0.11.16
* 4.2.6
* 4.4.2
* 5.10.0
* 6.2.0

--
This was inspired by (and loosely based on) #13834.
Again, mad props to @teropa for leading the way :)

--
**Note:**
The old version of the tutorial, that is compatible with Angular version 1.4 or older, has been
saved on the `pre-v1.5.0-snapshot` branch of
[angular-phonecat](https://github.com/angular/angular-phonecat). The `v1.4.x` version of the
tutorial should be pointed to that branch instead of `master`.

--
Related to angular/angular-phonecat#326.
Related to angular/angular-seed#341.

Closes #14416
2016-05-24 15:44:19 +03:00
Peter Bacon Darwin 57f10251db docs(tutorial): add svg and visio versions of the graffle images 2016-05-24 15:43:25 +03:00
Peter Bacon Darwin 48cd05a1ad docs(guide): add svg and visio versions of the graffle images 2016-05-24 15:42:33 +03:00
Peter Bacon Darwin 6a71ba17f0 docs(images): add svg and visio versions of the graffle image 2016-05-24 15:41:09 +03:00
marija cf1b175508 perf(ngClass): improve even-odd checking
This now uses the same technique as ngRepeat.
2016-05-23 23:31:52 +02:00
marija 5bba68c264 refactor($sniffer): avoid unnecessary call to substring 2016-05-23 23:31:51 +02:00
Alireza Mirian e5a4345aac docs(guide/Conceptual Overview): clarify service instantiation explanation
Change a sentence which describes how currencyConverter service is instantiated
2016-05-23 23:31:16 +02:00
Martin Staffa 49ef92041f docs(input[text]): remove deprecated tt tag
Closes #14547
2016-05-23 23:30:33 +02:00
Peter Bacon Darwin 081ae8bfca chore(docs): add horizontal rules between known issues 2016-05-23 22:19:23 +01:00
Peter Bacon Darwin 4f8aa6f5bb chore(docs): fix api.template.html to display git links 2016-05-23 22:19:19 +01:00
Xavier Haniquaut d7e888b8c6 docs(error/$compile): add reqslot error description
Explains what could generate a `reqslot` error.

Closes #14618
2016-05-23 14:21:00 +01:00
Peter Bacon Darwin 491b4af92e chore(docs): add horizontal rules between known issues 2016-05-23 14:03:00 +01:00
Peter Bacon Darwin 5930b8ee27 docs($interpolate): add known issue about custom interpolation symbols
Closes #14610
Closes #6493
2016-05-23 13:52:57 +01:00
Jukka 69d9072d5b fix(ngMessagesInclude): do not compile template if scope is destroyed
Messages imported with `ngMessagesInclude` are loaded asynchronously and
they can arrive after the ngMessages element has already been removed from DOM.

Previously we tried to compile these messages and that caused a `$compile:ctreq`
error. Now they are silently ignored if `ngMessagesInclude`'s scope has already
been destroyed.

Closes #12695
Closes #14640
2016-05-23 13:00:56 +01:00
Wesley Cho 9b5de0ac97 docs(contributing): fix the styleguide link
Update the link to Google's JavaScript style guide to the updated version

Closes #14652
2016-05-23 12:49:09 +01:00
Georgios Kalpakas 21b76aed06 fix($animate): don't break on anchored animations without duration
If the `from` element of an animation does not actually have an animation
then there will be no animation runner on that element. This is possible
if the element has the `ng-animate-ref` attribute but does not have any
CSS animations or transitions defined.

In this case, it is not necessary to try to update the host of the
non-existent runner.

Fixes #14641
Closes #14645
2016-05-22 19:02:45 +01:00
Bijay Deo 363fb16c10 fix(ngMock): match HTTP request regardless of the order of query params
Closes #12762
2016-05-21 10:44:37 +01:00
Peter Bacon Darwin e00f9f62e3 docs(toJson): documented the Safari RangeError known issue
Closes #14221
Closes #13415
2016-05-21 10:15:45 +01:00
Georgios Kalpakas 507c666d16 docs(ngMock/$exceptionHandler): fix formatting
Too much indentation, made text get formatted as code block.
2016-05-20 21:23:51 +03:00
Adrian Moos 743b33ab9d fix($brower): set the url even if the browser transforms it
While $location expects that $browser stores the URL unchanged, "some browsers" transform the URL
when setting or defer the acutal update. To work around this, $browser.url() kept the unchanged
URL in pendingLocation.

However, it failed to update pendingLocation in all code paths, causing
$browser.url() to sometimes incorrectly report previous URLs, which horribly confused $location.

This fix ensures that pendingLocation is always updated if set, causing url() to report the
current url.

Fixes #14427
Closes #14499
2016-05-20 15:44:53 +01:00
Peter Bacon Darwin 9f8fa79f25 docs(misc/contribute): specify node version 2016-05-18 16:46:44 +01:00
Peter Bacon Darwin fe3c1d44a5 docs(ngMock): final installation description fix 2016-05-18 08:42:05 +01:00
Georgios Kalpakas 5ae72dc7af fix($compile): properly bind context to linking functions for directives with templateUrl
Also, fix some styling issues.
2016-05-17 22:21:22 +03:00
Paulo Cesar 47bc98a1ea fix($compile): always use the DDO as this in pre-/post-linking functions
Closes #9306
2016-05-17 22:20:26 +03:00
Peter Bacon Darwin 10920a2857 docs(ngMock): fix installation instructions 2016-05-17 18:25:16 +01:00
Thomas Kowalski 90a9270dfa docs(guide/component-router): remove unused code
Closes #14613
2016-05-17 12:06:52 +03:00
Igor Minar d4b05dd13a revert: perf(ngAnimate): listen for document visibility changes
This reverts commit b377d6b043.

This commit introduces dependency on $document during the injector
bootstrap. This is usually fine, except for cases when $document is
mocked out in existing test suites. Since we don't provide an out
of box mock, people have created their owns that don't sufficiently
mock all apis. In these environments this change results in errors
like $document.on is not a function, etc.
2016-05-16 16:59:08 -07:00
Peter Bacon Darwin 59802bc790 docs(ngMock): fix installation formatting
The `@installation` section should be formatted with markdown, not
nunjucks template directives.

Closes #14604
2016-05-16 22:46:51 +01:00
Sander Boom b0a35a794a docs(guide/$location): fix typo
Closes #14607
2016-05-14 01:53:25 +03:00
Mark Pieszak a9545e3963 docs(readme): remove "(beta)" from Angular 2 link
Closes #14599
2016-05-13 23:17:18 +03:00
Georgios Kalpakas 269c15c74b docs(ngComponentRouter): specify correct version of npm package
The latest npm package does not contain the angular 1 version of the router.

Related to 824ce30.
2016-05-13 19:25:01 +03:00
Maksim Ryzhikov 9f48025733 fix(ngAnimate): properly handle empty jqLite collections
Previously `stripCommentsFromElement()` would return an empty Array (instead of a jqLite collection)
which would cause an exception to be thrown: "element.parent not a function".
This commit fixes it, by ensuring that the returned value is always a jqLite collection.

Closes #14558

Closes #14559
2016-05-13 18:17:43 +03:00
Peter Bacon Darwin 1d0ccd0d73 chore(package.json): update to use dgeni-packages@0.13.0 2016-05-12 11:05:27 +01:00
Peter Bacon Darwin 03e5164528 chore(npm/check-node-modules): cope with no npm-shrinkwrap file 2016-05-12 11:05:25 +01:00
Pete Bacon Darwin 3047964712 fix($compile): don't run unnecessary update to one-way bindings
The watch handler was triggering on its first invocation, even though
its change had already been dealt with when setting up the binding.

Closes #14546
Closes #14580
2016-05-10 22:31:29 +01:00
Peter Bacon Darwin 225afb9eb4 docs(guide/component-router): specify correct version of npm package
The latest npm package does not contain the angular 1 version of the router.

Closes #14564
Closes #14560
2016-05-07 21:40:13 +01:00
Martin Staffa b377d6b043 perf(ngAnimate): listen for document visibility changes
Accessing the document for the hidden state is costly for
platforms like Electron. Instead, listen for visibilitychange
and store the state.

Closes #14568
2016-05-06 15:53:24 +02:00
dmandelin ac650cb2e6 docs($sanitizeProvider): fix param comment for enableSvg
Change the text of the doc comment for the parameter of enableSvg to match the type of the comment and the behavior of the code (#14543).
2016-05-06 15:45:50 +02:00
FGasper 926088ba77 docs($location): clarify return value for path method
docs for return of path() inaccurately describe the function’s return when a value is passed in.

Closes #14544
2016-05-06 15:45:50 +02:00
Stephen Barker f94cf634d8 docs(guide/decorators): add decorator guide
+ explain decorators and how they are implemented in angular
+ explain how different types of services can be selected
+ explain `$delegate` objects and how they differ between services
+ warn of the risks/caveats of `$delegate` modification
+ note the exposure of `decorator` through the module api
+ show an example of decorating a core service
+ show an example of decorating a core directive
+ show an example of decorating a core filter

Closes #12163
Closes #14372
2016-05-06 15:45:49 +02:00
Michael Warner 85b3786f55 docs(ngRequired): add 'restrict' info
The Angular Docs do not show the restrictions

Closes #14541
2016-05-06 15:45:12 +02:00
Ivo Mirra 1116a96df6 fix($compile): removing unnecessary white space in element-transclusion comments
Fixes #14549

Closes #14550
2016-05-05 18:56:19 -06:00
Martin Probst 1c1c9b27cb fix(ng-bind-html): watch the unwrapped value using $sce.valueOf() (instead of toString())
Custom `$sce` implementations might not provide a `toString()` method on the wrapped object, or it
might be compiled away in non-debug mode. Watching the unwrapped value (retrieved using
`$sce.valueOf()`) fixes the problem.

The performance of this should be equivalent - `toString()` on objects usually touches all fields,
plus we will also avoid the (potentially big) string allocation.

Fixes #14526
Closes #14527
2016-04-28 20:25:13 +03:00
Mark Pieszak c5e7a5bc9b docs(README.md): add link to Angular 2 repo
Might be helpful for those completely new to Angular in general, that intended to view the upcoming
2.0 version.

Closes #14532
2016-04-28 19:46:57 +03:00
Georgios Kalpakas 7550b7bda8 fix($injector): add workaround for class stringification in Chrome v50/51
Partially fixes #14240.

Closes #14531
2016-04-28 14:31:50 +03:00
Petr Mikota 43b97b211b docs(guide/component-router): add missing backticks
Closes #14530
2016-04-28 11:40:39 +03:00
Weijing Jay Lin 76405897fc docs(identity): add example
Closes #14528
2016-04-28 11:07:00 +03:00
Georgios Kalpakas bb730704f2 fix($injector): add workaround for fat-arrow stringification in Chrome v50/51
Closes #14487

Closes #14495
2016-04-28 10:55:51 +03:00
Georgios Kalpakas 8965d57aa0 feat($compile): support omitting required controller name if same as the local name
Basically, making `require: {someDir: '?^someDir'}` equivalent to `require: {someDir: '?^'}`.

Closes #14513
2016-04-28 10:44:21 +03:00
Fabricio Ronchi 951a2743d5 docs(ngAria): remove redundant table column
Closes #14518
2016-04-28 10:38:35 +03:00
Michael de Wit a2a907e439 docs(guide/component): several unit-test fixes and remove obsolete testcase
Fixes #14426

Closes #14443
2016-04-26 20:24:56 +03:00
Perry Hooker 308f22ba9a fix($compile): properly handle setting srcset to undefined
Previously, calling `Attributes#$set('srcset', value)` on an `<img>` element would throw if `value`
were undefined, as it assumed `value` is always a string.
This commit fixes the issue, by skipping the unnecessary string manipulation when `value` is not
defined.

Closes #14470

Closes #14493
2016-04-26 09:17:51 +03:00
andrea 32e2643d90 docs(guide/index): fixed formatting with subtitles
The "Books" and "Videos" subtitles had no space between text and the '#' so it didn't render as a
subtitle.

Closes #14514
2016-04-26 08:33:36 +03:00
Tim van Dalen 3edaf0922f docs($anchorScroll): fix link to HTML5 spec
Closes #14364
2016-04-26 00:22:58 +03:00
Raphael Jamet 1095596962 fix($templateRequest): trust empty templates in $templateCache as well
Implicitly trust empty templates added to `$templateCache` as is the case for all other templates.

Fixes #14479

Closes #14496
2016-04-25 20:22:26 +03:00
Georgios Kalpakas ee0dac4d1d docs($interpolate): add known issue about end-symbol in expression
This has been discussed in #8642.

Closes #14494
2016-04-22 15:42:21 +03:00
Georgios Kalpakas 6f1fae8a91 fix(filters): always call splice() with 2 arguments or more
When calling `.splice()` without a 2nd argument (`deleteCount`), most browsers will splice to the
end of the array. As it turns out, this is the behavior specified in [ES2015][es6]. In [ES5][es5],
the spec seems to imply that nothing should happen.

To avoid inconsistent behavior among browsers implementing different versions of the EcmaScript
standart or when ES5 shims are included (e.g. https://github.com/es-shims/es5-shim/), this commit
ensures that all calls to `.splice()` provide at least two arguments.

[es5]: http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.12
[es6]: http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.splice

Fixes #14467

Closes #14489
2016-04-22 12:41:28 +03:00
Abhishek Garg f96485085a docs($http): add better explanation for error status codes
Add explanation for error status codes in `$http` and mention negative codes normalization.
This alleviates confusion about which status codes will trigger the error callback and what values
to expect in such callbacks.

Fixes #11945

Closes #14459
2016-04-22 12:24:11 +03:00
andreyjkee 147650b3be fix(ngMocks): pass eventHandlers to $httpBackend if passThrough is active
Closes #14471
2016-04-21 23:10:28 +02:00
Martin Staffa 10c426ffa3 docs(guide/Expressions): mention absence of bitwise operators
Closes #14485
2016-04-21 16:29:04 +02:00
Abhishek Garg 785647eb9d docs(changelog): make labels and list style consistent
Remove 'Breaking Changes' label where there are no breaking changes.

Only for '1.4.0-rc.2', breaking changes have different styling (bold without bulleted list). Change to be consistent with others

(#14482)
2016-04-21 16:29:04 +02:00
Amy a2a6279157 docs($sce): add missing article
...teeny letter missing.  Just a grammar change.
(#14480)
2016-04-21 16:29:03 +02:00
jody tate b50d2a4a1f docs(ngAria): fix markdown heading syntax
(#14477)
2016-04-21 16:29:03 +02:00
Martin Staffa f539fb1f7c docs(ngMock): add custom installation instructions
ngMock should be used in a test runner context, not directly in the application

Closes #14248
2016-04-21 16:01:26 +02:00
Martin Staffa 2dcb5acb7b docs: reorganize module overview page template 2016-04-21 16:01:23 +02:00
Michał Gołębiowski 905a8fd4a4 chore(jQuery): bump jQuery version from 2.2.1 to 2.2.3 2016-04-20 13:36:48 +02:00
Michał Gołębiowski df9b57a481 test(jqLite): make add/removeEventListener tests work with jQuery 2.1
The useCapture parameter defaults to false even in oldest of our supported
browsers; this is no longer needed so jQuery has removed it in 2.2.

In Angular 1.6 we apply the same refactoring, here in 1.5 we're just making
tests work with jQuery 2.2.
2016-04-20 13:30:46 +02:00
Michał Gołębiowski fee2077d0b chore(jqLite): stop patching the change jQuery special handler
Code patching the change event in jQuery doesn't exist in jQuery 2 so this patch
hasn't been needed since Angular 1.3
2016-04-20 12:29:40 +02:00
Michał Gołębiowski 691aafc981 tests(jQuery): test on both oldest & latest supported jQuery version 2016-04-20 12:26:36 +02:00
Ken Powers da7af937d6 docs(guide/Components): change snake to kebab case
The example given is not in snake_case, it is in kebab-case.

Closes #14464
2016-04-19 20:34:54 +02:00
Lucas Mirelmann 1c9b9e24ed feat($parse): Add support for ES6 object initializers
- Add support for computed property names
- Add support for short notation in properties definitions

Eg. The expressions `{x}` and `{[x + 'foo']: 1}` are now valid.

Closes: #14407
2016-04-18 22:09:17 +02:00
Martin Staffa 46a5b2c298 docs(ngMockE2E): add $httpBackend mock example 2016-04-18 14:09:24 +02:00
Peter Bacon Darwin 28e4707dc4 chore(CHANGELOG): fix version number for 1.5.5 2016-04-18 12:31:11 +01:00
Peter Bacon Darwin 420b5211da chore(CHANGELOG): add 1.5.5 release notes 2016-04-18 10:52:06 +01:00
Jeremy 04bccee099 docs(guide/Component Router): fix a typo in npm install instructions
Related #14452
2016-04-17 23:50:13 +02:00
Peter Bacon Darwin a404839795 docs(CHANGELOG): remove changes from 1.5.4
1.5.4 was only partially released.
These changes will be included in the 1.5.5 release
2016-04-16 09:29:37 +01:00
Georgios Kalpakas 25d4e5cca4 fix($http): pass event object to eventHandlers/uploadEventHandlers
Fixes #14436
2016-04-15 14:09:39 +01:00
Peter Bacon Darwin c67112563f revert: refactor($compile): move setting of controller data to single location
Reverted from commit 21d148aedc since it caused
the Angular Material tabs directive to fail.
2016-04-15 14:09:05 +01:00
Jannick Fahlbusch 2b2ec26a75 chore(docsApp): open plnkr.co with HTTPS
Plnkr should be opened via HTTPS instead of HTTP to supress warnings about an insecure connection

Closes #14445
2016-04-15 14:55:13 +02:00
cloverharvest 41f90e5fb0 docs($http): fix a typo (his --> this)
Closes #14430
2016-04-15 01:25:09 +03:00
Adam Demuri a85c591d36 docs(component): document 'require' in angular.component
Closes #14429
2016-04-15 01:12:43 +03:00
Peter Bacon Darwin f276ad0d51 docs(CHANGELOG): add release notes for 1.5.4 2016-04-14 09:13:48 +01:00
Pete Bacon Darwin 33f817b99c feat($componentController): provide isolated scope if none is passed (#14425)
Closes #14425
2016-04-13 18:34:39 +01:00
Martin Staffa 6a4124d0fb perf(ngOptions): use documentFragment to populate select
This changes the way option elements are generated when the ngOption collection changes.
Previously, we would re-use option elements when possible (updating their text and
label). Now, we first remove all currently displayed options and the create new options for the
collection. The new options are first appended to a documentFragment, which is in the end appended
to the selectElement.

Using documentFragment improves render performance in IE with large option collections
(> 100 elements) considerably.

Creating new options from scratch fixes issues in IE where the select would become unresponsive
to user input.

Fixes #13607
Fixes #13239
Fixes #12076
2016-04-13 18:42:10 +02:00
Georgios Kalpakas 26d1b34321 docs(ngView): add known issue about asynchronously loaded ngView
Closes #14424
2016-04-13 18:45:40 +03:00
Georgios Kalpakas 7fba6b603f revert: "fix(ngRoute): allow ngView to be included in an asynchronously loaded template"
This reverts commit 5e37b2a7fd.
Eagerly loading `$route`, could break tests, because it might request the root or default route
template (something `$httpBackend` would know nothing about).

It will be re-applied for `v1.6.x`, with a breaking change notice and possibly a way to disable
the feature is tests.

Fixes #14337
2016-04-13 18:45:06 +03:00
Jason Bedard c115b37c33 perf($compile): use createMap() for directive bindings to allow fast forEach
Closes #12529
2016-04-13 12:05:30 +03:00
Georgii Dolzhykov d20ba95e28 docs(Module): fix parameter names for .decorator()
Closes #14413
2016-04-12 14:52:18 +03:00
aortyl 7945e5010a docs(guide/scope): add comma for readability
Closes #14411
2016-04-11 22:22:36 +03:00
Jason Bedard 21d148aedc refactor($compile): move setting of controller data to single location
Closes #13421
2016-04-11 18:54:41 +01:00
Georgios Kalpakas 4c8aeefb62 fix($compile): do not use noop() as controller for multiple components
Currently, custom annotations are copied from the CDO onto the controller constructor.
Using `noop()` when no controller has been specified, pollutes it with custom annotations and
makes one component's annotations available to all other components that have `noop()` as their
controller.

Fixes #14391
Closes #14402
2016-04-11 18:43:17 +01:00
a510 d384834fde fix($injector): ensure functions with overridden toString() are annotated properly
Closes #14361
2016-04-11 13:03:56 +03:00
David Rodenas Pico f975d8d448 fix(ngClass): fix watching of an array expression containing an object
Closes #14405
2016-04-11 12:40:36 +03:00
Georgios Kalpakas 2602daf993 refactor($compile): remove unnecessary call to isDefined()
(As discussed in https://github.com/angular/angular.js/pull/14406/files#r59131398.)
2016-04-11 12:33:07 +03:00
Gene McCulley 9f681c459a docs(numberFilter): fix the description of the returned value
Closes #14408
2016-04-11 12:28:08 +03:00
Peter Bacon Darwin d9448dcb9f fix($compile): still trigger $onChanges even if the inner value already matches the new value
Closes #14406
2016-04-10 20:31:01 +01:00
Jurko Gospodnetić e9c718a465 fix(ngMock): fix collecting stack trace in inject() on IE10+, PhantomJS
Add support for collecting current stack trace information in browsers
(e.g. IE10+, PhantomJS) that do not automatically store the current stack trace
information in a newly created `Error` object's `stack` property, but
only add it there once the `Error` gets thrown.

The original implementation works fine in Firefox & Chrome, but fails on IE10+
and PhantomJS where it, for example, breaks Karma's error reporting in cases
when an exception is thrown in a test like the following:

```
it('the holy crusade', inject(function() {
  var x = {};
  x.holyGrail();
}));
```

In this case, the ngMock `inject()` implementation would incorrectly add the
word `undefined` at the end of the collected error stack trace information,
thus causing the main error description to be reported back to Karma as
`undefined`.

The added test makes sure this functionality:

- works as expected in browsers supporting JavaScript stack trace
  collection, e.g. Chrome, Firefox, IE10+, Opera & PhantomJS
- does not add any bogus stack track information in browsers that do
  not support JavaScript stack trace collection, e.g. IE9

Fixes #13591
Closes #13592

Closes #13593
2016-04-09 20:51:22 +03:00
Georgios Kalpakas 4dc44f7205 test(helpers): fix error message generation for toHaveBeenCalledOnce[With] matchers
Jasmine 2.4 (maybe earlier) does not support returning an array containing both the "normal" and the
negative error messages. It will always concatenate them.

Closes #14275
2016-04-09 17:06:47 +03:00
Jan Niehusmann 499e1b2adf fix($compile): handle boolean attributes in @ bindings
Commit db5e0ff handles initial values of boolean attributes. The same
change needs to be applied inside the attrs.$observe() call.

Closes #14070
2016-04-09 16:53:41 +03:00
Peter Bacon Darwin 28c6c4dae2 docs(jqlite): add known issue
Closes #14251
2016-04-08 21:27:21 +01:00
Peter Bacon Darwin 791148a328 chore(package.json): update dgeni-packages to 0.12.0
This gives us `@knownissues` tags
2016-04-08 21:27:05 +01:00
Peter Bacon Darwin 01b1845088 feat($http): support handling additional XHR events
Closes #14367
Closes #11547
Closes #1934
2016-04-08 19:16:56 +01:00
Chris Chua 56c861c9e1 feat($http): support handling additional XHR events
Closes #11547
Closes #1934
2016-04-08 19:16:49 +01:00
Martin Staffa 451e0f6175 docs(README): fix typo 2016-04-08 19:00:20 +02:00
Martin Staffa aee7f1c72f docs(guide/accessibility): make jshint happy 2016-04-08 18:55:22 +02:00
Pablo Iván G. Soto 5fe28a0422 docs(README): add https links, improve style 2016-04-08 18:37:04 +02:00
Martin Staffa f56586d9a9 docs(guide/Accessibility): fix markdown errors, tweak layout 2016-04-08 17:32:13 +02:00
mohamed amr ec0baadcb6 feat(ngAria): add support for aria-readonly based on ngReadonly
Closes #14140
Closes #14077
2016-04-08 17:32:12 +02:00
Martin Staffa 9147d5c04a docs(ngComponentRouter): add note about shims needed for IE 2016-04-08 17:32:12 +02:00
Josh cb801378c9 docs(ngComponentRouter): fix typo
Simple typo fix from `betweent he` to `between the`

Closes #14396
2016-04-08 15:47:01 +02:00
Martin Staffa 79604f4628 fix(ngAnimate): remove event listeners only after all listeners have been called
The fix for removing the event callbacks on destroy introduced in
ce7f400011 removed the events too early, so that the event callbacks
for the "close" phase in "leave" animations were not called.

This commit fixes the behavior so that the event callbacks are only removed during on('$destroy')
when no animation is currently active on the element. When an animation is active, the event callbacks
will be removed after all callbacks have run, and if the element has no parent (has been removed from
the DOM).

Closes #14321
2016-04-08 15:47:00 +02:00
Martin Staffa bf6cb8ab0d feat(ngAnimate): let $animate.off() remove all listeners for an element 2016-04-08 15:46:59 +02:00
Andrew de74b3fd85 docs(guide/Components): fix small single letter typo
line 136: 'not' should be 'note'

Closes #14390
2016-04-08 01:32:00 +02:00
Martin Staffa c7a92d2a9a fix(ngAnimate): fire callbacks when document is hidden
Since commit a3a7afd3aa, animations are not run
when the document is hidden (only their structural or class change effects are executed).
However, some libraries rely on the $animate.on() callbacks to be called even when no actual animation
runs.
This commit restores the behavior for the ngAnimate.$animate functions.
Note that callbacks still won't be called if animations are disabled, because this would be be a potential
breaking change, as some applications might rely on this implementation.

Fixes #14120
2016-04-08 01:31:59 +02:00
Martin Staffa da284fc354 test(ngAnimate): test calling callbacks for various constellations 2016-04-08 01:31:58 +02:00
Martin Staffa 90da3059ce fix(ngAnimate): fire callbacks in the correct order for certain skipped animations 2016-04-08 01:31:58 +02:00
SHAHRUKH-KHAN 651fd05eca docs(angular.equals): add example
This Pull requests improves the doc by adding a example to `angular.equals` function.

Closes #14232
2016-04-07 15:17:54 +02:00
glenr4 85d7e09bef docs(ngAnimate): fix toggle button in example
The toggle button code on line 153 only sets bool to true, rather than toggling it.
The proposed change fixes this.

Closes #14387
2016-04-07 15:17:54 +02:00
andykuszyk 243a57648b docs(misc/Getting Started): fix markdown for headings
Closes #14353
2016-04-07 15:17:54 +02:00
Maciej Kołodziejczak 158dec330c docs(ngComponentRouter): fix a typo
Closes #14357
2016-04-07 15:17:53 +02:00
Andrew a1e63c8d4a docs(guide/Components): clarify output events with extra example and note
Add additional line from example which demonstrates using the snake cased attribute binding in
parent component template.
Add note clarifying camelCase to snake-case requirement to use the Output binding callback feature.

Closes #14365
2016-04-07 15:17:53 +02:00
Artur 8cc9978d15 docs(guide/Components): fix typo, improve style
Closes #14384
2016-04-07 15:17:52 +02:00
Robin Janssens 78a404da0e docs($httpBackend): update response data types
Updated docs to reflect that response data can either be an array, object _or_ a string
Technically, response data can be anything that can be handled by angular.copy,
but since string and JSON data is most commonly mocked, the main types are sufficient.

Closes #14346
2016-04-07 15:17:52 +02:00
Michał Gołębiowski f1bb8369b5 refactor(jshint): don't assume browser-only globals
(cherry-picked from ddad26402b)

Fixes #13442
Closes #14345
2016-04-06 20:43:06 +02:00
Peter Bacon Darwin 76b6941b4c docs(componentRouter): add custom installation instructions 2016-04-05 21:10:19 +01:00
Peter Bacon Darwin e72990dc37 fix($compile): don't throw if controller is named 2016-04-04 21:26:13 +01:00
Peter Bacon Darwin f338e96ccc feat($compile): put custom annotations on DDO
Closes #14369
Closes #14279
Closes #14284
2016-04-04 20:07:31 +01:00
Peter Bacon Darwin 0ad2b70862 fix($compile): ensure that $onChanges hook is called correctly
Due to the way that we instantiate controllers, the `$onChanges` hook
was not always available at the time we were trying to trigger the initial
call to this hook. For instance, if the hook was actually defined inside
the constructor function.

This commit fixes that but also fixes the fact that the initial call was
being made in the postDigest anyway, which was incorrect because the
it should have been made before the `$onInit` call.

Closes #14355
Closes #14359
2016-04-01 17:41:41 +01:00
Georgios Kalpakas 5261a374a9 test($browser): fix typo in property name (histroy --> history)
(The semantics of the test aren't affected, because we just needed a falsy value.)
2016-03-31 13:30:25 +03:00
Martin Staffa 832eba5fc9 fix(ngOptions): set select value when model matches disabled option
When ngModel is set to a value that matches a disabled option, ngOptions will now select the option
in the select element, which will set select.val() to the option hash value and visually
show the option value / label as selected in the select box. Previously, disabled
options forced the unknown value.
The previous behavior is inconsistent with both default HTML behavior and select with
ngModel but without ngOptions. Both allow disabled values to be selected programmatically.

A common use case for this behavior is an option that was previously valid, but has
been disabled, and cannot be selected again.

This commit removes a duplicate test, and all other tests that previously checked that disabled
options are not set have been adjusted to the ensure the opposite.

Fixes #12756
2016-03-30 11:42:07 +02:00
cscport 2b569fc0b2 docs(angular.bootstrap): fix capitalization in error message
Closes #14325
2016-03-27 15:43:37 +03:00
Lucas Mirelmann ee6aeb08bf docs(ngParseExt): Fix package name 2016-03-27 00:00:14 +01:00
Peter Bacon Darwin 8d43d8b8e7 feat($compile): add isFirstChange() method to onChanges object
Closes #14318
Closes #14323
2016-03-26 20:06:13 +00:00
Lucas Mirelmann d08f5c6986 feat(ngParseExt): New ngParseExt module
New ngParseExt module

Including this module into an application will extend $parse to allow identifiers
following ES6 identifiers
2016-03-26 20:41:11 +01:00
Lucas Mirelmann 3e7fa19197 feat($parse): Add the ability to define the identifier characters
Add the ability to define the identifier starts and identifier continue characters
2016-03-26 20:41:01 +01:00
Lucas Mirelmann 5d379db72b chore(bower): Add parse-ext repository 2016-03-26 20:40:49 +01:00
Peter Bacon Darwin 514639b585 docs(CHANGELOG): add 1.5.3 release notes 2016-03-25 20:01:45 +00:00
Peter Bacon Darwin 9cd9956dcb feat($compile): add more lifecycle hooks to directive controllers
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   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.

Closes #14127
Closes #14030
Closes #14020
Closes #13991
Closes #14302
2016-03-25 12:56:08 +00:00
Martin Staffa c7813e9ebf fix(ngAnimate): run structural animations with cancelled out class changes
When multiple animations on the same element are queued before a $digest passes,
the animator tries to create as few actual animations as possible by joining / canceling
redundant animations. Class-based animations for example are cancelled when the classes that
are added and removed are the same, and the result is no class-change. This however must only
happen if there's no structural animation currently queued.

Fixes #14249
2016-03-24 00:13:16 +01:00
Martin Staffa ef91b04cdd fix(ngMessages): don't crash when nested messages are removed
Under specific circumstances, ngMessages would go into an infinite loop and crash the
browser / page:
- At least two ngMessage elements are wrapped inside another element (e.g. ngTransclude)
- The first message is currently visible
- The first message is removed (e.g. when the whole ngMessages element is removed by an ngIf)

When a message is removed, it looks for a previous message - in this specific case it would misidentify
the second message for a previous message, which would then cause the first message to be marked as the
second message's next message, resulting in an infinite loop, and crash.

This fix ensures that when searching for previous messages, ngMessage walks the DOM in a way so
that messages that come after the current message are never identified as previous messages.

This commit also detaches and destroys all child ngMessage elements when the ngMessages element is
destroyed, which should improve performance slightly.

Fixes #14183
Closes #14242
2016-03-24 00:13:16 +01:00
Alex Chuev 1acd97e18f docs(guide/component): add missing closing bracket
Closes #14299
2016-03-23 23:58:35 +02:00
Daniel Herman 513199ee9f fix($compile): workaround a GC bug in Chrome < 50
In the version of V8 used in Chrome < 50, the parent of template nodes for
`transclude: "element"` directives would be improperly garbage collected
despite still having been referenced via `parentNode`.

This bug surfaced due to the introduction of lazy transclusion (652b83e),
and appears under certain circumstances when using directive start and end elements.

It should be removed some time after Chrome 50 has been released.

Fixes #14041
Closes #14286
2016-03-23 22:06:17 +01:00
pmadruga 33f3c40e93 docs(error/$compile.baddir): mention "components" in directive name error
Closes #14212
2016-03-23 22:18:54 +02:00
Steve Mao 696cb95d5e docs($q): mention ES2015 (as a "synonym" for ES6) and remove "harmony"
Closes #14294
2016-03-22 12:09:02 +02:00
Georgios Kalpakas 457fd21a1a fix($sniffer): fix history sniffing in Chrome Packaged Apps
Although `window.history` is present in the context of Chrome Packaged Apps, it is not allowed to
access `window.history.pushState` or `window.history.state`, resulting in errors when trying to
"sniff" history support.
This commit fixes it by detecting a Chrome Packaged App (through the presence of
`window.chrome.app.runtime`). Note that `window.chrome.app` is present in the context of "normal"
webpages as well, but it doesn't have the `runtime` property, which is only available to packaged
apps (e.g. see https://developer.chrome.com/apps/api_index).

(It also also contains some style changes for making the structure and layout of `$sniffer` tests
 more consistent.)

Fixes #11932

Closes #13945
2016-03-22 11:57:18 +02:00
Wassim Chegham 3c6dfbf67d docs(guide/component-router): fix typos
Closes #14278
2016-03-22 02:18:44 +02:00
Owen Craig 3277b885c4 fix(formatNumber): handle small numbers correctly when gSize !== lgSize
By using `>=` when comparing the number length to `lgSize`, we'll provide the correct value, when
formatting numbers with different `lgSize` than `gSize`.

Fixes #14289

Closes #14290
2016-03-22 00:11:26 +02:00
Georgios Kalpakas 48a256d04b test(TzDate): fix test in Australia
Probably due to implementation differences in browsers for pre-DST period (see
https://github.com/angular/angular.js/issues/5017 and especially
https://github.com/angular/angular.js/issues/5017#issuecomment-90775226 for context), some
`TzDate` tests had different behavior on different Timezones/Regions (e.g. failed in Australia,
which started to observe DST in 1971).
Since the used year (`1970`) didn't have any particular significance, this commit fixes the issue
by using a year that is more consistently handled by browsers (`2000`).

Fixes #14272

Closes #14285
2016-03-21 20:45:35 +02:00
surya prakash singh 0579430799 docs(input[time]): fix a typo in the example
Closes #14220
2016-03-21 01:26:17 +02:00
Rongduan Zhu 39ac68dac1 docs(guide/component-router): changed path to match diagram
Closes #14277
2016-03-21 00:00:12 +02:00
Georgios Kalpakas 87fb44a5d3 docs(CHANGELOG.md): rearrange v1.5.1 to be right below v1.5.2
Moved the `v1.5.1` section above the `v1.4.10` one, so that it is right below the `v1.5.2` section
for easier reference. Also removed an empty "Breaking Changes" sub-section.

Closes #14283
2016-03-20 22:54:53 +02:00
Georgios Kalpakas 5c76b406f7 chore(ci-checks): fix the ddescribe-iit task for Jasmine 2
Closes #14276
2016-03-20 22:26:06 +02:00
Matias Niemelä f665968daf chore(CHANGELOG): update version reference 2016-03-18 15:37:43 -07:00
Matias Niemelä 5d1291c29d docs(CHANGELOG): add notes for v1.5.2 2016-03-18 15:04:06 -07:00
Martin Staffa ce7f400011 fix(ngAnimate.$animate): remove animation callbacks when the element is removed
The test for this didn't actually test the listener removal. The addClass animation after
the element removal didn't start because the enter animation was still in progress.
2016-03-18 17:10:26 +01:00
Martin Staffa 0fc8516b0c Revert "tests(jQuery): test on both oldest & latest supported jQuery version"
This reverts commit 94572e89c2. The commit snuck
in while cherry-picking commits from master.
2016-03-18 17:08:46 +01:00
Jason Bedard 28b2a9b583 style($compile,$controller): adding function names for debug/tracing
Closes #13420
2016-03-18 15:53:09 +01:00
Jason Bedard e8549372fc style($templateRequest): rename minError var to avoid name conflict
Closes #13701
2016-03-18 15:53:08 +01:00
Jason Bedard 5a434eb74e style(ngModel,ngOptions): make use of declared but unused variables 2016-03-18 15:53:06 +01:00
Jason Bedard 318de4db66 style(*): remove unused variables 2016-03-18 15:53:05 +01:00
Martin Staffa a6c79bf15d docs(guide/Services): add whitespace in code example
Closes #14156
2016-03-18 15:53:04 +01:00
Huc Arnaud c6a10a755e docs(error/tplrt): add missing ' in example code
Missing a ' @ line 46 class='wrapper'

Closes #14258
2016-03-18 15:53:03 +01:00
Maxim Salnikov 1d7bd5bf4f docs(guide/Component Router): fix typo in example code
Closes #14262
2016-03-18 15:53:03 +01:00
Michał Gołębiowski 94572e89c2 tests(jQuery): test on both oldest & latest supported jQuery version 2016-03-18 15:51:30 +01:00
Peter Bacon Darwin fee7bac392 revert: fix($compile): do not add <span> elements to root text nodes
This commit reverts 7617c08da6 which was accidentally
merged into 1.5.x (by @petebacondarwin in a moment of rebase madness) despite
it containing a breaking change.
2016-03-17 09:56:30 +00:00
Georgios Kalpakas dbb3b0f561 docs(CHANGELOG.md): add notes for v1.4.10 2016-03-16 21:17:02 +02:00
Michał Gołębiowski b8bfed6a52 tests(jQuery): make the tests pass on jQuery 3.0.0-beta1
Closes #14229
2016-03-16 18:29:13 +00:00
Georgios Kalpakas 7215a89e7d docs(CHANGELOG.md): fix typo in anchor name 2016-03-16 19:56:23 +02:00
Georgios Kalpakas b7cca56091 docs(CHANGELOG.md): add notes for v1.5.1 2016-03-16 19:53:43 +02:00
Josh Schneider 7338e433f8 docs(guide/component-router): fix incorrect hook name for $canActivate
The hook will most likely be named back to `$routerCanActivate` in the future,
but for now this change is accurate.

Closes #14237
2016-03-16 16:46:03 +00:00
Peter Bacon Darwin 119ed07d5a chore(travis): update node and browser versions 2016-03-16 14:08:10 +00:00
Peter Bacon Darwin 5f98ae8323 chore(package.json): fix up dist-tag
Now that 1.5.x is out of beta we need to change the dist-tag to `latest`
2016-03-16 14:08:10 +00:00
Peter Bacon Darwin 8a598b43bb chore(jenkins): update node version to 4.4 2016-03-16 14:08:10 +00:00
Peter Bacon Darwin e5dff4cfbe chore(jenkins): fix node version chooser in build scripts
The `set-node-version.sh` script was being run in its own shell and so
was not actually changing the current version of node.
2016-03-16 14:08:10 +00:00
Lucas Mirelmann 6c7a9cdd5f chore(*): Upgrade to Jasmine 2.4
Highlights:
New mechanism to run async tests as Jasmine 2 removed `runs`, `waits` and `waitsFor`
The functions `iit`, `ddescribe` and `tthey` were renamed `fit`, `fdescribe` and
`fthey` as the originals came from Karma, Karma no longer bundles Jasmine and the
new function name comes from Jasmine.

Closes #14226
2016-03-16 14:08:09 +00:00
Matias Niemelä 3b34f762fe chore(build): 1.5 versions should stick to 1.5.x 2016-03-16 14:06:49 +00:00
Martin Staffa fa167ba747 docs(guide/animations): fix code block styling 2016-03-16 14:06:49 +00:00
Peter Bacon Darwin a4e60cb697 docs(guide/location): include section on base[href]
Closes #14018
2016-03-14 14:45:29 +00:00
Lucas Mirelmann 81150ac77d feat($parse): Allow user-defined literals
Allow user-defined literals.

Close: #9504
Close: #9492
Close: #14194
2016-03-13 20:41:23 +01:00
lordg 7ecfa5deba docs(guide/Component Router): adjust the order in the menu
Component Router should come after the menu topic Components as Components should be understood first
before Component Routers. This made it easier to read the Component Routers topic.

Closes #14214
2016-03-11 14:21:38 +01:00
Martin Staffa 567f9b0136 chore: streamline issue/pr templates
Removes the bullet points and makes all prompts bold,
which should make it easier to see which content has been
added by the issue author
2016-03-11 14:21:16 +01:00
Thanos Korakas 0c2d3988ab docs(guide/component): use ctrl instead of this (for consistency)
Closes #14215
2016-03-11 09:34:14 +02:00
Gordon Zhu efd448d7d3 docs(guide/unit-testing): fix typo
Closes #14198
2016-03-09 00:54:07 +02:00
mohamed amr db281c133d refactor(*): use toBeUndefined consistently
Closes #14185
Fixes #14184
2016-03-07 10:35:54 +00:00
Peter Bacon Darwin 6a336ba6a0 docs(guide/component-router): initial draft for component router 0.2.0
Closes #14131
2016-03-04 13:57:15 +00:00
Martin Staffa 67a98112e4 docs($provide): clarify value and constant injectability
Closes #14168
2016-03-04 10:02:28 +01:00
Ciro Nunes f1aea54a9b docs(ngModel.NgModelController): fix typo
Closes #14157
2016-03-02 19:22:19 +01:00
Martin Staffa 663788d8c1 docs(changelog, migration): add BC notice for allowed form name values
Introduced by https://github.com/angular/angular.js/commit/94533e570673e6b2eb92073955541fa289aabe02

Closes #13771
2016-03-02 19:03:31 +01:00
Tim Ruffles af0574ebaa feat(ngMock): add sharedInjector() to angular.mock.module
Allow to opt-in to using a shared injector within a context. This allows  hooks to be
used in Jasmine 2.x.x/Mocha

Closes #14093
Closes #10238
2016-03-01 11:38:27 +00:00
Ivo Mirra 4883e95797 refactor(*): move noop functions to angular.noop
Closes #14151
2016-02-29 18:08:03 +01:00
Georgios Kalpakas 9c7c494c3e docs(errorDisplay): encode < and > in error messages
When an error message contains an HTML string (e.g. `$location:nobase` containing `<base>`), it was
interpreted as a literal HTML element, instead of text. Error messages are not expected to render
as HTML, but we still need to use `.html()` in `errorDisplay`, so that the links created by
`errorLinkFilter` are properly displayed.
This commit solves this issue by replacing `<`/`>` with `&lt;`/`&gt;`.

Related to #14016.
2016-02-29 17:19:29 +01:00
Georgios Kalpakas 321180af13 test(docs): add tests for the errors module 2016-02-29 17:19:29 +01:00
Jason Bedard e2898c9436 refactor($compile): move setup/get controller methods out of the compile node closure
Closes #13427
2016-02-29 17:19:29 +01:00
Jason Bedard c52d0957de refactor($compile): remove out of date jQuery vs jqLite comment/workaround 2016-02-29 17:19:29 +01:00
Nabil Hashmi 7bdc6cb358 docs($http): fix typo in link text (TransformationjqLiks --> Transformations)
Closes #14149
2016-02-28 23:07:45 +02:00
Martin Staffa 2c54a3c081 fix(ngOptions): always set the 'selected' attribute for selected options
We don't set selected property / attribute on options that are already selected.
That happens for example if the browser has automatically selected the first
option in a select. In that case, the selected property is set automatically, but
the selected attribute is not. This doesn't impact the functionality of the select,
but it can be problematic if option elements are selected with `option[selected]` in tests.

Closes #14115
Closes #14125
2016-02-28 16:12:38 +01:00
lordg 5078c76c5d docs(guide/Interpolation): fix code example
The function getForm is receiving a variable from the view and should be using that.

Closes #14142
2016-02-28 16:04:11 +01:00
Matt Janssen 30a7e3a144 docs(guide/Components): add missing $ctrl
docs(guide/Components): add missing $ctrl

The new component example does not work as is. It needs a missing reference to $ctrl.

Closes #14138

Closes #14143
2016-02-28 16:02:42 +01:00
Georgii Dolzhykov a6afa780b7 docs(guide/Services): improve the code example
A factory that doesn't return anything is a bad example of a factory.

Closes #14139
2016-02-28 15:56:49 +01:00
lordg 3faa01fb15 docs(guide/Templates): add title for consistency
Closes #14141
2016-02-28 15:56:44 +01:00
Martin Staffa 0f5bcb7356 docs(guide/interpolation): make some minor improvements, add info
- highlight that interpolation inside expressions is bad practice
- add info about type attr in buttons in IE
2016-02-28 15:56:39 +01:00
lordg db1cf6d293 docs(guide/Filters): add title for consistency
Closes #14143
2016-02-28 15:13:01 +01:00
mohamed amr 6253de3913 test(ngAria): remove incorrect closing div tag after input element
Closes #14146
Closes #14147
2016-02-28 14:58:50 +01:00
Lucas Mirelmann 32feb2b45f refactor($compile): Create non-descriptive comments when debugInfoEnabled is false
When debugInfoEnabled is `false` when comments generated by transclusions, ngIf,
ngRepeat and ngSwitch will not contain any information about the directive nor
the expression associated with it.

Closes: #8722
2016-02-25 20:18:59 +01:00
Georgios Kalpakas 5e37b2a7fd fix(ngRoute): allow ngView to be included in an asynchronously loaded template
During it's linking phase, `ngView` relies on the info provided in `$route.current` for
instantiating the initial view. `$route.current` is set in the callback of a listener to
`$locationChangeSuccess`, which is registered during the instantiation of the `$route` service.

Thus, it is crucial that the `$route` service is instantiated before the initial
`$locationChangeSuccess` is fired. Since `ngView` declares `$route` as a dependency, the service is
instantiated in time if `ngView` is present during the initial load of the page.

Yet, in cases where `ngView` is included in a template that is loaded asynchronously (e.g. in
another directive's template), the directive factory might not be called soon enough for `$route`
to be instantiated before the initial `$locationChangeSuccess` event is fired.

This commit fixes it, by always instantiating `$route` up front, during the initialization phase.

Fixes #1213
Fixes #6812

Closes #14088
2016-02-25 11:54:20 +02:00
Martin Staffa 0749eb44e5 docs($http): add a note about modifying data in transformRequest
Closes #12468
2016-02-24 17:35:54 +01:00
Peter Bacon Darwin c900b9c531 docs(guide/security): provide more information about security features
Thanks to Jim Manico for help updating this guide.
2016-02-24 13:19:05 +00:00
Steve Shaffer 6a4597b47d docs(guide/Internet Explorer Compatibility): Add ng-attr-type workaround for buttons in IE
Closes #14117
Closes #14119
2016-02-24 11:39:58 +00:00
Foxandxss d7cb37032b chore(ISSUE_TEMPLATE): fix typo in ISSUE_TEMPLATE
Closes #14121
2016-02-24 11:36:47 +00:00
Vadorequest 76f47d5632 feat($controllerProvider): add a has() method for checking the existence of a controller
Fixes #13951

Closes #14109
2016-02-24 00:00:13 +02:00
Georgios Kalpakas 871bebf7dc fix(ngMock): don't break if $rootScope.$destroy() is not a function
Previously, `angular-mocks` was calling `$rootScope.$destroy()` after each test as part of it's
cleaning up, assuming that it was always available. This could break if `$rootScope` was mocked
and the mocked version didn't provide the `$destroy()` method.
This commit prevents the error by first checking that `$rootScope.$destroy` is present.

Fixes #14106

Closes #14107
2016-02-23 23:18:18 +02:00
Peter Bacon Darwin 7e112c1fc3 feat($compile): add custom annotations to the controller
This means that we can access these annotations, such as
`$routeConfig` and `$routerCanActivate` without highjacking
the `ng` module.

Closes #14114
2016-02-23 18:55:18 +00:00
Georgios Kalpakas 59aef48281 refactor(ngMock): make ngMock minification-safe
It is not common, but some workflows result in `angular-mocks` being minified.

Fixes #13542

Closes #14073
2016-02-23 14:22:52 +02:00
marvin sl 2ffda41ab0 docs(guide/animations): fix typos in example
Closes #14111
2016-02-23 14:12:53 +02:00
Igor Dolgov f70237a3e8 docs(ngMock): add missing ")" in example
Closes #14112
2016-02-23 13:51:47 +02:00
Martin Staffa 3c86212710 chore: add issue and PR templates 2016-02-22 23:19:45 +01:00
Georgios Kalpakas 85ef70f428 fix(ngMock): prevent memory leak due to data attached to $rootElement
Starting with 88bb551, `ngMock` will attach the `$injector` to the `$rootElement`, but will never
clean it up, resulting in a memory leak. Since a new `$rootElement` is created for every test,
this leak causes Karma to crash on large test-suites.
The problem was not detected by our internal tests, because we do our own clean-up in
`testabilityPatch.js`.

88bb551 was revert with 1b8590a.
This commit incorporates the changes from 88bb551 and prevents the memory leak, by cleaning up all
data attached to `$rootElement` after each test.

Fixes #14094

Closes #14098
2016-02-22 15:57:10 +02:00
anh a7244fdcb0 docs(guide/component): fix $componentController usage
Fixes #14091

Closes #14092
2016-02-22 13:41:09 +02:00
Martin Staffa 565391d30a chore(travis): update Chrome and FF versions, add Safari 9
Closes #13888
2016-02-22 11:24:32 +00:00
Georgios Kalpakas a88473db8a test($resource): clean up commented out code
Closes #13891
Closes #13895
2016-02-22 11:21:02 +00:00
Ben Elliott 68f528aa04 docs(ngMessages): clarify ngMessages docs with clearer example
Closes #14103
2016-02-22 12:04:43 +01:00
Kin 3671adbba6 docs(numberFilter): improve wording for infinity description
Closes #14100
2016-02-22 12:04:43 +01:00
Kin 1edb13f784 docs(angular.forEach): fix typo 2016-02-22 12:04:43 +01:00
Ryo Utsunomiya 113a946a99 docs(guide/components): fix typo
Closes #14099
2016-02-21 10:03:15 +00:00
Gordon Zhu 70caf84634 docs(guide/index): add Firebase Foundations and Angular Course
Closes #14097
2016-02-21 07:52:03 +00:00
Matias Niemelä 1b8590a7c5 revert: fix(ngMock): attach $injector to $rootElement
This reverts commit 88bb5518eb.

The fixes applied in the reverted commit caused a memory leak
with JQuery + Karma.
2016-02-20 21:33:29 -08:00
Georgios Kalpakas 9955bd05ed docs(guide/migration): remove redundant horizontal ruler 2016-02-21 01:18:39 +02:00
Yonatan Kra 02a9543189 docs(guide/component): make clear when required controllers are available
It was unclear that the required controllers are available only just before the `$onInit` lifecycle
hook is triggered.

Closes #14096
2016-02-21 01:12:51 +02:00
TepigMC eda7ef66f7 docs(README.md): fix typo
Closes #14090
2016-02-21 00:50:58 +02:00
MicCarr 2d6c218327 docs(ngMock): fix typo in example
Closes #14069
2016-02-18 14:12:26 +02:00
Jason Bedard 7324804bf5 fix(input): re-validate when partially editing date-family inputs
Fixes #12207
Closes #13886
2016-02-18 10:54:30 +02:00
ryanhart2 84c04b0b68 docs($http): improve description of caching
Included changes:

* Point out that only GET & JSONP requests are cached.
* Explain that the URL+search params are used as cache keys (headers not considered).
* Add note about cache-control headers on response not affecting Angular caching.
* Mention `$httpProvider.defaults.cache` (in addition to `$http.defaults.cache`).
* Clear up how `defaults.cache` and `config.cache` are taken into account for determining the
  caching behavior for each request.

Fixes #11101
Closes #13003
2016-02-18 00:54:18 +02:00
Jason Bedard 735be18344 fix(formatNumber): allow negative fraction size
Closes #13913
2016-02-17 15:42:17 +02:00
Aftab Ansari 3ea4477266 docs(README.md): fix typo
Closes #14062
2016-02-17 15:30:39 +02:00
Georgios Kalpakas 0b1b9112a3 fix(copy): add support for copying Blob objects
Although `copy()` does not need to (and never will) support all kinds of objects, there is a
(not uncommon) usecase for supporting `Blob` objects:

`ngMock`'s `$httpBackend` will return a copy of the response data (so that changes in one test won't
affect others). Since returning `Blob` objects in response to HTTP requests is a valid usecase and
since `ngMocks`'s `$httpBackend` will use `copy()` to create a copy of that data, it is reasonable
to support `Blob` objects.
(I didn't run any benchmarks, but the additional check for the type of the copied element should
have negligible impact, compared to the other stuff that `copy()` is doing.)

Fixes #9669

Closes #14064
2016-02-17 14:33:50 +02:00
Martin Staffa 489835dd0b chore(docs-app): fix middle/right dropdown clicks in FF
Closes #14024
2016-02-17 11:23:05 +01:00
Martin Staffa adbc2b10d2 chore(docs-app): remove obsolete directives
Most of the directives in bootstrap.js haven't been in use since
https://github.com/angular/angular.js/commit/389d4879da4aa620ee95d789b19ff9be44eb730a:
Dropdown-related directives were moved to dropdown-toggle.js, and for
foldout, popover and syntax, the uses and tests were removed, but not the directives themselves.

The last use of tabbable was removed in
https://github.com/angular/angular.js/commit/6b7a1b82bc26bbf4640506a9a3cf37ebf254d3d2
2016-02-17 11:23:05 +01:00
biohazardpb4 ea6c2473c1 fix(ngMockE2E): pass responseType to $delegate when using passThrough
The `ngMockE2E` `$httpBackend` has a mechanism to allow requests to pass through, if one wants to
send a real HTTP request instead of mocking. The specified `responseType` of the request was never
passed through to the "real" `$httpBackend` (of the `ng` module), resulting in it being effectively
ignored.

Fixes #5415

Closes #5783
2016-02-17 00:53:38 +02:00
Georgios Kalpakas b43768a345 docs(guide/forms): make required ngModel optional in custom e-mail RegExp example 2016-02-16 22:52:21 +02:00
Alexander e47957248f docs(guide/component): use fieldType property in component's template
Closes #14059
2016-02-16 22:43:02 +02:00
srijan 019900d7c2 docs(guide/scope): fix typo in image
Closes #13724
2016-02-16 21:49:45 +02:00
Georgios Kalpakas 88bb5518eb fix(ngMock): attach $injector to $rootElement
Fixes #14022

Closes #14034
2016-02-16 21:37:58 +02:00
Martin Staffa 3940edced4 test(*): ensure console log doesn't break the app in IE9
When Angular is loaded more than once (by including the script multiple times),
a warning is logged in the console. IE9 only makes the console available when
the dev tools are open, so before this fix, the browser would throw an error

Note that Protractor doesn't actually support IE9.
2016-02-16 17:01:13 +01:00
lucienbertin 7c60e19eb8 fix(*): only call console.log when window.console exists
`window.console` only exists in IE 8 & 9 when the devtools are open

Fixes #14006
Closes #14007
Closes #14047
2016-02-16 17:00:55 +01:00
alex-teren 632fa30fe3 docs(README.md): fix casing
Closes #14050
2016-02-16 14:46:43 +02:00
Sean Murphy bf2a76d32f fix($routeProvider): properly handle optional eager path named groups
Closes #14011
2016-02-16 14:29:43 +02:00
Lucas Mirelmann 9421674dad fix(dateFilter): Correctly format BC years
- Correctly format BC years
- Fix a function name collition
- Allow TzDate to use BC years
2016-02-14 20:17:42 +01:00
Remy Sharp ece8266b01 docs(error/$location:nobase): fix <base> not showing up in heading
Closes #14016
2016-02-13 20:14:42 +02:00
Wesley Cho b8b5b885f7 docs($compile): change component example to use controllerAs
Closes #14010
2016-02-12 12:30:01 +01:00
Georgios Kalpakas e4e30961ca feat(dateFilter): add support for STANDALONEMONTH in format (LLLL)
Fixes #13999

Closes #14013
2016-02-12 13:12:33 +02:00
Lucas Mirelmann 1061c56fe1 fix($compile): allow directives to have decorators
Allow directives to have decorators that modify the directive `scope` property

Close: #10149
2016-02-12 11:24:41 +01:00
Lucas Mirelmann 7617c08da6 fix($compile): do not add <span> elements to root text nodes
BREAKING CHANGE:

Text nodes at the root of transcluded content will no longer be wrapped into <span>
elements. If there is a need for this <span> element to be present, then this should
be added to the content to be transcluded.

Before:

```html
<div directive-that-will-transclude-the-content>
  I expect this content to e wrapped
</div>
```

After:

```html
<div directive-that-will-transclude-the-content>
  <span>I expect this content to e wrapped</span>
</div>
```
2016-02-12 11:23:58 +01:00
Lucas Mirelmann a021a376fc style($compile): Style fixes 2016-02-12 11:20:02 +01:00
Martin Staffa a7d69c9d42 docs: allow plnkr links to open in new window
Closes #8328
Closes #14008
2016-02-11 06:25:57 -08:00
Gabriel Monteagudo f0f6da304c fix($resource): fix parse errors on older Android WebViews
Error is caused by reserved keyword 'finally'.

Closes #13989
2016-02-10 12:32:10 +02:00
Lee Adcock 9425015a69 fix(input[date]): support years with more than 4 digits
Previously, the date-related regular expressions only matched years with no more than 4 digits.
This commit adds support for years with more than 4 digits. It also resolves an ambiguity in
`ISO_DATE_REGEXP` by matching the whole string (when it previosuly allowed extra characters around
the date string).

Fixes #13735
Closes #13905
2016-02-10 11:58:03 +02:00
Martin Sikora 7b592f9edd docs(error/$compile:tplrt): fix typo
Closes #13992
2016-02-10 11:03:05 +02:00
Daniel Herman c966876e57 perf(ngAnimate): avoid jqLite/jQuery for upward DOM traversal
The `parentNode` property is well supported between all browsers.  Since
no other functionality was required here other than traversing upwards
using `.parent()`, we can use the DOM API directly.

Closes: #13879
2016-02-09 21:28:58 +01:00
Daniel Herman bfce0675e2 perf(ngAnimate): avoid $.fn.data overhead with jQuery
Unlike jqLite, jquery scrapes the attributes of an element looking for
data- keys that match the requested property.  When many elements are
being animated due to something like `ngRepeat` unrolling within one
digest cycle, the amount of time spent in that one function quickly adds
up.

By changing our API to use the lower level data API, we can cut the time
spent in this function by half when jQuery is loaded.
2016-02-09 21:28:42 +01:00
Daniel Herman 2e3c6404f2 perf(ngRepeat): avoid duplicate jqLite wrappers
Internally, `$animate` already wraps elements passed through with
`jqLite`, so we can avoid needless duplication here.
2016-02-09 21:28:28 +01:00
Martin Staffa b04871b43f docs(*): clarify limitations of app bootstrapping
- Note that bootstrapping on elements with transclusion directives
is dangerous and not recommended.

- group info on limitations, and add them to the guide

Closes #11421
Closes #13572
Closes #12583
2016-02-09 11:41:54 +01:00
Martin Staffa 4ba8e3463a docs(ngRepeat): clarify limitations of object iteration
Related #6266
2016-02-09 11:36:36 +01:00
Peter Bacon Darwin 9881e77ccb refactor($componentController): don't return an object from the provider constructor function
Closes #13969
Closes #13977
2016-02-08 16:09:41 -08:00
Martin Staffa 17ba2a6e7c docs(guide/Unit Testing): add info about promises
Related #1915
2016-02-08 23:50:28 +01:00
Georgios Kalpakas 3bfeda3b2b docs(guide/migration): document a BC to ngAria (d06431e)
Closes #13949
2016-02-08 23:25:23 +02:00
Martin Staffa 4fed66da6c docs(guide/animation): add info on various topics
- how to enable / disable animations

Closes #8812

- how to handle conflicts with existing animations

Closes #8033
Closes #11820

- what happens on boostrap / how to enable animations on bootstrap
2016-02-08 16:56:36 +01:00
Martin Staffa 7de7059f95 docs: clean up formatting of animation events
Closes #12670
Closes #10742
2016-02-08 16:56:36 +01:00
Aashish Nagpal cff232a8a2 docs(README.md): add purpose section
Add a new purpose section to enable newcomers (technical and non-technical)
better understand the purpose of AngularJS

Close #13963
2016-02-08 02:12:06 -08:00
John Mercer 614ecb7aa6 docs(guide): add new book
Closes #13954
2016-02-08 02:05:47 -08:00
Prayag Verma 77b1407e0d docs(guide/migration): fix typo (a --> an)
Closes #13959
2016-02-06 16:12:04 +02:00
Martin Staffa c4e47e491f docs(error/iscp): include one-way bindings, mark spaces as allowed 2016-02-05 16:12:00 +01:00
Martin Staffa 87ac4443b6 docs(guide/components): update to use one-way binding 2016-02-05 16:12:00 +01:00
Martin Staffa 75f23f0b87 style(filters): squelch a closure compiler warning
Related #13932
2016-02-05 16:05:07 +01:00
Peter Bacon Darwin 39eecd136f docs(CHANGELOG): add notes for 1.5.0 release 2016-02-05 10:04:17 +00:00
kuroky360 260cfe6dc9 refactor(toJson): use the isUndefined() function
Closes #13923
2016-02-04 10:35:48 +02:00
Georgios Kalpakas 455af41a19 docs(guide/migration): mention isolate scope one-way bindings
Closes #13940
2016-02-04 10:28:47 +02:00
campersau f3c8aa2790 refactor(ngAria): remove unused dependency from ngModel directive
Mentioned in https://github.com/angular/angular.js/commit/d06431e5309bb0125588877451dc79b935808134#commitcomment-15871053.

Closes #13942
2016-02-04 01:05:08 +02:00
Georgios Kalpakas e2312e3efd docs(ngRequired): fix link 2016-02-04 00:12:58 +02:00
Georgios Kalpakas a460ce4665 refactor(ngAria): remove redundant '?' in DDO's require
It also fixes some dangling links in Accessibility guide.
2016-02-03 23:54:43 +02:00
Marcy Sutton d06431e530 fix(ngAria): Apply ARIA attrs correctly
BREAKING CHANGE: Where appropriate, ngAria now applies ARIA to custom controls only, not native inputs. Because of this, support for `aria-multiline` on textareas has been removed.

New support added for ngValue, ngChecked, and ngRequired, along with updated documentation.

Closes #13078
Closes #11374
Closes #11830

Closes #13483
2016-02-03 23:18:49 +02:00
Georgios Kalpakas 34ec0d9629 docs(guide/migration): add TOC and fix heading levels
Closes #13938
2016-02-03 20:23:11 +02:00
Martin Staffa 4ac23c0ac5 feat($compile): add one-way binding to the isolate scope definition
This change allows the developer to bind an isolate scope / controller property
to an expression, using a `<` binding, in such a way that if the value of the
expression changes, the scope/controller property is updated but not the
converse.

The binding is implemented as a single simple watch, which can also provide
performance benefits over two way bindings.

Closes #13928
Closes #13854
Closes #12835
Closes #13900
2016-02-03 14:01:21 +00:00
Georgii Dolzhykov 507cf31ff9 docs($compile): refine explanation of isolate scope =-binding
The current version of this paragraph is in many ways inaccurate and confusing.

Closes #13921
2016-02-03 14:59:10 +02:00
Georgios Kalpakas 91414918d7 docs(guide/accessibility): fix links
Closes #13936
2016-02-03 12:17:31 +02:00
Georgios Kalpakas 52c21fe51d docs(CHANGELOG.md): more explicitly mention that the usemap posed security risks
(Related to https://github.com/angular/angular.js/pull/13826#issuecomment-178868005.)
2016-02-03 12:11:50 +02:00
Georgios Kalpakas 2f0a50b526 fix($route): allow preventing a route reload
Fixes #9824
Closes #13894
2016-02-02 23:14:14 +02:00
Georgios Kalpakas 4a80a2e8bc docs(guide/migration): update with changes from v1.5.0-rc.2
Closes #13919
2016-02-02 21:34:47 +02:00
Georgios Kalpakas 446fac84d9 docs(CHANGELOG.md): document 234053f as a BC
Closes #13927
2016-02-02 14:31:36 +02:00
thorn0 43f72066e1 refactor(injector): remove unneeded JSHint directives
Closes #13922
2016-02-02 13:51:53 +02:00
Georgios Kalpakas a909ed1a5c docs(CHANGELOG.md): fix function name ($ngOnInit --> $onInit) 2016-02-01 22:15:49 +02:00
Lucas Mirelmann 1c6edd416b fix($rootScope): Set no context when calling helper functions for $watch
When calling a $watch getter or listener, do not expose the inner workings with `this`.

Closes: #13909
2016-02-01 21:05:34 +01:00
Georgios Kalpakas 8bda5ec735 docs(guide/directive): minor fixes/improvements
Closes #13908
2016-02-01 15:12:19 +01:00
Wojciech Krzystek 23395ce07d docs($http): reword the XSRF attack overview
Previous version emphasised "gaining user's private data".
While this perfectly describes JSON vulnerability (which is based on XSRF),
data theft suits XSS more.
Pure XSRF is more about performing requests that have side effects.

Closes #13901
2016-01-31 13:21:33 +02:00
Prayag Verma c81c9e7cf4 docs(misc/downloading): fix typo (it --> in)
Closes #13899
2016-01-31 10:45:51 +02:00
Georgii Dolzhykov 344b4bcb95 docs(TRIAGING.md): fix a broken link
Closes #13904
2016-01-31 10:37:36 +02:00
Smith 34ba294f76 docs(error/$rootScope:inprog): fix typos ("a $apply" --> "an $apply")
Closes #13896
2016-01-31 10:32:10 +02:00
Prayag Verma 50ecc370b9 docs(guide/component): fix typo (defintion --> definition)
Closes #13898
2016-01-31 10:24:27 +02:00
Georgios Kalpakas 622c421696 fix(dateFilter, input): fix Date parsing in IE/Edge when timezone offset contains :
When `Date.parse`-ing a date string, IE and Edge don't recognize the timezone offset in the format
`+HH:mm` (but only without the `:`). According to [the spec][1], the timezone offset should
contain `:`. The [ISO 8601 Standard][2] allows both forms (with and without `:`).
Although the `Date` implementation in JavaScript does not 100% follow the ISO 8601 Standard (it's
just _based on it_), all other browsers seem to recognize both forms as well.

[1]: http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
[2]: https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC

Fixes #13880

Closes #13887
2016-01-30 00:05:49 +02:00
Dan Ryan db1180f3b3 docs(guide/component): fix fn parameter in example
The wrong field name was being passed into the `$ctrl.update` call in `heroDetail.html` resulting
in the wrong behavior (`name` was being updated instead of `location`)

Closes #13890
2016-01-29 16:48:18 +01:00
Georgios Kalpakas ca5b27bd0b fix(select): handle corner case of adding options via a custom directive
Under specific circumstances (e.g. adding options via a directive with `replace: true` and a
structural directive in its template), an error occurred when trying to call `hasAttribute()` on a
comment node (which doesn't support that method).
This commit fixes it by filtering out comment nodes in the `addOption()` method.

Fixes #13874
Closes #13878
2016-01-29 14:34:57 +02:00
Martin Staffa 3d158f629b docs(ngAnimateChildren) add docs 2016-01-28 21:14:53 +01:00
Martin Staffa 8aecf46ad2 fix(ngAnimateChildren): make it compatible with ngIf
Previously, ngAnimateChildren would set the data on the element
in an $observe listener, which means the data was available after one digest happend.
This is too late when the element is animated immediately after compilation, as happens with ngIf.
Now the data is also set right in the linking function.

Fixes #13865
Closes #13876
2016-01-28 21:14:40 +01:00
Martin Staffa 2072641537 docs(guide/component): add the component guide
- introduce components
- component types are based on Angular2 docs
- conceptually, we promote parent -> child data flow and clear inputs and outputs
- the info about multi-transclusion / requiring controllers, and components as route templates
has been moved from the component docs to the guide
2016-01-28 20:28:03 +01:00
Michael 63154c3d1a docs($compile): minor typo/style correction
Closes #13864
2016-01-28 19:18:20 +02:00
Lucas Mirelmann 37cb9ad436 fix($parse): Copy inputs for expressions with expensive checks
Closes: #13871
2016-01-28 15:33:39 +01:00
Peter Bacon Darwin 5a3504abdc docs(CHANGELOG): add changes for 1.5.0-rc.2 2016-01-28 09:51:01 +00:00
Martin Staffa 0dfc1dfebf fix(ngTouch): deprecate ngClick and disable it by default
This commit deprecates the ngClick directive from the ngTouch module.
Additionally, it disables it by default. It can be enabled in the new $touchProvider with
the $touchProvider.ngClickOverrideEnabled() method.

The directive was conceived to remove the 300ms delay
for click events on mobile browsers, by sending a synthetic click event on touchstart.
It also tried to make sure that the original click event that the browser sends after 300ms
was "busted", so that no redundant "ghost-clicks" appear.

There are various reasons why the directive is being deprecated.

- "This is an ugly, terrible hack!" (says so in the source)
- It is plagued by various bugs that are hard to fix / test for all platforms (see below)
- Simply including ngTouch activates the ngClick override, which means even if you simply want
to use ngSwipe, you may break parts of your app
- There exist alternatives for removing the 300ms delay, that can be used very well with Angular:
[FastClick](https://github.com/ftlabs/fastclick), [Tappy!](https://github.com/filamentgroup/tappy/)
(There's also hammer.js for touch events / gestures)
- The 300ms delay itself is on the way out - Chrome and Firefox for Android remove the 300ms delay
when the usual `<meta name="viewport" content="width=device-width">` is set. In IE, the
`touch-action` css property can be set to `none` or `manipulation` to remove the delay. Finally,
since iOs 8, Safari doesn't delay "slow" taps anymore. There are some caveats though, which can be
found in this excellent article on which this summary is based: http://developer.telerik.com/featured/300-ms-click-delay-ios-8/

Note that this change does not affect the `ngSwipe` directive.

Issues with interactive elements (input, a etc.) when parent element has ngClick:
Closes #4030
Closes #5307
Closes #6001
Closes #6432
Closes #7231
Closes #11358
Closes #12082
Closes #12153
Closes #12392
Closes #12545
Closes #12867
Closes #13213
Closes #13558

Other issues:
- incorrect event order
- incorrect event propagation
- ghost-clicks / failing clickbusting with corner cases
- browser specific bugs
- et al.

Closes #3296
Closes #3347
Closes #3447
Closes #3999
Closes #4428
Closes #6251
Closes #6330
Closes #7134
Closes #7935
Closes #9724
Closes #9744
Closes #9872
Closes #10211
Closes #10366
Closes #10918
Closes #11197
Closes #11261
Closes #11342
Closes #11577
Closes #12150
Closes #12317
Closes #12455
Closes #12734
Closes #13122
Closes #13272
Closes #13447

BREAKING CHANGE:

The `ngClick` override directive from the `ngTouch` module is **deprecated and disabled by default**.
This means that on touch-based devices, users might now experience a 300ms delay before a click event is fired.

If you rely on this directive, you can still enable it with the `$touchProvider.ngClickOverrideEnabled()`method:

```js
angular.module('myApp').config(function($touchProvider) {
  $touchProvider.ngClickOverrideEnabled(true);
});
```

For migration, we recommend using [FastClick](https://github.com/ftlabs/fastclick).
Also note that modern browsers remove the 300ms delay under some circumstances:
- Chrome and Firefox for Android remove the 300ms delay when the well-known `<meta name="viewport" content="width=device-width">` is set
- Internet Explorer removes the delay when  `touch-action` css property is set to `none` or `manipulation`
- Since iOs 8, Safari removes the delay on so-called "slow taps"

See this [article by Telerik](http://developer.telerik.com/featured/300-ms-click-delay-ios-8/) for more info on the topic.
Note that this change does not affect the `ngSwipe` directive.
2016-01-27 20:23:02 +01:00
Martin Staffa e9c406b246 fix($animateCss): cancel fallback timeout when animation ends normally
Previously, css animations would not cancel the timeout when the
animation ends normally (calling end explicitly / transitionEnd event).
This meant that the timeout callback fn was always called after 150% of
the animation time was over. Since the animation was already closed at this
point, it would not do any work twice, but simply remove the timer data
from the element.
This commit changes the behavior to cancel the timeout and remove the data
when it is found during animation closing.

Closes #13787
2016-01-27 19:27:34 +01:00
Matias Niemelä 79b6d55792 chore(travis): add an integration hook for the angular hubot daemon
Closes #13777
2016-01-27 17:47:33 +00:00
Georgios Kalpakas 8f94b5b277 docs(CHANGELOG): remove duplicates and fix typos
Removed some entries from `v1.5.0-beta.2` which are also included in `v1.5.0-beta.1`
and fixed some typos.

Closes #13858
2016-01-27 16:46:08 +00:00
Isaac b11120be0a docs($cookiesProvider): clarify parameters description
Fixed a grammatical mistake ("equals to"), made hyphenation consistent, fixed punctuation and
clarified the sentence structure.

Closes #13853
2016-01-27 16:30:46 +01:00
Martin Staffa bfba95ce46 docs($resource): fix an unmatched link 2016-01-27 16:30:46 +01:00
Thomas Moffett 310f80e78e docs(guide): change concepts.graffle/data.plist to fix 'World' spelling
The change is only to concepts.graffle/data.plist to fix 'World' spelling.
Another PR, #13724, already fixed the actual image.

Closes #13704
Closes #13734
2016-01-27 15:00:47 +00:00
Lucas Mirelmann acfda1022d fix($parse): Preserve expensive checks when runnning $eval inside an expression
When running an expression with expensive checks, there is a call to `$eval` or `$evalAsync`
then that expression is also evaluated using expensive checks

Closes: #13850
2016-01-27 15:30:50 +01:00
robw 04d4d93e5b docs(ngModel): add section explaining that ngModel watches by reference
The new section explains that changing only a property on an object doesn't
trigger re-rendering.

Closes #13224
Closes #13518
2016-01-27 14:24:34 +00:00
Georgios Kalpakas 8348365df9 fix($compile): properly denormalize templates when only one of the start/end symbols is different
Previously, if either of the start/end interpolation symbols remained unchanged (i.e. `{{` or `}}`),
then directive templates would not be denormalized properly. Changing only one of the start/end
symbols (but not both) is an uncommon but legitimate usecase.

Closes #13848
2016-01-26 20:16:49 +02:00
Georgios Kalpakas 16bcdcb61d docs(guide/migration): add notes for migrating from 1.4 to 1.5
Part of #13474 (includes changes up until `v1.5.0-rc.1`)
Closes #13808
2016-01-26 20:09:54 +02:00
Leo Gallucci adcfa74327 docs(guide/directives): improve Protractor test for bindings
This needs Protractor >= 1.3.0 to work.

Closes #9330
2016-01-26 15:09:02 +01:00
Michal Raczkowski d641901be6 feat($resource): add support for timeout in cancellable actions
Old behavior: actions can be either cancellable or have a numeric timeout.
When having both defined, cancellable was ignored.
With this commit: it's possible for actions to have both cancellable:true
and numeric timeout defined.

Example usage:

```js
var Post = $resource('/posts/:id', {id: '@id'}, {
  get: {
    method: 'GET',
    cancellable: true,
    timeout: 10000
  }
});

var currentPost = Post.get({id: 1});
...
// the next request can cancel the previous one
currentPost.$cancelRequest();
currentPost = Post.get({id: 2});

// any of those requests will also timeout, if the response
// doesn't come within 10 seconds
```

Closes #13824
2016-01-26 13:59:28 +02:00
Peter Bacon Darwin eae0a1121f chore(ngLocale): regenerate locales to include original localeId
Closes #13390
2016-01-26 11:27:22 +00:00
Peter Bacon Darwin 173c9063e7 style(i18n): improve indentation for readability 2016-01-26 11:27:14 +00:00
Peter Bacon Darwin b461551b81 chore(i18n): fix up i18n testing tools 2016-01-26 11:27:14 +00:00
Peter Bacon Darwin 63492a0261 feat($locale): Include original locale ID in $locale
Most systems use *IETF language tag* codes which are typically a combination
of the ISO 639 language code and ISO 3166-1 country code with an underscore
or hyphen delimiter. For example `en_US`, `en_AU`, etc.

Whilst the `$locale.id` comes close, the lowercase format makes it impossible
to transform to an IETF tag reliably. For example, it would be impossible
to deduce `en_Dsrt_US` from `en-dsrt-us`.

Closes #13390
2016-01-26 11:27:13 +00:00
Robert Reiz adb0e1746b docs(bower.json): add MIT license
Closes #13405
2016-01-26 11:03:28 +00:00
Zac Smith 3be79cd6a1 docs(tutorial): fix typo
Closes #13843
2016-01-26 11:07:58 +02:00
Martin Staffa e4c6e01791 docs($sceDelegateProvider): fix markdown errors
Closes #13360
2016-01-25 22:59:27 +01:00
Martin Staffa fb76d96009 docs(guide/interpolation): fix dangling link 2016-01-25 22:52:44 +01:00
Martin Staffa f322c4f3c3 docs(guide/directives): link to the scope property docs
Closes #12500
2016-01-25 22:52:44 +01:00
Robin Glauser 081f6ec7f2 docs(error/modulerr): add additional debugging help
This simple tip can help to diagnose the error.

Closes #12958
2016-01-25 17:07:20 +00:00
Moorzee 9bb6a30417 docs(tutorial/Tutorial): Java installation
Add step to ensure java is installed on development machine.

Closes #12938
2016-01-25 16:52:25 +00:00
marianoc84 97e97d1eb7 docs(guide/Modules): update style guide link
The linked blog post recommends John Papa's Guide.

Closes #12898
2016-01-25 16:34:16 +00:00
Lucas Galfaso 1ab4e44443 fix(dateFilter): follow the CLDR on pattern escape sequences
When there are two single quotes "''" (quotes for clarification) that are not
part of an escape sequence, then this sequence should be handled as one single
quote. See http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
second and forth examples

Closes #12839
2016-01-25 14:54:15 +00:00
Livvie Lin 99eeec358c style(src): delete whitespace and use single quotes
This change edits syntax for code consistency.

It removes whitespace to match the style of the rest of the code,
and changes double quotes to single quotes to conform with
Google's JavaScript Style Guide.

Closes #12889
2016-01-25 14:52:29 +00:00
Tobias Leugger - Vibes ce8a7525cc docs(error/unpr): add hint about using ngStrictDi
The unknown provider error often happens when code is minified and one
did not use the correct syntax that supports minification. It's
frustrating to have to hunt for a bug in minified code, so adding the
simple hint that `ngStrictDi` will tell you what is wrong in the original
code will save you quite some trouble.

Closes #12717
2016-01-25 14:40:24 +00:00
Martin Raifer 5df2e5ce29 docs(tutorial/step-7): add troubleshooting instructions
Show troubleshooting instructions as in step 11.

Closes #12715
2016-01-25 14:37:00 +00:00
Alireza Mirian ef03dfc4a4 docs($injector): fix inaccuracy in $provide.service docs
Closes #12664
Closes #12665
2016-01-25 14:33:16 +00:00
Wesley Cho 4ff9c027b0 docs(compile): improve nonassign error message
- Improve error message to mention attribute the expression errored on

Fixes #13827

Closes #13828
2016-01-24 17:17:35 +01:00
Matias Niemelä 20b8ece444 fix(ngAnimate): properly cancel-out previously running class-based animations
Prior to this fix the addition and removal of a CSS class via
ngAnimate would cause flicker effects because $animate was unable
to keep track of the CSS classes once they were applied to the
element. This fix ensures that ngAnimate always keeps a reference
to the classes in the currently running animation so that cancelling
works accordingly.

The commit also adds a test for a previously untested animation merge path.

Closes #10156
Closes #13822
2016-01-23 16:28:51 +01:00
Qingyu Zhou 6406e3b01d docs(tutorial/step_12): change "click" to "hover"
Should be "hover" not "click", since we trigger the change at "mouseenter", not "click".

Closes #13831
2016-01-23 14:21:24 +02:00
Lucas Mirelmann 234053fc9a fix(ngSanitize): Blacklist the attribute usemap
Given that the attribute `name` is blacklisted, the attribute `usemap` should be
blacklisted too.

Closes: ##13826
2016-01-22 21:16:31 +01:00
Josh Duff a277bcf0f7 refactor(equals): Cleanup equals function for readability
- Removes unnecessary nested if condition
- Simplify check when one argument is a regex

Closes: #13650
2016-01-22 20:52:38 +01:00
Peter Bacon Darwin 7985416d39 docs(CHANGELOG): fix animation grouping 2016-01-21 14:30:35 +00:00
Peter Bacon Darwin dc3013e848 docs(CHANGELOG): add release notes for 1.4.9 2016-01-21 12:42:44 +00:00
Edgar Flores 0f2926db38 docs(guide/Interpolation): fix links
The links were not working, either `{` was missing or they were in the wrong location

Closes #13809
2016-01-20 21:04:50 +01:00
Lucas Galfaso bd59335eba test(input): test for #12106
Add a test that checks that an <input> value is not set when the value is equal
to the current value

Closes #12592
2016-01-20 15:11:07 +00:00
Adrian Roselli 6aa111b333 docs(tutorial/step-6): add alt attribute to images
See http://www.ssbbartgroup.com/blog/accessible-images-using-angular/

Closes #12569
2016-01-20 14:50:53 +00:00
Martin Staffa 42b5ce99fb docs(guide/filter): clarify how to use filters in controllers
Closes #11915
2016-01-20 10:41:15 +01:00
Matias Niemelä 2cb1989d12 chore($AnimateRunner): examine the document more carefully
Some internal tests were failing because the `$document[0]` value
was null. This fix ensures that the if statement surrounding that
is more careful.
2016-01-19 13:27:38 -08:00
Martin Staffa 1137d91abd docs(ngRepeat): point out animate example, remove ng-init
Closes #9047
2016-01-19 20:09:29 +01:00
Maxime Lasserre 288e4e33c3 docs($animate): make naming consistent
In the description of the example, you use `element` to refer to the container parameter and
`listenerFn` to refer to the callback parameter.

Closes #12716
2016-01-19 20:09:29 +01:00
Daniel Herman d98c5f03a4 chore($compile): remove an unused dependency
Fixes #13791

Closes #13801
2016-01-19 20:25:36 +02:00
Peter Bacon Darwin 8d20b04f1c docs($compile): fix typo 2016-01-19 18:07:25 +00:00
Peter Bacon Darwin 56c3666fe5 feat($compile): allow required controllers to be bound to the directive controller
If directives are required through an object hash, rather than a string or array,
the required directives' controllers are bound to the current directive's controller
in much the same way as the properties are bound to using `bindToController`.

This only happens if `bindToController` is truthy.

The binding is done after the controller has been constructed and all the bindings
are guaranteed to be complete by the time the controller's `$onInit` method
is called.

This change makes it much simpler to access require controllers without the
need for manually wiring them up in link functions. In particular this
enables support for `require` in directives defined using `mod.component()`

Closes #6040
Closes #5893
Closes #13763
2016-01-19 18:07:24 +00:00
Peter Bacon Darwin cd21216ff7 feat($compile): allow require to be an object
This provides an elegant alternative to the array form of the `require`
property but also helps to support binding of `require`d controllers
to directive controllers.

Closes #8401
Closes #13763
2016-01-19 18:06:50 +00:00
Peter Bacon Darwin 3ffdf380c5 feat($compile): call $ngOnInit on directive controllers after controller construction
This enables option three of https://github.com/angular/angular.js/issues/13510#issuecomment-164140194
by allowing the creator of directive controllers using ES6 classes to have a hook
that is called when the bindings are definitely available.

Moreover this will help solve the problem of accessing `require`d controllers
from controller instances without resorting to wiring up in a `link` function.
See https://github.com/angular/angular.js/issues/5893

Closes #13763
2016-01-19 18:06:30 +00:00
Peter Bacon Darwin db5e0ffe12 fix($compile): handle boolean attributes in @ bindings
Closes #13767
Closes #13769
2016-01-19 16:35:37 +00:00
Daniel Herman 92e4801d88 perf($compile): avoid needless overhead when wrapping text nodes
This commit positively affects performance in two main ways:

1,  When wrapping text nodes in the compile step, we do not need the overhead
of the `forEach` function versus a normal for loop since we do not make
use of the closure for anything.

2.  When actually wrapping the node, we can completely bypass jqLite which
avoids several function calls and the overhead of cloning the wrapper node
which we already know to be unique.

Tests in applications show about an 83% decrease in time spent in this
specific loop.
2016-01-19 16:24:53 +00:00
thorn0 6a92e9111f docs(uppercase, lowercase): undocument these artifacts
Closes #11387
Closes #13779
2016-01-19 16:12:11 +00:00
Georgios Kalpakas ba6d37756e docs(ngModel): rename $asyncValidators error to nopromise and add missing error page
Closes #13795
2016-01-19 16:05:45 +02:00
Martin Staffa 683bd92f56 perf(ngAnimate): speed up areAnimationsAllowed check
This commit speeds up the code that checks if an element can
be animated, for the following two cases:

The checks will be sped up in cases where the animation
is disabled via $animate.enabled(element, false) on any parent element.

A minor speed-up is also included for cases where the $rootElement of the
app (the bootstrap element) is on the body or lower in the DOM tree.
2016-01-19 13:14:04 +01:00
Martin Staffa 7700e2df09 fix($animate): correctly handle $animate.pin() host elements
This commit fixes two bugs:
1) Previously, animate would assume that a found host element
was part of the $rootElement (while it's possible that it is also outside the root).

2) Previously, if a parent of the animated element was pinned to a host element, the
host would not be checked regarding animations enabled status etc.

Closes #13783
2016-01-19 13:14:04 +01:00
Martin Staffa 3fb809e412 docs($compile): correct transcludeControllers definition
Closes #13793
2016-01-19 12:08:08 +01:00
Matias Niemelä 52ea4110d3 fix(ngAnimate): ensure that animate promises resolve when the document is hidden
Prior to this fix any promise/callback chained on a call to the $animate
methods would only flush if and when the browser page is visible. This
fix ensures that a timeout will be used instead when the document
is hidden.
2016-01-17 20:00:49 +01:00
Matias Niemelä a3a7afd3aa fix(ngAnimate): do not trigger animations if the document is hidden
Prior to this fix, ngAnimate would always trigger animations even if
the browser tab or browser window was not visible. This would cause
issues with class updates / DOM operations even if elements were not
using animations. The root cause is that browsers do not flush calls to
requestAnimationFrame when browser windows / tabs are not visible.

This fix disables animations if `document.hidden` is `true`.

Closes #12842
Closes #13776
2016-01-17 20:00:41 +01:00
Martin Staffa 20bc37fbc8 chore(benchmark): improve largetable layout 2016-01-17 19:55:39 +01:00
Martin Staffa 7761b6c3b0 docs(CHANGELOG): add missing breaking changes for 1.5.0-rc.1, fix layout
- add missing component() breaking changes
- put component related feats/fixes under "component"
- move features above fixes
2016-01-17 19:26:23 +01:00
Peter Bacon Darwin b77e14beea docs(CHANGELOG): add missing breaking change to 1.5.0-rc.1 2016-01-15 20:31:08 +00:00
Matias Niemelä a1f461e429 chore(CHANGELOG): update with changes for 1.5.0-rc.1 2016-01-15 08:35:19 -08:00
Georgios Kalpakas 13587193a5 docs(CHANGELOG.md): add BC notice for b71d7c3f
Closes #13759
2016-01-14 14:44:05 +00:00
Peter Bacon Darwin a1ff35850c test($log): fix up to work with Safari 9
On Safari 9.0.2, you are not allowed to write to `sourceUrl` or `line`
on a native Error object.

This commit uses a custom error instead.
2016-01-14 12:40:18 +00:00
Peter Bacon Darwin 95b3e1ce6c chore(doc-gen): filter out componentGroup doc types from search results
These doc types do not contain useful information from the point of view
of search results and are making the results less clear
2016-01-13 13:59:01 +00:00
Martin Staffa b78b12976a docs($animate): correct fn parameters for js animation 2016-01-12 23:25:59 +01:00
Martin Staffa a31c082de6 docs($animate): clarify info about from and to for animate()
Closes #11150
2016-01-12 23:03:58 +01:00
dmitriz 5afd54514d docs(CONTRIBUTING): add warning about forced push
Add warning about the possible consequences of a forced push

Closes #13747
2016-01-12 18:02:52 +00:00
David Rodenas Pico 72b96ef57a refact(ngMock.$componentController): use $injector instead of adding new code to angular.min.js
Closes #13742
2016-01-12 13:29:54 +00:00
Peter Bacon Darwin 90975db5f9 feat($compileProvider): allow component() helper to copy over custom annotations
Closes #13741
2016-01-12 12:48:08 +00:00
Peter Bacon Darwin 25bc531802 fix($compileProvider): remove the ability to set the restrict option on component() helper
Closes #13741
2016-01-12 12:48:00 +00:00
Georgios Kalpakas 4e1b36c216 fix($controller): allow identifiers containing $
As discussed in https://github.com/angular/angular.js/issues/13664#issuecomment-170536024.

Closes #13736
2016-01-11 21:23:37 +00:00
Matias Niemelä d4fa331308 fix(ngAnimate): only copy over the animation options once
A bug in material has exposed that ngAnimate makes a copy of
the provided animation options twice. By making two copies,
the same DOM operations are performed during and at the end
of the animation. If the CSS classes being added/
removed contain existing transition code, then this will lead
to rendering issues.

Closes #13722
Closes #13578
2016-01-11 21:54:49 +01:00
Martin Staffa a801df719e fix(ngMock): ignore empty javascript animations in $animate.closeAndFlush() 2016-01-11 21:54:49 +01:00
Georgios Kalpakas cb74999b17 test: fix failing tests on MS Edge
Includes the following fixes (per component):

* `$sniffer`: Properly determine the expected `vendorPrefix` for MS Edge
* `input`: MS Edge does not support dates with years with more than 4 digits.
      Trying to set the value of an `input[datetime-local]` to `9999-12-31T23.59.59.999` throws an
      error (probably related to converting the date to one with a year with more than 4 digits,
      due to timezone offset).
* `$sanitize`: Fix failing tests on MS Edge
* `$animateCss`: Although the detected `vendorPrefix` for MS Edge is "ms", it doesn't seem to
      recognize some vendor-prefixed CSS rules (e.g. `-ms-animation-*`). Other browsers (currently)
      recognize either vendor-prefixed rules only or both.
      Fixed by adding and retrieving styles using both prefixed and un-prefixed names.
* `$compile`: Skip failing `foreignObject` test on MS Edge.
      For unknown reasons, an `<svg>` element inside a `<foreignObject>` element on MS Edge has no
      size, causing the included `<circle>` element to also have no size and thus fails an
      assertion (relying on the element having a non-zero size).
      This seems to be an MS Edge issue; i.e. it is also reproducible without Angular.
      (Tested with MS Edge version 25.10586.0.0 on Windows 10.)

Closes #13686
2016-01-11 15:50:53 +02:00
Georgios Kalpakas 2764536e8f refct(privateMocks): remove unused argument from createMockStyleSheet() 2016-01-11 15:49:51 +02:00
Peter Bacon Darwin 8ccc0547a8 docs(examples): add copyright and license info to each plunker file
Closes #13729
2016-01-10 19:47:26 +00:00
Peter Bacon Darwin dd14e0c44d feat(ngMock.$componentController): add helper to instantiate controllers for components
Closes #13683
Closes #13711
2016-01-10 19:19:03 +00:00
mohamed amr 7e24590fa3 test(ngList): add missing '>' to textarea closing tag
Fixes #13728
Closes #13727
2016-01-10 17:55:40 +02:00
Matias Niemelä 8b6360338d fix($animate): allow enabled children to animate on disabled parents
Prior to this fix if a parent container disabled animations for
itself then no children could be enabled explicity via
`$animate.enabled`. This patch allows for that to work.

Closes #13179
Closes #13695
2016-01-09 14:59:34 +01:00
Shahar Talmi d91cf16796 feat(component): default controllerAs to be $ctrl
Closes #13664
Closes #13710
2016-01-08 14:37:25 +00:00
Shahar Talmi f31c5a3924 feat(component): disallow non-isolate scopes
Closes #13710
2016-01-08 14:36:55 +00:00
Peter Bacon Darwin 16ccac91d0 test($compile): fix component helper test
The test was expecting to match an object containing a `transclude`
property set to `false` but now the property is `undefined`.
2016-01-08 12:51:09 +00:00
Peter Bacon Darwin 91b080e6e6 docs(tutorial/step-00): fix dangling link 2016-01-08 12:30:48 +00:00
Martin Staffa feeb19787c refactor(loader): move component definition code to the $compileProvider
The `Module.component()` helper now delegates to `$compileProvider.component()`.

This has the following benefits:

- when using only the loader, we are not accessing out of scope variables / functions
- components can be registered via $compileProvider
- docs are a bit easier to find
- it is easier to keep the Batarang version of the loader up to date if there is minimal
  code in that file.

Closes #13692
2016-01-08 12:27:37 +00:00
Georgios Kalpakas 98c2db7f9c fix(linky): throw error if input is not a string
BREAKING CHANGE:

Before this change, the filter assumed that the input (if not undefined/null) was of type 'string'
and that certain methods (such as `.match()`) would be available on it. Passing a non-string value
would most likely result in a not-very-useful error being thrown (trying to call a method that does
not exist) or in unexpected behavior (if the input happened to have the assumed methods).

After this change, a proper (informative) error will be thrown. If you want to pass non-string
values through `linky`, you need to explicitly convert them to strings first.
Since input values could be initialized asynchronously, `undefined` or `null` will still be
returned unchanged (without throwing an error).

Closes #13547

Closes #13693
2016-01-08 12:53:08 +02:00
Peter Bacon Darwin 06aa52efff chore(package): update karma to 0.13
This version of karma can sniff Microsoft Edge correctly.

Closes #13691
2016-01-07 20:17:49 +00:00
Lucas Mirelmann fabc6ab5b0 fix($injector): workaround for MS Edge class detection
Fix for MS Edge class detection

Closes: #13697
2016-01-07 20:53:16 +01:00
Georgios Kalpakas 93c7251f5f fix(isArrayLike): recognize empty instances of an Array subclass
Fixes #13560
Closes #13708
2016-01-07 19:43:22 +00:00
Matias Niemelä e1def1b8fe feat(ngMock): add support for $animate.closeAndFlush()
Use `$animate.closeAndFlush()` to close all running animations.

Closes #13005
Closes #13576
Closes #13707
2016-01-07 14:53:10 +01:00
Martin Staffa e5cab951f4 fix(ngAnimate): allow event listeners on document in IE
Fixes #13548
Closes #13696
2016-01-07 13:03:50 +00:00
Martin Staffa f7eab8d8fe fix(select): re-define ngModelCtrl.$render in the select postLink fn
Previously, the `$render` function was re-defined in the `select` directive's
`preLink` function. When a `select` element is compiled, every `option`
element inside it is linked and registered with the `selectCtrl`, which
calls `$render` to update the selected `option`. `$render` calls `selectCtrl.writeValue`,
which adds an unknown `option` in case no option is selected. In cases where
`optgroup` elements are followed by a line-break, adding the unknown `option`
confuses the html compiler and makes it call the link function of the following
`option` with a wrong element, which means this option is not correctly
registered.
Since manipulation of the DOM in the `preLink` function is wrong API usage,
the problem cannot be fixed in the compiler.

With this commit, the `$render` function is not re-defined until the `select` directive's
`postLink` function, at which point all `option` elements have been linked
already.

The commit also changes the `toEqualSelectWithOptions` matcher to
take selected options in groups into account.

Closes #13583

Closes #13583
Closes #13663
2016-01-07 12:06:13 +00:00
Martin Staffa 495d40d802 docs($compile): add docs for bindToController with object hash
Closes #13228
Closes #13625
Closes #13658
Closes #13681
2016-01-06 16:17:05 +01:00
Georgios Kalpakas d28ae2126e docs(validators): fix typos and make minor layout improvements 2016-01-06 13:53:37 +02:00
Lucas Mirelmann 8955cfb646 feat($compile): Allow ES6 classes as controllers with bindToController: true
Modify `$injector.invoke` so ES6 classes would be invoked using `new`

Closes: #13510
Closes: #13540
Closes: #13682
2016-01-05 22:35:57 +01:00
Martin Staffa 776972ed9c fix(ngAnimate): allow removing classes that are added by a running animation
This allows follow-up animations to remove a class that is currently
being added.

Fixes #13339
Fixes #13380
Closes #13414
Closes #13472
Closes #13678
2016-01-05 21:31:26 +00:00
Peter Bacon Darwin 1358b3ca9b chore(saucelabs): update to latest sauce version 2016-01-05 14:46:14 +00:00
Matias Niemelä e020b8993e fix(ngAnimate): do not use event.timeStamp anymore for time tracking
Due to recent changes in Chrome, Firefox and Webkit use of the
event.timeStamp value will lead to unpredictable behaviour due to
precision changes. Therefore it's best to stick entirely to use
`Date.now()` when it comes to confirming the end of transition-
ending values. See #13494 for more info.

Applies to 1.2, 1.3, 1.4 and 1.5.

Closes #13494
Closes #13495
2016-01-05 12:43:48 +00:00
Andy Patterson b2b896f949 test(booleanAttrsSpec): add unit test for IE11 URL parsing failure
IE11/10/Edge fail when setting a href to a URL containing a % that isn't a valid escape sequence

See #13388
Closes #13458
2016-01-05 12:09:15 +00:00
Konstantin Ulitin 3c5827b6f5 docs(loader): fix type in @return tag for angular.module()
Closes #13655
2016-01-05 11:57:30 +00:00
Waitaya Krongapiradee 0e03644dad docs(error/$rootScope/inprog): add missing "$timeout"
Closes #13630
2016-01-04 22:20:47 +00:00
Kyle Pittman 112024271b docs(tutorial/2): add e2e test missing filename
Add `__`test/e2e/scenarios.js`:__` to denote which file we should change
to add the behavioral tests.

Closes #13673
2016-01-04 22:10:43 +00:00
Peter Bacon Darwin bca0a1f786 revert: feat($compile): Allow ES6 classes as controllers with bindToController: true
This change caused IE9 to run out of memory.

This is reverted from commit b0248b7894
2016-01-04 21:48:19 +00:00
Martin Staffa 959f2bbb2d fix($animateCss): only (de)register listeners when events have been added
Previously, when an animation was closed because no animation styles
where found, it would call .off() with an empty string as the argument.

For both jquery/jqlite this is the same as calling .off() without any
argument, which deregisters all event listeners on an element.

Closes #13514
2016-01-04 21:01:45 +01:00
Sébastien Arod 6a47c0d75d fix(loader): use false as default value for transclude in component helper
The default value of for transclude in component helper is now `false`.

The change is motivated by the fact that using `transclude: true` when not necessary
made component unusable in conjunction with structural directives that also require
transclusion such as `ng-switch-when` and `ng-repeat`.

Closes #13566
Closes #13581

BREAKING CHANGE:
Angular 1.5.0.beta.2 introduced the `module.component` helper where `transclude` was true by default.
This changes the default for `transclude` to `false`. If you created components that expected
transclusion then you must change your code to specify `transclude: true`.
2016-01-04 16:24:51 +00:00
Lucas Mirelmann b0248b7894 feat($compile): Allow ES6 classes as controllers with bindToController: true
Modify `$injector.invoke` so ES6 classes would be invoked using `new`

Closes: #13510
Closes: #13540
2016-01-03 14:16:52 +01:00
Ieuan Griffiths 6fd41e7f59 chore(*): Updated year in licence
Closes: #13661
2016-01-02 20:40:55 +01:00
Martin Staffa 3297bbd188 docs: reorganize information about interpolation
- Move interpolation info from Directive guide into new interpolation guide
- Add information about boolean attributes to interpolation guide
- remove wroong examples from prefixed boolean attribute docs, link
to interpolation guide instead
- mention additional examples for attributes that benefit from ngAttr
- add docs for ngRequired directive
2015-12-31 18:11:43 +01:00
Martin Staffa 8863836cd4 docs: add docs for ngPattern, ngMinlength, ngMaxlength
Closes #9991
2015-12-31 18:11:43 +01:00
Martin Staffa b8fb0c4573 docs($interpolateProvider): remove superfluous ng-app attribute
The example processor is adding the module attr in the example tag as
the ng-app attr on the body.

Closes #13608
2015-12-31 18:11:43 +01:00
Waitaya Krongapiradee 17b700a339 docs(tutorial): fix some minor punctuation errors
Closes #13633
2015-12-31 18:11:43 +01:00
ammills01 811b20e3b9 docs(tutorial/6 - Templating Links): fix grammar
Corrected the grammar on line 62 by adding the word 'an' which forced
me to move 'only' down to line 63.

Closes #13651
2015-12-31 18:11:43 +01:00
Wesley Cho 5ded3d3e73 docs($resource): fix wording for failure
- Fix mention of promise resolution on failure: resolved -> rejected

Closes #13638
Closes #13624
2015-12-31 18:11:43 +01:00
Jason Bedard 986647a968 fix(copy): add support for ArrayBuffer, handle multiple references to ArrayBuffer
Closes: #13640
2015-12-31 16:35:26 +01:00
Jason Bedard 7b51243be5 fix(copy): add support for String/Boolean/Number object types
Closes: #13641
2015-12-30 12:57:34 +01:00
Martin Staffa 798fb18542 docs(Module): clarify that component's template(Url) fn is injectable
Related #13485
2015-12-20 22:37:05 +01:00
Shahar Talmi 99d601a048 fix(Module): allow passing template/templateUrl in array notation
Close: #13485
2015-12-20 21:06:17 +01:00
thorn0 a6e9174a27 refactor($parse): remove unnecessary check
Closes: #13588
2015-12-19 11:09:25 +01:00
thorn0 dec8a0eb72 refactor($parse): remove unused variables
Closes: #13579
2015-12-18 13:56:37 +01:00
Alexander Zagumennikov 98776487a0 fix(ngInclude): do not compile template if original scope is destroyed
With slow internet connection scope may be destroyed before template is loaded.
Previously in this case ngInclude compiled template that leaded to memory leaks
and errors in some cases.

Closes: #13515
Closes: #13543
2015-12-18 12:30:28 +01:00
thorn0 b3ef5e0852 fix($q): make instanceof work for $q promises
Closes: #13574
Closes: #13545
2015-12-18 12:24:23 +01:00
mkalish 04efdd5bfa docs(ngMock): update $http example to use standard promise syntax
Examples were using deprecated .success and .error rather .then

Closes #13557
2015-12-17 22:15:36 +00:00
Peter Bacon Darwin 9f5d76e16b chore(Gruntfile): replace double quotes with single quotes 2015-12-17 22:05:07 +00:00
Peter Bacon Darwin 525be5b7d4 chore(GruntFile): fix whitespace in lists 2015-12-17 22:05:07 +00:00
Peter Bacon Darwin 042e0f1f0a chore(GruntFile): move validate-angular-files task into its own file
Closes #13569
2015-12-17 22:05:07 +00:00
Matias Niemelä 03872983a4 chore(build): add a validation step for angularFiles
Closes #13553
2015-12-17 22:04:46 +00:00
Peter Bacon Darwin 62f79e820f chore(angularFiles): add documentation only file to list of files
This prevents errors when checking `validate-angular-files`
2015-12-17 22:02:05 +00:00
Peter Bacon Darwin e5c26e92cc chore(npm-shrinkwrap): install glob package 2015-12-17 22:02:05 +00:00
Peter Bacon Darwin 4bcb307abc chore(jenkins): remove unused argument definition 2015-12-17 14:15:13 +00:00
Peter Bacon Darwin 0e729e1dd5 chore(jenkins): run Jenkins builds on Node 4 (via nvm)
Closes #13568
2015-12-17 14:07:03 +00:00
Peter Bacon Darwin 9bb184d181 chore(jenkins): move jenkins_build.sh to scripts/jenkins/build.sh 2015-12-16 14:22:26 +00:00
Georgios Kalpakas a7a053f5be docs($compile): fix scope hierarchy indentation in HTML output 2015-12-16 15:27:37 +02:00
Peter Bacon Darwin 9630159444 chore(travis): update to use node 4.x 2015-12-16 10:42:54 +00:00
Georgios Kalpakas e3be5d6efa fix(input): fix URL validation being too strict
Background:
Prior to ffb6b2f, there was a bug in `URL_REGEXP`, trying to match the hostname as `\S+` (meaning
any non-space character). This resulted in never actually validating the structure of the URL (e.g.
segments such as port, path, query, fragment).
Then ffb6b2f and subsequently e4bb838 fixed that bug, but revealed `URL_REGEXP`'s "strictness" wrt
certain parts of the URL.

Since browsers are too lenient when it comes to URL validation anyway, it doesn't make sense for
Angular to be much stricter, so this commit relaxes the "strictness" of `URL_REGEXP`, focusing more
on the general structure, than on the specific characters allowed in each segment.

Note 1: `URL_REGEXP` still seems to be stricter than browsers in some cases.
Note 2: Browsers don't always agree on what is a valid URL and what isn't.

Fixes #13528

Closes #13544
2015-12-16 12:36:28 +02:00
Georgios Kalpakas c2173c1298 test(privateMocks): allow replacing $prop with strings with special RegExp semantics
`baseThey` used to construct the testcase description by replacing `$prop` using a RegExp.
If the replacement string contained `$&` (which has a special meaning with RegExps), the resulting
string was not as expected.x
2015-12-16 12:36:28 +02:00
Martin Staffa 0b94e8a8bf chore(travis): add a new job that runs ci-checks
Previously, ddescribe, merge-conflicts, jshint, and jscs would run
after unit & e2e tests ran. The order was orginally changed as part of
https://github.com/angular/angular.js/pull/9792.

While the logic is sound that style errors shouldn't block tests from
running, ddescribe should always run. This was not guaraneteed; when
Travis exits with a warning after some browsers have run, ddescribe
doesn't get run and it doesn't become apparent that not
all tests have run.

Additionally, a separate job clearly separates style from test errors,
which e.g. means you can open a PR that includes an iit to speed up
the job, and see immediately if the test passes, because the ddescribe
error is in another job.
2015-12-16 10:17:12 +00:00
Justas Brazauskas 983374c574 docs: fix typos throughout the codebase
Closes #13519
2015-12-15 21:52:47 +02:00
Peter Bacon Darwin 05d3ed0d9b docs(error/isecwindow): add note about coffeescript issue
Closes #4853
2015-12-15 10:39:44 +00:00
Georgios Kalpakas 1b25f80cd2 docs(form): remove mention of interpolated control names not being supported
The docs state that interpolation cannot be used in control names.
This used to be true, but not anymore.

Closes #13520
2015-12-14 11:00:50 +02:00
Lucas Mirelmann 6cdbda7cf1 fix($compile): Add missing variable declaration
Closes: #13521
Closes: #13525
2015-12-13 12:27:08 +01:00
Philip Harrison c9e6cf9be0 fix($compile): Fix namespace detection for achor elements
Closes: #13480
2015-12-13 10:39:38 +01:00
Georgios Kalpakas c7ed8a33af docs(component): add examples on how to use components with ngRoute
Closes #13498
2015-12-11 23:54:25 +02:00
Georgios Kalpakas 6988667e5e docs($routeProvider): document resolveAs and assiging resolve map on scope
Related to #13400.
2015-12-11 23:54:25 +02:00
Justas Brazauskas e57cf13d5d docs: fix typos throughout the codebase
Closes #13507
2015-12-11 21:04:18 +02:00
ReneFerwerda e4e5677fbd docs(select): fix typo
Closes #13491
2015-12-10 22:29:46 +02:00
Martin Probst 8b6b428271 feat($injector): support instantiating classes.
ES6's `class Foo {}` constructors cannot be instantiated using
`fn.apply`. This change extracts injection argument collection and then
uses new (Function.bind.apply(ctor, args)) to instantiate the service
instance.

Closes: #12598
Closes: #12597
2015-12-10 21:17:42 +01:00
Martin Staffa 8f0b482596 fix($animate): allow animations when pinned element is parent element
Previously, the animate queue would only detect pinned elements when
they were the same element as the to-be-animated element.

Related #12617
Closes #13466
2015-12-10 14:24:28 +01:00
Martin Staffa 6428ed5bb5 test($animate): ensure that pin() arguments are elements 2015-12-10 14:24:28 +01:00
Martin Staffa bc41ad8aa8 fix($animate): correctly access minErr
ngMinErr is available during unit tests, but not in the build. There's
currently no way to catch these access errors in automated testing.
2015-12-10 14:24:28 +01:00
Martin Staffa 6858caf251 fix(ngOptions): don't skip optgroup elements with value === ''
Internet Explorer 11 returns '' for optgroup elements without a value
attribute. We only want to skip option elements with value ''

Fixes #13487
Closes #13489
2015-12-10 14:22:33 +01:00
Martin Staffa 20604e7fc4 fix($animateCss): remove animation end event listeners on close
Previously the transition/animation end events were not removed when the
animation was closed. This normally didn't matter, because
the close function knows the animations are closed and won't do work
twice.
However, the listeners themselves do computation that could fail when
the event was missing some data, for example when the event was
triggered instead of natural.

Closes #10387
2015-12-10 14:04:02 +01:00
Matias Niemelä b7b06d8477 revert: fix($animateCss): respect transition styles already on the element 2015-12-09 16:51:21 -08:00
Martin Staffa de9777d819 fix($animateCss): respect transition styles already on the element
Previously, $animateCss wouldn't use transition styles that were on the element
before the animation process started. Precisely, transition property, timing-function
and delay were overwritten in the process.

Closes #12656
Closes #13333
2015-12-09 13:47:29 -08:00
Peter Bacon Darwin 1b06f33f30 chore(package): ensure branch version is good to fix docs 2015-12-09 15:01:01 +00:00
Peter Bacon Darwin ca6e266869 docs(CHANGELOG): fix typo 2015-12-09 14:07:43 +00:00
Peter Bacon Darwin 23c4ae522a chore(package.json): update version branch information 2015-12-09 13:50:58 +00:00
Peter Bacon Darwin 3112f8e910 docs(CHANGELOG): add 1.5.0-rc.0 changes 2015-12-09 13:45:50 +00:00
Matias Niemelä 21ab82906e chore(angularFiles): the animateRunner.js file doesn't exist for ngAnimate anymore 2015-12-08 13:57:18 -08:00
Peter Bacon Darwin 1dd206ef85 fix($compile): revert allowing non-normalized element names in transclude map
Closes #13455
2015-12-08 16:29:19 +00:00
Georgios Kalpakas da5db4b1b3 docs($resource): re-phrase note in the docs (has to --> would)
As discussed in https://github.com/angular/angular.js/pull/13462#discussion_r46891840.
2015-12-08 17:53:57 +02:00
Georgios Kalpakas 3694390c90 docs($resource): re-phrase warning message (has to --> would)
As discussed in https://github.com/angular/angular.js/pull/13462#discussion_r46891840.
2015-12-08 17:06:19 +02:00
Martin Staffa 36a3c81177 docs(guide/migration): add info for 1.3 checkbox breaking change
Introduced in commit https://github.com/angular/angular.js/commit/c90cefe16142d973a123e945fc9058e8a874c357

Closes #13464
2015-12-08 13:20:27 +01:00
Georgios Kalpakas b0e7d548d0 docs(guide/migration): better describe what the BC in c054288c is about
Also, updated the corresponding entry in changelog.
This came up in
https://github.com/angular/angular.js/commit/c054288c9722875e3595e6e6162193e0fb67a251#commitcomment-14783993.
2015-12-08 09:29:06 +02:00
Andy Patterson e4bb838795 fix(input): add missing chars to URL validation regex
Update the list of permitted chars in URLs.

Closes #13379
Closes #13460
2015-12-07 22:31:03 +02:00
Lucas Mirelmann 0ea535035a feat($parse): provide a mechanism to access the locals object
Extends the built-in identifiers definitions by adding `$local`. This is a
non-assignable reference to the locals object.

Closes: #13247
Closes: #13454
2015-12-07 20:21:17 +01:00
Georgios Kalpakas e9aba90f7f docs(guide/$location): fix table header formatting
Closes #13456

Closes #13459
2015-12-07 19:20:05 +02:00
Martin Staffa f50b0cb393 docs(guide/Unit Testing): fix typo
Closes #13227
2015-12-07 14:26:17 +01:00
zainengineer 8b3bec7e07 docs(orderBy): make examples consistent
Updated example which manually injects the filter.
It matches sibling example in functionality.

Also put  html, js and css into separate files.

Also change anchors to buttons.

Closes #13402
2015-12-07 14:21:54 +01:00
Hovhannes Babayan 6752337629 docs(guide/Expressions): note that new operator is unavailable
You cannot create new objects inside Angular expressions. For example:
{{ new Date() }} expression fails.
2015-12-07 13:53:22 +01:00
Martin Staffa 48ad7486d9 docs(changelog, guide/migration): add BC notes for observing unset attributes
Closes #11163
2015-12-07 13:38:42 +01:00
Mil4n 341b834229 docs(tutorial/step_08): fix tense
The original statement is in the past tense (as if it were referring to a previous step of the
tutorial). The mentioned changes, however, are being done in this setp.

Closes #13452
2015-12-07 13:36:27 +02:00
Peter Bacon Darwin 7a668cdd7d fix($sanitize): blacklist SVG <use> elements
The use element can reference external svg's (same origin) and can include
xlink javascript urls or foreign object that can execute xss.

This change disallows `<use>` elements in sanitized SVG markup.

An example of a malicious SVG document would be:

SVG to sanitize:
```
<svg><use xlink:href="test.svg#xss" /></svg>
```

External SVG file (test.svg)
```
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg" width="100"
   height="100"
   id="xss">
<a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="javascript:alert(1)">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</a>
</svg>
```

Here the SVG to sanitize loads in the `test.svg` file via the `<use>` element.
The sanitizer is not able to parse this file, which contains malicious
executable mark-up.

This can only be taken advantage of if the external file is available via the
same origin restrictions in place.

Closes #13453

BREAKING CHANGE:

The `<use>` element is now removed from SVG passed to the `$sanitize` service.

This element is only used to import external SVG resources, which is a security
risk as the `$sanitize` service does not have access to the resource in order
to sanitize it.
2015-12-06 14:13:39 +00:00
Lucas Mirelmann 5a674f3bb9 fix($parse): prevent assignment on constructor properties
Prevent malicious attacks involving assignment on `constructor` properties.

Closes #13417
2015-12-06 14:06:26 +00:00
Peter Bacon Darwin e94b37e20e docs(ngTransclude): add better multi-slot translusion docs 2015-12-04 21:44:28 +00:00
Peter Bacon Darwin f5ebcbacf8 docs($compile): add better multi-slot transclusion information 2015-12-04 21:44:28 +00:00
Peter Bacon Darwin 0812af49bd feat(ngTransclude): don't overwrite the contents with an unfilled optional slot
Previously the contents of the `ngTransclude` element would always be emptied,
even if there was no transclusion to replace it.
Now, optional slots that have not been filled with content will not cause
the `ngTransclude` contents to be emptied.

Closes #13426
2015-12-04 21:42:07 +00:00
Dmitrij Maslov c3ae6ed78e fix(ngTransclude): don't replace existing content if no transcluded content exists
Closes #11839
2015-12-04 21:23:38 +00:00
Peter Bacon Darwin c3a2691115 fix($compile): swap keys and values for transclude definition object
Closes #13439
2015-12-04 21:23:38 +00:00
Marcus Nielsen 6976d6d8d8 docs($resource): fix mixed singular/plural
"any of the parameter value" contains plural (any of the) as well as singular (value).
Fixed to be singular to match the rest of the text block.

Closes #13448
2015-12-04 20:49:55 +00:00
Andy Gurden b75c0d8d05 feat(ngMock): destroy $rootScope after each test
Previously $rootScope would be new for each test, but old $rootScopes would never be destroyed.
Now that we are able to destroy the $rootScope, doing so provides an opportunity for code to clean
up things like long-lived event handlers between tests.

Closes #13433
2015-12-04 20:47:26 +00:00
Peter Bacon Darwin df6fade6e6 fix($compile): include non-elements in default transclusion slot
See https://github.com/angular/angular.js/commit/a4ada8ba9c4358273575e16778e76446ad080054#commitcomment-14738387
2015-12-04 13:06:28 +00:00
Shahar Talmi 983b059812 feat(ngView): reference resolved locals in scope
All the resolves for a route are now attached to the route's local scope,
as the property whose name is given by the `resolveAs` property on the
route definition.

If `resolveAs` is not specified it defaults to `$resolve`.

This will make it easier to use `ngRoute`, by being able to reference all
the resolve values for the route, directly on the scope, rather than having
to implement a controller just to copy the resolves across manually.

For example, rather than

```js
$routeProvider.when('/', {
  resolve: {
    item1: ($http) => $http.get(...),
    item2: ($http) => $http.get(...)
  },
  template: '<my-app item1="vm.item1" item2="vm.item2">'</my-app>`,
  controllerAs: 'vm',
  controller: ['item1', 'item2', function(item1, item2) {
    this.item1 = item1;
    this.item2 = item2;
  }]
});
```

one can now do

```js
$routeProvider.when('/', {
  resolve: {
    item1: ($http) => $http.get(...),
    item2: ($http) => $http.get(...)
  },
  template: '<my-app item1="$resolve.item1" item2="$resolve.item2">'</my-app>`
});
```

BREAKING CHANGE:

A new property is being attached to the scope of the route. The default name
for this property is `$resolve`. If your scope already contains a property
with this name then it will be hidden or overwritten.

In this case, you should choose a custom name for this property, that will
not collide with other properties on the scope, by specifying the `resolveAs`
property on the route.

Closes #13400
2015-12-04 12:22:23 +00:00
Martin Staffa 25e8c5927c docs(ngModelController): improve $rollbackViewValue description & example
The example has been expanded to make it easier to provoke the
behavior that the description is talking about (rollbackViewValue
and programmatic model updates)

Related #13340
2015-12-03 23:59:42 +01:00
Utsav Shah 6628b4f1e5 fix($http): throw if url passed is not a string
Throw to prevent hard to debug errors in functions that are
called later.

Fixes #12925
Closes #13444
2015-12-03 21:28:10 +01:00
Martin Staffa 6e18b50a5b feat(ngAnimate): provide ng-[event]-prepare class for structural animations
The new prepare class is added before the animation is pushed to the
queue and removed before the animation runs, i.e. it is immediately
available when a structural animation (enter, leave, move)
is initialized.

The class can be used to apply CSS to explicitly hide these elements
to prevent a flash of content before the animation runs.
This can happen if a structural animation (such as ng-if) sits at the
bottom of a tree which has ng-class animations on the parents.
Because child animations are spaced out with requestAnimationFrame,
the ng-enter class might not be applied in time, so the ng.if element is
briefly visible before its animation starts.
2015-12-03 15:14:22 +01:00
Martin Staffa 77419cf19f fix(ngAnimate): ignore children without animation data when closing them
During parent structural animations, ongoing animations on child elements
are closed. These child elements are identified by their data-ng-animate
attribute. If an element is the clone of an animating element,
it might have this attribute, but no animation runner associated with it,
so we need to ignore it.

Fixes #11992
Closes #13424
2015-12-02 20:16:45 +01:00
Matias Niemelä 193153c3d3 fix(ngAnimate): do not alter the provided options data
Prior to this fix the provided options object would be
altered as the animation kicks off due to the underlying
mechanics of ngAnimate. This patch ensures that a
copy of the provided options is used instead. This patch
also works for when `$animateCss` is used by itself.

Fixes #13040
Closes #13175
2015-12-02 12:23:11 +01:00
Peter Bacon Darwin 6a0686d434 fix(formatNumber): cope with large and small number corner cases
By manually parsing and rounding we can deal with the more tricky numbers

Closes #13394
Closes #8674
Closes #12709
Closes #8705
Closes #12707
Closes #10246
Closes #10252
2015-12-01 21:27:00 +00:00
xieranmaya 08c9a5e9e7 docs($controller): fix typo
Closes #13418
2015-12-01 19:11:31 +00:00
Peter Bacon Darwin a72c12bd70 fix(ngMock): clear out $providerInjector after each test
Closes #13397
Closes #13416
2015-12-01 19:03:56 +00:00
Adam Zerner 73e38658c4 docs(guide/Scopes): fix grammar
Closes #13413
2015-11-30 12:45:18 +01:00
Martin Staffa b641181b93 style($animateCssSpec): remove dump from test 2015-11-29 18:19:44 +01:00
Martin Staffa 7ffb2d3c17 fix($animateCss): consider options.delay value for closing timeout
Previously, options.delay was only considered when a class added an
extra transition style (which leads to style recalculation).

Fixes #13355
Closes #13363
2015-11-26 18:16:22 +01:00
Joan Claret 023b777a56 docs(tutorial/2 - Angular Templates): add closing parenthesis
Closes #13368
2015-11-26 16:22:59 +01:00
Thodoris Bais 0c9480de8c docs(ngTransclude): add a comma for better reading flow
Closes #13385
2015-11-26 16:22:58 +01:00
Martin Staffa 0bc275461c docs(input): note that pattern validates the $viewValue
Closes #13376
2015-11-26 16:22:57 +01:00
Peter Bacon Darwin 0b5ecc64f0 fix($resource): still use the cancellable value if invalid timeout value
We log a deprecation message if `timeout` contains an invalid value.
Now we also use the `callable` value if provided.
2015-11-26 13:15:25 +00:00
Peter Bacon Darwin b183eae7ae fix($resource): don't add noop $cancelRequest after request has resolved 2015-11-26 13:14:12 +00:00
Peter Bacon Darwin 7ddbc9aa35 fix(ngTransclude): fix case where ngTransclude attribute value equals its key
Some preprocessors such as Jade will automatically provide a value for an attribute
rather than leave it empty. E.g. `<div ng-transclude="ng-transclude">`.
In these situations we still want to use the default transclusion slot.

Closes #12934
Closes #13383
2015-11-26 11:11:23 +00:00
Peter Bacon Darwin b2a937d425 test($compile): add test for undefined non-optional reference binding
Demonstrates that #13373 fixes #13367
2015-11-25 10:48:59 +00:00
Lucas Mirelmann 4473b81cda fix($parse): handle interceptors with undefined expressions
When calling `$parse` with `undefined` as the expression and with
an interceptor, then when the function is evaluated, then call the
interceptor

Closes: #13367
Closes: #13373
2015-11-25 10:48:59 +00:00
Georgios Kalpakas 98528be311 feat($resource): add proper support for cancelling requests
Introduced changes:

- Deprecate passing a promise as `timeout` (for `$resource` actions).
  It never worked correctly anyway.
  Now a warning is logged (using `$log.debug()`) and the property is
  removed.
- Add support for a boolean `cancellable` property in actions'
  configuration, the `$resource` factory's `options` parameter and the
  `$resourceProvider`'s `defaults` property.
  If true, the `$cancelRequest` method (added to all returned values for
  non-instance calls) will abort the request (if it's not already
  completed or aborted).
  If there is a numeric `timeout` specified on the action's configuration,
  the value of `cancellable` will be ignored.

Example usage:

```js
var Post = $resource('/posts/:id', {id: '@id'}, {
  get: {
    method: 'GET',
    cancellable: true
  }
});

var currentPost = Post.get({id: 1});
...
// A moment later the user selects another post, so
// we don't need the previous request any more
currentPost.$cancelRequest();
currentPost = Post.get({id: 2});
...
```

BREAKING CHANGE:

Using a promise as `timeout` is no longer supported and will log a
warning. It never worked the way it was supposed to anyway.

Before:

```js
var deferred = $q.defer();
var User = $resource('/api/user/:id', {id: '@id'}, {
  get: {method: 'GET', timeout: deferred.promise}
});

var user = User.get({id: 1});   // sends a request
deferred.resolve();             // aborts the request

// Now, we need to re-define `User` passing a new promise as `timeout`
// or else all subsequent requests from `someAction` will be aborted
User = $resource(...);
user = User.get({id: 2});
```

After:

```js
var User = $resource('/api/user/:id', {id: '@id'}, {
  get: {method: 'GET', cancellable: true}
});

var user = User.get({id: 1});   // sends a request
instance.$cancelRequest();      // aborts the request

user = User.get({id: 2});
```

Fixes #9332
Closes #13050
Closes #13058
Closes #13210
2015-11-24 22:10:54 +00:00
Peter Bacon Darwin 9190d4c3ad chore(bower/publish): read dist-tag from correct package.json 2015-11-24 10:57:16 +00:00
J.P. Poveda d9ec9951e2 docs($timeout): reword sentence for clarity
Closes #13302
2015-11-23 13:10:32 +01:00
Matt Erickson fedafdc677 docs($swipe): remove reference to ngCarousel
ngCarousel no longer exists (or has ever existed).

Closes #13322
Closes #13353
2015-11-23 13:05:09 +01:00
Rahat Ahmed 26c36bb4d1 docs(numberFilter): change decimalPlaces to fractionSize
Replace `decimalPlaces` with `fractionSize`, as `decimalPlaces`
isn't defined anywhere and is most likely meant to be `fractionSize`.

Closes #13323
2015-11-23 13:01:18 +01:00
mohamed amr c7a2028ab3 fix(ngOptions): don't $dirty multiple select after compilation
Closes #13211
Closes #13326
2015-11-23 12:58:56 +01:00
Martin Staffa 596af70101 chore(i18n): update locale files with standalone months
Closes #12844
2015-11-23 10:31:14 +00:00
Martin Staffa 96c73a0672 feat(ngLocale): add support for standalone months
This is needed for languages for which the month on its own has a
different format (case) than when used as part of a date.

Closes #3744
Fixes #10247
Fixes #12642
Closes #12844
2015-11-23 10:31:03 +00:00
Anita Perala 1537651c8c docs(guide/Conceptual Overview): add missing object in sentence
docs: minor grammar fix
missing word in overview

Closes #13346
2015-11-20 18:13:18 +01:00
Martin Staffa d59aeb4e0b docs(angular.element): add more info, fix formatting
- add info about ngJq
- fix alert box
- add info about css function
2015-11-20 18:11:50 +01:00
Julián Salgado 551a33db56 docs(angular.element): note that it does not find elements by tag name / selector
Closes #13107
Closes #13113
2015-11-20 18:11:49 +01:00
Anas Qadrei cd91640146 docs(error/nobase): make base tag visible
Closes #13350
2015-11-20 18:11:26 +01:00
Martin Staffa ab5824ee12 chore: make jshint happy 2015-11-20 12:18:37 +01:00
Matias Niemelä 5c50723535 chore(CHANGELOG): update with changes for 1.4.8 2015-11-19 16:15:30 -08:00
Matias Niemelä 546a277d65 fix(core): ensure animate runner is the same with and without animations
The $$AnimateRunner class is now the same for the core $animate service
and the ngAnimate $animate service. Previously, the core used a different
implementation that didn't match the ngAnimate behavior with regard
to callbacks.

Closes #13205
Closes #13347
2015-11-20 00:22:47 +01:00
Peter Bacon Darwin a5ff651a59 fix($compile): support merging special attribute names in replace directives
When compiling a `replace` directive, the compiler merges the attributes from
the replaced element onto the template element.

Unfortunately, `setAttribute` and other related DOM methods do not allow certain
attribute names - in particular Angular 2 style names such as `(click)` and `[value]`.

This is relevant when using ngForward with Angular Material, since the `mgButton`
directive uses `replace` and in the former you often use `(click)`.

This fixes the problem but for those special attributes the speed is considerably
slow.

Closes #13317
Closes #13318
2015-11-19 08:52:56 +00:00
Peter Bacon Darwin ccd47ec904 test(filterFilter): modify Date test to prevent off by one year error in Firefox 2015-11-18 12:56:06 +00:00
Peter Bacon Darwin 2e23a3cdbc docs(CHANGELOG): tweak the latest changelog descriptions 2015-11-18 08:28:52 +00:00
Matias Niemelä ca7f4a387c chore(CHANGELOG): update with changes for 1.5.0-beta.2 2015-11-17 15:57:27 -08:00
Jason Bedard 898a3fd3b9 perf($q): only bind Deferred methods when returned publicly from $q.defer 2015-11-17 21:53:09 +01:00
Jason Bedard 9473371343 perf($q): reduce closures when resolving promises
- changes Deferred.$$resolve to only wrap the internal resolve/reject when wrapping another promise

Closes: #13293
2015-11-17 21:49:52 +01:00
Lucas Mirelmann e5275590db refactor($interval): do not use notify to trigger the callback
Do not use `$q.notify` to trigger the callback. This allows `$q` to be replaced
with another Promise/A+ compilant library

Closes: #13261
2015-11-17 21:46:55 +01:00
Matias Niemelä 78297d252d feat(ngAnimate): introduce ngAnimateSwap directive 2015-11-17 11:36:07 -08:00
Steve Mao e5e0884eaf docs($http): add a missing semicolon
Closes #13311
2015-11-16 16:55:33 +01:00
Leonardo Borges Avelino 551d1c20cf docs(guide/Conceptual Overview): change deprecated $http.success into .then
Using the standard then method instead success, because success is deprecated

Closes #13309
2015-11-16 16:54:13 +01:00
Peter Bacon Darwin f5aa207960 fix(jqLite): deregister special mouseenter / mouseleave events correctly
Closes #12795
Closes #12799
2015-11-12 18:44:19 +00:00
rrsivabalan 4412fe238f fix($location): ensure $locationChangeSuccess fires even if URL ends with #
Closes #12175
Closes #13251
2015-11-12 13:34:18 +00:00
Eric Lee Carraway 8088284f66 docs(readme): fix typo (setup => set up)
spell set up as two words
here, it is an adjective modifying the noun "environment"

Closes #13297
2015-11-12 10:22:50 +02:00
Eric Lee Carraway 25f1bbaad1 docs(contributing): fix typo (a unambiguous => an unambiguous)
use the article “an” before words that start with a vowel sound

Closes #13292
2015-11-11 14:21:41 +02:00
Peter Bacon Darwin bd7b217729 fix($compile): bind all directive controllers correctly when using bindToController
Previously only the first directive's controller would be bound correctly.

Closes #11343
Closes #11345
2015-11-10 20:30:53 +00:00
Georgios Kalpakas 50557a6cd3 fix($compile): evaluate against the correct scope with bindToController on new scope
Previously, the directive bindings were evaluated against the directive's
new (non-isolate) scope, instead of the correct (parent) scope.
This went unnoticed most of the time, since a property would be eventually
looked up in the parent scope due to prototypal inheritance. The incorrect
behaviour was exhibited when a property on the child scope was shadowing
that on the parent scope.

This commit fixes it.

Fixes #13021
Closes #13025
2015-11-10 20:30:53 +00:00
Jakub Torbicki 1c13a4f45d fix($compile): bind all directive controllers correctly when using bindToController
Previously only the first directive's controller would be bound correctly.

Closes #11343
Closes #11345
2015-11-10 20:30:53 +00:00
mzdunek93 1a98c0ee34 fix($compile): fix scoping of transclusion directives inside replace directive
Closes #12975
Closes #12936
Closes #13244
2015-11-10 20:30:53 +00:00
Jason Bedard b837fc3116 refactor($compile): simplify multi element directive check
Previously, we would check if an attribute indicates a multi-element
directive, now we only do this check if the attribute name actually
matches the multi-element name pattern.

Closes #12365
2015-11-07 15:31:34 +01:00
Martin Staffa aff74ec87b docs(changelog, migration): add BC notice for ngMessages evaluation
Introduced by

Closes #11616
Closes #12001
2015-11-06 17:17:20 +01:00
Martin Staffa 077ee37942 docs(changelog, migration): add BC notice for setting ngOptions as attribute
Caused by 7fda214c4f

Closes #13145
2015-11-06 16:41:14 +01:00
Martin Staffa 0efef2385f chore(docs): display search result areas in a fixed order 2015-11-06 16:30:33 +01:00
Martin Staffa 7da22e6685 chore(docs): improve layout of search results
The API section now uses a multi-column list. This preserves the actual
order of items. Note that only browser that support @supports and
columns get the new behavior.
The line-breaking behavior of search results is also improved. Previously,
long words would break onto new lines or run into the second column.
2015-11-06 16:30:32 +01:00
Doug Krugman 92bdd7627f docs(guide/Concepts): remove unused refresh property
Closes #13257
2015-11-06 10:15:19 +02:00
jody tate 39ebb06baf docs(guide/Directives): change "it" to possessive
Closes #13253
2015-11-05 14:24:57 +02:00
Georgii Dolzhykov 9cf6b197ab docs($rootScope.Scope): default value of objectEquality parameter
Closes: #13252
2015-11-04 21:53:32 +01:00
Martin Staffa 4971ef12d4 fix(ngMessage): make ngMessage compatible with ngBind
Fixes #8089
Closes #13074

BREAKING CHANGE:

ngMessage is now compiled with a priority of 1, which means directives
on the same element as ngMessage with a priority lower than 1 will
be applied when ngMessage calls the $transclude function.
Previously, they were applied during the initial compile phase and were
passed the comment element created by the transclusion of ngMessage.
To restore this behavior, custom directives need to have
their priority increased to at least "1".
2015-11-04 17:13:53 +01:00
Martin Staffa 7c792f4cc9 docs(ngRepeat): add more info about watching and tracking
- mention $watchCollection
- highlight that track by "id" can improve render performance

Related #9508
2015-11-03 21:38:06 +01:00
Georgios Kalpakas 4daafd3dbe perf(merge): remove unnecessary wrapping of jqLite element
Fixes https://github.com/angular/angular.js/commit/75292a6cb5e17d618902f7996e80eb3118eff7b0#commitcomment-14137538

Closes #13236
2015-11-03 17:45:44 +02:00
Peter Bacon Darwin fe11265fdc test(merge): fix check on jquery object 2015-11-02 20:12:12 +00:00
Peter Bacon Darwin 75292a6cb5 fix(merge): ensure that jqlite->jqlite and DOM->DOM
Previously we were wrapping DOM elements into jqlite objects when cloning
and vice versa.

Fixes https://github.com/angular/angular.js/pull/12286#discussion_r43656917
2015-11-02 19:54:20 +00:00
JonyD 4ff6c85792 docs(ngRepeat): fix link to MDN
Closes #13226
2015-11-02 20:48:12 +01:00
Martin Staffa e26bc2370b docs(ngInclude): fix incorrect link 2015-11-02 20:45:13 +01:00
Martin Staffa 33713deeb8 docs(tutorial/0 - Bootstrapping): mention that the setup must be completed
Closes #13106
2015-11-02 20:40:53 +01:00
luckylooke 17715fa366 fix(merge): clone elements instead of treating them like simple objects
Similar fix to #11720

Closes #12286
2015-11-02 17:20:59 +00:00
Jason Bedard 96288d02d3 refactor($compile): remove skipDestroyOnNextJQueryCleanData, remove jq data of all replaced nodes
Closes: #12094
2015-11-01 23:43:01 +01:00
Lucas Mirelmann 8be98e4fdf test($interpolate): fix test on $interpolate
Fix for a test in $interpolate after an incomplete merge
2015-11-01 23:35:05 +01:00
Jason Bedard cf83b4f445 perf($interpolate): provide a simplified result for constant expressions
Closes: #10414
2015-11-01 23:31:33 +01:00
Matthew Hill 15bfea8339 docs(angular-mocks): clarify angular.mock.module usage with objects
Closes #12354
2015-11-01 07:13:00 +00:00
Jason Bedard 9b90c32f31 perf($compile): use static jquery data method to avoid creating new instances 2015-11-01 06:51:22 +00:00
Chris J. Lee f4bf744516 chore(protractor-conf.js): remove dangling comma
Closes #13051
2015-11-01 06:45:42 +00:00
Peter Bacon Darwin 0d96995fcc chore(package.json): update dgeni-packages to 0.11.0 2015-10-31 20:16:24 +00:00
Nuri Hodges 2a85a634f8 fix(orderByFilter): throw error if input is not array-like
BREAKING CHANGE:
Previously, an non array-like input would pass through the orderBy filter
unchanged.
Now, an error is thrown. This can be worked around by converting an object
to an array, either manually or using a filter such as
https://github.com/petebacondarwin/angular-toArrayFilter.
(`null` and `undefined` still pass through without an error, in order to
support asynchronous loading of resources.)

Closes #11255
Closes #11719
2015-10-31 02:52:03 +02:00
Bert Verhelst 00d2b2c4cf docs($location): improve style
Closes #13072
2015-10-30 22:05:49 +01:00
Martin Staffa e688f07023 docs(error/ctreq): fix typo
Closes #13083
2015-10-30 22:02:26 +01:00
Michael George Attard 8e2f7d37e4 docs($rootScope): improve clarity and consistency
Closes #13110
2015-10-30 21:59:43 +01:00
Georgios Kalpakas f5bc3ed9b4 test($templateRequest): remove unused dependencies
Closes #13199
2015-10-30 21:58:16 +01:00
Georgios Kalpakas 11d60af3dc docs($templateRequestProvider): make the description more generic and fix link 2015-10-30 21:58:12 +01:00
Pablo Villoslada Puigcerber 865f6065e7 docs(select): document the multiple attribute
Add the `multiple` attribute to the documentation of the select directive.

Closes #13119
2015-10-30 20:33:39 +02:00
Lucas Galfaso 91c0b364af style(ngOptionsSpec): fix code style issue 2015-10-30 12:28:26 +01:00
Lucas Mirelmann fce07f55e5 style($http): do not use angular global object to invoke isObject
Closes: #13204
2015-10-30 12:26:32 +01:00
Jason Bedard c8768d12f2 perf(copy): avoid regex in isTypedArray
Closes: #12054
2015-10-30 12:12:14 +01:00
Stephen Sauceda af6342d6fb docs(CONTRIBUTING.md): add commitizen instructions 2015-10-30 08:20:09 +00:00
Stephen Sauceda a179757fad chore(package.json): add commitizen, adapter and npm script
Closes #13194
2015-10-30 08:20:09 +00:00
Lucas Mirelmann 35eada68c4 refactor($parse): simplify constantWatchDelegate
Closes: #13176
2015-10-29 21:30:37 +01:00
Sreenivasan K bfad2a4f4a fix($animate): ensure leave animation calls close callback
Closes #12278
Closes #12096
Closes #13054
2015-10-29 07:51:18 +00:00
Shahar Talmi 54e816552f feat(Module): add helper method, component(...) for creating component directives
Since we are promoting component directives as the building blocks of
Angular applications, this new helper provides a simpler method for
defining such directives. By using sensible, widely accepted, conventions
the number of parameters needed has been cut down dramatically.

Many component directives can now be defined by simply providing a `name`,
`template`/`templateUrl`, a `controller`, and `bindings`:

```js
myMod.component('myComp', {
  template: '<div>My name is {{myComp.name}}</div>',
  controller: function() {
  },
  bindings: { name: '=' }
});
```

Closes #10007
Closes #12933
2015-10-29 07:25:02 +00:00
Stanislav Komanec 4fc734665e fix($resource): allow XHR request to be cancelled via timeout promise
Closes #12657
Closes #12675
Closes #10890
Closes #9332
2015-10-28 22:21:37 +00:00
Peter Bacon Darwin b8736e65b0 test($rootScope): ensure that only child scopes are disconnected
Related to #11786 and 8fe781fbe7
2015-10-28 22:03:42 +00:00
Alicia Lauerman b9bed7d9da fix($cacheFactory): check key exists before decreasing cache size count
Previously, there was no check for the existence of an item in the
cache when calling `$cacheFactory.remove()` before modifying the cache size
count.

Closes #12321
Closes #12329
2015-10-28 21:50:00 +00:00
Peter Bacon Darwin b2fc39d2dd feat($templateRequest): support configuration of $http options
It is now possible to configure the options sent to $http for template requests.
If no value is configured then the request will use the default $http options.

Thanks to @luckycadow for help on this feature

Closes #13188
Closes #11868
Closes #6860
2015-10-28 21:43:34 +00:00
Georgios Kalpakas 7c0731edb2 fix($http): apply transformResponse even when data is empty
Note, that (as a by-product of the previous implementation) only non-empty
data was passed through the `transformResponse` pipeline. This is no
longer the case.

When using a custom `transformResponse` function, one should make sure it
can also handle an empty (i.e. falsy) `data` argument appropriately.

Fixes #12976
Closes #12979
2015-10-28 21:41:30 +00:00
Peter Bacon Darwin 8fe781fbe7 fix($rootScope): stop IE9 memory leak when destroying scopes
Ensure that all child scopes are completely disconnected when a parent is
destroyed.

Closes #10706
Closes #11786
2015-10-28 21:32:43 +00:00
Charlie-Hua 23932a26ff docs(ngModelOptions): add missing user.data result for updateOn: blur example
In the updateOn:blur example, there is an input for user.data but the
result is missing and nowhere to see how the value changes compared to user.name.

Closes #13129
2015-10-28 22:09:04 +01:00
Georgios Kalpakas 3ca4ca463c refactor(ngMessage): remove unused argument
Closes #13087
Closes #12508
2015-10-28 18:56:51 +01:00
Peter Bacon Darwin 395f3ec638 fix(ngOptions): skip comments and empty options when looking for options
Related #12952
Closes #12190
Closes #13029
Closes #13033
2015-10-28 18:36:21 +01:00
Stu Cox 964a901bd8 docs($q): add a note re. difference in exception handling vs ES6
Closes #11472
Closes #13101
2015-10-28 08:17:39 +00:00
Ryan Hart a995ee17ee docs(ngOptions): explain the caveats of using select as and track by together
Changes:

* Modify warning message to indicate that `track by` can be used with `select as`,
  but subject to certain limitations.
* Provide both a working and an non-working example.
* Explain why the latter does not work.

Closes #13007
2015-10-27 22:00:31 +02:00
Sam Rawlins 794d1c1ebe docs($anchorScroll): fix link to HTML5 spec
Closes #13180
2015-10-27 20:39:08 +02:00
Marcy Sutton 662fb282c1 fix(ngAria): don't add tabindex to radio and checkbox inputs
Closes #12492
Closes #13095
2015-10-27 17:46:14 +01:00
Andrew Austin ffb6b2fb56 fix(ngInput): change URL_REGEXP to better match RFC3987
The URL_REGEXP in use to perform validation in ngInput is too restrictive and fails to
follow RFC3987. In particular, it only accepts ftp, http, and https scheme components and
rejects perfectly valid schemes such as "file", "mailto", "chrome-extension",
etc. The regex also requires the scheme to be followed by two "/" but the RFC says
0 to n are acceptable. This change fixes both of these issues to better align to
the standard.

Closes #11341
Closes #11381
2015-10-26 21:45:10 +00:00
Kuzminov Aleksandr Sergeevich 941c1c35f1 fix(jqLite): ensure mouseenter works with svg elements on IE
Closes #10259
Closes #10276
2015-10-26 21:21:44 +00:00
Lucas Mirelmann 29a05984fe feat($injector): Allow specifying a decorator on $injector
Allows the definition of a decorator on `$injector`

Closes: #13103
2015-10-26 22:10:41 +01:00
sevdog 4038aabffa docs($animateCss): add missing documentation for the structural option
Add missing documentation for structural option in `$animateCss` service

Closes #13049
2015-10-26 13:02:13 -07:00
Lucas Galfaso 773efd0812 fix(isArrayLike): handle jQuery objects of length 0
Closes: #13169
Closes: #13171
2015-10-26 16:37:38 +00:00
Risan Bagja Pradana 80881949fc docs(tutorial): add a note about Chrome or Firefox not being available
Based on the current configuration, Karma will run the tests on both
Chrome and Firefox, which will result in an error if either browser is not
available on the user's machine. This commit adds a note and directions on
how to solve this.

Closes #13114
2015-10-26 15:01:14 +02:00
Jack Viers 2c8d87e064 fix(Angular.js): fix isArrayLike for unusual cases
Closes #10186
Closes #8000
Closes #4855
Closes #4751
Closes #10272
2015-10-25 14:54:11 +00:00
Jason Bedard 33c67ce785 perf(copy): only validate/clear user specified destination
Closes #12068
2015-10-24 11:08:14 +02:00
Lucas Mirelmann ad4296d966 refactor($rootScope): remove unused dependency
Removed unused dependency

Closes #13102
2015-10-16 18:28:37 +02:00
Georgios Kalpakas 469b14a525 refactor($compile): remove unused var
Closes #13086
2015-10-15 17:02:49 +03:00
Lucas Mirelmann 1caf0b6bee fix($parse): evaluate once simple expressions in interpolations
For simple expressions without filters that have a stateless interceptor
then handle the 2nd phase parse evaluation using `inputs`.

TL;DR
This fixes the issue that interpolated simple expressions were evaluated twice
within one digest loop.

Long version, things happen in the following order:

* There was an overhaul on $interpolate, this overhaul changed $parse and
  incorporated the concept of an interceptor.
* Optimization on $parse landed  so expressions that have filters without
  parameters (or the parameters are constants) would be evaluated in 2 phases,
  first to evaluate the expression sans the filter evaluation and then with
  the filter evaluation. This also used interceptors [the second evaluation
  issue was added here]
* More optimizations on $parse landed and now expressions could be evaluated
  in 2 phases. One to get all the possible values that could change (lets call
  this state), the state was checked by $watch to know if an expression changed.
  The second to continue the evaluation (as long as this state is provided).
  This, once again, used interceptors

The last change, was supposed to fix the issue, but there was an assumption in
the existing code that the code would always generate the 2 phases functions,
but that is not true. If the expression is simple enough (just like the one in
your case) then the 2-phase evaluations functions are not generated. In this
case, if a stateless interceptor was added (just like what $interpolate adds)
then the state was not used and you see the function being evaluated twice.
This explains why, if you change the expression from
`Hello {{log('A')}} {{log('B')}}!` to `Hello {{log('A') + ' ' + log('B')}}!`,
then the repetition is not there.

Closes #12983
Closes #13002
2015-10-14 23:45:07 +02:00
zurin 9f716dd590 docs(guide/Scopes): fix grammar
Added a comma to make reading more natural.

Closes #13084
2015-10-14 16:14:21 +03:00
Michael Salmon 914a934b6f docs(guide/Directives): improve description of linking function
The `controller` and `transclude` parameters of the linking function were not
mentioned in the description, but used in the examples.
This commit improves the description and links to the `$compile` API docs
for more details.

Closes #13028
2015-10-14 10:48:06 +03:00
Peter Bacon Darwin a4ada8ba9c feat($compile): multiple transclusion via named slots
Now you can efficiently split up and transclude content into specified
places in a component's template.

```html
<pane>
  <pane-title>Some content for slot A</pane-title>
  <pane-content>Some content for slot A</pane-content>
</component>
```

```js
mod.directive('pane', function() {
  return {
    restrict: 'E',
    transclude: { paneTitle: '?titleSlot', paneContent: 'contentSlot' },
    template:
    '<div class="pane">' +
      '<h1 ng-transclude="titleSlot"></h1>' +
      '<div ng-transclude="contentSlot"></div>' +
    '</div>' +
  };
});
```

Closes #4357
Closes #12742
Closes #11736
Closes #12934
2015-10-12 14:46:53 +01:00
Martin Staffa 40c974ab14 docs(linky): mention sanitization, improve formatting 2015-10-09 15:10:37 +02:00
Stian Jensen 06f002b161 feat(linky): add support for custom attributes
Optional extra attributes may be defined either as:
- a map of attributes and values
- a function that takes the url as a parameter and returns a map

Closes #12558
Closes #13061
2015-10-09 15:10:36 +02:00
Peter Bacon Darwin 8226ff8b8e style(ngMockSpec): fix excessive indentation
See https://github.com/angular/angular.js/pull/12406#discussion_r41503587. Thanks @gkalpak :-)
2015-10-08 15:13:18 +01:00
Peter Bacon Darwin d67e999dfb feat(ngMock): add expectRoute and whenRoute shortcuts with colon param matching
Add `params` argument to the `when()` and `expect()` functions to give map regex
groups to keys on a new `params` argument of the `respond()` callback.

Add `whenRoute` and `expectRoute` methods to `$httpBackend` to support matching
URLs by patterns similar to those defined for `ngRoute`.

Closes #12406
2015-10-08 15:07:18 +01:00
Martin Staffa a8e03b3a90 docs(ngOptions): add info about preselecting complex models
Closes #12966
2015-10-08 15:54:20 +02:00
Chris J. Lee 6f3e26c404 test(ngResource): fix typos in tests
Closes #13044
2015-10-08 11:29:16 +03:00
Flavio Corpa Ríos 1c75ea613d docs(ngInclude): add workaround for using onload function with SVG in IE11
Closes #12493
Closes #13042
2015-10-07 23:02:23 +02:00
Jason Hopper c8e1db2050 docs(tutorial): update angular module versions to reflect tutorial files
Closes #12991
Closes #12992
2015-10-07 17:51:50 +02:00
Sugan Krishnan 74ed28665d docs($sce): fix typo
Closes #13030
2015-10-07 13:22:40 +01:00
Peter Bacon Darwin 4ad0ca130d refactor($compile): check removeWatches before calling
Previously we assigned `noop` if there was no function but there is no
performance advantage in doing this since the check would have to happen
either at assignment time or at call time.

Removing this use of `noop` makes the code clearer, IMO :-)

Closes #12528
2015-10-07 12:30:30 +01:00
Peter Bacon Darwin b51dd3010d refactor($compile): initialize removeWatchCollection at the start
This check means that we don't have to keep checking whether the collection
has been created when adding a new watcher

Closes #12528
2015-10-07 12:30:21 +01:00
Peter Bacon Darwin 6e6f31943c refactor($compile): rename variables to clarify their purpose
Closes #12528
2015-10-07 12:30:15 +01:00
Jason Bedard 66fee7e22a refactor($compile): move $scope.$on('$destroy') handler out of initializeDirectiveBindings
Since only one of three invocations of `initializeDirectiveBindings` actually
adds a `$destroy` handler to the scope (the others just manually call unwatch
as needed), we can move that code out of this method.

This also has the benefit of simplifying what parameters need to be passed
through to the linking functions

Closes #12528
2015-10-07 12:30:06 +01:00
Martin Staffa beea571660 Revert "fix(ngOptions): skip comments when looking for option elements"
This reverts commit 7f3f3dd3eb.
The fix only fixed a specific case and exhibited a flawed logic
(namely skipping every option if the emptyOption is a comment).
See https://github.com/angular/angular.js/issues/12190#issuecomment-145877914

Conflicts:
	test/ng/directive/ngOptionsSpec.js
2015-10-07 11:28:13 +02:00
Richard Harrington 0c8a9a0e1a docs(constant): fix pluralization
Closes #13024
2015-10-06 23:21:15 +03:00
Peter Bacon Darwin fd83d3724a fix(ngMock): reset cache before every test
We don't need to have values in the cache from previous tests. This was
causing failures in all subsequent tests when a single test failed due
to a memory leak.

Now that we reset the cache each time we do not need to store the cache
size at the start of each test

Closes #13013
2015-10-06 13:55:16 +01:00
Martin Staffa 2fcfd75a14 fix(ngOptions): override select option registration
When ngOptions is present on a select, the option directive should not be able to
register options on the selectCtrl since this may cause errors during the
ngOptions lifecycle.

This can happen in the following cases:

- there is a blank option below the select element, an ngModel
directive, an ngOptions directive and some other directive on the select
element, which compiles the children of the select
(i.e. the option elements) before ngOptions is has finished linking.

- there is a blank option below the select element, an ngModel
directive, an ngOptions directive and another directive, which uses
templateUrl and replace:true.

What happens is:
- the option directive is compiled and adds an element `$destroy` listener
that will call `ngModel.$render` when the option element is removed.
- when `ngOptions` processes the option, it removes the element, and
triggers the `$destroy` listener on the option.
- the registered `$destroy` listener calls `$render` on `ngModel`.
- $render calls `selectCtrl.writeValue()`, which accesses the `options`
object in the `ngOptions` directive.
- Since `ngOptions` has not yet completed linking the `options` has not
yet been defined and we get an error.

This fix moves the registration code for the `option` directive into the
`SelectController.registerOption()` method, which is then overridden by
the `ngOptions` directive as a `noop`.

Fixes #11685
Closes #12972
Closes #12968
Closes #13012
2015-10-06 13:43:28 +01:00
Raghav 2d40507547 docs($animate): fixed typo ("an animations" -> "any animations")
Closes #13020
2015-10-06 13:15:13 +03:00
Georgios Kalpakas ecf9304811 fix(limitTo): start at 0 if begin is negative and exceeds input length
Previously, specifying a negative `begin` whose abs value exceeds the
input's length, would behave unexpectedly (depending on the value of
`limit` relative to `begin`). E.g.:

```
limitToFilter('12345', 3, -7) === '1'
// but
limitToFilter('12345', 10, -7) === '123'
```

This commit fixes the unexpected behaviour, by setting `begin` to 0 in the
aforementioned cases. Thus, the previous examples become:

```
limitToFilter('12345', 3, -7) === limitToFilter('12345', 3, 0) === '123'
// and
limitToFilter('12345', 10, -7) === limitToFilter('12345', 10, 0) === '12345'
```

Fixes #12775
Closes #12781
2015-10-06 09:38:54 +01:00
Matias Niemelä b9ab88776b docs(ngAnimate): simplify $animateCss example code 2015-10-05 10:55:56 -07:00
spoonraker 00bf218304 docs(tutorial): updates for the text for animations in step 12
The grammar for the animation description has now been improved.

Closes #12740
2015-10-05 10:20:58 -07:00
Jason Hopper 95fbf168d1 docs(tutorial): update tutorial copy to reflect updates to tutorial source @bower.json excerpt for animations
Code breaks if tutorial is followed without reset.
bower.js exceprt copy does not match source.
Changed to reflect in text body.

Closes #12993
2015-10-05 10:17:30 -07:00
Shahar Talmi 51a27c0f1a feat(ngMock): invoke nested calls to module() immediately
Before 1.3, it was possible to call `angular.mock.module()` from inside
another module. After this version additional calls were just ignored.

It is helpful to be able to do this since a test may have helper functions
that need to access "config"-time things such as constants or providers,
and without this change it is difficult to get hold of the `$provide`
object from within those helpers.

Closes #12887
2015-10-05 12:50:31 +01:00
Magnus Pedersen f02811f0bb docs(ngOptions): rephrased a sentence for clarity
Closes #13010
2015-10-05 11:48:30 +03:00
Alexandr Gureev bcf78ebb18 docs(ngAnimate): fix typos in examples
Closes #12995
2015-10-02 11:23:48 +03:00
John Zhang 3050dd1b47 docs($httpProvider): fix description of useLegacyPromiseExtensions
useLegacyPromiseExtensions's default value is true, and the  legacy
methods exist when it is set to true.

Closes #12974
2015-10-01 18:30:01 +02:00
Donghwan Kim 1efdb4745a docs(guide/Running in Production): fix an incorrect indefinite article
Closes #12986
2015-10-01 18:25:11 +02:00
koyner d73f7dff45 docs(guide/Forms): fix indentation.
Closes #12988
2015-10-01 18:24:29 +02:00
Martin Staffa f047ad2628 docs(guide/Using $location): note that the fakeBrowser is not for actual projects
Closes #12982
Closes #12987
2015-10-01 18:20:31 +02:00
Peter Bacon Darwin 049d3def80 docs(CHANGELOG): the $time service feature was reverted as it is not ready 2015-10-01 13:22:40 +01:00
Peter Bacon Darwin 00778aa239 test($compile): move lazy compile specs into a describe block 2015-10-01 12:27:52 +01:00
Matias Niemelä 6b123a0419 chore(CHANGELOG): update with changes for 1.5.0-beta.1 2015-09-29 13:59:34 -07:00
Matias Niemelä 4079eea6b3 chore(CHANGELOG): update with changes for 1.4.7 2015-09-29 13:59:21 -07:00
Matias Niemelä d277ac2eb8 chore(CHANGELOG): update with changes for 1.3.20 2015-09-29 13:59:10 -07:00
Matias Niemelä 9deb123d04 chore(CHANGELOG): update with changes for 1.2.29 2015-09-29 13:58:54 -07:00
Martin Probst 1c2d2e8ba0 docs($sceProvider): XSS when turning of SCE
Document that turning off SCE is very, very dangerous and should normally not be
used by applications.
2015-09-28 14:19:38 +02:00
Martin Probst 144bcc84ab docs($interpolateProvider): document XSS in $interpolate
`$interpolateProvider.startSymbol` & friends are often used dangerously, to embed Angular templating in other templating languages. This change documents that that is a very dangerous practice.
2015-09-28 14:07:31 +02:00
Shrulik 693021c449 docs($animateCss): remove superfluous asterisk
Closes #12959
2015-09-27 22:14:46 +03:00
Rishabh Jain dc818e1165 docs(input[time]): fixes a typo 2015-09-27 20:11:24 +02:00
Martin Staffa e51174bf13 docs($http): link to usage where config is mentioned; make drier
Linking to usage section makes it easier for beginners to find out what the config object looks like.
The General Usage section now features an example that actually uses $http(config), and the Shortcut Methods section has been moved so that it appears directly after.

Closes #12949
Closes #12950
2015-09-27 15:42:25 +02:00
Martin Staffa 7f3f3dd3eb fix(ngOptions): skip comments when looking for option elements
When the empty/blank option has a directive that transcludes, ngIf for example,
a comment will be added into the select. Previously, ngOptions used this
comment as the empty option, which would mess up the displayed options.

Closes #12190
2015-09-27 15:08:35 +02:00
Martin Staffa d077966ff1 test(ngOptions): clarify a test description 2015-09-26 17:59:35 +02:00
Stefan Krüger 0df4ff800a docs(guide/Directives): let myTabs directive ctrl use inline array notation
modified `docsTabsExample` myTabs directive ctrl at
[Creating Directives that Communicate Example](https://docs.angularjs.org/guide/directive#creating-directives-that-communicate) so that it uses
[Inline Array Annotation](https://docs.angularjs.org/guide/di#inline-array-annotation)
and is compatible with
[Using Strict Dependency Injection](https://docs.angularjs.org/guide/di#using-strict-dependency-injection)

Closes #12767
2015-09-25 11:26:35 +02:00
Martin Staffa 6208b76afa chore(docs): update to lunr-0.5.12
This improves the search results for certain terms.
For example, previously guide/scope was unfindable with the search
term 'scope', now it's the first hit.

Closes #12937
2015-09-25 11:09:33 +02:00
daviskoh 70dac5ae82 fix($parse): fix typo in error message ("assing" -> "assign")
Closes #12940
2015-09-25 10:56:29 +03:00
Martin Staffa aafbd94439 docs(ngModel): align $viewValue description with $setViewValue 2015-09-24 21:14:50 +02:00
Matias Niemelä e732f8e579 docs($animateCss): options.transition should be options.transitionStyle 2015-09-24 10:07:14 -07:00
Matias Niemelä 9f67da6252 feat($animateCss): add support for temporary styles via cleanupStyles
Some animations make use of the `from` and `to` styling only for the
lifetime of the animation. This patch allows for those styles to be
removed once the animation is closed automatically within `$animateCss`.

Closes #12930
2015-09-24 09:55:43 -07:00
Igor Minar b3a3c6a72e build(travis): make sauce connect process query a bit more specific 2015-09-23 14:00:24 -07:00
Igor Minar e8cdabe129 build(travis): fix typo in a comment 2015-09-23 14:00:23 -07:00
Martin Staffa 3af71bee75 Revert "refactor(ngModel): move model -> view update from watchFn to watchAction"
This reverts commit 862c9d8bb2. The
commit was accidentially pushed. Sorry for the noise.
2015-09-23 19:14:43 +02:00
Igor Minar f2724b2bbc build(travis): gracefully shut down the sauce connect tunnel after the tests are done running
This is to prevent sauce connect tunnel leaks.

Closes #12921
2015-09-23 09:40:03 -07:00
Martin Staffa 38500669f6 docs(ngList): whitespace -> newline 2015-09-23 17:35:06 +02:00
Martin Staffa 862c9d8bb2 refactor(ngModel): move model -> view update from watchFn to watchAction 2015-09-23 13:39:42 +02:00
Matias Niemelä 240d5896ec fix(ngAnimate): ensure anchoring uses body as a container when needed
Prior to this fix anchoring would allow for a container to be a document
node or something higher beyond the body tag. This patch makes it fall
back to body incase the rootElement node exists as a parent ancestor.

Closes #12872
2015-09-22 12:49:28 -07:00
Matias Niemelä 64ef084b91 revert: chore(core): introduce $$body service
Relying on the body node to be present right at injection has
caused issues with unit testing as well as some animations on
the body element. Reverting this patch fixes these issues.

Closes #12874
2015-09-22 12:47:21 -07:00
Matias Niemelä 8b27c3f064 fix(ngAnimate): callback detection should only use RAF when necessary
Callbacks are detected within the internals of ngAnimate whenever an
animation starts and ends. In order to allow the user to set callbacks
the callback detection needs to happen during the next tick. Prior to
this fix we used $$rAF to do the tick detection, however, with this
patch we intelligently use $$postDigest to do that for us and then
only issue a call to `$$rAF` if necessary.
2015-09-22 11:01:33 -07:00
Peter Bacon Darwin 8366622bed fix(ngMessages): prevent race condition with ngAnimate
If `ngMessage` tried to add a message back in that was about to be removed
after an animation, the NgMessageController got confused and tried to detach
the newly added message, when the pending node was destroyed.

This change applies a unique `attachId` to the message object and its DOM
node when it is attached. This is then checked when a DOM node is being
destroyed to prevent unwanted calls to `detach`.

Closes #12856
Closes #12903
2015-09-22 17:54:04 +01:00
Georgios Kalpakas d3de0066b0 chore(check-node-modules): make check/reinstall node_modules work across platforms
The previous implementations (based on shell scripts) threw errors on
Windows, because it was not able to `rm -rf` 'node_modules' (due to the
255 character limit in file-paths).

This implementation works consistently across platforms and is heavily based on
'https://github.com/angular/angular/blob/3b9c08676a4c921bbfa847802e08566fb601ba7a/tools/npm/check-node-modules.js'.

Fixes #11143
Closes #11353

Closes #12792
2015-09-22 15:46:13 +03:00
Martin Staffa b7e5133b2e docs(guide/Directives): fix link formatting
Closes #12909;
2015-09-22 13:11:39 +02:00
Martin Staffa 42c97c5db5 fix(ngOptions): prevent frozen select ui in IE
In certain scenarios, IE10/11/Edge create unresponsive select elements.
The following contribute to the bug:
- There need to be at least 2 selects next to each other
- The option elements are added via javascript
- the option.value is accessed before it is set
- the option.label is added after the option.value has been set
- The first select is wrappend in an element with display: inline or
display: inline-block,

This cannot be tested in a unit-test or e2e test.

Closes #11314
Closes #11795
2015-09-22 12:58:41 +02:00
Lucas Galfaso e1f4f23f78 fix($parse): block assigning to fields of a constructor
Throw when assigning to a field of a constructor.

Closes #12860
2015-09-22 10:43:43 +01:00
Peter Bacon Darwin 630280c7fb feat(ngModel): provide ng-empty and ng-not-empty CSS classes
If the `$viewValue` is empty then the `ng-empty` CSS class is applied
to the input. Conversely, if it is not empty the `ng-not-empty` CSS class
is applied. Emptiness is ascertained by calling `NgModelController.$isEmpty()`

Closes #10050
Closes #12848
2015-09-22 10:16:49 +01:00
Peter Bacon Darwin 496a67c10e test(ngModel): remove jankiness test
It is no longer appropriate to test this here as $animate takes care of
queueing up CSS class changes into a single update.
2015-09-22 10:16:13 +01:00
Lucas Mirelmann 7dcfe5e03e revert: feat($time): create time service
This reverts commit fa4c7b7f1d.
2015-09-21 21:08:37 +02:00
Ivan Verevkin 9e83b8355e docs($cacheFactory): fix call to isUndefined() in example
Closes #12899
2015-09-21 15:20:50 +03:00
Shahar Talmi 03726f7fbd fix(injector): support arrow functions with no parenthesis
with arrow functions parenthesis are optional in case you have exactly
one argument to the function. the previous regexp assumed function
arguments are always inside parenthesis and so it didn't annotate
functions like `$http => $http.get(...)` correctly

Closes #12890
2015-09-21 08:49:19 +03:00
Shahar Talmi 75893ae9e7 chore(karma): upgrade chrome in saucelabs to latest 2015-09-21 08:49:06 +03:00
Shahar Talmi d9ca245917 refactor(injector): extract common code to function 2015-09-21 08:49:06 +03:00
Shahar Talmi 3259aabdf3 chore(npm): upgrade grunt-jscs 2015-09-21 08:49:06 +03:00
Lucas Mirelmann befeeb3689 style(*): small style fixes 2015-09-20 16:46:03 +02:00
Kent C. Dodds 79577c5d31 feat($injector): add strictDi property to $injector instance
Add a strictDi property which is true or false when creating an instance of an injector.

Closes #11728
Closes #11734
2015-09-20 16:41:27 +02:00
Peter Bacon Darwin b71d7c3f3c fix(ngOptions): allow falsy values as option group identifiers
Now one can use `''`, `0`, `false` and `null` as option groups. Previously
all of these falsy values were treated as the option not being a member of
a group.

Closes #7015
Closes #7024
Closes #12888

BREAKING CHANGES
If your data contains falsy values for option groups, then these options
will now be placed into option groups. Only option groups that are `undefined`
will result in the option being put in no group. If you have data that
contains falsy values that should not be used as groups then you must
filter the values before passing them to `ngOptions` converting falsy
values to `undefined`.
2015-09-20 16:40:36 +02:00
Marcin Wosinek fa4c7b7f1d feat($time): create time service
Add simple $time service to allow easier mocking dates in applications.

Closes #10402
Closes #10525
2015-09-20 16:37:50 +02:00
Daniel Herman 652b83eb22 perf($compile): Lazily compile the transclude function
For transcluded directives, the transclude function can be lazily compiled
most of the time since the contents will not be needed until the
`transclude` function was actually invoked.  For example, the `transclude`
function that is passed to `ng-if` or `ng-switch-when` does not need to be
invoked until the condition that it's bound to has been matched.  For
complex trees or switch statements, this can represent significant
performance gains since compilation of branches is deferred, and that
compilation may never actually happen if it isn't needed.

There are two instances where compilation will not be lazy; when we scan
ahead in the array of directives to be processed and find at least two of
the following:

* A directive that is transcluded and does not allow multiple transclusion
* A directive that has templateUrl and replace: true
* A directive that has a template and replace: true

In both of those cases, we will need to continue eager compilation in
order to generate the multiple transclusion exception at the correct time.
2015-09-19 22:32:59 +02:00
Lucas Mirelmann 20cf7d5e3a fix($parse): do not convert to string computed properties multiple times
Do not convert to string properties multiple times.
2015-09-19 22:19:14 +02:00
Martin Staffa ded2518756 fix(ngOptions): throw if ngModel is not present
Closes #7047
Closes #12840

BREAKING CHANGE:
`ngOptions` will now throw if `ngModel` is not present on the `select`
element. Previously, having no `ngModel` let `ngOptions` silently
fail, which could lead to hard to debug errors. The change should
therefore not affect any applications, as it simply makes the
requirement more strict and alerts the developer explicitly.
2015-09-19 15:26:42 +02:00
Martin Staffa b366f0352a fix(input): remove workaround for Firefox bug
The bug in question has been fixed in FF 38, which is also the
current ESR, so it's safe to remove the workaround: https://bugzilla.mozilla.org/show_bug.cgi?id=1064430
2015-09-19 12:24:17 +02:00
Jason Bedard 76c2491a31 fix($compile): use createMap() for $$observe listeners when initialized from attr interpolation
Closes #10446
2015-09-19 08:46:55 +01:00
Mark Knell ef3df93afe docs(guide/Unit Testing): tighter English
Leaner, more forceful style.

Fixes a grammatical problems with subject number doesn't agrees with the verb. (originally "We have built many features into
Angular which makes...", which reduces to "features...which makes").

More authoritative use of commas, such as the Oxford comma in lists of three or more.

Sentences that are sentences, not fragments. (Yes, that was a fragment just now. I'm not writing docs now that reflect the polish of the project.)

The English grammatical/stylistic notion of parallelism.

Etc. This is just polish. The ideas are fine.

Closes #10478
2015-09-18 17:11:15 -04:00
Sjur Bakka 106f90aafa feat($http): add $xhrFactory service to enable creation of custom xhr objects
Closes #2318
Closes #9319
Closes #12159
2015-09-18 19:43:26 +01:00
Igor Minar 86e8088b38 test($sanitize): add a test to prove that html comments are being stripped
Closes #12524
2015-09-18 19:38:43 +01:00
Igor Minar a654bdfed9 refactor(): rename local variables to improve code clarity
Closes #12524
2015-09-18 19:38:38 +01:00
Igor Minar 2c22c57e58 refactor($sanitize): remove <script> from valid block elements
the script and style tag are explicitly blacklisted, so this doesn't change any functionality.
the change is done to improve code clarity.

Closes #12524
2015-09-18 19:38:32 +01:00
Igor Minar a4dfa4d061 fix($sanitize): strip urls starting with 'unsafe:' as opposed to 'unsafe'
Closes #12524
2015-09-18 19:38:25 +01:00
Igor Minar bc0d8c4eea fix($sanitize): add mXSS protection
Closes #12524
2015-09-18 19:38:18 +01:00
Igor Minar 9b84fcad76 chore(travis): disable browserstack builds for now
we don't really pay attention to them anyway.

Closes #12524
2015-09-18 19:38:12 +01:00
Igor Minar f33ce173c9 fix($compile): properly sanitize xlink:href attribute interoplation
Closes #12524
2015-09-18 19:38:05 +01:00
Igor Minar 181fc567d8 feat($sanitize): make svg support an opt-in
Closes #12524

BREAKING CHANGE: The svg support in  is now an opt-in option

Applications that depend on this option can use  to turn the option back on,
but while doing so, please read the warning provided in the  documentation for
information on preventing click-hijacking attacks when this option is turned on.
2015-09-18 19:37:59 +01:00
Igor Minar 94207f8fb6 fix($sanitize): support void elements, fixups, remove dead code, typos
Closes #12524
2015-09-18 19:37:45 +01:00
Misko Hevery 35a21532b7 refactor($sanitize): new implementation of the html sanitized parser
This implementation is based on using inert document parsed by the browser

Closes #11442
Closes #11443
Closes #12524
2015-09-18 19:37:29 +01:00
Alessandro Diaferia 1c97a6057b fix(ngResource): encode & in URL query param values
Closes #12201
2015-09-18 16:32:04 +03:00
Peter Bacon Darwin 658a865c5b fix(filters): ensure formatNumber observes i18n decimal separators
Closes #10342
Closes #12850
2015-09-18 13:45:01 +01:00
Peter Bacon Darwin f8cf28a788 chore(package.json): kick-off 1.5 branch 2015-09-17 13:42:10 +01:00
Peter Bacon Darwin 4dd10fd964 docs(CHANGELOG): add 1.4.6 changes 2015-09-17 13:39:46 +01:00
Peter Bacon Darwin 26119c09d1 chore(bower/publish): move DIST_TAG so that it gets the correct value
In the position that DIST_TAG was being assigned it was trying to get the
`distTag` value from the wrong (i.e. a bower-...) repository.
2015-09-16 23:09:47 +01:00
Georgios Kalpakas 927ebd9986 docs(select): add missing id attributes in examples 2015-09-16 10:36:02 +03:00
Jay Springate f5536ab43c docs(select): correct sample file text
Closes #12868
2015-09-16 09:56:24 +03:00
Magee Mooney 9e6a9b9922 docs(gdocs.js): fix typo (Eror -> Error)
Closes #12858
2015-09-15 07:51:41 +03:00
Magee Mooney bfa66a90c2 docs(compare-master-to-stable.js): fix typo (comands -> commands)
Closes #12857
2015-09-15 07:42:15 +03:00
Georgios Kalpakas cdd1227a30 fix(jqLite): properly handle dash-delimited node names in jqLiteBuildFragment
Fixes #10617

Closes #12759
2015-09-15 07:32:09 +03:00
Georgios Kalpakas 19ecdb54bf fix(ngJq): properly detect when ng-jq is empty
Previously, even when `ng-jq` was empty (which should force the use of
jqLite), Angular tried to find jQuery on `window['']`. If it didn't find
anything there, it would fall back to jqLite (as expected).

Nonetheless, trying to access `window['']` calls `getElementById('')`,
which issues a warning in Firefox (maybe others).

This fix properly detects when `ng-jq` is empty and avoids trying to
access `window['']`.

Fixes #12741
2015-09-14 22:43:55 +02:00
Peter Bacon Darwin 30aa3eff4c chore(scripts/publish): get dist-tag from package.json
Closes #12722
2015-09-14 21:29:16 +01:00
Peter Bacon Darwin 8d39bd8abf fix($browser): handle async updates to location
Both browser reloads and iOS 9 bugs cause the window.location to report
a different href that which we have just set. The change does not become
available until the next tick.

This change generalises previous work to deal with reloads to deal with
the iOS 9 bug in the UIWebView component.

Closes #12241
Closes #12819
2015-09-14 21:27:46 +01:00
Matias Niemelä 472d076cca fix(ngAnimateMock): $animate.flush should work for looping animations 2015-09-14 13:02:46 -07:00
Arliang 1ae0be13c2 docs(CHANGELOG): fix typo
Closes #12837
2015-09-14 11:11:25 +03:00
toastman 159efdd429 docs($httpBackend): fix typo/mismatch
There is an mismatch for status in controller and test.
In controller $scope.status = 'ERROR!' and in test we
expect($rootScope.status).toBe('Failed...') so the test will fail;

Closes #12834
2015-09-13 22:18:07 +02:00
Martin Staffa 4755a35b7d test(input): clarify a test's description and expectations
The test ensures that when the trueValue is a string, the required error
is removed, not that the model is set to the trueValue.
2015-09-13 19:23:31 +02:00
Lucas Galfaso b2f8b0b875 fix($parse): throw error when accessing a restricted property indirectly
When accessing an instance thru a computed member and the property is an array,
then also check the string value of the array.

Closes #12833
2015-09-13 16:30:58 +01:00
lucastetreault 24cd70058d refactor(*): use isDefined and isUndefined consistently
Fix any place that compares with `undefined` to use `isUndefined` and `isDefined` instead.

Closes #4365
Closes #12831
2015-09-12 17:17:11 +01:00
indrimuska e46ab43422 docs($interpolate): add missing bracket in first example
Closes #12824
2015-09-11 15:00:15 +03:00
Georgios Kalpakas 8a62a8c7f0 docs(ngInit): fix typo ("unnecesary" --> "unnecessary")
Closes #12810
2015-09-11 14:54:16 +03:00
Georgios Kalpakas b6c2f8b854 docs(CONTRIBUTING.md): mention gitter community
Closes #12782
2015-09-11 14:46:33 +03:00
Martin Staffa 00ee090f4f docs(ngMessageFormat): convert plnkr to internal example
Fixes #12801
2015-09-10 00:12:32 +02:00
Georgios Kalpakas 544001f5a3 fix(input): ignore min/max if they are empty on all input types
When the min/max attributes are empty (i.e. `attrs.min/max === ''`), there
should be no min/max validation applied (i.e. all values should be valid
wrt min/max). This works correctly for `input[number]`, but not for date
input family (`input[date/datetime-local/time/week/month]`).

In the case on `input[number]`, an empty string for `attrs.min/max` is
translated to `undefined` for `minVal/maxVal` and a check for
`isUndefined(minVal/maxVal)` ensures that no min/max validation takes
place.
For the data input family, an empty string for `attrs.min/max` is
translated to `NaN` (by `parseDate()`), so an additional check (for
`isNaN(minVal/maxVal)`) is required.

Fixes #12363

Closes #12785
2015-09-09 15:31:33 +03:00
Peter Bacon Darwin 7175d0d0e3 docs(ngRepeat): make ngInit note a bit clearer
Closes #5623
2015-09-09 13:27:05 +01:00
Peter Bacon Darwin 010d9b6853 docs(ngInit): relaxed the warning notice 2015-09-09 13:15:02 +01:00
Peter Bacon Darwin 122ab074ca fix(angular.copy): support copying XML nodes
Closes #5429
Closes #12786
2015-09-09 13:10:03 +01:00
Peter Bacon Darwin e22bf9ac78 docs(indexPage): update Case Studies link to new site 2015-09-09 11:52:01 +01:00
Akshay Agarwal 324cb6b358 docs(angular.version): fix summary description
Fix summary description of `angular.version`.
The property description is best kept for the detailed page.

Closes #12790
2015-09-08 23:26:53 +03:00
Martin Staffa 80a2176e20 docs($compile): clarify scope types and controllerAs
Closes #12537
Closes #12758
2015-09-08 11:52:01 +01:00
Peter Bacon Darwin 681affef59 style($rootScope): remove trailing whitespace 2015-09-07 22:23:44 +01:00
kwypchlo 0ca8b1df20 fix(toDebugString): change replacement string
As discussed in #10085, the original replacement string can be treated
as html when displayed by the browser so it replaces it with '...' string.

Closes #10103
2015-09-07 22:23:43 +01:00
HeberLZ 20fb626b78 fix(rootScope): add support for watchCollection to watch an object which does not inherit from Object
Closes #9964
2015-09-07 22:08:02 +01:00
HeberLZ 7ea2c7f36e fix(ngRepeat): add support to iterate an object's properties even if it does not inherit from Object
Closes #9964
2015-09-07 22:06:41 +01:00
Bernie Telles 912cbdd468 docs($rootScope): explain why watchExpression should be idempotent
This attempts to clarify the rationale. The previous sentence was a bit ambiguous.

Closes #9963
2015-09-07 21:37:50 +01:00
Jason Bedard 0202663e93 perf(Angular): only create new collection in getBlockNodes if the block has changed
Closes #9899
2015-09-07 21:34:22 +01:00
=Florian Bernstein 159bbf11ac docs($compile): improve documentation on directive $scope usage
Add information about the behavior of several directives, especially of
their scopes when applied on a single element.

Closes #5761
Closes #9727
2015-09-07 21:05:34 +01:00
Peter Bacon Darwin 9d2cc8341c test($http): remove use of deprecated success and error calls in tests 2015-09-07 14:43:33 +01:00
Pawel Kozlowski 38520a1a73 fix($http): propagate status -1 for timed out requests
Fixes #4491
Closes #8756
2015-09-07 14:30:26 +01:00
Izhaki 470eb37d29 docs(guide/directive): clarification on the 'matches' terminology
Closes #8120
2015-09-07 12:19:09 +01:00
Peter Bacon Darwin 4baf25b3ce test(ng-options): add tests for option element with no value attribute
See #6519
2015-09-07 12:01:34 +01:00
Peter Bacon Darwin eb193686a5 test(select): add tests for option element with no value attribute
See #6519
2015-09-07 12:01:33 +01:00
Peter Bacon Darwin 4bebe7830b test(ngOptions): fix typo 2015-09-07 12:01:33 +01:00
Georgios Kalpakas 146cbf7eaa style(ngAria): make JSCS happy again 2015-09-07 12:54:38 +03:00
Marcy Sutton b8e356191f doc(ngAria): update the accessibility guide
Closes #12262
2015-09-07 12:16:36 +03:00
marcysutton f48244ce5e fix(ngAria): clean up tabindex usage
* Do not put tabindex on native controls using ng-model or ng-click
* Uses a single nodeBlacklist to limit which elements receive support

Closes #11500
2015-09-07 12:13:46 +03:00
thorn0 ebba426c0c docs($compile): clarify 'sharing' controllers
The current wording may make the reader erroneously think that one controller
can belong to multiple directives.

Closes #12768
2015-09-06 11:36:52 +03:00
Martin Staffa aa11dfc162 style(formSpec): fix indentation 2015-09-04 11:42:52 +02:00
Martin Staffa c6110e8b08 fix(form, ngModel): correctly notify parent form when children are added
Test that re-added controls propagate validity changes to the parent form.

Ensure that when a form / control that was removed and then attached
to a different parent, is renamed / deleted, the new parent will
be notified of the change.

Document that dynamic adding / removing of controls may require manually
propagating the current state of the control to the parent form.
2015-09-04 11:42:51 +02:00
Martin Staffa 290b5049c2 fix(ngModel): remove reference to parentForm from removed control
This fixes cases where the control gets removed, but the control's
element stays in the DOM.
Previously, if the removed control's validity changed, a reference to
it would again be stored on its former parent form.

Fixes #12263
2015-09-04 11:42:51 +02:00
Martin Staffa f8a07dd9fe refactor(form, ngModel): streamline how controls are added to parent forms
This delegates setting the control's parentForm to the parentForm's
$addControl method. This way, the model controller saves one instance
of looking up the parentForm controller. The form controller keeps two
lookups (one for its own ctrl, one for the optional parent).

This also fixes adding the parentForm in the following case:
- a control is removed from a parent, but its corresponding DOM
element is not destroyed
- the control is then re-added to the form

Before the fix, the control's parentForm was only set once during
controller initialization, so the the parentForm would not be set on
the control in that specific case.
2015-09-04 11:42:51 +02:00
Georgios Kalpakas 6f39f10827 fix($httpBackend): send null when post-data is undefined
IE11 (and maybe others) converts an `undefined` argument to `xhr.send()` to
string (`'undefined'`) for certain request methods (e.g. DELETE). This
causes the request to appear having a body, when it shouldn't.

Fixes #12141
Fixes #12739

Closes
2015-09-03 14:08:16 +03:00
Peter Bacon Darwin c3a654b7c8 fix($animate): invalid CSS class names should not break subsequent elements
The postDigest handler was not being added if the first element in
to modify the CSS classes contained invalid CSS class names. This meant
that subsequent valid CSS class changes were not being handled since we
were not then adding the handler for those correct cases.

Closes #12674
Closes #12725
2015-09-02 12:45:11 +01:00
Peter Bacon Darwin e7293daf2a refactor($animate): move CSS class update functions out of closure 2015-09-02 12:34:08 +01:00
Mike c71d414a95 docs(doc_widgets.css): remove dead link
This removes a dead link (https://bitbucket.org/alexg/syntaxhighlighter/issues/177/superfluous-vertical-scrollbars-in-chrome)
which linked to an issue on Bitbucket that no longer exists due to
the project moving to GitHub.

Closes #12710
2015-09-01 23:45:46 +02:00
Martin Staffa 06d4e18cda docs(faq): clarify browser support
Closes #12728
2015-09-01 23:37:00 +02:00
Tim Whitbeck 966e01cf26 docs(input): mention ngMin and ngMax for all date input types
Closes #11636
Closes #12244
2015-09-01 23:29:40 +02:00
Lucas Galfaso 67afd9dc63 docs(CHANGELOG): Add breaking change notice for issue 12506
Closes #12705
2015-09-01 22:14:38 +02:00
Martin Staffa 4175860af1 docs(ngModel): improve the $setViewValue documentation
- reorder the paragraphs to highlight more important info
- clarify what can / should be passed to the method,
and what to (not) expect from it
- clarify when the method will trigger a digest

Closes #12713
Closes #11121
Closes #12498
2015-09-01 19:38:11 +02:00
Martin Staffa 6fb90bda9a docs(guide/Directives): clarify what compile means
Closes #11908
2015-09-01 18:06:23 +02:00
Nabil Kadimi 770dd2dcfd docs(misc/Downloading): use the latest stable
Closes #12534
2015-09-01 17:59:21 +02:00
Martin Staffa 0ff7bba2e3 test(select): clean up and improve the option directive tests
- add tests to ensure options with interpolated text are added / updated
- refactor tests for interpolated option values to use the
standard compile helper defined in the spec file.
- rephrase some test descriptions for clarity

Closes #12580
2015-08-31 23:54:13 +02:00
Martin Staffa 82b0929e4e fix(select): update option if interpolated value attribute changes
This is for options added without ngOptions.
Previously, an option with an interpolated value attribute would
not be updated if the binding changed, i.e. the select controller would
not recognize the changed option. Now the value attribute will
be observed if it contains an interpolation.

Closes #12005
Closes #12582
2015-08-31 23:18:19 +02:00
Lucas Galfaso 7d2c6eeef8 fix($parse): assign returns the new value
The `.assign` function returns the new value.
The version with csp enabled already has this behavior.

Closes #12675
Closes #12708
2015-08-31 22:40:23 +02:00
Ron Fenolio 6d8c1950a0 style(guide/Conceptual Overview): clean up conceptual table overview.
Clean up the conceptual overview table to make it cleaner and easier
to look at.

Closes #12620
2015-08-31 21:55:56 +02:00
Rex Salisbury 1a5ea22079 docs(guide/Forms): replace form with user
Referring to the `user` as `form` in the previews is confusing,
since it makes it seem as though the data being displayed is attached
to the `form` object, when the `form` object is separate.

Closes #12687
2015-08-31 21:15:01 +02:00
Joakim Blomskøld 4f9eb2c6e4 docs(form): add info about pending prop and class
Closes #12704
2015-08-31 21:11:03 +02:00
Martin Staffa 43769fb676 fix(ngModel): let aliased validator directives work on any element
`ng(Pattern|Minlength|Maxlength)` directives will now validate the
`ngModel` when on an element that is not an `input` or
a `textarea`. Previously, only their HTML5 counterparts worked on
every element.

This is because the three validators were extracted
into  separate directives (see 26d91b653a
and 1be9bb9d35), whereas the aliased
attribute handling assumes the validators will only exist on
`input|textarea` (see d9b90d7c10 and
25541c1f87).

Since `ngMin` and `ngMax` are also aliased attributes, this means
observers of `min` and `max` will be fired if `ngMin` and `ngMax`
change. This will happen on any element, even if it does not have
an `ngModel`. However, since min/max validators are only ever added
as part of the `input[number|textarea]` types, even if the element
has an `ngModel`, no validators will be added.

Finally the commit also tests that `ng-required` works on any element,
although that validator worked on all elements before this fix.

Fixes #12158
Closes #12658
2015-08-31 20:52:06 +02:00
Ziyu Wang 170cd96646 fix(docs): fix typo "Hasbang"
Closes #12712
2015-08-31 10:27:13 +02:00
Matias Niemelä 1d18e60ef7 docs(CHANGELOG): add changes for 1.4.5 2015-08-28 12:06:35 -07:00
Matias Niemelä ea8016c4c8 fix(ngAnimate): use requestAnimationFrame to space out child animations
This reverts the previous behaviour of using foreced reflows to deal
with preparation classes in favour of a system that uses
requestAnimationFrame (RAF).

Closes #12669
Closes #12594
Closes #12655
Closes #12631
Closes #12612
Closes #12187
2015-08-27 16:56:18 -07:00
Matias Niemelä c3d5e33e18 fix($animate): $animate.enabled(false) should disable animations on $animateCss as well
Closes #12696
Closes #12685
2015-08-27 16:29:33 -07:00
Matias Niemelä 2f6b6fb7a1 fix($animateCss): do not throw errors when a closing timeout is fired on a removed element
Closes #12650
2015-08-27 14:07:59 -07:00
Lucas Galfaso ea2518fcea test($parse): fix csp setup
Run the parse interpreter for csp enabled tests
2015-08-26 23:24:02 +02:00
grsmvg 7e67e525a5 docs(jqLite): document unsupported event object as parameter in off()/unbind()
Closes #12291
2015-08-25 15:34:19 +03:00
Martin Staffa 0e001084ff fix(ngModel): validate pattern against the viewValue
Since the HTML5 pattern validation constraint validates the input value,
we should also validate against the viewValue. While this worked in
core up to Angular 1.2, in 1.3, we changed not only validation,
but the way `input[date]` and `input[number]` are handled - they parse
their input values into `Date` and `Number` respectively, which cannot
be validated by a regex.

Fixes #12344

BREAKING CHANGE:

The `ngPattern` and `pattern` directives will validate the regex
against the `viewValue` of `ngModel`, i.e. the value of the model
before the $parsers are applied. Previously, the modelValue
(the result of the $parsers) was validated.

This fixes issues where `input[date]` and `input[number]` cannot
be validated because the viewValue string is parsed into
`Date` and `Number` respectively (starting with Angular 1.3).
It also brings the directives in line with HTML5 constraint
validation, which validates against the input value.

This change is unlikely to cause applications to fail, because even
in Angular 1.2, the value that was validated by pattern could have
been manipulated by the $parsers, as all validation was done
inside this pipeline.

If you rely on the pattern being validated against the modelValue,
you must create your own validator directive that overwrites
the built-in pattern validator:

```
.directive('patternModelOverwrite', function patternModelOverwriteDirective() {
  return {
    restrict: 'A',
    require: '?ngModel',
    priority: 1,
    compile: function() {
      var regexp, patternExp;

      return {
        pre: function(scope, elm, attr, ctrl) {
          if (!ctrl) return;

          attr.$observe('pattern', function(regex) {
            /**
             * The built-in directive will call our overwritten validator
             * (see below). We just need to update the regex.
             * The preLink fn guaranetees our observer is called first.
             */
            if (isString(regex) && regex.length > 0) {
              regex = new RegExp('^' + regex + '$');
            }

            if (regex && !regex.test) {
              //The built-in validator will throw at this point
              return;
            }

            regexp = regex || undefined;
          });

        },
        post: function(scope, elm, attr, ctrl) {
          if (!ctrl) return;

          regexp, patternExp = attr.ngPattern || attr.pattern;

          //The postLink fn guarantees we overwrite the built-in pattern validator
          ctrl.$validators.pattern = function(value) {
            return ctrl.$isEmpty(value) ||
              isUndefined(regexp) ||
              regexp.test(value);
          };
        }
      };
    }
  };
});
```
2015-08-24 17:01:20 +02:00
Peter Bacon Darwin 85e3203918 chore(npm-shrinkwrap): update to dgeni-packages 0.10.19
See https://github.com/angular/dgeni-packages/commit/313a7c3832
2015-08-23 21:40:11 -04:00
Martin Staffa f95bc42cee docs(ngAnimate): fix typo
Closes #12521
2015-08-21 12:30:02 +02:00
Martin Staffa 9080d2c53c doc(ngMock.$controller): correct controller name in bindToController example
Closes #12550
2015-08-21 11:35:10 +02:00
Matias Niemelä 728f7e2a85 docs(ngAnimate): staggering example should contain duration:0s property
As of 1.4.4 this property needs to always be in the CSS code

Related #12594
Closes #12637
2015-08-20 20:54:31 +02:00
Matias Niemelä 5f704065a7 docs(ngShow): simplify the CSS transition code
The animation example contains unnecessarily complex CSS animation
code in it and the conventions are off.

Related #12631
2015-08-20 20:47:56 +02:00
Matias Niemelä 64631bf2e6 docs(ngAnimate): remove -webkit-transition properties
This property is no longer mandatory by browsers.
2015-08-20 20:47:55 +02:00
Karl Svartholm aa35b243f8 docs(ngAnimate): remove extraneous "then"
To improve readability

Closes #12634
2015-08-20 20:44:42 +02:00
Gabriel Monteagudo 1cc9c9ca9d fix($animateCss): fix parse errors on older Android WebViews
Errors are caused by reserved keywords 'finally' and 'catch'

Closes #12610
2015-08-20 20:39:41 +02:00
Matias Niemelä dc48aadd26 fix(ngAnimate): only buffer rAF requests within the animation runners
Closes #12280
2015-08-19 10:40:37 -07:00
Matias Niemelä ebce2f7253 revert: fix(core): ensure that multiple requests to requestAnimationFrame are buffered 2015-08-19 10:39:47 -07:00
Matias Niemelä d0e50fdcd0 docs(CHANGELOG): add changes for 1.3.18 2015-08-19 01:10:06 -07:00
Matias Niemelä d88167318d fix($animateCss): properly handle cancellation timeouts for follow-up animations
Prior to this fix if `$animateCss` was called multiple on the same
element with new animation data then the preceeding fallback timout
would cause the animation to cancel midway. This fix ensures that
`$animateCss` can be triggered multiple times and only when the final
timeout has passed then all animations will be closed.

Closes #12490
Closes #12359
2015-08-17 21:02:39 -07:00
Sreenivasan K 0a75a3db6e fix($animateCss): ensure failed animations clear the internal cache
Closes #12214
Closes #12518
Closes #12381
2015-08-17 16:06:25 -07:00
Lucas Galfaso b643f0d322 fix(ngResources): support IPv6 URLs
Do not confuse IPv6 URLs domains and resource parameters.

Closes #12512
Closes #12532
2015-08-16 12:36:56 +02:00
Martin Staffa 01dd588a28 docs(select): tweak description and add examples
- Change some wordings to make them more understandable
- Reorder the paragraphs so they can be read more easily as a coherent text
- Add examples for static single / multiple selects, and non-selected option
- Add example for select with repeated options
- Remove form-related info from ngOptions select (doesn't apply)
2015-08-15 18:32:50 +02:00
Meli 3d6dc3fe31 docs(select): explain how to set default value
Setting the default value in a select is a real trap for beginners, questions about how to do this on StackExchange have been view more than 40000 times in the last year.  This changes updates the documentation to make it clearer.

Closes #12546
2015-08-15 18:32:49 +02:00
Matias Niemelä 0c81e9fd25 fix($animateCss): the transitions options delay value should be applied before class application
When `options.delay` is passed into `$animateCss`the delay style would be
applied after the add/remove CSS classes are evaluated (for transitions).
At this point it is too late for the delay to be picked up (this
functionality however does work with keyfarme animations).

This patch ensures that the provided `options.delay` value is
applied before the CSS classes are applied to the element.

Closes #12584
2015-08-14 13:58:38 -07:00
Elvio Cavalcante 5df80e1854 docs(tutorial): fix test issue
Unnecessary split. The url returns a string without the hash,
resulting in an undefined value and making the test fails.

Matches the phonecat app more closely, too.

Closes #12590
2015-08-14 15:12:39 -04:00
David Czech ba9fb82f18 docs($animate): remove redundant 'animate' in link
Closes #12568
2015-08-14 12:08:32 +02:00
Martin Staffa b497f3e47f docs(CHANGELOG): add changes for 1.4.4 2015-08-13 11:15:10 -07:00
Matias Niemelä 39b634e50a feat(ngAnimate): expose a core version of $animateCss
A core version of `$animateCss` can now be injected when
ngAnimate is not present. This core version doesn't trigger any
animations in any way. All that it does is apply the provided from
and/or to styles as well as the addClass and removeClass values.

The motivation for this feature is to allow for directives to activate
animations automatically when ngAnimate is included without the need to
use `$animate`.

Closes #12509
Closes #12570
2015-08-13 10:49:59 -07:00
Matias Niemelä cf28c1a276 chore: rename angular.bind to angular.bind.js
Some internal tests were failing since `.bind` is a JS file which
is expected to have a `.js` file name suffix.
2015-08-12 13:11:48 -07:00
sreeramu 92e41ac904 fix($animate): leave animation callback should not overridden by follow-up animation
Closes #12271
Closes #12249
Closes #12161
2015-08-12 11:59:54 -07:00
Matias Niemelä d33cedda16 fix(ngAnimate): always apply a preparation reflow for CSS-based animations
It's unpredictable sometimes to ensure that a browser triggers a reflow
for an animation. Prior to this patch, reflows would be applied
carefully in between parent/child DOM structure, but that doesn't seem
to be enough for animations that contain complex CSS styling rules.

Closes #12553
Closes #12554
Closes #12267
Closes #12554
2015-08-12 10:20:18 +02:00
Lucas Galfaso 6838c97945 perf($q): small $q performance optimization
Only generate a new promise when `then` receives some non-undefined parameter

Closes #12535
2015-08-11 23:37:46 +02:00
Ilya Mochalov f827a8e050 docs($interval): cancel() ignores falsy parameter
Closes #12552
2015-08-11 16:57:01 -04:00
Luke Waite a844138060 docs($sce): correct typo
Fix markdown quotation of a `;` so that it is properly rendered in the docs.
Makes it more consistent with the other codeblocked characters in the
list.

Closes #12549
2015-08-11 10:50:21 -04:00
Caitlin Potter 8ae9e94ecb style(loader): make jscs happy 2015-08-11 10:43:49 -04:00
Frank 1bd451d082 docs(angular.module): simplify wording+improve grammar
A suggestion on the wording of retrieving a moudle

Closes #12543
2015-08-11 10:42:44 -04:00
arm1n c11a7d676f fix(ngOptions): allow empty option selection with multiple attribute
Fixes #12511
Closes #12541
2015-08-10 22:13:48 +02:00
Lucas Galfaso 0827e88e21 style(jscs): fix whitespace 2015-08-09 13:03:48 +02:00
Lucas Galfaso 1363cbd6b4 style(jshint): fix jshint warning 2015-08-09 12:40:28 +02:00
Lucas Galfaso 44a96a4c14 fix($injector): Allows ES6 function syntax
Closes #12424
Closes #12425
2015-08-09 12:20:31 +02:00
Lucas Galfaso 1cf10ab810 chore(saucelabs): Upgrade Chrome and Firefox to the latest versions
Closes #12430
2015-08-09 12:19:38 +02:00
Lucas Galfaso ed3a33a063 feat(orderBy): Stable sort the input
Stable sort the input array

Closes #12408
Fixes #12405
2015-08-08 22:33:53 +02:00
Martin Staffa a268c29fb0 fix(ngModel): correct minErr usage for correct doc creation
Remove the `new` from the minErr assignment, so the closure compiler
can detect the errors correctly. Also removes the leading $ from the
variable name to be consistent with the Angular.js file.

Closes #12386
Closes #12416
2015-08-08 17:57:23 +02:00
Martin Staffa adb286389c docs(form): explain why the empty-string setter is created 2015-08-07 19:28:11 +02:00
Lucas Galfaso 94533e5706 refactor(form): remove the use of the private setter function
Remove the private `setter` function from $parse
Replace the `setter` from the `form` directive with $parse

Closes #12483
2015-08-07 14:47:09 +02:00
Rouven Weßling 99d2c46a16 refactor(): remove more bits and pieces related to Internet Explorer 8
Closes #12407
2015-08-07 14:29:55 +02:00
Yun Liu 929ec6ba5a style($http): fix typo in useLegacyPromise var
Closes #12515
2015-08-07 14:13:25 +02:00
luanshixia 39ff3332a3 fix(ngSanitize): escape the wide char quote marks in a regex in linky.js
Escape the wide char quote marks in a regex in linky.js

Closes #11609
2015-08-06 23:09:22 +02:00
Ryan Hendry 4c92a3ccc7 style(ngAnimate): add missing semi-colon
Adding missing semi-colon which is breaking minification

Closes #12513
2015-08-06 22:30:18 +02:00
Steve Mao dc0b856e9c docs(CONTRIBUTING): correct spelling and grammar
Summary:
  - Use properly capitalized GitHub brand name
  - Correctly negate two clauses using "nor" (caitp feels this may confuse
non-english speakers and need to be revised, but hopefully not)
  - Correctly end sentence with period

Closes #12497
2015-08-04 09:24:03 -04:00
Martin Staffa bb281f85e7 docs(.Scope): correct link to scope guide 2015-08-03 22:09:45 +02:00
Martin Staffa 496e08a605 docs($rootScope.Scope): remove obsolete line, and link to guide
The removed line pointed to a removed example. Re-adding the example
would have been of questionable value, as it introduced several
concepts without context. It's therefore better to link to the guide,
which provides a better introduction.

Closes #12167
2015-08-03 21:55:40 +02:00
Eric Adams 548a1348d9 docs(guide/Dependency Injection): fix angular.injector arguments list
The original file included a code sample using `angular.injector(['myModule', 'ng'])`,
which appears to be incorrect when trying to retrieve anything attached to `myModule`.
Reversing the args fixes this.

Closes #12292
2015-08-03 21:07:48 +02:00
Derk Vedelaar 9845570be8 docs(tutorial/7 - Routing): update angular version
The versions are updated in the angular-phonecat repo, but not in
the documentation. This change syncs the version numbers.

Closes #12396
2015-08-03 21:02:53 +02:00
Satish Maurya 35d35e6a7e docs(guide/Forms): display scope form / master data in examples
It will be good to have the binding results in the CSS classes /
binding to form / control state example, similar to the Simple Form
example.

Closes #12326
2015-08-03 20:56:25 +02:00
Martin Probst 5abf593e6b fix(injector): check that modulesToLoad isArray.
When users accidentally just pass a single string, e.g.
`angular.injector('myModule')`, this change give them a better error message.

Currently Angular just reports that the module with the name 'm' is missing,
as it's iterating through all characters in the string, instead of all strings
in the module.

Closes #12285
2015-08-03 10:18:19 +02:00
ArchmageInc 9efe60f294 docs($q): add $q.when and $q.resolve callback arguments
Closes #12372
2015-08-03 10:13:37 +02:00
Jacob Carter 8553b56e97 docs(ngOptions): close select element
Close select element in html example to stop errors occurring for copy/paste users

Closes #12384
2015-08-03 10:12:12 +02:00
Rouven Weßling a8f7e9cfde feat($httpProvider): add 'useLegacyPromiseExtensions' configuration
The legacy methods, `success` and `error`, have been deprecated.

Set this to `false` to cause `$http` to throw an error if these methods are
used in the application.

For now it defaults to `true`. In a future release we will remove these
methods altogether.

DEPRECATION NOTICE:

The legacy methods 'success' and 'error' on promises returned by $http
are now deprecated.

Closes #12112
Closes #10508
2015-08-01 20:34:30 +01:00
Lucas Galfaso 7b8a16b238 refactor($locale): use en-us as generic built-in locale
Previously there was a custom built en-us locale that was included with
angular.js. This made likely that it would get out of sync with the real
en-us locale that is generated from the closure library.

This change removes that custom one and uses the generated one instead.
This also has the benefit of preventing the unwanted caught error on trying
to load `ngLocale` during angular bootstrap.

Closes #12462
Closes #12444
Closes #12134
Closes #8174
2015-07-31 22:07:27 +02:00
Steven d2695b04a7 docs(guide): Facebook was mispelled as Faceb0ok
Fixes typo :>

Closes #12470
2015-07-30 19:45:39 -04:00
Peter Bacon Darwin 6f3b8622ad fix($compile): don't trigger $observer if initial value is undefined
Closes #12383
Closes #12464
2015-07-30 23:23:08 +01:00
Strikeskids 97ac7634df docs($rootScope.Scope): improve clarity describing $watch with no listener
The previous explanation in parentheses created a bit of confusion because the documentation stated to leave off the `listener`, but then said "be prepared for multiple calls to your listener". The new explanation clarifies that it is indeed the `watchExpression` that will be executed multiple times.

Closes #12429
2015-07-30 15:22:40 -04:00
Laisky.Cai ef3846a7a6 docs(guide/expression): replace tt by code
Replaces <tt> elements with <code> in expressions guide. Looks identical
in Chromium

Closes #12437
2015-07-30 12:50:34 -04:00
patyatka 93985804a9 docs($compile): fix typo
Closes #12443
2015-07-30 12:32:42 -04:00
Caitlin Potter 533d9b7670 fix($compile): ignore optional =-bound properties with empty value
Previously, optional empty '='-bound expressions were ignored ---
erroneously they stopped being ignored, and no tests were caused to
fail for this reason. This change restores the original ignoring
behaviour while still preventing other errors fixed by 8a1eb16

Closes #12144
Closes #12259
Closes #12290
2015-07-29 16:58:18 +01:00
Matias Niemelä 0d6fc2dce5 fix(ngAnimate): ensure that only string-based addClass/removeClass values are applied
Related #11268
Closes #12458
Closes #12459
2015-07-29 14:07:10 +01:00
Peter Bacon Darwin addb1ae37d test(guide/expression): we must tell protractor to wait for the alert appear
This is a better solution than f91eb0e9ec
2015-07-28 14:41:01 +01:00
Jochen Niebuhr f13852c179 fix(Angular): allow unescaped = signs in values in parseKeyValue
In some cases people will not follow all URL standards and may have
unescaped = characters in their GET parameter values. Currently $location
will not parse them correctly dropping everything after the unescaped =.

This change includes all characters after the first `=` up to the next `&`.

Closes #12351
2015-07-27 22:30:28 +01:00
Peter Bacon Darwin 5298672411 fix(ng/$locale): by default put negative sign before currency symbol
It seems that the case where the negative sign goes between the currency
symbol and the numeric value is actually the special case and that locales
that require this have it built in. So we should default to having the
negative sign before the symbol.

See http://cldr.unicode.org/translation/number-patterns and
http://unicode.org/cldr/trac/ticket/5674

Closes #10158
2015-07-27 22:21:28 +01:00
Peter Bacon Darwin 058d462fa7 revert: refactor($locale): use en-us as generic built-in locale
This reverts commit 70ce425e6a.

There are internal projects in Google that generate their own version
of angular.js and so this commit caused those projects to break.

We are going to look into a more satisfactory way of getting this change
in.
2015-07-27 22:00:14 +01:00
Peter Bacon Darwin f91eb0e9ec test(expression): add sleep(100) to protractor spec that uses alert
In Chrome, if two alert boxes pop up, without enough time between them,
Protractor (or possibly ChromeDriver) sometimes fails to recognize the
second alert.
2015-07-27 21:53:14 +01:00
Matias Niemelä 861636c625 fix($animate): make sure to run a post-digest reflow for parentless animations
Closes #12400
Closes #12401
2015-07-27 16:21:50 -04:00
Lucas Galfaso e7423168fb fix(input): Firefox validation trigger
Do not trigger Firefox validation on form initialization.
- Do not set a value to an <input> field if the field already has the same value

Closes #12102
2015-07-26 19:40:05 +02:00
Martin Staffa 4bcf6c17c8 docs(ngOptions): remove obsolete trkslct error page
Closes #12417
2015-07-26 19:35:56 +02:00
Blake Johnston d506b8a9df docs($compile): pluralize DOM element
Previous description includes singular `collection of DOM element`. Current change revises `element` to be plural.

Closes #12431
2015-07-26 19:34:14 +02:00
Lucas Galfaso e0cf496f3c fix($rootScope): don't clear phase if $apply is re-entered
We cannot re-enter a `$apply` block while already in a `$apply` or `$digest`
phase.

Before this change such an invalid call to `$apply` was incorrectly clearing
the phase, which meant that a second invalid `$apply` call was being allowed.

Closes #12174
2015-07-25 20:44:08 +01:00
Sreenivasan K a5221f320a fix(merge): regExp should not be treated as a objects when merging.
angular.merge({ key: /regexp/ }) now works the way you'd expect it to.

Horray!

Closes #12419
Closes #12409
2015-07-24 09:00:31 -04:00
Lucas Galfaso 18a2e4fbfc fix(httpParamSerializerJQLike): Follow jQuery for index of arrays of objects
Follow jQuery when serializing arrays that contain objects

Close #12393
Close #12398
2015-07-23 23:05:20 +02:00
Matias Niemelä 32d3cbb3aa fix(ngAnimate): ensure that parent class-based animations are never closed by their children
This fix ensures that a structural child animation will never close a
parent class based early so that the CSS classes for the child are ready
for it to perform its CSS animation. The reasoning for the past for this
was because their is a one frame delay before the classes were applied.
If a parent and a child animation happen at the same time then the
animations may not be picked up for the element since the CSS classes
may not have been applied yet.

This fix ensures that parent CSS classes are applied in a synchronous
manner without the need to run a one RAF wait. The solution to this was
to apply the preparation classes during the pre-digest phase and then
apply the CSS classes right after with a forced reflow paint.

BREAKING CHANGE: CSS classes added/removed by ngAnimate are now applied
synchronously once the first digest has passed.

The previous behavior involved ngAnimate having to wait for one
requestAnimationFrame before CSS classes were added/removed. The CSS classes
are now applied directly after the first digest that is triggered after
`$animate.addClass`, `$animate.removeClass` or `$animate.setClass` is
called. If any of your code relies on waiting for one frame before
checking for CSS classes on the element then please change this
behavior. If a parent class-based animation, however, is run through a
JavaScript animation which triggers an animation for `beforeAddClass`
and/or `beforeRemoveClass` then the CSS classes will not be applied
in time for the children (and the parent class-based animation will not
be cancelled by any child animations).

Closes #11975
Closes #12276
2015-07-20 14:21:59 -07:00
Matias Niemelä acc53ce6ad revert: fix(ngAnimate): ensure nested class-based animations are spaced out with a RAF 2015-07-20 14:21:53 -07:00
Matias Niemelä 0f6d37ead5 chore(ngAnimate): skip adding the preparation classes when options.$$skipPreparationClasses is present 2015-07-20 14:21:43 -07:00
Matias Niemelä 11695ca6e2 fix($animateCss): make sure that skipBlocking avoids the pre-emptive transition-delay styling 2015-07-20 14:21:35 -07:00
ColinFletch cce084ee89 docs(guide/Controllers): Syntax adjustments.
Closes #12379
2015-07-19 17:39:53 +02:00
Jesse Mandel d935c245c0 docs(guide/module): fixed link to blog post
Closes #12165
Closes #12250
2015-07-19 16:41:55 +02:00
Matthew Hill b871b98a57 docs(filter.js): documents second parameter to .register
Closes #12378
2015-07-19 14:49:30 +02:00
Lucas Galfaso 1cb6bd4944 chore(angularFiles.js): Remove deleted file 2015-07-18 12:04:03 +02:00
bluepnume 3abb3fefe6 fix($q): Use extend to avoid overwriting prototype
Use `extend` on `Promise.prototype` and `Deferred.prototype`, to avoid having to
manually set `constructor` on the overwritten prototypes.

Closes #10697
2015-07-18 11:42:42 +02:00
Lucas Galfaso 8ed682941a chore(asyncCallback): Remove dead code
Closes #12371
2015-07-18 11:13:23 +02:00
Olen Davis 44ce9c8288 fix(ngAnimate): allow animations on body and root elements
Closes #11956
Closes #12245
2015-07-17 11:30:06 -07:00
Matias Niemelä 2ff1b09ab7 chore: replace jqLite($document[0].body) with $$body 2015-07-17 11:29:54 -07:00
Matias Niemelä 976cd036da chore(core): introduce $$body service
This patch makes it easier to gain access to document.body
via the injector.
2015-07-17 11:29:48 -07:00
sreeramu 21d6db382d fix($animate): ensure that class-based animations are properly applied when cancelled
Instead of merging existing animation option to new animation options we can
merge in reverse and utilize old animation runner.

Closes #12266
Closes #12007
2015-07-17 11:24:31 -07:00
Matias Niemelä fc7d2d2737 chore($$forceReflow): create service for issuing reflows in animations 2015-07-17 09:42:47 -07:00
Matias Niemelä c77b607e61 chore(mocks): remove $$animateReflow from triggerReflow()
This service was removed when 1.4.0 was released, but the mock
code still stubs it.
2015-07-17 09:42:47 -07:00
jbnizet ec22d2276e docs(CHANGELOG): fix release date of 1.4.3 version
Closes #12356
2015-07-17 10:44:03 +03:00
Matias Niemelä 344dffbc54 docs($animateCss): add missing options flag to animation example
Closes #12202
2015-07-16 14:33:57 -07:00
startswithaj 7db5f361b0 fix(ngAnimate): $timeout without invokeApply
This change calls $timeout with the invokeApply
parameter set to false which stops ngAnimate
from invoking its changes inside an $apply block

Closes #12281
Closes #12282
2015-07-16 14:29:40 -07:00
shoja d494a69ef6 docs($sce): correct typos
Line 548: Remove duplicate 'not' and clarify wording
Line 556: Remove period within parenthetical statement
Line 560: Clarify wording
Line 570: Capitalize 'E.g.' at the start of a sentence

Closes #12252
2015-07-16 22:28:32 +02:00
Ashish Dasnurkar 91212d9440 docs($cookiesProvider): fixed a typo
"This is *import* so that cookies will be visible" should be "This is *important* so that cookies will be visible"

Closes #12264
2015-07-16 22:27:02 +02:00
Nabil Kadimi b661887072 docs(guide/Dependency Injection): minor punctuation fixes
Closes #12268
2015-07-16 22:25:18 +02:00
Mohamed Samy 60b7b003fd docs(tutorial/7 - Routing): fix matching in test
It is corrected in github, but not in the angular.org site.
Copied it from https://github.com/angular/angular-phonecat/compare/step-6...step-7

Closes #12314
2015-07-16 22:20:01 +02:00
Andrew Passanisi 6ba5404406 docs(error/ctrlfmt): fixed a small typo in ctrl error message
Closes #12320
2015-07-16 22:18:08 +02:00
Peter Bacon Darwin 2b68136a20 chore(ngLocale): regenerate locales
This regeneration takes into account the changes due to:

* update to closure library 27.0.1
* fix to default position of negative sign in currency formats

Closes #12307
Closes #12362
2015-07-16 19:20:11 +01:00
Peter Bacon Darwin dc49b4d952 chore(i18n): update closure library 2015-07-16 19:20:11 +01:00
Peter Bacon Darwin 96f2e3bef5 fix(i18n): by default put negative sign before currency symbol
It seems that the case where the negative sign goes between the currency
symbol and the numeric value is actually the special case and that locales
that require this have it built in. So we should default to having the
negative sign before the symbol.

See http://cldr.unicode.org/translation/number-patterns and
http://unicode.org/cldr/trac/ticket/5674

Closes #10158
2015-07-16 19:20:11 +01:00
Peter Bacon Darwin 70ce425e6a refactor($locale): use en-us as generic built-in locale
Previously there was a custom built en-us locale that was included with
angular.js. This made likely that it would get out of sync with the real
en-us locale that is generated from the closure library.

This change removes that custom one and uses the generated one instead.
This also has the benefit of preventing the unwanted caught error on trying
to load `ngLocale` during angular bootstrap.

Closes #12134
Closes #8174
2015-07-16 19:19:39 +01:00
Peter Bacon Darwin 9e492c358c fix($location): don't crash if navigating outside the app base
Previously, if you navigate outside of the Angular application, say be clicking
the back button, the $location service would try to handle the url change
and error due to the URL not being valid for the application.

This fixes that issue by ensuring that a reload happens when you navigate
to a URL that is not within the application.

Closes #11667
2015-07-16 18:46:13 +01:00
Peter Bacon Darwin 92c7ce5bec refactor($location): compute appBaseNoFile only once 2015-07-16 18:46:13 +01:00
Peter Bacon Darwin 618356e481 fix(ngCsp): allow CSP to be configurable
There are two different features in Angular that can break CSP rules:
use of `eval` to execute a string as JavaScript and dynamic injection of
CSS style rules into the DOM.

This change allows us to configure which of these features should be turned
off to allow a more fine grained set of CSP rules to be supported.

Closes #11933
Closes #8459
Closes #12346
2015-07-16 12:26:24 +01:00
Peter Bacon Darwin 1f4aa47193 docs(migration): clarify non-numeric matching
Closes #12350
2015-07-15 13:52:56 +01:00
Peter Bacon Darwin 528cedaa0c docs(CHANGELOG): Remove redundant items from 1.4.3 changes
The update to the change log for the 1.4.3 release accidentally included
a number of changes from previous releases.
2015-07-15 12:34:46 +01:00
Matias Niemelä 1622182737 docs(CHANGELOG): add changes for 1.4.3 2015-07-14 18:26:10 -07:00
Matias Niemelä 36efe6c1a2 test($animateCss): avoid unnecessary checking for transition-timing-function
There is no need to check for this in the test and it adds complexity
for linux-based browsers.
2015-07-14 14:07:50 -07:00
Matias Niemelä 5081982e30 test($animateCss): ensure that transitionStyle by itself doesn't trigger anything
Using `transitionStyle` without any other properties does not trigger an
animation so we could have a test to assert that it doesn't do that.
2015-07-14 13:45:11 -07:00
Matias Niemelä 97d79eec80 fix($animateCss): ensure animations execute if only a keyframeStyle is provided
`$animateCss` is a fan of transition animations, but it turns out that
if only a keyframeStyle is provided into the animation upon constrution
then it will quit because it assumes that nothing will be animated
(since no classes or styles are being applied). This patch ensures that
a keyframe style can solely be applied to an animation triggered with
`$animateCss`.

```js
// this will now work as expected
$animateCss(element, { keyframeStyle: '1s rotate' }).start();
```

Closes #12124
Closes #12340
2015-07-14 13:45:03 -07:00
Matias Niemelä e4aeae0c73 fix(ngAnimate): ensure that orphaned elements do not throw errors when animated
This fix ensures that both `$animateCss` and `$animate` swallow the error
when an animation takes place in the sitation that the element is removed
from the parent element sometime before or during the preparation stages of the
animation.

Closes #11975
Closes #12338
2015-07-14 21:06:55 +01:00
Dominic Watson 7202bfafcd docs(ngAnimate) - Correct keyframe to keyframeStyle 2015-07-14 10:42:05 -07:00
Steve Mao 4cef752985 docs(CONTRIBUTING): state what is mandatory or optional
Closes #12032
2015-07-13 13:24:52 +01:00
Steve Mao d38f6ff401 docs(CONTRIBUTING): how to write a breaking change
Closes #12032
2015-07-13 13:24:44 +01:00
Steve Mao 8f6dac9536 docs(CONTRIBUTING): revert is a modifier
EG: https://github.com/angular/angular.js/commit/462f444b06ae5cad3ccb761b1dba7131df01a655

Closes #12032
2015-07-13 13:24:34 +01:00
Peter Bacon Darwin de5b8dc781 docs(guide/controller): add a line about controller as 2015-07-13 13:22:01 +01:00
Peter Bacon Darwin 41834e6f4a docs(guide/controller): add a line about controller as 2015-07-13 13:18:29 +01:00
niteshthakur dbb42b5c85 docs(guide/controller): clarify that controllers are defined **by** a constructor function
A controller is a instantiated object created **from** a constructor function.
It was not accurate to describe a Controller **as** a constructor function.

Closes #11888
2015-07-13 13:18:29 +01:00
Peter Bacon Darwin f012374f12 docs($routeChangeSuccess): note that resolve values are available on current route
Closes #11413
2015-07-13 13:10:47 +01:00
Rouven Weßling 14e0b9c352 refactor(ngCsp): use document.head
The `head` property is available from IE9 onwards.

Closes #11905
2015-07-13 09:37:03 +01:00
Jerry Orta 9ea52d818b fix(loader): define isFunction
Closes: #12299
Closes: #12287
2015-07-10 22:54:58 +02:00
Martin Staffa d518a64d93 docs(CHANGELOG): add changes for 1.4.2 2015-07-06 22:19:53 +02:00
Wesley Cho fe0af2c073 chore(animate): remove dead code
- Remove unused `$$asyncCallback`

Fixes #12251
Closes #12254
2015-07-02 22:57:00 +02:00
1224 changed files with 177490 additions and 26942 deletions
+27
View File
@@ -0,0 +1,27 @@
***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.**
**Do you want to request a *feature* or report a *bug*?**
**What is the current behavior?**
**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).**
**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)**
+23
View File
@@ -0,0 +1,23 @@
**What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)**
**What is the current behavior? (You can also link to an open issue here)**
**What is the new behavior (if this is a feature change)?**
**Does this PR introduce a breaking change?**
**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)
**Other information**:
+8 -3
View File
@@ -1,19 +1,24 @@
{
"bitwise": true,
"esversion": 6,
"immed": true,
"newcap": true,
"noarg": true,
"noempty": true,
"nonew": true,
"trailing": true,
"maxlen": 200,
"boss": true,
"eqnull": true,
"expr": true,
"globalstrict": true,
"laxbreak": true,
"loopfunc": true,
"strict": "global",
"sub": true,
"undef": true,
"indent": 2
"indent": 2,
"globals": {
"ArrayBuffer": false,
"Uint8Array": false
}
}
+20 -23
View File
@@ -1,7 +1,7 @@
language: node_js
sudo: false
node_js:
- '0.10'
- '4.4'
cache:
directories:
@@ -15,28 +15,27 @@ branches:
env:
matrix:
- JOB=ci-checks
- JOB=unit BROWSER_PROVIDER=saucelabs
- JOB=docs-e2e BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jquery-2.1 BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs
- JOB=unit BROWSER_PROVIDER=browserstack
- JOB=docs-e2e BROWSER_PROVIDER=browserstack
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=browserstack
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=browserstack
global:
- CXX=g++-4.8 # node 4 likes the G++ v4.8 compiler
- SAUCE_USERNAME=angular-ci
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
- BROWSER_STACK_USERNAME=VojtaJina
- BROWSER_STACK_ACCESS_KEY=QCQJ1ZpWXpBkSwEdD8ev
- LOGS_DIR=/tmp/angular-build/logs
- BROWSER_PROVIDER_READY_FILE=/tmp/browsersprovider-tunnel-ready
matrix:
allow_failures:
- env: "JOB=unit BROWSER_PROVIDER=browserstack"
- env: "JOB=docs-e2e BROWSER_PROVIDER=browserstack"
- env: "JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=browserstack"
- env: "JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=browserstack"
# 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
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
install:
# Check the size of caches
@@ -46,27 +45,25 @@ install:
- npm config set spin false
# Log HTTP requests
- npm config set loglevel http
- npm install -g npm@2.5
# Instal npm dependecies and ensure that npm cache is not stale
- scripts/npm/install-dependencies.sh
#- npm install -g npm@2.5
# Install npm dependencies and ensure that npm cache is not stale
- npm install
before_script:
- mkdir -p $LOGS_DIR
- ./scripts/travis/start_browser_provider.sh
- npm install -g grunt-cli
- grunt package
- ./scripts/travis/wait_for_browser_provider.sh
- ./scripts/travis/before_build.sh
script:
- ./scripts/travis/build.sh
after_script:
- ./scripts/travis/tear_down_browser_provider.sh
- ./scripts/travis/print_logs.sh
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/d2120f3f2bb39a4531b2
on_success: change # options: [always|never|change] default: always
- http://104.197.9.155:8484/hubot/travis/activity #hubot-server
on_success: always # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false
on_start: always # default: false
+2356 -62
View File
File diff suppressed because it is too large Load Diff
+22 -7
View File
@@ -19,7 +19,7 @@ Help us keep Angular open and inclusive. Please read and follow our [Code of Con
## <a name="question"></a> Got a Question or Problem?
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].
discussion list or [StackOverflow][stackoverflow]. We are also available on [IRC][irc] and [Gitter][gitter].
## <a name="issue"></a> Found an Issue?
If you find a bug in the source code or a mistake in the documentation, you can help us by
@@ -71,7 +71,7 @@ chances of your issue being dealt with quickly:
* **Angular Version(s)** - is it a regression?
* **Browsers and Operating System** - is this a problem with all browsers or only IE8?
* **Reproduce the Error** - provide a live example (using [Plunker][plunker] or
[JSFiddle][jsfiddle]) or a unambiguous set of steps.
[JSFiddle][jsfiddle]) or an unambiguous set of steps.
* **Related Issues** - has a similar issue been reported before?
* **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)
@@ -123,13 +123,19 @@ Before you submit your pull request consider the following guidelines:
* If we suggest changes then:
* Make the required updates.
* Re-run the Angular test suite to ensure tests are still passing.
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
* 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 the PR gets too outdated we may ask you to rebase and force push to update the PR:
```shell
git rebase master -i
git push origin my-fix-branch -f
```
*WARNING. Squashing or reverting commits and forced push thereafter may remove GitHub comments
on code that were previously made by you and others in your commits.*
That's it! Thank you for your contribution!
#### After your pull request is merged
@@ -187,6 +193,8 @@ We have very precise rules over how our git commit messages can be formatted. T
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 `npm 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**:
@@ -199,8 +207,13 @@ format that includes a **type**, a **scope** and a **subject**:
<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.
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:
@@ -210,7 +223,7 @@ Must be one of the following:
* **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 or adds a feature
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
@@ -228,13 +241,14 @@ The subject contains succinct description of the change:
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes"
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**.
**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].
@@ -262,10 +276,11 @@ You can find out more detailed information about contributing in the
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[dev-doc]: https://docs.angularjs.org/guide
[github]: https://github.com/angular/angular.js
[gitter]: https://gitter.im/angular/angular.js
[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]: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
[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
+46 -17
View File
@@ -17,6 +17,10 @@ module.exports = function(grunt) {
NG_VERSION.cdn = versionInfo.cdnVersion;
var dist = 'angular-'+ NG_VERSION.full;
if (versionInfo.cdnVersion == null) {
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?');
}
//config
grunt.initConfig({
NG_VERSION: NG_VERSION,
@@ -79,6 +83,8 @@ module.exports = function(grunt) {
tests: {
jqlite: 'karma-jqlite.conf.js',
jquery: 'karma-jquery.conf.js',
'jquery-2.2': 'karma-jquery-2.2.conf.js',
'jquery-2.1': 'karma-jquery-2.1.conf.js',
docs: 'karma-docs.conf.js',
modules: 'karma-modules.conf.js'
},
@@ -87,6 +93,8 @@ module.exports = function(grunt) {
autotest: {
jqlite: 'karma-jqlite.conf.js',
jquery: 'karma-jquery.conf.js',
'jquery-2.2': 'karma-jquery-2.2.conf.js',
'jquery-2.1': 'karma-jquery-2.1.conf.js',
modules: 'karma-modules.conf.js',
docs: 'karma-docs.conf.js'
},
@@ -115,7 +123,7 @@ module.exports = function(grunt) {
files: { src: 'test/**/*.js' },
},
ng: {
files: { src: files['angularSrc'] },
files: { src: files['angularSrc'].concat('!src/angular.bind.js') },
},
ngAnimate: {
files: { src: 'src/ngAnimate/**/*.js' },
@@ -135,6 +143,9 @@ module.exports = function(grunt) {
ngMock: {
files: { src: 'src/ngMock/**/*.js' },
},
ngParseExt: {
files: { src: 'src/ngParseExt/**/*.js' },
},
ngResource: {
files: { src: 'src/ngResource/**/*.js' },
},
@@ -156,9 +167,13 @@ module.exports = function(grunt) {
},
jscs: {
src: ['src/**/*.js', 'test/**/*.js'],
src: [
'src/**/*.js',
'test/**/*.js',
'!src/angular.bind.js' // we ignore this file since contains an early return statement
],
options: {
config: ".jscsrc"
config: '.jscsrc'
}
},
@@ -227,9 +242,13 @@ module.exports = function(grunt) {
dest: 'build/angular-aria.js',
src: util.wrap(files['angularModules']['ngAria'], 'module')
},
parseext: {
dest: 'build/angular-parse-ext.js',
src: util.wrap(files['angularModules']['ngParseExt'], 'module')
},
"promises-aplus-adapter": {
dest:'tmp/promises-aplus-adapter++.js',
src:['src/ng/q.js','lib/promises-aplus/promises-aplus-test-adapter.js']
src:['src/ng/q.js', 'lib/promises-aplus/promises-aplus-test-adapter.js']
}
},
@@ -245,11 +264,12 @@ module.exports = function(grunt) {
resource: 'build/angular-resource.js',
route: 'build/angular-route.js',
sanitize: 'build/angular-sanitize.js',
aria: 'build/angular-aria.js'
aria: 'build/angular-aria.js',
parseext: 'build/angular-parse-ext.js'
},
"ddescribe-iit": {
'ddescribe-iit': {
files: [
'src/**/*.js',
'test/**/*.js',
@@ -260,17 +280,22 @@ module.exports = function(grunt) {
],
options: {
disallowed: [
'fit',
'iit',
'xit',
'fthey',
'tthey',
'xthey',
'fdescribe',
'ddescribe',
'xdescribe'
'xdescribe',
'it.only',
'describe.only'
]
}
},
"merge-conflict": {
'merge-conflict': {
files: [
'src/**/*',
'test/**/*',
@@ -300,11 +325,11 @@ module.exports = function(grunt) {
},
shell: {
"npm-install": {
command: path.normalize('scripts/npm/install-dependencies.sh')
'npm-install': {
command: 'node scripts/npm/check-node-modules.js'
},
"promises-aplus-tests": {
'promises-aplus-tests': {
options: {
stdout: false,
stderr: true,
@@ -335,22 +360,26 @@ module.exports = function(grunt) {
grunt.task.run('shell:npm-install');
}
//alias tasks
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'jscs', 'package','test:unit','test:promises-aplus', 'tests:docs', 'test:protractor']);
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'jscs', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']);
grunt.registerTask('test:jqlite', 'Run the unit tests with Karma' , ['tests:jqlite']);
grunt.registerTask('test:jquery', 'Run the jQuery unit tests with Karma', ['tests:jquery']);
grunt.registerTask('test:jquery', 'Run the jQuery (latest) unit tests with Karma', ['tests:jquery']);
grunt.registerTask('test:jquery-2.2', 'Run the jQuery 2.2 unit tests with Karma', ['tests:jquery-2.2']);
grunt.registerTask('test:jquery-2.1', 'Run the jQuery 2.1 unit tests with Karma', ['tests:jquery-2.1']);
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', ['build', 'tests:modules']);
grunt.registerTask('test:docs', 'Run the doc-page tests with Karma', ['package', 'tests:docs']);
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['test:jqlite', 'test:jquery', 'test:modules']);
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['test:jqlite', 'test:jquery', 'test:jquery-2.2', 'test:jquery-2.1', 'test:modules']);
grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'protractor:normal']);
grunt.registerTask('test:travis-protractor', 'Run the end to end tests with Protractor for Travis CI builds', ['connect:testserver', 'protractor:travis']);
grunt.registerTask('test:ci-protractor', 'Run the end to end tests with Protractor for Jenkins CI builds', ['webdriver', 'connect:testserver', 'protractor:jenkins']);
grunt.registerTask('test:e2e', 'Alias for test:protractor', ['test:protractor']);
grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter','shell:promises-aplus-tests']);
grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter', 'shell:promises-aplus-tests']);
grunt.registerTask('minify', ['bower','clean', 'build', 'minall']);
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
grunt.registerTask('webserver', ['connect:devserver']);
grunt.registerTask('package', ['bower','clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'jshint', 'jscs']);
grunt.registerTask('default', ['package']);
};
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
Copyright (c) 2010-2016 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
+41 -12
View File
@@ -8,25 +8,27 @@ synchronizes data from your UI (view) with your JavaScript objects (model) throu
binding. To help you structure your application better and make it easy to test, AngularJS teaches
the browser how to do dependency injection and inversion of control.
Oh yeah and it helps with server-side communication, taming async callbacks with promises and
deferreds. It also makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
piece of cake. Best of all?? It makes development fun!
It also helps with server-side communication, taming async callbacks with promises and deferreds,
and it makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
piece of cake. Best of all? It makes development fun!
* Web site: http://angularjs.org
* Tutorial: http://docs.angularjs.org/tutorial
* API Docs: http://docs.angularjs.org/api
* Developer Guide: http://docs.angularjs.org/guide
* Web site: https://angularjs.org
* 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)
* Dashboard: http://dashboard.angularjs.org
* Dashboard: https://dashboard.angularjs.org
##### Looking for Angular 2? Go here: https://github.com/angular/angular
Building AngularJS
---------
[Once you have your environment setup](http://docs.angularjs.org/misc/contribute) just run:
[Once you have set up your environment](https://docs.angularjs.org/misc/contribute), just run:
grunt package
Running Tests
Running tests
-------------
To execute all unit tests, use:
@@ -37,9 +39,36 @@ To execute end-to-end (e2e) tests, use:
grunt package
grunt test:e2e
To learn more about the grunt tasks, run `grunt --help` and also read our
[contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
To learn more about the grunt tasks, run `grunt --help`
Contribute & Develop
--------------------
We've set up a separate document for our [contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/README.md?pixel)](https://github.com/igrigorik/ga-beacon)
What to use AngularJS for and when to use it
---------
AngularJS is the next generation framework where each component is designed to work with every other component in an interconnected way like a well-oiled machine. AngularJS is JavaScript MVC made easy and done right. (Well it is not really MVC, read on, to understand what this means.)
#### MVC, no, MV* done the right way!
MVC, short for Model-View-Controller, is a design pattern, i.e. how the code should be organized and how the different parts of an application separated for proper readability and debugging. Model is the data and the database. View is the user interface and what the user sees. Controller is the main link between Model and View. These are the three pillars of major programming frameworks present on the market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The _Whatever_ is AngularJS's way of telling that you may create any kind of linking between the Model and the View here.
Unlike other frameworks in any programming language, where MVC, the three separate components, each one has to be written and then connected by the programmer, AngularJS helps the programmer by asking him/her to just create these and everything else will be taken care of by AngularJS.
#### Interconnection with HTML at the root level
AngularJS uses HTML to define the user's interface. AngularJS also enables the programmer to write new HTML tags (AngularJS Directives) and increase the readability and understandability of the HTML code. Directives are AngularJSs way of bringing additional functionality to HTML. Directives achieve this by enabling us to invent our own HTML elements. This also helps in making the code DRY (Don't Repeat Yourself), which means once created, a new directive can be used anywhere within the application.
#### Data Handling made simple
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties directly on it and loop over objects and arrays at will.
#### Two-way Data Binding
One of AngularJS's strongest features. Two-way Data Binding means that if something changes in the Model, the change gets reflected in the View instantaneously, and the same happens the other way around. This is also referred to as Reactive Programming, i.e. suppose `a = b + c` is being programmed and after this, if the value of `b` and/or `c` is changed then the value of `a` will be automatically updated to reflect the change. AngularJS uses its "scopes" as a glue between the Model and View and makes these updates in one available for the other.
#### Less Written Code and Easily Maintainable Code
Everything in AngularJS is created to enable the programmer to end up writing less code that is easily maintainable and readable by any other new person on the team. Believe it or not, one can write a complete working two-way data binded application in less than 10 lines of code. Try and see for yourself!
#### Testing Ready
AngularJS has Dependency Injection, i.e. it takes care of providing all the necessary dependencies to its controllers whenever required. This helps in making the AngularJS code ready for unit testing by making use of mock dependencies created and injected. This makes AngularJS more modular and easily testable thus in turn helping a team create more robust applications.
+1 -1
View File
@@ -20,7 +20,7 @@ The following is done automatically so you don't have to worry about it:
This process based on the idea of minimizing user pain
[from this blog post](http://www.lostgarden.com/2008/05/improving-bug-triage-with-user-pain.html).
1. Open the list of [non triaged issues](https://github.com/angular/angular.js/issues?direction=desc&milestone=none&page=1&sort=created&state=open)
1. Open the list of [non triaged issues](https://github.com/angular/angular.js/issues?q=is%3Aopen+sort%3Acreated-desc+no%3Amilestone)
* Sort by submit date, with the newest issues first
* You don't have to do issues in order; feel free to pick and choose issues as you please.
* You can triage older issues as well
+36 -8
View File
@@ -5,6 +5,7 @@ var angularFiles = {
'src/minErr.js',
'src/Angular.js',
'src/loader.js',
'src/shallowCopy.js',
'src/stringify.js',
'src/AngularPublic.js',
'src/jqLite.js',
@@ -14,17 +15,20 @@ var angularFiles = {
'src/ng/anchorScroll.js',
'src/ng/animate.js',
'src/ng/asyncCallback.js',
'src/ng/animateRunner.js',
'src/ng/animateCss.js',
'src/ng/browser.js',
'src/ng/cacheFactory.js',
'src/ng/compile.js',
'src/ng/controller.js',
'src/ng/document.js',
'src/ng/exceptionHandler.js',
'src/ng/forceReflow.js',
'src/ng/http.js',
'src/ng/httpBackend.js',
'src/ng/interpolate.js',
'src/ng/interval.js',
'src/ng/jsonpCallbacks.js',
'src/ng/locale.js',
'src/ng/location.js',
'src/ng/log.js',
@@ -32,6 +36,7 @@ var angularFiles = {
'src/ng/q.js',
'src/ng/raf.js',
'src/ng/rootScope.js',
'src/ng/rootElement.js',
'src/ng/sanitizeUri.js',
'src/ng/sce.js',
'src/ng/sniffer.js',
@@ -76,11 +81,14 @@ var angularFiles = {
'src/ng/directive/script.js',
'src/ng/directive/select.js',
'src/ng/directive/style.js',
'src/ng/directive/validators.js'
'src/ng/directive/validators.js',
'src/angular.bind.js',
'src/publishExternalApis.js',
'src/ngLocale/angular-locale_en-us.js'
],
'angularLoader': [
'stringify.js',
'src/stringify.js',
'src/minErr.js',
'src/loader.js'
],
@@ -95,8 +103,8 @@ var angularFiles = {
'src/ngAnimate/animateJs.js',
'src/ngAnimate/animateJsDriver.js',
'src/ngAnimate/animateQueue.js',
'src/ngAnimate/animateRunner.js',
'src/ngAnimate/animation.js',
'src/ngAnimate/ngAnimateSwap.js',
'src/ngAnimate/module.js'
],
'ngCookies': [
@@ -114,10 +122,15 @@ var angularFiles = {
'ngMessages': [
'src/ngMessages/messages.js'
],
'ngParseExt': [
'src/ngParseExt/ucd.js',
'src/ngParseExt/module.js'
],
'ngResource': [
'src/ngResource/resource.js'
],
'ngRoute': [
'src/shallowCopy.js',
'src/ngRoute/route.js',
'src/ngRoute/routeParams.js',
'src/ngRoute/directive/ngView.js'
@@ -165,6 +178,7 @@ var angularFiles = {
'test/auto/*.js',
'test/ng/**/*.js',
'test/ngAnimate/*.js',
'test/ngMessageFormat/*.js',
'test/ngMessages/*.js',
'test/ngCookies/*.js',
'test/ngResource/*.js',
@@ -179,7 +193,6 @@ var angularFiles = {
'bower_components/jquery/dist/jquery.js',
'test/jquery_remove.js',
'@angularSrc',
'src/publishExternalApis.js',
'@angularSrcModules',
'@angularScenario',
'@angularTest'
@@ -188,7 +201,8 @@ var angularFiles = {
'karmaExclude': [
'test/jquery_alias.js',
'src/angular-bootstrap.js',
'src/ngScenario/angular-bootstrap.js'
'src/ngScenario/angular-bootstrap.js',
'src/angular.bind.js'
],
'karmaScenario': [
@@ -199,9 +213,12 @@ var angularFiles = {
"karmaModules": [
'build/angular.js',
'@angularSrcModules',
'test/modules/no_bootstrap.js',
'src/ngScenario/browserTrigger.js',
'test/helpers/*.js',
'test/ngAnimate/*.js',
'test/ngMessageFormat/*.js',
'test/ngMessages/*.js',
'test/ngMock/*.js',
'test/ngCookies/*.js',
'test/ngRoute/**/*.js',
@@ -215,7 +232,6 @@ var angularFiles = {
'bower_components/jquery/dist/jquery.js',
'test/jquery_alias.js',
'@angularSrc',
'src/publishExternalApis.js',
'@angularSrcModules',
'@angularScenario',
'@angularTest'
@@ -224,10 +240,22 @@ var angularFiles = {
'karmaJqueryExclude': [
'src/angular-bootstrap.js',
'src/ngScenario/angular-bootstrap.js',
'test/jquery_remove.js'
'test/jquery_remove.js',
'src/angular.bind.js'
]
};
['2.1', '2.2'].forEach(function (jQueryVersion) {
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);
}
return path;
});
});
angularFiles['angularSrcModules'] = [].concat(
angularFiles['angularModules']['ngAnimate'],
angularFiles['angularModules']['ngMessageFormat'],
+14 -14
View File
@@ -8,20 +8,20 @@
Large table rendered with AngularJS
</p>
<div>none: <input type="radio" ng-model="benchmarkType" value="none"></div>
<div>baseline binding: <input type="radio" ng-model="benchmarkType" value="baselineBinding"></div>
<div>baseline interpolation: <input type="radio" ng-model="benchmarkType" value="baselineInterpolation"></div>
<div>ngBind: <input type="radio" ng-model="benchmarkType" value="ngBind"></div>
<div>ngBindOnce: <input type="radio" ng-model="benchmarkType" value="ngBindOnce"></div>
<div>interpolation: <input type="radio" ng-model="benchmarkType" value="interpolation"></div>
<div>interpolation + bind-once: <input type="radio" ng-model="benchmarkType" value="bindOnceInterpolation"></div>
<div>attribute interpolation: <input type="radio" ng-model="benchmarkType" value="interpolationAttr"></div>
<div>ngBind + fnInvocation: <input type="radio" ng-model="benchmarkType" value="ngBindFn"></div>
<div>interpolation + fnInvocation: <input type="radio" ng-model="benchmarkType" value="interpolationFn"></div>
<div>ngBind + filter: <input type="radio" ng-model="benchmarkType" value="ngBindFilter"></div>
<div>interpolation + filter: <input type="radio" ng-model="benchmarkType" value="interpolationFilter"></div>
<div>ngModel (const name): <input type="radio" ng-model="benchmarkType" value="ngModelConstName"></div>
<div>ngModel (interp name): <input type="radio" ng-model="benchmarkType" value="ngModelInterpName"></div>
<div><label><input type="radio" ng-model="benchmarkType" value="none">none: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="baselineBinding">baseline binding: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="baselineInterpolation">baseline interpolation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngBind">ngBind: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindOnce">ngBindOnce: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="interpolation">interpolation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="bindOnceInterpolation">interpolation + bind-once: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationAttr">attribute interpolation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindFn">ngBind + fnInvocation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationFn">interpolation + fnInvocation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindFilter">ngBind + filter: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationFilter">interpolation + filter: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngModelConstName">ngModel (const name): </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngModelInterpName">ngModel (interp name): </label></div>
<ng-switch on="benchmarkType">
<baseline-binding-table ng-switch-when="baselineBinding">
+4 -1
View File
@@ -1,7 +1,10 @@
{
"name": "AngularJS",
"license": "MIT",
"devDependencies": {
"jquery": "2.1.1",
"jquery": "3.1.0",
"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.3/assets/ng-closure-runner.zip"
}
-2
View File
@@ -148,8 +148,6 @@ var writeChangelog = function(stream, commits, version) {
breaks: {}
};
sections.breaks[EMPTY_COMPONENT] = [];
commits.forEach(function(commit) {
var section = sections[commit.type];
var component = commit.component || EMPTY_COMPONENT;
+1 -1
View File
@@ -44,7 +44,7 @@ var noArgs = function (fn) {
var identity = function (i) { return i; };
// like Q.all, but runs the comands in series
// like Q.all, but runs the commands in series
// useful for ensuring env state (like which branch is checked out)
var allInSeries = function (fn) {
return function (args) {
+1 -1
View File
@@ -56,7 +56,7 @@ li.doc-example-live {
}
div.syntaxhighlighter {
padding-bottom: 1px !important; /* fix to remove unnecessary scrollbars http://is.gd/gSMgC */
padding-bottom: 1px !important; /* fix to remove unnecessary scrollbars */
}
/* TABS - tutorial environment navigation */
+98 -2
View File
@@ -124,7 +124,7 @@ h1,h2,h3,h4,h5,h6 {
font-size:1.2em;
padding:0;
margin:0;
border-bottom:1px soild #aaa;
border-bottom:1px solid #aaa;
margin-bottom:5px;
}
@@ -315,8 +315,13 @@ iframe.example {
color:white;
}
.search-results-group .search-results {
padding: 0 5px 0;
list-style-type: none;
}
.search-results-frame > .search-results-group:first-child > .search-results {
border-right:1px solid #050505;
border-right:1px solid #222;
}
.search-results-group.col-group-api { width:30%; }
@@ -325,10 +330,57 @@ iframe.example {
.search-results-group.col-group-misc,
.search-results-group.col-group-error { width:15%; float: right; }
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
.search-results-group.col-group-api .search-results {
-moz-column-count: 2;
-ms-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
/* Prevent bullets in the second column from being hidden in Chrome and IE */
-webkit-column-gap: 2em;
-ms-column-gap: 2em;
column-gap: 2em;
}
}
.search-results-group .search-result {
word-wrap: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
-ms-column-break-inside: avoid;
-webkit-column-break-inside: avoid;
-moz-column-break-inside: avoid; /* Unsupported */
column-break-inside: avoid;
text-indent: -0.65em; /* Make sure line wrapped words are aligned vertically */
}
@supports (-moz-column-count: 2) {
.search-results-group .search-result {
/* Prevents column breaks inside words in FF, but has adverse effects in IE11 and Chrome */
overflow: hidden;
padding-left: 1em; /* In FF the list item bullet is otherwise hidden */
margin-left: -1em; /* offset the padding left */
}
}
.search-result:before {
content: "\002D\00A0"; /* Dash and non-breaking space as List item type */
position: relative;
}
.search-results-group.col-group-api .search-result {
width:48%;
display:inline-block;
padding-left: 12px;
}
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
.search-results-group.col-group-api .search-result {
width:auto;
display: list-item;
}
}
.search-close {
@@ -589,6 +641,17 @@ ul.events > li {
vertical-align: top;
}
.table > tbody > tr.head > td,
.table > tbody > tr.head > th {
border-bottom: 2px solid #ddd;
padding-top: 50px;
}
.diagram {
margin-bottom: 10px;
margin-top: 30px;
}
@media only screen and (min-width: 769px) and (max-width: 991px) {
.main-body-grid {
margin-top: 160px;
@@ -682,6 +745,11 @@ ul.events > li {
padding-bottom:60px;
text-align:left;
}
.search-results-frame > .search-results-group:first-child > .search-results {
border-right: none;
}
.search-results-group {
float:none!important;
display:block!important;
@@ -689,14 +757,42 @@ ul.events > li {
border:0!important;
padding:0!important;
}
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
.search-results-group .search-results {
-moz-column-count: 2;
-ms-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
}
}
.search-results-group .search-result {
display:inline-block!important;
padding:0 5px;
width:auto!important;
text-indent: initial;
margin-left: 0;
}
.search-results-group .search-result:after {
content:", ";
}
.search-results-group .search-result:before {
content: "";
}
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
.search-results-group .search-result {
display: list-item !important;
}
.search-results-group .search-result:after {
content: "";
}
}
#wrapper {
padding-bottom:0px;
}
-442
View File
@@ -1,442 +0,0 @@
'use strict';
var directive = {};
directive.runnableExample = ['$templateCache', '$document', function($templateCache, $document) {
var exampleClassNameSelector = '.runnable-example-file';
var doc = $document[0];
var tpl =
'<nav class="runnable-example-tabs" ng-if="tabs">' +
' <a ng-class="{active:$index==activeTabIndex}"' +
'ng-repeat="tab in tabs track by $index" ' +
'href="" ' +
'class="btn"' +
'ng-click="setTab($index)">' +
' {{ tab }}' +
' </a>' +
'</nav>';
return {
restrict: 'C',
scope : true,
controller : ['$scope', function($scope) {
$scope.setTab = function(index) {
var tab = $scope.tabs[index];
$scope.activeTabIndex = index;
$scope.$broadcast('tabChange', index, tab);
};
}],
compile : function(element) {
element.html(tpl + element.html());
return function(scope, element) {
var node = element[0];
var examples = node.querySelectorAll(exampleClassNameSelector);
var tabs = [], now = Date.now();
angular.forEach(examples, function(child, index) {
tabs.push(child.getAttribute('name'));
});
if(tabs.length > 0) {
scope.tabs = tabs;
scope.$on('tabChange', function(e, index, title) {
angular.forEach(examples, function(child) {
child.style.display = 'none';
});
var selected = examples[index];
selected.style.display = 'block';
});
scope.setTab(0);
}
}
}
};
}];
directive.dropdownToggle =
['$document', '$location', '$window',
function ($document, $location, $window) {
var openElement = null, close;
return {
restrict: 'C',
link: function(scope, element, attrs) {
scope.$watch(function dropdownTogglePathWatch(){return $location.path();}, function dropdownTogglePathWatchAction() {
close && close();
});
element.parent().on('click', function(event) {
close && close();
});
element.on('click', function(event) {
event.preventDefault();
event.stopPropagation();
var iWasOpen = false;
if (openElement) {
iWasOpen = openElement === element;
close();
}
if (!iWasOpen){
element.parent().addClass('open');
openElement = element;
close = function (event) {
event && event.preventDefault();
event && event.stopPropagation();
$document.off('click', close);
element.parent().removeClass('open');
close = null;
openElement = null;
}
$document.on('click', close);
}
});
}
};
}];
directive.syntax = function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
function makeLink(type, text, link, icon) {
return '<a href="' + link + '" class="btn syntax-' + type + '" target="_blank" rel="nofollow">' +
'<span class="' + icon + '"></span> ' + text +
'</a>';
};
var html = '';
var types = {
'github' : {
text : 'View on Github',
key : 'syntaxGithub',
icon : 'icon-github'
},
'plunkr' : {
text : 'View on Plunkr',
key : 'syntaxPlunkr',
icon : 'icon-arrow-down'
},
'jsfiddle' : {
text : 'View on JSFiddle',
key : 'syntaxFiddle',
icon : 'icon-cloud'
}
};
for(var type in types) {
var data = types[type];
var link = attrs[data.key];
if(link) {
html += makeLink(type, data.text, link, data.icon);
}
};
var nav = document.createElement('nav');
nav.className = 'syntax-links';
nav.innerHTML = html;
var node = element[0];
var par = node.parentNode;
par.insertBefore(nav, node);
}
}
}
directive.tabbable = function() {
return {
restrict: 'C',
compile: function(element) {
var navTabs = angular.element('<ul class="nav nav-tabs"></ul>'),
tabContent = angular.element('<div class="tab-content"></div>');
tabContent.append(element.contents());
element.append(navTabs).append(tabContent);
},
controller: ['$scope', '$element', function($scope, $element) {
var navTabs = $element.contents().eq(0),
ngModel = $element.controller('ngModel') || {},
tabs = [],
selectedTab;
ngModel.$render = function() {
var $viewValue = this.$viewValue;
if (selectedTab ? (selectedTab.value != $viewValue) : $viewValue) {
if(selectedTab) {
selectedTab.paneElement.removeClass('active');
selectedTab.tabElement.removeClass('active');
selectedTab = null;
}
if($viewValue) {
for(var i = 0, ii = tabs.length; i < ii; i++) {
if ($viewValue == tabs[i].value) {
selectedTab = tabs[i];
break;
}
}
if (selectedTab) {
selectedTab.paneElement.addClass('active');
selectedTab.tabElement.addClass('active');
}
}
}
};
this.addPane = function(element, attr) {
var li = angular.element('<li><a href></a></li>'),
a = li.find('a'),
tab = {
paneElement: element,
paneAttrs: attr,
tabElement: li
};
tabs.push(tab);
attr.$observe('value', update)();
attr.$observe('title', function(){ update(); a.text(tab.title); })();
function update() {
tab.title = attr.title;
tab.value = attr.value || attr.title;
if (!ngModel.$setViewValue && (!ngModel.$viewValue || tab == selectedTab)) {
// we are not part of angular
ngModel.$viewValue = tab.value;
}
ngModel.$render();
}
navTabs.append(li);
li.on('click', function(event) {
event.preventDefault();
event.stopPropagation();
if (ngModel.$setViewValue) {
$scope.$apply(function() {
ngModel.$setViewValue(tab.value);
ngModel.$render();
});
} else {
// we are not part of angular
ngModel.$viewValue = tab.value;
ngModel.$render();
}
});
return function() {
tab.tabElement.remove();
for(var i = 0, ii = tabs.length; i < ii; i++ ) {
if (tab == tabs[i]) {
tabs.splice(i, 1);
}
}
};
}
}]
};
};
directive.table = function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
if (!attrs['class']) {
element.addClass('table table-bordered table-striped code-table');
}
}
};
};
var popoverElement = function() {
var object = {
init : function() {
this.element = angular.element(
'<div class="popover popover-incode top">' +
'<div class="arrow"></div>' +
'<div class="popover-inner">' +
'<div class="popover-title"><code></code></div>' +
'<div class="popover-content"></div>' +
'</div>' +
'</div>'
);
this.node = this.element[0];
this.element.css({
'display':'block',
'position':'absolute'
});
angular.element(document.body).append(this.element);
var inner = this.element.children()[1];
this.titleElement = angular.element(inner.childNodes[0].firstChild);
this.contentElement = angular.element(inner.childNodes[1]);
//stop the click on the tooltip
this.element.on('click', function(event) {
event.preventDefault();
event.stopPropagation();
});
var self = this;
angular.element(document.body).on('click',function(event) {
if(self.visible()) self.hide();
});
},
show : function(x,y) {
this.element.addClass('visible');
this.position(x || 0, y || 0);
},
hide : function() {
this.element.removeClass('visible');
this.position(-9999,-9999);
},
visible : function() {
return this.position().y >= 0;
},
isSituatedAt : function(element) {
return this.besideElement ? element[0] == this.besideElement[0] : false;
},
title : function(value) {
return this.titleElement.html(value);
},
content : function(value) {
if(value && value.length > 0) {
value = marked(value);
}
return this.contentElement.html(value);
},
positionArrow : function(position) {
this.node.className = 'popover ' + position;
},
positionAway : function() {
this.besideElement = null;
this.hide();
},
positionBeside : function(element) {
this.besideElement = element;
var elm = element[0];
var x = elm.offsetLeft;
var y = elm.offsetTop;
x -= 30;
y -= this.node.offsetHeight + 10;
this.show(x,y);
},
position : function(x,y) {
if(x != null && y != null) {
this.element.css('left',x + 'px');
this.element.css('top', y + 'px');
}
else {
return {
x : this.node.offsetLeft,
y : this.node.offsetTop
};
}
}
};
object.init();
object.hide();
return object;
};
directive.popover = ['popoverElement', function(popover) {
return {
restrict: 'A',
priority : 500,
link: function(scope, element, attrs) {
element.on('click',function(event) {
event.preventDefault();
event.stopPropagation();
if(popover.isSituatedAt(element) && popover.visible()) {
popover.title('');
popover.content('');
popover.positionAway();
}
else {
popover.title(attrs.title);
popover.content(attrs.content);
popover.positionBeside(element);
}
});
}
}
}];
directive.tabPane = function() {
return {
require: '^tabbable',
restrict: 'C',
link: function(scope, element, attrs, tabsCtrl) {
element.on('$remove', tabsCtrl.addPane(element, attrs));
}
};
};
directive.foldout = ['$http', '$animate','$window', function($http, $animate, $window) {
return {
restrict: 'A',
priority : 500,
link: function(scope, element, attrs) {
var container, loading, url = attrs.url;
if(/\/build\//.test($window.location.href)) {
url = '/build/docs' + url;
}
element.on('click',function() {
scope.$apply(function() {
if(!container) {
if(loading) return;
loading = true;
var par = element.parent();
container = angular.element('<div class="foldout">loading...</div>');
$animate.enter(container, null, par);
$http.get(url, { cache : true }).success(function(html) {
loading = false;
html = '<div class="foldout-inner">' +
'<div calss="foldout-arrow"></div>' +
html +
'</div>';
container.html(html);
//avoid showing the element if the user has already closed it
if(container.css('display') == 'block') {
container.css('display','none');
$animate.addClass(container, 'ng-hide');
}
});
}
else {
container.hasClass('ng-hide') ? $animate.removeClass(container, 'ng-hide') : $animate.addClass(container, 'ng-hide');
}
});
});
}
}
}];
angular.module('bootstrap', [])
.directive(directive)
.factory('popoverElement', popoverElement)
.run(function() {
marked.setOptions({
gfm: true,
tables: true
});
});
+3 -1
View File
@@ -54,7 +54,9 @@ angular.module('ui.bootstrap.dropdown', [])
}
};
var closeDropdown = function() {
var closeDropdown = function(evt) {
if (evt && evt.which === 3) return;
openScope.$apply(function() {
openScope.isOpen = false;
});
+1 -1
View File
@@ -3,7 +3,7 @@
/* global importScripts, onmessage: true, postMessage, lunr */
// Load up the lunr library
importScripts('../components/lunr.js-0.4.2/lunr.min.js');
importScripts('../components/lunr.js-0.5.12/lunr.min.js');
// Create the lunr index - the docs should be an array of object, each object containing
// the path and search terms for a page
+4 -1
View File
@@ -19,9 +19,12 @@
"dump": false,
/* e2e */
"protractor": false,
"browser": false,
"element": false,
"by": false,
"$": false,
"$$": false,
/* testabilityPatch / matchers */
"inject": false,
@@ -39,4 +42,4 @@
"browserTrigger": false,
"jqLiteCacheSize": false
}
}
}
+6 -6
View File
@@ -39,7 +39,7 @@ describe('docs.angularjs.org', function () {
it('should change the page content when clicking a link to a service', function () {
browser.get('build/docs/index.html');
browser.get('build/docs/index-production.html');
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
ngBindLink.click();
@@ -51,33 +51,33 @@ describe('docs.angularjs.org', function () {
it('should be resilient to trailing slashes', function() {
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/');
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
});
it('should be resilient to trailing "index"', function() {
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/index');
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
});
it('should be resilient to trailing "index/"', function() {
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/index/');
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index/');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
});
it('should display formatted error messages on error doc pages', function() {
browser.get('build/docs/index.html#!error/ng/areq?p0=Missing&p1=not%20a%20function,%20got%20undefined');
browser.get('build/docs/index-production.html#!error/ng/areq?p0=Missing&p1=not%20a%20function,%20got%20undefined');
expect(element(by.css('.minerr-errmsg')).getText()).toEqual("Argument 'Missing' is not a function, got undefined");
});
it("should display an error if the page does not exist", function() {
browser.get('build/docs/index.html#!/api/does/not/exist');
browser.get('build/docs/index-production.html#!/api/does/not/exist');
expect(element(by.css('h1')).getText()).toBe('Oops!');
});
-1
View File
@@ -13,7 +13,6 @@ angular.module('docsApp', [
'search',
'tutorials',
'versions',
'bootstrap',
'ui.bootstrap.dropdown'
])
+12 -1
View File
@@ -34,4 +34,15 @@ angular.module('directives', [])
return function(scope, element) {
$anchorScroll.yOffset = element;
};
}]);
}])
.directive('table', function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
if (!attrs['class']) {
element.addClass('table table-bordered table-striped code-table');
}
}
};
});
+2 -4
View File
@@ -1,13 +1,11 @@
angular.module('DocsController', [])
.controller('DocsController', [
'$scope', '$rootScope', '$location', '$window', '$cookies', 'openPlunkr',
'$scope', '$rootScope', '$location', '$window', '$cookies',
'NG_PAGES', 'NG_NAVIGATION', 'NG_VERSION',
function($scope, $rootScope, $location, $window, $cookies, openPlunkr,
function($scope, $rootScope, $location, $window, $cookies,
NG_PAGES, NG_NAVIGATION, NG_VERSION) {
$scope.openPlunkr = openPlunkr;
$scope.docsVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.version;
$scope.navClass = function(navItem) {
+10 -3
View File
@@ -13,10 +13,10 @@ angular.module('errors', ['ngSanitize'])
};
return function (text, target) {
var targetHtml = target ? ' target="' + target + '"' : '';
if (!text) return text;
var targetHtml = target ? ' target="' + target + '"' : '';
return $sanitize(text.replace(LINKY_URL_REGEXP, function (url) {
if (STACK_TRACE_REGEXP.test(url)) {
return url;
@@ -34,6 +34,10 @@ angular.module('errors', ['ngSanitize'])
.directive('errorDisplay', ['$location', 'errorLinkFilter', function ($location, errorLinkFilter) {
var encodeAngleBrackets = function (text) {
return text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
};
var interpolate = function (formatString) {
var formatArgs = arguments;
return formatString.replace(/\{\d+\}/g, function (match) {
@@ -51,12 +55,15 @@ angular.module('errors', ['ngSanitize'])
link: function (scope, element, attrs) {
var search = $location.search(),
formatArgs = [attrs.errorDisplay],
formattedText,
i;
for (i = 0; angular.isDefined(search['p'+i]); i++) {
formatArgs.push(search['p'+i]);
}
element.html(errorLinkFilter(interpolate.apply(null, formatArgs), '_blank'));
formattedText = encodeAngleBrackets(interpolate.apply(null, formatArgs));
element.html(errorLinkFilter(formattedText, '_blank'));
}
};
}]);
+149 -28
View File
@@ -1,5 +1,55 @@
angular.module('examples', [])
.directive('runnableExample', ['$templateCache', '$document', function($templateCache, $document) {
var exampleClassNameSelector = '.runnable-example-file';
var doc = $document[0];
var tpl =
'<nav class="runnable-example-tabs" ng-if="tabs">' +
' <a ng-class="{active:$index==activeTabIndex}"' +
'ng-repeat="tab in tabs track by $index" ' +
'href="" ' +
'class="btn"' +
'ng-click="setTab($index)">' +
' {{ tab }}' +
' </a>' +
'</nav>';
return {
restrict: 'C',
scope : true,
controller : ['$scope', function($scope) {
$scope.setTab = function(index) {
var tab = $scope.tabs[index];
$scope.activeTabIndex = index;
$scope.$broadcast('tabChange', index, tab);
};
}],
compile : function(element) {
element.html(tpl + element.html());
return function(scope, element) {
var node = element[0];
var examples = node.querySelectorAll(exampleClassNameSelector);
var tabs = [], now = Date.now();
angular.forEach(examples, function(child, index) {
tabs.push(child.getAttribute('name'));
});
if(tabs.length > 0) {
scope.tabs = tabs;
scope.$on('tabChange', function(e, index, title) {
angular.forEach(examples, function(child) {
child.style.display = 'none';
});
var selected = examples[index];
selected.style.display = 'block';
});
scope.setTab(0);
}
};
}
};
}])
.factory('formPostData', ['$document', function($document) {
return function(url, newWindow, fields) {
/**
@@ -22,29 +72,110 @@ angular.module('examples', [])
};
}])
.factory('createCopyrightNotice', function() {
var COPYRIGHT = 'Copyright ' + (new Date()).getFullYear() + ' Google Inc. All Rights Reserved.\n'
+ 'Use of this source code is governed by an MIT-style license that\n'
+ 'can be found in the LICENSE file at http://angular.io/license';
var COPYRIGHT_JS_CSS = '\n\n/*\n' + COPYRIGHT + '\n*/';
var COPYRIGHT_HTML = '\n\n<!-- \n' + COPYRIGHT + '\n-->';
.factory('openPlunkr', ['formPostData', '$http', '$q', function(formPostData, $http, $q) {
return function(exampleFolder, clickEvent) {
return function getCopyright(filename) {
switch (filename.substr(filename.lastIndexOf('.'))) {
case '.html':
return COPYRIGHT_HTML;
case '.js':
case '.css':
return COPYRIGHT_JS_CSS;
case '.md':
return COPYRIGHT;
}
return '';
};
})
var exampleName = 'AngularJS Example';
var newWindow = clickEvent.ctrlKey || clickEvent.metaKey;
.directive('plnkrOpener', ['$q', 'getExampleData', 'formPostData', 'createCopyrightNotice', function($q, getExampleData, formPostData, createCopyrightNotice) {
return {
scope: {},
bindToController: {
'examplePath': '@'
},
controllerAs: 'plnkr',
template: '<button ng-click="plnkr.open($event)" class="btn pull-right"> <i class="glyphicon glyphicon-edit">&nbsp;</i> Edit in Plunker</button> ',
controller: [function() {
var ctrl = this;
ctrl.example = {
path: ctrl.examplePath,
manifest: undefined,
files: undefined,
name: 'AngularJS Example'
};
ctrl.prepareExampleData = function() {
if (ctrl.example.manifest) {
return $q.when(ctrl.example);
}
return getExampleData(ctrl.examplePath).then(function(data) {
ctrl.example.files = data.files;
ctrl.example.manifest = data.manifest;
// Build a pretty title for the Plunkr
var exampleNameParts = data.manifest.name.split('-');
exampleNameParts.unshift('AngularJS');
angular.forEach(exampleNameParts, function(part, index) {
exampleNameParts[index] = part.charAt(0).toUpperCase() + part.substr(1);
});
ctrl.example.name = exampleNameParts.join(' - ');
return ctrl.example;
});
};
ctrl.open = function(clickEvent) {
var newWindow = clickEvent.ctrlKey || clickEvent.metaKey;
var postData = {
'tags[0]': "angularjs",
'tags[1]': "example",
'private': true
};
// Make sure the example data is available.
// If an XHR must be made, this might break some pop-up blockers when
// new window is requested
ctrl.prepareExampleData()
.then(function() {
angular.forEach(ctrl.example.files, function(file) {
postData['files[' + file.name + ']'] = file.content + createCopyrightNotice(file.name);
});
postData.description = ctrl.example.name;
formPostData('https://plnkr.co/edit/?p=preview', newWindow, postData);
});
};
// Initialize the example data, so it's ready when clicking the open button.
// Otherwise pop-up blockers will prevent a new window from opening
ctrl.prepareExampleData(ctrl.example.path);
}]
};
}])
.factory('getExampleData', ['$http', '$q', function($http, $q) {
return function(exampleFolder){
// Load the manifest for the example
$http.get(exampleFolder + '/manifest.json')
return $http.get(exampleFolder + '/manifest.json')
.then(function(response) {
return response.data;
})
.then(function(manifest) {
var filePromises = [];
// Build a pretty title for the Plunkr
var exampleNameParts = manifest.name.split('-');
exampleNameParts.unshift('AngularJS');
angular.forEach(exampleNameParts, function(part, index) {
exampleNameParts[index] = part.charAt(0).toUpperCase() + part.substr(1);
});
exampleName = exampleNameParts.join(' - ');
angular.forEach(manifest.files, function(filename) {
filePromises.push($http.get(exampleFolder + '/' + filename, { transformResponse: [] })
.then(function(response) {
@@ -52,7 +183,7 @@ angular.module('examples', [])
// The manifests provide the production index file but Plunkr wants
// a straight index.html
if (filename === "index-production.html") {
filename = "index.html"
filename = "index.html";
}
return {
@@ -61,21 +192,11 @@ angular.module('examples', [])
};
}));
});
return $q.all(filePromises);
})
.then(function(files) {
var postData = {};
angular.forEach(files, function(file) {
postData['files[' + file.name + ']'] = file.content;
return $q.all({
manifest: manifest,
files: $q.all(filePromises)
});
postData['tags[0]'] = "angularjs";
postData['tags[1]'] = "example";
postData.private = true;
postData.description = exampleName;
formPostData('http://plnkr.co/edit/?p=preview', newWindow, postData);
});
};
}]);
}]);
+9 -1
View File
@@ -11,7 +11,15 @@ angular.module('search', [])
var MIN_SEARCH_LENGTH = 2;
if(q.length >= MIN_SEARCH_LENGTH) {
docsSearch(q).then(function(hits) {
var results = {};
// Make sure the areas are always in the same order
var results = {
api: [],
guide: [],
tutorial: [],
error: [],
misc: []
};
angular.forEach(hits, function(hit) {
var area = hit.area;
+4 -3
View File
@@ -5,7 +5,8 @@ angular.module('tutorials', [])
'',
'step_00', 'step_01', 'step_02', 'step_03', 'step_04',
'step_05', 'step_06', 'step_07', 'step_08', 'step_09',
'step_10', 'step_11', 'step_12', 'the_end'
'step_10', 'step_11', 'step_12', 'step_13', 'step_14',
'the_end'
];
return {
scope: {},
@@ -43,7 +44,7 @@ angular.module('tutorials', [])
'<a href="http://angular.github.io/angular-phonecat/step-{{step}}/app">Step {{step}} Live Demo</a>.</p>\n' +
'</div>\n' +
'<p>The most important changes are listed below. You can see the full diff on ' +
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}" title="See diff on Github">GitHub</a>\n' +
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}" title="See diff on Github">GitHub</a>.\n' +
'</p>'
};
});
});
+25
View File
@@ -0,0 +1,25 @@
{
"extends": "../../../.jshintrc-base",
"browser": true,
"globals": {
// AngularJS
"angular": false,
// ngMocks
"module": false,
"inject": true,
// Jasmine
"jasmine": false,
"describe": false,
"ddescribe": false,
"xdescribe": false,
"it": false,
"iit": false,
"xit": false,
"beforeEach": false,
"afterEach": false,
"spyOn": false,
"expect": false
}
}
+1 -2
View File
@@ -3,7 +3,6 @@ describe("DocsController", function() {
angular.module('fake', [])
.value('$cookies', {})
.value('openPlunkr', function() {})
.value('NG_PAGES', {})
.value('NG_NAVIGATION', {})
.value('NG_VERSION', {});
@@ -26,7 +25,7 @@ describe("DocsController", function() {
it("should update the Google Analytics with $location.path if currentPage is missing", inject(function($window, $location) {
$window._gaq = [];
spyOn($location, 'path').andReturn('x/y/z');
spyOn($location, 'path').and.returnValue('x/y/z');
$scope.$broadcast('$includeContentLoaded');
expect($window._gaq.pop()).toEqual(['_trackPageview', 'x/y/z']);
}));
+166
View File
@@ -0,0 +1,166 @@
'use strict';
describe('errors', function() {
// Mock `ngSanitize` module
angular.
module('ngSanitize', []).
value('$sanitize', jasmine.createSpy('$sanitize').and.callFake(angular.identity));
beforeEach(module('errors'));
describe('errorDisplay', function() {
var $sanitize;
var errorLinkFilter;
beforeEach(inject(function(_$sanitize_, _errorLinkFilter_) {
$sanitize = _$sanitize_;
errorLinkFilter = _errorLinkFilter_;
}));
it('should return empty input unchanged', function() {
var inputs = [undefined, null, false, 0, ''];
var remaining = inputs.length;
inputs.forEach(function(falsyValue) {
expect(errorLinkFilter(falsyValue)).toBe(falsyValue);
remaining--;
});
expect(remaining).toBe(0);
});
it('should recognize URLs and convert them to `<a>`', function() {
var urls = [
['ftp://foo/bar?baz#qux'],
['http://foo/bar?baz#qux'],
['https://foo/bar?baz#qux'],
['mailto:foo_bar@baz.qux', null, 'foo_bar@baz.qux'],
['foo_bar@baz.qux', 'mailto:foo_bar@baz.qux', 'foo_bar@baz.qux']
];
var remaining = urls.length;
urls.forEach(function(values) {
var actualUrl = values[0];
var expectedUrl = values[1] || actualUrl;
var expectedText = values[2] || expectedUrl;
var anchor = '<a href="' + expectedUrl + '">' + expectedText + '</a>';
var input = 'start ' + actualUrl + ' end';
var output = 'start ' + anchor + ' end';
expect(errorLinkFilter(input)).toBe(output);
remaining--;
});
expect(remaining).toBe(0);
});
it('should not recognize stack-traces as URLs', function() {
var urls = [
'ftp://foo/bar?baz#qux:4:2',
'http://foo/bar?baz#qux:4:2',
'https://foo/bar?baz#qux:4:2',
'mailto:foo_bar@baz.qux:4:2',
'foo_bar@baz.qux:4:2'
];
var remaining = urls.length;
urls.forEach(function(url) {
var input = 'start ' + url + ' end';
expect(errorLinkFilter(input)).toBe(input);
remaining--;
});
expect(remaining).toBe(0);
});
it('should should set `[target]` if specified', function() {
var url = 'https://foo/bar?baz#qux';
var target = '_blank';
var outputWithoutTarget = '<a href="' + url + '">' + url + '</a>';
var outputWithTarget = '<a target="' + target + '" href="' + url + '">' + url + '</a>';
expect(errorLinkFilter(url)).toBe(outputWithoutTarget);
expect(errorLinkFilter(url, target)).toBe(outputWithTarget);
});
it('should truncate the contents of the generated `<a>` to 60 characters', function() {
var looongUrl = 'https://foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo';
var truncatedUrl = 'https://foooooooooooooooooooooooooooooooooooooooooooooooo...';
var output = '<a href="' + looongUrl + '">' + truncatedUrl + '</a>';
expect(looongUrl.length).toBeGreaterThan(60);
expect(truncatedUrl.length).toBe(60);
expect(errorLinkFilter(looongUrl)).toBe(output);
});
it('should pass the final string through `$sanitize`', function() {
$sanitize.calls.reset();
var input = 'start https://foo/bar?baz#qux end';
var output = errorLinkFilter(input);
expect($sanitize).toHaveBeenCalledTimes(1);
expect($sanitize).toHaveBeenCalledWith(output);
});
});
describe('errorDisplay', function() {
var $compile;
var $location;
var $rootScope;
var errorLinkFilter;
beforeEach(module(function($provide) {
$provide.decorator('errorLinkFilter', function() {
errorLinkFilter = jasmine.createSpy('errorLinkFilter');
errorLinkFilter.and.callFake(angular.identity);
return errorLinkFilter;
});
}));
beforeEach(inject(function(_$compile_, _$location_, _$rootScope_) {
$compile = _$compile_;
$location = _$location_;
$rootScope = _$rootScope_;
}));
it('should set the element\s HTML', function() {
var elem = $compile('<span error-display="bar">foo</span>')($rootScope);
expect(elem.html()).toBe('bar');
});
it('should interpolate the contents against `$location.search()`', function() {
spyOn($location, 'search').and.returnValue({p0: 'foo', p1: 'bar'});
var elem = $compile('<span error-display="foo = {0}, bar = {1}"></span>')($rootScope);
expect(elem.html()).toBe('foo = foo, bar = bar');
});
it('should pass the interpolated text through `errorLinkFilter`', function() {
$location.search = jasmine.createSpy('search').and.returnValue({p0: 'foo'});
var elem = $compile('<span error-display="foo = {0}"></span>')($rootScope);
expect(errorLinkFilter).toHaveBeenCalledTimes(1);
expect(errorLinkFilter).toHaveBeenCalledWith('foo = foo', '_blank');
});
it('should encode `<` and `>`', function() {
var elem = $compile('<span error-display="&lt;xyz&gt;"></span>')($rootScope);
expect(elem.text()).toBe('<xyz>');
});
});
});
+2 -2
View File
@@ -1,8 +1,8 @@
{
"name": "AngularJS-docs-app",
"dependencies": {
"jquery": "2.1.1",
"lunr.js": "0.4.3",
"jquery": "2.2.3",
"lunr.js": "0.5.12",
"open-sans-fontface": "1.0.4",
"google-code-prettify": "1.0.1",
"bootstrap": "3.1.1"
+6 -1
View File
@@ -42,7 +42,7 @@ module.exports = new Package('angularjs', [
readFilesProcessor.basePath = path.resolve(__dirname,'../..');
readFilesProcessor.sourceFiles = [
{ include: 'src/**/*.js', basePath: 'src' },
{ include: 'src/**/*.js', exclude: 'src/angular.bind.js', basePath: 'src' },
{ include: 'docs/content/**/*.ngdoc', basePath: 'docs/content' }
];
@@ -54,6 +54,7 @@ module.exports = new Package('angularjs', [
.config(function(parseTagsProcessor) {
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/tutorial-step'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/sortOrder'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/installation'));
})
@@ -170,4 +171,8 @@ module.exports = new Package('angularjs', [
jqueryDeployment,
productionDeployment
];
})
.config(function(generateKeywordsProcessor) {
generateKeywordsProcessor.docTypesToIgnore = ['componentGroup'];
});
+27 -20
View File
@@ -16,9 +16,11 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
ignoreWordsFile: undefined,
areasToSearch: ['api', 'guide', 'misc', 'error', 'tutorial'],
propertiesToIgnore: [],
docTypesToIgnore: [],
$validate: {
ignoreWordsFile: { },
areasToSearch: { presence: true },
docTypesToIgnore: { },
propertiesToIgnore: { }
},
$runAfter: ['memberDocsProcessor'],
@@ -28,6 +30,7 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
// Keywords to ignore
var wordsToIgnore = [];
var propertiesToIgnore;
var docTypesToIgnore;
var areasToSearch;
// Keywords start with "ng:" or one of $, _ or a letter
@@ -47,6 +50,8 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
areasToSearch = _.indexBy(this.areasToSearch);
propertiesToIgnore = _.indexBy(this.propertiesToIgnore);
log.debug('Properties to ignore', propertiesToIgnore);
docTypesToIgnore = _.indexBy(this.docTypesToIgnore);
log.debug('Doc types to ignore', docTypesToIgnore);
var ignoreWordsMap = _.indexBy(wordsToIgnore);
@@ -78,34 +83,36 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
// We are only interested in docs that live in the right area
docs = _.filter(docs, function(doc) { return areasToSearch[doc.area]; });
docs = _.filter(docs, function(doc) { return !docTypesToIgnore[doc.docType]; });
_.forEach(docs, function(doc) {
var words = [];
var keywordMap = _.clone(ignoreWordsMap);
var members = [];
var membersMap = {};
// Search each top level property of the document for search terms
_.forEach(doc, function(value, key) {
var words = [];
var keywordMap = _.clone(ignoreWordsMap);
var members = [];
var membersMap = {};
if ( _.isString(value) && !propertiesToIgnore[key] ) {
extractWords(value, words, keywordMap);
}
// Search each top level property of the document for search terms
_.forEach(doc, function(value, key) {
if ( key === 'methods' || key === 'properties' || key === 'events' ) {
_.forEach(value, function(member) {
extractWords(member.name, members, membersMap);
});
}
});
if ( _.isString(value) && !propertiesToIgnore[key] ) {
extractWords(value, words, keywordMap);
}
if ( key === 'methods' || key === 'properties' || key === 'events' ) {
_.forEach(value, function(member) {
extractWords(member.name, members, membersMap);
});
}
});
doc.searchTerms = {
titleWords: extractTitleWords(doc.name),
keywords: _.sortBy(words).join(' '),
members: _.sortBy(members).join(' ')
};
doc.searchTerms = {
titleWords: extractTitleWords(doc.name),
keywords: _.sortBy(words).join(' '),
members: _.sortBy(members).join(' ')
};
});
@@ -18,7 +18,6 @@ module.exports = function debugDeployment(getVersion) {
'../angular-touch.js',
'../angular-animate.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/bootstrap.js',
'js/angular-bootstrap/dropdown-toggle.js',
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
@@ -18,7 +18,6 @@ module.exports = function defaultDeployment(getVersion) {
'../angular-touch.min.js',
'../angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/bootstrap.min.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
-1
View File
@@ -22,7 +22,6 @@ module.exports = function jqueryDeployment(getVersion) {
'../angular-touch.min.js',
'../angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/bootstrap.min.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
@@ -21,7 +21,6 @@ module.exports = function productionDeployment(getVersion) {
cdnUrl + '/angular-touch.min.js',
cdnUrl + '/angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/bootstrap.min.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
name: 'installation'
};
@@ -0,0 +1,66 @@
{% extends "base.template.html" %}
{% block content %}
<a href='https://github.com/{$ git.info.owner $}/{$ git.info.repo $}/tree/{$ git.version.isSnapshot and 'master' or git.version.raw $}/{$ doc.fileInfo.projectRelativePath $}#L{$ doc.startingLine $}' class='view-source pull-right btn btn-primary'>
<i class="glyphicon glyphicon-zoom-in">&nbsp;</i>View Source
</a>
{% block header %}
<header class="api-profile-header">
<h1 class="api-profile-header-heading">{$ doc.name $}</h1>
<ol class="api-profile-header-structure naked-list step-list">
{% block related_components %}{% endblock %}
<li>
- {$ doc.docType $} in module <a href="{$ doc.moduleDoc.path $}">{$ doc.moduleDoc.name $}</a>
</li>
</ol>
</header>
{% endblock %}
{% block description %}
<div class="api-profile-description">
{$ doc.description | marked $}
</div>
{% endblock %}
{% if doc.knownIssues %}
<h2 id="known-issues">Known Issues</h2>
{% for issue in doc.knownIssues -%}
<div class="known-issue">
{$ issue | marked $} {% if not loop.last %}<hr>{% endif %}
</div>
{% endfor -%}
{% endif %}
{% if doc.deprecated %}
<fieldset class="deprecated">
<legend>Deprecated API</legend>
{$ doc.deprecated| marked $}
</fieldset>
{% endif %}
<div>
{% block dependencies %}
{%- if doc.requires %}
<h2 id="dependencies">Dependencies</h2>
<ul>
{% for require in doc.requires %}<li>{$ require | link $}</li>{% endfor %}
</ul>
{% endif -%}
{% endblock %}
{% block additional %}
{% endblock %}
{% block examples %}
{%- if doc.examples %}
<h2 id="example">Example</h2>
{%- for example in doc.examples -%}
{$ example | marked $}
{%- endfor -%}
{% endif -%}
{% endblock %}
</div>
{% endblock %}
@@ -0,0 +1,100 @@
{% extends "base.template.html" %}
{% block content %}
<h1>
{% if doc.title %}{$ doc.title | marked $}{% else %}{$ doc.name | code $}{% endif %}
</h1>
<h2>Installation</h2>
{% if doc.installation or doc.installation == '' %}
{$ doc.installation | marked $}
{% else %}
<p>First, get the file:</p>
<ul>
<li>
<a href="https://developers.google.com/speed/libraries/devguide#angularjs">Google CDN</a> e.g.
{% code %}"//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/{$ doc.packageFile $}"{% endcode %}
</li>
<li>
<a href="https://www.npmjs.com/">NPM</a> e.g.
{% code %}npm install {$ doc.packageName $}@X.Y.Z{% endcode %}
</li>
<li>
<a href="http://bower.io">Bower</a> e.g.
{% code %}bower install {$ doc.packageName $}#X.Y.Z{% endcode %}
</li>
<li>
<a href="https://code.angularjs.org/">code.angularjs.org</a>
(discouraged for production use) e.g.
{% code %}"//code.angularjs.org/X.Y.Z/{$ doc.packageFile $}"{% endcode %}
</li>
</ul>
<p>where X.Y.Z is the AngularJS version you are running.</p>
<p>Then, include {$ doc.packageFile | code $} in your HTML:</p>
{% code %}
<script src="path/to/angular.js"></script>
<script src="path/to/{$ doc.packageFile $}"></script>
{% endcode %}
<p>Finally, load the module in your application by adding it as a dependent module:</p>
{% code %}
angular.module('app', ['{$ doc.name $}']);
{% endcode %}
<p>With that you&apos;re ready to get started!</p>
{% endif %}
{$ doc.description | marked $}
{% if doc.knownIssueDocs %}
<div class="known-issues">
<h2 id="known-issues">Known Issues</h2>
<table class="definition-table">
<tr><th>Name</th><th>Description</th></tr>
{% for issueDoc in doc.knownIssueDocs -%}
<tr>
<td>{$ issueDoc.id | link(issueDoc.name, issueDoc) $}</td>
<td>
{% for issue in issueDoc.knownIssues -%}
{$ issue | marked $} {% if not loop.last %}<hr>{% endif %}
{% endfor -%}
</td>
</tr>
{% endfor -%}
</table>
</div>
{% endif %}
{% if doc.componentGroups.length %}
<div class="component-breakdown">
<h2>Module Components</h2>
{% for componentGroup in doc.componentGroups %}
<div>
<h3 class="component-heading" id="{$ componentGroup.groupType | dashCase $}">{$ componentGroup.groupType | title $}</h3>
<table class="definition-table">
<tr>
<th>Name</th>
<th>Description</th>
</tr>
{% for component in componentGroup.components %}
<tr>
<td>{$ component.id | link(component.name, component) $}</td>
<td>{$ component.description | firstParagraph | marked $}</td>
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
</div>
{% endif %}
{% if doc.usage %}
<h2>Usage</h2>
{$ doc.usage | marked $}
{% endif %}
{% endblock %}
+12 -12
View File
@@ -90,7 +90,7 @@
<li class="disabled"><a href="http://angularjs.org/">Why AngularJS?</a></li>
<li><a href="http://www.youtube.com/user/angularjs">Watch</a></li>
<li><a href="tutorial">Tutorial</a></li>
<li><a href="http://builtwith.angularjs.org/">Case Studies</a></li>
<li><a href="https://www.madewithangular.com/">Case Studies</a></li>
<li><a href="https://github.com/angular/angular-seed">Seed App project template</a></li>
<li><a href="misc/faq">FAQ</a></li>
</ul>
@@ -147,13 +147,13 @@
<div class="search-results-container" ng-show="hasResults">
<div class="container">
<div class="search-results-frame">
<div ng-repeat="(key, value) in results" class="search-results-group" ng-class="colClassName + ' col-group-' + key">
<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>
<div class="search-results">
<div ng-repeat="item in value" class="search-result">
- <a ng-click="hideResults()" ng-href="{{ item.path }}">{{ item.name }}</a>
</div>
</div>
<ul class="search-results">
<!-- Do not insert a line break between li and a. Chrome will insert an actual line-break, which breaks the list item view.
TODO: use a html minifier instead -->
<li ng-repeat="item in value" class="search-result"><a ng-click="hideResults()" ng-href="{{ item.path }}">{{ item.name }}</a></li>
</ul>
</div>
</div>
<a href="" ng-click="hideResults()" class="search-close">
@@ -220,7 +220,7 @@
<p class="pull-right"><a back-to-top>Back to top</a></p>
<p>
Super-powered by Google ©2010-2015
Super-powered by Google ©2010-2016
( <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">
@@ -228,10 +228,10 @@
)
</p>
<p>
Code licensed under the
<a href="https://github.com/angular/angular.js/blob/master/LICENSE" target="_blank">The
MIT License</a>. Documentation licensed under <a
href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.
Code licensed under
<a href="https://github.com/angular/angular.js/blob/master/LICENSE" target="_blank">The MIT License</a>.
Documentation licensed under
<a href="http://creativecommons.org/licenses/by/3.0/" target="_blank">CC BY 3.0</a>.
</p>
</div>
</footer>
@@ -1,10 +1,8 @@
{# Be aware that we need these extra new lines here or marked will not realise that the <div>
{# Be aware that we need these extra new lines here or marked will not realize that the <div>
is HTML and wrap each line in a <p> - thus breaking the HTML #}
<div>
<a ng-click="openPlunkr('{$ doc.path $}', $event)" class="btn pull-right">
<i class="glyphicon glyphicon-edit">&nbsp;</i>
Edit in Plunker</a>
<plnkr-opener example-path="{$ doc.path $}"></plnkr-opener>
<div class="runnable-example"
path="{$ doc.example.deployments.default.path $}"
@@ -24,5 +22,5 @@
</div>
</div>
{# Be aware that we need these extra new lines here or marked will not realise that the <div>
{# Be aware that we need these extra new lines here or marked will not realize that the <div>
above is HTML and wrap each line in a <p> - thus breaking the HTML #}
+2
View File
@@ -8,6 +8,8 @@ Welcome to the AngularJS API docs page. These pages contain the AngularJS refere
The documentation is organized into **{@link guide/module modules}** which contain various components of an AngularJS application.
These components are {@link guide/directive directives}, {@link guide/services services}, {@link guide/filter filters}, {@link guide/providers providers}, {@link guide/templates templates}, global APIs, and testing mocks.
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 `$$`**:
+3 -3
View File
@@ -1,8 +1,8 @@
@ngdoc error
@name $compile:baddir
@fullName Invalid Directive Name
@fullName Invalid Directive/Component Name
@description
This error occurs when the name of a directive is not valid.
This error occurs when the name of a directive or component is not valid.
Directives must start with a lowercase character and must not contain leading or trailing whitespaces.
Directives and Components must start with a lowercase character and must not contain leading or trailing whitespaces.
+1 -1
View File
@@ -8,7 +8,7 @@ but the required directive controller is not present on the current DOM element
To resolve this error ensure that there is no typo in the required controller name and that the required directive controller is present on the current element.
If the required controller is expected to be on a ancestor element, make sure that you prefix the controller name in the `require` definition with `^`.
If the required controller is expected to be on an ancestor element, make sure that you prefix the controller name in the `require` definition with `^`.
If the required controller is optionally requested, use `?` or `^?` to specify that.
+30
View File
@@ -0,0 +1,30 @@
@ngdoc error
@name $compile:infchng
@fullName Unstable `$onChanges` hooks
@description
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.
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:
```html
<c1 prop="a" on-change="a = -a"></c1>
```
```js
function Controller1() {}
Controller1.$onChanges = function() {
this.onChange();
};
mod.component('c1', {
controller: Controller1,
bindings: {'prop': '<', onChange: '&'}
}
```
The maximum number of allowed iterations of the `$onChanges` hooks is controlled via TTL setting which can be configured via
{@link ng.$compileProvider#onChangesTtl `$compileProvider.onChangesTtl`}.
+6 -4
View File
@@ -3,7 +3,7 @@
@fullName Invalid Isolate Scope Definition
@description
When declaring isolate scope the scope definition object must be in specific format which starts with mode character (`@&=`) with an optional local name.
When declaring isolate scope the scope definition object must be in specific format which starts with mode character (`@&=<`), after which comes an optional `?`, and it ends with an optional local name.
```
myModule.directive('directiveName', function factory() {
@@ -12,9 +12,11 @@ myModule.directive('directiveName', function factory() {
scope: {
'attrName': '@', // OK
'attrName2': '=localName', // OK
'attrName3': 'name', // ERROR: missing mode @&=
'attrName4': ' = name', // ERROR: extra spaces
'attrName5': 'name=', // ERROR: must be prefixed with @&=
'attrName3': '<?localName', // OK
'attrName4': ' = name', // OK
'attrName5': 'name', // ERROR: missing mode @&=
'attrName6': 'name=', // ERROR: must be prefixed with @&=
'attrName7': '=name?', // ERROR: ? must come directly after the mode
}
...
}
+47
View File
@@ -0,0 +1,47 @@
@ngdoc error
@name $compile:reqslot
@fullName Required transclusion slot
@description
This error occurs when a directive or component try to transclude a slot that is not provided.
Transcluded elements must contain something. This error could happen when you try to transclude a self closing tag element.
Also you can make a transclusion slot optional with a `?` prefix.
```js
// In this example the <my-component> must have an <important-component> inside to transclude it.
// If not, a reqslot error will be generated.
var componentConfig = {
template: 'path/to/template.html',
tranclude: {
importantSlot: 'importantComponent', // mandatory transclusion
optionalSlot: '?optionalComponent', // optional transclusion
}
};
angular
.module('doc')
.component('myComponent', componentConfig)
```
```html
<!-- Will not work because <important-component> is missing -->
<my-component>
</my-component>
<my-component>
<optional-component></optional-component>
</my-component>
<!-- Will work -->
<my-component>
<important-component></important-component>
</my-component>
<my-component>
<optional-component></optional-component>
<important-component></important-component>
</my-component>
```
+2 -2
View File
@@ -31,7 +31,7 @@ single root element, like the `div` element in this template:
<div><b>Hello</b> World!</div>
```
An an invalid template to be used with this directive is one that defines multiple root nodes or
An invalid template to be used with this directive is one that defines multiple root nodes or
elements. For example:
```
@@ -43,7 +43,7 @@ well. Consider the following template:
```
<div class='container'>
<div class='wrapper>
<div class='wrapper'>
...
</div> <!-- wrapper -->
</div> <!-- container -->
+1 -1
View File
@@ -11,7 +11,7 @@ Supported formats:
1. `__name__`
2. `__name__ as __identifier__`
N'either `__name__` or `__identifier__` may contain spaces.
Neither `__name__` or `__identifier__` may contain spaces.
Example of incorrect usage that leads to this error:
```html
+45
View File
@@ -0,0 +1,45 @@
@ngdoc error
@name $http:legacy
@fullName The `success` and `error` methods on the promise returned from `$http` have been disabled.
@description
This error occurs when the legacy promise extensions (`success` and `error`)
{@link $httpProvider#useLegacyPromiseExtensions legacy `$http` promise extensions} have been disabled.
To resolve this error, either turn on the legacy extensions by adding
`$httpProvider.useLegacyPromiseExtensions(true);` to your application's configuration; or refactor you
use of `$http` to use `.then()` rather than `.success()` and `.error()`.
For example if you code looked like this:
```js
// Simple GET request example :
$http.get('/someUrl').
success(function(data, status, headers, config) {
// This callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
```
then you would change it to look like:
```js
// Simple GET request example :
$http.get('/someUrl').
then(function(response) {
// (The response object contains the data, status, headers and config properties)
// This callback will be called asynchronously
// when the response is available.
}, function(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
```
For more information, see the
{@link $httpProvider#useLegacyPromiseExtensions `$httpProvider.useLegacyPromiseExtensions`}
documentation.
+4 -1
View File
@@ -6,6 +6,9 @@
This error occurs when a module fails to load due to some exception. The error
message above should provide additional context.
A common reason why the module fails to load is that you've forgotten to
include the file with the defined module or that the file couldn't be loaded.
### Using `ngRoute`
In AngularJS `1.2.0` and later, `ngRoute` has been moved to its own module.
@@ -24,4 +27,4 @@ angular.module('ng').filter('tel', function (){});
Instead create your own module and add it as a dependency to your application's top-level module.
See [#9692](https://github.com/angular/angular.js/issues/9692) and
[#7709](https://github.com/angular/angular.js/issues/7709) for more information
[#7709](https://github.com/angular/angular.js/issues/7709) for more information
+3
View File
@@ -81,3 +81,6 @@ angular.module('myModule', [])
// a scope object cannot be injected into a service.
}]);
```
If you encounter this error only with minified code, consider using `ngStrictDi` (see
{@link ng.directive:ngApp ngApp}) to provoke the error with the non-minified source.
+2 -2
View File
@@ -1,6 +1,6 @@
@ngdoc error
@name $location:nobase
@fullName $location in HTML5 mode requires a <base> tag to be present!
@fullName $location in HTML5 mode requires a &lt;base&gt; tag to be present!
@description
If you configure {@link ng.$location `$location`} to use
@@ -15,7 +15,7 @@ $locationProvider.html5Mode({
});
```
Note that removing the requirement for a <base> tag will have adverse side effects when resolving
Note that removing the requirement for a `<base>` tag will have adverse side effects when resolving
relative paths with `$location` in IE9.
The base URL is then used to resolve all relative URLs throughout the application regardless of the
@@ -14,3 +14,32 @@ perform this check - it's up to the developer to not expose such sensitive and p
directly on the scope chain.
To resolve this error, avoid Window access.
### Common CoffeeScript Issue
Be aware that if you are using CoffeeScript, it automatically returns the value of the last statement in a
function. So for instance
```coffeescript
scope.foo = ->
window.open 'https://example.com'
```
compiles to something like
```js
scope.foo = function() {
return window.open('https://example.com');
};
```
You can see that this function will return the result of calling `window.open`, which is a `Window`
object.
You can avoid this by explicitly returning something else from the function:
```coffeescript
scope.foo = ->
window.open 'https://example.com'
return true;
```
+3 -3
View File
@@ -100,7 +100,7 @@ To resolve this type of issue, either fix the api to be always synchronous or as
your callback handler to always run asynchronously by using the `$timeout` service.
```
function MyController($scope, thirdPartyComponent) {
function MyController($scope, $timeout, thirdPartyComponent) {
thirdPartyComponent.getData(function(someData) {
$timeout(function() {
$scope.someData = someData;
@@ -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 a
by using `$timeout(fn, 0, false)`, where the `false` value tells Angular not to wrap this `fn` in an
`$apply` block:
```
@@ -200,7 +200,7 @@ the top of the call stack.
Once you have identified this call you work your way up the stack to see what the problem is.
* If the second call was made in your application code then you should look at why this code has been
called from within a `$apply`/`$digest`. It may be a simple oversight or maybe it fits with the
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
@@ -1,11 +0,0 @@
@ngdoc error
@name $sanitize:badparse
@fullName Parsing Error while Sanitizing
@description
This error occurs when the HTML string passed to '$sanitize' can't be parsed by the sanitizer.
The error contains part of the html string that can't be parsed.
The parser is more strict than a typical browser parser, so it's possible that some obscure input would produce this error despite the string being recognized as valid HTML by a browser.
If a valid html code results in this error, please file a bug.
@@ -0,0 +1,10 @@
@ngdoc error
@name $sanitize:noinert
@fullName Can't create an inert html document
@description
This error occurs when `$sanitize` sanitizer determines that `document.implementation.createHTMLDocument ` api is not supported by the current browser.
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.
+13
View File
@@ -0,0 +1,13 @@
@ngdoc error
@name $sanitize:uinput
@fullName Failed to sanitize html because the input is unstable
@description
This error occurs when `$sanitize` sanitizer tries to check the input for possible mXSS payload and the verification
errors due to the input mutating indefinitely. This could be a sign that the payload contains code exploiting an mXSS
vulnerability in the browser.
mXSS attack exploit browser bugs that cause some browsers parse a certain html strings into DOM, which once serialized
doesn't match the original input. These browser bugs can be exploited by attackers to create payload which looks
harmless to sanitizers, but due to mutations caused by the browser are turned into dangerous code once processed after
sanitization.
+16
View File
@@ -0,0 +1,16 @@
@ngdoc error
@name linky:notstring
@fullName Not a string
@description
This error occurs when {@link ngSanitize.linky linky} is used with a non-empty, non-string value:
```html
<div ng-bind-html="42 | linky"></div>
```
`linky` is supposed to be used with string values only, and therefore assumes that several methods
(such as `.match()`) are available on the passed in value.
The value can be initialized asynchronously and therefore null or undefined won't throw this error.
If you want to pass non-string values to `linky` (e.g. Objects whose `.toString()` should be
utilized), you need to manually convert them to strings.
@@ -0,0 +1,28 @@
@ngdoc error
@name ngModel:nopromise
@fullName No promise
@description
The return value of an async validator, must always be a promise. If you want to return a
non-promise value, you can convert it to a promise using {@link ng.$q#resolve `$q.resolve()`} or
{@link ng.$q#reject `$q.reject()`}.
Example:
```
.directive('asyncValidator', function($q) {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ngModel) {
ngModel.$asyncValidators.myAsyncValidation = function(modelValue, viewValue) {
if (/* I don't need to hit the backend API */) {
return $q.resolve(); // to mark as valid or
// return $q.reject(); // to mark as invalid
} else {
// ...send a request to the backend and return a promise
}
};
}
};
})
```
@@ -1,33 +0,0 @@
@ngdoc error
@name ngOptions:trkslct
@fullName Comprehension expression cannot contain both `select as` and `track by` expressions.
@description
NOTE: This error was introduced in 1.3.0-rc.5, and was removed for 1.3.0-rc.6 in order to
not break existing apps.
This error occurs when 'ngOptions' is passed a comprehension expression that contains both a
`select as` expression and a `track by` expression. These two expressions are fundamentally
incompatible.
* Example of bad expression: `<select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected">`
`values: [{id: 1, label: 'aLabel', subItem: {name: 'aSubItem'}}, {id: 2, label: 'bLabel', subItem: {name: 'bSubItem'}}]`,
`$scope.selected = {name: 'aSubItem'};`
* track by is always applied to `value`, with purpose to preserve the selection,
(to `item` in this case)
* To calculate whether an item is selected, `ngOptions` does the following:
1. apply `track by` to the values in the array:
In the example: [1,2]
2. apply `track by` to the already selected value in `ngModel`:
In the example: this is not possible, as `track by` refers to `item.id`, but the selected
value from `ngModel` is `{name: aSubItem}`.
Here's an example of how to make this example work by using `track by` without `select as`:
```
<select ng-model="selected" ng-options="item.label for item in values track by item.id">
```
Note: This would store the whole `item` as the model to `scope.selected` instead of `item.subItem`.
For more information on valid expression syntax, see 'ngOptions' in {@link ng.directive:select select} directive docs.
+52
View File
@@ -0,0 +1,52 @@
@ngdoc error
@name orderBy:notarray
@fullName Value is not array-like
@description
This error occurs when {@link ng.orderBy orderBy} is not passed an array-like value:
```html
<div ng-repeat="(key, value) in myObj | orderBy:someProp">
{{ key }} : {{ value }}
</div>
```
`orderBy` must be used with an array-like value so a subset of items can be returned.
The array can be initialized asynchronously and therefore `null` or `undefined` won't throw this error.
To use `orderBy` to order the properties of an object, you can create your own array based on that object:
```js
angular.module('aModule', [])
.controller('aController', function($scope) {
var myObj = {
one: {id: 1, name: 'Some thing'},
two: {id: 2, name: 'Another thing'},
three: {id: 3, name: 'A third thing'}
};
$scope.arrFromMyObj = Object.keys(myObj).map(function(key) {
return myObj[key];
});
});
```
That can be used as:
```html
<label>
Order by:
<select ng-model="orderProp" ng-options="prop for prop in ['id', 'name']"></select>
</label>
<div ng-repeat="item in arrFromMyObj | orderBy:orderProp">
[{{ item.id }}] {{ item.name }}
</div>
```
You could as well convert the object to an array using a filter such as
[toArrayFilter](https://github.com/petebacondarwin/angular-toArrayFilter):
```html
<label>
Order by:
<select ng-model="orderProp" ng-options="prop for prop in ['id', 'name']"></select>
</label>
<div ng-repeat="item in myObj | toArray:false | orderBy:orderProp">
[{{ item.id }}] {{ item.name }}
</div>
```
+29 -12
View File
@@ -301,7 +301,7 @@ it('should show example', inject(
### Fallback for legacy browsers
For browsers that support the HTML5 history API, `$location` uses the HTML5 history API to write
path and search. If the history API is not supported by a browser, `$location` supplies a Hasbang
path and search. If the history API is not supported by a browser, `$location` supplies a Hashbang
URL. This frees you from having to worry about whether the browser viewing your app supports the
history API or not; the `$location` service makes this transparent to you.
@@ -330,8 +330,8 @@ reload to the original link.
### Relative links
Be sure to check all relative links, images, scripts etc. Angular requires you to specify the url
base in the head of your main html file (`<base href="/my-base">`) unless `html5Mode.requireBase` is
set to `false` in the html5Mode definition object passed to `$locationProvider.html5Mode()`. With
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
document was different.
@@ -339,6 +339,7 @@ There is one exception: Links that only contain a hash fragment (e.g. `<a href="
will only change `$location.hash()` and not modify the url otherwise. This is useful for scrolling
to anchors on the same page without needing to know on which page the user currently is.
### Server side
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
@@ -346,6 +347,20 @@ to entry point of your application (e.g. index.html). Requiring a `<base>` tag i
this case, as it allows Angular 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
The `$location` service is not able to function properly if the current URL is outside the URL given
as the base href. This can have subtle confusing consequences...
Consider a base href set as follows: `<base href="/base/">` (i.e. the application exists in the "folder"
called `/base`). The URL `/base` is actually outside the application (it refers to the `base` file found
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/`.
See https://github.com/angular/angular.js/issues/14018 for more information.
### Sending links among different browsers
Because of rewriting capability in HTML5 mode, your users will be able to open regular url links in
@@ -356,15 +371,15 @@ legacy browsers and hashbang links in modern browser:
### Example
Here you can see two `$location` instances, both in **Html5 mode**, but on different browsers, so
that you can see the differences. These `$location` services are connected to a fake browsers. Each
input represents the address bar of the browser.
Here you can see two `$location` instances that show the difference between **Html5 mode** and **Html5 Fallback mode**.
Note that to simulate different levels of browser support, the `$location` instances are connected to
a fakeBrowser service, which you don't have to set up in actual projects.
Note that when you type hashbang url into first browser (or vice versa) it doesn't rewrite /
Note that when you type hashbang url into the first browser (or vice versa) it doesn't rewrite /
redirect to regular / hashbang url, as this conversion happens only during parsing the initial URL
= on page reload.
In these examples we use `<base href="/base/index.html" />`
In these examples we use `<base href="/base/index.html" />`. The inputs represent the address bar of the browser.
#### Browser in HTML5 mode
<example module="html5-mode" name="location-html5-mode">
@@ -389,6 +404,7 @@ In these examples we use `<base href="/base/index.html" />`
<file name="app.js">
angular.module('html5-mode', ['fake-browser', 'address-bar'])
// Configure the fakeBrowser. Do not set these values in actual projects.
.constant('initUrl', 'http://www.example.com/base/path?a=b#h')
.constant('baseHref', '/base/index.html')
.value('$sniffer', { history: true })
@@ -538,6 +554,7 @@ In these examples we use `<base href="/base/index.html" />`
<file name="app.js">
angular.module('hashbang-mode', ['fake-browser', 'address-bar'])
// Configure the fakeBrowser. Do not set these values in actual projects.
.constant('initUrl', 'http://www.example.com/base/index.html#!/path?a=b#h')
.constant('baseHref', '/base/index.html')
.value('$sniffer', { history: false })
@@ -769,8 +786,8 @@ then uses the information it obtains to compose hashbang URLs (such as
</tr>
<tr class="head">
<td>Navigation outside the app</td>
<td>Use lower level API</td>
<th>Navigation outside the app</td>
<th>Use lower level API</td>
</tr>
<tr>
@@ -784,8 +801,8 @@ then uses the information it obtains to compose hashbang URLs (such as
</tr>
<tr class="head">
<td>Read access</td>
<td>Change to</td>
<th>Read access</td>
<th>Change to</td>
</tr>
<tr>
+169 -142
View File
@@ -10,7 +10,7 @@ The goal of ngAria is to improve Angular's default accessibility by enabling com
[ARIA](http://www.w3.org/TR/wai-aria/) attributes that convey state or semantic information for
assistive technologies used by persons with disabilities.
##Including ngAria
## Including ngAria
Using {@link ngAria ngAria} is as simple as requiring the ngAria module in your application. ngAria hooks into
standard AngularJS directives and quietly injects accessibility support into your application
@@ -20,19 +20,23 @@ at runtime.
angular.module('myApp', ['ngAria'])...
```
###Using ngAria
### Using ngAria
Most of what ngAria does is only visible "under the hood". To see the module in action, once you've
added it as a dependency, you can test a few things:
* Using your favorite element inspector, look for ngAria attributes in your own code.
* Using your favorite element inspector, look for attributes added by ngAria in your own code.
* Test using your keyboard to ensure `tabindex` is used correctly.
* Fire up a screen reader such as VoiceOver to listen for ARIA support.
* Fire up a screen reader such as VoiceOver or NVDA to check for ARIA support.
[Helpful screen reader tips.](http://webaim.org/articles/screenreader_testing/)
##Supported directives
## Supported directives
Currently, ngAria interfaces with the following directives:
* {@link guide/accessibility#ngmodel ngModel}
* {@link guide/accessibility#ngdisabled ngDisabled}
* {@link guide/accessibility#ngrequired ngRequired}
* {@link guide/accessibility#ngreadonly ngReadonly}
* {@link guide/accessibility#ngvaluechecked ngChecked}
* {@link guide/accessibility#ngvaluechecked ngValue}
* {@link guide/accessibility#ngshow ngShow}
* {@link guide/accessibility#nghide ngHide}
* {@link guide/accessibility#ngclick ngClick}
@@ -41,8 +45,8 @@ Currently, ngAria interfaces with the following directives:
<h2 id="ngmodel">ngModel</h2>
Most of ngAria's heavy lifting happens in the {@link ngModel ngModel}
directive. For elements using ngModel, special attention is paid by ngAria if that element also
Much of ngAria's heavy lifting happens in the {@link ng.ngModel ngModel}
directive. For elements using ngModel, special attention is paid by ngAria if that element also
has a role or type of `checkbox`, `radio`, `range` or `textbox`.
For those elements using ngModel, ngAria will dynamically bind and update the following ARIA
@@ -54,12 +58,62 @@ attributes (if they have not been explicitly specified by the developer):
* aria-valuenow
* aria-invalid
* aria-required
* aria-readonly
###Example
### Example
<example module="ngAria_ngModelExample" deps="angular-aria.js">
<file name="index.html">
<style>
<file name="index.html">
<form ng-controller="formsController">
<some-checkbox role="checkbox" ng-model="checked" ng-class="{active: checked}"
ng-disabled="isDisabled" ng-click="toggleCheckbox()"
aria-label="Custom Checkbox" show-attrs>
<span class="icon" aria-hidden="true"></span>
Custom Checkbox
</some-checkbox>
</form>
</file>
<file name="script.js">
var app = angular.module('ngAria_ngModelExample', ['ngAria'])
.controller('formsController', function($scope){
$scope.checked = false;
$scope.toggleCheckbox = function(){
$scope.checked = !$scope.checked;
};
})
.directive('someCheckbox', function(){
return {
restrict: 'E',
link: function($scope, $el, $attrs) {
$el.on('keypress', function(event){
event.preventDefault();
if(event.keyCode === 32 || event.keyCode === 13){
$scope.toggleCheckbox();
$scope.$apply();
}
});
}
};
})
.directive('showAttrs', function() {
return function($scope, $el, $attrs) {
var pre = document.createElement('pre');
$el.after(pre);
$scope.$watch(function() {
var $attrs = {};
Array.prototype.slice.call($el[0].attributes, 0).forEach(function(item) {
if (item.name !== 'show-$attrs') {
$attrs[item.name] = item.value;
}
});
return $attrs;
}, function(newAttrs, oldAttrs) {
pre.textContent = JSON.stringify(newAttrs, null, 2);
}, true);
};
});
</file>
<file name="style.css">
[role=checkbox] {
cursor: pointer;
display: inline-block;
@@ -78,93 +132,101 @@ attributes (if they have not been explicitly specified by the developer):
pre {
white-space: pre-wrap;
}
</style>
<div>
<form ng-controller="formsController">
<some-checkbox role="checkbox" ng-model="checked" ng-class="{active: checked}"
ng-disabled="isDisabled" ng-click="toggleCheckbox()"
aria-label="Custom Checkbox" show-attrs>
<span class="icon" aria-hidden="true"></span>
Custom Checkbox
</some-checkbox>
</form>
</div>
<script>
var app = angular.module('ngAria_ngModelExample', ['ngAria'])
.controller('formsController', function($scope){
$scope.checked = false;
$scope.toggleCheckbox = function(){
$scope.checked = !$scope.checked;
}
})
.directive('someCheckbox', function(){
return {
restrict: 'E',
link: function($scope, $el, $attrs) {
$el.on('keypress', function(event){
event.preventDefault();
if(event.keyCode === 32 || event.keyCode === 13){
$scope.toggleCheckbox();
$scope.$apply();
}
});
}
}
})
.directive('showAttrs', function() {
return function($scope, $el, $attrs) {
var pre = document.createElement('pre');
$el.after(pre);
$scope.$watch(function() {
var $attrs = {};
Array.prototype.slice.call($el[0].attributes, 0).forEach(function(item) {
if (item.name !== 'show-$attrs') {
$attrs[item.name] = item.value;
}
});
return $attrs;
}, function(newAttrs, oldAttrs) {
pre.textContent = JSON.stringify(newAttrs, null, 2);
}, true);
}
});
</script>
</file>
</file>
</example>
ngAria will also add `tabIndex`, ensuring custom elements with these roles will be reachable from
the keyboard. It is still up to **you** as a developer to **ensure custom controls will be
operable** from the keybard. Think of `ng-click` on a `<div>` or `<md-checkbox>`: you still need
to bind `ng-keypress` to make it fully operable from the keyboard. As a rule, any time you create
a widget involving user interaction, be sure to test it with your keyboard and at least one mobile
and desktop screen reader (preferably more).
accessible**. As a rule, any time you create a widget involving user interaction, be sure to test
it with your keyboard and at least one mobile and desktop screen reader.
<h2 id="ngdisabled">ngDisabled</h2>
<h2 id="ngvaluechecked">ngValue and ngChecked</h2>
The `disabled` attribute is only valid for certain elements such as `button`, `input` and
`textarea`. To properly disable custom element directives such as `<md-checkbox>` or `<taco-tab>`,
using ngAria with [ngDisabled](https://docs.angularjs.org/api/ng/directive/ngDisabled) will also
add `aria-disabled`. This tells assistive technologies when a non-native input is disabled, helping
custom controls to be more accessible.
To ease the transition between native inputs and custom controls, ngAria now supports
{@link ng.ngValue ngValue} and {@link ng.ngChecked ngChecked}.
The original directives were created for native inputs only, so ngAria extends
support to custom elements by managing `aria-checked` for accessibility.
###Example
### Example
```html
<md-checkbox ng-disabled="disabled">
<custom-checkbox ng-checked="val"></custom-checkbox>
<custom-radio-button ng-value="val"></custom-radio-button>
```
Becomes:
```html
<md-checkbox disabled aria-disabled="true">
<custom-checkbox ng-checked="val" aria-checked="true"></custom-checkbox>
<custom-radio-button ng-value="val" aria-checked="true"></custom-radio-button>
```
>You can check whether a control is legitimately disabled for a screen reader by visiting
[chrome://accessibility](chrome://accessibility).
<h2 id="ngdisabled">ngDisabled</h2>
The `disabled` attribute is only valid for certain elements such as `button`, `input` and
`textarea`. To properly disable custom element directives such as `<md-checkbox>` or `<taco-tab>`,
using ngAria with {@link ng.ngDisabled ngDisabled} will also
add `aria-disabled`. This tells assistive technologies when a non-native input is disabled, helping
custom controls to be more accessible.
### Example
```html
<md-checkbox ng-disabled="disabled"></md-checkbox>
```
Becomes:
```html
<md-checkbox disabled aria-disabled="true"></md-checkbox>
```
<div class="alert alert-info">
You can check whether a control is legitimately disabled for a screen reader by visiting
[chrome://accessibility](chrome://accessibility) and inspecting [the accessibility tree](http://www.paciellogroup.com/blog/2015/01/the-browser-accessibility-tree/).
</div>
<h2 id="ngrequired">ngRequired</h2>
The boolean `required` attribute is only valid for native form controls such as `input` and
`textarea`. To properly indicate custom element directives such as `<md-checkbox>` or `<custom-input>`
as required, using ngAria with {@link ng.ngRequired ngRequired} will also add
`aria-required`. This tells accessibility APIs when a custom control is required.
### Example
```html
<md-checkbox ng-required="val"></md-checkbox>
```
Becomes:
```html
<md-checkbox ng-required="val" aria-required="true"></md-checkbox>
```
<h2 id="ngreadonly">ngReadonly</h2>
The boolean `readonly` attribute is only valid for native form controls such as `input` and
`textarea`. To properly indicate custom element directives such as `<md-checkbox>` or `<custom-input>`
as required, using ngAria with {@link ng.ngReadonly ngReadonly} will also add
`aria-readonly`. This tells accessibility APIs when a custom control is read-only.
### Example
```html
<md-checkbox ng-readonly="val"></md-checkbox>
```
Becomes:
```html
<md-checkbox ng-readonly="val" aria-readonly="true"></md-checkbox>
```
<h2 id="ngshow">ngShow</h2>
>The [ngShow](https://docs.angularjs.org/api/ng/directive/ngShow) directive shows or hides the
The {@link ng.ngShow ngShow} directive shows or hides the
given HTML element based on the expression provided to the `ngShow` attribute. The element is
shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
@@ -181,7 +243,7 @@ screen reader users won't accidentally focus on "mystery elements". Managing tab
child control can be complex and affect performance, so its best to just stick with the default
`display: none` CSS. See the [fourth rule of ARIA use](http://www.w3.org/TR/aria-in-html/#fourth-rule-of-aria-use).
###Example
### Example
```css
.ng-hide {
display: block;
@@ -201,7 +263,7 @@ Becomes:
<h2 id="nghide">ngHide</h2>
>The [ngHide](https://docs.angularjs.org/api/ng/directive/ngHide) directive shows or hides the
The {@link ng.ngHide ngHide} directive shows or hides the
given HTML element based on the expression provided to the `ngHide` attribute. The element is
shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
@@ -210,16 +272,25 @@ The default CSS for `ngHide`, the inverse method to `ngShow`, makes ngAria redun
`display: none`. See explanation for {@link guide/accessibility#ngshow ngShow} when overriding the default CSS.
<h2><span id="ngclick">ngClick</span> and <span id="ngdblclick">ngDblclick</span></h2>
If `ng-click` or `ng-dblclick` is encountered, ngAria will add `tabindex="0"` if it isn't there
already.
If `ng-click` or `ng-dblclick` is encountered, ngAria will add `tabindex="0"` to any element not in
a node blacklist:
To fix widespread accessibility problems with `ng-click` on div elements, ngAria will dynamically
bind keypress by default as long as the element isn't an anchor, button, input or textarea.
You can turn this functionality on or off with the `bindKeypress` configuration option. ngAria
will also add the `button` role to communicate to users of assistive technologies.
* Button
* Anchor
* Input
* Textarea
* Select
* Details/Summary
For `ng-dblclick`, you must still manually add `ng-keypress` and role to non-interactive elements such
as `div` or `taco-button` to enable keyboard access.
To fix widespread accessibility problems with `ng-click` on `div` elements, ngAria will
dynamically bind a keypress event by default as long as the element isn't in the node blacklist.
You can turn this functionality on or off with the `bindKeypress` configuration option.
ngAria will also add the `button` role to communicate to users of assistive technologies. This can
be disabled with the `bindRoleForClick` configuration option.
For `ng-dblclick`, you must still manually add `ng-keypress` and a role to non-interactive elements
such as `div` or `taco-button` to enable keyboard access.
<h3>Example</h3>
```html
@@ -233,11 +304,11 @@ Becomes:
<h2 id="ngmessages">ngMessages</h2>
The new ngMessages module makes it easy to display form validation or other messages with priority
The ngMessages module makes it easy to display form validation or other messages with priority
sequencing and animation. To expose these visual messages to screen readers,
ngAria injects `aria-live="assertive"`, causing them to be read aloud any time a message is shown,
regardless of the user's focus location.
###Example
### Example
```html
<div ng-messages="myForm.myName.$error">
@@ -255,67 +326,23 @@ Becomes:
</div>
```
##Disabling attributes
## Disabling attributes
The attribute magic of ngAria may not work for every scenario. To disable individual attributes,
you can use the {@link ngAria.$ariaProvider#config config} method. Just keep in mind this will
tell ngAria to ignore the attribute globally.
<example module="ngAria_ngDisabledExample" deps="angular-aria.js">
<example module="ngAria_ngClickExample" deps="angular-aria.js">
<file name="index.html">
<style>
[role=checkbox] {
cursor: pointer;
display: inline-block;
}
[role=checkbox] .icon:before {
content: '\2610';
display: inline-block;
font-size: 2em;
line-height: 1;
vertical-align: middle;
speak: none;
}
[role=checkbox].active .icon:before {
content: '\2611';
}
</style>
<form ng-controller="formsController">
<div ng-model="someModel" show-attrs>
Div with ngModel and aria-invalid disabled
<div ng-click="someFunction" show-attrs>
&lt;div&gt; with ng-click and bindRoleForClick, tabindex set to false
</div>
<div role="checkbox" ng-model="checked" ng-class="{active: checked}"
aria-label="Custom Checkbox" ng-click="toggleCheckbox()" some-checkbox show-attrs>
<span class="icon" aria-hidden="true"></span>
Custom Checkbox for comparison
</div>
</form>
<script>
angular.module('ngAria_ngDisabledExample', ['ngAria'], function config($ariaProvider) {
angular.module('ngAria_ngClickExample', ['ngAria'], function config($ariaProvider) {
$ariaProvider.config({
ariaInvalid: false,
tabindex: true
bindRoleForClick: false,
tabindex: false
});
})
.controller('formsController', function($scope){
$scope.checked = false;
$scope.toggleCheckbox = function(){
$scope.checked = !$scope.checked;
}
})
.directive('someCheckbox', function(){
return {
restrict: 'A',
link: function($scope, $el, $attrs) {
$el.on('keypress', function(event){
event.preventDefault();
if(event.keyCode === 32 || event.keyCode === 13){
$scope.toggleCheckbox();
$scope.$apply();
}
});
}
}
})
.directive('showAttrs', function() {
return function(scope, el, attrs) {
var pre = document.createElement('pre');
@@ -337,7 +364,7 @@ tell ngAria to ignore the attribute globally.
</file>
</example>
##Common Accessibility Patterns
## Common Accessibility Patterns
Accessibility best practices that apply to web apps in general also apply to Angular.
+206 -41
View File
@@ -6,12 +6,19 @@
# Animations
AngularJS 1.3 provides animation hooks for common directives such as `ngRepeat`, `ngSwitch`, and `ngView`, as well as custom directives
AngularJS provides animation hooks for common directives such as `ngRepeat`, `ngSwitch`, and `ngView`, as well as custom directives
via the `$animate` service. These animation hooks are set in place to trigger animations during the life cycle of various directives and when
triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a JavaScript callback Animation (depending on if an animation is
placed on the given directive). Animations can be placed using vanilla CSS by following the naming conventions set in place by AngularJS
or with JavaScript code when it's defined as a factory.
<div class="alert alert-info">
Note that we have used non-prefixed CSS transition properties in our examples as the major browsers now support non-prefixed
properties. If you intend to support older browsers or certain mobile browsers then you will need to include prefixed
versions of the transition properties. Take a look at http://caniuse.com/#feat=css-transitions for what browsers require prefixes,
and https://github.com/postcss/autoprefixer for a tool that can automatically generate the prefixes for you.
</div>
Animations are not available unless you include the {@link ngAnimate `ngAnimate` module} as a dependency within your application.
Below is a quick example of animations being enabled for `ngShow` and `ngHide`:
@@ -29,18 +36,17 @@ Below is a quick example of animations being enabled for `ngShow` and `ngHide`:
</file>
<file name="animations.css">
.sample-show-hide {
padding:10px;
border:1px solid black;
background:white;
padding: 10px;
border: 1px solid black;
background: white;
}
.sample-show-hide {
-webkit-transition:all linear 0.5s;
transition:all linear 0.5s;
transition: all linear 0.5s;
}
.sample-show-hide.ng-hide {
opacity:0;
opacity: 0;
}
</file>
</example>
@@ -80,11 +86,8 @@ occur when ngRepeat triggers them:
class
*/
.repeated-item.ng-enter, .repeated-item.ng-move {
-webkit-transition:0.5s linear all;
-moz-transition:0.5s linear all;
-o-transition:0.5s linear all;
transition:0.5s linear all;
opacity:0;
transition: all 0.5s linear;
opacity: 0;
}
/*
@@ -95,7 +98,7 @@ occur when ngRepeat triggers them:
*/
.repeated-item.ng-enter.ng-enter-active,
.repeated-item.ng-move.ng-move-active {
opacity:1;
opacity: 1;
}
/*
@@ -104,10 +107,7 @@ occur when ngRepeat triggers them:
that has the .repeated-item class
*/
.repeated-item.ng-leave {
-webkit-animation:0.5s my_animation;
-moz-animation:0.5s my_animation;
-o-animation:0.5s my_animation;
animation:0.5s my_animation;
animation: 0.5s my_animation;
}
@keyframes my_animation {
@@ -115,24 +115,6 @@ occur when ngRepeat triggers them:
to { opacity:0; }
}
/*
Unfortunately each browser vendor requires
its own definition of keyframe animation code...
*/
@-webkit-keyframes my_animation {
from { opacity:1; }
to { opacity:0; }
}
@-moz-keyframes my_animation {
from { opacity:1; }
to { opacity:0; }
}
@-o-keyframes my_animation {
from { opacity:1; }
to { opacity:0; }
}
```
The same approach to animation can be used using JavaScript code (**jQuery is used within to perform animations**):
@@ -217,10 +199,7 @@ The example below shows how to perform animations during class changes:
</file>
<file name="style.css">
.css-class-add, .css-class-remove {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
.css-class,
@@ -231,7 +210,7 @@ The example below shows how to perform animations during class changes:
.css-class-remove.css-class-remove-active {
font-size:1.0em;
color:black;
color: black;
}
</file>
</example>
@@ -274,8 +253,194 @@ myModule.directive('my-directive', ['$animate', function($animate) {
}]);
```
## Animations on app bootstrap / page load
By default, animations are disabled when the Angular app {@link guide/bootstrap bootstraps}. If you are using the {@link ngApp} directive,
this happens in the `DOMContentLoaded` event, so immediately after the page has been loaded.
Animations are disabled, so that UI and content are instantly visible. Otherwise, with many animations on
the page, the loading process may become too visually overwhelming, and the performance may suffer.
Internally, `ngAnimate` waits until all template downloads that are started right after bootstrap have finished.
Then, it waits for the currently running {@link ng.$rootScope.Scope#$digest} and the one after that to finish.
This ensures that the whole app has been compiled fully before animations are attempted.
If you do want your animations to play when the app bootstraps, you can enable animations globally in
your main module's {@link angular.Module#run run} function:
```js
myModule.run(function($animate) {
$animate.enabled(true);
});
```
## How to (selectively) enable, disable and skip animations
There are three different ways to disable animations, both globally and for specific animations.
Disabling specific animations can help to speed up the render performance, for example for large `ngRepeat`
lists that don't actually have animations. Because ngAnimate checks at runtime if animations are present,
performance will take a hit even if an element has no animation.
### In the config: {@link $animateProvider#classNameFilter $animateProvider.classNameFilter()}
This function can be called in the {@link angular.Module#config config} phase of an app. It takes a regex as the only argument,
which will then be matched against the classes of any element that is about to be animated. The regex
allows a lot of flexibility - you can either allow animations only for specific classes (useful when
you are working with 3rd party animations), or exclude specific classes from getting animated.
```js
app.config(function($animateProvider) {
$animateProvider.classNameFilter(/animate-/);
});
```
```css
/&#42; prefixed with animate- &#42;/
.animate-fade-add.animate-fade-add-active {
transition: all 1s linear;
opacity: 0;
}
```
The classNameFilter approach generally applies the biggest speed boost, because the matching is
done before any other animation disabling strategies are checked. However, that also means it is not
possible to override class name matching with the two following strategies. It's of course still possible
to enable / disable animations by changing an element's class name at runtime.
### At runtime: {@link ng.$animate#enabled $animate.enabled()}
This function can be used to enable / disable animations in two different ways:
With a single `boolean` argument, it enables / disables animations globally: `$animate.enabled(false)`
disables all animations in your app.
When the first argument is a native DOM or jqLite/jQuery element, the function enables / disables
animations on this element *and all its children*: `$animate.enabled(myElement, false)`. This is the
most flexible way to change the animation state. For example, even if you have used it to disable
animations on a parent element, you can still re-enable it for a child element. And compared to the
`classNameFilter`, you can change the animation status at runtime instead of during the config phase.
Note however that the `$animate.enabled()` state for individual elements does not overwrite disabling
rules that have been set in the {@link $animateProvider#classNameFilter classNameFilter}.
### Via CSS styles: overwriting styles in the `ng-animate` CSS class
Whenever an animation is started, ngAnimate applies the `ng-animate` class to the element for the
whole duration of the animation. By applying CSS transition / animation styling to the class,
you can skip an animation:
```css
.my-class{
transition: transform 2s;
}
.my-class:hover {
transform: translateX(50px);
}
my-class.ng-animate {
transition: 0s;
}
```
By setting `transition: 0s`, ngAnimate will ignore the existing transition styles, and not try to animate them (Javascript
animations will still execute, though). This can be used to prevent {@link guide/animations#preventing-collisions-with-existing-animations-and-third-party-libraries
issues with existing animations interfering with ngAnimate}.
## Preventing flicker before an animation starts
When nesting elements with structural animations such as `ngIf` into elements that have class-based
animations such as `ngClass`, it sometimes happens that before the actual animation starts, there is a brief flicker or flash of content
where the animated element is briefly visible.
To prevent this, you can apply styles to the `ng-[event]-prepare` class, which is added as soon as an animation is initialized,
but removed before the actual animation starts (after waiting for a $digest). This class is only added for *structural*
animations (`enter`, `move`, and `leave`).
Here's an example where you might see flickering:
```html
<div ng-class="{red: myProp}">
<div ng-class="{blue: myProp}">
<div class="message" ng-if="myProp"></div>
</div>
</div>
```
It is possible that during the `enter` event, the `.message` div will be briefly visible before it starts animating.
In that case, you can add styles to the CSS that make sure the element stays hidden before the animation starts:
```css
.message.ng-enter-prepare {
opacity: 0;
}
/* Other animation styles ... */
```
## Preventing Collisions with Existing Animations and Third Party Libraries
By default, any `ngAnimate` enabled directives will assume any transition / animation styles on the
element are part of an `ngAnimate` animation. This can lead to problems when the styles are actually
for animations that are independent of `ngAnimate`.
For example, an element acts as a loading spinner. It has an inifinite css animation on it, and also an
{@link ngIf `ngIf`} directive, for which no animations are defined:
```css
@keyframes rotating {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
animation: rotating 2s linear infinite;
}
```
Now, when the `ngIf` changes, `ngAnimate` will see the spinner animation and use
it to animate the `enter`/`leave` event, which doesn't work because
the animation is infinite. The element will still be added / removed after a timeout, but there will be a
noticable delay.
This might also happen because some third-party frameworks place animation duration defaults
across many element or className selectors in order to make their code small and reuseable.
You can prevent this unwanted behavior by adding CSS to the `.ng-animate` class that is added
for the whole duration of an animation. Simply overwrite the transition / animation duration. In the
case of the spinner, this would be:
```css
.spinner.ng-animate {
transition: 0s none;
animation: 0s none;
}
```
If you do have CSS transitions / animations defined for the animation events, make sure they have higher priority
than any styles that are independent from ngAnimate.
You can also use one of the two other {@link guide/animations#how-to-selectively-enable-disable-and-skip-animations strategies to disable animations}.
### Enable animations for elements outside of the Angular application DOM tree: {@link ng.$animate#pin $animate.pin()}
Before animating, `ngAnimate` checks to see if the element being animated is inside the application DOM tree,
and if it is not, no animation is run. Usually, this is not a problem as most apps use the `ngApp`
attribute / bootstrap the app on the `html` or `body` element.
Problems arise when the application is bootstrapped on a different element, and animations are
attempted on elements that are outside the application tree, e.g. when libraries append popup and modal
elements as the last child in the body tag.
You can use {@link ng.$animate#pin `$animate.pin(elementToAnimate, parentHost)`} to specify that an
element belongs to your application. Simply call it before the element is added to the DOM / before
the animation starts, with the element you want to animate, and the element which should be its
assumed parent.
## More about animations
For a full breakdown of each method available on `$animate`, see the {@link ng.$animate API documentation}.
To see a complete demo, see the {@link tutorial/step_12 animation step within the AngularJS phonecat tutorial}.
To see a complete demo, see the {@link tutorial/step_14 animation step within the AngularJS phonecat tutorial}.
+14 -3
View File
@@ -53,13 +53,13 @@ initialization.
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
for the {@link ng.directive:ngApp `ng-app`} directive which designates your application root.
If the {@link ng.directive:ngApp `ng-app`} directive is found then Angular will:
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:
* 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
`ng-app`} directive as the root of the compilation. This allows you to tell it to treat only a
`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.
@@ -142,6 +142,17 @@ This is the sequence that your code should follow:
2. Call {@link angular.bootstrap} to {@link compiler compile} the element into an
executable, bi-directionally bound application.
## Things to keep in mind
There 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
caution is advised.
- Do not bootstrap your app on an element with a directive that uses {@link ng.$compile#transclusion transclusion}, such as
{@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.
Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
causing animations to stop working and making the injector inaccessible from outside the app.
## Deferred Bootstrap
File diff suppressed because it is too large Load Diff
+499
View File
@@ -0,0 +1,499 @@
@ngdoc overview
@name Components
@sortOrder 305
@description
# Understanding Components
In Angular, 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.
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
When not to use Components:
- for directives that rely on DOM manipulation, adding event listeners etc, because the compile
and link functions are unavailable
- when you need advanced directive definition options like priority, terminal, multi-element
- when you want a directive that is triggered by an attribute or CSS class, rather than an element
## 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:
* 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.)
<example name="heroComponentSimple" module="heroApp">
<file name="index.js">
angular.module('heroApp', []).controller('mainCtrl', function() {
this.hero = {
name: 'Spawn'
};
});
</file>
<file name="heroDetail.js">
function HeroDetailController() {
}
angular.module('heroApp').component('heroDetail', {
templateUrl: 'heroDetail.html',
controller: HeroDetailController,
bindings: {
hero: '='
}
});
</file>
<file name="index.html">
<!-- components match only elements -->
<div ng-controller="mainCtrl as ctrl">
<b>Hero</b><br>
<hero-detail hero="ctrl.hero"></hero-detail>
</div>
</file>
<file name="heroDetail.html">
<span>Name: {{$ctrl.hero.name}}</span>
</file>
</example>
It's also possible to add components via {@link $compileProvider#component} in a module's config phase.
### Comparison between Directive definition and Component definition
| | Directive | Component |
|-------------------|----------------------|-----------------|
| bindings | No | Yes (binds to controller) |
| bindToController | Yes (default: false) | No (use bindings instead) |
| compile function | Yes | No |
| controller | Yes | Yes (default `function() {}`) |
| controllerAs | Yes (default: false) | Yes (default: `$ctrl`) |
| link functions | Yes | No |
| multiElement | Yes | No |
| priority | Yes | No |
| require | Yes | Yes |
| restrict | Yes | No (restricted to elements only) |
| scope | Yes (default: false) | No (scope is always isolate) |
| template | Yes | Yes, injectable |
| templateNamespace | Yes | No |
| templateUrl | Yes | Yes, injectable |
| terminal | Yes | No |
| transclude | Yes (default: false) | Yes (default: false) |
## Component-based application architecture
As already mentioned, the component helper makes it easier to structure your application with
a component-based architecture. But what makes a component beyond the options that
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
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
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,
components should follow a few simple conventions:
- Inputs should be using `<` and `@` bindings. The `<` symbol denotes {@link $compile#-scope- one-way bindings} which are
available since 1.5. The difference to `=` is that the bound properties in the component scope are not watched, which means
if you assign a new value to the property in the component scope, it will not update the parent scope. Note however, that both parent
and component scope reference the same object, so if you are changing object properties or array elements in the
component, the parent will still reflect that change.
The general rule should therefore be to never change an object or array property in the component scope.
`@` bindings can be used when the input is a string, especially when the value of the binding doesn't change.
```js
bindings: {
hero: '<',
comment: '@'
}
```
- Outputs are realized with `&` bindings, which function as callbacks to component events.
```js
bindings: {
onDelete: '&',
onUpdate: '&'
}
```
- Instead of manipulating Input Data, the component calls the correct Output Event with the changed data.
For a deletion, that means the component doesn't delete the `hero` itself, but sends it back to
the owner component via the correct event.
```html
<!-- note that we use kebab-case for bindings in the template as usual -->
<editable-field on-update="$ctrl.update('location', value)"></editable-field><br>
<button ng-click="$ctrl.onDelete({hero: $ctrl.hero})">Delete</button>
```
- That way, the parent component can decide what to do with the event (e.g. delete an item or update the properties)
```js
ctrl.deleteHero(hero) {
$http.delete(...).then(function() {
var idx = ctrl.list.indexOf(hero);
if (idx >= 0) {
ctrl.list.splice(idx, 1);
}
});
}
```
- **Components have a well-defined lifecycle**
Each component can implement "lifecycle hooks". These are methods that will be called at certain points in the life
of the component. The following hook methods can be implemented:
* `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
had their bindings initialized (and before the pre &amp; post linking functions for the directives on
this element). This is a good place to put initialization code for your controller.
* `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
are the names of the bound properties that have changed, and the values are an object of the form
`{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a component such as
cloning the bound value to prevent accidental mutation of the outer value.
* `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
external resources, watches and event handlers.
* `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
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
be taken when upgrading.
By implementing these methods, your component can hook into its lifecycle.
- **An application is a tree of components:**
Ideally, the whole application should be a tree of components that implement clearly defined inputs
and outputs, and minimize two-way data binding. That way, it's easier to predict when data changes and what the state
of a component is.
## Example of a component tree
The following example expands on the simple component example and incorporates the concepts we introduced
above:
Instead of an ngController, we now have a heroList component that holds the data of
different heroes, and creates a heroDetail for each of them.
The heroDetail component now contains new functionality:
- a delete button that calls the bound `onDelete` function of the heroList component
- an input to change the hero location, in the form of a reusable editableField component. Instead
of manipulating the hero object itself, it sends a changeset upwards to the heroDetail, which sends
it upwards to the heroList component, which updates the original data.
<example name="heroComponentTree" module="heroApp">
<file name="index.js">
var mode = angular.module('heroApp', []);
</file>
<file name="heroList.js">
function HeroListController($scope, $element, $attrs) {
var ctrl = this;
// This would be loaded by $http etc.
ctrl.list = [
{
name: 'Superman',
location: ''
},
{
name: 'Batman',
location: 'Wayne Manor'
}
];
ctrl.updateHero = function(hero, prop, value) {
hero[prop] = value;
};
ctrl.deleteHero = function(hero) {
var idx = ctrl.list.indexOf(hero);
if (idx >= 0) {
ctrl.list.splice(idx, 1);
}
};
}
angular.module('heroApp').component('heroList', {
templateUrl: 'heroList.html',
controller: HeroListController
});
</file>
<file name="heroDetail.js">
function HeroDetailController() {
var ctrl = this;
ctrl.delete = function() {
ctrl.onDelete({hero: ctrl.hero});
};
ctrl.update = function(prop, value) {
ctrl.onUpdate({hero: ctrl.hero, prop: prop, value: value});
};
}
angular.module('heroApp').component('heroDetail', {
templateUrl: 'heroDetail.html',
controller: HeroDetailController,
bindings: {
hero: '<',
onDelete: '&',
onUpdate: '&'
}
});
</file>
<file name="editableField.js">
function EditableFieldController($scope, $element, $attrs) {
var ctrl = this;
ctrl.editMode = false;
ctrl.handleModeChange = function() {
if (ctrl.editMode) {
ctrl.onUpdate({value: ctrl.fieldValue});
ctrl.fieldValueCopy = ctrl.fieldValue;
}
ctrl.editMode = !ctrl.editMode;
};
ctrl.reset = function() {
ctrl.fieldValue = ctrl.fieldValueCopy;
};
ctrl.$onInit = function() {
// Make a copy of the initial value to be able to reset it later
ctrl.fieldValueCopy = ctrl.fieldValue;
// Set a default fieldType
if (!ctrl.fieldType) {
ctrl.fieldType = 'text';
}
};
}
angular.module('heroApp').component('editableField', {
templateUrl: 'editableField.html',
controller: EditableFieldController,
bindings: {
fieldValue: '<',
fieldType: '@?',
onUpdate: '&'
}
});
</file>
<file name="index.html">
<hero-list></hero-list>
</file>
<file name="heroList.html">
<b>Heroes</b><br>
<hero-detail ng-repeat="hero in $ctrl.list" hero="hero" on-delete="$ctrl.deleteHero(hero)" on-update="$ctrl.updateHero(hero, prop, value)"></hero-detail>
</file>
<file name="heroDetail.html">
<hr>
<div>
Name: {{$ctrl.hero.name}}<br>
Location: <editable-field field-value="$ctrl.hero.location" field-type="text" on-update="$ctrl.update('location', value)"></editable-field><br>
<button ng-click="$ctrl.delete()">Delete</button>
</div>
</file>
<file name="editableField.html">
<span ng-switch="$ctrl.editMode">
<input ng-switch-when="true" type="{{$ctrl.fieldType}}" ng-model="$ctrl.fieldValue">
<span ng-switch-default>{{$ctrl.fieldValue}}</span>
</span>
<button ng-click="$ctrl.handleModeChange()">{{$ctrl.editMode ? 'Save' : 'Edit'}}</button>
<button ng-if="$ctrl.editMode" ng-click="$ctrl.reset()">Reset</button>
</file>
</example>
## Components as route templates
Components are also useful as route templates (e.g. when using {@link ngRoute ngRoute}). In a component-based
application, every view is a component:
```js
var myMod = angular.module('myMod', ['ngRoute']);
myMod.component('home', {
template: '<h1>Home</h1><p>Hello, {{ $ctrl.user.name }} !</p>',
controller: function() {
this.user = {name: 'world'};
}
});
myMod.config(function($routeProvider) {
$routeProvider.when('/', {
template: '<home></home>'
});
});
```
<br />
When using {@link ngRoute.$routeProvider $routeProvider}, you can often avoid some
boilerplate, by passing the resolved route dependencies directly to the component. Since 1.5,
ngRoute automatically assigns the resolves to the route scope property `$resolve` (you can also
configure the property name via `resolveAs`). When using components, you can take advantage of this and pass resolves
directly into your component without creating an extra route controller:
```js
var myMod = angular.module('myMod', ['ngRoute']);
myMod.component('home', {
template: '<h1>Home</h1><p>Hello, {{ $ctrl.user.name }} !</p>',
bindings: {
user: '<'
}
});
myMod.config(function($routeProvider) {
$routeProvider.when('/', {
template: '<home user="$resolve.user"></home>',
resolve: {
user: function($http) { return $http.get('...'); }
}
});
});
```
## Intercomponent Communication
Directives can require the controllers of other directives to enable communication
between each other. This can be achieved in a component by providing an
object mapping for the `require` property. The object keys specify the property names under which
the required controllers (object values) will be bound to the requiring component's controller.
<div class="alert alert-warning">
Note that the required controllers will not be available during the instantiation of the controller,
but they are guaranteed to be available just before the `$onInit` method is executed!
</div>
Here is a tab pane example built from components:
<example module="docsTabsExample">
<file name="script.js">
angular.module('docsTabsExample', [])
.component('myTabs', {
transclude: true,
controller: function() {
var panes = this.panes = [];
this.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
};
this.addPane = function(pane) {
if (panes.length === 0) {
this.select(pane);
}
panes.push(pane);
};
},
templateUrl: 'my-tabs.html'
})
.component('myPane', {
transclude: true,
require: {
tabsCtrl: '^myTabs'
},
bindings: {
title: '@'
},
controller: function() {
this.$onInit = function() {
this.tabsCtrl.addPane(this);
console.log(this);
};
},
templateUrl: 'my-pane.html'
});
</file>
<file name="index.html">
<my-tabs>
<my-pane title="Hello">
<h4>Hello</h4>
<p>Lorem ipsum dolor sit amet</p>
</my-pane>
<my-pane title="World">
<h4>World</h4>
<em>Mauris elementum elementum enim at suscipit.</em>
<p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
</my-pane>
</my-tabs>
</file>
<file name="my-tabs.html">
<div class="tabbable">
<ul class="nav nav-tabs">
<li ng-repeat="pane in $ctrl.panes" ng-class="{active:pane.selected}">
<a href="" ng-click="$ctrl.select(pane)">{{pane.title}}</a>
</li>
</ul>
<div class="tab-content" ng-transclude></div>
</div>
</file>
<file name="my-pane.html">
<div class="tab-pane" ng-show="$ctrl.selected" ng-transclude></div>
</file>
</example>
# 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
advantage of this method is that you do not have to create any DOM elements. The following example
shows how to do this for the `heroDetail` component from above.
The examples use the [Jasmine](http://jasmine.github.io/) testing framework.
**Controller Test:**
```js
describe('component: heroDetail', function() {
var $componentController;
beforeEach(module('heroApp'));
beforeEach(inject(function(_$componentController_) {
$componentController = _$componentController_;
}));
it('should expose a `hero` object', function() {
// Here we are passing actual bindings to the component
var bindings = {hero: {name: 'Wolverine'}};
var ctrl = $componentController('heroDetail', null, bindings);
expect(ctrl.hero).toBeDefined();
expect(ctrl.hero.name).toBe('Wolverine');
});
it('should call the `onDelete` binding, when deleting the hero', function() {
var onDeleteSpy = jasmine.createSpy('onDelete');
var bindings = {hero: {}, onDelete: onDeleteSpy};
var ctrl = $componentController('heroDetail', null, bindings);
ctrl.delete();
expect(onDeleteSpy).toHaveBeenCalledWith({hero: ctrl.hero});
});
it('should call the `onUpdate` binding, when updating a property', function() {
var onUpdateSpy = jasmine.createSpy('onUpdate');
var bindings = {hero: {}, onUpdate: onUpdateSpy};
var ctrl = $componentController('heroDetail', null, bindings);
ctrl.update('foo', 'bar');
expect(onUpdateSpy).toHaveBeenCalledWith({
hero: ctrl.hero,
prop: 'foo',
value: 'bar'
});
});
});
```
+22 -23
View File
@@ -8,22 +8,22 @@
This section briefly touches on all of the important parts of AngularJS using a simple example.
For a more in-depth explanation, see the {@link tutorial/ tutorial}.
| Concept | Description |
|------------------|------------------------------------------|
|{@link concepts#template Template} | HTML with additional markup |
|{@link concepts#directive Directives} | extend HTML with custom attributes and elements |
|{@link concepts#model Model} | the data shown to the user in the view and with which the user interacts |
|{@link concepts#scope Scope} | context where the model is stored so that controllers, directives and expressions can access it |
|{@link concepts#expression Expressions} | access variables and functions from the scope |
|{@link concepts#compiler Compiler} | parses the template and instantiates directives and expressions |
|{@link concepts#filter Filter} | formats the value of an expression for display to the user |
|{@link concepts#view View} | what the user sees (the DOM) |
|{@link concepts#databinding Data Binding} | sync data between the model and the view |
|{@link concepts#controller Controller} | the business logic behind views |
|{@link concepts#di Dependency Injection} | Creates and wires objects and functions |
|{@link concepts#injector Injector} | dependency injection container |
|{@link concepts#module Module} | a container for the different parts of an app including controllers, services, filters, directives which configures the Injector |
|{@link concepts#service Service} | reusable business logic independent of views |
| Concept | Description |
|--------------------------------------------|--------------------------------------------------------------------------|
|{@link concepts#template Template} | HTML with additional markup |
|{@link concepts#directive Directives} | extend HTML with custom attributes and elements |
|{@link concepts#model Model} | the data shown to the user in the view and with which the user interacts |
|{@link concepts#scope Scope} | context where the model is stored so that controllers, directives and expressions can access it |
|{@link concepts#expression Expressions} | access variables and functions from the scope |
|{@link concepts#compiler Compiler} | parses the template and instantiates directives and expressions |
|{@link concepts#filter Filter} | formats the value of an expression for display to the user |
|{@link concepts#view View} | what the user sees (the DOM) |
|{@link concepts#databinding Data Binding} | sync data between the model and the view |
|{@link concepts#controller Controller} | the business logic behind views |
|{@link concepts#di Dependency Injection} | Creates and wires objects and functions |
|{@link concepts#injector Injector} | dependency injection container |
|{@link concepts#module Module} | a container for the different parts of an app including controllers, services, filters, directives which configures the Injector |
|{@link concepts#service Service} | reusable business logic independent of views |
## A first example: Data binding
@@ -76,7 +76,7 @@ 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
to read and write variables. Note that those variables are not global variables.
Angular 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.
The values that are stored in variables on the scope are referred to as the <a name="model"></a>*model*
@@ -277,8 +277,8 @@ Now that Angular knows of all the parts of the application, it needs to create t
In the previous section we saw that controllers are created using a factory function.
For services there are multiple ways to define their factory
(see the {@link services service guide}).
In the example above, we are using a function that returns the `currencyConverter` function as the factory
for the service.
In the example above, we are using an anonymous function as the factory function for `currencyConverter` service.
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
@@ -334,9 +334,9 @@ The following example shows how this is done with Angular:
var refresh = function() {
var url = YAHOO_FINANCE_URL_PATTERN.
replace('PAIRS', 'USD' + currencies.join('","USD'));
return $http.jsonp(url).success(function(data) {
return $http.jsonp(url).then(function(response) {
var newUsdToForeignRates = {};
angular.forEach(data.query.results.rate, function(rate) {
angular.forEach(response.data.query.results.rate, function(rate) {
var currency = rate.id.substring(3,6);
newUsdToForeignRates[currency] = window.parseFloat(rate.Rate);
});
@@ -348,8 +348,7 @@ The following example shows how this is done with Angular:
return {
currencies: currencies,
convert: convert,
refresh: refresh
convert: convert
};
}]);
</file>
+9 -6
View File
@@ -5,13 +5,16 @@
# Understanding Controllers
In Angular, a Controller is a JavaScript **constructor function** that is used to augment the
In Angular, a Controller is defined by a JavaScript **constructor function** that is used to augment the
{@link scope Angular 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 available as an injectable parameter to the
Controller's constructor function as `$scope`.
**constructor function**. A new **child scope** will be created and made available as an injectable
parameter to the Controller's constructor function as `$scope`.
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.
Use controllers to:
@@ -106,7 +109,7 @@ 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} {@link services
This is discussed in the {@link di Dependency Injection} and {@link services
Services} sections of this guide.
@@ -162,7 +165,7 @@ scope is augmented (managed) by the `SpicyController` Controller.
starts with capital letter and ends with "Controller".
- Assigning a property to `$scope` creates or updates the model.
- Controller methods can be created through direct assignment to scope (see the `chiliSpicy` method)
- The Controller methods and properties are available in the template (for the `<div>` element and
- The Controller methods and properties are available in the template (for both the `<div>` element and
its children).
## Spicy Arguments Example
@@ -302,7 +305,7 @@ describe('myController function', function() {
```
If you need to test a nested Controller you need to create the same scope hierarchy
If you need to test a nested Controller you must create the same scope hierarchy
in your test that exists in the DOM:
```js
+486
View File
@@ -0,0 +1,486 @@
@ngdoc overview
@name Decorators
@sortOrder 345
@description
# Decorators in AngularJS
<div class="alert alert-warning">
**NOTE:** This guide is targeted towards developers who are already familiar with AngularJS basics.
If you're just getting started, we recommend the {@link tutorial/ tutorial} first.
</div>
## 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
prior to its usage.
## How to use decorators
There are two ways to register decorators
- `$provide.decorator`, and
- `module.decorator`
Each provide access to a `$delegate`, which is the instantiated service/directive/filter, prior to being passed to the
service that required it.
### $provide.decorator
The {@link api/auto/service/$provide#decorator decorator function} allows access to a $delegate of the service once it
has been instantiated. For example:
```js
angular.module('myApp', [])
.config([ '$provide', function($provide) {
$provide.decorator('$log', [
'$delegate',
function $logDecorator($delegate) {
var originalWarn = $delegate.warn;
$delegate.warn = function decoratedWarn(msg) {
msg = 'Decorated Warn: ' + msg;
originalWarn.apply($delegate, arguments);
};
return $delegate;
}
]);
}]);
```
After the `$log` service has been instantiated the decorator is fired. The decorator function has a `$delegate` object
injected to provide access to the service that matches the selector in the decorator. This `$delegate` will be the
service you are decorating. The return value of the function *provided to the decorator* will take place of the service,
directive, or filter being decorated.
<hr>
The `$delegate` may be either modified or completely replaced. Given a service `myService` with a method `someFn`, the
following could all be viable solutions:
#### Completely Replace the $delegate
```js
angular.module('myApp', [])
.config([ '$provide', function($provide) {
$provide.decorator('myService', [
'$delegate',
function myServiceDecorator($delegate) {
var myDecoratedService = {
// new service object to replace myService
};
return myDecoratedService;
}
]);
}]);
```
#### Patch the $delegate
```js
angular.module('myApp', [])
.config([ '$provide', function($provide) {
$provide.decorator('myService', [
'$delegate',
function myServiceDecorator($delegate) {
var someFn = $delegate.someFn;
function aNewFn() {
// new service function
someFn.apply($delegate, arguments);
}
$delegate.someFn = aNewFn;
return $delegate;
}
]);
}]);
```
#### Augment the $delegate
```js
angular.module('myApp', [])
.config([ '$provide', function($provide) {
$provide.decorator('myService', [
'$delegate',
function myServiceDecorator($delegate) {
function helperFn() {
// an additional fn to add to the service
}
$delegate.aHelpfulAddition = helperFn;
return $delegate;
}
]);
}]);
```
<div class="alert alert-info">
Note that whatever is returned by the decorator function will replace that which is being decorated. For example, a
missing return statement will wipe out the entire object being decorated.
</div>
<hr>
Decorators have different rules for different services. This is because services are registered in different ways.
Services are selected by name, however filters and directives are selected by appending `"Filter"` or `"Directive"` to
the end of the name. The `$delegate` provided is dictated by the type of service.
| Service Type | Selector | $delegate |
|--------------|-------------------------------|-----------------------------------------------------------------------|
| Service | `serviceName` | The `object` or `function` returned by the service |
| Directive | `directiveName + 'Directive'` | An `Array.<DirectiveObject>`<sub>{@link guide/decorators#drtvArray 1}</sub> |
| Filter | `filterName + 'Filter'` | The `function` returned by the filter |
<small id="drtvArray">1. Multiple directives may be registered to the same selector/name</small>
<div class="alert alert-warning">
**NOTE:** Developers should take care in how and why they are modifying the `$delegate` for the service. Not only
should expectations for the consumer be kept, but some functionality (such as directive registration) does not take
place after decoration, but during creation/registration of the original service. This means, for example, that
an action such as pushing a directive object to a directive `$delegate` will likely result in unexpected behavior.
Furthermore, great care should be taken when decorating core services, directives, or filters as this may unexpectedly
or adversely affect the functionality of the framework.
</div>
### module.decorator
This {@link api/ng/type/angular.Module#decorator function} is the same as the `$provide.decorator` function except it is
exposed through the module API. This allows you to separate your decorator patterns from your module config blocks. The
main caveat here is that you will need to take note the order in which you create your decorators.
Unlike in the module config block (which allows configuration of services prior to their creation), the service must be
registered prior to the decorator (see {@link guide/providers#provider-recipe Provider Recipe}). For example, the
following would not work because you are attempting to decorate outside of the configuration phase and the service
hasn't been created yet:
```js
// will cause an error since 'someService' hasn't been registered
angular.module('myApp').decorator('someService', ...);
angular.module('myApp').factory('someService', ...);
```
## Example Applications
The following sections provide examples each of a service decorator, a directive decorator, and a filter decorator.
### Service Decorator Example
This example shows how we can replace the $log service with our own to display log messages.
<example module="myServiceDecorator" name="service-decorator">
<file name="script.js">
angular.module('myServiceDecorator', []).
controller('Ctrl', [
'$scope',
'$log',
'$timeout',
function($scope, $log, $timeout) {
var types = ['error', 'warn', 'log', 'info' ,'debug'], i;
for (i = 0; i < types.length; i++) {
$log[types[i]](types[i] + ': message ' + (i + 1));
}
$timeout(function() {
$log.info('info: message logged in timeout');
});
}
]).
directive('myLog', [
'$log',
function($log) {
return {
restrict: 'E',
template: '<ul id="myLog"><li ng-repeat="l in myLog" class="{{l.type}}">{{l.message}}</li></ul>',
scope: {},
compile: function() {
return function(scope) {
scope.myLog = $log.stack;
};
}
};
}
]).
config([
'$provide',
function($provide) {
$provide.decorator('$log', [
'$delegate',
function logDecorator($delegate) {
var myLog = {
warn: function(msg) {
log(msg, 'warn');
},
error: function(msg) {
log(msg, 'error');
},
info: function(msg) {
log(msg, 'info');
},
debug: function(msg) {
log(msg, 'debug');
},
log: function(msg) {
log(msg, 'log');
},
stack: []
};
function log(msg, type) {
myLog.stack.push({ type: type, message: msg.toString() });
if (console && console[type]) console[type](msg);
}
return myLog;
}
]);
}
]);
</file>
<file name="index.html">
<div ng-controller="Ctrl">
<h1>Logs</h1>
<my-log></my-log>
</div>
</file>
<file name="style.css">
li.warn { color: yellow; }
li.error { color: red; }
li.info { color: blue }
li.log { color: black }
li.debug { color: green }
</file>
<file name="protractor.js" type="protractor">
it('should display log messages in dom', function() {
element.all(by.repeater('l in myLog')).count().then(function(count) {
expect(count).toEqual(6);
});
});
</file>
</example>
### Directive Decorator Example
Failed interpolated expressions in `ng-href` attributes can easily go unnoticed. We can decorate `ngHref` to warn us of
those conditions.
<example module="urlDecorator" name="directive-decorator">
<file name="script.js">
angular.module('urlDecorator', []).
controller('Ctrl', ['$scope', function ($scope) {
$scope.id = 3;
$scope.warnCount = 0; // for testing
}]).
config(['$provide', function($provide) {
// matchExpressions looks for interpolation markup in the directive attribute, extracts the expressions
// from that markup (if they exist) and returns an array of those expressions
function matchExpressions(str) {
var exps = str.match(/{{([^}]+)}}/g);
// if there isn't any, get out of here
if (exps === null) return;
exps = exps.map(function(exp) {
var prop = exp.match(/[^{}]+/);
return prop === null ? null : prop[0];
});
return exps;
}
// remember: directives must be selected by appending 'Directive' to the directive selector
$provide.decorator('ngHrefDirective', [
'$delegate',
'$log',
'$parse',
function($delegate, $log, $parse) {
// store the original link fn
var originalLinkFn = $delegate[0].link;
// replace the compile fn
$delegate[0].compile = function(tElem, tAttr) {
// store the original exp in the directive attribute for our warning message
var originalExp = tAttr.ngHref;
// get the interpolated expressions
var exps = matchExpressions(originalExp);
// create and store the getters using $parse
var getters = exps.map(function(el) {
if (el) return $parse(el);
});
return function newLinkFn(scope, elem, attr) {
// fire the originalLinkFn
originalLinkFn.apply($delegate[0], arguments);
// observe the directive attr and check the expressions
attr.$observe('ngHref', function(val) {
// if we have getters and getters is an array...
if (getters && angular.isArray(getters)) {
// loop through the getters and process them
angular.forEach(getters, function(g, idx) {
// if val is truthy, then the warning won't log
var val = angular.isFunction(g) ? g(scope) : true;
if (!val) {
$log.warn('NgHref Warning: "' + exps[idx] + '" in the expression "' + originalExp +
'" is falsy!');
scope.warnCount++; // for testing
}
});
}
});
};
};
// get rid of the old link function since we return a link function in compile
delete $delegate[0].link;
// return the $delegate
return $delegate;
}
]);
}]);
</file>
<file name="index.html">
<div ng-controller="Ctrl">
<a ng-href="/products/{{ id }}/view" id="id3">View Product {{ id }}</a>
- <strong>id == 3</strong>, so no warning<br>
<a ng-href="/products/{{ id + 5 }}/view" id="id8">View Product {{ id + 5 }}</a>
- <strong>id + 5 == 8</strong>, so no warning<br>
<a ng-href="/products/{{ someOtherId }}/view" id="someOtherId">View Product {{ someOtherId }}</a>
- <strong style="background-color: #ffff00;">someOtherId == undefined</strong>, so warn<br>
<a ng-href="/products/{{ someOtherId + 5 }}/view" id="someOtherId5">View Product {{ someOtherId + 5 }}</a>
- <strong>someOtherId + 5 == 5</strong>, so no warning<br>
<div>Warn Count: {{ warnCount }}</div>
</div>
</file>
<file name="protractor.js" type="protractor">
it('should warn when an expression in the interpolated value is falsy', function() {
var id3 = element(by.id('id3'));
var id8 = element(by.id('id8'));
var someOther = element(by.id('someOtherId'));
var someOther5 = element(by.id('someOtherId5'));
expect(id3.getText()).toEqual('View Product 3');
expect(id3.getAttribute('href')).toContain('/products/3/view');
expect(id8.getText()).toEqual('View Product 8');
expect(id8.getAttribute('href')).toContain('/products/8/view');
expect(someOther.getText()).toEqual('View Product');
expect(someOther.getAttribute('href')).toContain('/products//view');
expect(someOther5.getText()).toEqual('View Product 5');
expect(someOther5.getAttribute('href')).toContain('/products/5/view');
expect(element(by.binding('warnCount')).getText()).toEqual('Warn Count: 1');
});
</file>
</example>
### Filter Decorator Example
Let's say we have created an app that uses the default format for many of our `Date` filters. Suddenly requirements have
changed (that never happens) and we need all of our default dates to be `'shortDate'` instead of `'mediumDate'`.
<example module="filterDecorator" name="filter-decorator">
<file name="script.js">
angular.module('filterDecorator', []).
controller('Ctrl', ['$scope', function ($scope) {
$scope.genesis = new Date(2010, 0, 5);
$scope.ngConf = new Date(2016, 4, 4);
}]).
config(['$provide', function($provide) {
$provide.decorator('dateFilter', [
'$delegate',
function dateDecorator($delegate) {
// store the original filter
var originalFilter = $delegate;
// return our filter
return shortDateDefault;
// shortDateDefault sets the format to shortDate if it is falsy
function shortDateDefault(date, format, timezone) {
if (!format) format = 'shortDate';
// return the result of the original filter
return originalFilter(date, format, timezone);
}
}
]);
}]);
</file>
<file name="index.html">
<div ng-controller="Ctrl">
<div id="genesis">Initial Commit default to short date: {{ genesis | date }}</div>
<div>ng-conf 2016 default short date: {{ ngConf | date }}</div>
<div id="ngConf">ng-conf 2016 with full date format: {{ ngConf | date:'fullDate' }}</div>
</div>
</file>
<file name="protractor.js" type="protractor">
it('should default date filter to short date format', function() {
expect(element(by.id('genesis')).getText())
.toMatch(/Initial Commit default to short date: \d{1,2}\/\d{1,2}\/\d{2}/);
});
it('should still allow dates to be formatted', function() {
expect(element(by.id('ngConf')).getText())
.toMatch(/ng-conf 2016 with full date format\: [A-Za-z]+, [A-Za-z]+ \d{1,2}, \d{4}/);
});
</file>
</example>
+3 -3
View File
@@ -163,8 +163,8 @@ someModule.controller('MyController', function($scope, greeter) {
});
```
Given a function the injector can infer the names of the services to inject by examining the
function declaration and extracting the parameter names. In the above example `$scope`, and
Given a function, the injector can infer the names of the services to inject by examining the
function declaration and extracting the parameter names. In the above example, `$scope` and
`greeter` are two services which need to be injected into the function.
One advantage of this approach is that there's no array of names to keep in sync with the
@@ -293,7 +293,7 @@ Create a new injector that can provide components defined in our `myModule` modu
`greeter` service from the injector. (This is usually done automatically by angular bootstrap).
```js
var injector = angular.injector(['myModule', 'ng']);
var injector = angular.injector(['ng', 'myModule']);
var greeter = injector.get('greeter');
```
+60 -96
View File
@@ -19,8 +19,9 @@ how to implement them.
## What are Directives?
At a high level, directives are markers on a DOM element (such as an attribute, element
name, comment or CSS class) that tell AngularJS's **HTML compiler** ({@link ng.$compile `$compile`}) to
attach a specified behavior to that DOM element or even transform the DOM element and its children.
name, comment or CSS class) that tell AngularJS's **HTML compiler** ({@link ng.$compile `$compile`})
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.
@@ -30,7 +31,7 @@ When Angular {@link guide/bootstrap bootstraps} your application, the
<div class="alert alert-info">
**What does it mean to "compile" an HTML template?**
For AngularJS, "compilation" means attaching event listeners to the HTML to make it interactive.
For AngularJS, "compilation" means attaching directives to the HTML to make it interactive.
The reason we use the term "compile" is that the recursive process of attaching directives
mirrors the process of compiling source code in
[compiled programming languages](http://en.wikipedia.org/wiki/Compiled_languages).
@@ -42,18 +43,27 @@ mirrors the process of compiling source code in
Before we can write a directive, we need to know how Angular's {@link guide/compiler HTML compiler}
determines when to use a given directive.
In the following example, we say that the `<input>` element **matches** the `ngModel` 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
directive when the directive is part of its declaration.
In the following example, we say that the `<input>` element **matches** the `ngModel` directive
```html
<input ng-model="foo">
```
The following also **matches** `ngModel`:
The following `<input>` element also **matches** `ngModel`:
```html
<input data-ng-model="foo">
```
And the following <person> element **matches** the `person` directive:
```html
<person>{{name}}</person>
```
### Normalization
Angular **normalizes** an element's tag and attribute name to determine which elements match which
@@ -89,8 +99,13 @@ For example, the following forms are all equivalent and match the {@link ngBind}
</file>
<file name="protractor.js" type="protractor">
it('should show off bindings', function() {
expect(element(by.css('div[ng-controller="Controller"] span[ng-bind]')).getText())
.toBe('Max Karl Ernst Ludwig Planck (April 23, 1858 October 4, 1947)');
var containerElm = element(by.css('div[ng-controller="Controller"]'));
var nameBindings = containerElm.all(by.binding('name'));
expect(nameBindings.count()).toBe(5);
nameBindings.each(function(elem) {
expect(elem.getText()).toEqual('Max Karl Ernst Ludwig Planck (April 23, 1858 October 4, 1947)');
});
});
</file>
</example>
@@ -131,63 +146,6 @@ directives when possible.
</div>
### Text and attribute bindings
During the compilation process the {@link ng.$compile compiler} matches text and attributes
using the {@link ng.$interpolate $interpolate} service to see if they contain embedded
expressions. These expressions are registered as {@link ng.$rootScope.Scope#$watch watches}
and will update as part of normal {@link ng.$rootScope.Scope#$digest digest} cycle. An
example of interpolation is shown below:
```html
<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>
```
### `ngAttr` attribute bindings
Web browsers are sometimes picky about what values they consider valid for attributes.
For example, considering this template:
```html
<svg>
<circle cx="{{cx}}"></circle>
</svg>
```
We would expect Angular to be able to bind to this, but when we check the console we see
something like `Error: Invalid value for attribute cx="{{cx}}"`. Because of the SVG DOM API's
restrictions, you cannot simply write `cx="{{cx}}"`.
With `ng-attr-cx` you can work around this problem.
If an attribute with a binding is prefixed with the `ngAttr` prefix (denormalized as `ng-attr-`)
then during the binding it will be applied to the corresponding unprefixed attribute. This allows
you to bind to attributes that would otherwise be eagerly processed by browsers
(e.g. an SVG element's `circle[cx]` attributes). When using `ngAttr`, the `allOrNothing` flag of
{@link ng.$interpolate $interpolate} is used, so if any expression in the interpolated string
results in `undefined`, the attribute is removed and not added to the element.
For example, we could fix the example above by instead writing:
```html
<svg>
<circle ng-attr-cx="{{cx}}"></circle>
</svg>
```
If one wants to modify a camelcased attribute (SVG elements have valid camelcased attributes), such as `viewBox` on the `svg` element, one can use underscores to denote that the attribute to bind to is naturally camelcased.
For example, to bind to `viewBox`, we can write:
```html
<svg ng-attr-view_box="{{viewBox}}">
</svg>
```
## Creating Directives
First let's talk about the {@link ng.$compileProvider#directive API for registering directives}. Much like
@@ -204,10 +162,6 @@ initialization work here. The function is invoked using
{@link auto.$injector#invoke $injector.invoke} which makes it injectable just like a
controller.
<div class="alert alert-success">
**Best Practice:** Prefer using the definition object over returning a function.
</div>
We'll go over a few common examples of directives, then dive deep into the different options
and compilation process.
@@ -345,6 +299,7 @@ The `restrict` option is typically set to:
* `'A'` - only matches attribute name
* `'E'` - only matches element name
* `'C'` - only matches class name
* `'M'` - only matches comment
These restrictions can all be combined as needed:
@@ -448,7 +403,7 @@ This is clearly not a great solution.
What we want to be able to do is separate the scope inside a directive from the scope
outside, and then map the outer scope to a directive's inner scope. We can do this by creating what
we call an **isolate scope**. To do this, we can use a directive's `scope` option:
we call an **isolate scope**. To do this, we can use a {@link $compile#-scope- directive's `scope`} option:
<example module="docsIsolateScopeDirective">
<file name="script.js">
@@ -577,14 +532,24 @@ want to reuse throughout your app.
In this example we will build a directive that displays the current time.
Once a second, it updates the DOM to reflect the current time.
Directives that want to modify the DOM typically use the `link` option.
`link` takes a function with the following signature, `function link(scope, element, attrs) { ... }`
where:
Directives that want to modify the DOM typically use the `link` option to register DOM listeners
as well as update the DOM. It is executed after the template has been cloned and is where
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.
* `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.
* `controller` is the directive's required controller instance(s) or its own controller (if any).
The exact value depends on the directive's require property.
* `transcludeFn` is a transclude linking function pre-bound to the correct transclusion scope.
<div class="alert alert-info">
For more details on the `link` option refer to the {@link ng.$compile#-link- `$compile` API} page.
</div>
In our `link` function, we want to update the displayed time once a second, or whenever a user
changes the time formatting string that our directive binds to. We will use the `$interval` service
@@ -678,6 +643,7 @@ To do this, we need to use the `transclude` option.
return {
restrict: 'E',
transclude: true,
scope: {},
templateUrl: 'my-dialog.html'
};
});
@@ -688,8 +654,7 @@ To do this, we need to use the `transclude` option.
</div>
</file>
<file name="my-dialog.html">
<div class="alert" ng-transclude>
</div>
<div class="alert" ng-transclude></div>
</file>
</example>
@@ -711,7 +676,7 @@ that redefines `name` as `Jeff`. What do you think the `{{name}}` binding will r
transclude: true,
scope: {},
templateUrl: 'my-dialog.html',
link: function (scope, element) {
link: function (scope) {
scope.name = 'Jeff';
}
};
@@ -723,8 +688,7 @@ that redefines `name` as `Jeff`. What do you think the `{{name}}` binding will r
</div>
</file>
<file name="my-dialog.html">
<div class="alert" ng-transclude>
</div>
<div class="alert" ng-transclude></div>
</file>
</example>
@@ -735,7 +699,7 @@ The `transclude` option changes the way scopes are nested. It makes it so that t
transcluded directive have whatever scope is outside the directive, rather than whatever scope is on
the inside. In doing so, it gives the contents access to the outside scope.
Note that if the directive did not create its own scope, then `scope` in `scope.name = 'Jeff';` would
Note that if the directive did not create its own scope, then `scope` in `scope.name = 'Jeff'` would
reference the outside scope and we would see `Jeff` in the output.
This behavior makes sense for a directive that wraps some content, because otherwise you'd have to
@@ -808,9 +772,9 @@ function.
Often it's desirable to pass data from the isolate scope via an expression to the
parent scope, this can be done by passing a map of local variable names and values into the expression
wrapper fn. For example, the hideDialog function takes a message to display when the dialog is hidden.
This is specified in the directive by calling `close({message: 'closing for now'})`. Then the local
variable `message` will be available within the `on-close` expression.
wrapper function. For example, the `hideDialog` function takes a message to display when the dialog
is hidden. This is specified in the directive by calling `close({message: 'closing for now'})`.
Then the local variable `message` will be available within the `on-close` expression.
<div class="alert alert-success">
**Best Practice:** use `&attr` in the `scope` option when you want your directive
@@ -869,7 +833,7 @@ element?
}]);
</file>
<file name="index.html">
<span my-draggable>Drag ME</span>
<span my-draggable>Drag Me</span>
</file>
</example>
@@ -892,7 +856,7 @@ to which tab is active.
restrict: 'E',
transclude: true,
scope: {},
controller: function($scope) {
controller: ['$scope', function($scope) {
var panes = $scope.panes = [];
$scope.select = function(pane) {
@@ -908,13 +872,13 @@ to which tab is active.
}
panes.push(pane);
};
},
}],
templateUrl: 'my-tabs.html'
};
})
.directive('myPane', function() {
return {
require: '^myTabs',
require: '^^myTabs',
restrict: 'E',
transclude: true,
scope: {
@@ -930,11 +894,9 @@ to which tab is active.
<file name="index.html">
<my-tabs>
<my-pane title="Hello">
<h4>Hello</h4>
<p>Lorem ipsum dolor sit amet</p>
</my-pane>
<my-pane title="World">
<h4>World</h4>
<em>Mauris elementum elementum enim at suscipit.</em>
<p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
</my-pane>
@@ -951,22 +913,25 @@ to which tab is active.
</div>
</file>
<file name="my-pane.html">
<div class="tab-pane" ng-show="selected" ng-transclude>
<div class="tab-pane" ng-show="selected">
<h4>{{title}}</h4>
<div ng-transclude></div>
</div>
</file>
</example>
The `myPane` directive has a `require` option with value `^myTabs`. When a directive uses this
option, `$compile` will throw an error unless the specified controller is found. The `^` prefix
means that this directive searches for the controller on its parents (without the `^` prefix, the
directive would look for the controller on just its own element).
The `myPane` directive has a `require` option with value `^^myTabs`. When a directive uses this
option, `$compile` will throw an error unless the specified controller is found. The `^^` prefix
means that this directive searches for the controller on its parents. (A `^` prefix would make the
directive look for the controller on its own element or its parents; without any prefix, the
directive would look on its own element only.)
So where does this `myTabs` controller come from? Directives can specify controllers using
the unsurprisingly named `controller` option. As you can see, the `myTabs` directive uses this
option. Just like `ngController`, this option attaches a controller to the template of the directive.
If it is necessary to reference the controller or any functions bound to the controller's scope in
the template, you can use the option `controllerAs` to specify the name of the controller as an alias.
If it is necessary to reference the controller or any functions bound to the controller from the
template, you can use the option `controllerAs` to specify the name of the controller as an alias.
The directive needs to define a scope for this configuration to be used. This is particularly useful
in the case when the directive is used as a component.
@@ -981,7 +946,7 @@ The corresponding parameter being sent to the `link` function will also be an ar
angular.module('docsTabsExample', [])
.directive('myPane', function() {
return {
require: ['^myTabs', '^ngModel'],
require: ['^^myTabs', 'ngModel'],
restrict: 'E',
transclude: true,
scope: {
@@ -1017,4 +982,3 @@ available in the {@link guide/compiler compiler guide}.
The {@link ng.$compile `$compile` API} page has a comprehensive list of directive options for
reference.
+20 -8
View File
@@ -5,8 +5,9 @@
# Angular Expressions
Angular expressions are JavaScript-like code snippets that are usually placed in bindings such as
`{{ expression }}`.
Angular 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:
@@ -26,6 +27,9 @@ Angular expressions are like JavaScript expressions with the following differenc
* **Forgiving:** In JavaScript, trying to evaluate undefined properties generates `ReferenceError`
or `TypeError`. In Angular, 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:
conditionals, loops, or exceptions.
@@ -35,10 +39,12 @@ Angular expressions are like JavaScript expressions with the following differenc
* **No RegExp Creation With Literal Notation:** You cannot create regular expressions
in an Angular expression.
* **No Comma And Void Operators:** You cannot use `,` or `void` in an Angular expression.
* **No Object Creation With New Operator:** You cannot use `new` operator in an Angular expression.
* **No Bitwise, Comma, And Void Operators:** You cannot use
[Bitwise](https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators),
`,` or `void` operators in an Angular expression.
* **Filters:** You can use {@link guide/filter filters} within expressions to format data before
displaying it.
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
@@ -70,7 +76,7 @@ You can try evaluating different expressions here:
<ul>
<li ng-repeat="expr in exprs track by $index">
[ <a href="" ng-click="removeExp($index)">X</a> ]
<tt>{{expr}}</tt> => <span ng-bind="$parent.$eval(expr)"></span>
<code>{{expr}}</code> => <span ng-bind="$parent.$eval(expr)"></span>
</li>
</ul>
</div>
@@ -113,6 +119,9 @@ This restriction is intentional. It prevents accidental access to the global sta
Instead use services like `$window` and `$location` in functions called from expressions. Such services
provide mockable access to globals.
It is possible to access the context object using the identifier `this` and the locals object using the
identifier `$locals`.
<example module="expressionExample">
<file name="index.html">
<div class="example2" ng-controller="ExampleController">
@@ -141,6 +150,9 @@ provide mockable access to globals.
}
element(by.css('[ng-click="greet()"]')).click();
// We need to give the browser time to display the alert
browser.wait(protractor.ExpectedConditions.alertIsPresent(), 1000);
var alertDialog = browser.switchTo().alert();
expect(alertDialog.getText()).toEqual('Hello World');
@@ -277,7 +289,7 @@ result is a non-undefined value (see value stabilization algorithm below).
</example>
### Why this feature
### Reasons for using one-time binding
The main purpose of one-time binding expression is to provide a way to create a binding
that gets deregistered and frees up resources once the binding is stabilized.
@@ -344,4 +356,4 @@ When using a directive that takes an expression:
<ul>
<li ng-repeat="item in ::items | orderBy:'name'">{{item.name}};</li>
</ul>
```
```
+147
View File
@@ -0,0 +1,147 @@
@ngdoc overview
@name External Resources
@sortOrder 205
@description
# External Angular 1 Resources
This is a collection of external, 3rd party resources for learning and developing Angular.
## Articles, Videos, and Projects
### Introductory Material
* [10 Reasons Why You Should Use AngularJS](http://www.sitepoint.com/10-reasons-use-angularjs/)
* [10 Reasons Why Developers Should Learn AngularJS](http://wintellect.com/blogs/jlikness/10-reasons-web-developers-should-learn-angularjs)
* [Design Principles of AngularJS (video)](https://www.youtube.com/watch?v=HCR7i5F5L8c)
* [Fundamentals in 60 Minutes (video)](http://www.youtube.com/watch?v=i9MHigUZKEM)
* [For folks with a jQuery background](http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background)
### Specific Topics
#### Application Structure & Style Guides
* [Angular 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)
#### Testing
* **Unit testing:** [Using Karma (video)](http://www.youtube.com/watch?v=YG5DEzaQBIc), [Karma in Webstorm](http://blog.jetbrains.com/webstorm/2013/10/running-javascript-tests-with-karma-in-webstorm-7/)
#### 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/)
* [Ionic Framework](http://ionicframework.com/)
#### Deployment
##### General
* **Javascript minification: **[Background](http://thegreenpizza.github.io/2013/05/25/building-minification-safe-angular.js-applications/), [ng-annotate automation tool](https://github.com/olov/ng-annotate)
* **Analytics and Logging:** [Angularyitcs (Google Analytics)](http://ngmodules.org/modules/angularytics), [Angulartics (Analytics)](https://github.com/luisfarzati/angulartics), [Logging Client-Side Errors](http://www.bennadel.com/blog/2542-Logging-Client-Side-Errors-With-AngularJS-And-Stacktrace-js.htm)
* **SEO:** [By hand](http://www.yearofmoo.com/2012/11/angularjs-and-seo.html), [prerender.io](http://prerender.io/), [Brombone](http://www.brombone.com/), [SEO.js](http://getseojs.com/), [SEO4Ajax](http://www.seo4ajax.com/)
##### Server-Specific
* **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/), [Firebase Foundations for AngularJS](http://blog.watchandcode.com/firebase-foundations/), [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)
* **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)
* **PHP: **[Building a RESTful web service](http://blog.brunoscopelliti.com/building-a-restful-web-service-with-angularjs-and-php-more-power-with-resource), [End to End with Laravel 4 (video)](http://www.youtube.com/watch?v=hqAyiqUs93c)
* **Meteor: **[angular-meteor package](https://github.com/Urigo/angular-meteor)
### Other Languages
* [ES6, Webpack, and JSPM Starter Project](https://github.com/AngularClass/NG6-starter)
* [ES6/Typescript Best Practices](https://codepen.io/martinmcwhorter/post/angularjs-1-x-with-typescript-or-es6-best-practices)
* [Dart](https://github.com/angular/angular.dart.tutorial/wiki)
* [CoffeeScript Tutorial](http://www.coffeescriptlove.com/2013/08/angularjs-and-coffeescript-tutorials.html)
### More Topics
* **Security:** [video](https://www.youtube.com/watch?v=18ifoT-Id54)
* **Internationalization and Localization:** [Creating multilingual support](http://www.novanet.no/blog/hallstein-brotan/dates/2013/10/creating-multilingual-support-using-angularjs/)
* **Authentication/Login: **[Google example](https://developers.google.com/+/photohunt/python), [AngularJS Facebook library](https://github.com/pc035860/angular-easyfb), [Facebook example](http://blog.brunoscopelliti.com/facebook-authentication-in-your-angularjs-web-app), [authentication strategy](http://blog.brunoscopelliti.com/deal-with-users-authentication-in-an-angularjs-web-app), [unix-style authorization](http://frederiknakstad.com/authentication-in-single-page-applications-with-angular-js/)
* **Visualization:** [SVG](http://gaslight.co/blog/angular-backed-svgs), [D3.js](http://www.ng-newsletter.com/posts/d3-on-angular.html)
* **Realtime Communication: **[Socket.io](http://www.creativebloq.com/javascript/angularjs-collaboration-board-socketio-2132885), [OmniBinder](https://github.com/jeffbcross/omnibinder)
## Tools
* **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)
* **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/)
## 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/).
* **Advanced Routing:** [UI-Router](https://github.com/angular-ui/ui-router)
* **Authentication:** [Http Auth Interceptor](https://github.com/witoldsz/angular-http-auth)
* **Internationalization:**
- [angular-translate](http://angular-translate.github.io)
- [angular-gettext](http://angular-gettext.rocketeer.be/)
- [angular-localization](http://doshprompt.github.io/angular-localization/)
* **RESTful services:** [Restangular](https://github.com/mgonto/restangular)
* **SQL and NoSQL backends:**
- [BreezeJS](http://www.breezejs.com/)
- [AngularFire](http://angularfire.com/)
* **Data Handling**
- Local Storage and session: [ngStorage](https://github.com/gsklee/ngStorage)
- [angular-cache](https://github.com/jmdobry/angular-cache)
- 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)
* **General UI Libraries:**
- [Angular Material](https://material.angularjs.org/latest/)
- [Angular 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)
- [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)
## General Learning Resources
### Books
* [AngularJS: Up and Running](http://www.amazon.com/AngularJS-Running-Enhanced-Productivity-Structured/dp/1491901942) by Brad Green and Shyam Seshadri
* [Mastering Web App Development](http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821) by Pawel Kozlowski and Pete Bacon Darwin
* [AngularJS Directives](http://www.amazon.com/AngularJS-Directives-Alex-Vanston/dp/1783280336) by Alex Vanston
* [Recipes With AngularJS](http://www.amazon.co.uk/Recipes-Angular-js-Frederik-Dietz-ebook/dp/B00DK95V48) by Frederik Dietz
* [Developing an AngularJS Edge](http://www.amazon.com/Developing-AngularJS-Edge-Christopher-Hiller-ebook/dp/B00CJLFF8K) by Christopher Hiller
* [ng-book: The Complete Book on AngularJS](http://ng-book.com/) by Ari Lerner
* [AngularJS : Novice to Ninja](http://www.amazon.in/AngularJS-Novice-Ninja-Sandeep-Panda/dp/0992279453) by Sandeep Panda
* [AngularJS UI Development](http://www.amazon.com/AngularJS-UI-Development-Amit-Ghart-ebook/dp/B00OXVAK7A) by Amit Gharat and Matthias Nehlsen
* [Responsive Web Design with AngularJS](http://www.amazon.com/Responsive-Design-AngularJS-Sandeep-Kumar/dp/178439842X) by Sandeep Kumar Patel
* [Professional AngularJS](http://www.amazon.com/Professional-AngularJS-Valeri-Karpov/dp/1118832078/)
### Videos:
* [egghead.io](http://egghead.io/)
### Courses
* **Free online:**
[thinkster.io](http://thinkster.io),
[CodeAcademy](http://www.codecademy.com/courses/javascript-advanced-en-2hJ3J/0/1),
[CodeSchool](https://www.codeschool.com/courses/shaping-up-with-angular-js)
* **Paid online:**
[The Angular Course (115 videos that show you how to build a full app)](http://watchandcode.com/courses/angular-course/),
[Pluralsite (3 courses)](http://www.pluralsight.com/training/Courses/Find?highlight=true&searchTerm=angularjs),
[Tuts+](https://tutsplus.com/course/easier-js-apps-with-angular/),
[lynda.com](http://www.lynda.com/AngularJS-tutorials/Up-Running-AngularJS/133318-2.html),
[WintellectNOW (4 lessons)](http://www.wintellectnow.com/Course/Detail/mastering-angularjs)
* **Paid onsite:**
[angularbootcamp.com](http://angularbootcamp.com/)
+36 -12
View File
@@ -3,10 +3,13 @@
@sortOrder 280
@description
A filter formats the value of an expression for display to the user. They can be used in view templates,
controllers or services and it is easy to define your own filter.
# Filters
The underlying API is the {@link ng.$filterProvider `filterProvider`}.
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
[built-in filters](api/ng/filter), but it is easy to define your own as well.
The underlying API is the {@link ng.$filterProvider}.
## Using filters in view templates
@@ -29,13 +32,31 @@ Filters may have arguments. The syntax for this is
E.g. the markup `{{ 1234 | number:2 }}` formats the number 1234 with 2 decimal points using the
{@link ng.filter:number `number`} filter. The resulting value is `1,234.00`.
### When filters are executed
In templates, filters are only executed when their inputs have changed. This is more performant than executing
a filter on each {@link ng.$rootScope.Scope#$digest `$digest`} as is the case with {@link guide/expression expressions}.
There are two exceptions to this rule:
1. In general, this applies only to filters that take [primitive values](https://developer.mozilla.org/docs/Glossary/Primitive)
as inputs. Filters that receive [Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Objects)
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
core filters are $stateful.
## Using filters in controllers, services, and directives
You can also use filters in controllers, services, and directives. For this, inject a dependency
with the name `<filterName>Filter` to your controller/service/directive. E.g. using the dependency
`numberFilter` will inject the number filter. The injected argument is a function that takes the
value to format as first argument and filter parameters starting with the second argument.
You can also use filters in controllers, services, and directives.
<div class="alert alert-info">
For this, inject a dependency with the name `<filterName>Filter` into your controller/service/directive.
E.g. a filter called `number` is injected by using the dependency `numberFilter`. The injected argument
is a function that takes the value to format as first argument, and filter parameters starting with the second argument.
</div>
The example below uses the filter called {@link ng.filter:filter `filter`}.
This filter reduces arrays into sub arrays based on
@@ -88,8 +109,9 @@ as the first argument. Any filter arguments are passed in as additional argument
function.
The filter function should be a [pure function](http://en.wikipedia.org/wiki/Pure_function), which
means that it should be stateless and idempotent. Angular relies on these properties and executes
the filter only when the inputs to the function change.
means that it should be stateless and idempotent, and not rely for example on other Angular services.
Angular 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`.
@@ -108,6 +130,7 @@ text upper-case.
No filter: {{greeting}}<br>
Reverse: {{greeting|reverse}}<br>
Reverse + uppercase: {{greeting|reverse:true}}<br>
Reverse, filtered in controller: {{filteredGreeting}}<br>
</div>
</file>
@@ -127,14 +150,15 @@ text upper-case.
return out;
};
})
.controller('MyController', ['$scope', function($scope) {
.controller('MyController', ['$scope', 'reverseFilter', function($scope, reverseFilter) {
$scope.greeting = 'hello';
$scope.filteredGreeting = reverseFilter($scope.greeting);
}]);
</file>
</example>
## Stateful filters
### 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
@@ -176,4 +200,4 @@ means that it will be executed one or more times during the each `$digest` cycle
## Testing custom filters
See the [phonecat tutorial](http://docs.angularjs.org/tutorial/step_09#test) for an example.
See the [phonecat tutorial](http://docs.angularjs.org/tutorial/step_11#testing) for an example.
+7 -4
View File
@@ -33,7 +33,7 @@ for other directives to augment its behavior.
<input type="button" ng-click="reset()" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
<pre>form = {{user | json}}</pre>
<pre>user = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div>
@@ -95,6 +95,8 @@ and failing to satisfy its validity.
<input type="button" ng-click="reset()" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
<pre>user = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div>
<style type="text/css">
@@ -183,6 +185,8 @@ didn't interact with a control
<input type="button" ng-click="reset(form)" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
<pre>user = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div>
</file>
@@ -379,7 +383,7 @@ In the following example we create two directives:
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
var usernames = ['Jim', 'John', 'Jill', 'Jackie'];
var usernames = ['Jim', 'John', 'Jill', 'Jackie'];
ctrl.$asyncValidators.username = function(modelValue, viewValue) {
@@ -436,8 +440,7 @@ Note that you can alternatively use `ng-pattern` to further restrict the validat
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i;
return {
require: 'ngModel',
restrict: '',
require: '?ngModel',
link: function(scope, elm, attrs, ctrl) {
// only apply the validator if ngModel is present and Angular has added the email validator
if (ctrl && ctrl.$validators.email) {
+90 -4
View File
@@ -156,8 +156,94 @@ The syntax extension is based on a subset of the ICU MessageFormat syntax that c
gender selections. Please refer to the links in the “Further Reading” section at the bottom of this
section.
You may find it helpful to play with our [Plnkr Example](http://plnkr.co/edit/QBVRQ70dvKZDWmHW9RyR?p=preview)
as you read the examples below.
You may find it helpful to play with the following example as you read the explanations below:
<example name="message-format-example" module="messageFormatExample" deps="angular-message-format.js">
<file name="index.html">
<div ng-controller="ckCtrl">
<b>Set number of recipients</b>
<button ng-click="setNumRecipients(0)">None</button>
<button ng-click="setNumRecipients(1)">One</button>
<button ng-click="setNumRecipients(2)">Two</button>
<button ng-click="setNumRecipients(3)">Three</button>
<br><br>
<b>Sender's</b> name: <input ng-model="sender.name"> &nbsp;&nbsp;
<br><br><b>Recipients</b><br>
<div ng-repeat="recipient in recipients">
Name: <input ng-model="recipient.name"> &nbsp;&nbsp;
Gender: <button ng-click="setGender(recipient, 'male')">male</button>
<button ng-click="setGender(recipient, 'female')">female</button>
<button ng-click="setGender(recipient, 'other')">other</button>
</div>
<br><br><b>Message</b><br>
{{recipients.length, plural, offset:1
=0 {You ({{sender.name}}) gave no gifts}
=1 { {{ recipients[0].gender, select,
male {You ({{sender.name}}) gave him ({{recipients[0].name}}) a gift.}
female {You ({{sender.name}}) gave her ({{recipients[0].name}}) a gift.}
other {You ({{sender.name}}) gave them ({{recipients[0].name}}) a gift.}
}}
}
one { {{ recipients[0].gender, select,
male {You ({{sender.name}}) gave him ({{recipients[0].name}}) and one other person a gift.}
female {You ({{sender.name}}) gave her ({{recipients[0].name}}) and one other person a gift.}
other {You ({{sender.name}}) gave them ({{recipients[0].name}}) and one other person a gift.}
}}
}
other {You ({{sender.name}}) gave {{recipients.length}} people gifts. }
}}
<br><br><b>In an attribute</b><br>
<div attrib="{{recipients.length, plural, offset:1
=0 {You ({{sender.name}}) gave no gifts}
=1 { {{ recipients[0].gender, select,
male {You ({{sender.name}}) gave him ({{recipients[0].name}}) a gift.}
female {You ({{sender.name}}) gave her ({{recipients[0].name}}) a gift.}
other {You ({{sender.name}}) gave them ({{recipients[0].name}}) a gift.}
}}
}
one { {{ recipients[0].gender, select,
male {You ({{sender.name}}) gave him ({{recipients[0].name}}) and one other person a gift.}
female {You ({{sender.name}}) gave her ({{recipients[0].name}}) and one other person a gift.}
other {You ({{sender.name}}) gave them ({{recipients[0].name}}) and one other person a gift.}
}}
}
other {You ({{sender.name}}) gave {{recipients.length}} people gifts. }
}}">
This div has an attribute interpolated with messageformat. Use the DOM inspector to check it out.
</div>
</div>
</file>
<file name="app.js">
function Person(name, gender) {
this.name = name;
this.gender = gender;
}
angular.module('messageFormatExample', ['ngMessageFormat'])
.controller('ckCtrl', function ($scope, $injector, $parse) {
var people = [ new Person("Alice", "female"),
new Person("Bob", "male"),
new Person("Charlie", "male") ];
$scope.sender = new Person("Harry Potter", "male");
$scope.recipients = people.slice();
$scope.setNumRecipients = function(n) {
n = n > people.length ? people.length : n;
$scope.recipients = people.slice(0, n);
};
$scope.setGender = function(person, gender) {
person.gender = gender;
};
});
</file>
</example>
### Plural Syntax
@@ -333,9 +419,9 @@ allows you to nest plural and gender expressions in any order.
Please note that if these are intended to reach a translator and be translated, it is recommended
that the messages appear as a whole and not be split up.
### More complex example that demonstrates nesting
### Demonstration of nesting
This is taken from the [plunker example](http://plnkr.co/edit/QBVRQ70dvKZDWmHW9RyR?p=preview) linked to earlier.
This is taken from the above example.
```text
{{recipients.length, plural, offset:1
+11 -1
View File
@@ -28,4 +28,14 @@ browsers, but it is up to you to test and decide whether it works for your parti
To ensure your Angular application works on IE please consider:
1. Use `ng-style` tags instead of `style="{{ someCss }}"`. The latter works in Chrome and Firefox
but does not work in Internet Explorer <= 11 (the most recent version at time of writing).
but does not work in Internet Explorer <= 11 (the most recent version at time of writing).
2. For the `type` attribute of buttons, use `ng-attr-type` tags instead of
`type="{{ someExpression }}"`. If using the latter, Internet Explorer overwrites the expression
with `type="submit"` before Angular has a chance to interpolate it.
3. For the `value` attribute of progress, use `ng-attr-value` tags instead of
`value="{{ someExpression}}"`. If using the latter, Internet Explorer overwrites the expression
with `value="0"` before Angular has a chance to interpolate it.
4. For the `placeholder` attribute of textarea, use `ng-attr-placeholder` tags instead
of `placeholder="{{ someExpression }}"`. If using the latter, Internet Explorer will error
on accessing the `nodeValue` on a parentless `TextNode` in Internet Explorer 10 & 11
(see [issue 5025](https://github.com/angular/angular.js/issues/5025)).
+40 -104
View File
@@ -2,22 +2,21 @@
@name Developer Guide
@description
# Guide to AngularJS Documentation
# Guide to Angular 1 Documentation
Everything you need to know about AngularJS
On this page, you will find a list of official Angular resources on various topics.
* {@link guide/introduction What is AngularJS?}
Just starting out with Angular 1? Try working through our step by step tutorial or try
building on our seed project.
* {@link tutorial/index Official Angular 1 Tutorial}
* [Angular Seed](https://github.com/angular/angular-seed)
Ready to find out more about Angular 1?
* {@link guide/introduction What is Angular 1?}
* {@link guide/concepts Conceptual Overview}
## Tutorials
* {@link tutorial/index Official AngularJS Tutorial}
* [10 Reasons Why You Should Use AngularJS](http://www.sitepoint.com/10-reasons-use-angularjs/)
* [10 Reasons Why Developers Should Learn AngularJS](http://wintellect.com/blogs/jlikness/10-reasons-web-developers-should-learn-angularjs)
* [Design Principles of AngularJS (video)](https://www.youtube.com/watch?v=HCR7i5F5L8c)
* [Fundamentals in 60 Minutes (video)](http://www.youtube.com/watch?v=i9MHigUZKEM)
* [For folks with a jQuery background](http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background)
## Core Concepts
### Templates
@@ -26,131 +25,68 @@ In Angular applications, you move the job of filling page templates with data fr
* {@link guide/databinding Data binding}
* {@link guide/expression Expressions}
* {@link guide/interpolation Interpolation}
* {@link guide/directive Directives}
* {@link ngRoute.$route Views and routes (see the example)}
* {@link guide/filter Filters}
* {@link guide/forms Forms} and [Concepts of AngularJS Forms](http://mrbool.com/the-concepts-of-angularjs-forms/29117)
* {@link guide/compiler HTML compiler}
* {@link guide/forms Forms}
### Application Structure
* **Blog post: **[When to use directives, controllers or services](http://kirkbushell.me/when-to-use-directives-controllers-or-services-in-angular/)
* **App wiring:** {@link guide/di Dependency injection}
* **Exposing model to templates:** {@link guide/scope Scopes}
* **Bootstrap:** {@link guide/bootstrap Bootstrapping an app}
* **Communicating with servers:** {@link ng.$http $http}, {@link ngResource.$resource $resource}
### Other AngularJS Features
### Other Features
* **Animation:** {@link guide/animations Core concepts}, {@link ngAnimate ngAnimate API}, and [Animation in AngularJS 1.2](http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html)
* **Animation:** {@link guide/animations Core concepts}, {@link ngAnimate ngAnimate API}
* **Security:** {@link guide/security Security Docs}, {@link ng.$sce Strict Contextual Escaping}, {@link ng.directive:ngCsp Content Security Policy}, {@link ngSanitize.$sanitize $sanitize}, [video](https://www.youtube.com/watch?v=18ifoT-Id54)
* **Internationalization and Localization:** {@link guide/i18n Angular Guide to i18n and l10n}, {@link ng.filter:date date filter}, {@link ng.filter:currency currency filter}, [Creating multilingual support](http://www.novanet.no/blog/hallstein-brotan/dates/2013/10/creating-multilingual-support-using-angularjs/)
* **Mobile:** {@link ngTouch Touch events}
* **Touch events:** {@link ngTouch Touch events}
* **Accessibility:** {@link guide/accessibility ngAria}
### Testing
* **Unit testing:** [Using Karma (video)](http://www.youtube.com/watch?v=YG5DEzaQBIc), {@link guide/unit-testing Unit testing}, {@link guide/services#unit-testing Testing services}, [Karma in Webstorm](http://blog.jetbrains.com/webstorm/2013/10/running-javascript-tests-with-karma-in-webstorm-7/)
* **Scenario testing:** [Protractor](https://github.com/angular/protractor)
* **Unit testing:** [Karma](http://karma-runner.github.io), {@link guide/unit-testing Unit testing}, {@link guide/services#unit-testing Testing services},
* **End-to-End Testing:** [Protractor](https://github.com/angular/protractor), {@link guide/e2e-testing e2e testing guide}
## Specific Topics
* **Login: **[Google example](https://developers.google.com/+/photohunt/python), [AngularJS Faceb0ok library](https://github.com/pc035860/angular-easyfb), [Facebook example](http://blog.brunoscopelliti.com/facebook-authentication-in-your-angularjs-web-app), [authentication strategy](http://blog.brunoscopelliti.com/deal-with-users-authentication-in-an-angularjs-web-app), [unix-style authorization](http://frederiknakstad.com/authentication-in-single-page-applications-with-angular-js/)
* **Mobile:** [Angular on Mobile Guide](http://www.ng-newsletter.com/posts/angular-on-mobile.html), [PhoneGap](http://devgirl.org/2013/06/10/quick-start-guide-phonegap-and-angularjs/)
* **Other Languages:** [CoffeeScript](http://www.coffeescriptlove.com/2013/08/angularjs-and-coffeescript-tutorials.html), [Dart](https://github.com/angular/angular.dart.tutorial/wiki)
* **Realtime: **[Socket.io](http://www.creativebloq.com/javascript/angularjs-collaboration-board-socketio-2132885), [OmniBinder](https://github.com/jeffbcross/omnibinder)
* **Visualization:** [SVG](http://gaslight.co/blog/angular-backed-svgs), [D3.js](http://www.ng-newsletter.com/posts/d3-on-angular.html)
* **Local Storage and session:** [ngStorage](https://github.com/gsklee/ngStorage)
## Community Resources
## Tools
We have set up a guide to many resources provided by the community, where you can find lots
of additional information and material on these topics, a list of complimentary libraries, and much more.
* **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)
* **Testing:** [Karma](http://karma-runner.github.io), [Protractor](https://github.com/angular/protractor)
* **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)
* **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/)
* {@link guide/external-resources External Angular 1 resources}
## Complementary Libraries
This is a short list of libraries with specific support and documentation for working with Angular. You can find a full list of all known Angular external libraries at [ngmodules.org](http://ngmodules.org/).
* **Internationalization:** [angular-translate](http://angular-translate.github.io), [angular-gettext](http://angular-gettext.rocketeer.be/), [angular-localization](http://doshprompt.github.io/angular-localization/)
* **RESTful services:** [Restangular](https://github.com/mgonto/restangular)
* **SQL and NoSQL backends:** [BreezeJS](http://www.breezejs.com/), [AngularFire](http://angularfire.com/)
* **UI Widgets: **[KendoUI](http://kendo-labs.github.io/angular-kendo/#/), [UI Bootstrap](http://angular-ui.github.io/bootstrap/), [Wijmo](http://wijmo.com/tag/angularjs-2/), [ngTagsInput](https://github.com/mbenford/ngTagsInput)
* **Advanced Routing:** [UI-Router](https://github.com/angular-ui/ui-router)
* **Maps:** [UI-Map (Google Maps)](https://github.com/angular-ui/ui-map)
## Deployment
### General
* **Docs Page:** {@link guide/production Running an AngularJS App in Production}
* **Javascript minification: **[Background](http://thegreenpizza.github.io/2013/05/25/building-minification-safe-angular.js-applications/), [ng-annotate automation tool](https://github.com/olov/ng-annotate)
* **Analytics and Logging:** [Angularyitcs (Google Analytics)](http://ngmodules.org/modules/angularytics), [Angulartics (Analytics)](https://github.com/luisfarzati/angulartics), [Logging Client-Side Errors](http://www.bennadel.com/blog/2542-Logging-Client-Side-Errors-With-AngularJS-And-Stacktrace-js.htm)
* **SEO:** [By hand](http://www.yearofmoo.com/2012/11/angularjs-and-seo.html), [prerender.io](http://prerender.io/), [Brombone](http://www.brombone.com/), [SEO.js](http://getseojs.com/), [SEO4Ajax](http://www.seo4ajax.com/)
### Server-Specific
* **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)
* **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)
* **PHP: **[Building a RESTful web service](http://blog.brunoscopelliti.com/building-a-restful-web-service-with-angularjs-and-php-more-power-with-resource), [End to End with Laravel 4 (video)](http://www.youtube.com/watch?v=hqAyiqUs93c)
* **Meteor: **[angular-meteor package](https://github.com/Urigo/angular-meteor)
## Learning Resources
###Books
* [AngularJS: Up and Running](http://www.amazon.com/AngularJS-Running-Enhanced-Productivity-Structured/dp/1491901942) by Brad Green and Shyam Seshadri
* [Mastering Web App Development](http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821) by Pawel Kozlowski and Pete Bacon Darwin
* [AngularJS Directives](http://www.amazon.com/AngularJS-Directives-Alex-Vanston/dp/1783280336) by Alex Vanston
* [Recipes With AngularJS](http://www.amazon.co.uk/Recipes-Angular-js-Frederik-Dietz-ebook/dp/B00DK95V48) by Frederik Dietz
* [Developing an AngularJS Edge](http://www.amazon.com/Developing-AngularJS-Edge-Christopher-Hiller-ebook/dp/B00CJLFF8K) by Christopher Hiller
* [ng-book: The Complete Book on AngularJS](http://ng-book.com/) by Ari Lerner
* [AngularJS : Novice to Ninja](http://www.amazon.in/AngularJS-Novice-Ninja-Sandeep-Panda/dp/0992279453) by Sandeep Panda
* [AngularJS UI Development](http://www.amazon.com/AngularJS-UI-Development-Amit-Ghart-ebook/dp/B00OXVAK7A) by Amit Gharat and Matthias Nehlsen
* [Responsive Web Design with AngularJS](http://www.amazon.com/Responsive-Design-AngularJS-Sandeep-Kumar/dp/178439842X) by Sandeep Kumar Patel
###Videos:
* [egghead.io](http://egghead.io/)
* [Angular on YouTube](http://youtube.com/angularjs)
### Courses
* **Free online:**
[thinkster.io](http://thinkster.io),
[CodeAcademy](http://www.codecademy.com/courses/javascript-advanced-en-2hJ3J/0/1),
[CodeSchool](https://www.codeschool.com/courses/shaping-up-with-angular-js)
* **Paid online:**
[Pluralsite (3 courses)](http://www.pluralsight.com/training/Courses/Find?highlight=true&searchTerm=angularjs),
[Tuts+](https://tutsplus.com/course/easier-js-apps-with-angular/),
[lynda.com](http://www.lynda.com/AngularJS-tutorials/Up-Running-AngularJS/133318-2.html),
[WintellectNOW (4 lessons)](http://www.wintellectnow.com/Course/Detail/mastering-angularjs)
* **Paid onsite:**
[angularbootcamp.com](http://angularbootcamp.com/)
## Getting Help
The recipe for getting help on your unique issue is to create an example that could work (even if it doesn't) in a shareable example on [Plunker](http://plnkr.co/), [JSFiddle](http://jsfiddle.net/), or similar site and then post to one of the following:
* [Stackoverflow.com](http://stackoverflow.com/search?q=angularjs)
* [AngularJS mailing list](https://groups.google.com/forum/#!forum/angular)
* [AngularJS IRC channel](http://webchat.freenode.net/?channels=angularjs&uio=d4)
* [Angular 1 mailing list](https://groups.google.com/forum/#!forum/angular)
* [Angular 1 IRC channel](http://webchat.freenode.net/?channels=angularjs&uio=d4)
## Social Channels
## Official Communications
* **Daily updates:** [Google+](https://plus.google.com/u/0/+AngularJS) or [Twitter](https://twitter.com/angularjs)
* **Weekly newsletter:** [ng-newsletter](http://www.ng-newsletter.com/)
* **Meetups: **[meetup.com](http://www.meetup.com/find/?keywords=angularJS&radius=Infinity&userFreeform=San+Francisco%2C+CA&mcId=z94108&mcName=San+Francisco%2C+CA&sort=member_count&eventFilter=mysugg)
* **Official news and releases: **[AngularJS Blog](http://blog.angularjs.org/)
Official announcements, news and releases are posted to our blog, G+ and Twitter:
## Contributing to AngularJS
* [Angular Blog](http://blog.angularjs.org/)
* [Google+](https://plus.google.com/u/0/+AngularJS)
* [Twitter](https://twitter.com/angularjs)
* [Angular on YouTube](http://youtube.com/angularjs)
Though we have a core group of core contributors at Google, Angular is an open source project with hundreds of contributors. We'd love you to be one of them. When you're ready, please read the {@link misc/contribute Guide for contributing to AngularJS}.
## Contributing to Angular 1
## Final Bits
Though we have a core group of core contributors at Google, Angular is an open source project with hundreds of contributors.
We'd love you to be one of them. When you're ready, please read the {@link misc/contribute Guide for contributing to Angular}.
Didn't find what you're looking for here? Check out [AngularJS-Learning](https://github.com/jmcunningham/AngularJS-Learning) for an even more comprehensive list of links to videos, tutorials, and blog posts.
## Something Missing?
If you have awesome AngularJS resources that belong on this page, please tell us about them on [Google+](https://plus.google.com/u/0/+AngularJS) or [Twitter](https://twitter.com/angularjs).
Didn't find what you're looking for here? Check out the {@link guide/external-resources External Angular 1 resources guide}.
If you have awesome Angular 1 resources that belong on that page, please tell us about them on
[Google+](https://plus.google.com/u/0/+AngularJS) or [Twitter](https://twitter.com/angularjs).
+159
View File
@@ -0,0 +1,159 @@
@ngdoc overview
@name Interpolation
@sortOrder 275
@description
# Interpolation and data-binding
Interpolation markup with embedded {@link guide/expression expressions} is used by Angular to
provide data-binding to text nodes and attribute values.
An example of interpolation is shown below:
```html
<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>
```
### How text and attribute bindings work
During the compilation process the {@link ng.$compile compiler} uses the {@link ng.$interpolate $interpolate}
service to see if text nodes and element attributes contain interpolation markup with embedded expressions.
If that is the case, the compiler adds an interpolateDirective to the node and
registers {@link ng.$rootScope.Scope#$watch watches} on the computed interpolation function,
which will update the corresponding text nodes or attribute values as part of the
normal {@link ng.$rootScope.Scope#$digest digest} cycle.
Note that the interpolateDirective has a priority of 100 and sets up the watch in the preLink function.
### Binding to boolean attributes
Attributes such as `disabled` are called `boolean` attributes, because their presence means `true` and
their absence means `false`. We cannot use normal attribute bindings with them, because the HTML
specification does not require browsers to preserve the values of boolean attributes. This means that
if we put an Angular interpolation expression into such an attribute then the binding information
would be lost, because the browser ignores the attribute value.
In the following example, the interpolation information would be ignored and the browser would simply
interpret the attribute as present, meaning that the button would always be disabled.
```html
Disabled: <input type="checkbox" ng-model="isDisabled" />
<button disabled="{{isDisabled}}">Disabled</button>
```
For this reason, Angular provides special `ng`-prefixed directives for the following boolean attributes:
{@link ngDisabled `disabled`}, {@link ngRequired `required`}, {@link ngSelected `selected`},
{@link ngChecked `checked`}, {@link ngReadonly `readOnly`} , and {@link ngOpen `open`}.
These directives take an expression inside the attribute, and set the corresponding boolean attribute
to true when the expression evaluates to truthy.
```html
Disabled: <input type="checkbox" ng-model="isDisabled" />
<button ng-disabled="isDisabled">Disabled</button>
```
### `ngAttr` for binding to arbitrary attributes
Web browsers are sometimes picky about what values they consider valid for attributes.
For example, considering this template:
```html
<svg>
<circle cx="{{cx}}"></circle>
</svg>
```
We would expect Angular to be able to bind to this, but when we check the console we see
something like `Error: Invalid value for attribute cx="{{cx}}"`. Because of the SVG DOM API's
restrictions, you cannot simply write `cx="{{cx}}"`.
With `ng-attr-cx` you can work around this problem.
If an attribute with a binding is prefixed with the `ngAttr` prefix (denormalized as `ng-attr-`)
then during the binding it will be applied to the corresponding unprefixed attribute. This allows
you to bind to attributes that would otherwise be eagerly processed by browsers
(e.g. an SVG element's `circle[cx]` attributes). When using `ngAttr`, the `allOrNothing` flag of
{@link ng.$interpolate $interpolate} is used, so if any expression in the interpolated string
results in `undefined`, the attribute is removed and not added to the element.
For example, we could fix the example above by instead writing:
```html
<svg>
<circle ng-attr-cx="{{cx}}"></circle>
</svg>
```
If one wants to modify a camelcased attribute (SVG elements have valid camelcased attributes),
such as `viewBox` on the `svg` element, one can use underscores to denote that the attribute to bind
to is naturally camelcased.
For example, to bind to `viewBox`, we can write:
```html
<svg ng-attr-view_box="{{viewBox}}">
</svg>
```
Other attributes may also not work as expected when they contain interpolation markup, and
can be used with `ngAttr` instead. The following is a list of known problematic attributes:
- **size** in `<select>` elements (see [issue 1619](https://github.com/angular/angular.js/issues/1619))
- **placeholder** in `<textarea>` in Internet Explorer 10/11 (see [issue 5025](https://github.com/angular/angular.js/issues/5025))
- **type** in `<button>` in Internet Explorer 11 (see [issue 14117](https://github.com/angular/angular.js/issues/5025))
- **value** in `<progress>` in Internet Explorer = 11 (see [issue 7218](https://github.com/angular/angular.js/issues/7218))
## Known Issues
### Dynamically changing an interpolated value
You should avoid dynamically changing the content of an interpolated string (e.g. attribute value
or text node). Your changes are likely to be overwriten, when the original string gets evaluated.
This restriction applies to both directly changing the content via JavaScript or indirectly using a
directive.
For example, you should not use interpolation in the value of the `style` attribute (e.g.
`style="color: {{ 'orange' }}; font-weight: {{ 'bold' }};"`) **and** at the same time use a
directive that changes the content of that attributte, such as `ngStyle`.
### Embedding interpolation markup inside expressions
<div class="alert alert-danger">
**Note:** Angular directive attributes take either expressions *or* interpolation markup with embedded expressions.
It is considered **bad practice** to embed interpolation markup inside an expression:
</div>
```html
<div ng-show="form{{$index}}.$invalid"></div>
```
You should instead delegate the computation of complex expressions to the scope, like this:
```html
<div ng-show="getForm($index).$invalid"></div>
```
```js
function getForm(index) {
return $scope['form' + index];
}
```
You can also access the `scope` with `this` in your templates:
```html
<div ng-show="this['form' + $index].$invalid"></div>
```
#### Why mixing interpolation and expressions is bad practice:
- It increases the complexity of the markup
- There is no guarantee that it works for every directive, because interpolation itself is a directive.
If another directive accesses attribute data before interpolation has run, it will get the raw
interpolation markup and not data.
- It impacts performance, as interpolation adds another watcher to the scope.
- Since this is not recommended usage, we do not test for this, and changes to
Angular core may break your code.
+435 -71
View File
@@ -3,17 +3,246 @@
@sortOrder 550
@description
# Migrating an App to a newer version
Minor version releases in AngularJS introduce several breaking changes that may require changes to your
application's source code; for instance from 1.0 to 1.2 and from 1.2 to 1.3.
Although we try to avoid breaking changes, there are some cases where it is unavoidable.
Although we try to avoid breaking changes, there are some cases where it is unavoidable:
* AngularJS has undergone thorough security reviews to make applications safer by default,
which drives many of these changes.
* Several new features, especially animations, would not be possible without a few changes.
* Finally, some outstanding bugs were best fixed by changing an existing API.
# Migrating from 1.3 to 1.4
## Contents
<ul class="nav nav-list">
<li>{@link guide/migration#migrating-from-1-4-to-1-5 Migrating from 1.4 to 1.5}</li>
<li>{@link guide/migration#migrating-from-1-3-to-1-4 Migrating from 1.3 to 1.4}</li>
<li>{@link guide/migration#migrating-from-1-2-to-1-3 Migrating from 1.2 to 1.3}</li>
<li>{@link guide/migration#migrating-from-1-0-to-1-2 Migrating from 1.0 to 1.2}</li>
</ul>
## Migrating from 1.4 to 1.5
Angular 1.5 takes a big step towards preparing developers for a smoother transition to Angular 2 in
the future. Architecturing your applications using components, multi-slot transclusion, one-way
bindings in isolate scopes, using lifecycle hooks in directive controllers and relying on native ES6
features (such as classes and arrow functions) are now all possible with Angular 1.5.
This release includes numerous bug and security fixes, as well as performance improvements to core
services, directives, filters and helper functions. Existing applications can start enjoying the
benefits of such changes in `$compile`, `$parse`, `$animate`, `$animateCss`, `$sanitize`, `ngOptions`,
`currencyFilter`, `numberFilter`, `copy()` (to name but a few) without any change in code.
New features have been added to more than a dozen services, directives and filters across 8 modules.
Among them, a few stand out:
* `angular.component()`: Introducing "components", a special sort of directive that are easy to
configure and promote best practices (plus can bring Angular 1 applications closer to Angular 2's
style of architecture).
* Multi-slot transclusion: Enabling the design of more powerful and complex UI elements with a much
simpler configuration and reduced boilerplate.
* `$onInit` lifecycle hook: Introducing a new lifecycle hook for directive controllers, called after
all required controllers have been constructed. This enables access to required controllers from
a directive's controller, without having to rely on the linking function.
* `ngAnimateSwap`: A new directive in `ngAnimate`, making it super easy to create rotating
banner-like components.
* Testing helpers: New helper functions in `ngMock`, simplifying testing for animations, component
controllers and routing.
Also, notable is the improved support for ES6 features, such as classes and arrow functions. These
features are now more reliably detected and correctly handled within the core.
All this goodness doesn't come without a price, though. Below is a list of breaking changes (grouped
by module) that need to be taken into account while migrating from 1.4. Fortunately, the majority of
them should have a pretty low impact on most applications.
### Core
We tried to keep the breaking changes inside the core components to a bare minimum. Still, a few of
them were unavoidable.
#### Services (`$parse`)
Due to [0ea53503](https://github.com/angular/angular.js/commit/0ea535035a3a1a992948490c3533bffb83235052),
a new special property, `$locals`, will be available for accessing the locals from an expression.
This is a breaking change, only if a `$locals` property does already exist (and needs to be
referenced) either on the `scope` or on the `locals` object. Your expressions should be changed to
access such existing properties as `this.$locals` and `$locals.$locals` respectively.
#### Directives (`ngOptions`)
A fair amount of work has been put into the `ngOptions` directive, fixing bugs and corner-cases and
neutralizing browser quirks. A couple of breaking changes were made in the process:
Due to [b71d7c3f](https://github.com/angular/angular.js/commit/b71d7c3f3c04e65b02d88b33c22dd90ae3cdfc27),
falsy values (`''`, `0`, `false` and `null`) are properly recognized as option group identifiers for
options passed to `ngOptions`. Previously, all of these values were ignored and the option was not
assigned to any group. `undefined` is still interpreted as "no group".
If you have options with falsy group indentifiers that should still not be assigned to any group,
then you must filter the values before passing them to `ngOptions`, converting falsy values to
`undefined`.
Due to [ded25187](https://github.com/angular/angular.js/commit/ded2518756d4409fdfda0d4af243f2125bea01b5),
`ngOptions` now explicitly requires `ngModel` on the same element, thus an error will be thrown if
`ngModel` is not found. Previously, `ngOptions` would silently fail, which could lead to
hard-to-debug errors.
This is not expected to have any significant impact on applications, since `ngOptions` didn't work
without `ngModel` before either. The main difference is that now it will fail with a more
informative error message.
#### Filters (`orderBy`)
Due to [2a85a634](https://github.com/angular/angular.js/commit/2a85a634f86c84f15b411ce009a3515fca7ba580),
passing a non-array-like value (other than `undefined` or `null`) through the `orderBy` filter will
throw an error. Previously, the input was returned unchanged, which could lead to hard-to-spot bugs
and was not consistent with other filters (e.g. `filter`).
Objects considered array-like include: arrays, array subclasses, strings, NodeLists,
jqLite/jQuery collections
### ngAria
Due to [d06431e](https://github.com/angular/angular.js/commit/d06431e5309bb0125588877451dc79b935808134),
the `ngAria`-enhanced directives (e.g. `ngModel`, `ngDisabled` etc) will not apply ARIA attributes
to native inputs, unless necessary. Previously, ARIA attributes were always applied to native
inputs, despite this being unnecessary in most cases.
In the context of `ngAria`, elements considered "native inputs" include:
`<a>`, `<button>`, `<details>`, `<input>`, `<select>`, `<summary>`, `<textarea>`
This change will not affect the accessibility of your applications (since native inputs are
accessible by default), but if you relied on ARIA attributes being present on native inputs (for
whatever reason), you'll have to add and update them manually.
Additionally, the `aria-multiline` attribute, which was previously added to elements with a `type`
or `role` of `textbox`, will not be added anymore, since there is no way `ngAria` can tell if the
textbox element is multiline or not.
If you relied on `aria-multiline="true"` being automatically added by `ngAria`, you need to apply it
yourself. E.g. change your code from `<div role="textbox" ng-model="..." ...>` to
`<div role="textbox" ng-model="..." ... aria-multiline="true">`.
### ngMessages (`ngMessage`)
Due to [4971ef12](https://github.com/angular/angular.js/commit/4971ef12d4c2c268cb8d26f90385dc96eba19db8),
the `ngMessage` directive is now compiled with a priority of 1, which means directives on the same
element as `ngMessage` with a priority lower than 1 will be applied when `ngMessage` calls its
`$transclude` function. Previously, they were applied during the initial compile phase and were
passed the comment element created by the transclusion of `ngMessage`.
If you have custom directives that relied on the previous behavior, you need to give them a priority
of 1 or greater.
### ngResource (`$resource`)
The `$resource` service underwent a minor internal refactoring to finally solve a long-standing bug
preventing requests from being cancelled using promises. Due to the nature of `$resource`'s
configuration, it was not possible to follow the `$http` convention. A new `$cancelRequest()` method
was introduced instead.
Due to [98528be3](https://github.com/angular/angular.js/commit/98528be311b48269ba0e15ba4e3e2ad9b89693a9),
using a promise as `timeout` in `$resource` is no longer supported and will log a warning. This is
hardly expected to affect the behavior of your application, since a promise as `timeout` didn't work
before either, but it will now warn you explicitly when trying to pass one.
If you need to be able to cancel pending requests, you can now use the new `$cancelRequest()` that
will be available on `$resource` instances.
### ngRoute (`ngView`)
Due to [983b0598](https://github.com/angular/angular.js/commit/983b0598121a8c5a3a51a30120e114d7e3085d4d),
a new property will be available on the scope of the route, allowing easy access to the route's
resolved values from the view's template. The default name for this property is `$resolve`. This is
a breaking change, only if a `$resolve` property is already available on the scope, in which case
the existing property will be hidden or overwritten.
To fix this, you should choose a custom name for this property, that does not collide with other
properties on the scope, by specifying the `resolveAs` property on the route.
### ngSanitize (`$sanitize`, `linky`)
The HTML sanitizer has been re-implemented using inert documents, increasing security, fixing some
corner-cases that were difficult to handle and reducing its size by about 20% (in terms of loc). In
order to make it more secure by default, a couple of breaking changes have been introduced:
Due to [181fc567](https://github.com/angular/angular.js/commit/181fc567d873df065f1e84af7225deb70a8d2eb9),
SVG support in `$sanitize` is now an opt-in feature (i.e. disabled by default), as it could make
an application vulnerable to click-hijacking attacks. If your application relies on it, you can
still turn it on with `$sanitizeProvider.enableSvg(true)`, but you extra precautions need to be
taken in order to keep your application secure. Read the documentation for more information about
the dangers and ways to mitigate them.
Due to [7a668cdd](https://github.com/angular/angular.js/commit/7a668cdd7d08a7016883eb3c671cbcd586223ae8),
the `$sanitize` service will now remove instances of the `<use>` tag from the content passed to it.
This element is used to import external SVG resources, which is a security risk as the `$sanitize`
service does not have access to the resource in order to sanitize it.
Similarly, due to [234053fc](https://github.com/angular/angular.js/commit/234053fc9ad90e0d05be7e8359c6af66be94c094),
the `$sanitize` service will now also remove instances of the `usemap` attribute from any elements
passed to it. This attribute is used to reference another element by `name` or `id`. Since the
`name` and `id` attributes are already blacklisted, a sanitized `usemap` attribute could only
reference unsanitized content, which is a security risk.
Due to [98c2db7f](https://github.com/angular/angular.js/commit/98c2db7f9c2d078a408576e722407d518c7ee10a),
passing a non-string value (other than `undefined` or `null`) through the `linky` filter will throw
an error. This is not expected to have any significant impact on applications, since the input was
always assumed to be of type 'string', so passing non-string values never worked correctly anyway.
The main difference is that now it will fail faster and with a more informative error message.
## ngTouch (`ngClick`)
Due to [0dfc1dfe](https://github.com/angular/angular.js/commit/0dfc1dfebf26af7f951f301c4e3848ac46f05d7f),
the `ngClick` override directive from the `ngTouch` module is **deprecated and disabled by default**.
This means that on touch-based devices, users might now experience a 300ms delay before a click
event is fired.
If you rely on this directive, you can still enable it using
`$touchProvider.ngClickOverrideEnabled()`:
```js
angular.module('myApp').config(function($touchProvider) {
$touchProvider.ngClickOverrideEnabled(true);
});
```
Going forward, we recommend using [FastClick](https://github.com/ftlabs/fastclick) or perhaps one of
the [Angular 3rd party touch-related modules](http://ngmodules.org/tags/touch) that provide similar
functionality.
Also note that modern browsers already remove the 300ms delay under some circumstances:
- **Chrome and Firefox for Android** remove the 300ms delay when the well-known
`<meta name="viewport" content="width=device-width">` is set.
- **Internet Explorer** removes the delay, when the `touch-action` css property is set to `none` or
`manipulation`.
- Since **iOS 8, Safari** removes the delay on so-called "slow taps".
For more info on the topic, you can take a look at this
[article by Telerik](http://developer.telerik.com/featured/300-ms-click-delay-ios-8/).
<div class="alert alert-warning">
**Note:** This change does **not** affect the `ngSwipe` directive.
</div>
## Migrating from 1.3 to 1.4
Angular 1.4 fixes major animation issues and introduces a new API for `ngCookies`. Further, there
are changes to `ngMessages`, `$compile`, `ngRepeat`, `ngOptions `and some fixes to core filters:
@@ -37,7 +266,7 @@ relatively straightforward otherwise.
## Animation (`ngAnimate`)
### Animation (`ngAnimate`)
Animations in 1.4 have been refactored internally, but the API has stayed much the same. There are, however,
some breaking changes that need to be addressed when upgrading to 1.4.
@@ -136,9 +365,9 @@ class based animations (animations triggered via ngClass) in order to ensure tha
## Forms (`ngMessages`, `ngOptions`, `select`)
### Forms (`ngMessages`, `ngOptions`, `select`)
### ngMessages
#### ngMessages
The ngMessages module has also been subject to an internal refactor to allow it to be more flexible
and compatible with dynamic message data. The `ngMessage` directive now supports a new attribute
called `ng-message-exp` which will evaluate an expression and will keep track of that expression
@@ -170,7 +399,26 @@ other inline messages situated as children within the `ngMessages` container dir
Depending on where the `ngMessagesInclude` directive is placed it will be prioritized inline with the other messages
before and after it.
### ngOptions
Also due to [c9a4421f](https://github.com/angular/angular.js/commit/c9a4421fc3c97448527eadef1f42eb2f487ec2e0),
it is no longer possible to use interpolation inside the `ngMessages` attribute expression. This technique
is generally not recommended, and can easily break when a directive implementation changes. In cases
where a simple expression is not possible, you can delegate accessing the object to a function:
```html
<div ng-messages="ctrl.form['field_{{$index}}'].$error">...</div>
```
would become
```html
<div ng-messages="ctrl.getMessages($index)">...</div>
```
where `ctrl.getMessages()`
```javascript
ctrl.getMessages = function($index) {
return ctrl.form['field_' + $index].$error;
}
```
#### ngOptions
The `ngOptions` directive has also been refactored and as a result some long-standing bugs
have been fixed. The breaking changes are comparatively minor and should not affect most applications.
@@ -189,13 +437,18 @@ But in practice this is not what people want and so this change iterates over pr
in the order they are returned by Object.keys(obj), which is almost always the order
in which the properties were defined.
Also due to [7fda214c](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef),
setting the ngOptions attribute expression after the element is compiled, will no longer trigger the ngOptions behavior.
This worked previously because the ngOptions logic was part of the select directive, while
it is now implemented in the ngOptions directive itself.
### select
#### select
Due to [7fda214c](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef),
the `select` directive will now use strict comparison of the `ngModel` scope value against `option`
values to determine which option is selected. This means `Number` scope values will not be matched
against numeric option strings.
values to determine which option is selected. This means non-string scope values (such as `Number` or `Boolean`)
will not be matched against equivalent option strings (such as the strings `"123"`, `"true"` or `"false"`).
In Angular 1.3.x, setting `scope.x = 200` would select the option with the value 200 in the following `select`:
```
@@ -206,7 +459,8 @@ In Angular 1.3.x, setting `scope.x = 200` would select the option with the value
```
In Angular 1.4.x, the 'unknown option' will be selected.
To remedy this, you can simply initialize the model as a string: `scope.x = '200'`, or if you want to
To remedy this, you can initialize the model as a string: `scope.x = '200'`, or if you want to
keep the model as a `Number`, you can do the conversion via `$formatters` and `$parsers` on `ngModel`:
```js
@@ -219,9 +473,50 @@ ngModelCtrl.$formatters.push(function(value) {
});
```
## Templating (`ngRepeat`, `$compile`)
### ngRepeat
### form
Due to [94533e57](https://github.com/angular/angular.js/commit/94533e570673e6b2eb92073955541fa289aabe02),
the `name` attribute of `form` elements can now only contain characters that can be evaluated as part
of an Angular expression. This is because Angular uses the value of `name` as an assignable expression
to set the form on the `$scope`. For example, `name="myForm"` assigns the form to `$scope.myForm` and
`name="myObj.myForm"` assigns it to `$scope.myObj.myForm`.
Previously, it was possible to also use names such `name="my:name"`, because Angular used a special setter
function for the form name. Now the general, more robust `$parse` setter is used.
The easiest way to migrate your code is therefore to remove all special characters from the `name` attribute.
If you need to keep the special characters, you can use the following directive, which will replace
the `name` with a value that can be evaluated as an expression in the compile function, and then
re-set the original name in the postLink function. This ensures that (1), the form is published on
the scope, and (2), the form has the original name, which might be important if you are doing server-side
form submission.
```js
angular.module('myApp').directive('form', function() {
return {
restrict: 'E',
priority: 1000,
compile: function(element, attrs) {
var unsupportedCharacter = ':'; // change accordingly
var originalName = attrs.name;
if (attrs.name && attrs.name.indexOf(unsupportedCharacter) > 0) {
attrs.$set('name', 'this["' + originalName + '"]');
}
return postLinkFunction(scope, element) {
// Don't trigger $observers
element.setAttribute('name', originalName);
}
}
};
});
```
### Templating (`ngRepeat`, `$compile`, `ngInclude`)
#### ngRepeat
Due to [c260e738](https://github.com/angular/angular.js/commit/c260e7386391877625eda086480de73e8a0ba921),
previously, the order of items when using ngRepeat to iterate over object properties was guaranteed to be consistent
@@ -240,7 +535,7 @@ https://github.com/petebacondarwin/angular-toArrayFilter
or some other mechanism, and then sort them manually in the order you need.
### $compile
#### $compile
Due to [6a38dbfd](https://github.com/angular/angular.js/commit/6a38dbfd3c34c8f9efff503d17eb3cbeb666d422),
previously, '&' expressions would always set up a function in the isolate scope. Now, if the binding
@@ -248,10 +543,48 @@ is marked as optional and the attribute is not specified, no function will be ad
Due to [62d514b](https://github.com/angular/angular.js/commit/62d514b06937cc7dd86e973ea11165c88343b42d),
returning an object from a controller constructor function will now override the scope. Views that use the
controllerAs method will no longer get the this reference, but the returned object.
controllerAs method will no longer get the this reference, but the returned object.
#### ngInclude
Due to [3c6e8ce044446735eb2e70d0061db8c6db050289](https://github.com/angular/angular.js/commit/3c6e8ce044446735eb2e70d0061db8c6db050289), the `src` attribute of ngInclude no longer accepts an
expression that returns the result of `$sce.trustAsResourceUrl`. This will now cause an infinite digest:
Before:
```html
<div ng-include="findTemplate('https://example.com/templates/myTemplate.html')"></div>
```
```js
$scope.findTemplate = function(templateName) {
return $sce.trustAsResourceUrl(templateName);
};
```
To migrate, either cache the result of `trustAsResourceUrl()`, or put the template url in the resource
whitelist in the `config()` function:
After:
```js
var templateCache = {};
$scope.findTemplate = function(templateName) {
if (!templateCache[templateName]) {
templateCache[templateName] = $sce.trustAsResourceUrl(templateName);
}
return templateCache[templateName];
};
// Alternatively, use `$sceDelegateProvider.resourceUrlWhitelist()`, which means you don't
// have to use `$sce.trustAsResourceUrl()` at all:
angular.module('myApp', []).config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist(['self', 'https://example.com/templates/**'])
});
```
## Cookies (`ngCookies`)
### Cookies (`ngCookies`)
Due to [38fbe3ee](https://github.com/angular/angular.js/commit/38fbe3ee8370fc449b82d80df07b5c2ed2cd5fbe),
`$cookies` will no longer expose properties that represent the current browser cookie
@@ -288,9 +621,7 @@ has been moved to `$cookies`, to which `$cookieStore` now simply
delegates calls.
## Server Requests (`$http`)
### Server Requests (`$http`)
Due to [5da1256](https://github.com/angular/angular.js/commit/5da1256fc2812d5b28fb0af0de81256054856369),
`transformRequest` functions can no longer modify request headers.
@@ -321,11 +652,9 @@ $http.get(url, {
```
### Filters (`filter`, `limitTo`)
## Filters (`filter`, `limitTo`)
### `filter` filter
#### `filter` filter
Due to [cea8e751](https://github.com/angular/angular.js/commit/cea8e75144e6910b806b63a6ec2a6d118316fddd),
the `filter` filter will throw an error when used with a non-array. Beforehand it would silently
return an empty array.
@@ -333,7 +662,7 @@ return an empty array.
If necessary, this can be worked around by converting an object to an array,
using a filter such as https://github.com/petebacondarwin/angular-toArrayFilter.
### `limitTo` filter
#### `limitTo` filter
Due to [a3c3bf33](https://github.com/angular/angular.js/commit/a3c3bf3332e5685dc319c46faef882cb6ac246e1),
the limitTo filter has changed behavior when the provided limit value is invalid.
Now, instead of returning empty object/array, it returns unchanged input.
@@ -341,10 +670,9 @@ Now, instead of returning empty object/array, it returns unchanged input.
## Migrating from 1.2 to 1.3
# Migrating from 1.2 to 1.3
## Controllers
### Controllers
Due to [3f2232b5](https://github.com/angular/angular.js/commit/3f2232b5a181512fac23775b1df4a6ebda67d018),
`$controller` will no longer look for controllers on `window`.
@@ -382,7 +710,7 @@ angular.module('myModule').config(['$controllerProvider', function($controllerPr
}]);
```
## Angular Expression Parsing (`$parse` + `$interpolate`)
### Angular Expression Parsing (`$parse` + `$interpolate`)
- due to [77ada4c8](https://github.com/angular/angular.js/commit/77ada4c82d6b8fc6d977c26f3cdb48c2f5fbe5a5),
@@ -440,7 +768,7 @@ expression parser; there are six of them: false, null, undefined, NaN, 0 and "".
## Miscellaneous Angular helpers
### Miscellaneous Angular helpers
- **Angular.copy:** due to [b59b04f9](https://github.com/angular/angular.js/commit/b59b04f98a0b59eead53f6a53391ce1bbcbe9b57),
@@ -471,15 +799,14 @@ This change also makes our forEach behave more like Array#forEach.
- **angular.toJson:** due to [c054288c](https://github.com/angular/angular.js/commit/c054288c9722875e3595e6e6162193e0fb67a251),
If you expected `toJson` to strip these types of properties before, you will have to
manually do this yourself now.
`toJson()` will no longer strip properties starting with a single `$`. If you relied on
`toJson()`'s stripping these types of properties before, you will have to do it manually now.
It will still strip properties starting with `$$` though.
## jqLite / JQuery
### jqLite / JQuery
- **jqLite:** due to [a196c8bc](https://github.com/angular/angular.js/commit/a196c8bca82a28c08896d31f1863cf4ecd11401c),
previously it was possible to set jqLite data on Text/Comment
@@ -495,7 +822,7 @@ jQuery. We don't expect that app code actually depends on this accidental featur
## Angular HTML Compiler (`$compile`)
### Angular HTML Compiler (`$compile`)
- due to [2ee29c5d](https://github.com/angular/angular.js/commit/2ee29c5da81ffacdc1cabb438f5d125d5e116cb9),
@@ -559,10 +886,40 @@ After:
};
});
- due to [531a8de7](https://github.com/angular/angular.js/commit/531a8de72c439d8ddd064874bf364c00cedabb11),
`$observe` no longer registers on undefined attributes. For example, if you were using `$observe` on
an absent optional attribute to set a default value, the following would not work anymore:
```html
<my-dir></my-dir>
```
```js
// Link function for directive myDir
link: function(scope, element, attr) {
attr.$observe('myAttr', function(newVal) {
scope.myValue = newVal ? newVal : 'myDefaultValue';
})
}
```
Instead, check if the attribute is set before registering the observer:
```js
link: function(scope, element, attr) {
if (attr.myAttr) {
// register the observer
} else {
// set the default
}
}
```
## Forms, Inputs and ngModel
### Forms, Inputs and ngModel
- due to [1be9bb9d](https://github.com/angular/angular.js/commit/1be9bb9d3527e0758350c4f7417a4228d8571440),
@@ -631,11 +988,18 @@ $scope.resetWithCancel = function (e) {
[#5864](https://github.com/angular/angular.js/issues/5864))
- {@link input[checkbox] `input[checkbox]`} now supports constant expressions in `ngTrueValue` and
`ngFalseValue`, making it now possible to e.g. use boolean and integer values. Previously, these attributes would
always be treated as strings, whereas they are now parsed as expressions, and will throw if an expression
is non-constant. To convert non-constant strings into constant expressions, simply wrap them in an
extra pair of quotes, like so:
`<input type="checkbox" ng-model="..." ng-true-value="'truthyValue'">`
See [c90cefe1614](https://github.com/angular/angular.js/commit/c90cefe16142d973a123e945fc9058e8a874c357)
## Scopes and Digests (`$scope`)
### Scopes and Digests (`$scope`)
- due to [8c6a8171](https://github.com/angular/angular.js/commit/8c6a8171f9bdaa5cdabc0cc3f7d3ce10af7b434d),
Scope#$id is now of type number rather than string. Since the
@@ -655,7 +1019,7 @@ anyone.
## Server Requests (`$http`, `$resource`)
### Server Requests (`$http`, `$resource`)
- **$http:** due to [ad4336f9](https://github.com/angular/angular.js/commit/ad4336f9359a073e272930f8f9bcd36587a8648f),
@@ -722,7 +1086,7 @@ More details on the new interceptors API (which has been around as of v1.1.4) ca
## Modules and Injector (`$inject`)
### Modules and Injector (`$inject`)
- due to [c0b4e2db](https://github.com/angular/angular.js/commit/c0b4e2db9cbc8bc3164cedc4646145d3ab72536e),
@@ -764,7 +1128,7 @@ app. This is no longer possible within a single module.
## Animation (`ngAnimate`)
### Animation (`ngAnimate`)
- due to [1cb8584e](https://github.com/angular/angular.js/commit/1cb8584e8490ecdb1b410a8846c4478c6c2c0e53),
@@ -786,7 +1150,7 @@ to:
Any class-based animation code that makes use of transitions
and uses the setup CSS classes (such as class-add and class-remove) must now
provide a empty transition value to ensure that its styling is applied right
provide an empty transition value to ensure that its styling is applied right
away. In other words if your animation code is expecting any styling to be
applied that is defined in the setup class then it will not be applied
"instantly" unless a `transition:0s none` value is present in the styling
@@ -817,7 +1181,7 @@ After:
Please view the documentation for ngAnimate for more info.
## Testing
### Testing
- due to [85880a64](https://github.com/angular/angular.js/commit/85880a64900fa22a61feb926bf52de0965332ca5), some deprecated features of
Protractor tests no longer work.
@@ -856,7 +1220,7 @@ or simply use:
var el = element(by.repeater('foo in foos').row(2))
## Internet Explorer 8
### Internet Explorer 8
- due to [eaa1d00b](https://github.com/angular/angular.js/commit/eaa1d00b24008f590b95ad099241b4003688cdda),
As communicated before, IE8 is no longer supported.
@@ -866,7 +1230,7 @@ or simply use:
# Migrating from 1.0 to 1.2
## Migrating from 1.0 to 1.2
<div class="alert alert-warning">
@@ -909,7 +1273,7 @@ below should still apply, but you may want to consult the
</ul>
## ngRoute has been moved into its own module
### ngRoute has been moved into its own module
Just like `ngResource`, `ngRoute` is now its own module.
@@ -940,7 +1304,7 @@ var myApp = angular.module('myApp', ['ngRoute', 'someOtherModule']);
See [5599b55b](https://github.com/angular/angular.js/commit/5599b55b04788c2e327d7551a4a699d75516dd21).
## Templates no longer automatically unwrap promises
### Templates no longer automatically unwrap promises
`$parse` and templates in general will no longer automatically unwrap promises.
@@ -974,7 +1338,7 @@ See [5dc35b52](https://github.com/angular/angular.js/commit/5dc35b527b3c99f6544b
[b6a37d11](https://github.com/angular/angular.js/commit/b6a37d112b3e1478f4d14a5f82faabf700443748).
## Syntax for named wildcard parameters changed in `$route`
### Syntax for named wildcard parameters changed in `$route`
To migrate the code, follow the example below. Here, `*highlight` becomes `:highlight*`
@@ -995,7 +1359,7 @@ $routeProvider.when('/Book1/:book/Chapter/:chapter/:highlight*/edit',
See [04cebcc1](https://github.com/angular/angular.js/commit/04cebcc133c8b433a3ac5f72ed19f3631778142b).
## You can only bind one expression to `*[src]`, `*[ng-src]` or `action`
### You can only bind one expression to `*[src]`, `*[ng-src]` or `action`
With the exception of `<a>` and `<img>` elements, you cannot bind more than one expression to the
`src` or `action` attribute of elements.
@@ -1070,7 +1434,7 @@ scope.getIframeSrc = function() {
See [38deedd6](https://github.com/angular/angular.js/commit/38deedd6e3d806eb8262bb43f26d47245f6c2739).
## Interpolations inside DOM event handlers are now disallowed
### Interpolations inside DOM event handlers are now disallowed
DOM event handlers execute arbitrary Javascript code. Using an interpolation for such handlers
means that the interpolated value is a JS string that is evaluated. Storing or generating such
@@ -1097,7 +1461,7 @@ HTML: <div ng-click="foo()">
See [39841f2e](https://github.com/angular/angular.js/commit/39841f2ec9b17b3b2920fd1eb548d444251f4f56).
## Directives cannot end with -start or -end
### Directives cannot end with -start or -end
This change was necessary to enable multi-element directives. The best fix is to rename existing
directives so that they don't end with these suffixes.
@@ -1105,7 +1469,7 @@ directives so that they don't end with these suffixes.
See [e46100f7](https://github.com/angular/angular.js/commit/e46100f7097d9a8f174bdb9e15d4c6098395c3f2).
## In $q, promise.always has been renamed promise.finally
### In $q, promise.always has been renamed promise.finally
The reason for this change is to align `$q` with the [Q promise
library](https://github.com/kriskowal/q), despite the fact that this makes it a bit more difficult
@@ -1137,7 +1501,7 @@ $http.get('/foo')['finally'](doSomething);
See [f078762d](https://github.com/angular/angular.js/commit/f078762d48d0d5d9796dcdf2cb0241198677582c).
## ngMobile is now ngTouch
### ngMobile is now ngTouch
Many touch-enabled devices are not mobile devices, so we decided to rename this module to better
reflect its concerns.
@@ -1148,7 +1512,7 @@ To migrate, replace all references to `ngMobile` with `ngTouch` and `angular-mob
See [94ec84e7](https://github.com/angular/angular.js/commit/94ec84e7b9c89358dc00e4039009af9e287bbd05).
## resource.$then has been removed
### resource.$then has been removed
Resource instances do not have a `$then` function anymore. Use the `$promise.then` instead.
@@ -1167,7 +1531,7 @@ Resource.query().$promise.then(callback);
See [05772e15](https://github.com/angular/angular.js/commit/05772e15fbecfdc63d4977e2e8839d8b95d6a92d).
## Resource methods return the promise
### Resource methods return the promise
Methods of a resource instance return the promise rather than the instance itself.
@@ -1187,7 +1551,7 @@ resource.chaining = true;
See [05772e15](https://github.com/angular/angular.js/commit/05772e15fbecfdc63d4977e2e8839d8b95d6a92d).
## Resource promises are resolved with the resource instance
### Resource promises are resolved with the resource instance
On success, the resource promise is resolved with the resource instance rather than HTTP response object.
@@ -1218,7 +1582,7 @@ var Resource = $resource('/url', {}, {
See [05772e15](https://github.com/angular/angular.js/commit/05772e15fbecfdc63d4977e2e8839d8b95d6a92d).
## $location.search supports multiple keys
### $location.search supports multiple keys
{@link ng.$location#search `$location.search`} now supports multiple keys with the
same value provided that the values are stored in an array.
@@ -1235,7 +1599,7 @@ passing it to `$location`.
See [80739409](https://github.com/angular/angular.js/commit/807394095b991357225a03d5fed81fea5c9a1abe).
## ngBindHtmlUnsafe has been removed and replaced by ngBindHtml
### ngBindHtmlUnsafe has been removed and replaced by ngBindHtml
`ngBindHtml` provides `ngBindHtmlUnsafe` like
behavior (evaluate an expression and innerHTML the result into the DOM) when bound to the result
@@ -1251,7 +1615,7 @@ trusted.
See [dae69473](https://github.com/angular/angular.js/commit/dae694739b9581bea5dbc53522ec00d87b26ae55).
## Form names that are expressions are evaluated
### Form names that are expressions are evaluated
If you have form names that will evaluate as an expression:
@@ -1283,7 +1647,7 @@ Supporting the previous behavior offers no benefit.
See [8ea802a1](https://github.com/angular/angular.js/commit/8ea802a1d23ad8ecacab892a3a451a308d9c39d7).
## hasOwnProperty disallowed as an input name
### hasOwnProperty disallowed as an input name
Inputs with name equal to `hasOwnProperty` are not allowed inside form or ngForm directives.
@@ -1294,7 +1658,7 @@ and bad practice. To migrate, change your input name.
See [7a586e5c](https://github.com/angular/angular.js/commit/7a586e5c19f3d1ecc3fefef084ce992072ee7f60).
## Directives: Order of postLink functions reversed
### Directives: Order of postLink functions reversed
The order of postLink fn is now mirror opposite of the order in which corresponding preLinking and compile functions execute.
@@ -1350,7 +1714,7 @@ attribute interpolation directive was adjusted.
See [31f190d4](https://github.com/angular/angular.js/commit/31f190d4d53921d32253ba80d9ebe57d6c1de82b).
## Directive priority
### Directive priority
the priority of ngRepeat, ngSwitchWhen, ngIf, ngInclude and ngView has changed. This could affect directives that explicitly specify their priority.
@@ -1368,7 +1732,7 @@ ngView | 1000 | 400
See [b7af76b4](https://github.com/angular/angular.js/commit/b7af76b4c5aa77648cc1bfd49935b48583419023).
## ngScenario
### ngScenario
browserTrigger now uses an eventData object instead of direct parameters for mouse events.
To migrate, place the `keys`,`x` and `y` parameters inside of an object and place that as the
@@ -1377,7 +1741,7 @@ third parameter for the browserTrigger function.
See [28f56a38](https://github.com/angular/angular.js/commit/28f56a383e9d1ff378e3568a3039e941c7ffb1d8).
## ngInclude and ngView replace its entire element on update
### ngInclude and ngView replace its entire element on update
Previously `ngInclude` and `ngView` only updated its element's content. Now these directives will
recreate the element every time a new content is included.
@@ -1389,7 +1753,7 @@ See [7d69d52a](https://github.com/angular/angular.js/commit/7d69d52acff8578e0f7d
[aa2133ad](https://github.com/angular/angular.js/commit/aa2133ad818d2e5c27cbd3933061797096356c8a).
## URLs are now sanitized against a whitelist
### URLs are now sanitized against a whitelist
A whitelist configured via `$compileProvider` can be used to configure what URLs are considered safe.
By default all common protocol prefixes are whitelisted including `data:` URIs with mime types `image/*`.
@@ -1399,7 +1763,7 @@ See [1adf29af](https://github.com/angular/angular.js/commit/1adf29af13890d612868
[3e39ac7e](https://github.com/angular/angular.js/commit/3e39ac7e1b10d4812a44dad2f959a93361cd823b).
## Isolate scope only exposed to directives with `scope` property
### Isolate scope only exposed to directives with `scope` property
If you declare a scope option on a directive, that directive will have an
[isolate scope](https://github.com/angular/angular.js/wiki/Understanding-Scopes). In Angular 1.0, if a
@@ -1472,7 +1836,7 @@ See [909cabd3](https://github.com/angular/angular.js/commit/909cabd36d779598763c
[#2500](https://github.com/angular/angular.js/issues/2500).
## Change to interpolation priority
### Change to interpolation priority
Previously, the interpolation priority was `-100` in 1.2.0-rc.2, and `100` before 1.2.0-rc.2.
Before this change the binding was setup in the post-linking phase.
@@ -1485,7 +1849,7 @@ See [79223eae](https://github.com/angular/angular.js/commit/79223eae502283889334
[#4528](https://github.com/angular/angular.js/issues/4528), and
[#4649](https://github.com/angular/angular.js/issues/4649)
## Underscore-prefixed/suffixed properties are non-bindable
### Underscore-prefixed/suffixed properties are non-bindable
<div class="alert alert-info">
<p>**Reverted**: This breaking change has been reverted in 1.2.1, and so can be ignored if you're using **version 1.2.1 or higher**</p>
@@ -1524,7 +1888,7 @@ are actually needed by the expressions.
See [3d6a89e8](https://github.com/angular/angular.js/commit/3d6a89e8888b14ae5cb5640464e12b7811853c7e).
## You cannot bind to select[multiple]
### You cannot bind to select[multiple]
Switching between `select[single]` and `select[multiple]` has always been odd due to browser quirks.
This feature never worked with two-way data-binding so it's not expected that anyone is using it.
@@ -1534,7 +1898,7 @@ If you are interested in properly adding this feature, please submit a pull requ
See [d87fa004](https://github.com/angular/angular.js/commit/d87fa0042375b025b98c40bff05e5f42c00af114).
## Uncommon region-specific local files were removed from i18n
### Uncommon region-specific local files were removed from i18n
AngularJS uses the Google Closure library's locale files. The following locales were removed from
Closure, so Angular is not able to continue to support them:
@@ -1550,7 +1914,7 @@ load and use your copy of the locale file provided that you maintain it yourself
See [6382e21f](https://github.com/angular/angular.js/commit/6382e21fb28541a2484ac1a241d41cf9fbbe9d2c).
## Services can now return functions
### Services can now return functions
Previously, the service constructor only returned objects regardless of whether a function was returned.
+2 -3
View File
@@ -75,9 +75,8 @@ that you break your application to multiple modules like this:
* And an application level module which depends on the above modules and contains any
initialization code.
We've also
[written a document](http://blog.angularjs.org/2014/02/an-angularjs-style-guide-and-best.html)
on how we organize large apps at Google.
You can find a community [style guide](https://github.com/johnpapa/angular-styleguide) to help
yourself when application grows.
The above is a suggestion. Tailor it to your needs.
+1 -1
View File
@@ -44,7 +44,7 @@ and {@link angular.reloadWithDebugInfo `angular.reloadWithDebugInfo`}.
## Strict DI Mode
Using strict di mode in your production application will throw errors when a injectable
Using strict di mode in your production application will throw errors when an injectable
function is not
{@link di#dependency-annotation annotated explicitly}. Strict di mode is intended to help
you make sure that your code will work when minified. However, it also will force you to
+3 -3
View File
@@ -257,7 +257,7 @@ the `$digest` phase. This delay is desirable, since it coalesces multiple model
2. **Watcher registration**
During template linking directives register {@link
During template linking, directives register {@link
ng.$rootScope.Scope#$watch watches} on the scope. These watches will be
used to propagate model values to the DOM.
@@ -391,7 +391,7 @@ implementing custom event callbacks, or when working with third-party library ca
5. The {@link ng.$rootScope.Scope#$watch $watch} list is a set of expressions
which may have changed since last iteration. If a change is detected then the `$watch`
function is called which typically updates the DOM with the new value.
6. Once the Angular {@link ng.$rootScope.Scope#$digest $digest} loop finishes
6. Once the Angular {@link ng.$rootScope.Scope#$digest $digest} loop finishes,
the execution leaves the Angular and JavaScript context. This is followed by the browser
re-rendering the DOM to reflect any changes.
@@ -419,4 +419,4 @@ user enters text into the text field.
which in turn updates the DOM.
6. Angular exits the execution context, which in turn exits the `keydown` event and with it
the JavaScript execution context.
7. The browser re-renders the view with update text.
7. The browser re-renders the view with the updated text.
+79 -10
View File
@@ -9,6 +9,27 @@ This document explains some of AngularJS's security features and best practices
keep in mind as you build your application.
## Reporting a security issue
Email us at [security@angularjs.org](mailto:security@angularjs.org) to report any potential
security issues in AngularJS.
Please keep in mind the points below about Angular's expression language.
## Use the latest AngularJS possible
Like any software library, it is critical to keep AngularJS up to date. Please track the
[CHANGELOG](https://github.com/angular/angular.js/blob/master/CHANGELOG.md) and make sure you are aware
of upcoming security patches and other updates.
Be ready to update rapidly when new security-centric patches are available.
Those that stray from Angular standards (such as modifying Angular's core) may have difficulty updating,
so keeping to AngularJS standards is not just a functionality issue, it's also critical in order to
facilitate rapid security updates.
## Expression Sandboxing
AngularJS's expressions are sandboxed not for security reasons, but instead to maintain a proper
@@ -25,7 +46,8 @@ But if an attacker can change arbitrary HTML templates, there's nothing stopping
<script>somethingEvil();</script>
```
It's better to design your application in such a way that users cannot change client-side templates.
**It's better to design your application in such a way that users cannot change client-side templates.**
For instance:
* Do not mix client and server templates
@@ -33,7 +55,8 @@ For instance:
* Do not run user input through `$scope.$eval`
* Consider using {@link ng.directive:ngCsp CSP} (but don't rely only on CSP)
## Mixing client-side and server-side templates
### Mixing client-side and server-side templates
In general, we recommend against this because it can create unintended XSS vectors.
@@ -41,20 +64,66 @@ However, it's ok to mix server-side templating in the bootstrap template (`index
as user input cannot be used on the server to output html that would then be processed by Angular
in a way that would allow for arbitrary code execution.
For instance, you can use server-side templating to dynamically generate CSS, URLs, etc, but not
for generating templates that are bootstrapped/compiled by Angular.
**For instance, you can use server-side templating to dynamically generate CSS, URLs, etc, but not
for generating templates that are bootstrapped/compiled by Angular.**
## Reporting a security issue
## HTTP Requests
Email us at [security@angularjs.org](mailto:security@angularjs.org) to report any potential
security issues in AngularJS.
Whenever your application makes requests to a server there are potential security issues that need
to be blocked. Both server and the client must cooperate in order to eliminate these threats.
Angular comes pre-configured with strategies that address these issues, but for this to work backend
server cooperation is required.
Please keep in mind the above points about Angular's expression language.
### Cross Site Request Forgery (XSRF/CSRF)
Protection from XSRF is provided by using the double-submit cookie defense pattern.
For more information please visit {@link $http#cross-site-request-forgery-xsrf-protection XSRF protection}.
### JSON Hijacking Protection
Protection from JSON Hijacking is provided if the server prefixes all JSON requests with following string `")]}',\n"`.
Angular will automatically strip the prefix before processing it as JSON.
For more information please visit {@link $http#json-vulnerability-protection JSON Hijacking Protection}.
Bear in mind that calling `$http.jsonp`, like in [our Yahoo! finance example](https://docs.angularjs.org/guide/concepts#accessing-the-backend),
gives the remote server (and, if the request is not secured, any Man-in-the-Middle attackers)
instant remote code execution in your application: the result of these requests is handed off
to the browser as regular `<script>` tag.
## Strict Contextual Escaping
Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain contexts to require
a value that is marked as safe to use for that context.
This mode is implemented by the {@link $sce} service and various core directives.
One example of such a context is rendering arbitrary content via the {@link ngBindHtml} directive. If the content is
provided by a user there is a chance of Cross Site Scripting (XSS) attacks. The {@link ngBindHtml} directive will not
render content that is not marked as safe by {@link $sce}. The {@link ngSanitize} module can be used to clean such
user provided content and mark the content as safe.
**Be aware that marking untrusted data as safe via calls to {@link $sce#trustAsHtml `$sce.trustAsHtml`}, etc is
dangerous and will lead to Cross Site Scripting exploits.**
For more information please visit {@link $sce} and {@link ngSanitize.$sanitize}.
## Using Local Caches
There are various places that the browser can store (or cache) data. Within Angular there are objects created by
the {@link $cacheFactory}. These objects, such as {@link $templateCache} are used to store and retrieve data,
primarily used by {@link $http} and the {@link script} directive to cache templates and other data.
Similarly the browser itself offers `localStorage` and `sessionStorage` objects for caching data.
**Attackers with local access can retrieve sensitive data from this cache even when users are not authenticated.**
For instance in a long running Single Page Application (SPA), one user may "log out", but then another user
may access the application without refreshing, in which case all the cached data is still available.
For more information please visit [Web Storage Security](https://www.whitehatsec.com/blog/web-storage-security/).
## See also
* {@link ng.directive:ngCsp Content Security Policy}
* {@link ng.$sce Strict Contextual Escaping}
* {@link ngSanitize.$sanitize $sanitize}
+8 -4
View File
@@ -43,7 +43,7 @@ subsystem takes care of the rest.
<file name="script.js">
angular.
module('myServiceModule', []).
controller('MyController', ['$scope','notify', function ($scope, notify) {
controller('MyController', ['$scope', 'notify', function ($scope, notify) {
$scope.callNotify = function(msg) {
notify(msg);
};
@@ -138,9 +138,13 @@ batchModule.factory('batchLog', ['$interval', '$log', function($interval, $log)
*/
batchModule.factory('routeTemplateMonitor', ['$route', 'batchLog', '$rootScope',
function($route, batchLog, $rootScope) {
$rootScope.$on('$routeChangeSuccess', function() {
batchLog($route.current ? $route.current.template : null);
});
return {
startMonitoring: function() {
$rootScope.$on('$routeChangeSuccess', function() {
batchLog($route.current ? $route.current.template : null);
});
}
};
}]);
```
+2
View File
@@ -3,6 +3,8 @@
@sortOrder 260
@description
# Templates
In Angular, templates are written with HTML that contains Angular-specific elements and attributes.
Angular combines the template with information from the model and controller to render the dynamic
view that a user sees in the browser.
+54 -7
View File
@@ -3,10 +3,12 @@
@sortOrder 410
@description
# Unit Testing
JavaScript is a dynamically typed language which comes with great power of expression, but it also
comes with almost no help from the compiler. For this reason we feel very strongly that any code
written in JavaScript needs to come with a strong set of tests. We have built many features into
Angular which makes testing your Angular applications easy. So there is no excuse for not testing.
Angular which make testing your Angular applications easy. With Angular, there is no excuse for not testing.
## Separation of Concerns
@@ -20,13 +22,13 @@ related pieces such as the DOM elements, or making any XHR calls to fetch the da
While this may seem obvious it can be very difficult to call an individual function on a
typical project. The reason is that the developers often mix concerns resulting in a
piece of code which does everything. It makes an XHR request, it sorts the response data and then it
piece of code which does everything. It makes an XHR request, it sorts the response data, and then it
manipulates the DOM.
With Angular we try to make it easy for you to do the right thing, and so we
provide dependency injection for your XHR requests, which can be mocked, and we provide abstractions which
allow you to test your model without having to resort to manipulating the DOM. The test can then
assert that the data has been sorted without having to create or look at the state of the DOM or
With Angular, we try to make it easy for you to do the right thing. For your XHR requests, we
provide dependency injection, so your requests can be simulated. For the DOM, we abstract it, so you can
test your model without having to manipulate the DOM directly. Your tests can then
assert that the data has been sorted without having to create or look at the state of the DOM or to
wait for any XHR requests to return data. The individual sort function can be tested in isolation.
## With great power comes great responsibility
@@ -359,7 +361,7 @@ element, to which it can then insert the transcluded content into its template.
Before compilation:
```html
<div translude-directive>
<div transclude-directive>
Some transcluded content
</div>
```
@@ -430,5 +432,50 @@ If your directive uses `templateUrl`, consider using
to pre-compile HTML templates and thus avoid having to load them over HTTP during test execution.
Otherwise you may run into issues if the test directory hierarchy differs from the application's.
## Testing Promises
When testing promises, it's important to know that the resolution of promises is tied to the {@link ng.$rootScope.Scope#$digest digest cycle}.
That means a promise's `then`, `catch` and `finally` callback functions are only called after a digest has run.
In tests, you can trigger a digest by calling a scope's {@link ng.$rootScope.Scope#$apply `$apply` function}.
If you don't have a scope in your test, you can inject the {@link ng.$rootScope $rootScope} and call `$apply` on it.
There is also an example of testing promises in the {@link ng.$q#testing `$q` service documentation}.
## Using `beforeAll()`
Jasmine's `beforeAll()` and mocha's `before()` hooks are often useful for sharing test setup - either to reduce test run-time or simply to make for more focussed test cases.
By default, ngMock will create an injector per test case to ensure your tests do not affect each other. However, if we want to use `beforeAll()`, ngMock will have to create the injector before any test cases are run, and share that injector through all the cases for that `describe`. That is where {@link angular.mock.module.sharedInjector module.sharedInjector()} comes in. When it's called within a `describe` block, a single injector is shared between all hooks and test cases run in that block.
In the example below we are testing a service that takes a long time to generate its answer. To avoid having all of the assertions we want to write in a single test case, {@link angular.mock.module.sharedInjector module.sharedInjector()} and Jasmine's `beforeAll()` are used to run the service only once. The test cases then all make assertions about the properties added to the service instance.
```javascript
describe("Deep Thought", function() {
module.sharedInjector();
beforeAll(module("UltimateQuestion"));
beforeAll(inject(function(DeepThought) {
expect(DeepThought.answer).toBeUndefined();
DeepThought.generateAnswer();
}));
it("has calculated the answer correctly", inject(function(DeepThought) {
// Because of sharedInjector, we have access to the instance of the DeepThought service
// that was provided to the beforeAll() hook. Therefore we can test the generated answer
expect(DeepThought.answer).toBe(42);
}));
it("has calculated the answer within the expected time", inject(function(DeepThought) {
expect(DeepThought.runTimeMillennia).toBeLessThan(8000);
}));
it("has double checked the answer", inject(function(DeepThought) {
expect(DeepThought.absolutelySureItIsTheRightAnswer).toBe(true);
}));
});
```
## Sample project
See the [angular-seed](https://github.com/angular/angular-seed) project for an example.
+3 -12
View File
@@ -26,9 +26,9 @@ machine:
* [Git](http://git-scm.com/): The [Github Guide to
Installing Git](https://help.github.com/articles/set-up-git) is a good source of information.
* [Node.js](http://nodejs.org): We use Node to generate the documentation, run a
* [Node.js v4.x](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.
pre-packaged bundle. (Currently our build does not work properly on Node v5 or greater - please use v4.x.)
* [Java](http://www.java.com): We minify JavaScript using our
[Closure Tools](https://developers.google.com/closure/) jar. Make sure you have Java (version 7 or higher) installed
@@ -40,15 +40,6 @@ and included in your [PATH](http://docs.oracle.com/javase/tutorial/essential/env
npm install -g grunt-cli
```
* [Bower](http://bower.io/): We use Bower to manage client-side packages for the docs. Install the `bower` command-line tool globally with:
```shell
npm install -g bower
```
**Note:** You may need to use sudo (for OSX, *nix, BSD etc) or run your command shell as Administrator (for Windows) to install Grunt &amp;
Bower globally.
## Forking Angular on Github
To create a Github account, follow the instructions [here](https://github.com/signup/free).
@@ -62,7 +53,7 @@ minified AngularJS files:
```shell
# Clone your Github repository:
git clone "git@github.com:<github username>/angular.js.git"
git clone https://github.com/<github username>/angular.js.git
# Go to the AngularJS directory:
cd angular.js
+88 -51
View File
@@ -2,85 +2,122 @@
@name Downloading
@description
# Including angular scripts from the Google CDN
The quickest way to get started is to point your html `<script>` tag to a Google CDN URL.
# Including Angular scripts from the Google CDN
The quickest way to get started is to point your html `<script>` tag to a
[Google CDN](https://developers.google.com/speed/libraries/#angularjs) URL.
This way, you don't have to download anything or maintain a local copy.
There are two types of angular script URLs you can point to, one for development and one for
There are two types of Angular script URLs you can point to, one for development and one for
production:
* __angular.js__ — This is the human-readable, non-minified version, suitable for web
development.
* __angular.js__ — This is the human-readable, non-minified version, suitable for web development.
* __angular.min.js__ — This is the minified version, which we strongly suggest you use in
production.
production.
To point your code to an angular script on the Google CDN server, use the following template. This
example points to the minified version 1.3.14:
To point your code to an angular script on the Google CDN server, use the following template. This
example points to the minified version 1.5.6:
```
```html
<!doctype html>
<html ng-app>
<head>
<title>My Angular App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body>
</body>
</html>
```
Note that only versions 1.0.1 and above are available on the CDN, if you need an earlier version
you can use the <http://code.angularjs.org/> URL which was the previous recommended location for
hosted code source. If you're still using the angular server you should switch to the CDN version
for even faster loading times.
<div class="alert alert-info">
Note that only versions 1.0.1 and above are available on the CDN. If you need an earlier version
(which you shouldn't) you can use the https://code.angularjs.org/ URL, which was the previous
recommended location for hosted code source. If you're still using the Angular server you should
switch to the CDN version for even faster loading times.
</div>
<br />
# Downloading and hosting angular files locally
This option is for those who want to work with angular offline, or those who want to host the
angular files on their own servers.
This option is for those who want to work with Angular offline, or those who want to host the
Angular files on their own servers.
If you navigate to <http://code.angularjs.org/>, you'll see a directory listing with all of the
angular versions since we started releasing versioned build artifacts (quite late in the project
lifetime). Each directory contains all artifacts that we released for a particular version.
Download the version you want and have fun.
If you navigate to https://code.angularjs.org/, you'll see a directory listing with all of the
Angular versions since we started releasing versioned build artifacts. Each directory contains all
artifacts that we released for a particular version. Download the version you want and have fun.
Each directory under <http://code.angularjs.org/> includes the following set of files:
<div class="alert alert-warning">
You can ignore directories starting with `2.` (e.g. `2.0.0-beta.17`) — they are not related to
AngularJS. They contain build artifacts from [Angular 2](https://angular.io) versions.
</div>
* __`angular.js`__ — This file is non-obfuscated, non-minified, and human-readable by
opening it it any editor or browser. In order to get better error messages during development, you
should always use this non-minified angular script.
<br />
Each directory under https://code.angularjs.org/ includes a set of files that comprise the
corresponding version. All JavaScript files (except for `angular-mocks` which is only used during
development) come in two flavors — one suitable for development, the other for production:
* __`angular.min.js`__ — This is a minified and obfuscated version of
`angular.js` created with the Closure compiler. Use this version for production in order
to minimize the size of the application that is downloaded by your user's browser.
* __`<filename>.js`__ — These files are non-obfuscated, non-minified, and human-readable by opening
them in any editor or browser. In order to get better error messages during development, you
should always use these non-minified scripts.
* __`angular.zip`__ — This is a zip archive that contains all of the files released
for this angular version. Use this file to get everything in a single download.
* __`<filename>.min.js`__ — These are minified and obfuscated versions, created with the
[Closure compiler](https://developers.google.com/closure/compiler/). Use these versions for
production in order to minimize the size of the application that is downloaded by your user's
browser.
* __`angular-mocks.js`__ — This file contains an implementation of mocks that makes
testing angular apps even easier. Your unit/integration test harness should load this file after
`angular.js` is loaded.
* __`<filename>.min.js.map`__ — These are
[sourcemap files](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/). You can
serve them alongside the `.min.js` files in order to be able to debug the minified code (e.g. on a
production deployment) more easily, but without impacting performance.
* __`angular-scenario.js`__ — This file is a very nifty JavaScript file that allows you
to write and execute end-to-end tests for angular applications.
<br />
The set of files included in each version directory are:
* __`angular-loader.min.js`__ — Module loader for Angular modules. If you are loading multiple script files containing
Angular modules, you can load them asynchronously and in any order as long as you load this file first. Often the
contents of this file are copy&pasted into the `index.html` to avoid even the initial request to `angular-loader.min.js`.
See [angular-seed](https://github.com/angular/angular-seed/blob/master/app/index-async.html) for an example of usage.
* __`angular.zip`__ — This is a zip archive that contains all of the files released for this Angular
version. Use this file to get everything in a single download.
* __Additional Angular modules:__ optional modules with additional functionality. These files should be loaded
after the core `angular.js` file:
* __`angular-animate.js`__ - Enable animation support
* __`angular-cookies.js`__ - A convenient wrapper for reading and writing browser cookies
* __`angular-resource.js`__ - Interaction support with RESTful services via the $resource service
* __`angular-route.js`__ - Routing and deeplinking services and directives for angular apps
* __`angular-sanitize.js`__ - Functionality to sanitize HTML
* __`angular-touch.js`__ - Touch events and other helpers for touch-enabled devices
* __`angular.js`__ — The core Angular framework. This is all you need to get your Angular app
running.
* __`angular-csp.css`__ — You only need this file if you are using
[CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP). See
{@link directive:ngCsp here} for more info.
* __`angular-mocks.js`__ This file contains an implementation of mocks that makes testing angular
apps even easier. Your unit/integration test harness should load this file after `angular.js` is
loaded.
* __`angular-loader.js`__ — Module loader for Angular modules. If you are loading multiple
script files containing Angular modules, you can load them asynchronously and in any order as long
as you load this file first. Often the contents of this file are copy&pasted into the `index.html`
to avoid even the initial request to `angular-loader[.min].js`.
See [angular-seed](https://github.com/angular/angular-seed/blob/master/app/index-async.html) for
an example of usage.
* __Additional Angular modules:__ Optional modules with additional functionality. These files
should be loaded after the core `angular[.min].js` file:
* __`angular-animate.js`__ — Enable animation support. ({@link module:ngAnimate API docs})
* __`angular-aria.js`__ — Make your apps [accessible](http://www.w3.org/TR/wai-aria/) to users of
assistive technologies. ({@link module:ngAria API docs})
* __`angular-cookies.js`__ — A convenient wrapper for reading and writing browser cookies.
({@link module:ngCookies API docs})
* __`angular-message-format.js`__ — Enhanced support for pluralization and gender specific
messages in interpolated text. ({@link module:ngMessageFormat API docs})
* __`angular-messages.js`__ — Enhanced support for displaying validation messages.
({@link module:ngMessages API docs})
* __`angular-parse-ext.js`__ — Allow Unicode characters in identifiers inside Angular expressions.
({@link module:ngParseExt API docs})
* __`angular-resource.js`__ — Easy interaction with RESTful services.
({@link module:ngResource API docs})
* __`angular-route.js`__ — Routing and deep-linking services and directives for Angular apps.
({@link module:ngRoute API docs})
* __`angular-sanitize.js`__ — Functionality to sanitize HTML. ({@link module:ngSanitize API docs})
* __`angular-touch.js`__ — Touch events and other helpers for touch-enabled devices.
({@link module:ngTouch API docs})
* __`docs`__ — this directory contains all the files that compose the
<http://docs.angularjs.org/> documentation app. These files are handy to see the older version of
our docs, or even more importantly, view the docs offline.
* __`docs/`__ — This directory contains all the files that compose the https://docs.angularjs.org/
documentation app. These files are handy to see the older versions of our docs, or even more
importantly, view the docs offline.
* __`i18n`__ - this directory contains locale specific `ngLocale` angular modules to override the defaults
defined in the `ng` module.
* __`i18n/`__ - This directory contains [locale specific](https://docs.angularjs.org/guide/i18n)
`ngLocale` Angular modules to override the defaults defined in the main `ng` module.
+9 -3
View File
@@ -86,9 +86,15 @@ Yes. See instructions in {@link downloading}.
### What browsers does Angular work with?
We run our extensive test suite against the following browsers: Safari, Chrome, Firefox, Opera 15,
IE9 and mobile browsers (Android, Chrome Mobile, iOS Safari). See {@link guide/ie Internet
Explorer Compatibility} for more details on supporting legacy IE browsers.
We run our extensive test suite against the following browsers: the latest versions of Chrome,
Firefox, Safari, and Safari for iOs, as well as Internet Explorer versions 9-11. See {@link guide/ie
Internet Explorer Compatibility} for more details on supporting legacy IE browsers.
If a browser is untested, it doesn't mean it won't work; for example, older Android (2.3.x)
is supported in the sense that we avoid the dot notation for reserved words as property names,
but we don't actively test changes against it. You can also expect browsers to work that share
a large part of their codebase with a browser we test, such as Opera > version 12
(uses the Blink engine), or the various Firefox derivatives.
### What's Angular's performance like?
+4 -4
View File
@@ -16,9 +16,9 @@ becoming an Angular expert.
starter app with a directory layout, test harness, and scripts to begin building your application.
#Further Steps
# Further Steps
##Watch Videos
## Watch Videos
If you havent had a chance to watch the videos from the homepage, please check out:
@@ -29,13 +29,13 @@ If you havent had a chance to watch the videos from the homepage, please chec
And visit our [YouTube channel](http://www.youtube.com/user/angularjs) for more AngularJS video presentations and
tutorials.
##Subscribe
## Subscribe
* Subscribe to the [mailing list](http://groups.google.com/forum/?fromgroups#!forum/angular). Ask questions here!
* Follow us on [Twitter](https://twitter.com/intent/follow?original_referer=http%3A%2F%2Fangularjs.org%2F&region=follow_link&screen_name=angularjs&source=followbutton&variant=2.0)
* Add us to your circles on [Google+](https://plus.google.com/110323587230527980117/posts)
##Read more
## Read more
The AngularJS documentation includes the {@link guide/index Developer Guide} covering concepts and the
{@link ./api API Reference} for syntax and usage.
+143 -88
View File
@@ -6,12 +6,12 @@
# PhoneCat Tutorial App
A great way to get introduced to AngularJS is to work through this tutorial, which walks you through
the construction of an AngularJS web app. The app you will build is a catalog that displays a list
the construction of an Angular web app. The app you will build is a catalog that displays a list
of Android devices, lets you filter the list to see only devices that interest you, and then view
details for any device.
<img class="diagram" src="img/tutorial/catalog_screen.png" width="488" height="413" alt="demo
application running in the browser">
<img class="diagram" src="img/tutorial/catalog_screen.png" width="488" height="413"
alt="demo application running in the browser">
Follow the tutorial to see how Angular makes browsers smarter — without the use of native
extensions or plug-ins:
@@ -28,10 +28,11 @@ When you finish the tutorial you will be able to:
* Create a dynamic application that works in all modern browsers.
* Use data binding to wire up your data model to your views.
* Create and run unit tests, with Karma.
* Create and run end to end tests, with Protractor.
* Move application logic out of the template and into Controllers.
* Create and run end-to-end tests, with Protractor.
* Move application logic out of the template and into components and controllers.
* Get data from a server using Angular services.
* Apply animations to your application, using ngAnimate.
* Apply animations to your application, using the `ngAnimate` module.
* Structure your Angular applications in a modular way that scales well for larger projects.
* Identify resources for learning more about AngularJS.
The tutorial guides you through the entire process of building a simple application, including
@@ -42,16 +43,18 @@ You can go through the whole tutorial in a couple of hours or you may want to sp
really digging into it. If you're looking for a shorter introduction to AngularJS, check out the
{@link misc/started Getting Started} document.
# Get Started
# Environment Setup
The rest of this page explains how you can set up your local machine for development.
If you just want to read the tutorial then you can just go straight to the first step:
If you just want to _read_ the tutorial, you can go straight to the first step:
[Step 0 - Bootstrapping](tutorial/step_00).
# Working with the code
## Working with the Code
You can follow along with this tutorial and hack on the code in the comfort of your own computer.
In this way you can get hands-on practice of really writing AngularJS code and also on using the
This way, you can get hands-on practice of really writing Angular code and also on using the
recommended testing tools.
The tutorial relies on the use of the [Git][git] versioning system for source code management.
@@ -61,11 +64,12 @@ a few git commands.
### Install Git
You can download and install Git from http://git-scm.com/download. Once installed you should have
access to the `git` command line tool. The main commands that you will need to use are:
You can download and install Git from http://git-scm.com/download. Once installed, you should have
access to the `git` command line tool. The main commands that you will need to use are:
* `git clone ...`: Clone a remote repository onto your local machine.
* `git checkout ...`: Check out a particular branch or a tagged version of the code to hack on.
- `git clone ...` : clone a remote repository onto your local machine
- `git checkout ...` : check out a particular branch or a tagged version of the code to hack on
### Download angular-phonecat
@@ -73,13 +77,14 @@ Clone the [angular-phonecat repository][angular-phonecat] located at GitHub by r
command:
```
git clone --depth=14 https://github.com/angular/angular-phonecat.git
git clone --depth=16 https://github.com/angular/angular-phonecat.git
```
This command creates the `angular-phonecat` directory in your current directory.
This command creates an `angular-phonecat` sub-directory in your current directory.
<div class="alert alert-info">The `--depth=14` option just tells Git to pull down only the last 14 commits. This makes the
download much smaller and faster.
<div class="alert alert-info">
The `--depth=16` option tells Git to pull down only the last 16 commits.
This makes the download much smaller and faster.
</div>
Change your current directory to `angular-phonecat`.
@@ -88,16 +93,16 @@ Change your current directory to `angular-phonecat`.
cd angular-phonecat
```
The tutorial instructions, from now on, assume you are running all commands from the
The tutorial instructions, from now on, assume you are running all commands from within the
`angular-phonecat` directory.
### Install Node.js
If you want to run the preconfigured local web-server and the test tools then you will also need
[Node.js v0.10.27+][node].
If you want to run the preconfigured local web server and the test tools then you will also need
[Node.js v4+][node].
You can download a Node.js installer for your operating system from http://nodejs.org/download/.
You can download a Node.js installer for your operating system from https://nodejs.org/en/download/.
Check the version of Node.js that you have installed by running the following command:
@@ -105,7 +110,7 @@ Check the version of Node.js that you have installed by running the following co
node --version
```
In Debian based distributions, there is a name clash with another utility called `node`. The
In Debian based distributions, there might be a name clash with another utility called `node`. The
suggested solution is to also install the `nodejs-legacy` apt package, which renames `node` to
`nodejs`.
@@ -115,44 +120,43 @@ nodejs --version
npm --version
```
<div class="alert alert-info">If you need to run different versions of node.js
in your local environment, consider installing
<a href="https://github.com/creationix/nvm" title="Node Version Manager Github Repo link">
Node Version Manager (nvm)
</a>.
<div class="alert alert-info">
If you need to run different versions of Node.js in your local environment, consider installing
[Node Version Manager (nvm)][nvm] or [Node Version Manager (nvm) for Windows][nvm-windows].
</div>
Once you have Node.js installed on your machine you can download the tool dependencies by running:
Once you have Node.js installed on your machine, you can download the tool dependencies by running:
```
npm install
```
This command reads angular-phonecat's `package.json` file and downloads the following tools
into the `node_modules` directory:
This command reads angular-phonecat's `package.json` file and downloads the following tools into the
`node_modules` directory:
- [Bower][bower] - client-side code package manager
- [Http-Server][http-server] - simple local static web server
- [Karma][karma] - unit test runner
- [Protractor][protractor] - end to end (E2E) test runner
* [Bower][bower] - client-side code package manager
* [Http-Server][http-server] - simple local static web server
* [Karma][karma] - unit test runner
* [Protractor][protractor] - end-to-end (E2E) test runner
Running `npm install` will also automatically use bower to download the Angular framework into the
Running `npm install` will also automatically use bower to download the AngularJS framework into the
`app/bower_components` directory.
<div class="alert alert-info">
Note the angular-phonecat project is setup to install and run these utilities via npm scripts.
This means that you do not have to have any of these utilities installed globally on your system
to follow the tutorial. See **Installing Helper Tools** below for more information.
to follow the tutorial. See [Installing Helper Tools](tutorial/#install-helper-tools-optional-)
below for more information.
</div>
The project is preconfigured with a number of npm helper scripts to make it easy to run the common
tasks that you will need while developing:
- `npm start` : start a local development web-server
- `npm test` : start the Karma unit test runner
- `npm run protractor` : run the Protractor end to end (E2E) tests
- `npm run update-webdriver` : install the drivers needed by Protractor
* `npm start`: Start a local development web server.
* `npm test`: Start the Karma unit test runner.
* `npm run protractor`: Run the Protractor end-to-end (E2E) tests.
* `npm run update-webdriver`: Install the drivers needed by Protractor.
### Install Helper Tools (optional)
@@ -167,7 +171,7 @@ For instance, to install the Bower command line executable you would do:
sudo npm install -g bower
```
*(Omit the sudo if running on Windows)*
_(Omit the sudo if running on Windows)_
Then you can run the bower tool directly, such as:
@@ -176,10 +180,10 @@ bower install
```
### Running Development Web Server
### Running the Development Web Server
While Angular applications are purely client-side code, and it is possible to open them in a web
browser directly from the file system, it is better to serve them from a HTTP web server. In
browser directly from the file system, it is better to serve them from an HTTP web server. In
particular, for security reasons, most modern browsers will not allow JavaScript to make server
requests if the page is loaded directly from the file system.
@@ -190,61 +194,64 @@ application during development. Start the web server by running:
npm start
```
This will create a local webserver that is listening to port 8000 on your local machine.
You can now browse to the application at:
```
http://localhost:8000/app/index.html
```
This will create a local web server that is listening to port 8000 on your local machine.
You can now browse to the application at http://localhost:8000/index.html.
<div class="alert alert-info">
To serve the web app on a different ip address or port, edit the "start" script within package.json.
You can use `-a` to set the address and `-p` to set the port.
To serve the web app on a different IP address or port, edit the "start" script within
`package.json`. You can use `-a` to set the address and `-p` to set the port. You also need to
update the `baseUrl` configuration property in `e2e-test/protractor.conf.js`.
</div>
### Running Unit Tests
We use unit tests to ensure that the JavaScript code in our application is operating correctly.
Unit tests focus on testing small isolated parts of the application. The unit tests are kept in the
`test/unit` directory.
Unit tests focus on testing small isolated parts of the application. The unit tests are kept in test
files (specs) side-by-side with the application code. This way it's easier to find them and keep
them up-to-date with the code under test. It also makes refactoring our app structure easier, since
tests are moved together with the source code.
The angular-phonecat project is configured to use [Karma][karma] to run the unit tests for the
application. Start Karma by running:
application. Start Karma by running:
```
npm test
```
This will start the Karma unit test runner. Karma will read the configuration file at
`test/karma.conf.js`. This configuration file tells Karma to:
This will start the Karma unit test runner. Karma will read the configuration file `karma.conf.js`,
located at the root of the project directory. This configuration file tells Karma to:
- open up a Chrome browser and connect it to Karma
- execute all the unit tests in this browser
- report the results of these tests in the terminal/command line window
- watch all the project's JavaScript files and re-run the tests whenever any of these change
* Open up instances of the Chrome and Firefox browsers and connect them to Karma.
* Execute all the unit tests in these browsers.
* Report the results of these tests in the terminal/command line window.
* Watch all the project's JavaScript files and re-run the tests whenever any of these change.
It is good to leave this running all the time, in the background, as it will give you immediate
feedback about whether your changes pass the unit tests while you are working on the code.
### Running End to End Tests
### Running E2E Tests
We use End to End tests to ensure that the application as a whole operates as expected.
End to End tests are designed to test the whole client side application, in particular that the
views are displaying and behaving correctly. It does this by simulating real user interaction with
the real application running in the browser.
We use E2E (end-to-end) tests to ensure that the application as a whole operates as expected.
E2E tests are designed to test the whole client-side application, in particular that the views are
displaying and behaving correctly. It does this by simulating real user interaction with the real
application running in the browser.
The End to End tests are kept in the `test/e2e` directory.
The E2E tests are kept in the `e2e-tests` directory.
The angular-phonecat project is configured to use [Protractor][protractor] to run the End to End
tests for the application. Protractor relies upon a set of drivers to allow it to interact with
the browser. You can install these drivers by running:
The angular-phonecat project is configured to use [Protractor][protractor] to run the E2E tests for
the application. Protractor relies upon a set of drivers to allow it to interact with the browser.
You can install these drivers by running:
```
npm run update-webdriver
```
*(You should only need to do this once.)*
<div class="alert alert-info">
You don't have to manually run this command. Our npm scripts are configured so that it will be
automatically executed as part of the command that runs the E2E tests.
</div>
Since Protractor works by interacting with a running application, we need to start our web server:
@@ -252,31 +259,79 @@ Since Protractor works by interacting with a running application, we need to sta
npm start
```
Then in a separate terminal/command line window, we can run the Protractor test scripts against the
application by running:
Then, in a _separate_ terminal/command line window, we can run the Protractor test scripts against
the application by running:
```
npm run protractor
```
Protractor will read the configuration file at `test/protractor-conf.js`. This configuration tells
Protractor to:
Protractor will read the configuration file at `e2e-tests/protractor.conf.js`. This configuration
file tells Protractor to:
- open up a Chrome browser and connect it to the application
- execute all the End to End tests in this browser
- report the results of these tests in the terminal/command line window
- close down the browser and exit
* Open up a Chrome browser and connect it to the application.
* Execute all the E2E tests in this browser.
* Report the results of these tests in the terminal/command line window.
* Close the browser and exit.
It is good to run the end to end tests whenever you make changes to the HTML views or want to check
that the application as a whole is executing correctly. It is very common to run End to End tests
before pushing a new commit of changes to a remote repository.
It is good to run the E2E tests whenever you make changes to the HTML views or want to check that
the application as a whole is executing correctly. It is very common to run E2E tests before pushing
a new commit of changes to a remote repository.
### Common Issues
<br />
**Firewall / Proxy issues**
Git and other tools, often use the `git:` protocol for accessing files in remote repositories.
Some firewall configurations are blocking `git://` URLs, which leads to errors when trying to clone
repositories or download dependencies. (For example corporate firewalls are "notorious" for blocking
`git:`.)
If you run into this issue, you can force the use of `https:` instead, by running the following
command: `git config --global url."https://".insteadOf git://`
<br />
**Updating WebDriver takes too long**
Running `update-webdriver` for the first time may take from several seconds up to a few minutes
(depending on your hardware and network connection). If you cancel the operation (e.g. using
`Ctrl+C`), you might get errors, when trying to run Protractor later.
In that case, you can delete the `node_modules/` directory and run `npm install` again.
<br />
**Protractor dependencies**
Under the hood, Protractor uses the [Selenium Stadalone Server][selenium], which in turn requires
the [Java Development Kit (JDK)][jdk] to be installed on your local machine. Check this by running
`java -version` from the command line.
If JDK is not already installed, you can download it [here][jdk-download].
<br />
**Error running the web server**
The web server is configured to use port 8000. If the port is already in use (for example by another
instance of a running web server) you will get an `EADDRINUSE` error. Make sure the port is
available, before running `npm start`.
<hr />
Now that you have set up your local machine, let's get started with the tutorial:
{@link step_00 Step 0 - Bootstrapping}
Now that you have set up your local machine, let's get started with the tutorial: {@link step_00 Step 0 - Bootstrapping}
[git]: http://git-scm.com/
[node]: http://nodejs.org/
[angular-phonecat]: https://github.com/angular/angular-phonecat
[protractor]: https://github.com/angular/protractor
[bower]: http://bower.io/
[git]: http://git-scm.com/
[http-server]: https://github.com/nodeapps/http-server
[karma]: https://github.com/karma-runner/karma
[jdk]: https://en.wikipedia.org/wiki/Java_Development_Kit
[jdk-download]: http://www.oracle.com/technetwork/java/javase/downloads/index.html
[karma]: https://karma-runner.github.io/
[node]: http://nodejs.org/
[nvm]: https://github.com/creationix/nvm
[nvm-windows]: https://github.com/coreybutler/nvm-windows
[protractor]: https://github.com/angular/protractor
[selenium]: http://docs.seleniumhq.org/
+89 -72
View File
@@ -6,129 +6,144 @@
<ul doc-tutorial-nav="0"></ul>
You are now ready to build the AngularJS phonecat app. In this step, you will become familiar
with the most important source code files, learn how to start the development servers bundled with
angular-seed, and run the application in the browser.
In this step of the tutorial, you will become familiar with the most important source code files of
the AngularJS Phonecat App. You will also learn how to start the development servers bundled with
[angular-seed][angular-seed], and run the application in the browser.
Before you continue, make sure you have set up your development environment and installed all
necessary dependencies, as described in the {@link tutorial/#environment-setup Environment Setup}
section.
In `angular-phonecat` directory, run this command:
In the `angular-phonecat` directory, run this command:
```
git checkout -f step-0
```
This resets your workspace to step 0 of the tutorial app.
You must repeat this for every future step in the tutorial and change the number to the number of
the step you are on. This will cause any changes you made within your working directory to be lost.
If you haven't already done so you need to install the dependencies by running:
If you haven't already done so, you need to install the dependencies by running:
```
npm install
```
To see the app running in a browser, open a *separate* terminal/command line tab or window, then
run `npm start` to start the web server. Now, open a browser window for the app and navigate to
<a href="http://localhost:8000/app/" target="_blank" title="Open app on localhost">`http://localhost:8000/app/`</a>
To see the app running in a browser, open a _separate_ terminal/command line tab or window, then run
`npm start` to start the web server. Now, open a browser window for the app and navigate to
http://localhost:8000/index.html.
Note that if you already ran the master branch app prior to checking out step-0, you may see the cached
master version of the app in your browser window at this point. Just hit refresh to re-load the page.
Note that if you already ran the master branch app prior to checking out step-0, you may see the
cached master version of the app in your browser window at this point. Just hit refresh to re-load
the page.
You can now see the page in your browser. It's not very exciting, but that's OK.
The HTML page that displays "Nothing here yet!" was constructed with the HTML code shown below.
The code contains some key Angular elements that we will need as we progress.
__`app/index.html`:__
**`app/index.html`:**
```html
<!doctype html>
<html lang="en" ng-app>
<head>
<meta charset="utf-8">
<title>My HTML File</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="css/app.css">
<script src="bower_components/angular/angular.js"></script>
</head>
<body>
<head>
<meta charset="utf-8">
<title>My HTML File</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
<script src="bower_components/angular/angular.js"></script>
</head>
<body>
<p>Nothing here {{'yet' + '!'}}</p>
<p>Nothing here {{'yet' + '!'}}</p>
</body>
</body>
</html>
```
## What is the code doing?
**`ng-app` directive:**
<br />
**`ng-app` attribute:**
<html ng-app>
```html
<html ng-app>
```
The `ng-app` attribute represents an Angular directive named `ngApp` (Angular uses
`spinal-case` for its custom attributes and `camelCase` for the corresponding directives
which implement them).
This directive is used to flag the html element that Angular should consider to be the root element
of our application.
This gives application developers the freedom to tell Angular if the entire html page or only a
portion of it should be treated as the Angular application.
The `ng-app` attribute represents an Angular directive, named `ngApp` (Angular uses `kebab-case` for
its custom attributes and `camelCase` for the corresponding directives which implement them). This
directive is used to flag the HTML element that Angular should consider to be the root element of
our application. This gives application developers the freedom to tell Angular if the entire HTML
page or only a portion of it should be treated as the AngularJS application.
**AngularJS script tag:**
For more info on `ngApp`, check out the {@link ngApp API Reference}.
<script src="bower_components/angular/angular.js">
<br />
**`angular.js` script tag:**
This code downloads the `angular.js` script which registers a callback that will be executed by the
```html
<script src="bower_components/angular/angular.js"></script>
```
This code downloads the `angular.js` script which registers a callback that will be executed by the
browser when the containing HTML page is fully downloaded. When the callback is executed, Angular
looks for the {@link ng.directive:ngApp ngApp} directive. If
Angular finds the directive, it will bootstrap the application with the root of the application DOM
being the element on which the `ngApp` directive was defined.
looks for the {@link ngApp ngApp} directive. If Angular finds the directive, it will bootstrap the
application with the root of the application DOM being the element on which the `ngApp` directive
was defined.
For more info on bootstrapping your app, checkout the [Bootstrap](guide/bootstrap) section of the
Developer Guide.
<br />
**Double-curly binding with an expression:**
Nothing here {{'yet' + '!'}}
```html
Nothing here {{'yet' + '!'}}
```
This line demonstrates two core features of Angular's templating capabilities:
* a binding, denoted by double-curlies `{{ }}`
* a simple expression `'yet' + '!'` used in this binding.
* A binding, denoted by double-curlies: `{{ }}`
* A simple expression used in this binding: `'yet' + '!'`
The binding tells Angular that it should evaluate an expression and insert the result into the
DOM in place of the binding. Rather than a one-time insert, as we'll see in the next steps, a
binding will result in efficient continuous updates whenever the result of the expression
evaluation changes.
The binding tells Angular that it should evaluate an expression and insert the result into the DOM
in place of the binding. As we will see in the next steps, rather than a one-time insert, a binding
will result in efficient continuous updates whenever the result of the expression evaluation
changes.
{@link guide/expression Angular expression} is a JavaScript-like code snippet that is
evaluated by Angular in the context of the current model scope, rather than within the scope of
the global context (`window`).
{@link guide/expression Angular expressions} are JavaScript-like code snippets that are evaluated by
Angular in the context of the current model scope, rather than within the scope of the global
context (`window`).
As expected, once this template is processed by Angular, the html page contains the text:
"Nothing here yet!".
As expected, once this template is processed by Angular, the HTML page contains the text:
## Bootstrapping AngularJS apps
```
Nothing here yet!
```
Bootstrapping AngularJS apps automatically using the `ngApp` directive is very easy and suitable
for most cases. In advanced cases, such as when using script loaders, you can use the
{@link guide/bootstrap imperative / manual way} to bootstrap the app.
## Bootstrapping Angular Applications
There are 3 important things that happen during the app bootstrap:
Bootstrapping Angular applications automatically using the `ngApp` directive is very easy and
suitable for most cases. In advanced cases, such as when using script loaders, you can use the
{@link guide/bootstrap#manual-initialization imperative/manual way} to bootstrap the application.
There are 3 important things that happen during the bootstrap phase:
1. The {@link auto.$injector injector} that will be used for dependency injection is created.
2. The injector will then create the {@link ng.$rootScope root scope} that will
become the context for the model of our application.
2. The injector will then create the {@link ng.$rootScope root scope} that will become the context
for the model of our application.
3. Angular will then "compile" the DOM starting at the `ngApp` root element, processing any
directives and bindings found along the way.
Once an application is bootstrapped, it will then wait for incoming browser events (such as mouse
click, key press or incoming HTTP response) that might change the model. Once such an event occurs,
Angular detects if it caused any model changes and if changes are found, Angular will reflect them
in the view by updating all of the affected bindings.
clicks, key presses or incoming HTTP responses) that might change the model. Once such an event
occurs, Angular detects if it caused any model changes and if changes are found, Angular will
reflect them in the view by updating all of the affected bindings.
The structure of our application is currently very simple. The template contains just one directive
and one static binding, and our model is empty. That will soon change!
@@ -138,27 +153,29 @@ and one static binding, and our model is empty. That will soon change!
## What are all these files in my working directory?
Most of the files in your working directory come from the [angular-seed project][angular-seed] which
is typically used to bootstrap new Angular projects. The seed project is pre-configured to install
the angular framework (via `bower` into the `app/bower_components/` folder) and tools for developing
a typical web app (via `npm`).
Most of the files in your working directory come from the [angular-seed project][angular-seed],
which is typically used to bootstrap new AngularJS projects. The seed project is pre-configured to
install the AngularJS framework (via `bower` into the `app/bower_components/` directory) and tools
for developing and testing a typical web application (via `npm`).
For the purposes of this tutorial, we modified the angular-seed with the following changes:
* Removed the example app
* Added phone images to `app/img/phones/`
* Added phone data files (JSON) to `app/phones/`
* Removed the example app.
* Removed unused dependencies.
* Added phone images to `app/img/phones/`.
* Added phone data files (JSON) to `app/phones/`.
* Added a dependency on [Bootstrap](http://getbootstrap.com) in the `bower.json` file.
# Experiments
* Try adding a new expression to the `index.html` that will do some math:
<div></div>
<p>1 + 2 = {{ 1 + 2 }}</p>
* Try adding a new expression to `index.html` that will do some math:
```html
<p>1 + 2 = {{1 + 2}}</p>
```
# Summary
+9 -5
View File
@@ -12,11 +12,11 @@ dynamically display the same result with any set of data.
In this step you will add some basic information about two cell phones to an HTML page.
- The page now contains a list with information about two phones.
* The page now contains a list with information about two phones.
<div doc-tutorial-reset="1"></div>
<br />
**`app/index.html`:**
```html
@@ -39,15 +39,19 @@ In this step you will add some basic information about two cell phones to an HTM
# Experiments
<div></div>
* Try adding more static HTML to `index.html`. For example:
<p>Total number of phones: 2</p>
```html
<p>Total number of phones: 2</p>
```
# Summary
This addition to your app uses static HTML to display the list. Now, let's go to {@link step_02
step 2} to learn how to use AngularJS to dynamically generate the same list.
This addition to your app uses static HTML to display the list. Now, let's go to
{@link step_02 step 2} to learn how to use Angular to dynamically generate the same list.
<ul doc-tutorial-nav="1"></ul>
+183 -113
View File
@@ -6,37 +6,38 @@
<ul doc-tutorial-nav="2"></ul>
Now it's time to make the web page dynamic — with AngularJS. We'll also add a test that verifies the
code for the controller we are going to add.
Now, it's time to make the web page dynamic — with AngularJS. We will also add a test that verifies
the code for the controller we are going to add.
There are many ways to structure the code for an application. For Angular apps, we encourage the use of
[the Model-View-Controller (MVC) design pattern](http://en.wikipedia.org/wiki/ModelViewController)
to decouple the code and to separate concerns. With that in mind, let's use a little Angular and
JavaScript to add model, view, and controller components to our app.
There are many ways to structure the code for an application. For Angular applications, we encourage
the use of the [Model-View-Controller (MVC) design pattern][mvc-pattern] to decouple the code and
separate concerns. With that in mind, let's use a little Angular and JavaScript to add models,
views, and controllers to our app.
- The list of three phones is now generated dynamically from data
* The list of three phones is now generated dynamically from data
<div doc-tutorial-reset="2"></div>
## View and Template
In Angular, the __view__ is a projection of the model through the HTML __template__. This means that
In Angular, the **view** is a projection of the model through the HTML **template**. This means that
whenever the model changes, Angular refreshes the appropriate binding points, which updates the
view.
The view component is constructed by Angular from this template:
The view is constructed by Angular from this template.
__`app/index.html`:__
<br />
**`app/index.html`:**
```html
<html ng-app="phonecatApp">
<head>
...
<script src="bower_components/angular/angular.js"></script>
<script src="js/controllers.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
<body ng-controller="PhoneListController">
<ul>
<li ng-repeat="phone in phones">
@@ -49,95 +50,117 @@ __`app/index.html`:__
</html>
```
We replaced the hard-coded phone list with the {@link ng.directive:ngRepeat ngRepeat directive}
and two {@link guide/expression Angular expressions}:
We replaced the hard-coded phone list with the {@link ngRepeat ngRepeat} directive and two
{@link guide/expression Angular expressions}:
* The `ng-repeat="phone in phones"` attribute in the `<li>` tag is an Angular repeater directive.
The repeater tells Angular to create a `<li>` element for each phone in the list using the `<li>`
tag as the template.
* The expressions wrapped in curly braces (`{{phone.name}}` and `{{phone.snippet}}`) will be replaced
by the value of the expressions.
* The `ng-repeat="phone in phones"` attribute on the `<li>` tag is an Angular repeater directive.
The repeater tells Angular to create a `<li>` element for each phone in the list, using the `<li>`
tag as the template.
* The expressions wrapped in curly braces (`{{phone.name}}` and `{{phone.snippet}}`) will be
replaced by the values of the expressions.
We have added a new directive, called `ng-controller`, which attaches a `PhoneListCtrl`
__controller__ to the &lt;body&gt; tag. At this point:
We have also added a new directive, called {@link ngController ngController}, which attaches a
`PhoneListController` **controller** to the `<body>` tag. At this point:
* The expressions in curly braces (`{{phone.name}}` and `{{phone.snippet}}` denote
bindings, which are referring to our application model, which is set up in our `PhoneListCtrl`
controller.
* `PhoneListController` is in charge of the DOM sub-tree under (and including) the `<body>` element.
* The expressions in curly braces (`{{phone.name}}` and `{{phone.snippet}}`) denote bindings, which
are referring to our application model, which is set up in our `PhoneListController` controller.
<div class="alert alert-info">
Note: We have specified an {@link angular.Module Angular Module} to load using `ng-app="phonecatApp"`,
where `phonecatApp` is the name of our module. This module will contain the `PhoneListCtrl`.
Note: We have specified an {@link angular.Module Angular Module} to load using
`ng-app="phonecatApp"`, where `phonecatApp` is the name of our module. This module will contain
the `PhoneListController`.
</div>
<img class="diagram" src="img/tutorial/tutorial_02.png">
## Model and Controller
The data __model__ (a simple array of phones in object literal notation) is now instantiated within
the `PhoneListCtrl` __controller__. The __controller__ is simply a constructor function that takes a
`$scope` parameter:
The data **model** (a simple array of phones in object literal notation) is now instantiated within
the `PhoneListController` **controller**. The **controller** is simply a constructor function that
takes a `$scope` parameter:
__`app/js/controllers.js`:__
<br />
**`app/app.js`:**
```js
// Define the `phonecatApp` module
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', function ($scope) {
// Define the `PhoneListController` controller on the `phonecatApp` module
phonecatApp.controller('PhoneListController', function PhoneListController($scope) {
$scope.phones = [
{'name': 'Nexus S',
'snippet': 'Fast just got faster with Nexus S.'},
{'name': 'Motorola XOOM™ with Wi-Fi',
'snippet': 'The Next, Next Generation tablet.'},
{'name': 'MOTOROLA XOOM™',
'snippet': 'The Next, Next Generation tablet.'}
{
name: 'Nexus S',
snippet: 'Fast just got faster with Nexus S.'
}, {
name: 'Motorola XOOM™ with Wi-Fi',
snippet: 'The Next, Next Generation tablet.'
}, {
name: 'MOTOROLA XOOM™',
snippet: 'The Next, Next Generation tablet.'
}
];
});
```
Here we declared a controller called `PhoneListCtrl` and registered it in an AngularJS
module, `phonecatApp`. Notice that our `ng-app` directive (on the `<html>` tag) now specifies the `phonecatApp`
module name as the module to load when bootstrapping the Angular application.
Here we declared a controller called `PhoneListController` and registered it in an Angular module,
`phonecatApp`. Notice that our `ngApp` directive (on the `<html>` tag) now specifies the
`phonecatApp` module name as the module to load when bootstrapping the application.
Although the controller is not yet doing very much, it plays a crucial role. By providing context
for our data model, the controller allows us to establish data-binding between
the model and the view. We connected the dots between the presentation, data, and logic components
as follows:
for our data model, the controller allows us to establish data-binding between the model and the
view. We connected the dots between the presentation, data, and logic components as follows:
* The {@link ng.directive:ngController ngController} directive, located on the `<body>` tag,
references the name of our controller, `PhoneListCtrl` (located in the JavaScript file
`controllers.js`).
* The {@link ngController ngController} directive, located on the `<body>` tag, references the name
of our controller, `PhoneListController` (located in the JavaScript file `app.js`).
* The `PhoneListController` controller attaches the phone data to the `$scope` that was injected
into our controller function. This _scope_ is a prototypal descendant of the _root scope_ that was
created when the application was defined. This controller scope is available to all bindings
located within the `<body ng-controller="PhoneListController">` tag.
* The `PhoneListCtrl` controller attaches the phone data to the `$scope` that was injected into our
controller function. This *scope* is a prototypical descendant of the *root scope* that was created
when the application was defined. This controller scope is available to all bindings located within
the `<body ng-controller="PhoneListCtrl">` tag.
### Scope
The concept of a scope in Angular is crucial. A scope can be seen as the glue which allows the
template, model and controller to work together. Angular uses scopes, along with the information
template, model, and controller to work together. Angular uses scopes, along with the information
contained in the template, data model, and controller, to keep models and views separate, but in
sync. Any changes made to the model are reflected in the view; any changes that occur in the view
are reflected in the model.
To learn more about Angular scopes, see the {@link ng.$rootScope.Scope angular scope documentation}.
<img class="diagram" src="img/tutorial/tutorial_02.png">
## Tests
<div class="alert alert-warning">
<p>
Angular scopes prototypally inherit from their parent scope, all the way up to the *root scope*
of the application. As a result, assigning values directly on the scope makes it easy to share
data across different parts of the page and create interactive applications.
While this approach works for prototypes and smaller applications, it quickly leads to tight
coupling and difficulty to reason about changes in our data model.
</p>
<p>
In the next step, we will learn how to better organize our code, by "packaging" related pieces
of application and presentation logic into isolated, reusable entities, called components.
</p>
</div>
# Testing
The "Angular way" of separating controller from the view, makes it easy to test code as it is being
developed. If our controller is available on the global namespace then we could simply instantiate it
with a mock `scope` object:
developed. If our controller were available on the global namespace, we could simply instantiate it
with a mock scope object:
<br />
```js
describe('PhoneListCtrl', function(){
describe('PhoneListController', function() {
it('should create "phones" model with 3 phones', function() {
var scope = {},
ctrl = new PhoneListCtrl(scope);
it('should create a `phones` model with 3 phones', function() {
var scope = {};
var ctrl = new PhoneListController(scope);
expect(scope.phones.length).toBe(3);
});
@@ -145,30 +168,31 @@ describe('PhoneListCtrl', function(){
});
```
The test instantiates `PhoneListCtrl` and verifies that the phones array property on the scope
contains three records. This example demonstrates how easy it is to create a unit test for code in
Angular. Since testing is such a critical part of software development, we make it easy to create
tests in Angular so that developers are encouraged to write them.
The test instantiates `PhoneListController` and verifies that the phones array property on the
scope contains three records. This example demonstrates how easy it is to create a unit test for
code in Angular. Since testing is such a critical part of software development, we make it easy to
create tests in Angular so that developers are encouraged to write them.
### Testing non-Global Controllers
In practice, you will not want to have your controller functions in the global namespace. Instead,
you can see that we have registered it via an anonymous constructor function on the `phonecatApp`
module.
## Testing non-global Controllers
In practice, you will not want to have your controller functions in the global namespace. Instead,
you can see that we have registered it via a constructor function on the `phonecatApp` module.
In this case Angular provides a service, `$controller`, which will retrieve your controller by name.
Here is the same test using `$controller`:
__`test/unit/controllersSpec.js`:__
<br />
**`app/app.spec.js`:**
```js
describe('PhoneListCtrl', function(){
describe('PhoneListController', function() {
beforeEach(module('phonecatApp'));
it('should create "phones" model with 3 phones', inject(function($controller) {
var scope = {},
ctrl = $controller('PhoneListCtrl', {$scope:scope});
it('should create a `phones` model with 3 phones', inject(function($controller) {
var scope = {};
var ctrl = $controller('PhoneListController', {$scope: scope});
expect(scope.phones.length).toBe(3);
}));
@@ -177,46 +201,78 @@ describe('PhoneListCtrl', function(){
```
* Before each test we tell Angular to load the `phonecatApp` module.
* We ask Angular to `inject` the `$controller` service into our test function
* We use `$controller` to create an instance of the `PhoneListCtrl`
* We ask Angular to `inject` the `$controller` service into our test function.
* We use `$controller` to create an instance of the `PhoneListController`.
* With this instance, we verify that the phones array property on the scope contains three records.
<div class="alert alert-info">
<p>**A note on file naming:**</p>
<p>
As already mentioned in the [introduction](tutorial/#running-unit-tests), the unit test files
(specs) are kept side-by-side with the application code. We name our specs after the file
containing the code to be tested plus a specific suffix to distinguish them from files
containing application code. Note that test files are still plain JavaScript files, so they have
a `.js` file extension.
</p>
<p>
In this tutorial, we are using the `.spec` suffix. So the test file corresponding to
`something.js` would be called `something.spec.js`.
(Another common convention is to use a `_spec` or `_test` suffix.)
</p>
</div>
### Writing and Running Tests
Angular developers prefer the syntax of Jasmine's Behavior-driven Development (BDD) framework when
writing tests. Although Angular does not require you to use Jasmine, we wrote all of the tests in
this tutorial in Jasmine v1.3. You can learn about Jasmine on the [Jasmine home page][jasmine] and
at the [Jasmine docs][jasmine-docs].
## Writing and Running Tests
The angular-seed project is pre-configured to run unit tests using [Karma][karma] but you will need
Many Angular developers prefer the syntax of
[Jasmine's Behavior-Driven Development (BDD) framework][jasmine-home], when writing tests. Although
Angular does not require you to use Jasmine, we wrote all of the tests in this tutorial in Jasmine
v2.4. You can learn about Jasmine on the [Jasmine home page][jasmine-home] and at the
[Jasmine docs][jasmine-docs].
The angular-seed project is pre-configured to run unit tests using [Karma][karma], but you will need
to ensure that Karma and its necessary plugins are installed. You can do this by running
`npm install`.
To run the tests, and then watch the files for changes: `npm test`.
To run the tests, and then watch the files for changes execute: `npm test`
* Karma will start new instances of Chrome and Firefox browsers automatically. Just ignore them and
let them run in the background. Karma will use these browsers for test execution.
* If you only have one of the browsers installed on your machine (either Chrome or Firefox), make
sure to update the karma configuration file (`karma.conf.js`), before running the test. Locate the
configuration file in the root directory and update the `browsers` property.
E.g. if you only have Chrome installed:
<pre>
...
browsers: ['Chrome'],
...
</pre>
* Karma will start a new instance of Chrome browser automatically. Just ignore it and let it run in
the background. Karma will use this browser for test execution.
* You should see the following or similar output in the terminal:
<pre>
info: Karma server started at http://localhost:9876/
info (launcher): Starting browser "Chrome"
info (Chrome 22.0): Connected on socket id tPUm9DXcLHtZTKbAEO-n
Chrome 22.0: Executed 1 of 1 SUCCESS (0.093 secs / 0.004 secs)
INFO [karma]: Karma server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 49.0]: Connected on socket ... with id ...
Chrome 49.0: Executed 1 of 1 SUCCESS (0.05 secs / 0.04 secs)
</pre>
Yay! The test passed! Or not...
* To rerun the tests, just change any of the source or test .js files. Karma will notice the change
* To rerun the tests, just change any of the source or test `.js` files. Karma will notice the change
and will rerun the tests for you. Now isn't that sweet?
<div class="alert alert-info">
Make sure you don't minimize the browser that Karma opened. On some OS, memory assigned to a minimized
browser is limited, which results in your karma tests running extremely slow.
Make sure you don't minimize the browser that Karma opened. On some OS, memory assigned to a
minimized browser is limited, which results in your karma tests running extremely slow.
</div>
# Experiments
<div></div>
* Add another binding to `index.html`. For example:
```html
@@ -225,46 +281,60 @@ browser is limited, which results in your karma tests running extremely slow.
* Create a new model property in the controller and bind to it from the template. For example:
$scope.name = "World";
```js
$scope.name = 'world';
```
Then add a new binding to `index.html`:
<p>Hello, {{name}}!</p>
```html
<p>Hello, {{name}}!</p>
```
Refresh your browser and verify that it says "Hello, World!".
Refresh your browser and verify that it says 'Hello, world!'.
* Update the unit test for the controller in `./test/unit/controllersSpec.js` to reflect the previous change. For example by adding:
* Update the unit test for the controller in `app/app.spec.js` to reflect the previous change.
For example by adding:
expect(scope.name).toBe('World');
```js
expect(scope.name).toBe('world');
```
* Create a repeater in `index.html` that constructs a simple table:
<table>
<tr><th>row number</th></tr>
<tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i}}</td></tr>
</table>
```html
<table>
<tr><th>Row number</th></tr>
<tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i}}</td></tr>
</table>
```
Now, make the list 1-based by incrementing `i` by one in the binding:
<table>
<tr><th>row number</th></tr>
<tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i+1}}</td></tr>
</table>
Extra points: try and make an 8x8 table using an additional `ng-repeat`.
```html
<table>
<tr><th>Row number</th></tr>
<tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i+1}}</td></tr>
</table>
```
* Make the unit test fail by changing `expect(scope.phones.length).toBe(3)` to instead use `toBe(4)`.
Extra points: Try and make an 8x8 table using an additional `ng-repeat`.
* Make the unit test fail by changing `expect(scope.phones.length).toBe(3)` to instead use
`toBe(4)`.
# Summary
You now have a dynamic app that features separate model, view, and controller components, and you
are testing as you go. Now, let's go to {@link step_03 step 3} to learn how to add full text search
to the app.
We now have a dynamic application which separates models, views, and controllers, and we are testing
as we go. Let's go to {@link step_03 step 3} to learn how to improve our application's architecture,
by utilizing components.
<ul doc-tutorial-nav="2"></ul>
[jasmine]: http://jasmine.github.io/
[jasmine-docs]: http://jasmine.github.io/1.3/introduction.html
[karma]: http://karma-runner.github.io/
[jasmine-docs]: http://jasmine.github.io/2.4/introduction.html
[jasmine-home]: http://jasmine.github.io/
[karma]: https://karma-runner.github.io/
[mvc-pattern]: http://en.wikipedia.org/wiki/ModelViewController

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