Compare commits

...

535 Commits

Author SHA1 Message Date
Martin Staffa 996c901ff9 docs(changelog, guide/migration): mention rare BC for ngInclude
See https://github.com/angular/angular.js/issues/13555#issuecomment-165118890
for detailed explanation.
2016-06-07 10:44:56 +02:00
Georgios Kalpakas 6234cda41c docs(tutorial): add deprecation notice to v1.4.x tutorial and point to the correct branch
- Add a deprecation notice on the 'index' page.
- Hide the "Live Demo" buttons (since we don't have a live demo).
- Update the GitHub diff links to point to the `1.4-snapshot` angular-phonecat branch.
- Modify all git commangs to use the appropriate branch and tags (e.g. `1.4-step-*`).

Related to #14416.

Closes #14675
2016-05-31 12:48:16 +03:00
Martin Staffa f8103a82bf docs(changelog): update with changes for 1.4.11 2016-05-27 12:42:41 +02:00
Martin Staffa 0d764b581d fix(ngAnimate): safe-guard against missing document
In tests, the $document service might be mocked out without providing a real
document, which can lead to errors when the animator is attempting to read properties from it.

This commit provides an object {hidden: true}, if the $document service doesn't have 
a document. This will prevent the animation process from trying to run any animations.

This commit also changes the check for document.hidden slightly. It
should be accessed independently of the current animationsEnabled state.
Since animations are only enabled after two digests, it's possible that
some tests never reach the animationsEnabled = true state and therefore
aren't actually checking the document.hidden state, which means that
the previous fix only works if no more than two digests happen in the test.

(#14633)
2016-05-24 16:44:11 +02:00
Igor Minar 57a37fcc20 fix(ngAnimate): guard $document[0].hidden access in case it was mocked out
Some tests mock out  and now that we always access the hidden property, existing
tests can get broken. This change keeps the existing tests working.
2016-05-17 12:52:01 -07:00
Sander Boom 7f6ba5534f docs(guide/$location): fix typo
Closes #14607
2016-05-14 01:55:18 +03:00
Martin Staffa b24bfae585 Revert: ngAnimate changes for listening on visibilitychange
Reverts d3e123b, bf1acf7 and aa28e48.
Backporting the changes is complicated because we don't destroy the rootScope
after each test in 1.4.x
(#14574)
2016-05-09 12:35:07 -07:00
Martin Staffa d3e123b0a6 test($$isDocumentHidden): really fix jasmine syntax 2016-05-06 17:12:17 +02:00
Martin Staffa bf1acf7b21 test($): fix jasmine syntax 2016-05-06 16:30:30 +02:00
Maksim Ryzhikov fdaf4d5e27 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-06 08:14:32 -06:00
FGasper 1c47abc462 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:56:24 +02:00
Stephen Barker 5222703444 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:56:15 +02:00
Michael Warner 4b38b44c91 docs(ngRequired): add 'restrict' info
The Angular Docs do not show the restrictions

Closes #14541
2016-05-06 15:56:01 +02:00
Martin Staffa aa28e48e17 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 #14066
2016-05-06 15:54:49 +02:00
Martin Probst f31586db41 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:26:03 +03:00
Weijing Jay Lin 8337b9b2d4 docs(identity): add example
Closes #14528
2016-04-28 11:07:30 +03:00
Perry Hooker 85a53ea9cd 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:20:54 +03:00
andrea 2d87ef8f23 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:34:11 +03:00
Tim van Dalen 3df8b637f3 docs($anchorScroll): fix link to HTML5 spec
Closes #14364
2016-04-26 00:31:52 +03:00
Georgios Kalpakas 28d3126fe5 test($templateRequest): fix code for jasmine 1.3 2016-04-25 22:14:41 +03:00
Raphael Jamet ad21f8feaf 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:54 +03:00
Georgios Kalpakas 7f2df141cd docs($interpolate): add known issue about end-symbol in expression
This has been discussed in #8642.

Closes #14494
2016-04-22 15:42:51 +03:00
Georgios Kalpakas 4e735e5363 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:42:01 +03:00
cloverharvest a9db6073c9 docs($http): fix a typo (his --> this)
Closes #14430
2016-04-15 01:25:40 +03:00
Martin Staffa e48e27aa2b test(ngAnimate): fix jasmine syntax 2016-04-13 04:00:26 -07:00
Jason Bedard 832b383cbc perf($compile): use createMap() for directive bindings to allow fast forEach
Closes #12529
2016-04-13 12:06:55 +03:00
Martin Staffa c4bff290e5 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-12 20:42:30 +02:00
Martin Staffa 55b00148dd test(ngAnimate): test calling callbacks for various constellations 2016-04-12 20:42:30 +02:00
Martin Staffa 23550b5e27 fix(ngAnimate): fire callbacks in the correct order for certain skipped animations 2016-04-12 20:42:29 +02:00
Georgii Dolzhykov 97d2a08c5a docs(Module): fix parameter names for .decorator()
Closes #14413
2016-04-12 14:52:48 +03:00
aortyl 7f6efb2822 docs(guide/scope): add comma for readability
Closes #14411
2016-04-11 22:23:03 +03:00
David Rodenas Pico b50867001b fix(ngClass): fix watching of an array expression containing an object
Closes #14405
2016-04-11 12:41:29 +03:00
Gene McCulley 8b9ce885d3 docs(numberFilter): fix the description of the returned value
Closes #14408
2016-04-11 12:28:56 +03:00
Jurko Gospodnetić 56dae6fa1b 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:56:16 +03:00
cscport 611dcbc035 docs(angular.bootstrap): fix capitalization in error message
Closes #14325
2016-03-27 15:45:11 +03:00
Martin Staffa 2c9066e012 test(ngMessages): fix most recent call syntax 2016-03-24 11:10:32 +01:00
Martin Staffa 8ecc9357ef test(ngMessages): fix callThrough syntax 2016-03-24 01:08:28 +01:00
Martin Staffa 71dca7c4c2 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:15:35 +01:00
Steve Mao ce77c25b06 docs($q): mention ES2015 (as a "synonym" for ES6) and remove "harmony"
Closes #14294
2016-03-22 12:09:31 +02:00
Owen Craig a1188721e1 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:12:18 +02:00
surya prakash singh 1917ff86c4 docs(input[time]): fix a typo in the example
Closes #14220
2016-03-21 01:26:54 +02:00
Georgios Kalpakas c60e1960c6 docs(CHANGELOG.md): add notes for v1.4.10 2016-03-20 22:49:46 +02:00
Peter Bacon Darwin 268e71eb8b chore(travis): update node and browser versions 2016-03-16 14:37:16 +00:00
Peter Bacon Darwin 03e6fb3df5 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 11:41:30 +00:00
Peter Bacon Darwin 4fc9cf6289 chore(jenkins): update node version to 4.4 2016-03-16 11:41:27 +00:00
Matias Niemela 8dee8f1b9e revert: fix(ngRoute): allow ngView to be included in an asynchronously loaded template
This reverts commit 88322c1af8.
2016-03-14 17:27:49 -04:00
Matias Niemela 1eef631ab5 revert: fix(ngMock): prevent memory leak due to data attached to $rootElement
This reverts commit 571e323f7d.
2016-03-14 17:27:49 -04:00
Matias Niemela 2ef92c329b revert: feat(ngMock): destroy $rootScope after each test 2016-03-14 17:27:49 -04:00
Matias Niemela 1467e15bca revert: fix(ngMock): don't break if $rootScope.$destroy() is not a function
This reverts commit 24a7f28f1e.
2016-03-14 17:27:49 -04:00
Peter Bacon Darwin 389349edc3 docs(guide/location): include section on base[href]
Closes #14018
2016-03-14 14:47:09 +00:00
Martin Staffa 722e97e8e6 docs($provide): clarify value and constant injectability
Closes #14168
2016-03-04 10:03:56 +01:00
Martin Staffa d3933a4181 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:30:42 +01:00
Georgios Kalpakas 8d02b07af4 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:34:11 +01:00
Georgios Kalpakas 24af9e2a6e test(docs): add tests for the errors module 2016-02-29 17:34:04 +01:00
Jason Bedard 4879e49c93 refactor($compile): remove out of date jQuery vs jqLite comment/workaround 2016-02-29 17:33:05 +01:00
Nabil Hashmi aec25f1829 docs($http): fix typo in link text (TransformationjqLiks --> Transformations)
Closes #14149
2016-02-28 23:12:22 +02:00
Martin Staffa f87e8288fb 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

Closes #14115
2016-02-28 16:11:56 +01:00
lordg 9b1beb8e09 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:11:55 +01:00
Georgii Dolzhykov 681e6246e3 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 16:08:16 +01:00
lordg 13e2ea73b0 docs(guide/Templates): add title for consistency
Closes #14141
2016-02-28 16:08:14 +01:00
Martin Staffa f5295ea448 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 16:08:13 +01:00
lordg bb01b8bf89 docs(guide/Filters): add title for consistency
Closes #14143
2016-02-28 16:08:11 +01:00
mohamed amr 711aba7727 test(ngAria): remove incorrect closing div tag after input element
Closes #14146
Closes #14147
2016-02-28 16:08:09 +01:00
Georgios Kalpakas 88322c1af8 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 12:10:03 +02:00
Martin Staffa 18f055eea5 docs($http): add a note about modifying data in transformRequest
Closes #12468
2016-02-24 17:57:45 +01:00
Georgios Kalpakas 24a7f28f1e 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:26:03 +02:00
Igor Dolgov 146f9c1611 docs(ngMock): add missing ")" in example
Closes #14112
2016-02-23 13:56:35 +02:00
Andy Gurden e55829a1cd 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
2016-02-22 17:02:25 +02:00
Georgios Kalpakas 571e323f7d 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 16:42:01 +02:00
Ben Elliott bf11cf3095 docs(ngMessages): clarify ngMessages docs with clearer example
Closes #14103
2016-02-22 12:20:03 +01:00
Kin 5a1e148da6 docs(numberFilter): improve wording for infinity description
Closes #14100
2016-02-22 12:20:00 +01:00
Kin eec095a751 docs(angular.forEach): fix typo 2016-02-22 12:19:56 +01:00
Gordon Zhu 7b2c7cbab8 docs(guide/index): add Firebase Foundations and Angular Course
Closes #14097
2016-02-21 07:52:58 +00:00
Matias Niemelä b830f5b68e revert: fix(ngMock): attach $injector to $rootElement
This reverts commit fad4dc07d7.

The fixes applied in the reverted commit caused a memory leak
with JQuery + Karma.
2016-02-20 22:16:47 -08:00
MicCarr 7e7a0693e5 docs(ngMock): fix typo in example
Closes #14069
2016-02-18 14:58:30 +02:00
Jason Bedard 02929f82f3 fix(input): re-validate when partially editing date-family inputs
Fixes #12207
Closes #13886
2016-02-18 11:04:09 +02:00
ryanhart2 b9d3625e92 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 01:03:27 +02:00
Georgios Kalpakas 863a4232a6 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 15:04:52 +02:00
Martin Staffa 4a39ad475b chore(docs-app): fix middle/right dropdown clicks in FF
Closes #14024
2016-02-17 13:45:19 +01:00
Martin Staffa 696d65dcba 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 13:45:17 +01:00
biohazardpb4 947cb4d145 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:59:10 +02:00
Matias Niemelä 77fc41f499 chore: fix version typo 2016-02-16 13:09:11 -08:00
Georgios Kalpakas d98a12a6f2 docs(guide/forms): make required ngModel optional in custom e-mail RegExp example 2016-02-16 23:06:56 +02:00
Matias Niemelä ef2c6e39be chore(build): 1.4 versions should stick to 1.4.x 2016-02-16 12:53:19 -08:00
srijan c219a87ad7 docs(guide/scope): fix typo in image
Closes #13724
2016-02-16 21:51:44 +02:00
Georgios Kalpakas fad4dc07d7 fix(ngMock): attach $injector to $rootElement
Fixes #14022

Closes #14034
2016-02-16 21:44:18 +02:00
Martin Staffa 373f054d5e 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 18:53:00 +01:00
lucienbertin beb00e44de 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 18:52:54 +01:00
Sean Murphy 6a4403a118 fix($routeProvider): properly handle optional eager path named groups
Closes #14011
2016-02-16 14:32:55 +02:00
Lucas Mirelmann 77cdc37c65 fix($compile): allow directives to have decorators
Allow directives to have decorators that modify the directive `scope` property

Close: #10149
2016-02-12 13:22:11 +01:00
Daniel Herman ab95ba65c0 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-12 11:27:35 +01:00
Daniel Herman 86416bcbee 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-12 11:27:35 +01:00
Daniel Herman d04c38c489 perf(ngRepeat): avoid duplicate jqLite wrappers
Internally, `$animate` already wraps elements passed through with
`jqLite`, so we can avoid needless duplication here.
2016-02-12 11:27:34 +01:00
Aashish Nagpal bdc5a1cde1 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:54 -08:00
John Mercer eccd618d76 docs(guide): add new book
Closes #13954
2016-02-08 02:06:55 -08:00
Martin Staffa 7f11af6b5e docs(error/iscp): extra spaces are allowed 2016-02-05 16:37:50 +01:00
Martin Staffa 437ba49a52 style(filters): squelch a closure compiler warning
Related #13932
2016-02-05 16:23:01 +01:00
Peter Bacon Darwin 9a576fa0fa chore(package): update the 1.4.x dist-tag 2016-02-05 12:52:27 +00:00
kuroky360 b5c317d672 refactor(toJson): use the isUndefined() function
Closes #13923
2016-02-04 10:36:58 +02:00
Georgios Kalpakas 05741ebf0b docs(guide/accessibility): fix links 2016-02-04 00:41:04 +02:00
Georgios Kalpakas 9e2c215779 docs(ngRequired): fix link 2016-02-04 00:20:37 +02:00
Georgii Dolzhykov 8a1f600c29 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 15:00:55 +02:00
Georgios Kalpakas 8519b8a60f docs(guide/accessibility): fix links
Closes #13936
2016-02-03 12:21:15 +02:00
Georgios Kalpakas 4bc3031497 fix($route): allow preventing a route reload
Fixes #9824
Closes #13894
2016-02-02 23:16:09 +02:00
Lucas Mirelmann ab5c7698bb 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 23:59:54 +02:00
Georgios Kalpakas 89690502d1 docs(guide/directive): minor fixes/improvements
Closes #13908
2016-02-01 15:15:35 +01:00
Lucas Mirelmann f47e218006 fix($parse): prevent assignment on constructor properties
Prevent malicious attacks involving assignment on `constructor` properties.

Closes #13417
2016-01-31 20:21:41 +00:00
Wojciech Krzystek 8dc4c75ade 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:23:16 +02:00
Prayag Verma e91811095b docs(misc/downloading): fix typo (it --> in)
Closes #13899
2016-01-31 10:46:35 +02:00
Smith afb298b7ff docs(error/$rootScope:inprog): fix typos ("a $apply" --> "an $apply")
Closes #13896
2016-01-31 10:35:33 +02:00
Georgios Kalpakas 571afd6558 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:08:47 +02:00
Georgios Kalpakas df6e731506 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:37:06 +02:00
Martin Staffa af9c2d71e2 docs(ngAnimateChildren) add docs 2016-01-28 21:40:22 +01:00
Martin Staffa dc158e7e40 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:40:22 +01:00
Lucas Mirelmann 0b7fff303f fix($parse): Copy inputs for expressions with expensive checks
Closes: #13871
2016-01-28 21:13:48 +02:00
Lucas Mirelmann 96d62cc0fc 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-28 19:21:39 +02:00
Michael 5cb7d0e046 docs($compile): minor typo/style correction
Closes #13864
2016-01-28 19:19:40 +02:00
Martin Staffa a60bbc12e8 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:28:36 +01:00
Isaac ca23d5f68f 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:32:48 +01:00
Thomas Moffett a398773b0c 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:01:10 +00:00
robw 1ef741563d 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:25:01 +00:00
Georgios Kalpakas 2d44a681eb 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:20:37 +02:00
Leo Gallucci 543af651d0 docs(guide/directives): improve Protractor test for bindings
This needs Protractor >= 1.3.0 to work.

Closes #9330
2016-01-26 15:33:23 +01:00
Peter Bacon Darwin e48666aeaf chore(ngLocale): regenerate locales to include original localeId
Closes #13390
2016-01-26 12:16:51 +00:00
Peter Bacon Darwin 87f80379ea style(i18n): improve indentation for readability 2016-01-26 11:44:49 +00:00
Peter Bacon Darwin 9cee054920 chore(i18n): fix up i18n testing tools 2016-01-26 11:44:43 +00:00
Peter Bacon Darwin e69f35507e 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:44:31 +00:00
Robert Reiz 379b8d9583 docs(bower.json): add MIT license
Closes #13405
2016-01-26 11:04:02 +00:00
Edgar Flores bf79770706 docs(guide/Interpolation): fix links
The links were not working, either `{` was missing or they were in the wrong location

Closes #13809
2016-01-25 23:03:29 +01:00
Martin Staffa 7b0a865c97 docs(guide/directives): link to the scope property docs
Closes #12500
2016-01-25 23:01:47 +01:00
Martin Staffa ce13cfd30a docs($sceDelegateProvider): fix markdown errors
Closes #13360
2016-01-25 23:00:58 +01:00
Robin Glauser c51fbcb7de docs(error/modulerr): add additional debugging help
This simple tip can help to diagnose the error.

Closes #12958
2016-01-25 17:08:03 +00:00
Martin Staffa 796f7ab414 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.
2016-01-25 16:38:46 +00:00
marianoc84 94d34beed4 docs(guide/Modules): update style guide link
The linked blog post recommends John Papa's Guide.

Closes #12898
2016-01-25 16:34:38 +00:00
Lucas Galfaso f476060de6 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 16:26:08 +00:00
Livvie Lin 6a953bb0cb 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:45 +00:00
Tobias Leugger - Vibes 3092fd31bb 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:41:43 +00:00
Martin Raifer dae4a2e736 docs(tutorial/step-7): add troubleshooting instructions
Show troubleshooting instructions as in step 11.

Closes #12715
2016-01-25 14:36:21 +00:00
Alireza Mirian 2632250a42 docs($injector): fix inaccuracy in $provide.service docs
Closes #12664
Closes #12665
2016-01-25 14:34:01 +00:00
Wesley Cho fdbd92ff99 docs($compile): improve nonassign error message
- Improve error message to mention attribute the expression errored on

Fixes #13827

Closes #13828
2016-01-24 17:20:17 +01:00
Matias Niemelä 3b27dd37a2 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:39:53 +01:00
Martin Staffa 76c6493c2b docs(guide/filter): clarify how to use filters in controllers
Closes #11915
2016-01-23 16:30:10 +01:00
Qingyu Zhou da03497f6b 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:25:52 +02:00
Peter Bacon Darwin a1fd2239c9 docs(CHANGELOG): fix animation grouping 2016-01-21 14:29:24 +00:00
Peter Bacon Darwin a39baef657 docs(CHANGELOG): add notes for 1.4.9 2016-01-21 12:40:38 +00:00
Lucas Galfaso 56508a1d5f 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-21 10:43:18 +00:00
Adrian Roselli d7d8708a9b docs(tutorial/step-6): add alt attribute to images
See http://www.ssbbartgroup.com/blog/accessible-images-using-angular/

Closes #12569
2016-01-21 10:43:17 +00:00
Peter Bacon Darwin 2ffbfb0ad0 fix($compile): handle boolean attributes in @ bindings
Closes #13767
Closes #13769
2016-01-21 10:43:17 +00:00
Daniel Herman 946d9ae90b 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-21 10:43:17 +00:00
Matias Niemelä a84393eadb 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-20 10:11:04 -08:00
Daniel Herman c429ad82f5 chore($compile): remove an unused dependency
Fixes #13791

Closes #13801
2016-01-19 20:45:21 +02:00
Georgios Kalpakas 900c7cd923 docs(ngModel): rename $asyncValidators error to nopromise and add missing error page
Closes #13795
2016-01-19 16:07:05 +02:00
Martin Staffa 2d3303ddda 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:32:36 +01:00
Martin Staffa a985adfdab 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:32:36 +01:00
Martin Staffa ca41996ef7 docs($compile): correct transcludeControllers definition
Closes #13793
2016-01-19 12:10:55 +01:00
Matias Niemelä 9a60408c80 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:08:49 +01:00
Matias Niemelä 09f6061a8e 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:08:43 +01:00
Peter Bacon Darwin 2d1ee4bffd 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:26 +00:00
Martin Staffa a412622f69 docs($animate): clarify info about from and to for animate() 2016-01-12 23:22:47 +01:00
dmitriz 63ffe5c360 docs(CONTRIBUTING): add warning about forced push
Add warning about the possible consequences of a forced push

Closes #13747
2016-01-12 18:03:24 +00:00
Matias Niemelä 2fc954d33a 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-12 17:35:24 +01:00
Matias Niemelä 512c081187 feat(ngMock): add support for $animate.closeAndFlush()
Use `$animate.closeAndFlush()` to close all running animations.

Includes a fix that landed separately in the master branch:
a801df719e
2016-01-12 17:35:24 +01:00
Georgios Kalpakas 2563ff7ba9 fix($controller): allow identifiers containing $
As discussed in https://github.com/angular/angular.js/issues/13664#issuecomment-170536024.

Closes #13736
2016-01-12 13:21:39 +02:00
Georgios Kalpakas 0a641c0181 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).
* `$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 19:26:11 +02:00
Georgios Kalpakas da04571dbc refct(privateMocks): remove unused argument from createMockStyleSheet() 2016-01-11 19:26:11 +02:00
mohamed amr 7f1cd3e6a2 test(ngList): add missing '>' to textarea closing tag
Fixes #13728
Closes #13727
2016-01-10 17:59:25 +02:00
Matias Niemelä 6d85f24e20 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 15:20:10 +01:00
Peter Bacon Darwin 0afd775433 docs(tutorial/step-00): fix dangling link 2016-01-08 12:31:07 +00:00
Peter Bacon Darwin 8eb01216b4 chore(package): update karma to 0.13
This version of karma can sniff Microsoft Edge correctly.

Closes #13691
2016-01-07 20:18:15 +00:00
Georgios Kalpakas 323f9ab736 fix(isArrayLike): recognize empty instances of an Array subclass
Fixes #13560
Closes #13708
2016-01-07 19:43:49 +00:00
Martin Staffa 5ba4419e26 fix(ngAnimate): allow event listeners on document in IE
Fixes #13548
Closes #13696
2016-01-07 13:04:42 +00:00
Martin Staffa 529b2507bd 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:40 +00:00
Martin Staffa 6d19aa2e7c docs($compile): add docs for bindToController with object hash
Closes #13228
Closes #13625
Closes #13658
Closes #13681
2016-01-06 16:18:42 +01:00
Georgios Kalpakas bf35d53855 docs(validators): fix typos and make minor layout improvements 2016-01-06 14:46:35 +01:00
Martin Staffa 6c4581fcb6 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-06 14:45:54 +01:00
Matias Niemelä 620a20d1b3 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:53:00 +00:00
Andy Patterson 1f8431bfaa 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:18:23 +00:00
Konstantin Ulitin b8773a71b5 docs(loader): fix type in @return tag for angular.module()
Closes #13655
2016-01-05 11:57:54 +00:00
Waitaya Krongapiradee 8a63071ab0 docs(error/$rootScope/inprog): add missing "$timeout"
Closes #13630
2016-01-04 22:22:09 +00:00
Kyle Pittman e2a0368726 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:11:17 +00:00
Martin Staffa d9157849df 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.

This commit includes the fix for a bug that was introduced by this change
and landed on master separately:
https://github.com/angular/angular.js/commit/959f2bbb2d12c23a74902433c6247290d8f2fb89

Closes #13672
2016-01-04 22:18:11 +01:00
Martin Staffa d558dc5f95 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:17:38 +01:00
Martin Staffa 616695eb05 docs: add docs for ngPattern, ngMinlength, ngMaxlength
Closes #9991
2015-12-31 18:17:37 +01:00
Martin Staffa 9ac4e5a64b 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:17:37 +01:00
Waitaya Krongapiradee fcb6e1e96b docs(tutorial): fix some minor punctuation errors
Closes #13633
2015-12-31 18:17:36 +01:00
ammills01 cf972fd0bd 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:17:36 +01:00
Wesley Cho ffc3115705 docs($resource): fix wording for failure
- Fix mention of promise resolution on failure: resolved -> rejected

Closes #13638
Closes #13624
2015-12-31 18:17:36 +01:00
Alexander Zagumennikov 9590bcf062 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-21 15:24:55 +02:00
thorn0 689c01f599 refactor($parse): remove unused variables
Closes: #13579
2015-12-21 13:51:12 +02:00
Peter Bacon Darwin 2334a5101d chore(Gruntfile): replace double quotes with single quotes 2015-12-17 22:08:53 +00:00
Peter Bacon Darwin ed7777d3e1 chore(GruntFile): fix whitespace in lists 2015-12-17 22:08:52 +00:00
Peter Bacon Darwin a1648737bd chore(GruntFile): move validate-angular-files task into its own file
Closes #13569
2015-12-17 22:08:52 +00:00
Matias Niemelä 420586bd09 chore(build): add a validation step for angularFiles
Closes #13553
2015-12-17 22:08:52 +00:00
Peter Bacon Darwin d89afc488f chore(angularFiles): add documentation only file to list of files
This prevents errors when checking `validate-angular-files`
2015-12-17 22:08:52 +00:00
Peter Bacon Darwin 0a8a6fa36b chore(npm-shrinkwrap): install glob package 2015-12-17 22:08:52 +00:00
Peter Bacon Darwin e1a182b105 chore(jenkins): remove unused argument definition 2015-12-17 14:15:30 +00:00
Peter Bacon Darwin 214f6822c3 chore(jenkins): run Jenkins builds on Node 4 (via nvm)
Closes #13568
2015-12-17 14:10:15 +00:00
Peter Bacon Darwin 9c5a1cd43c chore(jenkins): move jenkins_build.sh to scripts/jenkins/build.sh 2015-12-16 14:23:09 +00:00
Georgios Kalpakas 8120ab2f77 docs($compile): fix scope hierarchy indentation in HTML output 2015-12-16 15:28:56 +02:00
Peter Bacon Darwin 2f08eae48f chore(travis): update to use node 4.x 2015-12-16 11:15:01 +00:00
Georgios Kalpakas 6610ae816f 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:42:26 +02:00
Georgios Kalpakas fa56f8eadb 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:42:17 +02:00
Martin Staffa 7882c1c6ae 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:24:42 +00:00
Justas Brazauskas 84a6ef4d21 docs: fix typos throughout the codebase
Closes #13519
2015-12-15 21:54:41 +02:00
Georgios Kalpakas 4d680c3fad 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-15 20:04:26 +02:00
ReneFerwerda bab3069dff docs(select): fix typo
Closes #13491
2015-12-13 22:16:22 -08:00
Martin Staffa 4cb8ac61c7 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-13 22:16:22 -08:00
Igor Minar 9d28a79219 test(ngOptionsSpec): remove ddescribe which caused CI to skip most of unit tests 2015-12-13 22:16:22 -08:00
Igor Minar c4489eb3cb revert: fix($animateCss): remove animation end event listeners on close
This reverts commit c98e08fd87.

This commit was identified as incompatible with ng-material at Google
and is causing broken builds there. Proper fix to be investigated once
the immediate regression is addressed.
2015-12-13 22:16:22 -08:00
Martin Staffa 7caf91300f test($animate): ensure that pin() arguments are elements 2015-12-10 15:20:48 +01:00
Martin Staffa 0c1b54f04c 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 15:20:48 +01:00
Martin Staffa 85e392f354 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 15:18:24 +01:00
Martin Staffa c98e08fd87 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 15:05:21 +01:00
Matias Niemelä 33cc75e6fc chore(angularFiles): the animateRunner.js file doesn't exist for ngAnimate anymore 2015-12-08 14:48:54 -08:00
Georgios Kalpakas 474865242c fix($resource): don't allow using promises as timeout and log a warning
Promises never worked correctly as values for `timeout` in `$resource`, because the same value has
to be re-used for multiple requests (and it is not possible to `angular.copy()` a promise).
Now (in addition to ignoring a non-numeric `timeout`), a warning is logged to the console using
`$log.debug()`.

Partly fixes #13393.

BREAKING CHANGE:

Possible breaking change for users who updated their code to provide a `timeout`
promise for a `$resource` request in version 1.4.8.

Up to v1.4.7 (included), using a promise as a timeout in `$resource`, would silently
fail (i.e. have no effect).

In v1.4.8, using a promise as timeout would have the (buggy) behaviour described
in https://github.com/angular/angular.js/pull/12657#issuecomment-152108887
(i.e. it will work as expected for the first time you resolve the promise and will
cancel all subsequent requests after that - one has to re-create the resource
class. This is feature was not documented.)

With this change, using a promise as timeout in 1.4.9 onwsards is not allowed.
It will log a warning and ignore the timeout value.

If you need support for cancellable `$resource` actions, you should upgrade to
version 1.5 or higher.
2015-12-08 16:39:33 +00:00
Georgios Kalpakas 0292e6a1a8 docs($resource): add note about _promises as timeout_ not being supported
Fixes part of #13393.
2015-12-08 16:34:27 +00:00
Georgios Kalpakas de193422a3 refactor($resource): change if-block to switch-block for readability 2015-12-08 16:34:26 +00:00
Georgios Kalpakas ff228fb524 revert: fix($resource): allow XHR request to be cancelled via timeout promise
This reverts commit 7170f9d9ca.

Fixes part of #13393.
2015-12-08 16:34:26 +00:00
Martin Staffa 8709539d4c 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:21:39 +01:00
Andy Patterson 2995b54afd 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:33:32 +02:00
Georgios Kalpakas e26256fb70 docs(guide/$location): fix table header formatting
Closes #13456

Closes #13459
2015-12-07 19:50:10 +02:00
Martin Staffa e45f9b66fa docs(guide/Unit Testing): fix typo
Closes #13227
2015-12-07 14:37:32 +01:00
zainengineer 158f1aec86 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:37:31 +01:00
Hovhannes Babayan f53a7f62bb 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 14:37:31 +01:00
Martin Staffa d2b08a0465 docs(changelog, guide/migration): add BC notes for observing unset attributes
Closes #11163
2015-12-07 13:45:02 +01:00
Mil4n 43c4029c8a 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:53:22 +02:00
Marcus Nielsen 55ac985373 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:57:15 +00:00
Martin Staffa 37b6ed3225 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-04 00:02:17 +01:00
Utsav Shah c5bf9daef6 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-04 00:02:17 +01:00
Martin Staffa be01cebfae 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 21:01:53 +01:00
Matias Niemelä 7a81e6fe2d 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:28:37 +01:00
Peter Bacon Darwin 9c49eb131a 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 22:00:25 +00:00
xieranmaya 374a302b90 docs($controller): fix typo
Closes #13418
2015-12-01 19:12:02 +00:00
daviskoh b3da88077f docs($parse): fix typo in error message description
Closes #13409
2015-11-30 12:47:40 +01:00
Adam Zerner 6454f51741 docs(guide/Scopes): fix grammar
Closes #13413
2015-11-30 12:47:05 +01:00
Martin Staffa e509ab5be6 style($animateCssSpec): remove dump from test 2015-11-30 12:47:05 +01:00
Martin Staffa 592bf516e5 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:57:44 +01:00
Joan Claret 8cdafe46e3 docs(tutorial/2 - Angular Templates): add closing parenthesis
Closes #13368
2015-11-26 18:57:44 +01:00
Peter Bacon Darwin 45c5688d42 test($compile): add test for undefined non-optional reference binding
Demonstrates that #13373 fixes #13367
2015-11-25 10:53:10 +00:00
Lucas Mirelmann 7bb2414bf6 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:53:01 +00:00
Peter Bacon Darwin da11c1bcee chore(bower/publish): read dist-tag from correct package.json 2015-11-24 13:20:03 +00:00
J.P. Poveda a80697938e docs($timeout): reword sentence for clarity
Closes #13302
2015-11-23 13:16:23 +01:00
Matt Erickson 1d9ad76f1f docs($swipe): remove reference to ngCarousel
ngCarousel no longer exists (or has ever existed).

Closes #13322
Closes #13353
2015-11-23 13:16:22 +01:00
Rahat Ahmed 01387ba3c3 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:16:21 +01:00
mohamed amr f163c90555 fix(ngOptions): don't $dirty multiple select after compilation
Closes #13211
Closes #13326
2015-11-23 13:16:19 +01:00
Martin Staffa 4e94864e54 chore(i18n): update locale files with standalone months
Closes #12844
2015-11-23 10:44:30 +00:00
Martin Staffa 54c4041ebc 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:44:24 +00:00
Anita Perala f780aba434 docs(guide/Conceptual Overview): add missing object in sentence
docs: minor grammar fix
missing word in overview

Closes #13346
2015-11-20 18:16:53 +01:00
Martin Staffa 057f78de8b docs(angular.element): add more info, fix formatting
- add info about ngJq
- fix alert box
- add info about css function
2015-11-20 18:16:53 +01:00
Julián Salgado 7a36128efc docs(angular.element): note that it does not find elements by tag name / selector
Closes #13107
Closes #13113
2015-11-20 18:16:52 +01:00
Anas Qadrei d2cd8b9bb6 docs(error/nobase): making <base> visible in html
Closes #13350
2015-11-20 17:35:48 +01:00
Matias Niemelä 937942f5ad 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 17:34:34 +01:00
Matias Niemelä 75e876424d chore(CHANGELOG): update with changes for 1.4.8 2015-11-19 14:52:56 -08:00
Jason Bedard 19fab4a1d7 perf(copy): avoid regex in isTypedArray
Closes: #12054
2015-11-19 08:59:00 +00:00
Jason Bedard d1293540e1 perf(copy): only validate/clear user specified destination
Closes #12068
2015-11-19 08:58:47 +00:00
Peter Bacon Darwin 22f66025db fix(jqLite): deregister special mouseenter / mouseleave events correctly
Closes #12795
Closes #12799
2015-11-12 18:45:59 +00:00
rrsivabalan 6f8ddb6d43 fix($location): ensure $locationChangeSuccess fires even if URL ends with #
Closes #12175
Closes #13251
2015-11-12 13:40:29 +00:00
Eric Lee Carraway 34590e15d4 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:31:06 +02:00
Eric Lee Carraway 83098b9add 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:26:39 +02:00
Peter Bacon Darwin 5d8861fb2f 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:56:33 +00:00
Georgios Kalpakas b9f7c453e0 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:56:33 +00:00
Jakub Torbicki 750344129e 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:56:33 +00:00
Peter Bacon Darwin 74da034077 fix($compile): fix scoping of transclusion directives inside replace directive
Closes #12975
Closes #12936
Closes #13244
2015-11-10 20:56:07 +00:00
Jason Bedard 91ef94d284 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-10 20:48:33 +00:00
Martin Staffa ab9b021572 docs(changelog, migration): add BC notice for ngMessages evaluation
Introduced by

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

Closes #13145
2015-11-06 17:19:16 +01:00
Doug Krugman b0c19f8b06 docs(guide/Concepts): remove unused refresh property
Closes #13257
2015-11-06 10:17:00 +02:00
jody tate bbc2a0ae48 docs(guide/Directives): change "it" to possessive
Closes #13253
2015-11-05 14:27:07 +02:00
Martin Staffa ca53dfcc18 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:40:50 +01:00
Georgios Kalpakas ce6a96b0d7 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:49:54 +02:00
Peter Bacon Darwin d4b359f4b2 test(merge): fix check on jquery object 2015-11-02 20:13:14 +00:00
JonyD 8d841c3405 docs(ngRepeat): fix link to MDN
Closes #13226
2015-11-02 21:00:13 +01:00
Martin Staffa 2b285c75f4 docs(ngInclude): fix incorrect link 2015-11-02 21:00:12 +01:00
Martin Staffa 6e4464331d docs(tutorial/0 - Bootstrapping): mention that the setup must be completed
Closes #13106
2015-11-02 21:00:11 +01:00
Peter Bacon Darwin 2f8db1bf01 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:56:13 +00:00
luckylooke 838cf4be3c fix(merge): clone elements instead of treating them like simple objects
Similar fix to #11720

Closes #12286
2015-11-02 17:22:26 +00:00
Matthew Hill de2a56bbc8 docs(angular-mocks): clarify angular.mock.module usage with objects
Closes #12354
2015-11-01 07:14:20 +00:00
Jason Bedard 55ad192e4a perf($compile): use static jquery data method to avoid creating new instances 2015-11-01 07:00:22 +00:00
Chris J. Lee 5b4713e43e chore(protractor-conf.js): remove dangling comma
Closes #13051
2015-11-01 06:46:08 +00:00
Peter Bacon Darwin 3fa9aba0cc chore(package.json): update dgeni-packages to 0.11.0 2015-10-31 20:44:55 +00:00
Peter Bacon Darwin 1bba358a75 chore(package.json): add commitizen, adapter and npm script
Closes #13194
2015-10-31 20:43:13 +00:00
Bert Verhelst 7a4124c298 docs($location): improve style
Closes #13072
2015-10-30 22:09:58 +01:00
Martin Staffa 2512a81e09 docs(error/ctreq): fix typo
Closes #13083
2015-10-30 22:09:58 +01:00
Michael George Attard 44c9d1616a docs($rootScope): improve clarity and consistency
Closes #13110
2015-10-30 22:09:57 +01:00
Pablo Villoslada Puigcerber 5758d73964 docs(select): document the multiple attribute
Add the `multiple` attribute to the documentation of the select directive.

Closes #13119
2015-10-30 20:41:58 +02:00
Sreenivasan K 6bd6dbff49 fix($animate): ensure leave animation calls close callback
Closes #12278
Closes #12096
Closes #13054
2015-10-29 07:55:36 +00:00
Stanislav Komanec 7170f9d9ca fix($resource): allow XHR request to be cancelled via timeout promise
Closes #12657
Closes #12675
Closes #10890
Closes #9332
2015-10-28 22:26:21 +00:00
Peter Bacon Darwin 1c0f721368 test($rootScope): ensure that only child scopes are disconnected
Related to #11786 and 8fe781fbe7
2015-10-28 22:06:25 +00:00
Alicia Lauerman 2a5a52a76c 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:17 +00:00
Georgios Kalpakas c690946469 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:52 +00:00
Peter Bacon Darwin 87b0055c80 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:35:22 +00:00
Charlie-Hua 2116857a2a 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:10:03 +01:00
Peter Bacon Darwin 0f58334b7b fix(ngOptions): skip comments and empty options when looking for options
Related #12952
Closes #12190
Closes #13029
Closes #13033
2015-10-28 18:33:08 +01:00
Stu Cox bcc257b459 docs($q): add a note re. difference in exception handling vs ES6
Closes #11472
Closes #13101
2015-10-28 08:18:00 +00:00
Ryan Hart 980fb395e4 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:01:58 +02:00
Sam Rawlins 62ed26a84f docs($anchorScroll): fix link to HTML5 spec
Closes #13180
2015-10-27 20:40:43 +02:00
Marcy Sutton 59f1f4e19a fix(ngAria): don't add tabindex to radio and checkbox inputs
Closes #12492
Closes #13095
2015-10-27 17:52:02 +01:00
Andrew Austin cb51116dbd 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:53 +00:00
Kuzminov Aleksandr Sergeevich c1f34e8eeb fix(jqLite): ensure mouseenter works with svg elements on IE
Closes #10259
Closes #10276
2015-10-26 21:27:04 +00:00
sevdog 7bf5429e3b docs($animateCss): add missing documentation for the structural option
Add missing documentation for structural option in `$animateCss` service

Closes #13049
2015-10-26 13:03:37 -07:00
Lucas Galfaso d3da55c40f fix(isArrayLike): handle jQuery objects of length 0
Closes: #13169
Closes: #13171
2015-10-26 18:01:15 +00:00
Jack Viers 70edec947c fix(Angular.js): fix isArrayLike for unusual cases
Closes #10186
Closes #8000
Closes #4855
Closes #4751
Closes #10272
2015-10-26 18:01:15 +00:00
Risan Bagja Pradana fe17c0e066 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:44:43 +02:00
Lucas Mirelmann e403682444 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-15 22:20:30 +02:00
zurin 27d441b0d6 docs(guide/Scopes): fix grammar
Added a comma to make reading more natural.

Closes #13084
2015-10-14 16:16:02 +03:00
Michael Salmon 8a944b0872 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:53:12 +03:00
Martin Staffa 786a1a4429 docs(ngOptions): add info about preselecting complex models
Closes #12966
2015-10-08 15:56:17 +02:00
Chris J. Lee 8e5c4e92f7 test(ngResource): fix typos in tests
Closes #13044
2015-10-08 11:49:17 +03:00
Flavio Corpa Ríos 46d24ae4c8 docs(ngInclude): add workaround for using onload function with SVG in IE11
Closes #12493
Closes #13042
2015-10-07 23:04:31 +02:00
Jason Hopper 9dd33c09b1 docs(tutorial): update angular module versions to reflect tutorial files
Closes #12991
Closes #12992
2015-10-07 17:53:26 +02:00
Sugan Krishnan fea8240c81 docs($sce): fix typo
Closes #13030
2015-10-07 13:23:11 +01:00
Peter Bacon Darwin 3d2b1be211 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 13:05:04 +01:00
Peter Bacon Darwin f08a0c5ad1 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 13:05:03 +01:00
Peter Bacon Darwin 6f1e0ba563 refactor($compile): rename variables to clarify their purpose
Closes #12528
2015-10-07 13:05:03 +01:00
Jason Bedard 540338f9a5 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 13:05:03 +01:00
Martin Staffa 0e6a700807 Revert "fix(ngOptions): skip comments when looking for option elements"
This reverts commit 68d4dc5b71.
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:33:32 +02:00
Georgios Kalpakas 4fc40bc932 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-07 00:09:37 +03:00
Richard Harrington 216724b4cb docs(constant): fix pluralization
Closes #13024
2015-10-06 23:22:41 +03:00
Raghav 9bd1645970 docs($animate): fixed typo ("an animations" -> "any animations")
Closes #13020
2015-10-06 23:15:15 +03:00
Magnus Pedersen 3397a031a1 docs(ngOptions): rephrased a sentence for clarity
Closes #13010
2015-10-06 23:12:55 +03:00
Peter Bacon Darwin 5ec5aa7751 style(ngOptionsSpec): remove excess space
This was inadvertently added in 7b2ecf42c6
2015-10-06 14:36:47 +01:00
Peter Bacon Darwin bf5ac5261d style(ngOptions): fix missing closing brace
This was inadvertently added in 7b2ecf42c6
2015-10-06 14:20:37 +01:00
Peter Bacon Darwin 91b7cd9b74 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:58:23 +01:00
Martin Staffa 7b2ecf42c6 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:57:40 +01:00
Matias Niemelä 256d9a948c docs(ngAnimate): simplify $animateCss example code 2015-10-05 10:56:43 -07:00
spoonraker 99fc6cda98 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:22:17 -07:00
Jason Hopper 690b69b9cd 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:18:45 -07:00
Alexandr Gureev 4262f15e16 docs(ngAnimate): fix typos in examples
Closes #12995
2015-10-02 11:27:05 +03:00
John Zhang 3a8d1354ce 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:33:40 +02:00
Donghwan Kim f9387c6890 docs(guide/Running in Production): fix an incorrect indefinite article
Closes #12986
2015-10-01 18:33:29 +02:00
koyner 48d0ffcbc4 docs(guide/Forms): fix indentation.
Closes #12988
2015-10-01 18:23:51 +02:00
Martin Staffa 3485ba1e2b docs(guide/Using $location): note that the fakeBrowser is not for actual projects
Closes #12982
Closes #12987
2015-10-01 18:21:56 +02:00
Matias Niemelä 2f61145475 chore(CHANGELOG): update with changes for 1.4.7 2015-09-29 13:54:51 -07:00
Martin Staffa 8c618d896b 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:48:20 +02:00
Martin Staffa 68d4dc5b71 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:48:13 +02:00
Martin Staffa 03a4a96cf9 test(ngOptions): clarify a test description 2015-09-27 15:48:06 +02:00
Stefan Krüger 655c52a621 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-27 15:47:57 +02:00
Martin Staffa fa3ddba5f2 docs(ngModel): align $viewValue description with $setViewValue 2015-09-27 15:47:43 +02:00
Matias Niemelä c4a1b6124e docs($animateCss): options.transition should be options.transitionStyle 2015-09-24 10:06:22 -07:00
Matias Niemelä e52d731bfd 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 10:02:30 -07:00
Igor Minar 9b72843018 build(travis): make sauce connect process query a bit more specific 2015-09-23 14:01:32 -07:00
Georgios Kalpakas 9c1f8ea70b 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-23 23:01:15 +03:00
Igor Minar 9fde5648e4 build(travis): fix typo in a comment 2015-09-23 11:01:00 -07:00
Igor Minar ea829620b2 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:27 -07:00
Martin Staffa 1731d091f8 docs(ngList): whitespace -> newline 2015-09-23 17:38:15 +02:00
Matias Niemelä 9d3704ca46 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 13:47:16 -07:00
Matias Niemelä 215dff34dd 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 13:47:10 -07:00
Matias Niemelä fa8c399fad 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 13:47:04 -07:00
Peter Bacon Darwin 7295c60ffb 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 20:53:40 +01:00
Martin Staffa fa01571036 docs(guide/Directives): fix link formatting
Closes #12909;
2015-09-22 13:12:52 +02:00
Martin Staffa dbc698517f 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 13:05:06 +02:00
Lucas Galfaso a7f3761eda fix($parse): block assigning to fields of a constructor
Throw when assigning to a field of a constructor.

Closes #12860
2015-09-22 10:44:27 +01:00
Jason Bedard 5a98e806ef fix($compile): use createMap() for $$observe listeners when initialized from attr interpolation
Closes #10446
2015-09-21 19:05:20 +01:00
Ivan Verevkin 808f984ec0 docs($cacheFactory): fix call to isUndefined() in example
Closes #12899
2015-09-21 15:51:49 +03:00
Lucas Mirelmann 698af191de fix($parse): do not convert to string computed properties multiple times
Do not convert to string properties multiple times.
2015-09-19 22:21:59 +02:00
Sjur Bakka 7a413df5e4 feat($http): add $xhrFactory service to enable creation of custom xhr objects
Closes #2318
Closes #9319
Closes #12159
2015-09-18 19:52:50 +01:00
Peter Bacon Darwin 4994acd26e fix(filters): ensure formatNumber observes i18n decimal separators
Closes #10342
Closes #12850
2015-09-18 13:45:29 +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
960 changed files with 38945 additions and 10674 deletions
+16 -21
View File
@@ -1,7 +1,7 @@
language: node_js
sudo: false
node_js:
- '0.10'
- '4.4'
cache:
directories:
@@ -15,28 +15,26 @@ 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 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,21 +44,18 @@ 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:
+1003 -90
View File
File diff suppressed because it is too large Load Diff
+13 -6
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
@@ -202,7 +208,7 @@ format that includes a **type**, a **scope** and a **subject**:
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.
@@ -215,7 +221,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
@@ -233,7 +239,7 @@ 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
@@ -268,6 +274,7 @@ 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
+20 -14
View File
@@ -115,7 +115,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' },
@@ -156,9 +156,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 +231,9 @@ module.exports = function(grunt) {
dest: 'build/angular-aria.js',
src: util.wrap(files['angularModules']['ngAria'], 'module')
},
"promises-aplus-adapter": {
'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']
}
},
@@ -249,7 +253,7 @@ module.exports = function(grunt) {
},
"ddescribe-iit": {
'ddescribe-iit': {
files: [
'src/**/*.js',
'test/**/*.js',
@@ -270,7 +274,7 @@ module.exports = function(grunt) {
}
},
"merge-conflict": {
'merge-conflict': {
files: [
'src/**/*',
'test/**/*',
@@ -300,11 +304,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,8 +339,10 @@ 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:modules', 'Run the Karma module tests with Karma', ['build', 'tests:modules']);
@@ -346,11 +352,11 @@ module.exports = function(grunt) {
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']);
};
+25 -2
View File
@@ -18,10 +18,10 @@ piece of cake. Best of all?? It makes development fun!
* Developer Guide: http://docs.angularjs.org/guide
* Contribution guidelines: [CONTRIBUTING.md](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
* Dashboard: http://dashboard.angularjs.org
Building AngularJS
---------
[Once you have your environment setup](http://docs.angularjs.org/misc/contribute) just run:
[Once you have your environment set up](http://docs.angularjs.org/misc/contribute) just run:
grunt package
@@ -43,3 +43,26 @@ To learn more about the grunt tasks, run `grunt --help` and also read our
[![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 Maintable Code
Everything in AngularJS is created to enable the programmer ends 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.
+13 -8
View File
@@ -14,13 +14,15 @@ 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',
@@ -32,6 +34,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 +79,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,7 +101,6 @@ var angularFiles = {
'src/ngAnimate/animateJs.js',
'src/ngAnimate/animateJsDriver.js',
'src/ngAnimate/animateQueue.js',
'src/ngAnimate/animateRunner.js',
'src/ngAnimate/animation.js',
'src/ngAnimate/module.js'
],
@@ -179,7 +184,6 @@ var angularFiles = {
'bower_components/jquery/dist/jquery.js',
'test/jquery_remove.js',
'@angularSrc',
'src/publishExternalApis.js',
'@angularSrcModules',
'@angularScenario',
'@angularTest'
@@ -188,7 +192,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': [
@@ -215,7 +220,6 @@ var angularFiles = {
'bower_components/jquery/dist/jquery.js',
'test/jquery_alias.js',
'@angularSrc',
'src/publishExternalApis.js',
'@angularSrcModules',
'@angularScenario',
'@angularTest'
@@ -224,7 +228,8 @@ var angularFiles = {
'karmaJqueryExclude': [
'src/angular-bootstrap.js',
'src/ngScenario/angular-bootstrap.js',
'test/jquery_remove.js'
'test/jquery_remove.js',
'src/angular.bind.js'
]
};
+1
View File
@@ -1,5 +1,6 @@
{
"name": "AngularJS",
"license": "MIT",
"devDependencies": {
"jquery": "2.1.1",
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
+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 */
+7 -1
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;
}
@@ -589,6 +589,12 @@ ul.events > li {
vertical-align: top;
}
.table > tbody > tr.head > td,
.table > tbody > tr.head > th {
border-bottom: 2px solid #ddd;
padding-top: 50px;
}
@media only screen and (min-width: 769px) and (max-width: 991px) {
.main-body-grid {
margin-top: 160px;
-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
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');
}
}
};
});
+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'));
}
};
}]);
+50
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) {
/**
+5 -7
View File
@@ -11,8 +11,7 @@ angular.module('tutorials', [])
scope: {},
template:
'<a ng-href="tutorial/{{prev}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-step-backward"></i> Previous</li></a>\n' +
'<a ng-href="http://angular.github.io/angular-phonecat/step-{{seq}}/app"><li class="btn btn-primary"><i class="glyphicon glyphicon-play"></i> Live Demo</li></a>\n' +
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{diffLo}}...step-{{diffHi}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-search"></i> Code Diff</li></a>\n' +
'<a ng-href="https://github.com/angular/angular-phonecat/compare/1.4-step-{{diffLo}}...1.4-step-{{diffHi}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-search"></i> Code Diff</li></a>\n' +
'<a ng-href="tutorial/{{next}}"><li class="btn btn-primary">Next <i class="glyphicon glyphicon-step-forward"></i></li></a>',
link: function(scope, element, attrs) {
var seq = 1 * attrs.docTutorialNav;
@@ -38,12 +37,11 @@ angular.module('tutorials', [])
'<p><button class="btn" ng-click="show=!show">Workspace Reset Instructions ➤</button></p>\n' +
'<div class="alert alert-info" ng-show="show">\n' +
' <p>Reset the workspace to step {{step}}.</p>' +
' <p><pre>git checkout -f step-{{step}}</pre></p>\n' +
' <p>Refresh your browser or check out this step online: '+
'<a href="http://angular.github.io/angular-phonecat/step-{{step}}/app">Step {{step}} Live Demo</a>.</p>\n' +
' <p><pre>git checkout -f 1.4-step-{{step}}</pre></p>\n' +
' <p>Refresh your browser to see the changes.</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/1.4-step-{{step ? (step - 1) : \'0~1\'}}...1.4-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
}
}
+166
View File
@@ -0,0 +1,166 @@
'use strict';
describe('errors', function() {
// Mock `ngSanitize` module
angular.
module('ngSanitize', []).
value('$sanitize', jasmine.createSpy('$sanitize').andCallFake(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.reset();
var input = 'start https://foo/bar?baz#qux end';
var output = errorLinkFilter(input);
expect($sanitize.callCount).toBe(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.andCallFake(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').andReturn({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').andReturn({p0: 'foo'});
var elem = $compile('<span error-display="foo = {0}"></span>')($rootScope);
expect(errorLinkFilter.callCount).toBe(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>');
});
});
});
+5 -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' }
];
@@ -170,4 +170,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',
@@ -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>
@@ -1,4 +1,4 @@
{# 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>
@@ -24,5 +24,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 #}
+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.
+5 -3
View File
@@ -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
}
...
}
+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 `<base>` 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
+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
@@ -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.
+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>
+33 -70
View File
@@ -23,9 +23,9 @@ angular.module('myApp', ['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
@@ -41,8 +41,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.directive: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
@@ -134,16 +134,14 @@ attributes (if they have not been explicitly specified by the developer):
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>
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
using ngAria with {@link ng.directive: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.
@@ -160,11 +158,11 @@ Becomes:
```
>You can check whether a control is legitimately disabled for a screen reader by visiting
[chrome://accessibility](chrome://accessibility).
[chrome://accessibility](chrome://accessibility) and inspecting [the accessibility tree](http://www.paciellogroup.com/blog/2015/01/the-browser-accessibility-tree/).
<h2 id="ngshow">ngShow</h2>
>The [ngShow](https://docs.angularjs.org/api/ng/directive/ngShow) directive shows or hides the
>The {@link ng.directive: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.
@@ -201,7 +199,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.directive: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 +208,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
@@ -260,62 +267,18 @@ The attribute magic of ngAria may not work for every scenario. To disable indivi
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');
+31
View File
@@ -274,6 +274,37 @@ myModule.directive('my-directive', ['$animate', function($animate) {
}]);
```
## 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 ... */
```
## More about animations
For a full breakdown of each method available on `$animate`, see the {@link ng.$animate API documentation}.
+18 -19
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*
@@ -348,8 +348,7 @@ The following example shows how this is done with Angular:
return {
currencies: currencies,
convert: convert,
refresh: refresh
convert: convert
};
}]);
</file>
+3 -3
View File
@@ -109,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.
@@ -165,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
@@ -305,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 -92
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
@@ -345,6 +303,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 +407,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 +536,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 +647,7 @@ To do this, we need to use the `transclude` option.
return {
restrict: 'E',
transclude: true,
scope: {},
templateUrl: 'my-dialog.html'
};
});
@@ -688,8 +658,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 +680,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 +692,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 +703,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 +776,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 +837,7 @@ element?
}]);
</file>
<file name="index.html">
<span my-draggable>Drag ME</span>
<span my-draggable>Drag Me</span>
</file>
</example>
@@ -892,7 +860,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 +876,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 +898,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 +917,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 +950,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 +986,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.
+12 -6
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:
@@ -35,7 +36,9 @@ 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 Comma And Void Operators:** You cannot use `,` or `void` operators in an Angular expression.
* **Filters:** You can use {@link guide/filter filters} within expressions to format data before
displaying it.
@@ -70,7 +73,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>
@@ -141,6 +144,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 +283,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 +350,4 @@ When using a directive that takes an expression:
<ul>
<li ng-repeat="item in ::items | orderBy:'name'">{{item.name}};</li>
</ul>
```
```
+12 -5
View File
@@ -3,6 +3,8 @@
@sortOrder 280
@description
# Filters
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.
@@ -32,10 +34,13 @@ E.g. the markup `{{ 1234 | number:2 }}` formats the number 1234 with 2 decimal p
## 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
@@ -108,6 +113,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,8 +133,9 @@ 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>
+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
+7 -4
View File
@@ -53,7 +53,7 @@ In Angular applications, you move the job of filling page templates with data fr
## 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/)
* **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/)
* **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)
@@ -91,7 +91,7 @@ This is a short list of libraries with specific support and documentation for wo
### 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)
* **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)
@@ -101,7 +101,7 @@ This is a short list of libraries with specific support and documentation for wo
## Learning Resources
###Books
### 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
@@ -111,10 +111,12 @@ This is a short list of libraries with specific support and documentation for wo
* [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:
### Videos:
* [egghead.io](http://egghead.io/)
* [Angular on YouTube](http://youtube.com/angularjs)
* [Firebase Foundations for AngularJS](http://blog.watchandcode.com/firebase-foundations/)
### Courses
* **Free online:**
@@ -122,6 +124,7 @@ This is a short list of libraries with specific support and documentation for wo
[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),
+146
View File
@@ -0,0 +1,146 @@
@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))
### 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.
+146 -11
View File
@@ -170,6 +170,25 @@ 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.
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
@@ -189,13 +208,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
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 +230,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,7 +244,47 @@ ngModelCtrl.$formatters.push(function(value) {
});
```
## Templating (`ngRepeat`, `$compile`)
### 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
@@ -248,7 +313,46 @@ 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`)
@@ -288,8 +392,6 @@ has been moved to `$cookies`, to which `$cookieStore` now simply
delegates calls.
## Server Requests (`$http`)
Due to [5da1256](https://github.com/angular/angular.js/commit/5da1256fc2812d5b28fb0af0de81256054856369),
@@ -321,8 +423,6 @@ $http.get(url, {
```
## Filters (`filter`, `limitTo`)
### `filter` filter
@@ -340,8 +440,6 @@ Now, instead of returning empty object/array, it returns unchanged input.
# Migrating from 1.2 to 1.3
## Controllers
@@ -559,6 +657,36 @@ 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
}
}
```
@@ -631,8 +759,15 @@ $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`)
+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.
+7 -3
View File
@@ -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.
+1 -1
View File
@@ -359,7 +359,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>
```
+3 -3
View File
@@ -15,14 +15,14 @@ development.
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:
example points to the minified version 1.4.5:
```
<!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.4.5/angular.min.js"></script>
</head>
<body>
</body>
@@ -46,7 +46,7 @@ Download the version you want and have fun.
Each directory under <http://code.angularjs.org/> includes the following set of files:
* __`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
opening it in any editor or browser. In order to get better error messages during development, you
should always use this non-minified angular script.
* __`angular.min.js`__ — This is a minified and obfuscated version of
+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?
+25 -4
View File
@@ -5,6 +5,22 @@
# PhoneCat Tutorial App
<div class="alert alert-danger">
<p>
This version of the tutorial is deprecated and no longer maintained. You can find the most
recent version of the tutorial at https://docs.angularjs.org/tutorial/.
</p>
<p>
It is recommended to use the latest tutorial version for the following reasons:
<ul>
<li>It showcases features introduced in AngularJS v1.5+</li>
<li>It follows modern best practices in terms of architecture and code organization</li>
<li>It has more up-to-date dependencies and tools</li>
<li>It is actively maintained</li>
</ul>
</p>
</div>
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
of Android devices, lets you filter the list to see only devices that interest you, and then view
@@ -61,7 +77,7 @@ a few git commands.
### Install Git
You can download and install Git from http://git-scm.com/download. Once installed you should have
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
@@ -73,7 +89,7 @@ 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=14 --branch=1.4-snapshot https://github.com/angular/angular-phonecat.git
```
This command creates the `angular-phonecat` directory in your current directory.
@@ -82,6 +98,11 @@ This command creates the `angular-phonecat` directory in your current directory.
download much smaller and faster.
</div>
<div class="alert alert-info">
The `--branch=1.4-snapshot` option tells Git to pull down the `1.4-snapshot` branch.
The code for this older version of the tutorial is on that branch.
</div>
Change your current directory to `angular-phonecat`.
```
@@ -123,7 +144,7 @@ npm --version
</a>.
</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
@@ -198,7 +219,7 @@ http://localhost:8000/app/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.
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.
</div>
+6 -4
View File
@@ -6,15 +6,17 @@
<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
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, 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 {@link index#get-started Get Started}.
In `angular-phonecat` directory, run this command:
In the `angular-phonecat` directory, run this command:
```
git checkout -f step-0
git checkout -f 1.4-step-0
```
+17 -4
View File
@@ -61,7 +61,7 @@ by the value 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:
* The expressions in curly braces (`{{phone.name}}` and `{{phone.snippet}}` denote
* 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.
@@ -132,6 +132,8 @@ The "Angular way" of separating controller from the view, makes it easy to test
developed. If our controller is available on the global namespace then we could simply instantiate it
with a mock `scope` object:
__`test/e2e/scenarios.js`:__
```js
describe('PhoneListCtrl', function(){
@@ -195,8 +197,19 @@ to ensure that Karma and its necessary plugins are installed. You can do this by
To run the tests, and then watch the files for changes: `npm test`.
* 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.
* 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 before running the test. Locate the configuration file
in `test/karma.conf.js`, then update the `browsers` property.
E.g. if you only have Chrome installed:
<pre>
...
browsers: ['Chrome'],
...
</pre>
* You should see the following or similar output in the terminal:
<pre>
@@ -250,7 +263,7 @@ browser is limited, which results in your karma tests running extremely slow.
<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`.
* Make the unit test fail by changing `expect(scope.phones.length).toBe(3)` to instead use `toBe(4)`.
+2 -2
View File
@@ -65,7 +65,7 @@ phonecatApp.controller('PhoneListCtrl', function ($scope, $http) {
`$http` makes an HTTP GET request to our web server, asking for `phones/phones.json` (the url is
relative to our `index.html` file). The server responds by providing the data in the json file.
(The response might just as well have been dynamically generated by a backend server. To the
browser and our app they both look the same. For the sake of simplicity we used a json file in this
browser and our app, they both look the same. For the sake of simplicity, we used a json file in this
tutorial.)
The `$http` service returns a {@link ng.$q promise object} with a `success`
@@ -114,7 +114,7 @@ as strings, which will not get minified. There are two ways to provide these inj
* Create a `$inject` property on the controller function which holds an array of strings.
Each string in the array is the name of the service to inject for the corresponding parameter.
In our example we would write:
In our example, we would write:
```js
function PhoneListCtrl($scope, $http) {...}
+4 -4
View File
@@ -43,7 +43,7 @@ __`app/index.html`:__
...
<ul class="phones">
<li ng-repeat="phone in phones | filter:query | orderBy:orderProp" class="thumbnail">
<a href="#/phones/{{phone.id}}" class="thumb"><img ng-src="{{phone.imageUrl}}"></a>
<a href="#/phones/{{phone.id}}" class="thumb"><img ng-src="{{phone.imageUrl}}" alt="{{phone.name}}"></a>
<a href="#/phones/{{phone.id}}">{{phone.name}}</a>
<p>{{phone.snippet}}</p>
</li>
@@ -59,8 +59,8 @@ the element attribute.
We also added phone images next to each record using an image tag with the {@link
ng.directive:ngSrc ngSrc} directive. That directive prevents the
browser from treating the Angular `{{ expression }}` markup literally, and initiating a request to
invalid URL `http://localhost:8000/app/{{phone.imageUrl}}`, which it would have done if we had only
specified an attribute binding in a regular `src` attribute (`<img src="{{phone.imageUrl}}">`).
an invalid URL `http://localhost:8000/app/{{phone.imageUrl}}`, which it would have done if we had
only specified an attribute binding in a regular `src` attribute (`<img src="{{phone.imageUrl}}">`).
Using the `ngSrc` directive prevents the browser from making an http request to an invalid location.
@@ -75,7 +75,7 @@ __`test/e2e/scenarios.js`__:
query.sendKeys('nexus');
element.all(by.css('.phones li a')).first().click();
browser.getLocationAbsUrl().then(function(url) {
expect(url.split('#')[1]).toBe('/phones/nexus-s');
expect(url).toBe('/phones/nexus-s');
});
});
...
+19 -7
View File
@@ -33,17 +33,17 @@ We are using [Bower][bower] to install client-side dependencies. This step upda
"license": "MIT",
"private": true,
"dependencies": {
"angular": "~1.3.0",
"angular-mocks": "~1.3.0",
"jquery": "2.1.1",
"angular": "1.4.x",
"angular-mocks": "1.4.x",
"jquery": "~2.1.1",
"bootstrap": "~3.1.1",
"angular-route": "~1.3.0"
"angular-route": "1.4.x"
}
}
```
The new dependency `"angular-route": "~1.3.0"` tells bower to install a version of the
angular-route component that is compatible with version 1.3.x. We must tell bower to download
The new dependency `"angular-route": "1.4.x"` tells bower to install a version of the
angular-route component that is compatible with version 1.4.x. We must tell bower to download
and install this dependency.
If you have bower installed globally, then you can run `bower install` but for this project, we have
@@ -53,6 +53,18 @@ preconfigured npm to run bower install for us:
npm install
```
<div class="alert alert-warning">
**Warning:** If a new version of Angular has been released since you last ran `npm install`, then you may have a
problem with the `bower install` due to a conflict between the versions of angular.js that need to
be installed. If you get this then simply delete your `app/bower_components` folder before running
`npm install`.
</div>
<div class="alert alert-info">
**Note:** If you have bower installed globally then you can run `bower install` but for this project we have
preconfigured `npm install` to run bower for us.
</div>
## Multiple Views, Routing and Layout Template
@@ -313,7 +325,7 @@ to various URLs and verify that the correct view was rendered.
it('should redirect index.html to index.html#/phones', function() {
browser.get('app/index.html');
browser.getLocationAbsUrl().then(function(url) {
expect(url.split('#')[1]).toBe('/phones');
expect(url).toEqual('/phones');
});
});
+2 -2
View File
@@ -12,8 +12,8 @@ phone in the phone list.
* When you click on a phone on the list, the phone details page with phone-specific information
is displayed.
To implement the phone details view we used {@link ng.$http $http} to fetch our data, and we
fleshed out the `phone-detail.html` view template.
To implement the phone details view we are going to use {@link ng.$http $http} to fetch our data,
and then flesh out the `phone-detail.html` view template.
<div doc-tutorial-reset="8"></div>
+7 -6
View File
@@ -32,17 +32,18 @@ We are using [Bower][bower] to install client side dependencies. This step upda
"license": "MIT",
"private": true,
"dependencies": {
"angular": "~1.3.0",
"angular-mocks": "~1.3.0",
"angular": "1.4.x",
"angular-mocks": "1.4.x",
"jquery": "~2.1.1",
"bootstrap": "~3.1.1",
"angular-route": "~1.3.0",
"angular-resource": "~1.3.0"
"angular-route": "1.4.x",
"angular-resource": "1.4.x"
}
}
```
The new dependency `"angular-resource": "~1.3.0"` tells bower to install a version of the
angular-resource component that is compatible with version 1.3.x. We must ask bower to download
The new dependency `"angular-resource": "1.4.x"` tells bower to install a version of the
angular-resource component that is compatible with version 1.4.x. We must ask bower to download
and install this dependency. We can do this by running:
```
+16 -16
View File
@@ -36,20 +36,20 @@ We are using [Bower][bower] to install client side dependencies. This step upda
"license": "MIT",
"private": true,
"dependencies": {
"angular": "~1.3.0",
"angular-mocks": "~1.3.0",
"bootstrap": "~3.1.1",
"angular-route": "~1.3.0",
"angular-resource": "~1.3.0",
"angular": "1.4.x",
"angular-mocks": "1.4.x",
"jquery": "~2.1.1",
"angular-animate": "~1.3.0"
"bootstrap": "~3.1.1",
"angular-route": "1.4.x",
"angular-resource": "1.4.x",
"angular-animate": "1.4.x"
}
}
```
* `"angular-animate": "~1.3.0"` tells bower to install a version of the
angular-animate component that is compatible with version 1.3.x.
* `"jquery": "2.1.1"` tells bower to install the 2.1.1 version of jQuery. Note that this is not an
* `"angular-animate": "1.4.x"` tells bower to install a version of the
angular-animate component that is compatible with version 1.4.x.
* `"jquery": "~2.1.1"` tells bower to install the 2.1.1 version of jQuery. Note that this is not an
Angular library, it is the standard jQuery library. We can use bower to install a wide range of 3rd
party libraries.
@@ -111,7 +111,7 @@ __`app/index.html`.__
```
<div class="alert alert-error">
**Important:** Be sure to use jQuery version 2.1 or newer when using Angular 1.3; jQuery 1.x is
**Important:** Be sure to use jQuery version 2.1 or newer when using Angular 1.4; jQuery 1.x is
not officially supported.
Be sure to load jQuery before all AngularJS scripts, otherwise AngularJS won't detect jQuery and
animations will not work as expected.
@@ -239,9 +239,9 @@ The name of the starting class is the name of the event that is fired (like `ent
The active class name is the same as the starting class's but with an `-active` suffix.
This two-class CSS naming convention allows the developer to craft an animation, beginning to end.
In our example above, elements expand from a height of **0** to **120 pixels** when items are added or moved,
around and collapsing the items before removing them from the list.
There's also a nice fade-in and fade-out effect that also occurs at the same time. All of this is handled
In our example above, elements are expanded from a height of **0** to **120 pixels** when they're added to the
list and are collapsed back down to **0 pixels** before being removed from the list.
There's also a nice fade-in and fade-out effect that occurs at the same time. All of this is handled
by the CSS transition declarations at the top of the example code above.
Although most modern browsers have good support for [CSS transitions](http://caniuse.com/#feat=css-transitions)
@@ -357,10 +357,10 @@ For more on CSS animations, see the
## Animating `ngClass` with JavaScript
Let's add another animation to our application. Switching to our `phone-detail.html` page,
we see that we have a nice thumbnail swapper. By clicking on the thumbnails listed on the page,
we see that we have a nice thumbnail swapper. By hovering over the thumbnails listed on the page,
the profile phone image changes. But how can we change this around to add animations?
Let's think about it first. Basically, when you click on a thumbnail image, you're changing the
Let's think about it first. Basically, when you hover over a thumbnail image, you're changing the
state of the profile image to reflect the newly selected thumbnail image.
The best way to specify state changes within HTML is to use classes.
Much like before, how we used a CSS class to specify an animation, this time the animation will
@@ -369,7 +369,7 @@ occur whenever the CSS class itself changes.
Whenever a new phone thumbnail is selected, the state changes and the `.active` CSS class is added
to the matching profile image and the animation plays.
Let's get started and tweak our HTML code on the `phone-detail.html` page first. Notice that we
Let's get started and tweak our HTML code on the `phone-detail.html` page first. Notice that we
have changed the way we display our large image:
__`app/partials/phone-detail.html`.__
+3 -2
View File
@@ -21,6 +21,7 @@ var outputFolder = '../build/docs';
var bowerFolder = 'bower_components';
var src = 'app/src/**/*.js';
var ignoredFiles = '!src/angular.bind.js';
var assets = 'app/assets/**/*';
@@ -50,7 +51,7 @@ gulp.task('build-app', function() {
var minFile = 'docs.min.js';
var folder = outputFolder + '/js/';
return gulp.src(src)
return gulp.src([src, ignoredFiles])
.pipe(sourcemaps.init())
.pipe(concat(file))
.pipe(gulp.dest(folder))
@@ -107,5 +108,5 @@ gulp.task('jshint', ['doc-gen'], function() {
gulp.task('default', ['assets', 'doc-gen', 'build-app', 'jshint']);
gulp.task('watch', function() {
gulp.watch([src, assets], ['assets', 'build-app']);
gulp.watch([src, ignoredFiles, assets], ['assets', 'build-app']);
});
Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 76 KiB

+1 -1
View File
@@ -173,7 +173,7 @@ function request(method, url, options, response) {
res.on('error', function (e) { console.log(e); });
break;
case 401:
console.log('Eror: Login credentials expired! Please login.');
console.log('Error: Login credentials expired! Please login.');
break;
default:
data = [];
+5 -2
View File
@@ -303,8 +303,8 @@ goog.i18n.currency.CurrencyInfo = {
'KRW': [0, '\u20A9', 'KR₩'],
'LKR': [2, 'Rs', 'SLRs'],
'LTL': [2, 'Lt', 'Lt'],
'LVL': [2, 'Ls', 'Ls'],
'MNT': [0, '\u20AE', 'MN₮'],
'MVR': [2, 'Rf', 'MVR'],
'MXN': [2, '$', 'Mex$'],
'MYR': [2, 'RM', 'RM'],
'NOK': [50, 'kr', 'NOkr'],
@@ -339,6 +339,7 @@ goog.i18n.currency.CurrencyInfo = {
goog.i18n.currency.CurrencyInfoTier2 = {
'AFN': [48, 'Af.', 'AFN'],
'AMD': [0, 'Dram', 'dram'],
'ANG': [2, 'NAf.', 'ANG'],
'AOA': [2, 'Kz', 'Kz'],
'ARS': [2, '$', 'AR$'],
'AWG': [2, 'Afl.', 'Afl.'],
@@ -414,6 +415,7 @@ goog.i18n.currency.CurrencyInfoTier2 = {
'SLL': [0, 'SLL', 'SLL'],
'SOS': [0, 'SOS', 'SOS'],
'SRD': [2, '$', 'SR$'],
'SSP': [2, '£', 'SSP'],
'STD': [0, 'Db', 'Db'],
'SYP': [0, '£', 'SY£'],
'SZL': [2, 'SZL', 'SZL'],
@@ -430,5 +432,6 @@ goog.i18n.currency.CurrencyInfoTier2 = {
'XCD': [2, '$', 'EC$'],
'XOF': [0, 'CFA', 'CFA'],
'XPF': [0, 'FCFP', 'FCFP'],
'ZMK': [0, 'ZMK', 'ZMK']
'ZMW': [0, 'ZMW', 'ZMW'],
'ZWD': [0, '$', 'Z$']
};
+305 -54
View File
@@ -17,7 +17,7 @@
*
* This file is autogenerated by script. See
* http://go/generate_datetime_constants.py using --for_closure
* File generated from CLDR ver. 26
* File generated from CLDR ver. 27.0.1
*
* To reduce the file size (which may cause issues in some JS
* developing environments), this file will only contain locales
@@ -36,9 +36,11 @@ goog.provide('goog.i18n.DateTimeSymbols_af');
goog.provide('goog.i18n.DateTimeSymbols_am');
goog.provide('goog.i18n.DateTimeSymbols_ar');
goog.provide('goog.i18n.DateTimeSymbols_az');
goog.provide('goog.i18n.DateTimeSymbols_be');
goog.provide('goog.i18n.DateTimeSymbols_bg');
goog.provide('goog.i18n.DateTimeSymbols_bn');
goog.provide('goog.i18n.DateTimeSymbols_br');
goog.provide('goog.i18n.DateTimeSymbols_bs');
goog.provide('goog.i18n.DateTimeSymbols_ca');
goog.provide('goog.i18n.DateTimeSymbols_chr');
goog.provide('goog.i18n.DateTimeSymbols_cs');
@@ -50,6 +52,7 @@ goog.provide('goog.i18n.DateTimeSymbols_de_CH');
goog.provide('goog.i18n.DateTimeSymbols_el');
goog.provide('goog.i18n.DateTimeSymbols_en');
goog.provide('goog.i18n.DateTimeSymbols_en_AU');
goog.provide('goog.i18n.DateTimeSymbols_en_CA');
goog.provide('goog.i18n.DateTimeSymbols_en_GB');
goog.provide('goog.i18n.DateTimeSymbols_en_IE');
goog.provide('goog.i18n.DateTimeSymbols_en_IN');
@@ -60,6 +63,8 @@ goog.provide('goog.i18n.DateTimeSymbols_en_ZA');
goog.provide('goog.i18n.DateTimeSymbols_es');
goog.provide('goog.i18n.DateTimeSymbols_es_419');
goog.provide('goog.i18n.DateTimeSymbols_es_ES');
goog.provide('goog.i18n.DateTimeSymbols_es_MX');
goog.provide('goog.i18n.DateTimeSymbols_es_US');
goog.provide('goog.i18n.DateTimeSymbols_et');
goog.provide('goog.i18n.DateTimeSymbols_eu');
goog.provide('goog.i18n.DateTimeSymbols_fa');
@@ -118,6 +123,7 @@ goog.provide('goog.i18n.DateTimeSymbols_sk');
goog.provide('goog.i18n.DateTimeSymbols_sl');
goog.provide('goog.i18n.DateTimeSymbols_sq');
goog.provide('goog.i18n.DateTimeSymbols_sr');
goog.provide('goog.i18n.DateTimeSymbols_sr_Latn');
goog.provide('goog.i18n.DateTimeSymbols_sv');
goog.provide('goog.i18n.DateTimeSymbols_sw');
goog.provide('goog.i18n.DateTimeSymbols_ta');
@@ -343,6 +349,52 @@ goog.i18n.DateTimeSymbols_az = {
};
/**
* Date/time formatting symbols for locale be.
*/
goog.i18n.DateTimeSymbols_be = {
ERAS: ['да н.э.', 'н.э.'],
ERANAMES: ['да н.э.', 'н.э.'],
NARROWMONTHS: ['с', 'л', 'с', 'к', 'м', 'ч', 'л', 'ж', 'в', 'к',
'л', 'с'],
STANDALONENARROWMONTHS: ['с', 'л', 'с', 'к', 'м', 'ч', 'л', 'ж', 'в',
'к', 'л', 'с'],
MONTHS: ['студзеня', 'лютага', 'сакавіка',
'красавіка', 'мая', 'чэрвеня', 'ліпеня',
'жніўня', 'верасня', 'кастрычніка',
'лістапада', 'снежня'],
STANDALONEMONTHS: ['студзень', 'люты', 'сакавік',
'красавік', 'май', 'чэрвень', 'ліпень',
'жнівень', 'верасень', 'кастрычнік',
'лістапад', 'снежань'],
SHORTMONTHS: ['сту', 'лют', 'сак', 'кра', 'мая', 'чэр',
'ліп', 'жні', 'вер', 'кас', 'ліс', 'сне'],
STANDALONESHORTMONTHS: ['сту', 'лют', 'сак', 'кра', 'май',
'чэр', 'ліп', 'жні', 'вер', 'кас', 'ліс', 'сне'],
WEEKDAYS: ['нядзеля', 'панядзелак', 'аўторак',
'серада', 'чацвер', 'пятніца', 'субота'],
STANDALONEWEEKDAYS: ['нядзеля', 'панядзелак',
'аўторак', 'серада', 'чацвер', 'пятніца',
'субота'],
SHORTWEEKDAYS: ['нд', 'пн', 'аў', 'ср', 'чц', 'пт', 'сб'],
STANDALONESHORTWEEKDAYS: ['нд', 'пн', 'аў', 'ср', 'чц', 'пт',
'сб'],
NARROWWEEKDAYS: ['н', 'п', 'а', 'с', 'ч', 'п', 'с'],
STANDALONENARROWWEEKDAYS: ['н', 'п', 'а', 'с', 'ч', 'п', 'с'],
SHORTQUARTERS: ['1-шы кв.', '2-гі кв.', '3-ці кв.',
'4-ты кв.'],
QUARTERS: ['1-шы квартал', '2-гі квартал',
'3-ці квартал', '4-ты квартал'],
AMPMS: ['да палудня', 'пасля палудня'],
DATEFORMATS: ['EEEE, d MMMM y', 'd MMMM y', 'd.M.y', 'd.M.yy'],
TIMEFORMATS: ['HH.mm.ss zzzz', 'HH.mm.ss z', 'HH.mm.ss', 'HH.mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 0,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 6
};
/**
* Date/time formatting symbols for locale bg.
*/
@@ -439,16 +491,10 @@ goog.i18n.DateTimeSymbols_bn = {
NARROWWEEKDAYS: ['র', 'সো', 'ম', 'বু', 'বৃ', 'শু', 'শ'],
STANDALONENARROWWEEKDAYS: ['র', 'সো', 'ম', 'বু', 'বৃ',
'শু', 'শ'],
SHORTQUARTERS: [
'প্র. ত্রৈ. এক. চতুর্থাংশ',
'দ্বি.ত্রৈ.এক. চতুর্থাংশ',
'তৃ.ত্রৈ.এক.চতুর্থাংশ',
'চ.ত্রৈ.এক চতুর্থাংশ'],
QUARTERS: [
'প্রথম ত্রৈমাসিকের এক চতুর্থাংশ',
'দ্বিতীয় ত্রৈমাসিকের এক চতুর্থাংশ',
'তৃতীয় ত্রৈমাসিকের এক চতুর্থাংশ',
'চতুর্থ ত্রৈমাসিকের এক চতুর্থাংশ'],
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['ত্রৈমাসিক', 'ষাণ্মাসিক',
'তৃতীয় চতুর্থাংশ',
'চতুর্থ ত্রৈমাসিক'],
AMPMS: ['am', 'pm'],
DATEFORMATS: ['EEEE, d MMMM, y', 'd MMMM, y', 'd MMM, y', 'd/M/yy'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
@@ -497,6 +543,44 @@ goog.i18n.DateTimeSymbols_br = {
};
/**
* Date/time formatting symbols for locale bs.
*/
goog.i18n.DateTimeSymbols_bs = {
ERAS: ['p. n. e.', 'n. e.'],
ERANAMES: ['Prije nove ere', 'Nove ere'],
NARROWMONTHS: ['j', 'f', 'm', 'a', 'm', 'j', 'j', 'a', 's', 'o', 'n', 'd'],
STANDALONENARROWMONTHS: ['j', 'f', 'm', 'a', 'm', 'j', 'j', 'a', 's', 'o',
'n', 'd'],
MONTHS: ['januar', 'februar', 'mart', 'april', 'maj', 'juni', 'juli',
'august', 'septembar', 'oktobar', 'novembar', 'decembar'],
STANDALONEMONTHS: ['januar', 'februar', 'mart', 'april', 'maj', 'juni',
'juli', 'august', 'septembar', 'oktobar', 'novembar', 'decembar'],
SHORTMONTHS: ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep',
'okt', 'nov', 'dec'],
STANDALONESHORTMONTHS: ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul',
'aug', 'sep', 'okt', 'nov', 'dec'],
WEEKDAYS: ['nedjelja', 'ponedjeljak', 'utorak', 'srijeda', 'četvrtak',
'petak', 'subota'],
STANDALONEWEEKDAYS: ['nedjelja', 'ponedjeljak', 'utorak', 'srijeda',
'četvrtak', 'petak', 'subota'],
SHORTWEEKDAYS: ['ned', 'pon', 'uto', 'sri', 'čet', 'pet', 'sub'],
STANDALONESHORTWEEKDAYS: ['ned', 'pon', 'uto', 'sri', 'čet', 'pet', 'sub'],
NARROWWEEKDAYS: ['N', 'P', 'U', 'S', 'Č', 'P', 'S'],
STANDALONENARROWWEEKDAYS: ['n', 'p', 'u', 's', 'č', 'p', 's'],
SHORTQUARTERS: ['K1', 'K2', 'K3', 'K4'],
QUARTERS: ['Prvi kvartal', 'Drugi kvartal', 'Treći kvartal',
'Četvrti kvartal'],
AMPMS: ['prije podne', 'popodne'],
DATEFORMATS: ['EEEE, dd. MMMM y.', 'dd. MMMM y.', 'dd. MMM. y.', 'dd.MM.yy.'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
DATETIMEFORMATS: ['{1} \'u\' {0}', '{1} \'u\' {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 0,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 6
};
/**
* Date/time formatting symbols for locale ca.
*/
@@ -507,8 +591,9 @@ goog.i18n.DateTimeSymbols_ca = {
'NV', 'DS'],
STANDALONENARROWMONTHS: ['GN', 'FB', 'MÇ', 'AB', 'MG', 'JN', 'JL', 'AG',
'ST', 'OC', 'NV', 'DS'],
MONTHS: ['gener', 'febrer', 'març', 'abril', 'maig', 'juny', 'juliol',
'agost', 'setembre', 'octubre', 'novembre', 'desembre'],
MONTHS: ['de gener', 'de febrer', 'de març', 'dabril', 'de maig',
'de juny', 'de juliol', 'dagost', 'de setembre', 'doctubre',
'de novembre', 'de desembre'],
STANDALONEMONTHS: ['gener', 'febrer', 'març', 'abril', 'maig', 'juny',
'juliol', 'agost', 'setembre', 'octubre', 'novembre', 'desembre'],
SHORTMONTHS: ['gen.', 'febr.', 'març', 'abr.', 'maig', 'juny', 'jul.', 'ag.',
@@ -609,7 +694,7 @@ goog.i18n.DateTimeSymbols_cs = {
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['1. čtvrtletí', '2. čtvrtletí', '3. čtvrtletí',
'4. čtvrtletí'],
AMPMS: ['AM', 'PM'],
AMPMS: ['dopoledne', 'odpoledne'],
DATEFORMATS: ['EEEE d. MMMM y', 'd. MMMM y', 'd. M. y', 'dd.MM.yy'],
TIMEFORMATS: ['H:mm:ss zzzz', 'H:mm:ss z', 'H:mm:ss', 'H:mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
@@ -684,7 +769,7 @@ goog.i18n.DateTimeSymbols_da = {
SHORTQUARTERS: ['1. kvt.', '2. kvt.', '3. kvt.', '4. kvt.'],
QUARTERS: ['1. kvartal', '2. kvartal', '3. kvartal', '4. kvartal'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE \'den\' d. MMMM y', 'd. MMMM y', 'dd/MM/y', 'dd/MM/yy'],
DATEFORMATS: ['EEEE \'den\' d. MMMM y', 'd. MMMM y', 'd. MMM y', 'dd/MM/y'],
TIMEFORMATS: ['HH.mm.ss zzzz', 'HH.mm.ss z', 'HH.mm.ss', 'HH.mm'],
DATETIMEFORMATS: ['{1} \'kl.\' {0}', '{1} \'kl.\' {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 0,
@@ -758,7 +843,7 @@ goog.i18n.DateTimeSymbols_de_AT = {
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['1. Quartal', '2. Quartal', '3. Quartal', '4. Quartal'],
AMPMS: ['vorm.', 'nachm.'],
DATEFORMATS: ['EEEE, dd. MMMM y', 'dd. MMMM y', 'dd. MMM y', 'dd.MM.yy'],
DATEFORMATS: ['EEEE, d. MMMM y', 'd. MMMM y', 'dd.MM.y', 'dd.MM.yy'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
DATETIMEFORMATS: ['{1} \'um\' {0}', '{1} \'um\' {0}', '{1}, {0}', '{1}, {0}'],
FIRSTDAYOFWEEK: 0,
@@ -882,10 +967,47 @@ goog.i18n.DateTimeSymbols_en_AU = {
STANDALONENARROWWEEKDAYS: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'],
AMPMS: ['am', 'pm'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE, d MMMM y', 'd MMMM y', 'd MMM y', 'd/MM/y'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
DATETIMEFORMATS: ['{1} \'at\' {0}', '{1} \'at\' {0}', '{1}, {0}', '{1}, {0}'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 5
};
/**
* Date/time formatting symbols for locale en_CA.
*/
goog.i18n.DateTimeSymbols_en_CA = {
ERAS: ['BC', 'AD'],
ERANAMES: ['Before Christ', 'Anno Domini'],
NARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
STANDALONENARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',
'N', 'D'],
MONTHS: ['January', 'February', 'March', 'April', 'May', 'June', 'July',
'August', 'September', 'October', 'November', 'December'],
STANDALONEMONTHS: ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'],
SHORTMONTHS: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'],
STANDALONESHORTMONTHS: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
WEEKDAYS: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
'Saturday'],
STANDALONEWEEKDAYS: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday'],
SHORTWEEKDAYS: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
STANDALONESHORTWEEKDAYS: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
NARROWWEEKDAYS: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
STANDALONENARROWWEEKDAYS: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE, MMMM d, y', 'MMMM d, y', 'MMM d, y', 'y-MM-dd'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1} \'at\' {0}', '{1} \'at\' {0}', '{1}, {0}', '{1}, {0}'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 5
@@ -919,7 +1041,7 @@ goog.i18n.DateTimeSymbols_en_GB = {
STANDALONENARROWWEEKDAYS: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'],
AMPMS: ['am', 'pm'],
AMPMS: ['a.m.', 'p.m.'],
DATEFORMATS: ['EEEE, d MMMM y', 'd MMMM y', 'd MMM y', 'dd/MM/y'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
DATETIMEFORMATS: ['{1} \'at\' {0}', '{1} \'at\' {0}', '{1}, {0}', '{1}, {0}'],
@@ -958,7 +1080,7 @@ goog.i18n.DateTimeSymbols_en_IE = {
QUARTERS: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'],
AMPMS: ['a.m.', 'p.m.'],
DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'd MMM y', 'dd/MM/y'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1} \'at\' {0}', '{1} \'at\' {0}', '{1}, {0}', '{1}, {0}'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
@@ -993,7 +1115,7 @@ goog.i18n.DateTimeSymbols_en_IN = {
STANDALONENARROWWEEKDAYS: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'],
AMPMS: ['am', 'pm'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'dd-MMM-y', 'dd/MM/yy'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1} \'at\' {0}', '{1} \'at\' {0}', '{1}, {0}', '{1}, {0}'],
@@ -1030,7 +1152,7 @@ goog.i18n.DateTimeSymbols_en_SG = {
STANDALONENARROWWEEKDAYS: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'],
AMPMS: ['am', 'pm'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE, d MMMM y', 'd MMMM y', 'd MMM y', 'd/M/yy'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1} \'at\' {0}', '{1} \'at\' {0}', '{1}, {0}', '{1}, {0}'],
@@ -1074,7 +1196,7 @@ goog.i18n.DateTimeSymbols_en_ZA = {
SHORTQUARTERS: ['Q1', 'Q2', 'Q3', 'Q4'],
QUARTERS: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE dd MMMM y', 'dd MMMM y', 'dd MMM y', 'y/MM/dd'],
DATEFORMATS: ['EEEE, dd MMMM y', 'dd MMMM y', 'dd MMM y', 'y/MM/dd'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1} \'at\' {0}', '{1} \'at\' {0}', '{1}, {0}', '{1}, {0}'],
FIRSTDAYOFWEEK: 6,
@@ -1088,7 +1210,7 @@ goog.i18n.DateTimeSymbols_en_ZA = {
*/
goog.i18n.DateTimeSymbols_es = {
ERAS: ['a. C.', 'd. C.'],
ERANAMES: ['antes de Cristo', 'anno Dómini'],
ERANAMES: ['antes de Cristo', 'después de Cristo'],
NARROWMONTHS: ['E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
STANDALONENARROWMONTHS: ['E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',
'N', 'D'],
@@ -1114,7 +1236,7 @@ goog.i18n.DateTimeSymbols_es = {
'4.º trimestre'],
AMPMS: ['a. m.', 'p. m.'],
DATEFORMATS: ['EEEE, d \'de\' MMMM \'de\' y', 'd \'de\' MMMM \'de\' y',
'd \'de\' MMM \'de\' y', 'd/M/yy'],
'd MMM y', 'd/M/yy'],
TIMEFORMATS: ['H:mm:ss (zzzz)', 'H:mm:ss z', 'H:mm:ss', 'H:mm'],
DATETIMEFORMATS: ['{1}, {0}', '{1}, {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 0,
@@ -1129,17 +1251,17 @@ goog.i18n.DateTimeSymbols_es = {
goog.i18n.DateTimeSymbols_es_419 = {
ERAS: ['a. C.', 'd. C.'],
ERANAMES: ['antes de Cristo', 'después de Cristo'],
NARROWMONTHS: ['e', 'f', 'm', 'a', 'm', 'j', 'j', 'a', 's', 'o', 'n', 'd'],
NARROWMONTHS: ['E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
STANDALONENARROWMONTHS: ['E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',
'N', 'D'],
MONTHS: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio',
'agosto', 'setiembre', 'octubre', 'noviembre', 'diciembre'],
'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
STANDALONEMONTHS: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
'Julio', 'Agosto', 'Setiembre', 'Octubre', 'Noviembre', 'Diciembre'],
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
SHORTMONTHS: ['ene.', 'feb.', 'mar.', 'abr.', 'may.', 'jun.', 'jul.', 'ago.',
'set.', 'oct.', 'nov.', 'dic.'],
'sept.', 'oct.', 'nov.', 'dic.'],
STANDALONESHORTMONTHS: ['Ene.', 'Feb.', 'Mar.', 'Abr.', 'May.', 'Jun.',
'Jul.', 'Ago.', 'Set.', 'Oct.', 'Nov.', 'Dic.'],
'Jul.', 'Ago.', 'Sept.', 'Oct.', 'Nov.', 'Dic.'],
WEEKDAYS: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes',
'sábado'],
STANDALONEWEEKDAYS: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves',
@@ -1149,12 +1271,12 @@ goog.i18n.DateTimeSymbols_es_419 = {
'Sáb.'],
NARROWWEEKDAYS: ['d', 'l', 'm', 'm', 'j', 'v', 's'],
STANDALONENARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
SHORTQUARTERS: ['1.er trim.', '2.º trim.', '3.er trim.', '4.º trim.'],
SHORTQUARTERS: ['T1', 'T2', 'T3', 'T4'],
QUARTERS: ['1.er trimestre', '2.º trimestre', '3.er trimestre',
'4.º trimestre'],
AMPMS: ['a. m.', 'p. m.'],
AMPMS: ['a. m.', 'p. m.'],
DATEFORMATS: ['EEEE, d \'de\' MMMM \'de\' y', 'd \'de\' MMMM \'de\' y',
'd \'de\' MMM \'de\' y', 'd/M/yy'],
'd MMM y', 'd/M/yy'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1}, {0}', '{1}, {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 0,
@@ -1169,6 +1291,86 @@ goog.i18n.DateTimeSymbols_es_419 = {
goog.i18n.DateTimeSymbols_es_ES = goog.i18n.DateTimeSymbols_es;
/**
* Date/time formatting symbols for locale es_MX.
*/
goog.i18n.DateTimeSymbols_es_MX = {
ERAS: ['a. C.', 'd. C.'],
ERANAMES: ['antes de Cristo', 'después de Cristo'],
NARROWMONTHS: ['E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
STANDALONENARROWMONTHS: ['E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',
'N', 'D'],
MONTHS: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio',
'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
STANDALONEMONTHS: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
SHORTMONTHS: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep',
'oct', 'nov', 'dic'],
STANDALONESHORTMONTHS: ['Ene.', 'Feb.', 'Mar.', 'Abr.', 'May.', 'Jun.',
'Jul.', 'Ago.', 'Sept.', 'Oct.', 'Nov.', 'Dic.'],
WEEKDAYS: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes',
'sábado'],
STANDALONEWEEKDAYS: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves',
'Viernes', 'Sábado'],
SHORTWEEKDAYS: ['dom.', 'lun.', 'mar.', 'mié.', 'jue.', 'vie.', 'sáb.'],
STANDALONESHORTWEEKDAYS: ['Dom.', 'Lun.', 'Mar.', 'Mié.', 'Jue.', 'Vie.',
'Sáb.'],
NARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
STANDALONENARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
SHORTQUARTERS: ['1er. trim.', '2º. trim.', '3er. trim.', '4º trim.'],
QUARTERS: ['1er. trimestre', '2º. trimestre', '3er. trimestre',
'4º trimestre'],
AMPMS: ['a.m.', 'p.m.'],
DATEFORMATS: ['EEEE, d \'de\' MMMM \'de\' y', 'd \'de\' MMMM \'de\' y',
'dd/MM/y', 'dd/MM/yy'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1}, {0}', '{1}, {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 5
};
/**
* Date/time formatting symbols for locale es_US.
*/
goog.i18n.DateTimeSymbols_es_US = {
ERAS: ['a. C.', 'd. C.'],
ERANAMES: ['antes de Cristo', 'después de Cristo'],
NARROWMONTHS: ['E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
STANDALONENARROWMONTHS: ['E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',
'N', 'D'],
MONTHS: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio',
'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
STANDALONEMONTHS: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
SHORTMONTHS: ['ene.', 'feb.', 'mar.', 'abr.', 'may.', 'jun.', 'jul.', 'ago.',
'sept.', 'oct.', 'nov.', 'dic.'],
STANDALONESHORTMONTHS: ['Ene.', 'Feb.', 'Mar.', 'Abr.', 'May.', 'Jun.',
'Jul.', 'Ago.', 'Sept.', 'Oct.', 'Nov.', 'Dic.'],
WEEKDAYS: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes',
'sábado'],
STANDALONEWEEKDAYS: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves',
'Viernes', 'Sábado'],
SHORTWEEKDAYS: ['dom.', 'lun.', 'mar.', 'mié.', 'jue.', 'vie.', 'sáb.'],
STANDALONESHORTWEEKDAYS: ['Dom.', 'Lun.', 'Mar.', 'Mié.', 'Jue.', 'Vie.',
'Sáb.'],
NARROWWEEKDAYS: ['d', 'l', 'm', 'm', 'j', 'v', 's'],
STANDALONENARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
SHORTQUARTERS: ['T1', 'T2', 'T3', 'T4'],
QUARTERS: ['1.er trimestre', '2.º trimestre', '3.er trimestre',
'4.º trimestre'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE, d \'de\' MMMM \'de\' y', 'd \'de\' MMMM \'de\' y',
'd MMM y', 'd/M/yy'],
TIMEFORMATS: ['h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a', 'h:mm a'],
DATETIMEFORMATS: ['{1}, {0}', '{1}, {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 5
};
/**
* Date/time formatting symbols for locale et.
*/
@@ -1327,7 +1529,8 @@ goog.i18n.DateTimeSymbols_fi = {
AMPMS: ['ap.', 'ip.'],
DATEFORMATS: ['cccc d. MMMM y', 'd. MMMM y', 'd.M.y', 'd.M.y'],
TIMEFORMATS: ['H.mm.ss zzzz', 'H.mm.ss z', 'H.mm.ss', 'H.mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
DATETIMEFORMATS: ['{1} \'klo\' {0}', '{1} \'klo\' {0}', '{1} \'klo\' {0}',
'{1} {0}'],
FIRSTDAYOFWEEK: 0,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 3
@@ -1440,10 +1643,9 @@ goog.i18n.DateTimeSymbols_fr_CA = {
SHORTQUARTERS: ['T1', 'T2', 'T3', 'T4'],
QUARTERS: ['1er trimestre', '2e trimestre', '3e trimestre', '4e trimestre'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'y-MM-dd', 'yy-MM-dd'],
TIMEFORMATS: ['HH \'h\' mm \'min\' ss \'s\' zzzz', 'HH:mm:ss z', 'HH:mm:ss',
'HH:mm'],
DATETIMEFORMATS: ['{1} \'à\' {0}', '{1} \'à\' {0}', '{1} {0}', '{1} {0}'],
DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'd MMM y', 'yy-MM-dd'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 5
@@ -1697,7 +1899,7 @@ goog.i18n.DateTimeSymbols_he = {
QUARTERS: ['רבעון 1', 'רבעון 2', 'רבעון 3', 'רבעון 4'],
AMPMS: ['לפנה״צ', 'אחה״צ'],
DATEFORMATS: ['EEEE, d בMMMM y', 'd בMMMM y', 'd בMMM y', 'd.M.y'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
TIMEFORMATS: ['H:mm:ss zzzz', 'H:mm:ss z', 'H:mm:ss', 'H:mm'],
DATETIMEFORMATS: ['{1} בשעה {0}', '{1} בשעה {0}', '{1}, {0}',
'{1}, {0}'],
FIRSTDAYOFWEEK: 6,
@@ -2073,7 +2275,7 @@ goog.i18n.DateTimeSymbols_iw = {
QUARTERS: ['רבעון 1', 'רבעון 2', 'רבעון 3', 'רבעון 4'],
AMPMS: ['לפנה״צ', 'אחה״צ'],
DATEFORMATS: ['EEEE, d בMMMM y', 'd בMMMM y', 'd בMMM y', 'd.M.y'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
TIMEFORMATS: ['H:mm:ss zzzz', 'H:mm:ss z', 'H:mm:ss', 'H:mm'],
DATETIMEFORMATS: ['{1} בשעה {0}', '{1} בשעה {0}', '{1}, {0}',
'{1}, {0}'],
FIRSTDAYOFWEEK: 6,
@@ -2941,7 +3143,7 @@ goog.i18n.DateTimeSymbols_my = {
'တတိယ သုံးလပတ်',
'စတုတ္ထ သုံးလပတ်'],
AMPMS: ['နံနက်', 'ညနေ'],
DATEFORMATS: ['EEEE, dd MMMM y', 'd MMMM y', 'd MMM y', 'dd-MM-yy'],
DATEFORMATS: ['EEEE dd MMMM y', 'd MMMM y', 'd MMM y', 'dd-MM-yy'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
DATETIMEFORMATS: ['{1}မှာ {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 6,
@@ -2999,7 +3201,7 @@ goog.i18n.DateTimeSymbols_ne = {
STANDALONENARROWMONTHS: ['१', '२', '३', '४', '५', '६', '७',
'८', '९', '१०', '११', '१२'],
MONTHS: ['जनवरी', 'फेब्रुअरी', 'मार्च',
'अप्रिल', 'म', 'जुन', 'जुलाई',
'अप्रिल', 'म', 'जुन', 'जुलाई',
'अगस्ट', 'सेप्टेम्बर',
'अक्टोबर', 'नोभेम्बर',
'डिसेम्बर'],
@@ -3019,10 +3221,10 @@ goog.i18n.DateTimeSymbols_ne = {
'अक्टोबर', 'नोभेम्बर',
'डिसेम्बर'],
WEEKDAYS: ['आइतबार', 'सोमबार',
'मङ्गलबार', 'बुधबार', 'बिहबार',
'मङ्गलबार', 'बुधबार', 'बिहिबार',
'शुक्रबार', 'शनिबार'],
STANDALONEWEEKDAYS: ['आइतबार', 'सोमबार',
'मङ्गलबार', 'बुधबार', 'बिहबार',
'मङ्गलबार', 'बुधबार', 'बिहिबार',
'शुक्रबार', 'शनिबार'],
SHORTWEEKDAYS: ['आइत', 'सोम', 'मङ्गल', 'बुध',
'बिही', 'शुक्र', 'शनि'],
@@ -3036,8 +3238,7 @@ goog.i18n.DateTimeSymbols_ne = {
'चौथो सत्र'],
QUARTERS: ['पहिलो सत्र', 'दोस्रो सत्र',
'तेस्रो सत्र', 'चौथो सत्र'],
AMPMS: ['पूर्व मध्यान्ह',
'उत्तर मध्यान्ह'],
AMPMS: ['पूर्वाह्न', 'अपराह्न'],
DATEFORMATS: ['y MMMM d, EEEE', 'y MMMM d', 'y MMM d', 'y-MM-dd'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1}, {0}', '{1}, {0}'],
@@ -3265,7 +3466,7 @@ goog.i18n.DateTimeSymbols_pl = {
SHORTQUARTERS: ['K1', 'K2', 'K3', 'K4'],
QUARTERS: ['I kwartał', 'II kwartał', 'III kwartał', 'IV kwartał'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE, d MMMM y', 'd MMMM y', 'd MMM y', 'dd.MM.y'],
DATEFORMATS: ['EEEE, d MMMM y', 'd MMMM y', 'dd.MM.y', 'dd.MM.y'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1}, {0}', '{1}, {0}'],
FIRSTDAYOFWEEK: 0,
@@ -3330,12 +3531,12 @@ goog.i18n.DateTimeSymbols_pt_PT = {
'N', 'D'],
MONTHS: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho',
'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
STANDALONEMONTHS: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
STANDALONEMONTHS: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho',
'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
SHORTMONTHS: ['jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set',
'out', 'nov', 'dez'],
STANDALONESHORTMONTHS: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul',
'Ago', 'Set', 'Out', 'Nov', 'Dez'],
STANDALONESHORTMONTHS: ['jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul',
'ago', 'set', 'out', 'nov', 'dez'],
WEEKDAYS: ['domingo', 'segunda-feira', 'terça-feira', 'quarta-feira',
'quinta-feira', 'sexta-feira', 'sábado'],
STANDALONEWEEKDAYS: ['domingo', 'segunda-feira', 'terça-feira',
@@ -3570,7 +3771,7 @@ goog.i18n.DateTimeSymbols_sl = {
'4. četrtletje'],
AMPMS: ['dop.', 'pop.'],
DATEFORMATS: ['EEEE, dd. MMMM y', 'dd. MMMM y', 'd. MMM y', 'd. MM. yy'],
TIMEFORMATS: ['HH.mm.ss zzzz', 'HH.mm.ss z', 'HH.mm.ss', 'HH.mm'],
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 0,
WEEKENDRANGE: [5, 6],
@@ -3661,6 +3862,44 @@ goog.i18n.DateTimeSymbols_sr = {
};
/**
* Date/time formatting symbols for locale sr_Latn.
*/
goog.i18n.DateTimeSymbols_sr_Latn = {
ERAS: ['p. n. e.', 'n. e.'],
ERANAMES: ['Pre nove ere', 'Nove ere'],
NARROWMONTHS: ['j', 'f', 'm', 'a', 'm', 'j', 'j', 'a', 's', 'o', 'n', 'd'],
STANDALONENARROWMONTHS: ['j', 'f', 'm', 'a', 'm', 'j', 'j', 'a', 's', 'o',
'n', 'd'],
MONTHS: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust',
'septembar', 'oktobar', 'novembar', 'decembar'],
STANDALONEMONTHS: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul',
'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],
SHORTMONTHS: ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'avg', 'sep',
'okt', 'nov', 'dec'],
STANDALONESHORTMONTHS: ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul',
'avg', 'sep', 'okt', 'nov', 'dec'],
WEEKDAYS: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak',
'subota'],
STANDALONEWEEKDAYS: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak',
'petak', 'subota'],
SHORTWEEKDAYS: ['ned', 'pon', 'uto', 'sre', 'čet', 'pet', 'sub'],
STANDALONESHORTWEEKDAYS: ['ned', 'pon', 'uto', 'sre', 'čet', 'pet', 'sub'],
NARROWWEEKDAYS: ['n', 'p', 'u', 's', 'č', 'p', 's'],
STANDALONENARROWWEEKDAYS: ['n', 'p', 'u', 's', 'č', 'p', 's'],
SHORTQUARTERS: ['K1', 'K2', 'K3', 'K4'],
QUARTERS: ['Prvo tromesečje', 'Drugo tromesečje', 'Treće tromesečje',
'Četvrto tromesečje'],
AMPMS: ['pre podne', 'po podne'],
DATEFORMATS: ['EEEE, dd. MMMM y.', 'dd. MMMM y.', 'dd.MM.y.', 'd.M.yy.'],
TIMEFORMATS: ['HH.mm.ss zzzz', 'HH.mm.ss z', 'HH.mm.ss', 'HH.mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 0,
WEEKENDRANGE: [5, 6],
FIRSTWEEKCUTOFFDAY: 6
};
/**
* Date/time formatting symbols for locale sv.
*/
@@ -3726,7 +3965,7 @@ goog.i18n.DateTimeSymbols_sw = {
'Alhamisi', 'Ijumaa', 'Jumamosi'],
NARROWWEEKDAYS: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
STANDALONENARROWWEEKDAYS: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
SHORTQUARTERS: ['Robo ya 1', 'Robo ya 2', 'Robo ya 3', 'Robo ya 4'],
SHORTQUARTERS: ['R1', 'R2', 'R3', 'R4'],
QUARTERS: ['Robo ya 1', 'Robo ya 2', 'Robo ya 3', 'Robo ya 4'],
AMPMS: ['AM', 'PM'],
DATEFORMATS: ['EEEE, d MMMM y', 'd MMMM y', 'd MMM y', 'dd/MM/y'],
@@ -4189,7 +4428,7 @@ goog.i18n.DateTimeSymbols_zh = {
QUARTERS: ['第一季度', '第二季度', '第三季度', '第四季度'],
AMPMS: ['上午', '下午'],
DATEFORMATS: ['y年M月d日EEEE', 'y年M月d日', 'y年M月d日', 'yy/M/d'],
TIMEFORMATS: ['zzzzah:mm:ss', 'zah:mm:ss', 'ah:mm:ss', 'ah:mm'],
TIMEFORMATS: ['zzzz ah:mm:ss', 'z ah:mm:ss', 'ah:mm:ss', 'ah:mm'],
DATETIMEFORMATS: ['{1} {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
@@ -4330,12 +4569,16 @@ if (goog.LOCALE == 'af') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_ar;
} else if (goog.LOCALE == 'az') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_az;
} else if (goog.LOCALE == 'be') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_be;
} else if (goog.LOCALE == 'bg') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_bg;
} else if (goog.LOCALE == 'bn') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_bn;
} else if (goog.LOCALE == 'br') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_br;
} else if (goog.LOCALE == 'bs') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_bs;
} else if (goog.LOCALE == 'ca') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_ca;
} else if (goog.LOCALE == 'chr') {
@@ -4358,6 +4601,8 @@ if (goog.LOCALE == 'af') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_en;
} else if (goog.LOCALE == 'en_AU' || goog.LOCALE == 'en-AU') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_en_AU;
} else if (goog.LOCALE == 'en_CA' || goog.LOCALE == 'en-CA') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_en_CA;
} else if (goog.LOCALE == 'en_GB' || goog.LOCALE == 'en-GB') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_en_GB;
} else if (goog.LOCALE == 'en_IE' || goog.LOCALE == 'en-IE') {
@@ -4376,6 +4621,10 @@ if (goog.LOCALE == 'af') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_es_419;
} else if (goog.LOCALE == 'es_ES' || goog.LOCALE == 'es-ES') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_es;
} else if (goog.LOCALE == 'es_MX' || goog.LOCALE == 'es-MX') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_es_MX;
} else if (goog.LOCALE == 'es_US' || goog.LOCALE == 'es-US') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_es_US;
} else if (goog.LOCALE == 'et') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_et;
} else if (goog.LOCALE == 'eu') {
@@ -4492,6 +4741,8 @@ if (goog.LOCALE == 'af') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_sq;
} else if (goog.LOCALE == 'sr') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_sr;
} else if (goog.LOCALE == 'sr_Latn' || goog.LOCALE == 'sr-Latn') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_sr_Latn;
} else if (goog.LOCALE == 'sv') {
goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_sv;
} else if (goog.LOCALE == 'sw') {
File diff suppressed because it is too large Load Diff
+351 -2
View File
@@ -18,7 +18,7 @@
* This file is autogenerated by script:
* http://go/generate_number_constants.py
* using the --for_closure flag.
* File generated from CLDR ver. 26
* File generated from CLDR ver. 27.0.1
*
* To reduce the file size (which may cause issues in some JS
* developing environments), this file will only contain locales
@@ -41,14 +41,21 @@ goog.provide('goog.i18n.NumberFormatSymbols_am');
goog.provide('goog.i18n.NumberFormatSymbols_am_ET');
goog.provide('goog.i18n.NumberFormatSymbols_ar');
goog.provide('goog.i18n.NumberFormatSymbols_ar_001');
goog.provide('goog.i18n.NumberFormatSymbols_ar_EG');
goog.provide('goog.i18n.NumberFormatSymbols_az');
goog.provide('goog.i18n.NumberFormatSymbols_az_Latn');
goog.provide('goog.i18n.NumberFormatSymbols_az_Latn_AZ');
goog.provide('goog.i18n.NumberFormatSymbols_be');
goog.provide('goog.i18n.NumberFormatSymbols_be_BY');
goog.provide('goog.i18n.NumberFormatSymbols_bg');
goog.provide('goog.i18n.NumberFormatSymbols_bg_BG');
goog.provide('goog.i18n.NumberFormatSymbols_bn');
goog.provide('goog.i18n.NumberFormatSymbols_bn_BD');
goog.provide('goog.i18n.NumberFormatSymbols_br');
goog.provide('goog.i18n.NumberFormatSymbols_br_FR');
goog.provide('goog.i18n.NumberFormatSymbols_bs');
goog.provide('goog.i18n.NumberFormatSymbols_bs_Latn');
goog.provide('goog.i18n.NumberFormatSymbols_bs_Latn_BA');
goog.provide('goog.i18n.NumberFormatSymbols_ca');
goog.provide('goog.i18n.NumberFormatSymbols_ca_AD');
goog.provide('goog.i18n.NumberFormatSymbols_ca_ES');
@@ -71,11 +78,13 @@ goog.provide('goog.i18n.NumberFormatSymbols_de_CH');
goog.provide('goog.i18n.NumberFormatSymbols_de_DE');
goog.provide('goog.i18n.NumberFormatSymbols_de_LU');
goog.provide('goog.i18n.NumberFormatSymbols_el');
goog.provide('goog.i18n.NumberFormatSymbols_el_CY');
goog.provide('goog.i18n.NumberFormatSymbols_el_GR');
goog.provide('goog.i18n.NumberFormatSymbols_en');
goog.provide('goog.i18n.NumberFormatSymbols_en_001');
goog.provide('goog.i18n.NumberFormatSymbols_en_AS');
goog.provide('goog.i18n.NumberFormatSymbols_en_AU');
goog.provide('goog.i18n.NumberFormatSymbols_en_CA');
goog.provide('goog.i18n.NumberFormatSymbols_en_DG');
goog.provide('goog.i18n.NumberFormatSymbols_en_FM');
goog.provide('goog.i18n.NumberFormatSymbols_en_GB');
@@ -100,6 +109,8 @@ goog.provide('goog.i18n.NumberFormatSymbols_es_419');
goog.provide('goog.i18n.NumberFormatSymbols_es_EA');
goog.provide('goog.i18n.NumberFormatSymbols_es_ES');
goog.provide('goog.i18n.NumberFormatSymbols_es_IC');
goog.provide('goog.i18n.NumberFormatSymbols_es_MX');
goog.provide('goog.i18n.NumberFormatSymbols_es_US');
goog.provide('goog.i18n.NumberFormatSymbols_et');
goog.provide('goog.i18n.NumberFormatSymbols_et_EE');
goog.provide('goog.i18n.NumberFormatSymbols_eu');
@@ -157,6 +168,7 @@ goog.provide('goog.i18n.NumberFormatSymbols_ja_JP');
goog.provide('goog.i18n.NumberFormatSymbols_ka');
goog.provide('goog.i18n.NumberFormatSymbols_ka_GE');
goog.provide('goog.i18n.NumberFormatSymbols_kk');
goog.provide('goog.i18n.NumberFormatSymbols_kk_Cyrl');
goog.provide('goog.i18n.NumberFormatSymbols_kk_Cyrl_KZ');
goog.provide('goog.i18n.NumberFormatSymbols_km');
goog.provide('goog.i18n.NumberFormatSymbols_km_KH');
@@ -165,6 +177,7 @@ goog.provide('goog.i18n.NumberFormatSymbols_kn_IN');
goog.provide('goog.i18n.NumberFormatSymbols_ko');
goog.provide('goog.i18n.NumberFormatSymbols_ko_KR');
goog.provide('goog.i18n.NumberFormatSymbols_ky');
goog.provide('goog.i18n.NumberFormatSymbols_ky_Cyrl');
goog.provide('goog.i18n.NumberFormatSymbols_ky_Cyrl_KG');
goog.provide('goog.i18n.NumberFormatSymbols_ln');
goog.provide('goog.i18n.NumberFormatSymbols_ln_CD');
@@ -179,10 +192,12 @@ goog.provide('goog.i18n.NumberFormatSymbols_mk_MK');
goog.provide('goog.i18n.NumberFormatSymbols_ml');
goog.provide('goog.i18n.NumberFormatSymbols_ml_IN');
goog.provide('goog.i18n.NumberFormatSymbols_mn');
goog.provide('goog.i18n.NumberFormatSymbols_mn_Cyrl');
goog.provide('goog.i18n.NumberFormatSymbols_mn_Cyrl_MN');
goog.provide('goog.i18n.NumberFormatSymbols_mr');
goog.provide('goog.i18n.NumberFormatSymbols_mr_IN');
goog.provide('goog.i18n.NumberFormatSymbols_ms');
goog.provide('goog.i18n.NumberFormatSymbols_ms_Latn');
goog.provide('goog.i18n.NumberFormatSymbols_ms_Latn_MY');
goog.provide('goog.i18n.NumberFormatSymbols_mt');
goog.provide('goog.i18n.NumberFormatSymbols_mt_MT');
@@ -200,6 +215,7 @@ goog.provide('goog.i18n.NumberFormatSymbols_no_NO');
goog.provide('goog.i18n.NumberFormatSymbols_or');
goog.provide('goog.i18n.NumberFormatSymbols_or_IN');
goog.provide('goog.i18n.NumberFormatSymbols_pa');
goog.provide('goog.i18n.NumberFormatSymbols_pa_Guru');
goog.provide('goog.i18n.NumberFormatSymbols_pa_Guru_IN');
goog.provide('goog.i18n.NumberFormatSymbols_pl');
goog.provide('goog.i18n.NumberFormatSymbols_pl_PL');
@@ -219,7 +235,10 @@ goog.provide('goog.i18n.NumberFormatSymbols_sl_SI');
goog.provide('goog.i18n.NumberFormatSymbols_sq');
goog.provide('goog.i18n.NumberFormatSymbols_sq_AL');
goog.provide('goog.i18n.NumberFormatSymbols_sr');
goog.provide('goog.i18n.NumberFormatSymbols_sr_Cyrl');
goog.provide('goog.i18n.NumberFormatSymbols_sr_Cyrl_RS');
goog.provide('goog.i18n.NumberFormatSymbols_sr_Latn');
goog.provide('goog.i18n.NumberFormatSymbols_sr_Latn_RS');
goog.provide('goog.i18n.NumberFormatSymbols_sv');
goog.provide('goog.i18n.NumberFormatSymbols_sv_SE');
goog.provide('goog.i18n.NumberFormatSymbols_sw');
@@ -238,12 +257,14 @@ goog.provide('goog.i18n.NumberFormatSymbols_uk_UA');
goog.provide('goog.i18n.NumberFormatSymbols_ur');
goog.provide('goog.i18n.NumberFormatSymbols_ur_PK');
goog.provide('goog.i18n.NumberFormatSymbols_uz');
goog.provide('goog.i18n.NumberFormatSymbols_uz_Latn');
goog.provide('goog.i18n.NumberFormatSymbols_uz_Latn_UZ');
goog.provide('goog.i18n.NumberFormatSymbols_vi');
goog.provide('goog.i18n.NumberFormatSymbols_vi_VN');
goog.provide('goog.i18n.NumberFormatSymbols_zh');
goog.provide('goog.i18n.NumberFormatSymbols_zh_CN');
goog.provide('goog.i18n.NumberFormatSymbols_zh_HK');
goog.provide('goog.i18n.NumberFormatSymbols_zh_Hans');
goog.provide('goog.i18n.NumberFormatSymbols_zh_Hans_CN');
goog.provide('goog.i18n.NumberFormatSymbols_zh_TW');
goog.provide('goog.i18n.NumberFormatSymbols_zu');
@@ -340,6 +361,13 @@ goog.i18n.NumberFormatSymbols_ar = {
goog.i18n.NumberFormatSymbols_ar_001 = goog.i18n.NumberFormatSymbols_ar;
/**
* Number formatting symbols for locale ar_EG.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_ar_EG = goog.i18n.NumberFormatSymbols_ar;
/**
* Number formatting symbols for locale az.
* @enum {string}
@@ -363,6 +391,13 @@ goog.i18n.NumberFormatSymbols_az = {
};
/**
* Number formatting symbols for locale az_Latn.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_az_Latn = goog.i18n.NumberFormatSymbols_az;
/**
* Number formatting symbols for locale az_Latn_AZ.
* @enum {string}
@@ -370,6 +405,36 @@ goog.i18n.NumberFormatSymbols_az = {
goog.i18n.NumberFormatSymbols_az_Latn_AZ = goog.i18n.NumberFormatSymbols_az;
/**
* Number formatting symbols for locale be.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_be = {
DECIMAL_SEP: ',',
GROUP_SEP: '\u00A0',
PERCENT: '%',
ZERO_DIGIT: '0',
PLUS_SIGN: '+',
MINUS_SIGN: '-',
EXP_SYMBOL: 'E',
PERMILL: '\u2030',
INFINITY: '\u221E',
NAN: 'NaN',
DECIMAL_PATTERN: '#,##0.###',
SCIENTIFIC_PATTERN: '#E0',
PERCENT_PATTERN: '#,##0%',
CURRENCY_PATTERN: '\u00A4#,##0.00',
DEF_CURRENCY_CODE: 'BYR'
};
/**
* Number formatting symbols for locale be_BY.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_be_BY = goog.i18n.NumberFormatSymbols_be;
/**
* Number formatting symbols for locale bg.
* @enum {string}
@@ -460,6 +525,43 @@ goog.i18n.NumberFormatSymbols_br = {
goog.i18n.NumberFormatSymbols_br_FR = goog.i18n.NumberFormatSymbols_br;
/**
* Number formatting symbols for locale bs.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_bs = {
DECIMAL_SEP: ',',
GROUP_SEP: '.',
PERCENT: '%',
ZERO_DIGIT: '0',
PLUS_SIGN: '+',
MINUS_SIGN: '-',
EXP_SYMBOL: 'E',
PERMILL: '\u2030',
INFINITY: '\u221E',
NAN: 'NaN',
DECIMAL_PATTERN: '#,##0.###',
SCIENTIFIC_PATTERN: '#E0',
PERCENT_PATTERN: '#,##0%',
CURRENCY_PATTERN: '#,##0.00\u00A0\u00A4',
DEF_CURRENCY_CODE: 'BAM'
};
/**
* Number formatting symbols for locale bs_Latn.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_bs_Latn = goog.i18n.NumberFormatSymbols_bs;
/**
* Number formatting symbols for locale bs_Latn_BA.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_bs_Latn_BA = goog.i18n.NumberFormatSymbols_bs;
/**
* Number formatting symbols for locale ca.
* @enum {string}
@@ -758,6 +860,13 @@ goog.i18n.NumberFormatSymbols_el = {
};
/**
* Number formatting symbols for locale el_CY.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_el_CY = goog.i18n.NumberFormatSymbols_el;
/**
* Number formatting symbols for locale el_GR.
* @enum {string}
@@ -825,6 +934,29 @@ goog.i18n.NumberFormatSymbols_en_AU = {
};
/**
* Number formatting symbols for locale en_CA.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_en_CA = {
DECIMAL_SEP: '.',
GROUP_SEP: ',',
PERCENT: '%',
ZERO_DIGIT: '0',
PLUS_SIGN: '+',
MINUS_SIGN: '-',
EXP_SYMBOL: 'E',
PERMILL: '\u2030',
INFINITY: '\u221E',
NAN: 'NaN',
DECIMAL_PATTERN: '#,##0.###',
SCIENTIFIC_PATTERN: '#E0',
PERCENT_PATTERN: '#,##0%',
CURRENCY_PATTERN: '\u00A4#,##0.00',
DEF_CURRENCY_CODE: 'CAD'
};
/**
* Number formatting symbols for locale en_DG.
* @enum {string}
@@ -1105,6 +1237,52 @@ goog.i18n.NumberFormatSymbols_es_ES = goog.i18n.NumberFormatSymbols_es;
goog.i18n.NumberFormatSymbols_es_IC = goog.i18n.NumberFormatSymbols_es;
/**
* Number formatting symbols for locale es_MX.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_es_MX = {
DECIMAL_SEP: '.',
GROUP_SEP: ',',
PERCENT: '%',
ZERO_DIGIT: '0',
PLUS_SIGN: '+',
MINUS_SIGN: '-',
EXP_SYMBOL: 'E',
PERMILL: '\u2030',
INFINITY: '\u221E',
NAN: 'NaN',
DECIMAL_PATTERN: '#,##0.###',
SCIENTIFIC_PATTERN: '#E0',
PERCENT_PATTERN: '#,##0%',
CURRENCY_PATTERN: '\u00A4#,##0.00',
DEF_CURRENCY_CODE: 'MXN'
};
/**
* Number formatting symbols for locale es_US.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_es_US = {
DECIMAL_SEP: '.',
GROUP_SEP: ',',
PERCENT: '%',
ZERO_DIGIT: '0',
PLUS_SIGN: '+',
MINUS_SIGN: '-',
EXP_SYMBOL: 'E',
PERMILL: '\u2030',
INFINITY: '\u221E',
NAN: 'NaN',
DECIMAL_PATTERN: '#,##0.###',
SCIENTIFIC_PATTERN: '#E0',
PERCENT_PATTERN: '#,##0\u00A0%',
CURRENCY_PATTERN: '\u00A4#,##0.00',
DEF_CURRENCY_CODE: 'USD'
};
/**
* Number formatting symbols for locale et.
* @enum {string}
@@ -1905,6 +2083,13 @@ goog.i18n.NumberFormatSymbols_kk = {
};
/**
* Number formatting symbols for locale kk_Cyrl.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_kk_Cyrl = goog.i18n.NumberFormatSymbols_kk;
/**
* Number formatting symbols for locale kk_Cyrl_KZ.
* @enum {string}
@@ -2025,6 +2210,13 @@ goog.i18n.NumberFormatSymbols_ky = {
};
/**
* Number formatting symbols for locale ky_Cyrl.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_ky_Cyrl = goog.i18n.NumberFormatSymbols_ky;
/**
* Number formatting symbols for locale ky_Cyrl_KG.
* @enum {string}
@@ -2236,6 +2428,13 @@ goog.i18n.NumberFormatSymbols_mn = {
};
/**
* Number formatting symbols for locale mn_Cyrl.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_mn_Cyrl = goog.i18n.NumberFormatSymbols_mn;
/**
* Number formatting symbols for locale mn_Cyrl_MN.
* @enum {string}
@@ -2296,6 +2495,13 @@ goog.i18n.NumberFormatSymbols_ms = {
};
/**
* Number formatting symbols for locale ms_Latn.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_ms_Latn = goog.i18n.NumberFormatSymbols_ms;
/**
* Number formatting symbols for locale ms_Latn_MY.
* @enum {string}
@@ -2449,7 +2655,7 @@ goog.i18n.NumberFormatSymbols_nl = {
DECIMAL_PATTERN: '#,##0.###',
SCIENTIFIC_PATTERN: '#E0',
PERCENT_PATTERN: '#,##0%',
CURRENCY_PATTERN: '\u00A4\u00A0#,##0.00;\u00A4\u00A0#,##0.00-',
CURRENCY_PATTERN: '\u00A4\u00A0#,##0.00;\u00A4\u00A0-#,##0.00',
DEF_CURRENCY_CODE: 'EUR'
};
@@ -2544,6 +2750,13 @@ goog.i18n.NumberFormatSymbols_pa = {
};
/**
* Number formatting symbols for locale pa_Guru.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_pa_Guru = goog.i18n.NumberFormatSymbols_pa;
/**
* Number formatting symbols for locale pa_Guru_IN.
* @enum {string}
@@ -2837,6 +3050,13 @@ goog.i18n.NumberFormatSymbols_sr = {
};
/**
* Number formatting symbols for locale sr_Cyrl.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_sr_Cyrl = goog.i18n.NumberFormatSymbols_sr;
/**
* Number formatting symbols for locale sr_Cyrl_RS.
* @enum {string}
@@ -2844,6 +3064,37 @@ goog.i18n.NumberFormatSymbols_sr = {
goog.i18n.NumberFormatSymbols_sr_Cyrl_RS = goog.i18n.NumberFormatSymbols_sr;
/**
* Number formatting symbols for locale sr_Latn.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_sr_Latn = {
DECIMAL_SEP: ',',
GROUP_SEP: '.',
PERCENT: '%',
ZERO_DIGIT: '0',
PLUS_SIGN: '+',
MINUS_SIGN: '-',
EXP_SYMBOL: 'E',
PERMILL: '\u2030',
INFINITY: '\u221E',
NAN: 'NaN',
DECIMAL_PATTERN: '#,##0.###',
SCIENTIFIC_PATTERN: '#E0',
PERCENT_PATTERN: '#,##0%',
CURRENCY_PATTERN: '#,##0.00\u00A0\u00A4',
DEF_CURRENCY_CODE: 'RSD'
};
/**
* Number formatting symbols for locale sr_Latn_RS.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_sr_Latn_RS =
goog.i18n.NumberFormatSymbols_sr_Latn;
/**
* Number formatting symbols for locale sv.
* @enum {string}
@@ -3130,6 +3381,13 @@ goog.i18n.NumberFormatSymbols_uz = {
};
/**
* Number formatting symbols for locale uz_Latn.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_uz_Latn = goog.i18n.NumberFormatSymbols_uz;
/**
* Number formatting symbols for locale uz_Latn_UZ.
* @enum {string}
@@ -3220,6 +3478,13 @@ goog.i18n.NumberFormatSymbols_zh_HK = {
};
/**
* Number formatting symbols for locale zh_Hans.
* @enum {string}
*/
goog.i18n.NumberFormatSymbols_zh_Hans = goog.i18n.NumberFormatSymbols_zh;
/**
* Number formatting symbols for locale zh_Hans_CN.
* @enum {string}
@@ -3309,14 +3574,30 @@ if (goog.LOCALE == 'ar_001' || goog.LOCALE == 'ar-001') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ar;
}
if (goog.LOCALE == 'ar_EG' || goog.LOCALE == 'ar-EG') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ar;
}
if (goog.LOCALE == 'az') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_az;
}
if (goog.LOCALE == 'az_Latn' || goog.LOCALE == 'az-Latn') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_az;
}
if (goog.LOCALE == 'az_Latn_AZ' || goog.LOCALE == 'az-Latn-AZ') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_az;
}
if (goog.LOCALE == 'be') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_be;
}
if (goog.LOCALE == 'be_BY' || goog.LOCALE == 'be-BY') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_be;
}
if (goog.LOCALE == 'bg') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_bg;
}
@@ -3341,6 +3622,18 @@ if (goog.LOCALE == 'br_FR' || goog.LOCALE == 'br-FR') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_br;
}
if (goog.LOCALE == 'bs') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_bs;
}
if (goog.LOCALE == 'bs_Latn' || goog.LOCALE == 'bs-Latn') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_bs;
}
if (goog.LOCALE == 'bs_Latn_BA' || goog.LOCALE == 'bs-Latn-BA') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_bs;
}
if (goog.LOCALE == 'ca') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ca;
}
@@ -3429,6 +3722,10 @@ if (goog.LOCALE == 'el') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_el;
}
if (goog.LOCALE == 'el_CY' || goog.LOCALE == 'el-CY') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_el;
}
if (goog.LOCALE == 'el_GR' || goog.LOCALE == 'el-GR') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_el;
}
@@ -3449,6 +3746,10 @@ if (goog.LOCALE == 'en_AU' || goog.LOCALE == 'en-AU') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_en_AU;
}
if (goog.LOCALE == 'en_CA' || goog.LOCALE == 'en-CA') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_en_CA;
}
if (goog.LOCALE == 'en_DG' || goog.LOCALE == 'en-DG') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_en;
}
@@ -3545,6 +3846,14 @@ if (goog.LOCALE == 'es_IC' || goog.LOCALE == 'es-IC') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_es;
}
if (goog.LOCALE == 'es_MX' || goog.LOCALE == 'es-MX') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_es_MX;
}
if (goog.LOCALE == 'es_US' || goog.LOCALE == 'es-US') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_es_US;
}
if (goog.LOCALE == 'et') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_et;
}
@@ -3773,6 +4082,10 @@ if (goog.LOCALE == 'kk') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_kk;
}
if (goog.LOCALE == 'kk_Cyrl' || goog.LOCALE == 'kk-Cyrl') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_kk;
}
if (goog.LOCALE == 'kk_Cyrl_KZ' || goog.LOCALE == 'kk-Cyrl-KZ') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_kk;
}
@@ -3805,6 +4118,10 @@ if (goog.LOCALE == 'ky') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ky;
}
if (goog.LOCALE == 'ky_Cyrl' || goog.LOCALE == 'ky-Cyrl') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ky;
}
if (goog.LOCALE == 'ky_Cyrl_KG' || goog.LOCALE == 'ky-Cyrl-KG') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ky;
}
@@ -3861,6 +4178,10 @@ if (goog.LOCALE == 'mn') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_mn;
}
if (goog.LOCALE == 'mn_Cyrl' || goog.LOCALE == 'mn-Cyrl') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_mn;
}
if (goog.LOCALE == 'mn_Cyrl_MN' || goog.LOCALE == 'mn-Cyrl-MN') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_mn;
}
@@ -3877,6 +4198,10 @@ if (goog.LOCALE == 'ms') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ms;
}
if (goog.LOCALE == 'ms_Latn' || goog.LOCALE == 'ms-Latn') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ms;
}
if (goog.LOCALE == 'ms_Latn_MY' || goog.LOCALE == 'ms-Latn-MY') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_ms;
}
@@ -3945,6 +4270,10 @@ if (goog.LOCALE == 'pa') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_pa;
}
if (goog.LOCALE == 'pa_Guru' || goog.LOCALE == 'pa-Guru') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_pa;
}
if (goog.LOCALE == 'pa_Guru_IN' || goog.LOCALE == 'pa-Guru-IN') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_pa;
}
@@ -4021,10 +4350,22 @@ if (goog.LOCALE == 'sr') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_sr;
}
if (goog.LOCALE == 'sr_Cyrl' || goog.LOCALE == 'sr-Cyrl') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_sr;
}
if (goog.LOCALE == 'sr_Cyrl_RS' || goog.LOCALE == 'sr-Cyrl-RS') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_sr;
}
if (goog.LOCALE == 'sr_Latn' || goog.LOCALE == 'sr-Latn') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_sr_Latn;
}
if (goog.LOCALE == 'sr_Latn_RS' || goog.LOCALE == 'sr-Latn-RS') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_sr_Latn;
}
if (goog.LOCALE == 'sv') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_sv;
}
@@ -4097,6 +4438,10 @@ if (goog.LOCALE == 'uz') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_uz;
}
if (goog.LOCALE == 'uz_Latn' || goog.LOCALE == 'uz-Latn') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_uz;
}
if (goog.LOCALE == 'uz_Latn_UZ' || goog.LOCALE == 'uz-Latn-UZ') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_uz;
}
@@ -4121,6 +4466,10 @@ if (goog.LOCALE == 'zh_HK' || goog.LOCALE == 'zh-HK') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_zh_HK;
}
if (goog.LOCALE == 'zh_Hans' || goog.LOCALE == 'zh-Hans') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_zh;
}
if (goog.LOCALE == 'zh_Hans_CN' || goog.LOCALE == 'zh-Hans-CN') {
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_zh;
}
File diff suppressed because it is too large Load Diff
+19 -1
View File
@@ -17,7 +17,7 @@
*
* This file is autogenerated by script:
* http://go/generate_pluralrules.py
* File generated from CLDR ver. 26
* File generated from CLDR ver. 27.0.1
*
* Before check in, this file could have been manually edited. This is to
* incorporate changes before we could fix CLDR. All manual modification must be
@@ -821,6 +821,9 @@ if (goog.LOCALE == 'ar') {
if (goog.LOCALE == 'az') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.esSelect_;
}
if (goog.LOCALE == 'be') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.beSelect_;
}
if (goog.LOCALE == 'bg') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.esSelect_;
}
@@ -830,6 +833,9 @@ if (goog.LOCALE == 'bn') {
if (goog.LOCALE == 'br') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.brSelect_;
}
if (goog.LOCALE == 'bs') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.srSelect_;
}
if (goog.LOCALE == 'ca') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
}
@@ -863,6 +869,9 @@ if (goog.LOCALE == 'en') {
if (goog.LOCALE == 'en_AU' || goog.LOCALE == 'en-AU') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
}
if (goog.LOCALE == 'en_CA' || goog.LOCALE == 'en-CA') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
}
if (goog.LOCALE == 'en_GB' || goog.LOCALE == 'en-GB') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
}
@@ -890,6 +899,12 @@ if (goog.LOCALE == 'es_419' || goog.LOCALE == 'es-419') {
if (goog.LOCALE == 'es_ES' || goog.LOCALE == 'es-ES') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.esSelect_;
}
if (goog.LOCALE == 'es_MX' || goog.LOCALE == 'es-MX') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.esSelect_;
}
if (goog.LOCALE == 'es_US' || goog.LOCALE == 'es-US') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.esSelect_;
}
if (goog.LOCALE == 'et') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
}
@@ -1070,6 +1085,9 @@ if (goog.LOCALE == 'sq') {
if (goog.LOCALE == 'sr') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.srSelect_;
}
if (goog.LOCALE == 'sr_Latn' || goog.LOCALE == 'sr-Latn') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.srSelect_;
}
if (goog.LOCALE == 'sv') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
}
+1 -1
View File
@@ -5,7 +5,7 @@ set -e
BASE_DIR=`dirname $0`
cd $BASE_DIR
./run-tests.sh
npm run test-i18n
node src/closureSlurper.js
-6
View File
@@ -1,6 +0,0 @@
#!/bin/bash
set -e
PARENT_DIR="$(dirname "$0")"
../node_modules/.bin/jasmine-node "$PARENT_DIR"/spec/
+78 -63
View File
@@ -4,6 +4,7 @@ findLocaleId = closureI18nExtractor.findLocaleId;
extractNumberSymbols = closureI18nExtractor.extractNumberSymbols;
extractCurrencySymbols = closureI18nExtractor.extractCurrencySymbols;
extractDateTimeSymbols = closureI18nExtractor.extractDateTimeSymbols;
outputLocale = closureI18nExtractor.outputLocale;
function newTestLocaleInfo() {
@@ -11,6 +12,8 @@ function newTestLocaleInfo() {
DATETIME_FORMATS: {
MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre',
'octobre', 'novembre', 'décembre'],
STANDALONEMONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre',
'octobre', 'novembre', 'décembre'],
SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.',
'nov.', 'déc.'],
DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
@@ -70,7 +73,7 @@ describe("findLocaleId", function() {
it("should throw an error otherwise", function() {
expect(function() {
findLocaleId("str", "otherwise")
}).toThrow("unknown type in findLocaleId: otherwise");
}).toThrowError("unknown type in findLocaleId: otherwise");
});
});
@@ -129,7 +132,10 @@ describe("extractCurrencySymbols", function() {
].join('\n');
var localeInfo = {};
expect(extractCurrencySymbols(CONTENT)).toEqual({
var currencySymbols = extractCurrencySymbols(CONTENT);
expect(currencySymbols.GBP).toEqual([2, '£', 'GB£']);
expect(currencySymbols.AOA).toEqual([2, 'Kz', 'Kz']);
expect(currencySymbols).toEqual({
'GBP':[2, '£', 'GB£'],
'AOA':[2, 'Kz', 'Kz']
});
@@ -140,69 +146,71 @@ describe("extractCurrencySymbols", function() {
describe("extractDateTimeSymbols", function() {
it("should extract date time data", function() {
var CONTENT = [
"goog.i18n.DateTimeSymbols_fr_CA = {",
" ERAS: ['av. J.-C.', 'ap. J.-C.'],",
" ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'],",
" NARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],",
" STANDALONENARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',",
" 'N', 'D'],",
" MONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',",
" 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
" STANDALONEMONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',",
" 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
" SHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.',",
" 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
" STANDALONESHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin',",
" 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
" WEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi',",
" 'samedi'],",
" STANDALONEWEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi',",
" 'vendredi', 'samedi'],",
" SHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],",
" STANDALONESHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.',",
" 'sam.'],",
" NARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
" STANDALONENARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
" SHORTQUARTERS: ['T1', 'T2', 'T3', 'T4'],",
" QUARTERS: ['1er trimestre', '2e trimestre', '3e trimestre', '4e trimestre'],",
" AMPMS: ['AM', 'PM'],",
" DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'yyyy-MM-dd', 'yy-MM-dd'],",
" TIMEFORMATS: ['HH \\'h\\' mm \\'min\\' ss \\'s\\' zzzz', 'HH:mm:ss z',",
" 'HH:mm:ss', 'HH:mm'],",
" FIRSTDAYOFWEEK: 6,",
" WEEKENDRANGE: [5, 6],",
" FIRSTWEEKCUTOFFDAY: 2",
"};"
"goog.i18n.DateTimeSymbols_fr_CA = {",
" ERAS: ['av. J.-C.', 'ap. J.-C.'],",
" ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'],",
" NARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],",
" STANDALONENARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',",
" 'N', 'D'],",
" MONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',",
" 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
" STANDALONEMONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',",
" 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
" SHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.',",
" 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
" STANDALONESHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin',",
" 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
" WEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi',",
" 'samedi'],",
" STANDALONEWEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi',",
" 'vendredi', 'samedi'],",
" SHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],",
" STANDALONESHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.',",
" 'sam.'],",
" NARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
" STANDALONENARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
" SHORTQUARTERS: ['T1', 'T2', 'T3', 'T4'],",
" QUARTERS: ['1er trimestre', '2e trimestre', '3e trimestre', '4e trimestre'],",
" AMPMS: ['AM', 'PM'],",
" DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'yyyy-MM-dd', 'yy-MM-dd'],",
" TIMEFORMATS: ['HH \\'h\\' mm \\'min\\' ss \\'s\\' zzzz', 'HH:mm:ss z',",
" 'HH:mm:ss', 'HH:mm'],",
" FIRSTDAYOFWEEK: 6,",
" WEEKENDRANGE: [5, 6],",
" FIRSTWEEKCUTOFFDAY: 2",
"};"
].join('\n');
var localeInfo = {};
var expectedLocaleInfo = {
fr_CA: {
DATETIME_FORMATS: {
MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre',
'octobre', 'novembre', 'décembre'],
SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.',
'nov.', 'déc.'],
DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
SHORTDAY: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
AMPMS: ['AM', 'PM'],
ERAS: ['av. J.-C.', 'ap. J.-C.'],
ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'],
medium: 'yyyy-MM-dd HH:mm:ss',
short: 'yy-MM-dd HH:mm',
fullDate: 'EEEE d MMMM y',
longDate: 'd MMMM y',
mediumDate: 'yyyy-MM-dd',
shortDate: 'yy-MM-dd',
mediumTime: 'HH:mm:ss',
shortTime: 'HH:mm'
}
var localeInfo = {};
var expectedLocaleInfo = {
fr_CA: {
DATETIME_FORMATS: {
MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre',
'octobre', 'novembre', 'décembre'],
STANDALONEMONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',
'août', 'septembre', 'octobre', 'novembre', 'décembre'],
SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.',
'nov.', 'déc.'],
DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
SHORTDAY: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
FIRSTDAYOFWEEK: 6,
WEEKENDRANGE: [5, 6],
AMPMS: ['AM', 'PM'],
ERAS: ['av. J.-C.', 'ap. J.-C.'],
ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'],
medium: 'yyyy-MM-dd HH:mm:ss',
short: 'yy-MM-dd HH:mm',
fullDate: 'EEEE d MMMM y',
longDate: 'd MMMM y',
mediumDate: 'yyyy-MM-dd',
shortDate: 'yy-MM-dd',
mediumTime: 'HH:mm:ss',
shortTime: 'HH:mm'
}
};
extractDateTimeSymbols(CONTENT, localeInfo);
expect(localeInfo).toEqual(expectedLocaleInfo);
})
}
};
extractDateTimeSymbols(CONTENT, localeInfo);
expect(localeInfo).toEqual(expectedLocaleInfo);
});
});
describe("pluralExtractor", function() {
@@ -268,3 +276,10 @@ describe("serializeContent", function() {
});
});
describe("outputLocale", function() {
it("should render the correct locale ids", function() {
var output = outputLocale(newTestLocaleInfo(), 'fr_CA');
expect(output).toContain('"id": "fr-ca"');
expect(output).toContain('"localeID": "fr_CA"');
});
});
+2
View File
@@ -27,6 +27,7 @@ describe("convertNumberData", function() {
describe("convertDatetimeData", function() {
var convert = converter.convertDatetimeData,
dataObj = { MONTHS: ['Enero', 'Pebrero'],
STANDALONEMONTHS: ['Enero', 'Pebrero'],
SHORTMONTHS: ['Ene', 'Peb'],
WEEKDAYS: ['Linggo', 'Lunes'],
SHORTWEEKDAYS: ['Lin', 'Lun'],
@@ -37,6 +38,7 @@ describe("convertDatetimeData", function() {
it('should convert empty datetime obj', function() {
var processedData = convert(dataObj);
expect(processedData.MONTH).toEqual(['Enero', 'Pebrero']);
expect(processedData.STANDALONEMONTH).toEqual(['Enero', 'Pebrero']);
expect(processedData.SHORTMONTH).toEqual(['Ene', 'Peb']);
expect(processedData.DAY).toEqual(['Linggo', 'Lunes']);
expect(processedData.SHORTDAY).toEqual(['Lin', 'Lun']);
+3 -3
View File
@@ -38,16 +38,16 @@ describe('parsePattern', function() {
parseAndExpect('#,##,##0.00\u00A4', '', '-', '\u00A4', '\u00A4', 1, 2, 2, 2, 3);
parseAndExpect('#,##,##0.00\u00A4;(#,##,##0.00\u00A4)',
'', '(', '\u00A4', '\u00A4)', 1, 2, 2, 2, 3);
parseAndExpect('\u00A4#,##0.00', '\u00A4', '\u00A4-', '', '', 1, 2, 2, 3, 3);
parseAndExpect('\u00A4#,##0.00', '\u00A4', '-\u00A4', '', '', 1, 2, 2, 3, 3);
parseAndExpect('\u00A4#,##0.00;(\u00A4#,##0.00)',
'\u00A4', '(\u00A4', '', ')', 1, 2, 2, 3, 3);
parseAndExpect('\u00A4#,##0.00;\u00A4-#,##0.00',
'\u00A4', '\u00A4-', '', '', 1, 2, 2, 3, 3);
parseAndExpect('\u00A4 #,##0.00', '\u00A4 ', '\u00A4 -', '', '', 1, 2, 2, 3, 3);
parseAndExpect('\u00A4 #,##0.00', '\u00A4 ', '-\u00A4 ', '', '', 1, 2, 2, 3, 3);
parseAndExpect('\u00A4 #,##0.00;\u00A4-#,##0.00',
'\u00A4 ', '\u00A4-', '', '', 1, 2, 2, 3, 3);
parseAndExpect('\u00A4 #,##0.00;\u00A4 #,##0.00-',
'\u00A4 ', '\u00A4 ', '', '-', 1, 2, 2, 3, 3);
parseAndExpect('\u00A4 #,##,##0.00', '\u00A4 ', '\u00A4 -', '', '', 1, 2, 2, 2, 3);
parseAndExpect('\u00A4 #,##,##0.00', '\u00A4 ', '-\u00A4 ', '', '', 1, 2, 2, 2, 3);
});
});
+9 -7
View File
@@ -50,10 +50,10 @@ function extractNumberSymbols(content, localeInfo, currencySymbols) {
function extractCurrencySymbols(content) {
//eval script in the current context so that we get access to all the symbols
eval(content.toString());
var currencySymbols = goog.i18n.currency.CurrencyInfo;
currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
// var currencySymbols = goog.i18n.currency.CurrencyInfo;
// currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
return currencySymbols;
return Object.assign({}, goog.i18n.currency.CurrencyInfoTier2, goog.i18n.currency.CurrencyInfo);
}
function extractDateTimeSymbols(content, localeInfo) {
@@ -79,7 +79,7 @@ function pluralExtractor(content, localeInfo) {
goog.LOCALE = localeIds[i].match(/[^_]+/)[0];
try {
eval(contentText);
} catch(e) {
} catch (e) {
console.log("Error in eval(contentText): " + e.stack);
}
if (!goog.i18n.pluralRules.select) {
@@ -133,7 +133,7 @@ function canonicalizeForJsonStringify(unused_key, object) {
function serializeContent(localeObj) {
return JSON.stringify(localeObj, canonicalizeForJsonStringify, ' ')
.replace(new RegExp('[\\u007f-\\uffff]', 'g'), function(c) { return '\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4); })
.replace(new RegExp('[\\u007f-\\uffff]', 'g'), function(c) { return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4); })
.replace(/"@@|@@"/g, '');
}
@@ -161,6 +161,7 @@ function outputLocale(localeInfo, localeID) {
if (!localeObj.DATETIME_FORMATS) {
localeObj.DATETIME_FORMATS = fallBackObj.DATETIME_FORMATS;
}
localeObj.localeID = localeID;
localeObj.id = correctedLocaleId(localeID);
var getDecimals = [
@@ -201,10 +202,11 @@ function outputLocale(localeInfo, localeID) {
DATETIME_FORMATS: localeObj.DATETIME_FORMATS,
NUMBER_FORMATS: localeObj.NUMBER_FORMATS,
pluralCat: localeObj.pluralCat,
id: localeObj.id
id: localeObj.id,
localeID: localeID
};
var content = serializeContent(localeInfo[localeID]);
var content = serializeContent(localeObj);
if (content.indexOf('getVF(') < 0) {
getVF = '';
}
+1
View File
@@ -39,6 +39,7 @@ function convertDatetimeData(dataObj) {
datetimeFormats.MONTH = dataObj.MONTHS;
datetimeFormats.SHORTMONTH = dataObj.SHORTMONTHS;
datetimeFormats.STANDALONEMONTH = dataObj.STANDALONEMONTHS;
datetimeFormats.DAY = dataObj.WEEKDAYS;
datetimeFormats.SHORTDAY = dataObj.SHORTWEEKDAYS;
datetimeFormats.AMPMS = dataObj.AMPMS;
+1 -1
View File
@@ -56,7 +56,7 @@ function parsePattern(pattern) {
p.negSuf = negative.substr(pos + trunkLen).replace(/\'/g, '');
} else {
// hardcoded '-' sign is fine as all locale use '-' as MINUS_SIGN. (\u2212 is the same as '-')
p.negPre = p.posPre + '-';
p.negPre = '-' + p.posPre;
p.negSuf = p.posSuf;
}
@@ -2142,7 +2142,7 @@ queue}</string>
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qr
\f0\fs22 \cf2 $scope\
name='Wold'}</string>
name='World'}</string>
<key>VerticalPad</key>
<integer>0</integer>
</dict>
+5 -3
View File
@@ -17,7 +17,9 @@ module.exports = function(config, specificOptions) {
testName: specificOptions.testName || 'AngularJS',
startConnect: true,
options: {
'selenium-version': '2.41.0'
// We need selenium version +2.46 for Firefox 39 and the last selenium version for OS X is 2.45.
// TODO: Uncomment when there is a selenium 2.46 available for OS X.
// 'selenium-version': '2.46.0'
}
},
@@ -35,12 +37,12 @@ module.exports = function(config, specificOptions) {
'SL_Chrome': {
base: 'SauceLabs',
browserName: 'chrome',
version: '39'
version: '43'
},
'SL_Firefox': {
base: 'SauceLabs',
browserName: 'firefox',
version: '31'
version: '39'
},
'SL_Safari': {
base: 'SauceLabs',
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
set -e -o pipefail
echo "Shutting down Browserstack tunnel"
echo "TODO: implement me"
exit 1
+1 -1
View File
@@ -116,7 +116,7 @@ module.exports = {
.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(/\r?\n/g, '\\n');
js = "!window.angular.$$csp() && window.angular.element(document.head).prepend('<style type=\"text/css\">" + css + "</style>');";
js = "!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('<style type=\"text/css\">" + css + "</style>');";
state.js.push(js);
return state;
+58
View File
@@ -0,0 +1,58 @@
'use strict';
var path = require('path');
var fs = require('fs');
var glob = require("glob");
var _ = require('lodash');
var files = require('../../angularFiles').files;
module.exports = function(grunt) {
grunt.registerTask('validate-angular-files', function() {
var combinedFiles = _.clone(files.angularModules);
combinedFiles.ng = files.angularSrc;
combinedFiles.angularLoader = files.angularLoader;
var errorsDetected = false;
var directories = [];
var detectedFiles = {};
for (var section in combinedFiles) {
var sectionFiles = combinedFiles[section];
if (section != 'angularLoader') {
directories.push('src/' + section);
}
grunt.log.debug('Validating ' + sectionFiles.length + ' files from the "' + section + '" module.');
sectionFiles.forEach(function(file) {
detectedFiles[file] = true;
if (!fs.existsSync(file)) {
grunt.log.error(file + ' does not exist in the local file structure.');
errorsDetected = true;
}
});
}
directories.forEach(function(directory) {
glob.sync(directory + '/**/*').forEach(function(filePath) {
if (!fs.lstatSync(filePath).isDirectory()) {
var fileName = path.basename(filePath);
var isHiddenFile = fileName[0] == '.';
if (!isHiddenFile && !detectedFiles[filePath]) {
grunt.log.error(filePath + ' exists in the local file structure but isn\'t used by any module.');
errorsDetected = true;
}
}
});
});
if (errorsDetected) {
throw new Error('Not all files were properly detected in the local file structure.');
} else {
grunt.log.ok('All files were detected successfully!');
}
});
};
@@ -4,6 +4,8 @@
var isFunction = function isFunction(value){return typeof value == 'function';};
var isPromiseLike = function isPromiseLike(obj) {return obj && isFunction(obj.then);};
var isObject = function isObject(value){return value != null && typeof value === 'object';};
var isUndefined = function isUndefined(value) {return typeof value === 'undefined';};
var minErr = function minErr (module, constructor) {
return function (){
var ErrorConstructor = constructor || Error;
@@ -11,6 +13,20 @@ var minErr = function minErr (module, constructor) {
};
};
var extend = function extend(dst) {
for (var i = 1, ii = arguments.length; i < ii; i++) {
var obj = arguments[i];
if (obj) {
var keys = Object.keys(obj);
for (var j = 0, jj = keys.length; j < jj; j++) {
var key = keys[j];
dst[key] = obj[key];
}
}
}
return dst;
};
var $q = qFactory(process.nextTick, function noopExceptionHandler() {});
exports.resolved = $q.resolve;
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
set -e -o pipefail
echo "Shutting down Sauce Connect tunnel"
killall sc
while [[ -n `ps -ef | grep "sauce-connect-" | grep -v "grep"` ]]; do
printf "."
sleep .5
done
echo ""
echo "Sauce Connect tunnel has been shut down"
+4580 -875
View File
File diff suppressed because it is too large Load Diff
+7233 -1505
View File
File diff suppressed because it is too large Load Diff
+28 -13
View File
@@ -1,8 +1,9 @@
{
"name": "angularjs",
"license": "MIT",
"branchVersion": "^1.4.0-beta.0",
"branchVersion": "1.4.x",
"branchPattern": "1.4.*",
"distTag": "previous_1_4",
"repository": {
"type": "git",
"url": "https://github.com/angular/angular.js.git"
@@ -12,6 +13,12 @@
"npm": "~2.5"
},
"engineStrict": true,
"scripts": {
"preinstall": "node scripts/npm/check-node-modules.js --purge",
"postinstall": "node scripts/npm/copy-npm-shrinkwrap.js",
"commit": "git-cz",
"test-i18n": "jasmine-node i18n/spec"
},
"devDependencies": {
"angular-benchpress": "0.x.x",
"benchmark": "1.x.x",
@@ -19,9 +26,12 @@
"browserstacktunnel-wrapper": "~1.3.1",
"canonical-path": "0.0.2",
"cheerio": "^0.17.0",
"commitizen": "^2.3.0",
"cz-conventional-changelog": "^1.1.4",
"dgeni": "^0.4.0",
"dgeni-packages": "^0.10.0",
"dgeni-packages": "^0.11.0",
"event-stream": "~3.1.0",
"glob": "^6.0.1",
"grunt": "~0.4.2",
"grunt-bump": "~0.0.13",
"grunt-contrib-clean": "~0.6.0",
@@ -42,18 +52,18 @@
"gulp-sourcemaps": "^1.2.2",
"gulp-uglify": "^1.0.1",
"gulp-util": "^3.0.1",
"jasmine-node": "~1.14.5",
"jasmine-node": "^2.0.0",
"jasmine-reporters": "~1.0.1",
"jshint-stylish": "~1.0.0",
"karma": "0.12.32",
"karma-browserstack-launcher": "0.1.2",
"karma-chrome-launcher": "0.1.5",
"karma-firefox-launcher": "0.1.3",
"karma-jasmine": "0.1.5",
"karma-junit-reporter": "0.2.2",
"karma-ng-scenario": "0.1.0",
"karma-sauce-launcher": "0.2.10",
"karma-script-launcher": "0.1.0",
"karma": "^0.13.19",
"karma-browserstack-launcher": "^0.1.8",
"karma-chrome-launcher": "^0.2.2",
"karma-firefox-launcher": "^0.1.7",
"karma-jasmine": "^0.1.6",
"karma-junit-reporter": "^0.3.8",
"karma-ng-scenario": "^0.1.0",
"karma-sauce-launcher": "^0.3.0",
"karma-script-launcher": "^0.1.0",
"load-grunt-tasks": "~0.6.0",
"lodash": "~2.4.1",
"marked": "~0.3.0",
@@ -75,5 +85,10 @@
"url": "https://github.com/angular/angular.js/blob/master/LICENSE"
}
],
"dependencies": {}
"dependencies": {},
"config": {
"commitizen": {
"path": "node_modules/cz-conventional-changelog"
}
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ config.specs = [
];
config.capabilities = {
browserName: 'chrome',
browserName: 'chrome'
};
exports.config = config;
+6 -6
View File
@@ -9,7 +9,7 @@ if (process.env.BROWSER_PROVIDER === 'browserstack') {
capabilitiesForBrowserStack({
browserName: 'chrome',
platform: 'MAC',
version: '34'
version: '49'
}),
capabilitiesForBrowserStack({
browserName: 'firefox',
@@ -18,7 +18,7 @@ if (process.env.BROWSER_PROVIDER === 'browserstack') {
capabilitiesForBrowserStack({
browserName: 'safari',
platform: 'MAC',
version: '7'
version: '9'
})
];
} else {
@@ -28,8 +28,8 @@ if (process.env.BROWSER_PROVIDER === 'browserstack') {
config.multiCapabilities = [
capabilitiesForSauceLabs({
browserName: 'chrome',
platform: 'OS X 10.9',
version: '34'
platform: 'OS X 10.11',
version: '48'
}),
capabilitiesForSauceLabs({
browserName: 'firefox',
@@ -37,8 +37,8 @@ if (process.env.BROWSER_PROVIDER === 'browserstack') {
}),
capabilitiesForSauceLabs({
browserName: 'safari',
platform: 'OS X 10.9',
version: '7'
platform: 'OS X 10.11',
version: '9'
})
];
}
+5 -13
View File
@@ -14,6 +14,9 @@ function init {
TMP_DIR=$(resolveDir ../../tmp)
BUILD_DIR=$(resolveDir ../../build)
NEW_VERSION=$(cat $BUILD_DIR/version.txt)
PROJECT_DIR=$(resolveDir ../..)
# get the npm dist-tag from a custom property (distTag) in package.json
DIST_TAG=$(readJsonProp "$PROJECT_DIR/package.json" "distTag")
}
@@ -95,19 +98,8 @@ function publish {
# don't publish every build to npm
if [ "${NEW_VERSION/+sha}" = "$NEW_VERSION" ] ; then
if [ "${NEW_VERSION/-}" = "$NEW_VERSION" ] ; then
if [[ $NEW_VERSION =~ ^1\.2\.[0-9]+$ ]] ; then
# publish 1.2.x releases with the appropriate tag
# this ensures that `npm install` by default will not grab `1.2.x` releases
npm publish --tag=old
else
# publish releases as "latest"
npm publish
fi
else
# publish prerelease builds with the beta tag
npm publish --tag=beta
fi
echo "-- Publishing to npm as $DIST_TAG"
npm publish --tag=$DIST_TAG
fi
cd $SCRIPT_DIR
@@ -4,6 +4,8 @@ echo "#################################"
echo "#### Jenkins Build ############"
echo "#################################"
source scripts/jenkins/set-node-version.sh
# Enable tracing and exit on first failure
set -xe
@@ -19,6 +21,7 @@ rm -f angular.js.size
# BUILD #
npm install -g grunt-cli
npm install --color false
grunt ci-checks package --no-color

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