Compare commits

...

686 Commits

Author SHA1 Message Date
Pete Bacon Darwin dd26545870 docs(CHANGELOG): add 1.7.8 release notes 2019-03-11 11:30:02 +00:00
Martin Staffa a4c7bdccd7 fix(required): correctly validate required on non-input element surrounded by ngIf
Closes #16830
Closes #16836
2019-03-06 18:09:35 +01:00
Ashish Kamble edb3e22c01 docs(guide/di): clarify example description
Closes #16833
2019-03-05 22:01:01 +02:00
Pete Bacon Darwin 7446836e56 chore(scripts): use https for git repo URLs 2019-02-04 13:31:07 +00:00
Pete Bacon Darwin 3f79662d61 docs(CHANGELOG): update with 1.7.7 release notes 2019-02-04 13:04:28 +00:00
Pete Bacon Darwin e4830b9fd2 docs(RELEASE): store release instructions 2019-02-04 13:04:23 +00:00
Martin Staffa 5ad4f5562c fix(ngRequired): set error correctly when inside ngRepeat and false by default
Previously, in the required validator, we would read the required setting directly
from attr.required, where it is set by ngRequired.

However, when the control is inside ngRepeat, ngRequired sets it only after a another digest has
passed, which means the initial validation run of ngModel does not include the correct required
setting. (Before commit 0637a2124c this would not have been a problem,
as every observed value change triggered a validation).

We now use the initially parsed value from ngRequired in the validator.

Fixes #16814
Closes #16820
2019-01-26 11:31:56 +01:00
Martin Staffa 43bb414e23 docs(angular.copy): fix list of unsupported types 2019-01-21 20:36:49 +01:00
Martin Staffa 64c7c53190 docs(angular.merge): add notes about support and lodash compatibility
Closes #16187
Closes #14512
2019-01-21 20:36:49 +01:00
Martin Staffa 5075c870fd docs(angular.copy): list object types / features that are not supported
Closes #5085
Closes #13193
Closes #14352
Closes #15904
Closes #16055
Closes #16061
Closes #16067
2019-01-21 20:36:48 +01:00
Martin Staffa b9edb415b2 docs(angular.copy): add note about destination and source compatibility
Closes #15444
Closes #15462
2019-01-21 20:36:47 +01:00
Martin Staffa 7ca6543244 docs(ngParseExt): note limitations with ngOptions and ngRepeat
Closes #15954
Closes #15926
2019-01-21 20:36:47 +01:00
Martin Staffa e58b4ceed8 docs(input[email]): note limitations with IPv6 addresses
Closes #16599
2019-01-21 20:36:46 +01:00
Martin Staffa c97237bcb8 docs(ngDisabled): remove restriction to input element
Disabled can be set on many different elements, and might also be used
on custom controls, so it's better to remove the restriction completely

Closes #16775
2019-01-21 12:55:31 +01:00
Pete Bacon Darwin 8822a4ff69 chore(*): update CHANGELOG with release notes for 1.7.6 2019-01-17 09:20:48 +00:00
Jason Bedard 772440cdaf fix($compile): fix ng-prop-* with undefined values
Fixes #16797
Closes #16798
2019-01-11 10:04:26 -08:00
George Kalpakas 1fbddf950f chore(saucelabs): remove SL_Safari from browser list
Closes #16806
2019-01-10 21:42:12 +02:00
George Kalpakas 369ca3e13e chore(saucelabs): add SL_EDGE-1 to browser list 2019-01-10 21:42:12 +02:00
George Kalpakas 00d38e3358 chore(travis): suppress verbose log output and allow error logging
Based on angular/angular#27657.
2019-01-10 21:42:11 +02:00
George Kalpakas a0ed1b73ff chore(package): upgrade to latest karma-sauce-launcher
Based on angular/angular#27634.
2019-01-10 21:42:11 +02:00
George Kalpakas e44c3ac327 chore(package): upgrade to latest karma
This includes a Karma fix that affects CI flakiness.
Based on angular/angular#27735.
2019-01-10 21:42:11 +02:00
George Kalpakas c6551231b2 chore(saucelabs): use 'websocket' for transmission when possible 2019-01-10 21:42:10 +02:00
George Kalpakas bf073be69d chore(saucelabs): upgrade to latest SauceConnect 2019-01-10 21:42:10 +02:00
George Kalpakas aed34c75be test(ngHref): only run Edge-specific test on relevant Edge versions 2019-01-10 21:42:10 +02:00
Bernhard Kiselka 78e17f5729 docs(guide/Conceptual Overview): use exchangeratesapi.io
As fixer.io introduced an API key and thus a limitation of calls
(see https://github.com/fixerAPI/fixer#readme ),
change https://api.fixer.io to https://api.exchangeratesapi.io instead,
which is "designed and tested to handle thousands of request per second"
and has "built in Fixer.io compatibility so you can keep all the libraries you already like
and use daily" (from https://api.exchangeratesapi.io ).
The idea is from https://github.com/fixerAPI/fixer/issues/107

fixes  #16807

Closes #16808
2019-01-07 13:13:29 +02:00
Julien RAJERISON ba6f477ac8 docs(ISSUE_TEMPLATE.md): add Opera to browser list
Opera is indirectly supported, although not explicitly tested on (see
[here](https://docs.angularjs.org/misc/faq#what-browsers-does-angularjs-work-with-)
for more info), so it doesn't hurt adding it to the list of browsers.

Closes #16801
2018-12-29 12:46:36 +02:00
Frederik Prijck 6482297185 chore(package): rename to angular to match npm
Previously, angularjs was used as the name inside the package.json file.
However, angularjs is published to npm using angular.
To avoid conflicts, the name is updated to reflect the same name as being published on npm.

Fixes #16799

Closes #16800
2018-12-27 20:29:11 +02:00
Pete Bacon Darwin 41deaf1d21 test(ngAnimate): ensure that blockTransitions can be spied upon
Previously the test was assuing that this function was attached to
the window, which is not the case in production, nor in the isolated
module tests.
2018-12-12 08:10:44 +00:00
Pete Bacon Darwin 23e4138c07 chore(modules): execute modules unit tests in one karma run
SauceLabs  is struggling to keep connecting and disconnecting
for each of the modules unit test runs. This commit puts most of
the module tests into IIFEs so that they can be run in one go.

* ngMock is still tested separately since unlike the other tests
it doesn't want to have a pre-built version of ngMock available.

* ngAnimate is still tested separately because it does some funny
things with globals that were difficult to isolate in the main modules
test run.
2018-12-12 08:10:12 +00:00
Pete Bacon Darwin 0ffb30f585 chore(utils): do not mutate source arrays 2018-12-12 08:09:59 +00:00
Pete Bacon Darwin 6f52013668 test(*): isolate cache leaks from subsequent tests 2018-12-12 08:09:42 +00:00
Michał Gołębiowski-Owczarek 07e1ba29f0 test(ngSanitize): disable a failing Edge test in all versions, including 18
It's been only disabled on Edge 16/17 so far which made it fail in Edge 18.

Closes #16786
2018-12-09 03:23:44 +01:00
Pete Bacon Darwin 04c64b3d10 chore(code.angularjs.org): fix directory list paging 2018-12-06 10:34:57 +00:00
Pete Bacon Darwin 4d9a95ffdb chore(code.angularjs.org): update firebase libraries 2018-12-06 10:34:47 +00:00
Michał Gołębiowski-Owczarek 27486bd15e fix(compile): properly handle false value for boolean attrs with jQuery
jQuery skips special boolean attrs treatment in XML nodes for historical reasons
and hence AngularJS cannot freely call `.attr(attrName, false) with such
attributes. To avoid issues in XHTML, call `removeAttr` in such cases instead.

Ref jquery/jquery#4249
Fixes #16778
Closes #16779
2018-12-06 10:09:55 +01:00
Jason Bedard cf919a6fb7 fix(ngRepeat): fix reference to last collection value remaining across linkages
Ref #16776
2018-12-06 10:09:47 +01:00
Jason Bedard d4d1031bcd fix(ngRepeat): fix trackBy function being invoked with incorrect scope
Also fixes a leak of that scope across all further instances of the
repeated element.

Fixes #16776
Closes #16777
2018-12-06 10:09:38 +01:00
Joseph Jacobs 798114075f docs(tutorial/step_3): clarify how components are mapped to HTML elements
Closes #16768
2018-12-05 18:59:20 +02:00
Anthony X 838dd12ee1 docs(tutorial/step_6): fix experiment description
In the experiments section, it is suggested to add a `-` symbol to
`<option value="age">Oldest</option>`. This change is made to reverse
the sort order when selecting the `age` option.

However, this change affects the default `$ctrl.orderProp` that we had
set in `phone-list.component.js`. After making the change, our default
when refreshing the page is "Sort by: [blank]".

This commit adds some additional documentation to clarify that this
behavior makes sense and that the reader should try and fix this within
`phone-list.component.js`.

Closes #16781
2018-12-05 17:24:40 +02:00
Martin Staffa 6926223963 perf(input): prevent multiple validations on initialization
This commit updates in-built validators with observers to prevent
multiple calls to $validate that could happen on initial linking of the directives in
certain circumstances:

- when an input is wrapped in a transclude: element directive (e.g. ngRepeat),
the order of execution between ngModel and the input / validation directives changes so that
the initial observer call happens when ngModel has already been initalized,
leading to another call to $validate, which calls *all* defined validators again.
Without ngRepeat, ngModel hasn't been initialized yet, and $validate does not call the validators.

When using validators with scope expressions, the expression value is not available when
ngModel first runs the validators (e.g. ngMinlength="myMinlength"). Only in the first call to
the observer does the value become available, making a call to $validate a necessity.

This commit solves the first problem by storing the validation attribute value so we can compare
the current value and the observed value - which will be the same after compilation.

The second problem is solved by parsing the validation expression once in the link function,
so the value is available when ngModel first validates.

Closes #14691 
Closes #16760
2018-12-05 14:10:09 +01:00
Martin Staffa 5f8372ee2d chore(Saucelabs): increase max session duration
We have amassed so many e2e tests, that the default 30 minute
Saucelabs session limit is often not enough, especially during
the week, when the VMs are under heavy load.
2018-12-05 08:31:03 +01:00
Eirik Blakstad 289374a43c fix(aria/ngClick): check if element is contenteditable before blocking spacebar
`ngAria`'s `ngClick` blocks spacebar keypresses on non-blacklisted
elements, which is an issue when the element is `contenteditable`.

Closes #16762
2018-12-02 13:19:47 +02:00
Pete Bacon Darwin 3b333f3b9f chore(package): update protractor & webdriver dependencies 2018-12-02 10:06:18 +00:00
Jason Bedard 7cbb1044fc fix(input): prevent browsers from autofilling hidden inputs
Autofilling with previous values (which will then be `$interpolate`ed) could lead to XSS or errors
2018-12-02 09:48:46 +00:00
Martin Staffa a8bfeff5d8 chore(travis): put unit module tests into separate job
They take a lot of time since we created different karma jobs for them
2018-11-26 14:53:33 +01:00
Martin Staffa fc0e100c45 chore(saucelabs): always test 2 latest Safari versions
Safari 10 does not finish the tests, but Safari 11 and 12 do
2018-11-26 14:53:32 +01:00
Martin Staffa eb49f6b755 revert: fix(Angular): add workaround for Safari / Webdriver problem
This reverts commit 6b915ad9db.
Karma has this workaround built in since 3.1.0:
https://github.com/karma-runner/karma/commit/873e4f9
2018-11-26 14:53:31 +01:00
Martin Staffa f9e651d113 chore(*): update karma
This allows us to remove the workaround added in #16645
2018-11-26 14:53:23 +01:00
Jason Bedard 2f72a69ded fix($browser): normalize inputted URLs
Calls to `$browser.url` now normalize the inputted URL ensuring multiple
calls only differing in formatting do not force a browser `pushState`.

Normalization is done the same as the browser location URL and may
differ per browser and may be changed by browsers. Today no browsers
fully normalize URLs so this does not fix all instances of this issue.

See #16100
Closes #16606
2018-11-26 14:50:39 +01:00
Jason Bedard 8a67ac57fc test($browser): update MockWindow to normalize URLs similar to real window.location 2018-11-26 14:50:39 +01:00
Pete Bacon Darwin 90a41d415c fix(interpolate): do not create directives for constant media URL attributes
By creating attribute directives that watch the value of
media url attributes (e.g. `img[src]`) we caused a conflict
when both `src` and `data-src` were appearing on the
same element. As each directive was trying to write to the
attributes on the element, where AngularJS treats `src` and
`data-src` as synonymous.

This commit ensures that we do not create create such directives
when the media url attribute is a constant (no interpolation).

Because of this (and because we no longer sanitize URLs in the
`$attr.$set()` method, this commit also updates `ngHref` and
`ngSrc` to do a preliminary sanitization of URLs in case there
is no interpolation in the attribute value.

Fixes #16734
2018-11-20 14:12:22 +00:00
Volker Braun eefaa76a90 fix($q): allow third-party promise libraries
For testing, it can be useful to overwrite `$q` with other promise
implementions, such as Bluebird + angular-bluebird-promises. This broke
in v1.6.x with "TypeError: Cannot set property 'pur' of undefined".

Closes #16164

Closes #16471
2018-11-15 17:39:49 +02:00
Alejandro López bc3432365c test(e2e): replace the deprecated browser.getLocationAbsUrl() with browser.getCurrentUrl()
According to angular/protractor#3969, `browser.getLocationAbsUrl()` is
now deprecated and `browser.getCurrentUrl()` should be used instead.

Closes #16053
2018-11-15 17:14:05 +02:00
George Kalpakas f4ac5c8487 docs(tutorial): mention that Protractor might need upgrading
Since Protractor requires specific WebDriver versions and these are only
compatible with specific browser version ranges, it is often necessary
to upgrade Protractor just so that it picks up a more recent WebDriver
version.
Related: #16739

Closes #16753
2018-11-15 16:50:10 +02:00
George Kalpakas 9f2f567167 docs(tutorial): explain how to upgrade dependencies
Related: angular/angular-seed#439
2018-11-15 16:50:10 +02:00
George Kalpakas 3e6f49a227 docs(tutorial): replace getLocationAbsUrl() with getCurrentUrl()
Protractor's `browser.getLocationAbsUrl()` has been deprecated and
`browser.getCurrentUrl()` is the recommended alternative.
Related: angular/angular-phonecat#430
2018-11-15 16:50:09 +02:00
George Kalpakas 795398fab0 docs(tutorial): switch from bower to npm and upgrade AngularJS to 1.7.x
Related: angular/angular-phonecat#430
2018-11-15 16:50:08 +02:00
George Kalpakas f1a34bad20 docs(tutotial): switch all links to https 2018-11-15 16:50:07 +02:00
teresy 84a6ea9eb4 refactor(production): remove duplicate expression
Remove a duplicate expression (the left and right sides both check `versionInfo.currentVersion.version`). [48f0957](https://github.com/angular/angular.js/blob/48f0957dde728b050e2d8f76db81cbf12cffd42a/docs/config/services/deployments/production.js#L18) is the most recent commit I found where these expressions differ. My best guess is the duplicated expression can be removed.

Closes #16738
2018-11-15 16:08:12 +02:00
George Kalpakas ff0ef2aeaf test(ngOn*): add tests for binding to camelCased event names
Closes #16757
2018-11-12 13:19:32 +02:00
George Kalpakas c81e3556e8 test($compile): fix incorrect markup in tests 2018-11-12 13:19:32 +02:00
George Kalpakas 8cc69b9edb chore(i18n): fix UCD extraction for Node 10.x
Previously (e.g. Node.js 8.x), the 3rd argument to `fs.writeFile()`
(i.e. the callback) could be undefined. On Node.js 10.x, this throws an
error.

This commit fixes it by switching to `fs.writeFileSync()` which seems to
have been the original intention (based on the sorrounding code).
2018-11-12 13:19:31 +02:00
George Kalpakas ae8ce3ec60 chore(docs): fix rendering of methods' this type 2018-11-12 13:19:31 +02:00
George Kalpakas df0d5d245e chore(package): fix scripts for Node 10.x on Windows 2018-11-12 13:19:31 +02:00
Daniel Breen 67ec5e8ceb docs(guide/migration): fix typos, change 'ctrk' to 'ctrl'
Closes #16754
2018-11-02 19:35:34 +02:00
Daniel Breen 4df2188e96 docs(changelog): fix typos, change 'ctrk' to 'ctrl' 2018-11-02 19:35:34 +02:00
Hallstein Brøtan 816a587578 docs(guide/Developer Guide): correct broken link
The blog post "Creating multilingual support using AngularJS" has moved. Corrected the URL.

Closes #16746
2018-10-29 11:00:20 +02:00
Michał Gołębiowski-Owczarek 0e1bd7822e fix(urlUtils): make IPv6 URL's hostname wrapped in square brackets in IE/Edge
IE 9-11 and Edge 16-17 (fixed in 18 Preview) incorrectly don't wrap IPv6
addresses' hostnames in square brackets when parsed out of an anchor element.

Fixes #16692
Closes #16715
2018-10-18 11:45:53 +02:00
George Kalpakas b27080d525 fix(ngAnimateSwap): make it compatible with ngIf on the same element
Previously, both `ngAnimateSwap` and `ngIf` had a priority of 600, which
meant that (while both are [terminal directives][1]) they were executed
on top of each other (essentially messing each other's comment node).

This commit fixes it, by giving `ngAnimateSwap` a priority of 550, which
is lower than `ngIf` but still higher than other directives.

For reference, here is a list of built-in directive per priority:

```
-400: ngInclude, ngView
  -1: ngRef
   1: ngMessage, ngMessageDefault, ngMessageExp, ngModel, select
  10: ngModelOptions
  99: ngHref, ngSrc, ngSrcset
 100: attr interpolation, ngChecked, ngDisabled, ngList, ngMax,
      ngMaxlength, ngMin, ngMinlength, ngModel (aria), ngMultiple,
      ngOpen, ngPattern, ngProp*, ngReadonly, ngRequired, ngSelected,
      ngStep, ngValue, option
 400: ngInclude, ngView
 450: ngInit
 500: ngController
 600: ngAnimateSwap, ngIf
1000: ngNonBindable, ngRepeat
1200: ngSwitchDefault, ngSwitchWhen
```

[1]: https://docs.angularjs.org/api/ng/service/$compile#-terminal-

Fixes #16616

Closes #16729
2018-10-15 23:25:45 +03:00
George Kalpakas 1a509873bf refactor(ngAnimateSwap): remove unnecessary inject() from tests 2018-10-15 23:25:12 +03:00
Martin Staffa fead62e958 test(modules): properly isolate module tests
Closes #16712
2018-10-15 15:12:13 +02:00
Martin Staffa e2011bd0b3 docs(ngMock/ngMockE2E.$httpBackend): fix method name to matchLatestDefinitionEnabled
See #16702
2018-10-15 15:12:12 +02:00
Martin Staffa 3cdffcecba fix(ngMock): make matchLatestDefinitionEnabled work
Fixes #16702
2018-10-15 15:12:11 +02:00
Michał Gołębiowski-Owczarek f87d6648d7 chore(*): update Sauce Connect from 4.4.12 to 4.5.1
Sauce Connect 4.5.0 fixes "a major bug in connection state logic that caused
clients to exit prematurely".
See https://wiki.saucelabs.com/display/DOCS/Sauce+Connect+Proxy+Change+Logs
This will possibly improve the stability of our test runs.

Closes #16730
2018-10-15 12:59:28 +02:00
Michał Gołębiowski-Owczarek b1d0a83d01 chore(*): update minimum Yarn version, do some Yarn-related cleanups
Included changes:

*Update minimum Yarn version from 1.3.2 to 1.10.1*

Yarn 1.10 added the integrity field to the lockfile, making newer Yarn users
have their lockfile changed a lot if they run `yarn`. This commit updates the
required Yarn version to be at least 1.10.1 and changes Travis & Jenkins to use
Yarn 1.10.1

*Change the package.json's engines grunt field to grunt-cli*

The grunt field suggested it's the grunt package version we're checking while
we check the grunt-cli version instead.

*Stop separating Yarn script arguments from script names via " -- "*

The " -- " separator is necessary in npm but not in Yarn. In fact, it's
deprecated in Yarn and some future version is supposed to start passing this
parameter directly to the scripts which may break them.

*Don't install grunt-cli globally during the build*

It's enough to use `yarn grunt` instead of `grunt` and the global grunt-cli
installation is no longer needed.

*Use `yarn grunt` instead of `yarn run grunt`*

The former form is shorter.

*Don't define the `grunt` Yarn script*

As opposed to npm, `yarn binName` invokes a binary named `binName` exposed
by the respective package so the `grant` Yarn script is no longer needed.

*Allow Node versions newer than 8; bump the minimum*

Closes #16714
2018-10-11 16:36:49 +02:00
itchyny d6098eeb1c fix(ngStyle): skip setting empty value when new style has the property
Previously, all the properties in oldStyles are set to empty value once.
Using AngularJS with jQuery 3.3.1, this disables the CSS transition as
reported in jquery/jquery#4185.

Closes #16709
2018-10-04 17:03:21 +02:00
Pete Bacon Darwin c903b76f6c docs(changelog): add 1.7.5 release notes 2018-10-04 14:59:37 +01:00
George Kalpakas f3a565872d fix(ngClass): do not break on invalid values
Previously, when an `ngClass` expression evaluated to something that was
not a string, array or object (and was truthy), an error would be thrown
while trying to call `.split()` on a non-string value. This error was
not very helpful for the user to identify the root cause of the problem.

This commit fixes it by ensuring such values are converted to string.

Fixes #16697

Closes #16699
2018-09-20 12:20:50 +03:00
Sibiraj 582b03b983 docs(*): update LTS information in README.md and docs landing page
Closes #16688
2018-09-10 21:00:30 +03:00
Pete Bacon Darwin be240b1176 docs(changelog): add 1.7.4 release notes 2018-09-07 09:57:37 +01:00
Martin Staffa 61b33543ff fix(ngAria.ngClick): preventDefault on space/enter only on non-interactive elements
Fixes #16664
Closes #16680
2018-09-06 15:59:19 +02:00
Martin Staffa 1dcba9cd88 chore(benchpress): add ngRepeat animation benchmark
Closes #13976
2018-09-06 15:46:25 +02:00
Michał Gołębiowski-Owczarek 8cd54d7794 docs(version-support-status): remove outdated info, resolve inconsistencies
Closes #16684
2018-09-06 15:42:24 +02:00
Martin Staffa 3105b2c26a fix(ngAnimate): remove prepare classes with multiple structural animations
Closes #16681
Closes #16677
2018-09-06 15:42:18 +02:00
Craig Johnson bc5a48d4a4 docs(guide): grammar correction in security guide
Closes #16683
2018-09-06 15:42:00 +02:00
George Kalpakas 2bbc7c464f refactor(ngMocks): simplify routeToRegExp by assuming path has query/hash stripped off
Closes #16672
2018-08-26 00:00:03 +03:00
George Kalpakas e85f91d582 refactor(ngMocks): clean up MockHttpExpectation 2018-08-26 00:00:01 +03:00
George Kalpakas 862a78dfd2 refactor(ngMocks): ignore query/hash when extracting path params for MockHttpExpectation 2018-08-25 23:59:59 +03:00
George Kalpakas bd772abf34 refactor(ngMocks): clean up MockHttpExpectation#params() 2018-08-25 23:59:57 +03:00
George Kalpakas b074d719ae refactor(ngRoute): do not unnecessarily return originalPath in routeToRegExp 2018-08-25 23:59:56 +03:00
George Kalpakas a43a40b778 test(ngMocks): use correct method name in $httpBackend test 2018-08-25 23:59:54 +03:00
Susisu 2ceeb739f3 fix($route): correctly extract path params if path contains question mark or hash
The `routeToRegExp()` function, introduced by 840b5f0, could not extract
path params if the path contained question mark or hash. Although these
characters would normally be encoded in the path, they are decoded by
`$location.path()`, before being passed to the RegExp returned by
`routeToRegExp()`.

`routeToRegExp()` has to be able to deal with both encoded URL and
decoded path, because it is being shared between `ngRoute` and
`ngMocks`.

This commit fixes the issue, by introducing an `isUrl` option that
allows creating an appropriate RegExp for each usecase.
2018-08-25 23:59:53 +03:00
George Kalpakas fa715abf45 chore(doc-gen): upgrade dgeni-packages to 0.26.5
Related: #16671, angular/dgeni-packages#271
2018-08-23 15:08:29 +03:00
George Kalpakas f943e377e8 docs(angular.copy): fix formatting
Using `<br>` messes formatting (due to a bug in
`dgeni`/`dgeni-packages`). This started breaking in c387e0d79.

Fixes #16671
2018-08-21 11:46:06 +03:00
Martin Staffa 30084c1369 fix(ngHref): allow numbers and other objects in interpolation
Interpolated content in ngHref must be stringified before being passed to $$sanitizeUri by $sce. Before 1.7.x, the sanitization had happened on the already interpolated value inside $compile.

Closes #16652
Fixes #16626
2018-08-20 20:05:20 +02:00
Martin Staffa 668a33da34 fix(select): allow to select first option with value undefined
Previously, the value observer incorrectly assumed a value had changed even if
it was the first time it was set, which caused it to remove an option with
the value `undefined` from the internal option map.

Fixes #16653
Closes #16656
2018-08-08 09:18:10 +02:00
John Mantas 19e2347759 docs(ngRepeat): redundant "and" on line 77
Closes #16657
2018-08-07 16:21:28 +03:00
George Kalpakas f17292e1b5 docs(guide/migration): fix typos, format inline code 2018-08-06 15:52:32 +03:00
Martin Staffa 77b4330011 docs(select): remove solved known issue
The issue in question has been resolved some time in 2017.
The bug report is still open, but the behavior has changed:
https://bugzilla.mozilla.org/show_bug.cgi?id=126379

Let's hope they have tests for this!

Related #9134
2018-08-03 18:20:53 +02:00
Martin Staffa 7717de4c51 docs(CHANGELOG.md): add changes for 1.7.3 2018-08-03 13:35:40 +02:00
Jason Bedard e68697e2e3 fix($location): fix infinite recursion/digest on URLs with special characters
Some characters are treated differently by `$location` compared to `$browser` and
the native browser. When comparing URLs across these two services this must be
taken into account.

Fixes #16592
Closes #16611
2018-08-03 13:12:28 +02:00
Martin Staffa a02ed88279 docs($compile): add docs for ngProp and ngOn bindings
The docs are written as if ngProp and ngOn were regular directives,
which makes them easier to find.

Closes #16627
2018-08-03 12:28:27 +02:00
Jason Bedard a5914c94a8 feat($compile): add support for arbitrary DOM property and event bindings
Properties:

Previously only arbitrary DOM attribute bindings were supported via interpolation such as
`my-attribute="{{expression}}"` or `ng-attr-my-attribute="{{expression}}"`, and only a set of
distinct properties could be bound. `ng-prop-*` adds support for binding expressions to any DOM
properties. For example `ng-prop-foo="x"` will assign the value of the expression `x` to the
`foo` property, and re-assign whenever the expression `x` changes.

Events:

Previously only a distinct set of DOM events could be bound using directives such as `ng-click`,
`ng-blur` etc. `ng-on-*` adds support for binding expressions to any DOM event. For example
`ng-on-bar="barOccured($event)"` will add a listener to the "bar" event and invoke the
`barOccured($event)` expression.

Since HTML attributes are case-insensitive, property and event names are specified in snake_case
for `ng-prop-*` and `ng-on-*`. For example, to bind property `fooBar` use `ng-prop-foo_bar`, to
listen to event `fooBar` use `ng-on-foo_bar`.

Fixes #16428
Fixes #16235
Closes #16614
2018-08-03 12:28:17 +02:00
Jason Bedard 63c9c9e8d7 refactor($compile): move img[srcset] sanitizing to helper method 2018-08-03 12:28:08 +02:00
Georgii Dolzhykov 4adbf82a84 fix(ngMock): pass failed HTTP expectations to $exceptionHandler
This was only partially fixed in f18dd2957.

Closes #16644
2018-07-31 14:36:33 +03:00
George Kalpakas 1144b1eccb fix($location): avoid unnecessary $locationChange* events due to empty hash
Fixes #16632

Closes #16636
2018-07-30 23:39:46 +03:00
George Kalpakas 8970087e58 test($location): add assertion 2018-07-30 23:39:45 +03:00
George Kalpakas 131e62a819 refactor($browser): correctly export helper used in specs
The helper is used in `fakeWindow.location.hash`. ATM, no test is using
the `hash` getter, so there were no errors.
2018-07-30 23:39:44 +03:00
George Kalpakas 2fad638237 refactor($location): remove unnecessary capturing group in RegExp 2018-07-30 23:39:44 +03:00
George Kalpakas a0940895a2 refactor($location): minor changes (unused deps, exported globals, unused deps, etc) 2018-07-30 23:39:43 +03:00
Martin Staffa 0a1db2ad5f fix(Angular): add workaround for Safari / Webdriver problem
Closes #16645
2018-07-28 13:50:25 +03:00
George Kalpakas 4bd4246906 fix($animate): avoid memory leak with $animate.enabled(element, enabled)
When disabling/enabling animations on a specific element (via
`$animate.enabled(element, enabled)`), the element is added in a map to
track its state. Previously, the element was never removed from the map,
causing AngularJS to hold on to the element even after it is removed
from the DOM, thus preventing it from being garbage collected.

This commit fixes it by removing the element from the map on `$destroy`.

Fixes #16637.

Closes #16649
2018-07-27 20:48:38 +03:00
Martin Staffa 05ac702bc7 fix($compile): use correct parent element when requiring on html element
Fixes #16535
Closes #16647
2018-07-27 17:11:16 +02:00
Martin Staffa 6882113bc1 fix(ngEventDirs): pass error in handler to $exceptionHandler when event was triggered in a digest
This ensures that the error handling is the same for events triggered inside and outside a digest.
2018-07-25 13:39:33 +02:00
Mark Gardner 535ee32a0b fix(ngEventDirs): don't wrap the event handler in $apply if already in $digest
Digest cycle already in progress error can inadvertently be caused when triggering an
element's click event while within an active digest cycle. This is due to the ngEventsDirs
event handler always calling $rootScope.$apply regardless of the status of $rootScope.$$phase.
Checking the phase and calling the function immediately if within an active digest cycle
will prevent the problem without reducing current functionality.

Closes #14673
Closes #14674
2018-07-25 13:39:29 +02:00
George Kalpakas 7cf4a2933c fix(angular.element): do not break on cleanData() if _data() returns undefined
This shouldn't happen in supported jQuery versions (2+), but if someone
uses the unsupported 1.x version the app will break. The change that
causes this new behavior was introduced in b7d396b8b.

Even though jQuery 1.x is not supported, it is worth avoiding the
unnecessary breakage (given how simple).

Fixes #16641

Closes #16642
2018-07-23 14:22:11 +03:00
George Kalpakas 7dd6c87eec docs(browserTrigger): document eventData.data property 2018-07-22 19:09:50 +03:00
George Kalpakas 17f963c5d8 docs($route): fix typo (inluding --> including) 2018-07-22 18:45:49 +03:00
Jason Bedard ba09ba5344 refactor($location): move repeated path normalization code into helper method (#16618)
Closes #16618
2018-07-22 18:01:03 +03:00
George Kalpakas 8c36a43e91 docs(ngMock/$interval.flush): fix param type (not optional)
Closes #16640
2018-07-22 17:33:16 +03:00
George Kalpakas af14d67b84 chore(saucelabs): upgrade sauce-connect to latest version
Closes #16639
2018-07-21 13:40:35 +03:00
George Kalpakas c8acff1cdc chore(karma): upgrade karma and related dependencies to latest versions 2018-07-21 13:40:34 +03:00
George Kalpakas 876e9842a2 docs(ngMocks): fix type for $flushPendingTasks/$verifyPendingsTasks
Closes #16638
2018-07-21 10:47:01 +03:00
George Kalpakas 5cb9465093 docs(ngMock/$timeout): deprecate flush() and verifyNoPendingTasks()
Closes #16603
2018-07-13 13:37:22 +03:00
George Kalpakas 58f9413ad3 docs(ngMock/$timeout): recommend $verifyNoPendingTasks() when appropriate
For historical reasons, `$timeout.verifyNoPendingTasks()` throws if
there is any type of task pending (even if it is not a timeout). When
calling `$timeout.verifyNoPendingTasks()`, the user is most likely
interested in verifying pending timeouts only, which is now possible
with `$verifyNoPendingTasks('$timeout')`.

To raise awareness of `$verifyNoPendingTasks()`, it is mentioned in the
error message thrown by `$timeoutverifyNoPendingTasks()` if none of the
pending tasks is a timeout.
2018-07-13 13:37:20 +03:00
George Kalpakas 6f7674a7d0 feat(ngMock): add $flushPendingTasks() and $verifyNoPendingTasks()
`$flushPendingTasks([delay])` allows flushing all pending tasks (or up
to a specific delay). This includes `$timeout`s, `$q` promises and tasks
scheduled via `$rootScope.$applyAsync()` and `$rootScope.$evalAsync()`.
(ATM, it only flushes tasks scheduled via `$browser.defer()`, which does
not include `$http` requests and `$route` transitions.)

`$verifyNoPendingTasks([taskType])` allows verifying that there are no
pending tasks (in general or of a specific type). This includes tasks
flushed by `$flushPendingTasks()` as well as pending `$http` requests
and in-progress `$route` transitions.

Background:
`ngMock/$timeout` has `flush()` and `verifyNoPendingTasks()` methods,
but they take all kinds of tasks into account which is confusing. For
example, `$timeout.verifyNoPendingTasks()` can fail (even if there are
no pending timeouts) because of an unrelated pending `$http` request.

This behavior is retained for backwards compatibility, but the new
methods are more generic (and thus less confusing) and also allow
more fine-grained control (when appropriate).

Closes #14336
2018-07-13 13:37:17 +03:00
George Kalpakas 8dc153db75 refactor($browser): share task-tracking code between $browser and ngMock/$browser
This avoids code/logic duplication and helps the implementations stay
in-sync.
2018-07-13 13:37:15 +03:00
George Kalpakas 4a6f0996f6 refactor($interval): share code between $interval and ngMock/$interval
This avoids code/logic duplication and helps the implementations stay
in-sync.
2018-07-13 13:37:12 +03:00
George Kalpakas 522d581fc9 refactor(ngMock/$interval): more closely follow actual $interval's internal implementation 2018-07-13 13:36:38 +03:00
George Kalpakas 17b139f107 feat(*): implement more granular pending task tracking
Previously, all pending async tasks (tracked via `$browser`) are treated
the same. I.e. things like `$$testability.whenStable()` and
`ngMock#$timeout.verifyNoPendingTasks()` take all tasks into account.

Yet, in some cases we might be interested in specific tasks only. For
example, if one wants to verify there are no pending `$timeout`s, they
don't care if there are other pending tasks, such as `$http` requests.
Similarly, one might want to get notified when all `$http` requests have
completed and does not care about pending promises.

This commit adds support for more granular task tracking, by enabling
callers to specify the type of task that is being added/removed from the
queue and enabling listeners to be triggered when specific types of
tasks are completed (even if there are more pending tasks of different
types).

The change is backwards compatible. I.e. calling the affected methods
with no explicit task-type, behaves the same as before.

Related to #14336.
2018-07-13 13:35:50 +03:00
George Kalpakas 10973c3366 fix($compile): work around Firefox DocumentFragment bug
DOM nodes passed to `compilationGenerator()` will eventually be wrapped
in `jqLite`, when the compilation actually happens. In Firefox 60+,
there seems to be a `DocumentFragment`-related bug that sometimes causes
the `childNodes` to be empty at the time the compilation happens.

This commit works around this bug by eagerly wrapping `childNodes` in
`jqLite`.

NOTE:
The wrapped nodes have references to their `DocumentFragment` container.
This is "by design", since we want to be able to traverse the nodes via
`nextSibling` (in order to correctly handle multi-element directives).

Once the nodes are compiled, they will be either moved to a new
container element or the `jqLite` wrapper is release making them
eligible for garbage collection. In both cases, the original
`DocumentFragment` container should be eligible for garbage collection
too.

Fixes #16607

Closes #16615
2018-07-09 21:27:26 +03:00
Martin Staffa fc64e68076 feat($animate): add option data to event callbacks
Closes #12697
Closes #13059
2018-07-09 17:11:24 +02:00
Martin Staffa ac5e92de9b docs($animate): clarify possible options and fired events 2018-07-09 17:11:19 +02:00
Matias Niemelä 0936353e9a perf(ngAnimate): avoid repeated calls to addClass/removeClass when animation has no duration
Background:
ngAnimate writes helper classes to DOM elements to see if animations are defined on them. If many
elements have the same definition, and the same parent, we can cache the definition and skip the
application of the helper classes altogether. This helps particularly with large ngRepeat
collections.

Closes #14165
Closes #14166
Closes #16613
2018-07-05 19:46:11 +02:00
Martin Staffa ed22d2fe7b docs(changelog, guide/Migration): add info about $sce BC in 1.7
Closes #16593
Closes #16622
2018-07-05 19:46:10 +02:00
Martin Staffa a5cfa88630 docs(guide/Using Location): change / remove obsolete information 2018-07-05 19:46:09 +02:00
Martin Staffa bbf74f9994 docs(*): fix headlines 2018-07-05 19:46:09 +02:00
Atef Ben Ali 62ad450d60 docs(guide/component): add missing :
Add `:` to `Components have a well-defined lifecycle` title.

Closes #16620
2018-06-29 11:10:55 +03:00
Martin Staffa faa4b17c86 chore: fix eslint error 2018-06-23 17:57:24 +02:00
Pete Bacon Darwin 4d980a8771 chore(docs-app): ensure ToC links contain the path
Without the path the link is always pointing to the
root page, rather than the current page, which means
that copying the link address or opening the page in
a new tab is broken.

Closes #16608
2018-06-22 21:59:46 +01:00
Ilia Choly 369469b4f3 fix(grunt-utils): correctly detect java 32bit support
Closes #16605
2018-06-20 21:14:19 +03:00
Georgii Dolzhykov be417f2854 fix(ngMock/$httpBackend): correctly ignore query params in {expect,when}Route
Previously, a route definition such as
`$httpBackend.whenRoute('GET', '/route/:id')` matched against a URL with
query params, for example `/route/1?q=foo`, would incorrectly include
the query params in `id`: `{id: '1?q=foo', q: 'foo'}`.

This commit fixes it, so that the extracted `params` will now be:
`{id: '1', q: 'foo'}`.

Fixes #14173

Closes #16589
2018-06-18 19:50:10 +03:00
George Kalpakas 3a517c25f6 fix(ngAria): do not scroll when pressing spacebar on custom buttons
By default, pressing spacebar causes the browser to scroll down.
However, when a native button is focused, the button is clicked instead.

`ngAria`'s `ngClick` directive, sets elements up to behave like buttons.
For example, it adds `role="button"` and forwards `ENTER` and `SPACEBAR`
keypresses to the `click` handler (to emulate the behavior of native
buttons).

Yet, pressing spacebar on such an element, still invokes the default
browser behavior of scrolling down.

This commit fixes this, by calling `preventDefault()` on the keyboard
event, thus preventing the default scrolling behavior and making custom
buttons behave closer to native ones.

Closes #14665

Closes #16604
2018-06-18 18:49:50 +03:00
George Kalpakas 29b8dcf387 refactor(ngAria): clean up accessible actions tests 2018-06-18 18:49:21 +03:00
Martin Staffa c9d1e690aa feat(form.FormController): add $getControls()
Closes #16601
Fixes #14749
Closes #14517
Closes #13202
2018-06-18 16:05:39 +02:00
Martin Staffa a47247b5e0 docs(downloading.ngdoc): remove link to Google CDN overview page
AngularJS is no longer listed on the CDN page, because the available versions
were almost always out of date due to the need to manually update the list
2018-06-15 16:18:14 +02:00
Martin Staffa b682213d72 feat(ngModelOptions): add timeStripZeroSeconds and timeSecondsFormat
Closes #10721
Closes #16510
Closes #16584
2018-06-13 13:20:37 +02:00
George Kalpakas 223cf2b5bb docs(CHANGELOG): add release notes for 1.7.2 2018-06-12 16:34:38 +03:00
George Kalpakas c387e0d79d chore(doc-gen): error on unmatched links
Closes #16597
2018-06-12 14:45:22 +03:00
George Kalpakas cbf74d5d64 docs(*): fix dangling or ambiguous links 2018-06-12 14:45:06 +03:00
George Kalpakas a812327acd revert: refactor($compile): remove preAssignBindingsEnabled leftovers
This reverts commit 8e104ee508.

This internal clean-up turned out to break popular UI libraries (e.g.
`ngMaterial`, `ui-bootstrap`) and cause pain to developers.

Fixes #16594

Closes #16595
2018-06-11 17:09:48 +03:00
George Kalpakas 35fce310e9 docs(CHANGELOG): fix links to issues/PRs 2018-06-08 17:10:08 +03:00
George Kalpakas 93a754a490 docs(CHANGELOG): add release notes for 1.7.1 2018-06-08 16:26:22 +03:00
Georgios Kalpakas 7d9d387195 feat(ngAria): add support for ignoring a specific element
Fixes #14602
Fixes #14672

Closes #14833
2018-06-08 11:23:37 +03:00
Georgios Kalpakas feac52d840 refactor(ngAria): move test helpers inside of closure 2018-06-08 11:23:26 +03:00
Georgios Kalpakas f4f571efdf feat($route): add support for the reloadOnUrl configuration option
Enables users to specify that a particular route should not be reloaded after a
URL change (including a change in `$location.path()`), if the new URL maps to
the same route.
The default behavior is still to always load the matched route when any part of
the URL changes.

Related to #1699, #5860, #14999 (potentially closing the first two).

Fixes #7925

Closes #15002
2018-06-08 11:01:35 +03:00
Martin Staffa a8c263c194 feat(ngMessages): add support for default message
add support for showing default message when a truthy value is not matched by an ng-message directive.

Closes #12008
Closes #12213
Closes #16587
2018-06-06 17:54:59 +02:00
Martin Staffa 3d6c45d76e feat(errorHandlingConfig): add option to exclude error params from url
Specific errors, such as those during nested module loading, can create very long
error urls because the error message includes the error stack. These urls create visual
clutter in the browser console, are often not clickable, and may be rejected
by the docs page because they are simply too long.

We've already made improvements to the error display in #16283, which excludes
the error url from error parameters, which results in cleaner error messages.

Further, modern browsers restrict console message length intelligently.

This option can still be useful for older browsers like Internet Explorer, or
in general to reduce visual clutter in the console.

Closes #14744
Closes #15707
Closes #16283
Closes #16299 
Closes #16591
2018-06-06 17:54:57 +02:00
Martin Staffa bf841d3512 feat(ngRef): add directive to publish controller, or element into scope
Thanks to @drpicox for the original implementation: PR #14080 

Closes #16511
2018-06-06 17:54:52 +02:00
Christian Oliff a1d88457de docs(.editorconfig): change link to use https 2018-06-06 17:54:40 +02:00
Jakub Freisler b011ae9544 docs(ngAnimate): add "animating between value changes" section
Add a section which covers use case when users need to animate upon
a variable's value changes (not between two states).

Refers #16561

Closes #16582
2018-06-05 23:24:52 +03:00
Georgii Dolzhykov 63fdee6b9c docs($httpBackend): headers param of expect* can be function
Closes #16588
2018-06-04 15:18:34 +03:00
Jakub Freisler 257ebbb514 docs(ngAnimate): refactor of ngAnimate docs
- Synced "animation aware" directives tables in API docs and "Animation"
  guide.
- Sorted tables alphabetically.
- Added info about `ngAnimateSwap` directive.

References #16561

Closes #16581
2018-06-02 11:49:37 +03:00
George Kalpakas 2b6c986736 fix(ngModel): do not throw if view value changes on destroyed scope
This could for example happen if updating the value is debounced (either
by asynchronously calling `$setViewValue()` or via `ngModelOptions`).

Fixes #16583

Closes #16585
2018-05-31 12:31:22 +03:00
Georgii Dolzhykov 2da4950406 refactor($compile): remove preAssignBindingsEnabled leftovers
Now that we don't need to support `preAssignBindingsEnabled` (removed in #15782),
complexity introduced in `$controller` by #7645 can be removed.

One difference with the previous implementation is that all non-ES2015-class controller instances
were available on the element before calling their constructors. Now it depends on the relative
order of controllers. Controller constructors shouldn't be used to access other controllers
(e.g. via `$element.controller(directiveName)`). The recommended way is to use the `require`
property of the directive definition object and the life cycle hooks `$onChanges` or `$onInit`.

See
https://docs.angularjs.org/api/ng/service/$compile#-require-
https://docs.angularjs.org/api/ng/service/$compile#life-cycle-hooks

Closes #16580
2018-05-30 23:05:29 +03:00
George Kalpakas 789db83a8a fix($compile): support transcluding multi-element directives
Previously, transcluding multi-element directives (e.g. `foo-start`/`foo-end`)
was not supported on elements with multi-slot transclusion (a `uterdir` error
was thrown).
This commit fixes it by putting the transcluded nodes into a DocumentFragment,
where they can be traversed via `.nextSibling`.

Fixes #15554
Closes #15555
2018-05-26 17:29:46 +02:00
Martin Staffa ce443792c4 docs(ngMockE2E): add docs for $httpBackend.matchLatestDefinitionEnabled()
Closes #16577
2018-05-26 17:29:43 +02:00
Martin Staffa dd47867bfb chore: try ios 11.2 2018-05-26 11:05:27 +02:00
George Kalpakas f2ebb82ba5 refactor(ngModelOptions): fix ng-closure-runner warning
Without this fix `grunt minall` emits the following warning:
> WARNING - Parse error. Non-JSDoc comment has annotations.
> Did you mean to start it with '/**'?

Closes #16575
2018-05-24 13:02:28 +03:00
Martin Staffa 12698755be chore: set ios 11 in saucelabs to 11.3 2018-05-24 00:02:17 +02:00
Martin Staffa f7d7954904 chore: add platform to ios saucelabs 2018-05-24 00:02:13 +02:00
Martin Staffa 62660be328 docs(input[number]): note issue with large number and step validation
Closes #16486 
Closes #16573
2018-05-22 13:10:43 +02:00
Martin Staffa 773f39c934 feat(ngMock, ngMockE2E): add option to match latest definition for $httpBackend request
Closes #16251
Closes #11637
Closes #16560
2018-05-21 13:59:22 +01:00
Pete Bacon Darwin 7d121accdf chore(package.json): update docs app to use latest version of AngularJS 2018-05-21 10:19:44 +01:00
Mohamed amr 10a229ce1b feat(ngCookies): support samesite option
Closes  #16543 
Closes  #16544
2018-05-17 19:02:04 +02:00
Jason Bedard f9d1ca20c3 feat($compile): add one-way collection bindings
Closes #14039
Closes #16553
Closes  #15874
2018-05-17 15:30:39 +02:00
George Kalpakas f6e189dde0 refactor(ngAnimateSwap): simplify scope creation add tests regarding creating/removing scopes
Closes #16565
2018-05-16 22:50:20 +03:00
George Kalpakas c0b01d9123 refactor(ngAnimateSwap): remove usused dependency 2018-05-16 22:49:44 +03:00
Martin Staffa 45879a8c5a docs(CHANGELOG.md): update date for 1.7.0 2018-05-11 10:31:53 +02:00
Martin Staffa fe600c03da docs(CHANGELOG.md): add changes for 1.7.0 2018-05-09 22:30:41 +02:00
Daniel Herman 02c04690da fix($rootScope): don't allow explicit digest calls to affect $evalAsync
Fixes #15127

Closes #15494
2018-05-09 22:33:23 +03:00
Jason Bedard c3d5cc50cc refactor($compile): remove workaround for chrome bug fixed in v50
Closes #16554
2018-05-09 21:29:10 +02:00
Martin Staffa 6f85b3b699 chore(package.json): change distTag to "latest" 2018-05-09 19:40:07 +02:00
Martin Staffa 70b801f326 test(Angular): remove special case for Edge
Edge 17 supports this behavior.

Closes #16558
2018-05-07 18:10:16 +02:00
Martin Staffa 3cf4eed6b5 test($sanitize): exclude elclob test in Edge 17 (#16555)
We don't exclude Edge completely to know if the bug has been fixed
in the next version
2018-05-06 19:34:53 +02:00
George Kalpakas 376804676e docs(migration.ngdoc): add missing breaking changes from #16476
Closes #16557
2018-05-05 13:36:47 +03:00
George Kalpakas e3cb64b9e4 docs(CHANGELOG.md): add missing breaking changes from #16476
Closes #16556
2018-05-05 13:11:07 +03:00
Oscar Busk fb2d3fa15b docs(guide/Components): add link to documentation for component method
Closes #16548
2018-05-03 23:02:29 +02:00
Oscar Busk 0517799a05 docs(angular.Module): improved documentation for component method
Copy improved documentation for component() method from $compileProvider
and add missing object syntax.

Closes #16547
2018-05-03 22:59:41 +02:00
George Kalpakas 627180fb71 fix(input[date]): correctly parse 2-digit years
When parsing a date string value, AngularJS uses `new Date(year, ...)`
to create a Date object and assign it to the model. In the constructor,
2-digit years map to 1900-1999, so the created Date object has the wrong
value for year.
This commit fixes it, by explicitly using `setFullYear()` to set the
year to the correct value, when necessary.

Fixes #16537

Closes #16539
2018-04-27 18:51:58 +03:00
Martin Staffa 841feb0a05 docs(guide/migration): add notes on 1.6 to 1.7 migration
Closes #16474
2018-04-19 10:07:41 +02:00
Martin Staffa b85c70a958 docs(CHANGELOG.md): add changes for 1.7.0-rc.0
Closes #16439
Closes #16514
2018-04-19 10:07:41 +02:00
Martin Staffa b2ed68d723 docs(CHANGELOG.md): update date for 1.6.10 2018-04-17 18:34:13 +02:00
Michał Gołębiowski-Owczarek 5b7e4b4394 chore(*): remove manualLowercase & manualUppercase functions
The `manualLowercase` & `manualUppercase` functions were inspired by Google Caja
code which worked around Java issues where problems with `toLowerCase`
working differently in Turkish locale are well known[1]. In JavaScript
`String#toLowerCase` is defined in the ECMAScript spec and all implementations
are required to lowercase I in the same way, regardless of the current locale.
Differences may (and do) happen only in `String#toLocaleLowerCase`.

The mirroring of the Java workarounds in Caja was needed due to an old Rhino bug.
Rhino is a pre-Nashorn JavaScript interpreter written in Java and it used to
delegate `String.prototype.toLowerCase` to `java.lang.String.toLowerCase`. This
has since been long fixed.

Other libraries doing string normalization, like jQuery or DOMPurify don't
apply special lowercasing logic in a Turkish environment.

Therefore, the `manualLowercase` & `manualUppercase` logic is dead code in
AngularJS and can be removed.

Also, the `manualLowercase` & `manualUppercase` functions are incomplete; they
only lowercase ASCII characters which is different to native
`String#toLowerCase`. Since those functions are used in many places in the
library, they would break a lot of code. For example, the lowercase filter would
not lowercase Ω to ω but leave it as Ω.

[1] https://garygregory.wordpress.com/2015/11/03/java-lowercase-conversion-turkey/

Closes #15890
Ref #11387
2018-04-13 09:43:38 +02:00
Martin Staffa 77f26bddf7 docs(CHANGELOG.md): add changes for 1.6.10 2018-04-12 18:39:35 +02:00
Martin Staffa c8c3de490f docs($compile): add known issues with replace:true
Closes #16523

Related #2573
Related #5695
Related #9837
Related #10612
2018-04-09 10:20:50 +02:00
Martin Staffa 3a2aea78ad fix(input): allow overriding timezone for date input types
This commit also fixes a bug where part of the Date object
was re-used even after the input was emptied.

Fixes #16181
Closes #13382
Closes #16336
2018-04-06 16:40:14 +02:00
Mohamed amr b7bb797e5c fix(input): take timezone into account when validating minimum and maximum date types
Closes #16342
Closes #16390
2018-04-06 11:53:32 +02:00
George Kalpakas 059d4f6118 refactor(urlResolve): return already parsed URLs unchanged
Closes #14890
2018-04-04 21:04:22 +03:00
Georgios Kalpakas 1e90d03077 feat($http): support sending XSRF token to whitelisted origins
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes #7862
2018-04-04 21:04:20 +03:00
Michał Gołębiowski-Owczarek b7d396b8b6 fix(jqLite): make removeData() not remove event handlers
This change aligns jqLite with jQuery.

Fixes #15869
Closes #16512

BREAKING CHANGE:

Before this commit `removeData()` invoked on an element removed its event
handlers as well. If you want to trigger a full cleanup of an element, change:

```js
elem.removeData();
```

to:

```js
angular.element.cleanData(elem);
```

In most cases, though, cleaning up after an element is supposed to be done
only when it's removed from the DOM as well; in such cases the following:

```js
elem.remove();
```

will remove event handlers as well.
2018-04-03 21:49:52 +02:00
Jason Bedard 71d2c147a8 test($parse): add tests for watching one-time array/object literals
Closes #16477
2018-04-03 21:34:32 +02:00
Jason Bedard 4492db3077 test($rootScope): add tests clarifying $watchGroup oldValues behavior
Closes #16024 
Closes #16494
See also #16514
2018-04-03 21:25:52 +02:00
Michał Gołębiowski-Owczarek 09a638559a docs(jqLite): document that append doesn't work well with a multi-node object
Contrary to jQuery jqLite's append doesn't clone elements so will not work
correctly when invoked on a jqLite object containing more than one DOM node.

Refs #11446
Closes #16517
2018-04-03 21:10:12 +02:00
Michał Gołębiowski-Owczarek a8dedf7a01 fix(jqLite): use XHTML-compliant HTML as input for jqLite
Fixes #6917
Closes #16518
2018-04-03 20:58:00 +02:00
Michał Gołębiowski-Owczarek b0815a702e chore(*): stop testing on Edge 15 due to its instability
Edge 15 disconnects from Karma frequently causing extreme build instability.
We are testing on Edge 16 & Edge 17 should be released soon anyway.

Closes #16516
2018-03-28 14:43:45 +02:00
Michał Gołębiowski-Owczarek feee36c8c9 tests(ngMock): remove a broken jqLite cache clearing (#16515)
This commit removes the resetting of `angular.element.cache` in some tests;
this was desynchronizing jqLite.cache & the local jqCache variable and since
some parts of the code use one of them and some the other one, it was breaking
JQLite._data. `angular.element.cache` doesn't even exist when jQuery 2+ is used.

Closes #16515
Refs #16512
2018-03-28 13:20:42 +02:00
Martin Staffa 983e27b628 fix($compile): throw error in $onChanges immediately
This brings it in line with how we throw errors in a digest cycle, 
and also avoids throwing an array.

Closes #15578 
Closes #16492
2018-03-22 10:37:15 +01:00
Giuseppe Scoppino c68b31cb2c docs(guide/Internet Explorer Compatibility): include warnings for usage of 'disabled' attribute
* docs(guide/Internet Explorer Compatibility): Mention 'disabled' attribute

Setting the 'disabled' attribute on an element that has descendant elements has unexpected behavior in Internet Explorer 11.

* Input elements that are descendants have the text content of the 'placeholder' attribute inserted as the value (and it is not removed when typing in the field).
* Select elements that are descendants are disabled.

To avoid this issue, it is important to not set `disabled` or `ng-disabled` on an element that has descendant form elements. Normally these should only be used on actual form controls so the issue would not manifest.

The issue can also appear if a directive/component is named 'disabled' or takes an attribute named 'disabled' as an input/output attribute, so avoid these.

Closes  #16490
Related #15700
2018-03-19 18:02:52 +01:00
Martin Staffa 4b2de4bcbf feat(minErr): strip error url from error parameters
Related https://github.com/angular/angular.js/issues/14744
2018-03-19 17:57:44 +01:00
Martin Staffa 786cb30c61 fix(minErr): update url to https 2018-03-19 17:57:44 +01:00
Martin Staffa c0bc1df3f7 chore(travis): update iOs test browsers
Closes #16493
2018-03-16 16:48:12 +01:00
Martin Staffa 98e0e047b0 docs(ngShow/ngHide): add note about flicker when toggling elements
Related to https://github.com/angular/angular.js/issues/14015

Closes #16489
2018-03-14 22:35:34 +01:00
George Kalpakas a8bef95127 fix($interval): throw when trying to cancel non-$interval promise
Previously, calling `$interval.cancel()` with a promise that was not
generated by a call to `$interval()` would do nothing. This could, for
example, happen when calling `.then()`/`.catch()` on the returned
promise, which creates a new promise, and passing that to
`$interval.cancel()`.
With this commit, `$interval.cancel()` will throw an error if called
with a non-$interval promise, thus surfacing errors that would otherwise
go unnoticed.

Related to #16424.

BREAKING CHNAGE:

`$interval.cancel()` will throw an error if called with a promise that
was not generated by `$interval()`. Previously, it would silently do
nothing.

Before:
```js
var promise = $interval(doSomething, 1000, 5).then(doSomethingElse);
$interval.cancel(promise);  // No error; interval NOT canceled.
```

After:
```js
var promise = $interval(doSomething, 1000, 5).then(doSomethingElse);
$interval.cancel(promise);  // Throws error.
```

Correct usage:
```js
var promise = $interval(doSomething, 1000, 5);
var newPromise = promise.then(doSomethingElse);
$interval.cancel(promise);  // Interval canceled.
```

Closes #16476
2018-03-13 21:20:10 +02:00
George Kalpakas 3365256502 fix($timeout): throw when trying to cancel non-$timeout promise
Previously, calling `$timeout.cancel()` with a promise that was not
generated by a call to `$timeout()` would do nothing. This could, for
example, happen when calling `.then()`/`.catch()` on the returned
promise, which creates a new promise, and passing that to
`$timeout.cancel()`.
With this commit, `$timeout.cancel()` will throw an error if called with
a non-$timeout promise, thus surfacing errors that would otherwise go
unnoticed.

Fixes #16424

BREAKING CHNAGE:

`$timeout.cancel()` will throw an error if called with a promise that
was not generated by `$timeout()`. Previously, it would silently do
nothing.

Before:
```js
var promise = $timeout(doSomething, 1000).then(doSomethingElse);
$timeout.cancel(promise);  // No error; timeout NOT canceled.
```

After:
```js
var promise = $timeout(doSomething, 1000).then(doSomethingElse);
$timeout.cancel(promise);  // Throws error.
```

Correct usage:
```js
var promise = $timeout(doSomething, 1000);
var newPromise = promise.then(doSomethingElse);
$timeout.cancel(promise);  // Timeout canceled.
```
2018-03-13 21:19:45 +02:00
George Kalpakas de94dd4079 style($interval): fix indentation 2018-03-13 21:19:44 +02:00
George Kalpakas a2a8d7e791 style($timeout): fix indentation 2018-03-13 21:19:44 +02:00
Michał Gołębiowski-Owczarek 73c6467f14 fix($cookies): remove the deprecated $cookieStore factory
Closes #16465

BREAKING CHANGE:

The $cookieStore has been removed. Migrate to the $cookies service. Note that
for object values you need to use the `putObject` & `getObject` methods as
`get`/`put` will not correctly save/retrieve them.

Before:
```js
$cookieStore.put('name', {key: 'value'});
$cookieStore.get('name'); // {key: 'value'}
$cookieStore.remove('name');
```

After:
```js
$cookies.putObject('name', {key: 'value'});
$cookies.getObject('name'); // {key: 'value'}
$cookies.remove('name');
```
2018-03-13 09:31:15 +01:00
George Kalpakas 6e55b890de docs(input[radio]): explain what happens with same name on multiple inputs
Closes #15009

Closes #16478
2018-03-12 16:30:31 +02:00
Martin Staffa 64c23e4d9c docs($http): move response object documentation into Usage section 2018-03-07 10:40:02 +01:00
Martin Staffa 7e2e235cf2 fix($http): set correct xhrStatus in response when using 'timeout'
This correctly sets "timeout" if a request fails because the timeout
(numerical or $timeout) is exceeded,
and "abort" if the request is aborted by resolving a promise that was passed in.
2018-03-07 10:40:02 +01:00
Martin Staffa 4f4ad3cad4 chore(docs.angularjs.org): add csp headers for csp example
Fixes #16270
2018-03-01 12:52:12 +01:00
Martin Staffa a37f89f864 chore(docs-app): add dynamic 404 behavior
Adapted from https://github.com/angular/angular/commit/88045a50506adfe32c2f7a213c8e95f46d1e40e1,
https://github.com/angular/angular/commit/c3fb820473d64036ef0dd3d4c004cc7fbc67be75,
and https://github.com/angular/angular/commit/5a624fa1be530a1b3479a4cc7f96e5a20a3d64fb.
2018-03-01 12:52:12 +01:00
Martin Staffa 02fb980de6 chore(docs.angularjs.org): only deploy production index.html as entry file
Previously, we rewrote index.html to index-production.html, but Firebase ignored
this, probably because an exact file match always takes priority. This lead
to the problem thatthe root - angularjs.org - didn't include the angular.js source
files from the CDN
2018-03-01 12:52:12 +01:00
Martin Staffa 77917e34c9 chore(docs.angularjs.org): allow crawling of examples, don't deploy e2e test files 2018-03-01 12:52:12 +01:00
Martin Staffa 290a5f2339 docs(tutorial): fix headlines 2018-02-27 17:41:13 +01:00
Frederik Prijck 719e66b38b docs(README): fix incorrect version-support-status link (#16473)
Closes #16472
2018-02-26 15:00:42 +01:00
George Kalpakas c0adcc3a4b refactor($compile): avoid catastrophic backtracking when parsing bindings
This isn't expected to have any actual impact, since AngularJS is only
intended to be used in the browser (not the server) and for this RegExp
to be exploited by malicious user code the developer would have to have
to give the user rights to execute arbitrary JavaScript code anyway.
Fixing as a general good practice and to avoid encouraging use of a
similar RegExp in other environments where it might actually matter.

Closes #16464
2018-02-21 11:46:22 +02:00
Pete Bacon Darwin 33b251d55e docs(misc): add version-support-status page (#16460)
Closes #16058
Closes #16458
2018-02-21 08:33:28 +00:00
George Kalpakas ea0585773b fix($resource): fix interceptors and success/error callbacks
Previously, action-specific interceptors and `success`/`error` callbacks
were executed in inconsistent relative orders and in a way that did not
meet the general expectation for interceptor behavior (e.g. ability to
recover from errors, performing asynchronous operations, etc).

This commit fixes the behavior to make it more consistent and expected.
The main differences are that `success`/`error` callbacks will now be
run _after_ `response`/`responseError` interceptors complete (even if
interceptors return a promise) and the correct callback will be called
based on the result of the interceptor (e.g. if the `responseError`
interceptor recovers from an error, the `success` callback will be
called).
See also https://github.com/angular/angular.js/issues/9334#issuecomment-364650642.

This commit also replaces the use of `success`/`error` callbacks in the
docs with using the returned promise.

Fixes #6731
Fixes #9334
Closes #6865

Closes #16446

BREAKING CHANGE:

If you are not using `success` or `error` callbacks with `$resource`,
your app should not be affected by this change.

If you are using `success` or `error` callbacks (with or without
response interceptors), one (subtle) difference is that throwing an
error inside the callbacks will not propagate to the returned
`$promise`. Therefore, you should try to use the promises whenever
possible. E.g.:

```js
// Avoid
User.query(function onSuccess(users) { throw new Error(); }).
  $promise.
  catch(function onError() { /* Will not be called. */ });

// Prefer
User.query().
  $promise.
  then(function onSuccess(users) { throw new Error(); }).
  catch(function onError() { /* Will be called. */ });
```

Finally, if you are using `success` or `error` callbacks with response
interceptors, the callbacks will now always run _after_ the interceptors
(and wait for them to resolve in case they return a promise).
Previously, the `error` callback was called before the `responseError`
interceptor and the `success` callback was synchronously called after
the `response` interceptor. E.g.:

```js
var User = $resource('/api/users/:id', {id: '@id'}, {
  get: {
    method: 'get',
    interceptor: {
      response: function(response) {
        console.log('responseInterceptor-1');
        return $timeout(1000).then(function() {
          console.log('responseInterceptor-2');
          return response.resource;
        });
      },
      responseError: function(response) {
        console.log('responseErrorInterceptor-1');
        return $timeout(1000).then(function() {
          console.log('responseErrorInterceptor-2');
          return $q.reject('Ooops!');
        });
      }
    }
  }
});
var onSuccess = function(value) { console.log('successCallback', value); };
var onError = function(error) { console.log('errorCallback', error); };

// Assuming the following call is successful...
User.get({id: 1}, onSuccess, onError);
  // Old behavior:
  //   responseInterceptor-1
  //   successCallback, {/* Promise object */}
  //   responseInterceptor-2
  // New behavior:
  //   responseInterceptor-1
  //   responseInterceptor-2
  //   successCallback, {/* User object */}

// Assuming the following call returns an error...
User.get({id: 2}, onSuccess, onError);
  // Old behavior:
  //   errorCallback, {/* Response object */}
  //   responseErrorInterceptor-1
  //   responseErrorInterceptor-2
  // New behavior:
  //   responseErrorInterceptor-1
  //   responseErrorInterceptor-2
  //   errorCallback, Ooops!
```
2018-02-20 15:55:15 +02:00
Pete Bacon Darwin 8b399545a5 docs($route): fix typo in error message 2018-02-20 14:04:25 +01:00
Pete Bacon Darwin b87c6a6d4d test(*): fix references to tpload minerr in tests 2018-02-20 14:04:25 +01:00
Pete Bacon Darwin c617d6dcee fix($templateRequest): give tpload error the correct namespace
BREAKING CHANGE

Previously the `tpload` error was namespaced to `$compile`. If you have
code that matches errors of the form `[$compile:tpload]` it will no
longer run. You should change the code to match
`[$templateRequest:tpload]`.
2018-02-20 10:25:33 +00:00
Pete Bacon Darwin 56b6ba8e0b docs($route): add missing error document 2018-02-19 19:37:26 +00:00
Pete Bacon Darwin f1c164c92f docs($parse): add missing error documents 2018-02-19 19:31:43 +00:00
Martin Staffa 3eabaab009 chore(docs.angularjs.org): allow crawling but not indexing of partials/
The sitemap.xml might also prevent the indexing, as the partials are not
listed.

Related to #16432 
Closes #16457
2018-02-15 14:37:24 +01:00
Martin Staffa 9645a08b61 chore(docs.angularjs.org): allow robots access to js files
Related to #16432
2018-02-15 14:36:50 +01:00
Michał Gołębiowski-Owczarek 04ee1e781b docs(*): add CODE_OF_CONDUCT.md
Closes #16456
2018-02-15 14:28:47 +01:00
George Kalpakas a126b346ff chore(travis): fix ROOT_DIR path when build.sh is sourced 2018-02-13 02:21:22 +02:00
George Kalpakas ba140dbff9 chore(docs.angularjs.org): install firebase dependencies before deploying
Firebase is trying to execute our functions code locally in order to
parse the triggers. Install npm dependencies to avoid errors like:

```
Error: Error parsing triggers: Cannot find module 'firebase-functions'
```

Closes #16453
2018-02-13 01:36:22 +02:00
George Kalpakas fb479188f5 chore(docs.angular.js): do not break when deploying
Follow-up to #16451.

Closes #16452
2018-02-12 23:18:52 +02:00
Martin Staffa 75bf199421 chore(docs.angularjs.org): serve snapshots for googlebot
This commit restores serving the plain partials (content) when a docs
page is accessed with ?_escaped_fragment_=.
The Google Ajax Crawler accesses these urls when the page has
`<meta type="fragment" content="!">` is set.

During the migration to Firebase, this was lost, which resulted in Google
dropping the docs almost completely from the index.

We are using a Firebase cloud function to serve the partials. Since
we cannot access the static hosted files from the function, we have to
deploy them as part of the function directory instead, from which they
can be read.

Related to #16432
Related to #16417
2018-02-12 14:34:06 +01:00
Martin Staffa 9196c80c33 chore(deploy): rename deploy folders 2018-02-12 14:34:06 +01:00
Martin Staffa e1e2100e66 chore(code.angularjs.org): don't gzip compressed image files 2018-02-12 14:34:06 +01:00
Martin Staffa 9f1793fd2d chore(eslint): allow ES6 for node scripts 2018-02-12 14:34:06 +01:00
George Kalpakas a7a9688962 fix(docs): fix @media breakpoints for small/extra small devices
Previously, our custom styles used `@media` breakpoints for
small/extra small devices that were off-by-one from
[Bootstrap breakpoints](https://getbootstrap.com/docs/3.3/css/#responsive-utilities-classes)
(767px vs 768px). This caused the site to not be displayed correctly on
these exact sizes, which affected for example all iPad devices (whose
screens are exactly 768px wide).

This commit fixes it by making our breakpoints match those of Bootstrap.

Fixes #16448

Closes #16449
2018-02-11 21:22:15 +02:00
Martin Staffa 32b1a0c580 chore(docs.angularjs.org): actually fix deployment
When a file is symlinked, relative paths obviously aren't correct anymore.
This error was masked because Travis didn't fail the job when Firebase
couldn't find the public folder.
To fix, we copy the file and adjust the folder path
2018-02-09 00:31:48 +01:00
Martin Staffa 9a0f1abdda chore(docs.angularjs.org): deploy sitemap.xml
Closes #16445
2018-02-08 23:50:45 +01:00
Martin Staffa c484213180 test(input): add test for IE composition bug 2018-02-08 23:50:07 +01:00
Jae Ik Lee 2789ccbcf9 fix(input): fix composition mode in IE for Korean input
Fixes #6656
Closes #16273
2018-02-08 23:50:07 +01:00
Martin Staffa 3e7a87d7d1 fix(browserTrigger): support CompositionEvent 2018-02-08 23:50:07 +01:00
Martin Staffa 3ecb00115a chore(docs.angularjs.org): serve xml files (sitemap) 2018-02-08 18:56:59 +01:00
Martin Staffa e4e2024d1c chore(code.angularjs.org): increase the cache duration
This is already set, but wasn't checked in
2018-02-08 18:54:25 +01:00
frederikprijck 02f4ca4887 docs(ngClass): add docs regarding animation for ngClassEven and ngClassOdd
Previously, the documentation has no information regarding using
`ngAnimate` together with the `ngClassEven` and `ngClassOdd` directives.

This commit adds the same docs used by the `ngClass` directive to the
`ngClassEven` and `ngClassOdd` docs and adds an extra example for both
`ngClassEven` and `ngClassOdd` that showcases animations.

Closes #15654
2018-02-06 21:55:29 +02:00
Maksim Ryzhikov 8d6ac5f317 feat($sanitize): support enhancing elements/attributes white-lists
Fixes #5900
Closes #16326
2018-02-06 16:07:49 +02:00
Martin Staffa 7d50b2e9ee chore(docs.angularjs.org): allow robots to access js and css
Otherwise, the google bot cannot execute the JS
2018-02-05 17:52:34 +01:00
Martin Staffa ea04dbb229 chore(code.angularjs.org): fix robots.txt
- allow all-versions-data.js in snapshot, which is used by docs.angularjs.org
- disallow access to folders like docs-0.9.2 etc which are used by early versions
2018-02-05 17:52:34 +01:00
Martin Staffa fbe679dfbc chore(doc-gen): generate sitemap.xml 2018-02-05 17:52:34 +01:00
frederikprijck fb00991460 fix($templateRequest): always return the template that is stored in the cache
Previously, `$templateRequest` returned the raw `$http` response data on the
first request for a template and then the value from the cache for subsequent
requests.

If the value is transformed when being added to the cache (by decorating
`$templateCache.put`)  the return value of `$templateRequest` would be
inconsistent depending upon when the request is made.

This commit ensures the cached value is returned instead of the raw `$http`
response data, thus allowing the `$templateCache` service to be decorated.

Closes #16225
2018-02-05 11:21:28 +00:00
Martin Staffa d3bffc5476 chore(docs.angularjs.org): add robots.txt 2018-02-02 13:55:13 +01:00
Martin Staffa b969c3e354 docs(changelog): add changes for 1.6.9 2018-02-02 13:55:11 +01:00
Martin Staffa 16b82c6afe fix($animate): let cancel() reject the runner promise
Closes #14204
Closes #16373

BREAKING CHANGE:

$animate.cancel(runner) now rejects the underlying
promise and calls the catch() handler on the runner
returned by $animate functions (enter, leave, move,
addClass, removeClass, setClass, animate).
Previously it would resolve the promise as if the animation
had ended successfully.

Example:

```js
var runner = $animate.addClass('red');
runner.then(function() { console.log('success')});
runner.catch(function() { console.log('cancelled')});

runner.cancel();
```

Pre-1.7.0, this logs 'success', 1.7.0 and later it logs 'cancelled'.
To migrate, add a catch() handler to your animation runners.
2018-02-02 10:02:06 +01:00
Georgii Dolzhykov e3ece2fad9 feat(isArray): support Array subclasses in angular.isArray()
Closes #15533
Closes #15541

BREAKING CHANGE:

Previously, `angular.isArray()` was an alias for `Array.isArray()`.
Therefore, objects that prototypally inherit from `Array` where not
considered arrays. Now such objects are considered arrays too.

This change affects several other methods that use `angular.isArray()`
under the hood, such as `angular.copy()`, `angular.equals()`,
`angular.forEach()`, and `angular.merge()`.

This in turn affects how dirty checking treats objects that prototypally
inherit from `Array` (e.g. MobX observable arrays). AngularJS will now
be able to handle these objects better when copying or watching.
2018-02-01 23:06:03 +02:00
Martin Staffa 67f54b6600 fix(ngTouch): deprecate the module and its contents
Closes #16427
Closes #16431
2018-02-01 10:31:32 +01:00
Martin Staffa 3fc6843528 chore(code.angularjs.org): improve output of directory listing 2018-01-31 18:01:10 +01:00
Pete Bacon Darwin 1e9eadcd72 feat($sce): handle URL sanitization through the $sce service
Thanks to @rjamet for the original work on this feature.

This is a large patch to handle URLs with the $sce service, similarly to HTML context.

Where we previously sanitized URL attributes when setting attribute value inside the
`$compile` service, we now only apply an `$sce` context requirement and leave the
`$interpolate` service to deal with sanitization.

This commit introduces a new `$sce` context called `MEDIA_URL`, which represents
a URL used as a source for a media element that is not expected to execute code, such as
image, video, audio, etc.
The context hierarchy is setup so that a value trusted as `URL` is also trusted in the
`MEDIA_URL` context, in the same way that the a value trusted as `RESOURCE_URL` is also
trusted in the `URL` context (and transitively also the `MEDIA_URL` context).

The `$sce` service will now automatically attempt to sanitize non-trusted values that
require the `URL` or `MEDIA_URL` context:

* When calling `getTrustedMediaUrl()` a value that is not already a trusted `MEDIA_URL`
will be sanitized using the `imgSrcSanitizationWhitelist`.
* When calling `getTrustedUrl()` a value that is not already a trusted `URL` will be
sanitized using the `aHrefSanitizationWhitelist`.

This results in behaviour that closely matches the previous sanitization behaviour.

To keep rough compatibility with existing apps, we need to allow concatenation of values
that may contain trusted contexts. The following approach is taken for situations that
require a `URL` or `MEDIA_URL` secure context:

* A single trusted value is trusted, e.g. `"{{trustedUrl}}"` and will not be sanitized.
* A single non-trusted value, e.g. `"{{ 'javascript:foo' }}"`, will be handled by
  `getTrustedMediaUrl` or `getTrustedUrl)` and sanitized.
* Any concatenation of values (which may or may not be trusted) results in a
  non-trusted type that will be handled by `getTrustedMediaUrl` or `getTrustedUrl` once the
  concatenation is complete.
  E.g. `"javascript:{{safeType}}"` is a concatenation of a non-trusted and a trusted value,
  which will be sanitized as a whole after unwrapping the `safeType` value.
* An interpolation containing no expressions will still be handled by `getTrustedMediaUrl` or
  `getTrustedUrl`, whereas before this would have been short-circuited in the `$interpolate`
  service. E.g. `"some/hard/coded/url"`. This ensures that `ngHref` and similar directives
  still securely, even if the URL is hard-coded into a template or index.html (perhaps by
  server-side rendering).

BREAKING CHANGES:

If you use `attrs.$set` for URL attributes (a[href] and img[src]) there will no
longer be any automated sanitization of the value. This is in line with other
programmatic operations, such as writing to the innerHTML of an element.

If you are programmatically writing URL values to attributes from untrusted
input then you must sanitize it yourself. You could write your own sanitizer or copy
the private `$$sanitizeUri` service.

Note that values that have been passed through the `$interpolate` service within the
`URL` or `MEDIA_URL` will have already been sanitized, so you would not need to sanitize
these values again.
2018-01-31 13:12:29 +00:00
Dmitriy a8830d2be4 feat(input): add drop event support (#16420) 2018-01-28 11:24:00 +00:00
Martin Staffa 8d9984e530 chore(docs-gen): generate list of versions in correct order
Closes #16419
2018-01-26 12:05:46 +01:00
Frederik Prijck 1d804645f7 feat(orderBy): consider null and undefined greater than other values
Previously, `null` values where sorted using type `string` resulting in a string
comparison. `undefined` values where compared to other values by type and were
usually considered greater than other values (since their type happens to start
with a `u`), but this was coincidental.

This commit ensures that `null` and `undefined ` values are explicitly
considered greater than other values (with `undefined` > `null`) and will
effectively be put at the end of the sorted list (for ascending order sorting).

Closes #15294

Closes #16376

BREAKING CHANGE:

When using `orderBy` to sort arrays containing `null` values, the `null` values
will be considered "greater than" all other values, except for `undefined`.
Previously, they were sorted as strings. This will result in different (but more
intuitive) sorting order.

Before:
```js
orderByFilter(['a', undefined, 'o', null, 'z']);
//--> 'a', null, 'o', 'z', undefined
```

After:
```js
orderByFilter(['a', undefined, 'o', null, 'z']);
//--> 'a', 'o', 'z', null, undefined
```
2018-01-25 13:16:48 +02:00
Martin Staffa 40c49902b6 docs(*): fix headings and links 2018-01-25 12:12:46 +01:00
Martin Staffa 7300a5311c chore(docs.angularjs.org): fix firebase deploy
Travis looks for the firebase.json in the repo root,
but we moved each firebase project in its own sub-folder.
To fix, we create a symlink before deployment.
2018-01-23 10:31:31 +01:00
Martin Staffa 4c97df5852 chore(code.angularjs.org): don't use trailing slashes, and don't set headers after response was sent 2018-01-19 13:57:26 +01:00
Martin Staffa 2ea1e49cd6 chore(code.angularjs.org): don't gzip the zip file before uploading 2018-01-19 13:57:25 +01:00
Martin Staffa c76b09beed chore(errors.angularjs.org): add project with redirects to docs.angularjs.org 2018-01-19 13:57:09 +01:00
Martin Staffa f9d29889c4 chore(docs.angularjs.org): move project in separate folder
Firebase projects should be in their own folder, because the firebase-tools
search for projects in the parent folder, which makes it more difficult to create
new projects.
2018-01-18 13:35:16 +01:00
Pete Bacon Darwin 50ceb23277 fix(ngMessages): prevent memory leak from messages that are never attached
Closes #16389
Closes #16404
Closes #16406
2018-01-17 14:57:32 +01:00
Martin Staffa ab386cdef2 fix(ngTransclude): remove terminal: true
This was introduced in commit 2adaff083f,
but made obsolete in 41f3269bfb.

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

Closes #16332
Closes #16334 
Closes #16397
2018-01-17 12:01:54 +01:00
Martin Staffa a7e5e83240 docs(*): clarify module API and dependency injection rules
Closes #16363
Closes #16395
2018-01-17 12:00:10 +01:00
Martin Staffa 3f95ae21ef chore(code.angularjs.org): resolve gcs file stream on 'finish'
'response' is called before the data transfer is complete.
2018-01-16 19:49:04 +01:00
Martin Staffa 00b482fd8b chore(docs.angularjs.org): copy unminified angular files
e2e tests use the unminified files even in production deployment
2018-01-16 19:49:04 +01:00
Deb Saunders 9ba3d0070d docs(guide/External Resources): remove link to deprecated content
Content at URL is deprecated.

Closes #16403
2018-01-15 18:26:26 +01:00
Frederik Prijck ddbf197ad9 docs(guide/Animations): fix minor typos
Closes #16409
2018-01-15 13:10:10 +01:00
Manuel Darveau 7a9b7ba913 docs(guide/Using $location): fix typo
Closes #16408
2018-01-15 13:08:24 +01:00
Martin Staffa 62e2ec18e6 chore(node): add karma launchers for Edge, IE, and Safari
That makes it easier to run the tests with these browsers locally.

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

Thanks to Masato Kinugawa at Cure23
2018-01-11 14:34:06 +01:00
Martin Staffa c7bea44107 chore(travis): test on 2 latest Safari versions 2018-01-11 13:29:19 +01:00
Martin Staffa 8510143a0e test(*): fix tests for Safari 10+
The mocksSpec change is due to the following issue in Safari 10+ strict mode:
In the following code, Safari will not use the name of the enclosing function (testCaller)
in the stack, but rather list the anonymous function that is called to inject:

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

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

Fixes #16268
Fixes #14961
Ref yarnpkg/yarn#1483
2018-01-08 13:01:21 +01:00
Martin Staffa 8da3aef91c chore(node): update karma to 2.0.0
Also reduce karma log level on Travis to INFO.
Before, the log level was DEBUG, but it seems that
prior to karma 2.0.0, the debug messages were not outoput on Karma,
so this simply restores the status quo (and prevents cluttering the log).
2018-01-08 10:41:06 +01:00
Martin Staffa 8988157861 chore(node): update jasmine to 2.8.0, and adjust tests 2018-01-08 10:41:06 +01:00
Martin Staffa d253c9d45c test($sanitize): skip nextSibling clobber test on Edge 16
In some circumstances, Edge 16 will not throw on clobbered
elements, because the nextSibling property is null. The exact
cause is currently unknown.
2018-01-08 10:41:06 +01:00
Martin Staffa 07d84dd85f chore(*): update copyright year
Closes #16386
2018-01-05 21:06:09 +01:00
Martin Staffa 88cb9af594 docs(DEVELOPERS.md): improve testing section 2018-01-03 18:19:05 +01:00
Sergey Kryvets e942e1e988 docs(developers.md): update node version as specified in package.json
Closes #16384
2017-12-29 17:48:35 +01:00
Georgii Dolzhykov 96dd35afb6 docs(ngModel.NgModelController): correct description for $viewChangeListeners
It was misleading.

Closes #16382
2017-12-29 14:30:31 +01:00
Frederik Prijck 9a521cb3ad docs(PULL_REQUEST_TEMPLATE.md): fix broken links in PR template
Closes #16377
2017-12-19 18:29:53 +01:00
Georgios Kalpakas 62743a54b7 feat(currencyFilter): trim whitespace around an empty currency symbol
In most locales, this won't make a difference (since they do not have
whitespace around their currency symbols). In locales where there is a
whitespace separating the currency symbol from the number, it makes
sense to also remove such whitespace if the user specified an empty
currency symbol (indicating they just want the number).

Fixes #15018
Closes #15085

Closes #15105
2017-12-19 11:29:33 +02:00
Martin Staffa 22450e5b7c docs(CHANGELOG.md): add changes for 1.6.8 2017-12-18 16:15:06 +01:00
George Kalpakas 240a3ddbf1 feat($resource): add support for request and requestError interceptors (#15674)
This commit adds `request` and `requestError` interceptors for `$resource`, as
per the documentation found for `$http` interceptors. It is important to note
that returning an error at this stage of the request - before the call to
`$http` - will completely bypass any global interceptors and/or recovery
handlers, as those are added to a separate context. This is intentional;
intercepting a request before it is passed to `$http` indicates that the
resource itself has made a decision, and that it accepts the responsibility for
recovery.

Closes #5146

BREAKING CHANGE:

Previously, calling a `$resource` method would synchronously call
`$http`. Now, it will be called asynchronously (regardless if a
`request`/`requestError` interceptor has been defined.

This is not expected to affect applications at runtime, since the
overall operation is asynchronous already, but may affect assertions in
tests. For example, if you want to assert that `$http` has been called
with specific arguments as a result of a `$resource` call, you now need
to run a `$digest` first, to ensure the (possibly empty) request
interceptor promise has been resolved.

Before:
```js
it('...', function() {
  $httpBackend.expectGET('/api/things').respond(...);
  var Things = $resource('/api/things');
  Things.query();

  expect($http).toHaveBeenCalledWith(...);
});
```

After:
```js
it('...', function() {
  $httpBackend.expectGET('/api/things').respond(...);
  var Things = $resource('/api/things');
  Things.query();
  $rootScope.$digest();

  expect($http).toHaveBeenCalledWith(...);
});
```
2017-12-18 12:48:15 +00:00
Martin Staffa 7df29521d8 refactor($location): remove obsolete workaround for Firefox bug
The bug was fixed in Firefox 48: https://bugzilla.mozilla.org/show_bug.cgi?id=684208,
and only affected the scenario runner
2017-12-14 11:50:36 +01:00
Martin Staffa 167766a5dd docs(*): add browserTrigger docs; remove references to scenario runner 2017-12-14 11:50:36 +01:00
Martin Staffa 0cd3921782 fix(ngScenario): completely remove the angular scenario runner
The runner has been deprecated and undocumented since 2014:
See commit 8d6d126899d4b1927360599403a7592011243270

Closes #9405

BREAKING CHANGE:

The angular scenario runner end-to-end test framework has been
removed from the project and will no longer be available on npm
or bower starting with 1.7.0.
It was deprecated and removed from the documentation in 2014.
Applications that still use it should migrate to
[Protractor](http://www.protractortest.org).
Technically, it should also be possible to continue using an
older version of the scenario runner, as the underlying APIs have
not changed. However, we do not guarantee future compatibility.
2017-12-14 11:50:36 +01:00
Martin Staffa f6e60c14c0 docs(ngForm): clarify usage and limitations 2017-12-13 19:23:49 +01:00
Martin Staffa 223de59e98 fix(form): set $submitted to true on child forms when parent is submitted
Closes #10071

BREAKING CHANGE:

Forms will now set $submitted on child forms when they are submitted.
For example:
```
<form name="parentform" ng-submit="$ctrl.submit()">
  <ng-form name="childform">
    <input type="text" name="input" ng-model="my.model" />
  </ng-form>
  <input type="submit" />
</form>

Submitting this form will set $submitted on "parentform" and "childform".
Previously, it was only set on "parentform".

This change was introduced because mixing form and ngForm does not create
logically separate forms, but rather something like input groups.
Therefore, child forms should inherit the submission state from their parent form.
2017-12-13 19:23:49 +01:00
Jason Bedard 5c38fb744e test($rootScope): test recursive event broadcast and emit 2017-12-13 11:45:31 +01:00
Jason Bedard 97d0224ae6 fix($rootScope): fix potential memory leak when removing scope listeners
When removing listeners they are removed from the array but the array size
is not changed until the event is fired again. If the event is never fired
but listeners are added/removed then the array will continue growing.

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

Fixes #16135
Closes #16161
2017-12-13 11:45:31 +01:00
Jason Bedard e5fb92978f revert: fix($rootScope): fix potential memory leak when removing scope listeners
This reverts commit 817ac56719.
2017-12-13 11:45:31 +01:00
Peter Bacon Darwin 41d5c90f17 feat($rootScope): allow suspending and resuming watchers on scope
This can be very helpful for external modules that help making the digest
loop faster by ignoring some of the watchers under some circumstance.
Example: https://github.com/shahata/angular-viewport-watch

Thanks to @shahata for the original implementation.

Closes #5301
2017-12-11 19:48:03 +00:00
Peter Bacon Darwin 2c1e58984b fix($location): always decode special chars in $location.url(value)
The original fix for #16312 included changing how `$location.url(value)`
decoded the special characters passed to it as a setter.
This broke a number of use cases (mostly involving the ui-router).

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

This commit reverts changes to `$location.url(value)` so that encoded
chars will once again be decoded and passed to `$location.path(value)`.
In particular it will convert encoded forward slashes, which changes how
the path is updated, since e.g. `a/b/%2Fc%2Fd` will become `a/b/c/d`.
While this is arguably not "correct", it appears that there are too many
use cases relying upon this behaviour.
2017-12-11 19:41:14 +00:00
Martin Staffa 6d5ef34fc6 fix(ngAria): do not set aria attributes on input[type="hidden"]
This fixes a error found by @edclements  using the Google Accessibility Developer Tools audit.
Input fields of type hidden shouldn't have aria attributes.
https://www.w3.org/TR/html-aria/#allowed-aria-roles-states-and-properties-1

Closes #15113 
Closes #16367

BREAKING CHANGE:

ngAria no longer sets aria-* attributes on input[type="hidden"] with ngModel.
This can affect apps that test for the presence of aria attributes on hidden inputs.
To migrate, remove these assertions.
In actual apps, this should not have a user-facing effect, as the previous behavior 
was incorrect, and the new behavior is correct for accessibility.
2017-12-11 19:27:47 +01:00
John Hampton 00815db8ef docs(ng-model-options): remove extra quotes in example
Remove unnecessary quotes around attribute directive name in the docs example.  This syntax is incorrect.

Closes #16362
2017-12-11 10:55:47 +02:00
Michał Gołębiowski-Owczarek a61c5d382e chore(*): bump Yarn in Jenkins init-node script
Without it Jenkins builds are broken.

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

Closes #16360
Ref angular/angular#20807
Ref angular/angular#20832
2017-12-07 19:26:32 +01:00
Martin Staffa dde520e02a docs(ngModelOptions): fix link text 2017-12-07 11:51:03 +01:00
Jason Bedard 394b185416 refactor($rootScope): consistently use noop as the default $watch listener
Closes #16343
2017-12-05 22:26:20 +01:00
Martin Staffa da72477701 fix(ngModelController): allow $overrideModelOptions to set updateOn
Also adds more docs about "default" events and how to override
ngModelController options.

Closes #16351
Closes #16352
2017-12-05 20:07:45 +01:00
Martin Staffa 74b04c9403 fix(ngModel, input): improve handling of built-in named parsers
This commit changes how input elements use the private $$parserName
property on the ngModelController to name parse errors. Until now,
the input types (number, date etc.) would set $$parserName when
the inputs were initialized, which meant that any other parsers on
the ngModelController would also be named after that type. The
effect of that was that the `$error` property and the `ng-invalid-...`
class would always be that of the built-in parser, even if the custom
parser had nothing to do with it.

The new behavior is that the $$parserName is only set if the built-in
parser is invalid i.e. returns `undefined`.

Also, $$parserName has been removed from input[email] and input[url],
as these types do not have a built-in parser anymore.

Closes #14292
Closes #10076
Closes #16347

BREAKING CHANGE:

*Custom* parsers that fail to parse on input types "email", "url", "number", "date", "month",
"time", "datetime-local", "week", do no longer set `ngModelController.$error[inputType]`, and
the `ng-invalid-[inputType]` class. Also, custom parsers on input type "range" do no
longer set `ngModelController.$error.number` and the `ng-invalid-number` class.

Instead, any custom parsers on these inputs set `ngModelController.$error.parse` and
`ng-invalid-parse`. This change was made to make distinguishing errors from built-in parsers
and custom parsers easier.
2017-12-04 11:17:32 +01:00
Francesco Pipita 2e03aedc85 feat($parse): add a hidden interface to retrieve an expression's AST
This PR adds a new private method to the `$parse` service, `$$getAst`,
which takes an Angular expression as its only argument and returns
the computed AST. This feature is not meant to be part of the public
API and might be subject to changes, so use it with caution.

Closes #16253

Closes #16260
2017-11-30 15:59:30 +02:00
Peter Bacon Darwin 199d888b84 fix($location): decode non-component special chars in Hashbang URLS
Fixes https://github.com/angular/angular.js/pull/16316#issuecomment-347527097
2017-11-30 13:22:38 +00:00
Martin Staffa 8b69d91fff chore(travis): fix deployment condition to include tagged commits
Tagged commits are not considered to belong to any branch.

Closes #16346
2017-11-29 15:45:59 +01:00
jugglinmike 0fa5a37838 docs(ngNonBindable): document effect on the element's directives
The phrase "contents of the current DOM element" may be interpreted either as
inclusive of the DOM element's attributes or as exclusive of the attributes.
This situation concerns markup such as:

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

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

Closes #16338
2017-11-27 13:11:50 +01:00
Martin Staffa 07e475137e docs(CHANGELOG.md): add changes for 1.6.7 2017-11-24 09:31:19 +01:00
Jason Bedard 5838017f26 refactor($rootScope): simplify $emit stopPropagation handling
See https://github.com/angular/angular.js/pull/16293#discussion_r147960028

Closes #16339
2017-11-24 09:25:33 +01:00
Michał Gołębiowski-Owczarek f2f5ac7ce4 chore(*): normalize Vojta's email in .mailmap correctly
Closes #16340
2017-11-22 13:24:56 +01:00
Martin Staffa 55ba44913e feat(ngModelOptions): add debounce catch-all + allow debouncing 'default' only
Closes #15411
Closes #16335

BREAKING CHANGE:

the 'default' key in 'debounce' now only debounces the default event, i.e. the event
that is added as an update trigger by the different input directives automatically.

Previously, it also applied to other update triggers defined in 'updateOn' that
did not have a corresponding key in the 'debounce'.

This behavior is now supported via a special wildcard / catch-all key: '*'.

See the following example:

Pre-1.7:
'mouseup' is also debounced by 500 milliseconds because 'default' is applied:
```
ng-model-options="{
  updateOn: 'default blur mouseup',
  debounce: { 'default': 500, 'blur': 0 }
}
```

1.7:
The pre-1.7 behavior can be re-created by setting '*' as a catch-all debounce value:
```
ng-model-options="{
  updateOn: 'default blur mouseup',
  debounce: { '*': 500, 'blur': 0 }
}
```

In contrast, when only 'default' is used, 'blur' and 'mouseup' are not debounced:
```
ng-model-options="{
  updateOn: 'default blur mouseup',
  debounce: { 'default': 500 }
}
```
2017-11-21 13:50:25 +01:00
Martin Staffa aa3f951330 fix(input[number]): validate min/max against viewValue
This brings the validation in line with HTML5 validation, i.e. what the user has entered
is validated, and not a possibly transformed value.

Fixes #12761
Closes #16325

BREAKING CHANGE

`input[type=number]` with `ngModel` now validates the input for the `max`/`min` restriction against
the `ngModelController.$viewValue` instead of against the `ngModelController.$modelValue`.

This affects apps that use `$parsers` or `$formatters` to transform the input / model value.

If you rely on the $modelValue validation, you can overwrite the `min`/`max` validator from a custom directive, as seen in the following example directive definition object:

```
{
  restrict: 'A',
  require: 'ngModel',
  link: function(scope, element, attrs, ctrl) {
    var maxValidator = ctrl.$validators.max;

    ctrk.$validators.max = function(modelValue, viewValue) {
      return maxValidator(modelValue, modelValue);
    };
  }
}
```
2017-11-17 12:28:03 +01:00
Denys B 12cf994fcc fix($compile): sanitize special chars in directive name
This fixes regression bug
when directive name with preceeding special char
in HTML markup does not match the registered name.
(introduced in https://github.com/angular/angular.js/commit/73050cdda04675bfa6705dc841ddbbb6919eb048)

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

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

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

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

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

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

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

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

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

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

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

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

Closes #16288
2017-11-03 10:13:59 +00:00
Lisa Pfisterer 2c9c3a0784 docs(guide/Unit Testing): change $scope = {} to $scope = $rootScope.$new()
{} will just create an empty object. This will break if the module uses for example $watch or others.
While it's not necessary for this example, it's good general practice.

Closes #16315
2017-11-02 17:23:20 +01:00
Jason Bedard 817ac56719 fix($rootScope): fix potential memory leak when removing scope listeners
Previously the array entry for listeners was set to null but the array size was
not trimmed until the event was broadcasted again (see e6966e05f5).

By keeping track of the listener iteration index globally it can be adjusted if
a listener removal effects the index.

Fixes #16135
Closes #16293

BREAKING CHANGE:

Recursively invoking `$emit` or `$broadcast` with the same event name is
no longer supported. This will now throw a `inevt` minErr.
2017-10-31 21:36:58 -07:00
Martin Staffa 0864f73458 docs($compileProvider): improve strictComponentBindingsEnabled info
Related to #16303 
Closes #16306
2017-10-30 11:23:44 +01:00
Jason Bedard c15c8a1380 test($rootScope): test removal of event listeners during event broadcast 2017-10-27 20:52:30 -07:00
Martin Staffa 9871ada04b chore(travis): tighten up deploy conditions 2017-10-26 14:25:45 +02:00
Martin Staffa 202f1809ad chore(travis): fix deploy conditions
Closes #16296
2017-10-25 10:44:55 +02:00
Martin Staffa 32fbb2e78f chore(travis): split unit test into 'core' and 'jquery'
"unit-core" consists of code+jqlite, module test, and promise A+ tests.
"unit-jquery" is code+jquery
"docs-app" includes unit and e2e tests

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

Closes #16292
2017-10-23 12:53:36 +02:00
Sagir Khan 9ba07e974a docs(tutorial/step_14): replace broken web platform docs link
Replace broken [webplatform-animations][1] link with [mdn-animations][2].

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

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

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

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

Closes #16294
2017-10-23 11:45:05 +03:00
Martin Staffa dfcb5ac1e4 chore(travis): deploy to docs and code when distTag=latest
We now deploy to code.angularjs.org and docs.angularjs.org
when we are on the branch which has distTag=latest set in the
package.json, i.e. the stable branch.

Previously, we deployed to docs only when distTag=latest and
the commit was tagged, and to code only on the master branch.
2017-10-20 13:17:20 +02:00
Martin Staffa 10b48094d7 chore(doc-gen, docs-app): generate "stable snapshot" for distTag=latest
The "stable snapshot" is the current state of the branch that has
distTag=latest, i.e. a preview of the next patch version of the stable branch.
2017-10-20 13:17:20 +02:00
Martin Staffa 0f0a16ec40 chore(travis): remove unnessecary addons
The "Trusty" build environment on Travis includes these addons,
see https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements

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

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

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

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

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

Closes #14045
Closes #16265
2017-10-18 13:29:50 +02:00
Martin Staffa bf758d0bef chore(node): update karma-sauce-launcher
Related to #14961
Closes #16281
2017-10-16 11:51:00 +02:00
Martin Staffa 00936ad12b docs(select.SelectController): fix example
Closes #16271
Closes #16275
2017-10-13 16:57:21 +02:00
Martin Staffa 656c8fa8f2 fix(input): listen on "change" instead of "click" for radio/checkbox ngModels
input[radio] and inout[checkbox] now listen on the change event instead
of the click event. This fixes issue with 3rd party libraries that trigger
a change event on inputs, e.g. Bootstrap 3 custom checkbox / radio button
toggles.
It also makes it easier to prevent specific events that can cause a checkbox / radio
to change, e.g. click events. Previously, this was difficult because the custom click
handler had to be registered before the input directive's click handler.

It is possible that radio and checkbox listened to click because IE8 has
broken support for listening on change, see http://www.quirksmode.org/dom/events/change.html

Closes #4516
Closes #14667
Closes #14685

BREAKING CHANGE:

`input[radio]` and `input[checkbox]` now listen to the "change" event instead of the "click" event.
Most apps should not be affected, as "change" is automatically fired by browsers after "click"
happens.

Two scenarios might need migration:

- Custom click events:

Before this change, custom click event listeners on radio / checkbox would be called after the
input element and `ngModel` had been updated, unless they were specifically registered before
the built-in click handlers.
After this change, they are called before the input is updated, and can call event.preventDefault()
to prevent the input from updating.

If an app uses a click event listener that expects ngModel to be updated when it is called, it now
needs to register a change event listener instead.

- Triggering click events:

Conventional trigger functions:

The change event might not be fired when the input element is not attached to the document. This
can happen in **tests** that compile input elements and
trigger click events on them. Depending on the browser (Chrome and Safari) and the trigger method,
the change event will not be fired when the input isn't attached to the document.

Before:

```js
    it('should update the model', inject(function($compile, $rootScope) {
      var inputElm = $compile('<input type="checkbox" ng-model="checkbox" />')($rootScope);

      inputElm[0].click(); // Or different trigger mechanisms, such as jQuery.trigger()
      expect($rootScope.checkbox).toBe(true);
    });
```

With this patch, `$rootScope.checkbox` might not be true, because the click event
hasn't triggered the change event. To make the test, work append the inputElm to the app's
`$rootElement`, and the `$rootElement` to the `$document`.

After:

```js
    it('should update the model', inject(function($compile, $rootScope, $rootElement, $document) {
      var inputElm = $compile('<input type="checkbox" ng-model="checkbox" />')($rootScope);

      $rootElement.append(inputElm);
      $document.append($rootElement);

      inputElm[0].click(); // Or different trigger mechanisms, such as jQuery.trigger()
      expect($rootScope.checkbox).toBe(true);
    });
```

`triggerHandler()`:

If you are using this jQuery / jqLite function on the input elements, you don't have to attach
the elements to the document, but instead change the triggered event to "change". This is because
`triggerHandler(event)` only triggers the exact event when it has been added by jQuery / jqLite.
2017-10-13 15:39:53 +02:00
Martin Staffa 5462373b5b chore($resource): remove undocumented API
This code has been in the $resource service since 2010, but was
never documented and can therefore be removed. It'll save precious bytes!

Shout-out to @gkalpak for finding this

Closes #16267
2017-10-13 15:36:32 +02:00
Dmitriy 5f76bc6097 feat($sanitize, $compileProvider, linky): add support for the "sftp" protocol in links
Add support for the sftp protocol in the linky filter and the "aHrefSanitizationWhitelist" that is used by $sanitize and can be configured in the $compileProvider.

Closes #16102
2017-10-11 15:10:07 +02:00
Martin Staffa c8d3498708 docs(ngPattern): add option of specifying literal RegExp
Closes #15929
2017-10-11 14:36:05 +02:00
Martin Staffa 2cb0318c1c docs(ngInit): clarify when it's okay to use ngInit
Closes #10489
2017-10-11 14:36:05 +02:00
Martin Staffa 2c8bfd8a08 docs(*): add / correct @-tags; fix headlines; add info
- add / correct `@param`, `@restrict`, `@element`, `@priorìty` to directives
- use `@animations` instead of manual headings
- fix more incorrect h1 headings
- fix incorrectly indented `<examples>`
- add some info to $templateCache and $templateRequest
2017-10-11 14:36:05 +02:00
Martin Staffa e5c6174839 docs(*): fix heading levels; use @example instead of headings
This ensures the doc-gen creates correct headlines and
table of contents entries.
2017-10-05 14:06:08 +02:00
Martin Staffa f05f548546 chore(doc-gen): improve headings for events and examples
The "Events" heading now gets an id (which makes them show in
the table of contents, and their "Parameters" use a heading with
a lower priority (previously it was the same as "Events" itself).

The "@example" tag now generates the heading "Example" if there's
only one, or "Examples" if there are multiple.
2017-10-05 14:06:08 +02:00
Michał Gołębiowski-Owczarek 8166dd40e4 chore(*): add a Git .mailmap with my new name
In this way:
* my past contributions are mapped correctly
* other people's distinct entries are collapsed into one

Closes #16254
2017-10-04 23:24:47 +02:00
Martin Staffa 0822d34b10 refactor(api-pages.scenario.js): remove misleading describe block 2017-10-04 15:48:33 +02:00
Martin Staffa 87273022f2 docs(*): fix heading levels and general clean-up
- docs pages should only have one h1
- docs pages shouldn't skip a h* in the hierarchy
- manual table of contents are no longer necesary
- references to the doc-module-components directive are obsolete
2017-10-04 15:48:33 +02:00
Martin Staffa ddd78bd3e4 chore(docs-app): add table of contents to individual pages 2017-10-04 15:48:33 +02:00
Martin Staffa 05fdf918d9 feat(ngModel.NgModelController): expose $processModelValue to run model -> view pipeline
Closes #3407
Closes #10764
Closes #16237
2017-09-29 13:12:18 +02:00
Trotyl Yu 6eb15cb114 docs(changelog): fix typo
Closes #16242
2017-09-25 17:14:22 +02:00
Peter Bacon Darwin 72a87ceda7 fix(http): do not allow encoded callback params in jsonp requests 2017-09-23 23:14:05 +01:00
George Kalpakas 6d997f56a3 chore(doc-gen): fix script paths in plnkr for examples with deps
Closes #16238
2017-09-22 23:22:56 +03:00
Craig Leyshan 34237f9299 feat($injector): ability to load new modules after bootstrapping
The new method `$injector.loadNewModules(modules)` will add each of the
injectables to the injector and execute all of the config and run blocks
for each module passed to the method.

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

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

Closes #16233
2017-09-21 13:13:42 +02:00
Michał Gołębiowski-Owczarek efaf59f988 chore(jqLite): fix $destroy describe block titles 2017-09-20 14:02:53 +02:00
Marcin Wosinek f18dd2957c fix(ngMock): pass unexpected request failures in $httpBackend to the error handler
Closes #16150
Closes #15855
2017-09-18 21:01:14 +01:00
Jason Bedard 97b00ca497 perf($rootScope): allow $watchCollection use of expression input watching
By adding a $$pure flag to the $watchCollectionInterceptor to shallow
watch all inputs regardless of type when watching an object/array
literal.
2017-09-18 12:50:33 -07:00
Jason Bedard 57280768e1 perf(jqLite): avoid setting class attribute when not changed 2017-09-17 13:28:59 -07:00
Jason Bedard bf60182df1 perf(jqLite): avoid repeated add/removeAttribute in jqLiteRemoveClass
Fixes #16078
Closes #16131
2017-09-17 13:28:59 -07:00
Fengwei Wang 8f61cf631a docs(guide/bootstrap): fix typo ('There a few things' --> 'There are a few things')
Closes #16221
2017-09-11 14:36:21 +03:00
melbourne2991 21a2f4bb23 docs(input[checkbox]): fix @param type for ngChange
Closes #16219
2017-09-07 15:44:19 +03:00
Martin Staffa 20590c0bd0 fix(ngAnimate): don't close animations when child transitions close 2017-09-06 16:16:55 +02:00
Martin Staffa 2f7fad5f9f fix(ngMock.browserTrigger): add 'bubbles' to Transition/Animation Event
When the event objects are created synthetically, the bubbles property is set to false
if not explicitly defined
2017-09-06 16:16:55 +02:00
Yonatan Kra ecc09a45f0 docs(guide/expression): add clarification for RegExp literal in ngPattern expression
The `ngPattern` expression does accept a RegExp created with literal notation,
hence it should be mentioned as an exception to the
"No RegExp Creation With Literal Notation" rule.

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

This commit removes the usage of these terms and replace them with `leader/follower`.
2017-08-28 10:10:54 +01:00
Oscar Busk 233a93f6e0 docs($compileProvider): add more info on debugInfoEnabled()
Add more info on what `debugInfoEnabled()` affects.

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

Closes #16155
2017-08-23 18:56:45 +03:00
Martin Staffa 66dff7cf5f chore(docs.angularjs.org): fix docs deploy for source file changes
Since the embedded examples in the docs app now include the local source files instead
of CDN files, we need to include the source files into the folder that is deployed
to Firebase hosting
2017-08-23 11:52:46 +02:00
Martin Staffa 3072938186 chore(doc-gen): include source files from code.angularjs.org for production plnkr examples 2017-08-23 11:52:46 +02:00
Martin Staffa 48f0957dde revert: chore(docs-app): load example files based on active deployment
This reverts commit d91a6bdbc6.

The runnable examples cannot rely on the CDN for loading the common files,
because the CDN push does not happen at the same time as the docs are generated,
which means the doc examples are non-functional for an unforeseeable time.
2017-08-23 11:52:46 +02:00
Martin Staffa 6d2ff0ac6d docs(CHANGELOG.md): add changes for 1.6.6 2017-08-18 15:23:17 +02:00
Georgios Kalpakas 7c876285cb test(ngOptions): fix flaky test on Firefox 54+ and Safari 9
Closes #16149
2017-08-12 11:58:55 +03:00
Martin Staffa a83d64605f chore(karma): use dots reporter by default
dots is nicer for local testing, as you usually don't run a
ton of test suites, and the progress visualization is more important .
It's also more readable if you skip many tests (i.e. run isolated tests)

Closes #16167
2017-08-11 22:56:02 +02:00
Martin Staffa 919087f0ec chore(code.angular): correctly remove old zip files from snapshot
Previously, the event would be triggered on the deletion of the previous zip files,
which would delete the current zip file as well

Closes #16168
2017-08-11 22:54:51 +02:00
Frederik Prijck 5b31b379a6 docs(*): change Angular to AngularJS
Closes #16163
2017-08-11 16:53:56 +03:00
Martin Staffa c9691a29f2 chore(travis): manually install yarn (#16166)
Currently, the yarn version on Travis is outdated:
https://github.com/travis-ci/packer-templates/issues/478
2017-08-11 15:29:21 +02:00
Frederik Prijck 9b6c1540a5 docs($compile): update preAssignBindingsEnabled description
Previously, the changelog and migration guide did not mention the fact
that this only applies to controllers which are part of a
directive/component.

This commit ensures the changelog and migration guide mentions this explicitly.

Closes #15740

Closes #16162
2017-08-11 16:25:37 +03:00
Georgios Kalpakas 56ac2a7b3c chore(karma): run tests on latest Chrome (59) and Firefox (54) available on Saucelabs
Closes #16141
2017-08-04 12:07:55 +03:00
Georgios Kalpakas 811af9ccfb test(*): fix tests involving submit on Chrome 60
On Chrome 60 (at least on Windows) the `submit` event when clicking on a submit
button is not fired on the form element, unless it is already part of the DOM.
2017-08-04 12:07:34 +03:00
Frederik Prijck a784fab605 fix($httpParamSerializerJQLike): call functions as jQuery does
Previously, `httpParamSerializerJQLike` stringified function properties without executing them.
This commit ensures function properties are executed and the return value is used.

Fixes #16138

Closes #16139
2017-08-03 21:01:39 +03:00
andypotts 3650723501 docs(guide/concepts): simplify currency exchange API example (YQL --> Fixer.io)
Fixes #16130

Closes #16137
2017-08-02 13:33:38 +03:00
Martin Staffa aee5d02cb7 chore(travis): actually skip build on deployment job when from Pull Request 2017-07-31 23:31:39 +02:00
Martin Staffa 0179c70d02 chore(code.angularjs): enable directory listings 2017-07-31 15:58:11 +02:00
Martin Staffa 84061c2954 chore(code.angularjs): delete old zip files on snapshot 2017-07-31 15:58:11 +02:00
Martin Staffa 9936e570ea chore(travis): skip build on deployment job when from Pull Request 2017-07-31 15:58:11 +02:00
Martin Staffa 1b196332f5 chore(docs-app): only copy relevant assets
This keeps the size of the docs-app build down.
Especially needed to keep the size of the generated build .zip
under 10MB, which is the limit for firebase / gcs https function transfers
2017-07-31 15:58:11 +02:00
Martin Staffa d91a6bdbc6 chore(docs-app): load example files based on active deployment 2017-07-31 15:58:11 +02:00
Carl 394dbcc277 fix($httpParamSerializer): ignore functions
Closes #16133
2017-07-31 16:14:33 +03:00
Zita Nemeckova f1d01bbc74 feat($compile): add strictComponentBindingsEnabled() method
Closes #16129
2017-07-28 12:51:38 +03:00
Chirag Bhatia 01d6a47e91 fix($resource): do not throw when calling old $cancelRequest()
Closes #16037
2017-07-27 10:37:16 +03:00
Jason Bedard ac57a25cd9 test(ngStyle): add test for object literal 2017-07-26 21:25:48 -07:00
gdi2290 15bbd3e18c perf(ngStyleDirective): use $watchCollection
Since we are simply watching a flat object collection it is more performant
to use $watchCollection than a deepWatch...

BREAKING CHANGE:

Previously the use of deep watch by ng-style would trigger styles to be
re-applied when nested state changed. Now only changes to direct
properties of the watched object will trigger changes.

Closes #15947
2017-07-26 21:25:48 -07:00
Jason Bedard 87a586eb9a fix($parse): do not pass scope/locals to interceptors of one-time bindings 2017-07-21 20:56:14 -07:00
sathify e6d5fe7dea style(css) separate selectors and declarations by new lines 2017-07-19 14:18:08 +02:00
Kerry McCullough 823c7edb84 feat($resource): add resource to response for error interceptors
Closes #16109
2017-07-18 17:10:47 +03:00
Jason Bedard 631076a31b fix($parse): do not shallow-watch computed property keys
Shallow watching is not enough when an object implements a non-pure toString
2017-07-17 23:38:39 -07:00
Jason Bedard 341f8dbe24 refactor($parse): remove unnecessary .constant if when collecting inputs 2017-07-17 22:11:42 -07:00
Jason Bedard 8de97949c5 fix($parse): support constants in computed keys 2017-07-17 20:54:43 -07:00
Jason Bedard 2fb2d09971 test(ngClass): add test for one-time objects in array literal 2017-07-16 22:01:40 -07:00
Jason Bedard 2ee5033967 fix($parse): always pass the intercepted value to watchers
Fixes #16021
2017-07-16 22:01:40 -07:00
Jason Bedard de74034ddf fix($parse): respect the interceptor.$stateful flag 2017-07-16 22:01:40 -07:00
Jason Bedard 529550d0da refactor($parse): do not pass scope,locals to interceptor fns
All internal use of interceptors are for things such as data
conversion/normalizing, never reading state from the scope/locals.
This is the intended use and makes interceptors more like filters
(which receive only the input value + args, no scope/locals).
2017-07-14 01:53:48 -07:00
Martin Staffa 828a2757b2 chore(*): deploy (docs|code) .angularjs.org to Firebase via Travis
- code.angularjs.org and docs.angularjs.org are two separate Firebase projects
- both are automatically deployed via Travis config
- Travis is split up into 2 build stages: first, all tests are run, and if they pass, the deploy
stage runs a single job with both deployments (actual deployment depends on the state of the commit)
- docs. is deployed directly to Firebase hosting
- code. is uploaded to Firebase Google Cloud Storage and uses Firebase hosting rewrites to acces the
files
- jenkins builds still push the code builds to the code.angularjs.org Github repository

Closes #9674
Closes #16093
2017-07-13 11:14:55 +02:00
SteveAndrewArcher 7e97db93ff docs(input[week]): clarify value of Date object
Add a note to documentation of input[week] to explicitly state that the
resulting Date object's value is set to Thursday at midnight of the
specified week.

Resolves #15883 
Closes #16104
2017-07-13 11:13:09 +02:00
Martin Staffa 6a22c79a94 chore(travis): fix bower install
We removed `grunt package` from JOB_UNIT in 4015e0fde5,
but this runs `grunt bower` which JOB_UNIT needs.

This commit adds `grunt bower` to JOB_UNIT.

Closes #16105
2017-07-13 10:38:57 +02:00
Martin Staffa 0616dde95e chore(travis): add commitplease validation to ci-checks
This will provide feedback to contributors without getting in the way of writing invalid commit messages locally. 

The git hook integration is turned off.

Committers who push directly to the repo can be expected to use correct commit messages ;) Most changes go through PRs anyway.

Note that "Merge commit" messages and everything starting with "WIP" is always allowed by commitplease. Follow issue https://github.com/jzaefferer/commitplease/issues/101 for more info.

Related to #14888 
Closes #16097
2017-07-12 12:02:18 +02:00
Martin Staffa 25bf1ef07c chore(doc-gen): insert current tagged version if missing from list of all versions
In commit ce49edc08b, we switched to npm info (now yarn info)
instead of the local git repository information to get the list of currently available versions for
the docs app. This means that during a release the version that is currently tagged is not yet
available on npm, and therefore our list of available versions is incomplete.

We now simply add the current build version (read from build/version.json) to the list of all
versions if it fulfills the following conditions:

- it is not a snapshot build
- it is not already part of the list of all versions (i.e. if you are building locally on a tagged commit)

Closes #15741
Closes #16099
2017-07-12 11:15:09 +02:00
Nikos Katsos 7f2accaa3a fix($http): do not throw error if Content-Type is not application/json but response is JSON-like
Previously, when the response data was JSON-like, `$http` would try to
`JSON.parse` them and throw if they were not actually JSON. This happened even
if the `Content-Type` header was not `application/json`. As a result, it was not
possible to send `text/plain` data that looked like JSON (e.g. `{abcd}`).
The reason for not relying solely on the `Content-Type` is that many users serve
JSON data without proper headers.

This commit fixes it by returning the raw response text if `$http` fails to
parse a JSON-like response, unless the `Content-Type` header has been explicitly
set to `application/json` (in which case it will still fail with an error).

Fixes #16027

Closes #16075
2017-07-11 18:32:12 +03:00
Martin Staffa c8793431b6 docs($rootScope.Scope): improve wording in $watch
Closes #16050
2017-07-11 15:34:46 +02:00
Eyal Ronel 77b302ab00 docs($resource): add missing closing square bracket in example
Closes #16090
2017-07-11 09:48:49 +03:00
z.ky af83c1541c docs(ngRepeat): correct typo
Closes #16088
2017-07-06 19:06:34 +02:00
Frederik Prijck e872f0ed36 feat($http): allow differentiation between XHR completion, error, abort, timeout
Previously, it wasn't possible to tell if an `$http`-initiated XMLHttpRequest
was completed normally or with an error or it was aborted or timed out.
This commit adds a new property on the `response` object (`xhrStatus`) which
allows to defferentiate between the possible statuses.

Fixes #15924

Closes #15847
2017-07-04 15:20:48 +03:00
Martin Staffa 122d89b240 docs(ngOpen): improve example, correct browser compat note
Firefox supports details since version 49
2017-07-04 12:33:00 +02:00
Georgios Kalpakas 1991e77e43 docs(changelog): add release notes for 1.6.5 2017-07-03 14:50:58 +03:00
ksvitkovsky 57a972d899 feat($compile): overload .component() to accept object map of components
Register multiple components with single call as it is possible with other module units.

Closes #14579 
Closes #16062
2017-07-03 11:07:10 +02:00
Jason Bedard cdaa6a951b fix($timeout/$interval): do not trigger a digest on cancel
Previously, `.catch(noop)` was used on a rejected timeout/interval to prevent an unhandled rejection error (introduced in #c9dffde1cb). However this would schedule a deferred task to run the `noop`. If the cancelling was outside a digest this could cause a new digest such as with the ng-model `debounce` option.

For unit testing, this means that it's no longer necessary to use `$timeout.flush()` when a `$timeout` has been cancelled outside of a digest. Previously, this was necessary to execute the deferred task added by `.catch(noop).
There's an example of such a change in this commit's changeset in the file `/test/ngAnimate/animateCssSpec.js`.

Fixes #16057
Closes #16064
2017-07-03 11:04:17 +02:00
davesidious bf0af6dbb1 docs($log): add note about blackboxing
Add browser-agnostic hint about blackboxing and the benefits it brings developers when using $log.

Closes #15592
2017-06-30 11:58:30 +02:00
Idan Cohen 62c9d1da7a docs(misc/FAQ): correct misspell
The brackets are still just 'angular' :-)

Fixing over-correction made in [this PR](https://github.com/angular/angular.js/commit/03043839d5a540b02208001fe12e812dfde00a8e)

Closes #16070
2017-06-29 11:02:58 +02:00
Martin Staffa 8deff89e5f test(ngOptions): ensure options are only painted once on compile 2017-06-29 10:51:09 +02:00
Pol Bonastre 65728383f3 perf(ngOptions): prevent initial options repainting
Avoid double execution of `updateOptions()` method,
which causes a complete repainting of all `<option>` elements.

Fixes #15801
Closes #15812
Close #16071
2017-06-29 10:51:09 +02:00
Jason Bedard a772b94b0a chore(benchmarks): add $watchCollection tests 2017-06-27 21:42:28 -07:00
Jason Bedard 423acc2c67 chore(benchmarks): remove no longer applicable tests and literal watching workarounds 2017-06-27 21:42:28 -07:00
Jason Bedard a03b75c6a8 refactor($browser): remove workaround for old ff bug
- https://bugzilla.mozilla.org/show_bug.cgi?id=407172 was fixed in ff 40

Closes #16065
2017-06-21 16:34:37 +02:00
Martin Staffa e58bcfab99 chore(grunt): increase task readability 2017-06-13 10:40:09 +01:00
Martin Staffa 4015e0fde5 chore(travis): don't build package for the "unit" job
Source test:unit do not need built or packaged code,
and, and tests:docs only need built code.
2017-06-13 10:40:09 +01:00
Martin Staffa 030ae660bb chore(travis): use "karma-spec-reporter"
dots reporter creates lots of empty space that makes it tedious to scroll
through the logs. "Spec" is configured to only report on failures.
2017-06-13 10:40:09 +01:00
Jason Bedard b85926b33f test($parse): add one-time/interceptor tests 2017-06-12 22:07:00 -07:00
Jason Bedard b12a0b7652 fix($parse): do not shallow-watch inputs when wrapped in an interceptor fn
Fixes #15905
Closes #16018
2017-06-12 21:30:36 -07:00
Martin Staffa 464dde8bd1 fix(Angular): deprecate angular.merge
This function has problems with special object types but since it's not used in core,
it is not worth implementing fixes for these cases.
A general purpose library like lodash (provides `merge`) should be used instead.

Closes #12653
Closes #14941
Closes #15180
Closes #15992
Closes #16036
2017-06-12 15:59:20 +02:00
Saurav Bhattacharya 42299e9f6d docs(external-resources.ngdoc): fix broken link
Closes #16042
2017-06-12 15:02:02 +03:00
Georgios Kalpakas 53fb909068 test(ngMock): fix Firefox craches on Travis
This test keeps causing Firefox 47 (currently used on Travis) to crash and fail
the build. The test passes locally (on Firefox 53). Lowering the loop count from
1000 to 100 seems to fix the issue.
(Note: The crach only affects the mocked implementation of `$interval` and does
not happen locally.)

Closes #16040
2017-06-12 14:39:13 +03:00
Peter Bacon Darwin 420ceb6e48 chore(jenkins): do not publish to code.angularjs.org snapshot
While the firewall continues to block the update ports
we will not try to publish there. This will be fixed when we move to hosting
the sites on Firebase.

This means that successful builds on master will not automatically update
code.angularjs.org, this will affect:

* https://code.angularjs.org/snapshot, which people often use to check latest features
* https://docs.angularjs.org, which is supposed to display the docs for the latest master

As it turns out we can manually partially trigger an update by browsing to
https://code.angularjs.org/gitFetchSite.php but we just can’t guarantee that we will update
both the round robin servers.
2017-06-06 12:26:05 +01:00
Lucio Martinez 32f4645314 fix(ngMock/$interval): add support for zero-delay intervals in tests
Previously, trying to test code thaat contained zero-delay intervals (e.g.
`$interval(fn, 0)` or `$interval(fn)`) would result in an infinite loop.
This commit avoids the infinite loop, by treating zero-delay intervals as one
second intervals (except for the initial trigger, where they can also be
executed with `$interval.flush(0)`).

Fixes #15952

Closes #15953
2017-06-06 13:28:34 +03:00
Georgios Kalpakas e5c5b4a131 chore(i18n): update CLDR to v30.0.1
Fixes #15976

Closes #15997
2017-06-06 13:08:05 +03:00
Georgios Kalpakas 5d5fd6292a chore(i18n): fix parser for currency patterns without fraction digits
Previously, it was assumed that all currency pattern would have fraction digits.
However, in [closure-library@b9155d5][1] the `agq_CM` locale was modified to
have such a pattern (namely `#,##0\u00A4`).
This commit modifies the parser implementation to account for pattern without a
decimal point (and thus no fraction digits).

[1]: https://github.com/google/closure-library/commit/b9155d5966a228cb33f367c30c275c833b30e3ff#diff-02793124214ad0470ccea6f86b90d786R711
2017-06-06 13:08:03 +03:00
Georgios Kalpakas 7fbbacc104 chore(i18n): fix relative paths in scripts 2017-06-06 13:07:35 +03:00
Georgios Kalpakas 1df736e256 test(i18n): remove bad assertion 2017-06-06 13:07:35 +03:00
Peter Bacon Darwin 7673ca7d15 fix($sanitize): use appropriate inert document strategy for Firefox and Safari
Both Firefox and Safari are vulnerable to XSS if we use an inert document
created via `document.implementation.createHTMLDocument()`.

Now we check for those vulnerabilities and then use a DOMParser or XHR
strategy if needed.

Thanks to @cure53 for the heads up on this issue.
2017-06-05 21:02:03 +01:00
Martin Staffa e65928eecb docs($compile): add more info about optional bindings
This centralizes the info about optional bindings.
Also adds more examples to the $compile:iscp error.

Closes #15989
Closes #16025
2017-06-05 20:23:12 +02:00
Martin Staffa 3bce707421 docs(ngRepeat): highlight track by expression position 2017-05-31 18:37:31 +02:00
Michał Gołębiowski b4651e5278 test(support): verify support tests results in all tested browsers (#16008)
Closes #16008
2017-05-25 16:14:31 +02:00
Jason Bedard aef3ef7b03 test($parse): reorganize $parse tests 2017-05-24 21:42:21 -07:00
Jason Bedard b5118ac6a9 fix($parse): always re-evaluate filters within literals when an input is an object
Fixes #15964
Closes #15990
2017-05-24 21:42:21 -07:00
Michał Gołębiowski 33cd29b3a3 chore(testabilityPatch): fix a typo 2017-05-24 10:25:30 +02:00
Michał Gołębiowski 667d4734fc test($log): run all $log tests in IE9 & non-IE9 logging mode (#15995)
In IE 9 console methods don't inherit from Function.prototype and, hence, don't
have apply. Until recently IE 9 logging in AngularJS was restricted to the
first 2 parameters but that changed as we could just reuse
Function.prototype.apply everywhere, creating one code path for all browsers.
Therefore, we can now run all tests in modes where apply exists on logging
methods and where it doesn't.

Ref #15911
Ref b277e3ead7
Closes #15995
2017-05-24 10:14:29 +02:00
Thomas Grainger 837acd14e0 fix(*): correctly detect Error instances from different contexts
Previously, errors thrown from different contexts (such as an iframe or
webworker) were not detected as `Error` instances and handled accordingly.
This commit fixes it by introducing an `isError()` helper, that is able to
correctly detect such instances.

Fixes #15868

Closes #15872
2017-05-22 14:07:52 +03:00
Sercan Eraslan 63b6d64a60 docs(guide/component): remove redundant empty controller from example
There is no need for empty controller functions on components, since this is the
default.

Closes #16003
2017-05-22 11:50:20 +03:00
BobChao87 762580ff34 fix(orderBy): guarantee stable sort
If a user-provided comparator fails to differentiate between two items, fall
back to the built-in comparator (using the tie-breaker predicate).

Fixes #14881

Closes #15914
2017-05-19 14:40:04 +03:00
Martin Staffa a86a3195b4 chore(*): update protractor
Update protractor to latest 5.1.2 to make it work with Chrome 58 on Jenkins.
This protractor version is not compatible with FF 53 and directConnect, but this should be irrelevant as Travis does not use directConnect and on Jenkins we don't test FF.

Closes #15991
2017-05-17 09:22:34 +02:00
Martin Staffa 2acea11a17 chore(ci): disable unit testing on Firefox
Related to https://github.com/angular/angular.js/issues/15987

Closes #15988
2017-05-15 13:29:13 +02:00
Georgios Kalpakas 9bcdfcfe17 docs(*): fix dangling links
Closes #15984
2017-05-12 18:09:33 +03:00
Georgios Kalpakas 66945e217e docs(form): improve the docs for FormController.$setValidity()
Fixes #15963
2017-05-12 18:09:32 +03:00
tsclaus cd5efa095e docs(ngRepeat): fix argument name in comment to match actual argument (element --> clone)
Closes #15975
2017-05-11 11:40:16 +03:00
Jake Danforth e79c472fdd docs(error/badrestrict): fix typo (of --> or)
Closes #15979
2017-05-11 11:34:36 +03:00
Martin Staffa e1dd00e4ef chore(*): update jasmine-core to 2.5.2
This might resolve an issue where Firefox 51+ fails on Jenkins at this
test: https://github.com/angular/angular.js/blob/8a89586bede0256494cb3027d856f1ebf592afde/test/ng/directive/ngOptionsSpec.js#L2891

The failure can also be reproduced locally when running the whole test suite with the
Firefox window unfocused. With 2.5.2, the failure happens too, but much less
frequent.

Latest jasmine (2.6.2) has problems with some browsers, see here:
https://github.com/jasmine/jasmine/issues/1327

Closes #15978
2017-05-10 14:10:23 +02:00
David Fuka 8a89586bed docs(errors/badjsonp): fix typo
Closes #15977
2017-05-10 13:26:49 +02:00
Jason Bedard d0d829899c test($rootScope): add $watch/$watchCollection/$watchGroup tests
Closes #15949
2017-05-09 21:54:15 -07:00
Michał Gołębiowski 30eb194341 test(*): run class-related tests everywhere; fix eval syntax
1. Wrap an evaled class definition in parens; previously they weren't; the test
   wasn't failing only because it was disabled everywhere outside of Chrome
   and Chrome <59 incorrectly accepted such input.
2. There's no reason to restrict class-related tests just to Chrome; now they
   run in every browser that supports ES6 classes. The classes support test
   was modified to check not only if a class definition parses but also if
   it stringifies correctly which is required by AngularJS. This restriction
   disables class-related tests in current Firefox (53) but will work in v55
   or newer.

Closes #15967
2017-05-09 15:08:35 +02:00
musclor 2f3bd89a51 docs(guide/component): remove redundant unit test
Fixes #15968
Closes #15974
2017-05-09 10:18:38 +03:00
Lucas Mirelmann 301fdda648 fix(httpParamSerializerJQLike): Follow jQuery for null and undefined
Follow jQuery when serializing `null` and `undefined`.

Closes: #15969
Closes: #15971
2017-05-07 20:24:07 +02:00
Michał Gołębiowski 1069086299 chore(*): update all Karma-related packages except Karma
The updated karma-chrome-launcher adds support for ChromeHeadless &
ChromeCanaryHeadless launchers; test with:

    karma start karma-jqlite.conf.js --browsers=ChromeCanaryHeadless

The updated karma-firefox-launcher disables multi-process which may increase
stability on Jenkins.

Closes #15966
2017-05-06 17:50:42 +02:00
Valentin 2a8a29ac43 docs(guide/templates): add missing closing <script> tag
Closes #15961
2017-05-04 14:02:48 +03:00
Leonardo Souza d21acafa77 docs(guide/interpolation): fix typo in markdown (code highlight)
Closes #15935
2017-05-02 15:41:58 +03:00
Georgios Kalpakas 8f563e2ecf perf(animate): avoid unnecessary computations if animations are globally disabled
Closes #14914
2017-04-28 12:48:03 +03:00
Georgios Kalpakas c09e613aac feat($animate): add support for customFilter
This commit adds a new `customFilter()` function on `$animateProvider` (similar
to `classNameFilter()`), which can be used to filter animations (i.e. decide
whether they are allowed or not), based on the return value of a custom filter
function.
This allows to easily create arbitrarily complex rules for filtering animations,
such as allowing specific events only, or enabling animations on specific
subtrees of the DOM, etc.

Fixes #14891
2017-04-28 12:48:02 +03:00
Georgios Kalpakas 913cf794c9 perf($animate): do not retrieve className unless classNameFilter is used 2017-04-28 12:47:49 +03:00
Georgios Kalpakas 17fb15d7a4 docs(guide/animations): list missing animated directives (and other improvements)
- List missing animation-aware directives.
- Fix/Improve wording/formatting.
- Fix typos.
- Limit lines to 100 chars.
2017-04-28 12:47:49 +03:00
Dimitri Tarasiuk 9341671d78 docs($q): fix typo in qFactory documentation
Closes #15946
2017-04-28 12:20:27 +03:00
Georgios Kalpakas 4a12ae7b36 fix(angular-loader): do not depend on "closure" globals that may not be available
Code that is distributed as part of both `angular.js` and `angular-loader.js`
should not depend on "closure" globals that may not be available in
`angular-loader`.

Fixes #15880

Closes #15881
2017-04-27 22:46:35 +03:00
Martin Staffa b496daabe6 fix(ngOptions): re-render after empty option has been removed 2017-04-27 21:35:26 +02:00
Martin Staffa 6fc0f02ad2 feat(select): expose info about selection state in controller
This allows custom directives to manipulate the select's and
ngModel's behavior based on the state of the unknown and
the empty option.

Closes #13172
Closes #10127
2017-04-27 21:35:26 +02:00
Pol Bonastre 2fdfbe7296 fix(ngOptions): allow empty option to be removed and re-added
This bug was reported as part of angular/angular.js#15801
2017-04-27 21:35:26 +02:00
Georgios Kalpakas f90b48d7d8 chore(docs-app): fix vertical scrolling offset after recent re-design
Previously, the `yOffset` pointed to the `<header>` element, which had a height
of 0 (since all its children have fixed positions). This caused scrolled items
to have 0 vertical offset, essentially hiding the top part behind the static
`<nav>` items.
This commit fixes the vertical scrolling offset, by setting `yOffset` to the
last (lowest) `<nav>` item.

Closes #15945
2017-04-27 17:00:49 +03:00
Martin Staffa dcc57f1718 docs(select): add known issue about Firefox selection behavior
Related to #9134
2017-04-26 12:48:36 +02:00
Michał Gołębiowski 602fa698a5 refactor($injector): require standard class stringification
ES6 classes now require Edge 14 or newer to work.

Closes #15911
2017-04-25 20:56:10 +02:00
Michał Gołębiowski b277e3ead7 feat($log): log all parameters in IE 9, not just the first two.
IE 9 lacks apply on console methods but it's possible to borrow the apply
method from Function.prototype.
2017-04-22 15:33:05 +02:00
Michał Gołębiowski e4c2fe6d42 refactor(*): remove workarounds for IE <9, update IE/Edge-related comments 2017-04-22 15:31:36 +02:00
Martin Staffa ff0e61166d refactor(select, ngOptions): extract common methods; make consistent 2017-04-21 20:38:57 +02:00
Martin Staffa 4b06637f70 chore(matchers): improve output for toBeMarkedAsSelected 2017-04-21 20:38:57 +02:00
Martin Staffa 5878f07474 fix(ngOptions): select unknown option if unmatched model does not match empty option
When a regular / ngOptions select has an explicit *empty* option, this option can be selected
by the user and will set the model to `null`. It is also selected when the model is set to
`null` or `undefined`.

When the model is set to a value that does not match any option value, and is also not
`null` or `undefined`, the *unknown* option is inserted and selected - this is an explicit marker
that the select is in an invalid / unknown state, which is different from an allowed empty state.

Previously, regular selects followed this logic, whereas ngOptions selects selected the empty
option in the case described above.

This patch makes the behavior consistent between regular / ngOptions select - the latter will now
insert and select the unknown option. The order of the options has been fixed to unknown -> empty
-> actual options.
2017-04-21 20:38:57 +02:00
Martin Staffa 8d7c7f4a8e test(select, ngOptions): add more tests for "required" with "empty" or "unknown" option 2017-04-21 20:38:57 +02:00
Jacob Hansson 080357e906 feat(ngMock): describe unflushed http requests
The current implementation of $httpBackend.verifyNoOutstandingRequest
gives an integer number describing how many requests are unflushed.

While it's superficially easy to solve test errors from that message
by simply adding an additional $httpBackend.flush(), if a developer
is truly not expecting the code to make further requests this is
not ideal.

This change explicitly prints out which additional requests remain
unflushed in the error message, helping her determine if the code
needs changing, or if an additional flush is appropriate.

Before this change:

    Unflushed requests: 1

After this change:

    Unflushed requests: 1
      GET /some

Closes #10596
Closes #15928
2017-04-21 13:39:36 +02:00
Martin Staffa 69c3faf405 test(core): expect that Edge cannot auto-bootstrap in extensions 2017-04-19 13:05:25 +02:00
Martin Staffa 7efed00632 test(input): exclude tests that are only failing on Edge 2017-04-19 13:05:25 +02:00
Martin Staffa 496138f12a chore: test on Microsoft Edge
Closes #13687
Closes #14401
2017-04-19 13:05:25 +02:00
TheHalcyonSavant 37a2c20bb8 docs(guide/migration): remove duplicate entry for commit 13c252
Closes #15919
2017-04-18 10:28:20 +03:00
Michał Gołębiowski 8eb925d7c5 chore(browserstack): Update OS X, make iOS 8-10 available to test 2017-04-12 15:00:57 +01:00
Michał Gołębiowski ad0bb83819 chore(browserstack): Update browserstacktunnel-wrapper, fix options
Only the latest version of the package works correctly (the backend for it at
BrowserStack is not versioned) and the options have changed in the new version
of the package.

Also, iOS 8.0 is no longer available on BrowserStack, only 8.3 is. Instead,
this commit changes it to 9.3 as we shouldn't be testing on 8 anymore anyway.

Closes #15892
2017-04-12 13:20:43 +02:00
Martin Staffa e23782b8c2 docs($http): correct and clarify default transforms
- baddata error described incorrect http behavior, and workarounds
- httpProvider defaults were missing transformResponse / transformRequest
- http was not clear about JSON detection strategy

Closes #15897 
Closes #15906
2017-04-12 11:21:10 +02:00
Vigneshkumar Chinnachamy d0622d0649 docs(guide/Developer Guide): Update twitter handle
Replaced the old Angular twitter handle with the new one.

Closes #15903
2017-04-08 14:10:21 +02:00
Eli Sadoff e812b9fa9e docs(filter/uppercase): add an example
I saw that the uppercase filter had no example so I decided to add a minimal example to explain how the uppercase filter works.

Thank you very much to @narretz for helping me through this process.

Closes #15885
2017-04-07 17:23:19 +02:00
Martin Staffa 6ee7c29ca7 docs(filter/filter): remove duplicate 'the'
Closes #15893
2017-04-07 15:02:48 +02:00
Atef Ben Ali 0fbb1187b8 docs(guide/directive): delete redundant 'the'
Closes #15891
2017-04-05 15:13:28 +02:00
Atul Shimpi 136a42abc1 docs(README): improve vocabulary and orthography
Closes #15876
Closes #15875
2017-04-03 10:19:35 +02:00
michaelb958 06516d7c27 docs(guide/i18n): fix links to CLDR
The old link target is dead, deceased, pushing up daisies. I quote:
> The cldr-tmp repository is no longer available.
> For access to CLDR sources and data, please see the [CLDR pages](link to new one).

Closes #15879
2017-04-02 16:12:46 +03:00
Martin Staffa 617b36117a docs(changelog): add release notes for 1.6.4 2017-03-31 10:47:45 +02:00
Jason Bedard 189461f9bf fix($parse): standardize one-time literal vs non-literal and interceptors
Previously literal one-time bindings did not use the expression `inputs`, causing infinite digest issues with literal values. This often forces the use of deepEquals when watching one-time literals.

`ng-class` is one example of deepEquals which is no longer required.

This one-time/literal behavior is now also consistently propogated through interceptors.

Closes #15858
2017-03-31 09:36:19 +02:00
Jason Bedard 93879b3c72 fix($parse): fix infinite digest errors when watching objects with .valueOf in literals
Closes #15867
2017-03-31 09:17:55 +02:00
Jason Bedard c2b8fab0a4 fix($rootScope): provide correct value of one-time bindings in watchGroup 2017-03-30 22:22:22 -07:00
bennycoomans f403925ee0 docs(guide/Migrating from Previous Versions): fix typo "indentifiers"
Closes #15871
2017-03-29 14:49:00 +02:00
Michał Gołębiowski 1e841a89c1 docs($compile): remove a mention of preassigning bindings in controllers
The deprecation warning is no longer needed as the feature has been removed
in 1.7.

Closes #15870
2017-03-29 14:15:26 +02:00
Jason Bedard 2b0c0505e2 refactor($parse): move duplicate $parse interpreter/compiler logic into Parser
- the construction of the AST is now in the Parser
- the assigning of the literal and constant flags is now in the Parser
- remove unused references to the lexer, $filter and options on the Parser
2017-03-27 23:29:02 -07:00
Jason Bedard 9d74f0fdcb refactor($compile): reuse shared simpleCompare method 2017-03-27 23:25:22 -07:00
Jason Bedard f1d0f03863 refactor($parse): make use of local variable instead of refetching property 2017-03-27 22:53:12 -07:00
Jason Bedard b0f6afcdac test($compile): add test for #15833 2017-03-27 22:47:25 -07:00
Jason Bedard 2931a6df03 refactor(ngModel): use local scope param in watcher 2017-03-27 22:47:15 -07:00
Michał Gołębiowski bf5c2eef34 fix(jqLite): make jqLite invoke jqLite.cleanData as a method
The previous implementation of jqLite didn't use cleanData from the jqLite
object but instead used a cached version which maede it impossible to
monkey-patch jqLite.cleanData similarly to how you can do it in jQuery.

The cleanData method is not meant to be called directly by userland code;
its purpose is mainly to be able to be monkey-patched; therefore, the previous
implementation didn't make a lot of sense.

This commit enables one of the tests so far run only with jQuery to run with
jqLite as well.

Ref #8486
Ref #8695
Closes #15846
2017-03-27 11:55:56 +02:00
Michał Gołębiowski dcdd5def8f test(jQuery): run tests with jQuery 2.1, 2.2 & 3.2
Also, update jQuery 2.2.x mentions in the tutorial to 3.2.x.

Closes #15843
2017-03-27 11:23:49 +02:00
Peter Mertz f3aa1d183a docs($interval): Update interval promise docs
It's currently not clear when or why the promise returned by `$interval` resolves. This updates the docs to be more specific.

Closes #15862
2017-03-25 18:08:38 +02:00
Martin Staffa 80077f35d0 docs(faq): clarify the versioning strategy
- When do breaking changes appear
- Relationship with Semver
- Compatibility of modules

Closes #15845
2017-03-24 12:45:28 +01:00
Martin Staffa 32f38a33b6 docs($animate): remove obsolete error doc 2017-03-24 10:44:51 +01:00
Martin Staffa 9de0842719 chore(doc-gen): report on missing or obsolete error docs
Closes #12527
2017-03-24 10:44:51 +01:00
Rodrigo b9d2b30808 docs(filterFilter): clarify the comparator parameter
Closes #15827
2017-03-23 16:00:37 +02:00
Michał Gołębiowski 3d0abffbc0 chore(yarn): rely on Travis built-in Yarn support, update Yarn in Jenkins
On Travis we now rely on built-in Yarn support and we only cache the Yarn cache,
not node_modules. This creates a more stable environment as we don't install
over previous node_modules state but we still won't download packages from the
internet in the second run for the same yarn.lock as Yarn takes packages from
its local cache if they exist there.

We install a new Yarn verison manually on Jenkins; the location of the install
script changed.

Closes #15851
2017-03-22 22:49:51 +01:00
Martin Staffa c35786ae26 chore(github): update issue template
Closes #15824
2017-03-22 17:03:44 +01:00
Michał Gołębiowski 60644d5d05 chore(*): remove unused docs/bower_components mentions 2017-03-22 16:49:16 +01:00
Michał Gołębiowski 233f47b98a chore($parse): make sure no one changes .toEqual(-0) to .toBe(-0) 2017-03-22 12:08:05 +01:00
Martin Staffa 421040588c docs(component-router): give deprecation notice red color 2017-03-22 12:00:32 +01:00
Jason Bedard f132ce740a refactor($controller): remove unused injected $window
Closes #15839
2017-03-22 11:54:55 +01:00
Joshua J Wilborn 5377baf0fc docs ($compile): add error documentation for noslot error in $compile
Fixes #15790
Closes  #15828
2017-03-22 11:51:55 +01:00
Michał Gołębiowski bf7685abbd test(jqLite): test not firing $destroy on jqLite.cleanData with jQuery UI
So far it wasn't tested that Angular's logic for skipping it triggering
the $destroy event on jQuery.cleanData in the replaceWith internal function
works correctly when Angular is not the last one to patch the cleanData method
(e.g. if jQuery UI does the patching later). This commits adds the relevant
test.

Ref #8486
2017-03-22 10:37:17 +00:00
Michał Gołębiowski ba2e0d3d9b docs(faq): document the AngularJS/jqLite deprecation strategy
Fixes #15282
2017-03-22 10:32:28 +00:00
Raphael Jamet 0d9d57d418 docs($sce): overhaul the $sce service documentation
A big docs update around `$sce`:
There is a lot of content in there that is often misunderstood, and some of the
documentation starts to get really old too. Also fixed capitalization,
formatting, indentation and uniformized `@param` descriptions.

Closes #15735
2017-03-21 17:34:33 +02:00
Richard Kaufhold d96e58fdc8 feat($resource): add hasBody action configuration option
By default, only `PUT`, `POST` and `PATCH` requests have a body, but you can use
`hasBody` to configure any action to either have or not have a body, regardless
of its HTTP method.

Fixes #10128

Closes #12181
2017-03-21 12:43:48 +02:00
Georgios Kalpakas 70dbb15846 docs($sanitize): fix incorrect test description 2017-03-20 16:26:14 +02:00
BobChao87 d94153939c docs($resource): encode ) in link
JSDoc to HTML converter was treating the close parenthesis in
`[MDN](...#toJson()_behavior)` as the final close parenthesis, thus resulting in
a broken link.
This commit fixes it by percent-encoding the parentesis in the link address.

Closes #15825
2017-03-20 12:50:18 +02:00
xfg eacf06f5cf docs(ngMock/$httpBackend): add catch() block to example
Make the `it should fail authentication` test pass.

Closes #15822
2017-03-20 12:45:06 +02:00
TheRealMaxion bb2a247aa5 docs(tutorial/step_09) fix typo
Closes #15829
2017-03-20 12:32:39 +02:00
TheRealMaxion 24c94b83fa docs(tutorial/step_04): fix typo (each --> its)
Closes #15826
2017-03-20 12:27:44 +02:00
Vitaliy 0c3620bbf5 docs($interpolate): fix typo
There was missing `JS` at line 141.

Closes #15817
2017-03-15 18:19:06 +01:00
Michał Gołębiowski 38f8c97af7 fix($compile): remove the preAssignBindingsEnabled flag
Closes #15782

BREAKING CHANGE:

Previously, the `$compileProvider.preAssignBindingsEnabled` flag was supported.
The flag controlled whether bindings were available inside the controller
constructor or only in the `$onInit` hook. The bindings are now no longer
available in the constructor.

To migrate your code:

1. If you haven't invoked `$compileProvider.preAssignBindingsEnabled()` you
don't have to do anything to migrate.

2. If you specified `$compileProvider.preAssignBindingsEnabled(false)`, you
can remove that statement - since AngularJS 1.6.0 this is the default so your
app should still work even in AngularJS 1.6 after such removal. Afterwards,
migrating to AngularJS 1.7.0 shouldn't require any further action.

3. If you specified `$compileProvider.preAssignBindingsEnabled(true)` you need
to first migrate your code so that the flag can be flipped to `false`. The
instructions on how to do that are available in the "Migrating from 1.5 to 1.6"
guide:
https://docs.angularjs.org/guide/migration#migrating-from-1-5-to-1-6
Afterwards, remove the `$compileProvider.preAssignBindingsEnabled(true)`
statement.
2017-03-15 15:38:44 +01:00
Chirag Bhatia c80fa1cfe1 fix($http): throw more informative error on invalid JSON response
Fixes #15695

Closes #15724
2017-03-14 14:47:39 +02:00
Martin Staffa 11d9ad1eb2 fix(ngTouch): remove ngClick override, $touchProvider, and $touch
Closes #15761
Closes #15755

BREAKING CHANGE:

The `ngClick` directive from the ngTouch module has been removed, and with it the
corresponding `$touchProvider` and `$touch` service.

If you have included ngTouch v1.5.0 or higher in your application, and have not
changed the value of `$touchProvider.ngClickOverrideEnabled()`, or injected and used the `$touch`
service, then there are no migration steps for your code. Otherwise you must remove references to
the provider and service.

The `ngClick` override directive had been deprecated and by default disabled since v1.5.0,
because of buggy behavior in edge cases, and a general trend to avoid special touch based
overrides of click events. In modern browsers, it should not be necessary to use a touch override
library:

- Chrome, Firefox, Edge, and Safari remove the 300ms delay when
  `<meta name="viewport" content="width=device-width">` is set.
- Internet Explorer 10+, Edge, Safari, and Chrome remove the delay on elements that have the
  `touch-action` css property is set to `manipulation`.

You can find out more in these articles:
https://developers.google.com/web/updates/2013/12/300ms-tap-delay-gone-away
https://developer.apple.com/library/content/releasenotes/General/WhatsNewInSafari/Articles/Safari_9_1.html#//apple_ref/doc/uid/TP40014305-CH10-SW8
https://blogs.msdn.microsoft.com/ie/2015/02/24/pointer-events-w3c-recommendation-interoperable-touch-and-removing-the-dreaded-300ms-tap-delay/
2017-03-14 11:48:54 +01:00
eeeqxxtg 5a13cacf9f docs(changelog): fix typo (resourceUrlWhiteList --> resourceUrlWhitelist)
Closes #15809
2017-03-14 11:30:14 +02:00
Ash Searle 28bad725b1 fix(dateFilter): correctly handle newlines in format string
Fixes #15794

Closes #15792
2017-03-13 19:28:26 +02:00
Martin Staffa 1daa4f2231 fix(Angular): remove angular.lowercase and angular.uppercase
Closes #15445

BREAKING CHANGE:

The helper functions `angular.lowercase` `and angular.uppercase` have
been removed.

These functions have been deprecated since 1.5.0. They are internally
used, but should not be exposed as they contain special locale handling 
(for Turkish) to maintain internal consistency regardless of user-set locale.

Developers should generally use the built-ins `toLowerCase` and `toUpperCase`
or `toLocaleLowerCase` and `toLocaleUpperCase` for special cases.

Further, we generally discourage using the angular.x helpers in application code.
2017-03-08 14:33:34 +01:00
Martin Staffa 4d43ee3327 docs(changelog): move bootstrap fixes to Bug Fix section 2017-03-08 12:47:23 +01:00
Martin Staffa a59f46b37d docs(changelog): add release notes for 1.6.3 2017-03-08 12:22:32 +01:00
Pablo Targa 728ce72372 docs(ngAnimate): update staggering config for use with css animations
Closes #15743
2017-03-07 20:20:01 +01:00
diegomrsantos b779091ffd docs(guide/migration): add info for 1.4 (ng)Pattern BC
Breaking change was introduced in commit 0e001084ff.
This content being included in the migration guide is taken from the commit message of commit 0e001084ff.

Closes #15758
Closes #15765
2017-03-07 20:13:24 +01:00
Raphael Jamet 6ccbfa65d6 feat($compile): lower the xlink:href security context for SVG's a and image elements
Previously, `xlink:href` on SVG's `<a>` and `<image>` elements, was
`$sce.RESOURCE_URL`. While this makes sense for other `xlink:href` usecases, it
was an overkill for these elements.
This commit lowers the `xlink:href` security context for these specific
elements, treating it in the same way as `a[href]` or `img[src]` respectively.
The `xlink:href` security context for other elements is not affected.

BREAKING CHANGE:

In the unlikely case that an app relied on RESOURCE_URL whitelisting for the
purpose of binding to the `xlink:href` property of SVG's `<a>` or `<image>`
elements and if the values do not pass the regular URL sanitization, they will
break.

To fix this you need to ensure that the values used for binding to the affected
`xlink:href` contexts are considered safe URLs, e.g. by whitelisting them in
`$compileProvider`'s `aHrefSanitizationWhitelist` (for `<a>` elements) or
`imgSrcSanitizationWhitelist` (for `<image>` elements).

Closes #15736
2017-03-05 00:57:04 +02:00
mohamed amr cc793a1364 test(errorHandlingConfig): add tests for errorHandlingConfig() (independent of minErr)
Closes #15770
2017-03-05 00:44:45 +02:00
Michał Gołębiowski 3dc0096dc4 fix($log): don't parse error stacks manually outside of IE/Edge
IE/Edge display errors in such a way that it requires the user to click in
4 places to see the stack trace. There is no way to feature-detect it so
there's a chance of the user agent sniffing to go wrong but since it's only
about logging, this shouldn't break apps. Other browsers display errors in
a sensible way and some of them map stack traces along source maps if available
so it makes sense to let browsers display it as they want.

Fixes #15590
Closes #15767
2017-03-03 11:38:58 +01:00
jason-larigakis-hs 846fa1cdf6 docs(guide/Providers): remove confusing section
This part of the guide  is called "Providers", which means the section no longer applies.

Closes #15771
2017-03-03 11:08:54 +01:00
Peter Bacon Darwin 60e294cbd8 feat(info): add angularVersion info to each module
You can now check what version of AngularJS a core module is designed for:

```
var angularVersion = $injector.modules['myModule'].info().angularVersion;
```
2017-03-02 08:22:08 +00:00
Peter Bacon Darwin 550f309dba feat($injector): add new modules property
The `modules` property is a hash of the modules loaded into the injector
at bootstrap time. This can be used to access the module's info.
2017-03-02 08:22:08 +00:00
Peter Bacon Darwin 49aba51e6b feat(Module): add info() method
The new `info()` method lets developers store arbitrary information about
their module for consumption later.

Closes #15225
2017-03-02 08:22:08 +00:00
Martin Staffa e269c14425 fix($controller): remove instantiating controllers defined on window
This also removes the likewise deprecated `$controllerProvider.allowGlobals()` method.

Closes #15349
Closes #15762

BREAKING CHANGE:

The option to instantiate controllers from constructors on the global `window` object
has been removed. Likewise, the deprecated `$controllerProvider.allowGlobals()`
method that could enable this behavior, has been removed.

This behavior had been deprecated since AngularJS v1.3.0, because polluting the global scope
is bad. To migrate, remove the call to $controllerProvider.allowGlobals() in the config, and
register your controller via the Module API or the $controllerProvider, e.g.

```
angular.module('myModule', []).controller('myController', function() {...});

angular.module('myModule', []).config(function($controllerProvider) {
  $controllerProvider.register('myController', function() {...});
});

```
2017-03-01 13:27:17 +01:00
Peter Bacon Darwin 19bc52127f fix(Angular): do not autobootstrap if the src exists but is empty
In Chrome an empty `src` attribute will be ignored, but in Firefox it seems
happy to prepend the `base[href]` and try to load whatever that is.
2017-02-27 11:53:44 +00:00
Georgios Kalpakas 4f69d38f09 fix($sanitize): prevent clobbered elements from freezing the browser
Closes #15699
2017-02-24 16:38:16 +00:00
Peter Bacon Darwin ebe90051ed fix(Angular): do not auto bootstrap if the currentScript has been clobbered 2017-02-24 14:53:22 +00:00
Peter Bacon Darwin a649758655 fix(Angular): do not auto bootstrap if the script source is bad and inside SVG 2017-02-24 14:52:13 +00:00
Peter Bacon Darwin c357b1aba6 test(Angular): refactor auto bootstrap tests 2017-02-24 14:46:27 +00:00
Martin Staffa 603b66e1fa docs(changelog): insert release notes for 1.2.32
They were only in the v1.2.x branch.
2017-02-24 11:09:11 +01:00
Martin Staffa 295043d32e docs($compile): clarify to which element scope isolation applies
Closes #13556
2017-02-22 21:05:44 +01:00
waahhhh 892d236afc docs(changelog): correct typo
changed spelling from "auto-bootstraping" to "auto-bootstrapping".

Closes #15729
2017-02-21 15:20:14 +01:00
Peter Bacon Darwin b7ee5ee3c6 chore(jenkins): disable unit testing on Safari
There is a strange failure in the animation code that only appears to happen
on Safari 10 on OS/X. While we investigate we are disabling this browser
to allow the development (and doc generation) to continue.
2017-02-20 20:09:38 +00:00
Georgios Kalpakas b55637a8f7 fix($animate): reset classNameFilter to null when a disallowed RegExp is used
Closes #14913
2017-02-17 11:26:23 +02:00
Georgios Kalpakas 9a2efb7b66 fix($animate): improve detection on ng-animate in classNameFilter RegExp
Fixes #14806
2017-02-17 11:26:21 +02:00
Martin Staffa db46d24491 chore(docs-app): add debounce to search input
This fixes issues where the search results do not correctly reflect
the search query. This happens in Firefox when you enter a search query
very rapidly.
There is probably an issue with the async behavior of the search / webworker,
so this is just a workaround.
2017-02-16 14:28:43 +01:00
Keith Walsh f779230f70 docs($resource): add minor clarification
Closes #15711
2017-02-16 11:59:35 +02:00
Martin Staffa 62494bae38 chore(docs-app): update links in header menu
They are now in the same order as angularjs.org

Closes #14351
2017-02-15 15:53:51 +01:00
Martin Staffa f85656e934 chore(docs-app): update the header style
Also adds a new fixed strip / bar about the AngularJS version

Closes #14963
Closes #15670
2017-02-15 15:53:51 +01:00
Martin Staffa b9d3185e52 docs(select, ngOptions): add ngAttrSize as argument
Closes #1619
2017-02-15 15:25:25 +01:00
Martin Staffa 43cf54c3a2 docs(ngModelController): improve $formatters and $parsers info
Closes #11714
Closes #8194
2017-02-15 13:05:15 +01:00
Martin Staffa 15149c1da1 docs(filterFilter): add note about self-referencing objects in array
Relate #6655, #6319
2017-02-15 12:19:06 +01:00
Martin Staffa 23e747331b docs(guide/directive): clarify which type of matching directives support
Closes #15710
2017-02-15 12:19:06 +01:00
Georgii Dolzhykov 71f437c15a refactor($rootScope): remove extraneous call to $parse in $evalAsync
Closes #15682
2017-02-09 23:38:03 +02:00
Michał Gołębiowski 2c7400e7d0 chore(jenkins): get rid of Opera from the Jenkins build script
The Opera launcher hasn't been installed for ages, but until Karma 1.4.0 the
error of Opera not being able to start was ignored. Karma has fixed the bug and
now Jenkins is failing.

This commit also removes Opera/Opera launcher mentions from the docs. We don't
support Opera officially anymore (it's sort-of supported via being based on
Blink).

Closes #15691
2017-02-09 12:56:59 +02:00
PRIJCK Frederik (FPRJ) 2af2607fba fix(filterFilter): don't throw if key.charAt is not a function
Previously, when an object has keys which are not of type string, `filterFilter`
would throw an exception for trying to call `key.charAt()`, which is a string
method.

This commit checks whether `charAt` is defined before calling it.

Fixes #15644

Closes #15660
2017-02-08 23:17:26 +02:00
mohamed amr a0641ea475 feat(errorHandlingConfig): make the depth for object stringification in errors configurable
Closes #15402
Closes #15433
2017-02-08 19:05:43 +02:00
Martin Staffa 538f4606ff fix(select): add attribute "selected" for select[multiple]
This helps screen readers identify the selected options,
see #14419
2017-02-08 17:44:47 +01:00
Martin Staffa 4385e1268a fix(select): keep original selection when using shift to add options in IE/Edge
In IE9-11 + Edge, the selected options were previously incorrect under the following
circumstances:
- at least two options are selected
- shift+click or shift+down/up is used to add to the selection (any number of options)

In these cases, only the last of the previously selected options and the newly selected
options would be selected.

The problems seems to be that the render engine gets confused when an option that
already has selected = true gets selected = true set again.

Note that this is not testable via unit test because it's not possible to simulate
click / keyboard events on option elements (the events are delegated to the select element
change event), and the problem also doesn't appear when modifying the option elements directly
and then using the selectController API. It seems that this only happens when you manipulate the
select directly in the user interface.

Fixes #15675
Closes #15676
2017-02-08 17:44:47 +01:00
Martin Staffa ba8b924bf5 test($http): ensure json deserialization errors are forwarded to error handler
Since https://github.com/angular/angular.js/commit/e13eeabd7e34a78becec06cfbe72c23f2dcb85f9,
errors thrown from onFulfilled and onRejected handlers are passed to the regular http
error handlers. Before this, JSON deserialization errors lead to hard application errors, and could
not be handled by application code. This behavior was introduced in https://github.com/angular/angular.js/commit/7b6c1d08aceba6704a40302f373400aed9ed0e0b, and originally, a malformed JSON string was forwarded
as the data to the http success response handler.

This commit adds a specifc test case, even though the behavior is unlikely to break in the future without
a change in the $q rejection handling.

Related #11433
Closes #15689
2017-02-08 17:41:23 +01:00
Matt Lewis 0ce9348bc0 fix($jsonpCallbacks): allow $window to be mocked in unit tests
Fixes #15685

Closes #15686
2017-02-08 18:07:17 +02:00
Georgios Kalpakas a29f66c465 chore(*): update dependencies (including changez-angular) 2017-02-08 18:07:17 +02:00
Georgios Kalpakas 79c4a712d7 docs(changelog): update with changes for 1.6.2 2017-02-07 15:26:25 +02:00
Martin Staffa 2f667b177c docs(guide/scopes): mention component directive scopes, reorder info
Closes #15634
2017-02-06 17:25:14 +01:00
Martin Staffa 07f34e7af3 docs: fix some dangling links
They broke during the Angular -> AngularJS rename
2017-02-06 16:42:49 +01:00
Georgios Kalpakas 493b4967de test($resource): fix broken test
(Introduced while "cleaning up" the tests for in edfb691.)
2017-02-05 17:56:51 +02:00
Georgios Kalpakas 8c1b4c020d refactor(*): remove ignored expensiveChecks argument passed to $parse()
This is a follow-up to #15094.

Closes #15680
2017-02-05 15:38:27 +02:00
Kyle Wuolle edfb691deb fix($resource): do not swallow errors in success callback
Previously, errors thrown inside the `success` callback would be swallowed by a
noop `catch()` handler. The `catch()` handler was added in order to avoid an
unnecessary "Possibly Unhandled Rejection" error, in case the user provided an
`error` callback (which would handle request errors).

The handler was added too "eagrly" and as a result would swallow errors thrown
in the `success` callback, despite the fact that those errors would _not_ be
handled by the `error` callback.

This commit fixes this, by adding the `catch()` handler "lazily", only when it
is certain that a rejection will be handled by the `error` callback.

Fixes #15624

Closes #15628
2017-02-04 21:00:32 +02:00
Kindy Lin 8162362217 fix($parse): make sure ES6 object computed properties are watched
Add the missing watches for ES6 object computed properties which were
implemented in #14407.

Closes #15678
2017-02-04 16:16:04 +02:00
Dimitris Vardoulakis 15581287a4 refactor(*): avoid non-existent property warnings from Closure Compiler
Closes #15672
2017-02-02 22:37:17 +02:00
Chris fd76d872fc docs(misc/started): update Twitter handle (@angularjs --> @angular)
Closes #15671
2017-02-02 19:29:25 +02:00
Jessica Soltero 3708162bc8 docs(guide/expression): typo in one-time-binding
Closes #15668
2017-02-02 12:45:10 +02:00
Michał Gołębiowski 813117da31 refactor($injector): remove the Chrome stringification hack
The Chrome stringification hack added in afcedff34c
is no longer needed. I verified that both of the commented out tests pass
on Chrome 56.
2017-02-01 15:02:11 +00:00
Michał Gołębiowski dc8762eff1 chore(anchorScroll): remove a Jasmine toHaveBeenCalled workaround
The Jasmine fix landed long time ago and we've updated Jasmine since that
happened.
2017-02-01 13:36:08 +00:00
Michał Gołębiowski 1e3c7d2922 docs($location): fix examples
The examples contained tests with assertions in form of regular equality
comparisons which would be noops and in case of an error nothing would get
reported. Also, one of the test mixed a HTML5 browser scenario with a non-HTML5
one.
2017-02-01 13:35:01 +00:00
Michał Gołębiowski 187fce7cdf docs($animation): fix weird spaces around colons 2017-02-01 13:29:06 +00:00
Peter Bacon Darwin 2b00e8893e feat(ngModel): add $overrideModelOptions support
This change allows developers to modify the model options for an `ngModel`
directive programmatically.

Closes #15415
2017-02-01 12:19:37 +00:00
Patrick McElhaney d03357a320 docs(guide/component): add replace option
Add `replace` to the table comparing components to directives options. The
`replace` option is deprecated, but it is still documented for directives, so
it is worth pointing it out as a difference between directives and components.

Closes #15658
2017-01-31 19:34:29 +02:00
Georgios Kalpakas 03dbd94cb8 fix($compile): do not swallow thrown errors in test
In e13eeab, errors/rejections produced during fetching the template or compiling
an asynchronous directive, where overzealously silenced. This doesn't make any
difference in (most) production apps, where `$exceptionHandler` does not rethrow
the errors. In tests though (where `$exceptionHandler` rethrows by default), it
can unexpectedly "swallow" thrown errors.

This commit fixes it by removing the extraneous `.catch(noop)`, thus letting
errors thrown by `$exceptionHandler` to surface.

The changes in 'compileSpec.js' essentially revert the modifications that were
unnecessarily (and incorrectly) done in e13eeab (and also one incorrect
modification from [c22615c][1]).

[1]: https://github.com/angular/angular.js/commit/c22615cbfbaa7d1712e79b6bf2ace6eb41313bac#diff-348c2f3781ed66a24894c2046a52c628L2084

Fixes #15629

Closes #15631
2017-01-30 19:23:50 +02:00
Peter Bacon Darwin 0ef193f1a3 chore(docs): don't use bower for docs dependencies 2017-01-30 13:31:56 +00:00
Frederik Prijck dea8ae9af0 chore(doc-gen): show arguments as a subsection of the usage section
Previously, on the docs of directives which include the `animation` section, `arguments` are shown as an `h3` element below the `animation` `h2` element, making it look like it's a subsection of `animations`.

This commit ensures that the àrgument` `h3`element is rendered correctly after the `usage` `h2` element.

Fixes #15645
Closes #15646
2017-01-28 15:20:05 +01:00
vteremasov 39a90a9c20 fix($resource): correctly unescape /\. even if \. comes from a param value
Closes #15627
2017-01-27 18:15:49 +02:00
Jason Bedard fd4f011118 perf($compile): do not use deepWatch in literal one-way bindings
Avoiding deep watchers for array/object literals will improve watcher
performance of all literals passed as one-way bindings, especially those
containing references to large/complex objects.

BREAKING CHANGE:
Previously when a literal value was passed into a directive/component via
one-way binding it would be watched with a deep watcher.

For example, for `<my-component input="[a]">`, a new instance of the array
would be passed into the directive/component (and trigger $onChanges) not
only if `a` changed but also if any sub property of `a` changed such as
`a.b` or `a.b.c.d.e` etc.

This also means a new but equal value for `a` would NOT trigger such a
change.

Now literal values use an input-based watch similar to other directive/component
one-way bindings. In this context inputs are the non-constant parts of the
literal. In the example above the input would be `a`. Changes are only
triggered when the inputs to the literal change.

Closes #15301
2017-01-27 10:05:51 +00:00
Jason Bedard 7084deccaa feat($parse): allow watching array/object of inputs to literal values
The inputs of array/object literals are now watched for changes.
If the an input changes then a new instance of the literal will be
provided when the parsed expression is executed.

Closes #15301
2017-01-27 10:05:50 +00:00
frederikprijck 7019d9f27a fix($sniffer): allow history for NW.js apps
Previously `$sniffer` incorrectly detected NW.js apps as Chrome Packaged Apps,
disallowing them to use the history API.

This commit correctly detects NW.js apps and allows them to use the History API.

Fixes #15474

Closes #15633
2017-01-27 00:11:58 +02:00
Martin Staffa 89f3e3b0af fix(select): keep ngModel when selected option is recreated by ngRepeat
Fixes #15630 
Closes #15632
2017-01-26 13:29:11 +01:00
Georgios Kalpakas 641e13acc1 refactor(*): replace HashMap with NgMap
For the time being, we will be using `NgMap`, which is an API-compatible
implementation of native `Map` (for the features required in Angular). This will
make it easy to switch to using the native implementations, once they become
more stable.

Note:
At the moment some native implementations are still buggy (often in subtle ways)
and can cause hard-to-debug failures.)

Closes #15483
2017-01-25 23:20:18 +02:00
Georgios Kalpakas 028fa1abb2 test(hashKey): add tests for hashKey() 2017-01-25 23:17:06 +02:00
Martin Staffa 3c259ce624 docs(ngDisabled): list some elements that natively support
Closes #15473
2017-01-25 20:07:50 +01:00
Martin Staffa ef7d18b1c4 docs($compile): fix AngularJS versions 2017-01-25 20:03:04 +01:00
Peter Bacon Darwin 03043839d5 docs(*): ensure naming is correct for Angular(JS) versions 2017-01-25 08:18:39 +00:00
Georgios Kalpakas d24617bf32 fix(ngAnimate): correctly animate transcluded clones with templateUrl
Previously, `$animate` would decide whether an animation should be cancelled
based on some assumption that didn't hold in specific cases (e.g. when animating
transcluded clones with `templateUrl` directives on them for the first time). As
a result, the entering elements would not be animated in such cases. This
affected commonly used, structural built-in directives (`ngIf`, `ngRepeat`,
`ngSwitch` etc).
This commit fixes it by avoiding invalid assumptions (i.e. by taking into
account the transformations that take place while compiling such elements).

Partly addresses #14074 and #14124.

Fixes #15510

Closes #15514
2017-01-24 23:54:33 +02:00
Georgios Kalpakas 2b7a359363 test(ngAnimate): make expectations more specific 2017-01-24 23:54:33 +02:00
Georgios Kalpakas e7d8eee46d refactor(ngAnimate): simplify functions and remove redundant args/calls
Simplifies/Optimizes the following functions:

- `areAnimationsAllowed()`
- `cleanupEventListeners()`
- `closeChildAnimations()`
- `clearElementAnimationState()`
- `markElementAnimationState()`
- `findCallbacks()`

Although not its primary aim, this commit also offers a small performance boost
to animations (~5% as measured with the `animation-bp` benchmark).
2017-01-24 23:54:32 +02:00
Georgios Kalpakas 565ca6a1f5 chore(benchmarks): add basic animation benchmark 2017-01-24 23:54:32 +02:00
Georgios Kalpakas 54a7caf667 docs(*): document the breaking change in 7ceb5f6 2017-01-20 22:47:27 +02:00
Peter Bacon Darwin eba7c28261 chore(package): relax yarn version constraint 2017-01-19 08:18:40 +00:00
Peter Bacon Darwin 83b67b6c54 revert:docs(guide/scope): access the current element's scope in the console
This reverts commit c6bd58eb58.
The recommended approach of just typing scope does not appear to work out of the box.

See https://github.com/angular/angular.js/pull/4884#issuecomment-273686380
2017-01-19 07:55:33 +00:00
frederikprijck d85b3f56ac fix(ngValue): correctly update the value property when value is undefined
Previously, when the expression evaluated to `undefined` the `value` property
was not updated. This happened because jqLite/jQuery's `prop(_, undefined)` is
treated as a getter, thus not apdating the property.

This commit fixes it by setting the property to `null` instead.
(On IE9 we use `''` - see inline comments for more info.)

Fixes #15603

Closes #15605
2017-01-18 19:01:11 +02:00
Raphael Jamet 1cf728e209 fix($compile) : add base[href] to the list of RESOURCE_URL context attributes
Previously, `base[href]` didn't have an SCE context. This was not ideal, because
`base[href]` affects the behavior of all relative URLs across the page.
Furthermore, since #15145, `base[href]` also affects which URLs are considered
trusted under the 'self' policy for white- or black-listed resource URLs.

This commit tightens the security of Angular apps, by adding `base[href]` to the
list of RESOURCE_URL context attributes, essentially putting the same
constraints on bindings to `base[href]` as on iframe or script sources.

Refer to the
[`$sce` API docs](https://code.angularjs.org/snapshot/docs/api/ng/service/$sce)
for more info on SCE trusted contexts.

Closes #15597

BREAKING CHANGE:

Previously, `<base href="{{ $ctrl.baseUrl }}" />` would not require `baseUrl` to
be trusted as a RESOURCE_URL. Now, `baseUrl` will be sent to `$sce`'s
RESOURCE_URL checks. By default, it will break unless `baseUrl` is of the same
origin as the application document.

Refer to the
[`$sce` API docs](https://code.angularjs.org/snapshot/docs/api/ng/service/$sce)
for more info on how to trust a value in a RESOURCE_URL context.

Also, concatenation in trusted contexts is not allowed, which means that the
following won't work: `<base href="/something/{{ $ctrl.partialPath }}" />`.

Either construct complex values in a controller (recommended):

```js
this.baseUrl = '/something/' + this.partialPath;
```
```html
<base href="{{ $ctrl.baseUrl }}" />
```

Or use string concatenation in the interpolation expression (not recommended
except for the simplest of cases):

```html
<base href="{{ '/something/' + $ctrl.partialPath }}" />
```
2017-01-18 12:02:15 +02:00
Martin Brown 675f99bc5a docs(guide/i18n): fix typos
Closes #15616
2017-01-17 18:09:19 +02:00
Georgios Kalpakas 5b6763f575 docs(changelog): update with changes for 1.5.11 2017-01-13 01:07:45 +02:00
Georgios Kalpakas 22392ef949 style($compile): remove trailing whitespace 2017-01-12 23:12:01 +02:00
Grace Benz f63c46406f docs($compile): add some detail about $onChanges
Closes #15604
2017-01-12 22:39:47 +02:00
Georgios Kalpakas 3983a66eda test(e2e): make test less flakey-prone 2017-01-12 22:24:49 +02:00
Peter Bacon Darwin 74e232dab7 fix(ngMockE2E): ensure that mocked $httpBackend uses correct $browser
The fix from #13124 enabled ngMock and ngMockE2E to work together but
did it in a way that meant that the "real" `$httpBackend` service that
was used in pass-through depended upon a different `$browser` service
to the rest of the app.

This broke Protractor since it watches the `$browser` for outstanding
requests and the pass through requests were being tracked by the wrong
`$browser` instance.

Closes #15593
2017-01-12 09:46:24 +00:00
Georgios Kalpakas 2e27df690c chore(*): update dgeni-packages (and other devDependencies)
`dgeni-packages` prior to version 0.16.3 specified `engine.yarn: '^0.17.9'`,
which was unnecessarily strict and would cause any task to fail if someone had a
yarn version >=0.18.0.
Other devDependencies were also updated (because why not).

Closes #15600
2017-01-12 00:33:26 +02:00
Sammy Jelin c522a43f41 fix($route): make asynchronous tasks count as pending requests
Protractor users were having a problem where if they had asynchonous code in a
`route.resolve` or `route.resolveRedirectTo` variable, Protractor was not
waiting for that code to complete before continuing. See
https://github.com/angular/protractor/issues/789#issuecomment-190983200 for
details.

This commit fixes it by ensuring that `$browser#outstandingRequestCount` is
properly increased/decreased while `$route` (asynchronously) processes a route.

Also, enhanced `ngMock` to wait for pending requests, before calling callbacks
from `$browser.notifyWhenNoOutstandingRequests()`.

Related to angular/protractor#789.

Closes #14159
2017-01-12 00:07:22 +02:00
frederikprijck 9c722cfcd2 fix($compile): allow the usage of "$" in isolate scope property alias
Previously, when using an alias for an isolate scope or `bindings` property
(e.g. `alias: '<attrName'` instead of `attrName: '<'`), a `$compile:iscp` error
was thrown if the attribute name contained a "$".
This commit removes the error by changing the regex to allow "$" characters in
the attribute name when using a property alias.

Fixes: #15586

Closes #15594
2017-01-11 11:39:03 +02:00
Alex Dobkin 9412962696 fix($sce): consider document base URL in 'self' URL policy
Page authors can use the `<base>` tag in HTML to specify URL to use as a base
when resovling relative URLs. This can cause SCE to reject relative URLs on the
page, because they fail the same-origin test.

To improve compatibility with the `<base>` tag, this commit changes the logic
for matching URLs to the 'self' policy to allow URLs that match the protocol and
domain of the base URL in addition to URLs that match the loading origin.

**Security Note:**
If an attacker can inject a `<base>` tag into the page, they can circumvent SCE
protections. However, injecting a `<base>` tag typically requires the ability to
inject arbitrary HTML into the page, which is a more serious vulnerabilty than
bypassing SCE.

Fixes #15144

Closes #15145
2017-01-10 14:20:15 +02:00
Georgios Kalpakas 752f411c8b fix($location): correctly handle external URL change during $digest
Previously, when the URL was changed directly (e.g. via `location.href`) during
a `$digest` (e.g. via `scope.$evalAsync()` or `promise.then()`) the change was
not handled correctly, unless a `popstate` or `hashchange` event was fired
synchronously.

This was an issue when calling `history.pushState()/replaceState()` in all
browsers, since these methods do not emit any event. This was also an issue when
setting `location.href` in IE11, where (unlike other browsers) no `popstate`
event is fired at all for hash-only changes ([known bug][1]) and the
`hashchange` event is fired asynchronously (which is too late).

This commit fixes both usecases by:

1. Keeping track of `$location` setter methods being called and only processing
   a URL change if it originated from such a call. If there is a URL difference
   but no setter method has been called, this means that the browser URL/history
   has been updated directly and the change hasn't yet been propagated to
   `$location` (e.g. due to no event being fired synchronously or at all).
2. Checking for URL/state changes at the end of the `$digest`, in order to
   detect changes via `history` methods (that took place during the `$digest`).

[1]: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/3740423/

Fixes #11075
Fixes #12571
Fixes #15556

Closes #15561
2017-01-09 23:58:10 +02:00
Georgios Kalpakas 2b360bf305 fix(*): detect external changes in history.state
Previously, `$browser.$$checkUrlChange()` (which was run before each `$digest`)
would only detect an external change (i.e. not via `$location`) to the browser
URL. External changes to `history.state` would not be detected and propagated to
`$location`.

This would not be a problem if changes were followed by a `popstate` or
`hashchange` event (which would call `cacheStateAndFireUrlChange()`). But since
`history.pushState()/replaceState()` do not fire any events, calling these
methods manually would result in `$location` getting out-of-sync with the actual
history state.

This was not detected in tests, because the mocked `window.history` would
incorrectly trigger `popstate` when calling `pushState()/replaceState()`, which
"covered" the bug.

This commit fixes it by always calling `cacheState()`, before looking for and
propagating a URL/state change.
2017-01-09 23:57:31 +02:00
Nikhil Wins c00903be7a refactor($interpolate): remove unnecessary else
Closes: #15575
2017-01-05 13:57:56 +01:00
David Jöch 3776b2ef30 style($log): fix indentation
Closes #15579
2017-01-05 13:02:01 +02:00
Florian Berger e193cda800 docs(*): fix typos
Closes #15577
2017-01-05 11:04:17 +02:00
Nic Mitchell 296e9f6cdf chore(*): update copyright year
Closes #15573
2017-01-04 12:14:45 +02:00
Georgios Kalpakas 035f1cd90e docs(guide/$location): correctly format heading 2017-01-03 22:36:28 +02:00
Georgios Kalpakas 0694af8fc4 fix(angularInit): allow auto-bootstraping from inline script
Some browsers (e.g. Safari 9.x, PhantomJS) do not set `link.origin/protocol`
correctly, when setting `link.href` to `null`, which prevented auto-bootstraping
Angular from scripts without a `src` attribute (i.e. inline scripts).
Inline scripts are on the same origin as the loading page, so auto-bootstraping
should be allowed.

Fixes #15567

Closes #15571
2017-01-03 19:14:57 +02:00
Soumya Ranjan Mohanty 090a839ac9 docs(guide/services): fix syntax for Jasmine v2.x
Closes #15570
2017-01-03 16:13:22 +02:00
Georgios Kalpakas 5294d208ae docs(ngShow/ngHide): improve docs and fix inconsistencies between ngShow/ngHide
Closes #15471
2017-01-03 12:41:11 +02:00
Deco 4082fb03b6 docs(tutorial/step_04): fix typo
Closes #15562
2016-12-31 12:31:31 +02:00
Georgios Kalpakas a24777a2c4 fix(input): fix step validation for input[type=number/range]
Previously, the validation would incorrectly fail in certain cases (e.g.
`step: 0.01`, `value: 1.16 or 20.1`), due to Floating Point Arithmetic
limitations. The previous fix for FPA limitations (081d06ff) tried to solve the
issue by converting the numbers to integers, before doing the actual
calculation, but it failed to account for cases where the conversion itself
returned non-integer values (again due to FPA limitations).
This commit fixes it by ensuring that the values used in the final calculation
are always integers.

Fixes #15504

Closes #15506
2016-12-29 10:16:07 +02:00
Georgios Kalpakas 99a3adbdaa docs(CHANGELOG.md): add missing commas 2016-12-29 10:08:40 +02:00
supasak 922a83e94f fix($resource): delete $cancelRequest() in toJSON()
Closes #15244
2016-12-29 10:00:42 +02:00
Peter Bacon Darwin ee1458fdba docs(CHANGELOG): add 1.6.1 release info 2016-12-23 10:53:38 +00:00
Peter Bacon Darwin cfc16b17f7 chore(deps): update changez-angular version 2016-12-23 10:52:32 +00:00
Naomi Black 8ceeeccdd7 docs(guide/forms): remove implicit bias from example
Closes #15543
2016-12-23 11:42:16 +02:00
Thomas Grainger 316f60fd14 fix($q): Add traceback to unhandled promise rejections
Fixes #14631
Closes #15527
2016-12-21 20:08:24 +01:00
sp00m f768da2488 fix($$cookieReader): correctly handle forbidden access to document.cookie
In certain cases (e.g. on LG webOS using the `file:` protocol), access to
`document.cookie` may not be allowed and throw an error. This could break
`$http` which relies on `$$cookieReader()` for retrieving the XSRF token.
This commit fixes it by treating `document.cookie` as empty, when access to it
is fordibben.

Fixes  #15523

Closes #15532
2016-12-20 23:28:34 +02:00
Simon Legner c898ae9e45 docs(CHANGELOG): fix typo
Closes #15529
2016-12-20 10:29:36 +02:00
Thomas Grainger 47b14bf3e3 docs(guide/migration): improve grammar
Closes #15526
2016-12-20 01:16:24 +02:00
Georgios Kalpakas 4e143fcae3 fix(ngOptions): do not unset the selected property unless necessary
Previously, when updating the value of a `select[multiple]` element, all options
were first set to `selected = false` and then the selected ones were set to
`true`. By setting an already selected option to `selected = false` and then
`true` again - essentially unselecting and reselecting it - caused some browsers
(including Firefox, IE and under some circumstances Chrome) to unexpectedly
scroll to the last selected option.

This commit fixes it by ensuring that the `selected` property is only set if its
current value is different than the new one and even then it is set to its final
value at once (i.e. without first setting it to `false`), thus avoiding the
undesirable behavior.

Fixes #15477

Closes #15478
2016-12-19 22:44:36 +02:00
Peter Neave 15d07c0108 docs(tutorial/step_13): add missing dependency phoneDetails module
Closes #15521
2016-12-19 20:53:38 +02:00
Peter Bacon Darwin d08e31984d chore(doc-gen): update to dgeni-packages@0.16.2 2016-12-16 14:08:37 +00:00
Georgios Kalpakas fbe0b73ab5 docs(CHANGELOG.md): remove reverted bug fix
Related to 02f045b.
2016-12-16 11:11:22 +02:00
Peter Bacon Darwin 07987e26e9 docs(CHANGELOG): add note to 1.5.0-beta.1 2016-12-15 20:41:13 +00:00
Georgios Kalpakas c6842b5a65 docs(CHANGELOG.md): add changes for v1.5.10 2016-12-15 19:18:29 +02:00
Georgios Kalpakas baa30695f3 docs(CHANGELOG.md): add missing entries for v1.6.0-rc.0/v1.6.0 2016-12-15 19:18:28 +02:00
Georgios Kalpakas d03cac4cd5 docs($q): document the default value for errorOnUnhandledRejections 2016-12-14 00:43:52 +02:00
Jannick Fahlbusch e9a4de035d docs($interval): improve fn description
If no additional arguments are passed, the function is called with the current iteration count.

Closes #15503
2016-12-13 14:07:58 +02:00
Georgios Kalpakas ce8abac66d fix(ngModelOptions): work correctly when on the template of replace directives
Previously, in order for `ngModel` and `ngModelOptions` to work correctly
together, the latter's pre-linking function should be run before the former's
pre-linking function. This was typically what happened, except when `ngModel`
was used on an element which also had a `replace` directive, whose template
included `ngModelOptions`. In that case, the order was reversed.

This commit fixes it by moving the initialization logic of `ngModelOptions` from
its pre-linking function to its controller's `$onInit()` lifecycle hook.

Fixes #15492

Closes #15493
2016-12-13 00:09:56 +02:00
Georgios Kalpakas fade1db253 refactor(testabilityPatch): remove code duplication 2016-12-13 00:04:57 +02:00
Aaron Brewer 29f3bf4bd6 docs(ngMessageExp): improve description
Closes #15486
2016-12-11 20:58:13 +02:00
idhindsight 7f8bc587ae docs(tutorial/step_09): fix typo (it's --> its)
Closes #15485
2016-12-10 22:15:35 +02:00
David Rodenas Pico 1ecf6efa81 chore(benchpress): add an ngClass benchmark
Closes #15243
2016-12-09 12:20:31 +02:00
Georgios Kalpakas b82097085d perf(ngClass): avoid unnecessary .data() accesses, deep-watching and copies
Includes the following commits (see #15246 for details):

- **perf(ngClass): only access the element's `data` once**

- **refactor(ngClass): simplify conditions**

- **refactor(ngClass): move helper functions outside the closure**

- **refactor(ngClass): exit `arrayDifference()` early if an input is empty**

- **perf(ngClass): avoid deep-watching (if possible) and unnecessary copies**

  The cases that should benefit most are:

  1. When using large objects as values (e.g.: `{loaded: $ctrl.data}`).
  2. When using objects/arrays and there are frequent changes.
  3. When there are many `$index` changes (e.g. addition/deletion/reordering in large `ngRepeat`s).

  The differences in operations per digest include:

  1. `Regular expression (when not changed)`
     **Before:** `equals()`
     **After:**  `toClassString()`

  2. `Regular expression (when changed)`
     **Before:** `copy()` + 2 x `arrayClasses()` + `shallowCopy()`
     **After:**  2 x `split()`

  3. `One-time expression (when not changed)`
     **Before:** `equals()`
     **After:**  `toFlatValue()` + `equals()`*

  4. `One-time expression (when changed)`
     **Before:** `copy()` + 2 x `arrayClasses()` + `shallowCopy()`
     **After:**  `copy()`* + `toClassString()`* + 2 x `split()`

  5. `$index modulo changed`
     **Before:** `arrayClasses()`
     **After:**  -

  (*): on flatter structure

  In large based on #14404. Kudos to @drpicox for the initial idea and a big part
  of the implementation.

Closes #14404

Closes #15246
2016-12-09 11:49:10 +02:00
Georgios Kalpakas 5fd5e131b6 fix(ngClassOdd/Even): add/remove the correct classes when expression/$index change simultaneously 2016-12-09 11:49:09 +02:00
David Rodenas Pico 7b2ed4ae41 test(ngClass): add some tests about one-time bindings and objects inside arrays 2016-12-09 11:49:09 +02:00
Georgios Kalpakas 7c80d8afa9 refactor(ngClass): remove redundant $observer and dependency on $animate
Includes the following commits (see #15246 for details):

- **refactor(ngClass): remove unnecessary dependency on `$animate`**

- **refactor(ngClass): remove redundant `$observe`r**

  The code was added in b41fe9f in order to support having both `ngClass` and
  interpolation in `class` work together. `ngClass` has changed considerably since
  b41fe9f and for simple cases to work the `$observe`r is no longer necessary (as
  indicated by the expanded test still passing).

  That said, it is a [documented known issue][1] that `ngClass` should not be used
  together with interpolation in `class` and more complicated cases do not work
  anyway.

[1]: https://docs.angularjs.org/api/ng/directive/ngClass#known-issues
2016-12-09 11:48:02 +02:00
Aman Mittal d05f894aff docs(guide/external-resources): add "AngularJS in Action" book
Closes #15480
2016-12-09 11:34:53 +02:00
Georgios Kalpakas 1c0c2605d3 fix($rootScope): when adding/removing watchers during $digest
Previously, adding a watcher during a `$digest` (i.e. from within a watcher),
would result in the next watcher getting skipped. Similarly, removing a watcher
during a `$digest` could result in the current watcher being run twice (if the
removed watcher had not run yet in the current `$digest`).

This commit fixes both cases by keeping track of the current watcher index
during a digest and properly updating it when adding/removing watchers.

Fixes #15422

Closes #15424
2016-12-09 10:39:54 +02:00
Peter Bacon Darwin 5b477614ff chore(docs): fix plnkrOpener to use $onInit
Since 1.6.0 does not preassign bindings before running the controller
constructor function, we must move initialisation into the `$onInit`
method.
2016-12-09 01:12:59 +00:00
Peter Bacon Darwin 9595337f67 chore(package): update docs app to run on 1.6.0 2016-12-08 23:42:55 +00:00
Georgios Kalpakas a9e91461a8 fix(jqLite): silently ignore after() if element has no parent
Previously, the element was always assumed to have a parent and an error was
thrown when that was not the case.
This commit makes jqLite consistent with jQuery, which silently ignores a call
on elements that do not have a parent.

Fixes #15331
Closes #15367

Closes #15475
2016-12-08 18:11:34 +02:00
Peter Bacon Darwin 4e7f652b5f chore(package): update dist-tag for master/1.7 2016-12-08 13:56:34 +00:00
1000 changed files with 66458 additions and 44632 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# http://editorconfig.org
# https://editorconfig.org
root = true
+1 -2
View File
@@ -1,6 +1,4 @@
bower_components/**
build/**
docs/bower_components/**
docs/app/assets/js/angular-bootstrap/**
docs/config/templates/**
node_modules/**
@@ -9,3 +7,4 @@ src/angular.bind.js
src/ngParseExt/ucd.js
i18n/closure/**
tmp/**
vendor/**
+7 -2
View File
@@ -1,8 +1,13 @@
{
"extends": "./.eslintrc-base.json",
"env": {
"browser": false,
"node": true
}
},
"parserOptions": {
"ecmaVersion": 2017
},
"plugins": [
"promise"
]
}
+29 -19
View File
@@ -1,27 +1,37 @@
***Note*: for support questions, please use one of these channels: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question. This repository's issues are reserved for feature requests and bug reports.**
<!--
IF YOU DON'T FILL OUT THE FOLLOWING INFORMATION WE MIGHT CLOSE YOUR ISSUE WITHOUT INVESTIGATION
-->
**Do you want to request a *feature* or report a *bug*?**
<!--
- For *SUPPORT QUESTIONS*, use one of the
[support channels](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question).
- Before submitting, please **SEARCH GITHUB** for a similar issue or PR. -->
**I'm submitting a ...**
<!-- (check one with "x") -->
- [ ] bug report
- [ ] feature request
- [ ] other <!--(Please do not submit support requests here - see above)-->
**Current behavior:**
<!-- Describe how the bug manifests / how the current features are insufficient. -->
**What is the current behavior?**
**Expected / new behavior:**
<!-- Describe what the behavior would be without the bug / how the feature would improve AngularJS -->
**Minimal reproduction of the problem with instructions:**
<!--
If the current behavior is a bug or you can illustrate your feature request better with an example,
please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:yBpEi4).
-->
**AngularJS version:** 1.x.y
<!-- Check whether this is still an issue in the most recent stable or in the snapshot AngularJS
version (https://code.angularjs.org/snapshot/) -->
**If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).**
**Browser:** [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView | Opera XX ]
<!-- All browsers where this could be reproduced (and Operating System if relevant) -->
**What is the expected behavior?**
**What is the motivation / use case for changing the behavior?**
**Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.**
**Other information (e.g. stacktraces, related issues, suggestions how to fix)**
**Anything else:**
<!-- e.g. stacktraces, related issues, suggestions how to fix -->
+4 -3
View File
@@ -1,3 +1,4 @@
<!-- General PR submission guidelines https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#submit-pr -->
**What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)**
@@ -15,9 +16,9 @@
**Please check if the PR fulfills these requirements**
- [ ] The commit message follows our guidelines: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
- [ ] The commit message follows our [guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits)
- [ ] Fix/Feature: [Docs](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#documentation) have been added/updated
- [ ] Fix/Feature: Tests have been added; existing tests pass
**Other information**:
+3 -4
View File
@@ -1,4 +1,5 @@
/build/
/deploy/
/benchpress-build/
.DS_Store
gen_docs.disable
@@ -9,8 +10,7 @@ performance/temp*.html
*~
*.swp
angular.js.tmproj
/node_modules/
bower_components/
node_modules/
angular.xcodeproj
.idea
*.iml
@@ -19,7 +19,6 @@ angular.xcodeproj
libpeerconnection.log
npm-debug.log
/tmp/
/scripts/bower/bower-*
.vscode
*.log
*.stackdump
*.stackdump
+29
View File
@@ -0,0 +1,29 @@
Andres Ornelas <aornelas@google.com>
Caitlin Potter <caitpotter88@gmail.com>
Caitlin Potter <caitpotter88@gmail.com> <snowball@defpixel.com>
Di Peng <pengdi@google.com>
Di Peng <pengdi@google.com> <pengdi@go.wustl.edu>
Georgios Kalpakas <kalpakas.g@gmail.com>
Georgios Kalpakas <kalpakas.g@gmail.com> <g.kalpakas@hotmail.com>
Julie Ralph <ju.ralph@gmail.com>
Lucas Galfaso <lgalfaso@gmail.com>
Martin Staffa <mjstaffa@gmail.com>
Martin Staffa <mjstaffa@gmail.com> <mjstaffa@googlemail.com>
Matias Niemelä <matias@yearofmoo.com>
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Misko Hevery <misko@hevery.com>
Misko Hevery <misko@hevery.com> <misko@google.com>
Igor Minar <igor@angularjs.org>
Igor Minar <igor@angularjs.org> <iiminar@gmail.com>
Igor Minar <igor@angularjs.org> <iminar@google.com>
Igor Minar <igor@angularjs.org> <iminar@dhcp-172-19-37-154.mtv.corp.google.com>
Pawel Kozlowski <pkozlowski.opensource@gmail.com>
Peter Bacon Darwin <pete@bacondarwin.com>
Rodric Haddad <rody@rodyhaddad.com>
Shahar Talmi <shahar.talmi@gmail.com>
Shahar Talmi <shahar.talmi@gmail.com> <shahart@wix.com>
Shyam Seshadri <shyamseshadri@google.com>
Shyam Seshadri <shyamseshadri@google.com> <shyamseshadri@gmail.com>
Vojta Jina <vojta.jina@gmail.com>
Vojta Jina <vojta.jina@gmail.com> <vojta@gemin-i.org>
Vojta Jina <vojta.jina@gmail.com> <vojta@google.com>
+1 -1
View File
@@ -1 +1 @@
6
8
+72 -29
View File
@@ -1,61 +1,104 @@
language: node_js
sudo: false
node_js:
- '6'
- '8'
cache:
directories:
- node_modules
- bower_components
- docs/bower_components
yarn: true
branches:
except:
- /^g3_.*$/
- "/^g3_.*$/"
env:
matrix:
- JOB=ci-checks
- JOB=unit BROWSER_PROVIDER=saucelabs
- JOB=docs-e2e BROWSER_PROVIDER=saucelabs
- JOB=unit-core BROWSER_PROVIDER=saucelabs
- JOB=unit-jquery BROWSER_PROVIDER=saucelabs
- JOB=unit-modules BROWSER_PROVIDER=saucelabs
- JOB=docs-app BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs
global:
- CXX=g++-4.8 # node 4 likes the G++ v4.8 compiler
- SAUCE_USERNAME=angular-ci
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
- LOGS_DIR=/tmp/angular-build/logs
- BROWSER_PROVIDER_READY_FILE=/tmp/browsersprovider-tunnel-ready
# 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
- secure: oTBjhnOKhs0qDSKTf7fE4f6DYiNDPycvB7qfSF5QRIbJK/LK/J4UtFwetXuXj79HhUZG9qnoT+5e7lPaiaMlpsIKn9ann7ffqFWN1E8TMtpJF+AGigx3djYElwfgf5nEnFUFhwjFzvbfpZNnxVGgX5YbIZpe/WUbHkP4ffU0Wks=
before_install:
- curl -o- -L https://raw.githubusercontent.com/yarnpkg/yarn/2a0afc73210c7a82082585283e518eeb88ca19ae/scripts/install-latest.sh | bash -s -- --version 0.17.9
- export PATH=$HOME/.yarn/bin:$PATH
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.10.1
- export PATH="$HOME/.yarn/bin:$PATH"
before_script:
- du -sh ./node_modules ./bower_components/ ./docs/bower_components/ || true
- ./scripts/travis/before_build.sh
- du -sh ./node_modules || true
- "./scripts/travis/before_build.sh"
script:
- ./scripts/travis/build.sh
- "./scripts/travis/build.sh"
after_script:
- ./scripts/travis/tear_down_browser_provider.sh
- ./scripts/travis/print_logs.sh
- "./scripts/travis/tear_down_browser_provider.sh"
- "./scripts/travis/print_logs.sh"
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/d2120f3f2bb39a4531b2
- http://104.197.9.155:8484/hubot/travis/activity #hubot-server
on_success: always # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: always # default: false
on_success: always # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: always # default: false
jobs:
include:
- stage: deploy
# Don't deploy from PRs. Only deploy from our default branches, or if commit is tagged.
# This is a Travis-specific boolean language: https://docs.travis-ci.com/user/conditional-builds-stages-jobs#Specifying-conditions
# The deployment logic for pushed branches is further defined in scripts\travis\build.sh
if: type != pull_request and (branch =~ ^(v1\.\d+\.x|master)$ or tag IS present)
env:
- JOB=deploy
before_script: skip
script:
# Export the variables into the current process
- . ./scripts/travis/build.sh
- "echo DEPLOY_DOCS: $DEPLOY_DOCS, DEPLOY_CODE: $DEPLOY_CODE"
after_script: skip
# Work around the 10min Travis timeout so the code.angularjs firebase+gcs code deploy can complete
# Only run the keep_alive once (before_deploy is run for each provider)
before_deploy: |
if ! [ "$BEFORE_DEPLOY_RUN" ]; then
export BEFORE_DEPLOY_RUN=1;
function keep_alive() {
while true; do
echo -en "\a"
sleep 10
done
}
keep_alive &
fi
deploy:
- provider: firebase
# the upload folder for firebase is configured in /firebase.json
skip_cleanup: true
project: docs-angularjs-org-9p2
token:
secure: $FIREBASE_TOKEN
on:
repo: angular/angular.js
all_branches: true
condition: "$DEPLOY_DOCS == true"
- provider: gcs
skip_cleanup: true
access_key_id: GOOGLDB7W2J3LFHICF3R
secret_access_key:
secure: tHIFdSq55qkyZf9zT/3+VkhUrTvOTMuswxXU3KyWaBrSieZqG0UnUDyNm+n3lSfX95zEl/+rJAWbfvhVSxZi13ndOtvRF+MdI1cvow2JynP0aDSiPffEvVrZOmihD6mt2SlMfhskr5FTduQ69kZG6DfLcve1PPDaIwnbOv3phb8=
bucket: code-angularjs-org-338b8.appspot.com
local-dir: deploy/code
detect_encoding: true # detects gzip compression
on:
repo: angular/angular.js
all_branches: true
condition: "$DEPLOY_CODE == true"
+2834 -43
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
# Contributor Code of Conduct
The AngularJS project follows the Code of Conduct defined in [the angular/code-of-conduct repository](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md). Please read it.
+116 -186
View File
@@ -3,85 +3,101 @@
We'd love for you to contribute to our source code and to make AngularJS even better than it is
today! Here are the guidelines we'd like you to follow:
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Coding Rules](#rules)
- [Commit Message Guidelines](#commit)
- [Signing the CLA](#cla)
- [Further Info](#info)
* [Code of Conduct](#coc)
* [Questions and Problems](#question)
* [Issues and Bugs](#issue)
* [Feature Requests](#feature)
* [Improving Documentation](#docs)
* [Issue Submission Guidelines](#submit)
* [Pull Request Submission Guidelines](#submit-pr)
* [Signing the CLA](#cla)
## <a name="coc"></a> Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc].
Help us keep AngularJS open and inclusive. Please read and follow our [Code of Conduct][coc].
## <a name="question"></a> Got a Question or Problem?
## <a name="requests"></a> Questions, Bugs, Features
If you have questions about how to use AngularJS, please direct these to the [Google Group][groups]
discussion list or [StackOverflow][stackoverflow]. We are also available on [IRC][irc] and
[Gitter][gitter].
### <a name="question"></a> Got a Question or Problem?
## <a name="issue"></a> Found an Issue?
Do not open issues for general support questions as we want to keep GitHub issues for bug reports
and feature requests. You've got much better chances of getting your question answered on dedicated
support platforms, the best being [Stack Overflow][stackoverflow].
If you find a bug in the source code or a mistake in the documentation, you can help us by
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
with a fix.
Stack Overflow is a much better place to ask questions since:
**Localization Issues:** Angular.js uses the [Google Closure I18N library] to generate
its own I18N files (the ngLocale module). This means that any changes to these files would be lost
the next time that we import the library.
- there are thousands of people willing to help on Stack Overflow
- questions and answers stay available for public viewing so your question / answer might help
someone else
- Stack Overflow's voting system assures that the best answers are prominently visible.
To save your and our time, we will systematically close all issues that are requests for general
support and redirect people to the section you are reading right now.
Other channels for support are:
- the [Google Group][groups] discussion list
- the [AngularJS IRC][irc]
- the [AngularJS Gitter][gitter]
### <a name="issue"></a> Found an Issue or Bug?
If you find a bug in the source code, you can help us by submitting an issue to our
[GitHub Repository][github]. Even better, you can submit a Pull Request with a fix.
**Please see the [Submission Guidelines](#submit) below.**
**Special Note for Localization Issues:** AngularJS uses the [Google Closure I18N library] to
generate its own I18N files (the ngLocale module). This means that any changes to these files
would be lost the next time that we import the library.
Since the Closure library i18n data is itself auto-generated from the data of the
[Common Locale Data Repository (CLDR)] project, errors in the data should
be reported there. See also the [Closure guide to i18n changes].
**Please see the [Submission Guidelines](#submit) below.**
### <a name="feature"></a> Missing a Feature?
## <a name="feature"></a> Want a Feature?
You can request a new feature by submitting an issue to our [GitHub Repository][github-issues].
You can request a new feature by submitting an issue to our [GitHub Repository][github]. If you
would like to implement a new feature then consider what kind of change it is:
If you would like to implement a new feature then consider what kind of change it is:
* **Major Changes** that you wish to contribute to the project should be discussed first on our
[dev mailing list][angular-dev] or [IRC][irc] so that we can better coordinate our efforts,
prevent duplication of work, and help you to craft the change so that it is successfully accepted
into the project.
* **Small Changes** can be crafted and submitted to the [GitHub Repository][github] as a Pull
Request.
* **Major Changes** that you wish to contribute to the project should be discussed first in an
[GitHub issue][github-issues] that clearly outlines the changes and benefits of the feature.
* **Small Changes** can directly be crafted and submitted to the [GitHub Repository][github]
as a Pull Request. See the section about [Pull Request Submission Guidelines](#submit-pr), and
for detailed information the [core development documentation][developers].
### <a name="docs"></a> Want a Doc Fix?
## <a name="docs"></a> Want a Doc Fix?
Should you have a suggestion for the documentation, you can open an issue and outline the problem
or improvement you have - however, creating the doc fix yourself is much better!
If you want to help improve the docs, it's a good idea to let others know what you're working on to
minimize duplication of effort. Create a new issue (or comment on a related existing one) to let
others know what you're working on.
If you're making a small change (typo, phrasing) don't worry about filing an issue first. Use the
friendly blue "Improve this doc" button at the top right of the doc page to fork the repository
in-place and make a quick change on the fly. The commit message is preformatted to the right type
and scope, so you only have to add the description.
For large fixes, please build and test the documentation before submitting the PR to be sure you
haven't accidentally introduced any layout or formatting issues. You should also make sure that your
commit message starts with "docs" and follows the **[Commit Message Guidelines](#commit)** outlined
below.
commit message follows the **[Commit Message Guidelines][developers.commits]**.
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue
"Improve this doc" button at the top right of the doc page to fork the repository in-place and make
a quick change on the fly. When naming the commit, it is advised to follow the commit message
guidelines below, by starting the commit message with **docs** and referencing the filename. Since
this is not obvious and some changes are made on the fly, this is not strictly necessary and we will
understand if this isn't done the first few times.
## <a name="submit"></a> Submission Guidelines
### Submitting an Issue
## <a name="submit"></a> Issue Submission Guidelines
Before you submit your issue search the archive, maybe your question was already answered.
If your issue appears to be a bug, and hasn't been reported, open a new issue. Help us to maximize
the effort we can spend fixing issues and adding new features, by not reporting duplicate issues.
Providing the following information will increase the chances of your issue being dealt with
quickly:
The "[new issue][github-new-issue]" form contains a number of prompts that you should fill out to
make it easier to understand and categorize the issue.
In general, providing the following information will increase the chances of your issue being dealt
with quickly:
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
* **Motivation for or Use Case** - explain why this is a bug for you
* **Angular Version(s)** - is it a regression?
* **AngularJS Version(s)** - is it a regression?
* **Browsers and Operating System** - is this a problem with all browsers or only specific ones?
* **Reproduce the Error** - provide a live example (using [Plunker][plunker] or
[JSFiddle][jsfiddle]) or an unambiguous set of steps.
@@ -89,41 +105,43 @@ quickly:
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit)
Here is a great example of a well defined issue: https://github.com/angular/angular.js/issues/5069
Here is a great example of a well defined issue: https://github.com/angular/angular.js/issues/5069.
**If you get help, help others. Good karma rulez!**
### Submitting a Pull Request
## <a name="submit-pr"></a> Pull Request Submission Guidelines
Before you submit your pull request consider the following guidelines:
* Search [GitHub](https://github.com/angular/angular.js/pulls) for an open or closed Pull Request
that relates to your submission. You don't want to duplicate effort.
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending pull
requests. We cannot accept code without this.
* Create the [development environment][developers.setup]
* Make your changes in a new git branch:
```shell
git checkout -b my-fix-branch master
```
* Create your patch, **including appropriate test cases**.
* Follow our [Coding Rules](#rules).
* Run the full Angular test suite, as described in the [developer documentation][dev-doc],
and ensure that all tests pass.
* Create your patch commit, **including appropriate test cases**.
* Follow our [Coding Rules][developers.rules].
* If the changes affect public APIs, change or add relevant [documentation][developers.documentation].
* Run the AngularJS [unit][developers.tests-unit] and [E2E test][developers.tests-e2e] suites, and ensure that all tests
pass. It is generally sufficient to run the tests only on Chrome, as our Travis integration will
run the tests on all supported browsers.
* Run `yarn grunt eslint` to check that you have followed the automatically enforced coding rules
* Commit your changes using a descriptive commit message that follows our
[commit message conventions](#commit) and passes our commit message presubmit hook
(`validate-commit-msg.js`). Adherence to the [commit message conventions](#commit) is required,
because release notes are automatically generated from these messages.
[commit message conventions][developers.commits]. Adherence to the
[commit message conventions][developers.commits] is required, because release notes are
automatically generated from these messages.
```shell
git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
* Build your changes locally to ensure all the tests pass:
* Before creating the Pull Request, package and run all tests a last time:
```shell
grunt test
yarn grunt test
```
* Push your branch to GitHub:
@@ -132,24 +150,30 @@ Before you submit your pull request consider the following guidelines:
git push origin my-fix-branch
```
In GitHub, send a pull request to `angular:master`.
If we suggest changes, then:
* In GitHub, send a pull request to `angular.js:master`. This will trigger the check of the
[Contributor License Agreement](#cla) and the Travis integration.
* Make the required updates.
* Re-run the Angular test suite to ensure tests are still passing.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
* If you find that the Travis integration has failed, look into the logs on Travis to find out
if your changes caused test failures, the commit message was malformed etc. If you find that the
tests failed or times out for unrelated reasons, you can ping a team member so that the build can be
restarted.
If the PR gets too outdated we may ask you to rebase and force push to update the PR:
* If we suggest changes, then:
```shell
git rebase master -i
git push origin my-fix-branch -f
```
* Make the required updates.
* Re-run the AngularJS test suite to ensure tests are still passing.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
_WARNING: Squashing or reverting commits and force-pushing thereafter may remove GitHub comments
on code that were previously made by you or others in your commits. Avoid any form of rebasing
unless necessary._
You can also amend the initial commits and force push them to the branch.
```shell
git rebase master -i
git push origin my-fix-branch -f
```
This is generally easier to follow, but seperate commits are useful if the Pull Request contains
iterations that might be interesting to see side-by-side.
That's it! Thank you for your contribution!
@@ -182,135 +206,41 @@ from the main (upstream) repository:
git pull --ff upstream master
```
## <a name="rules"></a> Coding Rules
## <a name="cla"></a> Signing the Contributor License Agreement (CLA)
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more [specs][unit-testing].
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
out the existing ngdocs and see [this wiki page][ngDocs].
* With the exceptions listed below, we follow the rules contained in
[Google's JavaScript Style Guide][js-style-guide]:
* **Do not use namespaces**: Instead, wrap the entire angular code base in an anonymous closure and
export our API explicitly rather than implicitly.
* Wrap all code at **100 characters**.
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
inheritance only when absolutely necessary.
* We **love functions and closures** and, whenever possible, prefer them over objects.
* To write concise code that can be better minified, we **use aliases internally** that map to the
external API. See our existing code to see what we mean.
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal API
that is used throughout AngularJS. The best guidance is to do what makes the most sense.
## <a name="commit"></a> Git Commit Guidelines
We have very precise rules over how our git commit messages can be formatted. This leads to **more
readable messages** that are easy to follow when looking through the **project history**. But also,
we use the git commit messages to **generate the AngularJS change log**.
The commit message formatting can be added using a typical git workflow or through the use of a CLI
wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `yarn run commit`
in your terminal after staging your changes in git.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:
```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The **header** is mandatory and the **scope** of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
### Type
Must be one of the following:
* **feat**: A new feature
* **fix**: A bug fix
* **docs**: Documentation only changes
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing or correcting existing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation
### Scope
The scope could be anything specifying place of the commit change. For example `$location`,
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
You can use `*` when the change affects more than a single scope.
### Subject
The subject contains succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
[reference GitHub issues that this commit closes][closing-issues].
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
The rest of the commit message is then used for this.
A detailed explanation can be found in this [document][commit-message-format].
## <a name="cla"></a> Signing the CLA
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
Upon submmitting a Pull Request, a friendly bot will ask you to sign our CLA if you haven't done
so before. Unfortunately, this is necessary for documentation changes, too.
It's a quick process, we promise!
* For individuals we have a [simple click-through form][individual-cla].
* For corporations we'll need you to
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
## <a name="info"></a> Further Information
You can find out more detailed information about contributing in the
[AngularJS documentation][contributing].
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
[angular-dev]: https://groups.google.com/forum/?fromgroups#!forum/angular-dev
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[contribute]: http://docs.angularjs.org/misc/contribute
[contributing]: http://docs.angularjs.org/misc/contribute
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[dev-doc]: https://docs.angularjs.org/guide
[developers]: DEVELOPERS.md
[developers.commits]: DEVELOPERS.md#commits
[developers.documentation]: DEVELOPERS.md#documentation
[developers.rules]: DEVELOPERS.md#rules
[developers.setup]: DEVELOPERS.md#setup
[developers.tests-e2e]: DEVELOPERS.md#e2e-tests
[developers.tests-unit]: DEVELOPERS.md#unit-tests
[github-issues]: https://github.com/angular/angular.js/issues
[github-new-issue]: https://github.com/angular/angular.js/issues/new
[github]: https://github.com/angular/angular.js
[gitter]: https://gitter.im/angular/angular.js
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
[groups]: https://groups.google.com/forum/?fromgroups#!forum/angular
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
[irc]: http://webchat.freenode.net/?channels=angularjs&uio=d4
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
[jsfiddle]: http://jsfiddle.net/
[list]: https://groups.google.com/forum/?fromgroups#!forum/angular
[ngDocs]: https://github.com/angular/angular.js/wiki/Writing-AngularJS-Documentation
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
[plunker]: http://plnkr.co/edit
[stackoverflow]: http://stackoverflow.com/questions/tagged/angularjs
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/CONTRIBUTING.md?pixel)](https://github.com/igrigorik/ga-beacon)
+489
View File
@@ -0,0 +1,489 @@
# Developing AngularJS
* [Development Setup](#setup)
* [Running Tests](#tests)
* [Coding Rules](#rules)
* [Commit Message Guidelines](#commits)
* [Writing Documentation](#documentation)
## <a name="setup"> Development Setup
This document describes how to set up your development environment to build and test AngularJS, and
explains the basic mechanics of using `git`, `node`, `yarn` and `grunt`.
### Installing Dependencies
Before you can build AngularJS, you must install and configure the following dependencies on your
machine:
* [Git](http://git-scm.com/): The [Github Guide to
Installing Git][git-setup] is a good source of information.
* [Node.js v8.x (LTS)](http://nodejs.org): We use Node to generate the documentation, run a
development web server, run tests, and generate distributable files. Depending on your system,
you can install Node either from source or as a pre-packaged bundle.
We recommend using [nvm](https://github.com/creationix/nvm) (or
[nvm-windows](https://github.com/coreybutler/nvm-windows))
to manage and install Node.js, which makes it easy to change the version of Node.js per project.
* [Yarn](https://yarnpkg.com): We use Yarn to install our Node.js module dependencies
(rather than using npm). See the detailed [installation instructions][yarn-install].
* [Java](http://www.java.com): We minify JavaScript using
[Closure Tools](https://developers.google.com/closure/), which require Java (version 7 or higher)
to be installed and included in your
[PATH](http://docs.oracle.com/javase/tutorial/essential/environment/paths.html) variable.
* [Grunt](http://gruntjs.com): We use Grunt as our build system. We're using it as a local dependency,
but you can also add the grunt command-line tool globally (with `yarn global add grunt-cli`), which allows
you to leave out the `yarn` prefix for all our grunt commands.
### Forking AngularJS on Github
To contribute code to AngularJS, you must have a GitHub account so you can push code to your own
fork of AngularJS and open Pull Requests in the [GitHub Repository][github].
To create a Github account, follow the instructions [here](https://github.com/signup/free).
Afterwards, go ahead and [fork](http://help.github.com/forking) the
[main AngularJS repository][github].
### Building AngularJS
To build AngularJS, you clone the source code repository and use Grunt to generate the non-minified
and minified AngularJS files:
```shell
# Clone your Github repository:
git clone https://github.com/<github username>/angular.js.git
# Go to the AngularJS directory:
cd angular.js
# Add the main AngularJS repository as an upstream remote to your repository:
git remote add upstream "https://github.com/angular/angular.js.git"
# Install JavaScript dependencies:
yarn install
# Build AngularJS:
yarn grunt package
```
**Note:** If you're using Windows, you must use an elevated command prompt (right click, run as
Administrator). This is because `yarn grunt package` creates some symbolic links.
The build output is in the `build` directory. It consists of the following files and
directories:
* `angular-<version>.zip` — The complete zip file, containing all of the release build
artifacts.
* `angular.js` / `angular.min.js` — The regular and minified core AngularJS script file.
* `angular-*.js` / `angular-*.min.js` — All other AngularJS module script files.
* `docs/` — A directory that contains a standalone version of the docs
(same as served in `docs.angularjs.org`).
### <a name="local-server"></a> Running a Local Development Web Server
To debug code, run end-to-end tests, and serve the docs, it is often useful to have a local
HTTP server. For this purpose, we have made available a local web server based on Node.js.
1. To start the web server, run:
```shell
yarn grunt webserver
```
2. To access the local server, enter the following URL into your web browser:
```text
http://localhost:8000/
```
By default, it serves the contents of the AngularJS project directory.
3. To access the locally served docs, visit this URL:
```text
http://localhost:8000/build/docs/
```
## <a name="tests"> Running Tests
### <a name="unit-tests"></a> Running the Unit Test Suite
We write unit and integration tests with Jasmine and execute them with Karma. To run all of the
tests once on Chrome run:
```shell
yarn grunt test:unit
```
To run the tests on other browsers use the command line flag:
```shell
yarn grunt test:unit --browsers=Chrome,Firefox
```
**Note:** there should be _no spaces between browsers_. `Chrome, Firefox` is INVALID.
If you have a Saucelabs or Browserstack account, you can also run the unit tests on these services
via our pre-defined customLaunchers. See the [karma config file](/karma-shared.conf.js) for all pre-configured browsers.
For example, to run the whole unit test suite on selected browsers:
```shell
# Browserstack
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_10
# Saucelabs
yarn grunt test:unit --browsers=SL_Chrome,SL_Firefox,SL_Safari,SL_IE_9,SL_IE_10,SL_IE_11,SL_EDGE,SL_iOS_10
```
Running these commands requires you to set up [Karma Browserstack][karma-browserstack] or
[Karma-Saucelabs][karma-saucelabs], respectively.
During development, however, it's more productive to continuously run unit tests every time the
source or test files change. To execute tests in this mode run:
1. To start the Karma server, capture Chrome browser and run unit tests, run:
```shell
yarn grunt autotest
```
2. To capture more browsers, open this URL in the desired browser (URL might be different if you
have multiple instance of Karma running, read Karma's console output for the correct URL):
```text
http://localhost:9876/
```
3. To re-run tests just change any source or test file.
To learn more about all of the preconfigured Grunt tasks run:
```shell
yarn grunt --help
```
### <a name="e2e-tests"></a> Running the End-to-end Test Suite
AngularJS's end to end tests are run with Protractor. Simply run:
```shell
yarn grunt test:e2e
```
This will start the webserver and run the tests on Chrome.
## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more [specs][unit-testing].
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
out the existing source code and see the section about [writing documentation](#documentation)
* With the exceptions listed below, we follow the rules contained in
[Google's JavaScript Style Guide][js-style-guide]:
* **Do not use namespaces**: Instead, wrap the entire AngularJS code base in an anonymous
closure and export our API explicitly rather than implicitly.
* Wrap all code at **100 characters**.
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
inheritance only when absolutely necessary.
* We **love functions and closures** and, whenever possible, prefer them over objects.
* To write concise code that can be better minified, we **use aliases internally** that map to
the external API. See our existing code to see what we mean.
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal
API that is used throughout AngularJS. The best guidance is to do what makes the most sense.
### Specific topics
#### Provider configuration
When adding configuration (options) to [providers][docs.provider], we follow a special pattern.
- for each option, add a `method` that ...
- works as a getter and returns the current value when called without argument
- works as a setter and returns itself for chaining when called with argument
- for boolean options, uses the naming scheme `<option>Enabled([enabled])`
- non-primitive options (e.g. objects) should be copied or the properties assigned explicitly to a
new object so that the configuration cannot be changed during runtime.
For a boolean config example, see [`$compileProvider#debugInfoEnabled`][code.debugInfoEnabled]
For an object config example, see [`$location.html5Mode`][code.html5Mode]
#### Throwing errors
User-facing errors should be thrown with [`minErr`][code.minErr], a special error function that provides
errors ids, templated error messages, and adds a link to a detailed error description.
The `$compile:badrestrict` error is a good example for a well-defined `minErr`:
[code][code.badrestrict] and [description][docs.badrestrict].
## <a name="commits"></a> Git Commit Guidelines
We have very precise rules over how our git commit messages can be formatted. This leads to **more
readable messages** that are easy to follow when looking through the **project history**. But also,
we use the git commit messages to **generate the AngularJS change log**.
The commit message formatting can be added using a typical git workflow or through the use of a CLI
wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `yarn run commit`
in your terminal after staging your changes in git.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:
```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The **header** is mandatory and the **scope** of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header
of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit
being reverted.
A commit with this format is automatically created by the [`git revert`][git-revert] command.
### Type
Must be one of the following:
* **feat**: A new feature
* **fix**: A bug fix
* **docs**: Documentation only changes
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing or correcting existing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation
### Scope
The scope could be anything specifying place of the commit change. For example `$location`,
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
You can use `*` when the change affects more than a single scope.
### Subject
The subject contains succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
[reference GitHub issues that this commit closes][closing-issues].
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
The rest of the commit message is then used for this.
A detailed explanation can be found in this [document][commit-message-format].
## <a name="documentation"></a> Writing Documentation
The AngularJS project uses a form of [jsdoc](http://usejsdoc.org/) called ngdoc for all of its code
documentation.
This means that all the docs are stored inline in the source code and so are kept in sync as it
changes.
There is also extra content (the developer guide, error pages, the tutorial,
and misceallenous pages) that live inside the AngularJS repository as markdown files.
This means that since we generate the documentation from the source code, we can easily provide
version-specific documentation by simply checking out a version of AngularJS and running the build.
Extracting the source code documentation, processing and building the docs is handled by the
documentation generation tool [Dgeni][dgeni].
### Building and viewing the docs locally
The docs can be built from scratch using grunt:
```shell
yarn grunt docs
```
This defers the doc-building task to `gulp`.
Note that the docs app is using the local build files to run. This means you might first have to run
the build:
```shell
yarn grunt build
```
(This is also necessary if you are making changes to minErrors).
To view the docs, see [Running a Local Development Web Server](#local-server).
### Writing jsdoc
The ngdoc utility has basic support for many of the standard jsdoc directives. But in particular it
is interested in the following block tags:
* `@name name` - the name of the ngdoc document
* `@param {type} name description` - describes a parameter of a function
* `@returns {type} description` - describes what a function returns
* `@requires` - normally indicates that a JavaScript module is required; in an Angular service it is
used to describe what other services this service relies on
* `@property` - describes a property of an object
* `@description` - used to provide a description of a component in markdown
* `@link` - specifies a link to a URL or a type in the API reference.
Links to the API have the following structure:
* the module namespace, followed by `.` (optional, default `ng`)
* the `@ngdoc` type (see below), followed by `:` (optional, automatically inferred)
* the name
* the method, property, or anchor (optional)
* the display name
For example: `{@link ng.type:$rootScope.Scope#$new Scope.$new()}`.
* `@example` - specifies an example. This can be a simple code block, or a
[runnable example](#the-example-tag).
* `@deprecated` - specifies that the following code is deprecated and should not be used.
In The AngularJS docs, there are two specific patterns which can be used to further describe
the deprecation: `sinceVersion="<version>"` and `removeVersion="<version>"`
The `type` in `@param` and `@returns` must be wrapped in `{}` curly braces, e.g. `{Object|Array}`.
Parameters can be made optional by *either* appending a `=` to the type, e.g. `{Object=}`, *or* by
putting the `[name]` in square brackets.
Default values are only possible with the second syntax by appending `=<value>` to the parameter
name, e.g. `@param {boolean} [ownPropsOnly=false]`.
Descriptions can contain markdown formatting.
#### AngularJS-specific jsdoc directives
In addition to the standard jsdoc tags, there are a number that are specific to the Angular
code-base:
* `@ngdoc` - specifies the type of thing being documented. See below for more detail.
* `@eventType emit|broadcast` - specifies whether the event is emitted or broadcast
* `@usage` - shows how to use a `function` or `directive`. Is usually automatically generated.
* `@knownIssue` - adds info about known quirks, problems, or limitations with the API, and possibly,
workarounds. This section is not for bugs.
The following are specific to directives:
* `@animations` - specifies the animations a directive supports
* `@multiElement` - specifies if a directive can span over multiple elements
* `@priority` - specifies a directive's priority
* `@restrict` - is extracted to show the usage of a directive. For example, for [E]lement,
[A]ttribute, and [C]lass, use `@restrict ECA`
* `@scope` - specifies that a directive will create a new scope
### The `@ngdoc` Directive
This directive helps to specify the template used to render the item being documented. For instance,
a directive would have different properties to a filter and so would be documented differently. The
commonly used types are:
* `overview` - a general page (guide, api index)
* `provider` - AngularJS provider, such as `$compileProvider` or `$httpProvider`.
* `service` - injectable AngularJS service, such as `$compile` or `$http`.
* `object` - well defined object (often exposed as a service)
* `function` - function that will be available to other methods (such as a helper function within
the ng module)
* `method` - method on an object/service/controller
* `property` - property on an object/service/controller
* `event` - AngularJS event that will propagate through the `$scope` tree.
* `directive` - AngularJS directive
* `filter` - AngularJS filter
* `error` - minErr error description
### General documentation with Markdown
Any text in tags can contain markdown syntax for formatting. Generally, you can use any markdown
feature.
#### Headings
Only use *h2* headings and lower, as the page title is set in *h1*. Also make sure you follow the
heading hierarchy. This ensures correct table of contents are created.
#### Code blocks
In line code can be specified by enclosing the code in back-ticks (\`).
A block of multi-line code can be enclosed in triple back-ticks (\`\`\`) but it is formatted better
if it is enclosed in &lt;pre&gt;...&lt;/pre&gt; tags and the code lines themselves are indented.
### Writing runnable (live) examples and e2e tests
It is possible to embed examples in the documentation along with appropriate e2e tests. These
examples and scenarios will be converted to runnable code within the documentation. So it is
important that they work correctly. To ensure this, all these e2e scenarios are run as part of the
automated Travis tests.
If you are adding an example with an e2e test, you should [run the test locally](#e2e-tests) first
to ensure it passes. You can change `it(...)` to `fit(...)` to run only your test,
but make sure you change it back to `it(...)` before committing.
#### The `<example>` tag
This tag identifies a block of HTML that will define a runnable example. It can take the following
attributes:
* `animations` - if set to `true` then this example uses ngAnimate.
* `deps` - Semicolon-separated list of additional angular module files to be loaded,
e.g. `angular-animate.js`
* `name` - every example should have a name. It should start with the component, e.g directive name,
and not contain whitespace
* `module` - the name of the app module as defined in the example's JavaScript
Within this tag we provide `<file>` tags that specify what files contain the example code.
```
<example
module="angularAppModule"
name="exampleName"
deps="angular-animate.js;angular-route.js"
animations="true">
...
<file name="index.html">...</file>
<file name="script.js">...</file>
<file name="animations.css">...</file>
<file name="protractor.js">...</file>
...
</example>
```
You can see an example of a well-defined example [in the `ngRepeat` documentation][code.ngRepeat-example].
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
[code.badrestrict]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/ng/compile.js#L1107-L1110
[code.debugInfoEnabled]: https://github.com/angular/angular.js/blob/32fbb2e78f53d765fbb170f7cf99e42e072d363b/src/ng/compile.js#L1378-L1413
[code.html5Mode]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/ng/location.js#L752-L797
[code.minErr]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/minErr.js#L53-L113
[code.ngRepeat-example]: https://github.com/angular/angular.js/blob/0822d34b10ea0371c260c80a1486a4d508ea5a91/src/ng/directive/ngRepeat.js#L249-L340
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[dgeni]: https://github.com/angular/dgeni
[docs.badrestrict]: docs/content/error/$compile/badrestrict.ngdoc
[docs.provider]: https://code.angularjs.org/snapshot/docs/api/auto/service/$provide#provider
[git-revert]: https://git-scm.com/docs/git-revert
[git-setup]: https://help.github.com/articles/set-up-git
[github-issues]: https://github.com/angular/angular.js/issues
[github]: https://github.com/angular/angular.js
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
[yarn-install]: https://yarnpkg.com/en/docs/install
+193 -29
View File
@@ -4,6 +4,7 @@ var serveFavicon = require('serve-favicon');
var serveStatic = require('serve-static');
var serveIndex = require('serve-index');
var files = require('./angularFiles').files;
var mergeFilesFor = require('./angularFiles').mergeFilesFor;
var util = require('./lib/grunt/utils.js');
var versionInfo = require('./lib/versions/version-info');
var path = require('path');
@@ -13,6 +14,8 @@ var semver = require('semver');
var exec = require('shelljs').exec;
var pkg = require(__dirname + '/package.json');
var docsScriptFolder = 'scripts/docs.angularjs.org-firebase';
// Node.js version checks
if (!semver.satisfies(process.version, pkg.engines.node)) {
reportOrFail('Invalid node version (' + process.version + '). ' +
@@ -28,7 +31,7 @@ if (!semver.satisfies(currentYarnVersion, expectedYarnVersion)) {
}
// Grunt CLI version checks
var expectedGruntVersion = pkg.engines.grunt;
var expectedGruntVersion = pkg.engines['grunt-cli'];
var currentGruntVersions = exec('grunt --version', {silent: true}).stdout;
var match = /^grunt-cli v(.+)$/m.exec(currentGruntVersions);
if (!match) {
@@ -49,7 +52,6 @@ if (!process.env.TRAVIS && !process.env.JENKINS_HOME) {
}
}
module.exports = function(grunt) {
// this loads all the node_modules that start with `grunt-` as plugins
@@ -64,6 +66,12 @@ module.exports = function(grunt) {
NG_VERSION.cdn = versionInfo.cdnVersion;
var dist = 'angular-' + NG_VERSION.full;
var deployVersion = NG_VERSION.full;
if (NG_VERSION.isSnapshot) {
deployVersion = NG_VERSION.distTag === 'latest' ? 'snapshot-stable' : 'snapshot';
}
if (versionInfo.cdnVersion == null) {
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?\n' +
'Perhaps you want to set the NG1_BUILD_NO_REMOTE_VERSION_REQUESTS environment variable?');
@@ -134,7 +142,9 @@ module.exports = function(grunt) {
'jquery-2.2': 'karma-jquery-2.2.conf.js',
'jquery-2.1': 'karma-jquery-2.1.conf.js',
docs: 'karma-docs.conf.js',
modules: 'karma-modules.conf.js'
modules: 'karma-modules.conf.js',
'modules-ngAnimate': 'karma-modules-ngAnimate.conf.js',
'modules-ngMock': 'karma-modules-ngMock.conf.js'
},
@@ -157,7 +167,12 @@ module.exports = function(grunt) {
clean: {
build: ['build'],
tmp: ['tmp']
tmp: ['tmp'],
deploy: [
'deploy/docs',
'deploy/code',
docsScriptFolder + '/functions/html'
]
},
eslint: {
@@ -168,11 +183,11 @@ module.exports = function(grunt) {
'docs/**/*.js',
'lib/**/*.js',
'scripts/**/*.js',
'!scripts/*/*/node_modules/**',
'src/**/*.js',
'test/**/*.js',
'i18n/**/*.js',
'!docs/app/assets/js/angular-bootstrap/**',
'!docs/bower_components/**',
'!docs/config/templates/**',
'!src/angular.bind.js',
'!i18n/closure/**',
@@ -182,16 +197,6 @@ module.exports = function(grunt) {
},
build: {
scenario: {
dest: 'build/angular-scenario.js',
src: [
'bower_components/jquery/dist/jquery.js',
util.wrap([files['angularSrc'], files['angularScenario']], 'ngScenario/angular')
],
styles: {
css: ['css/angular.css', 'css/angular-scenario.css']
}
},
angular: {
dest: 'build/angular.js',
src: util.wrap([files['angularSrc']], 'angular'),
@@ -209,6 +214,12 @@ module.exports = function(grunt) {
dest: 'build/angular-touch.js',
src: util.wrap(files['angularModules']['ngTouch'], 'module')
},
touchModuleTestBundle: {
dest: 'build/test-bundles/angular-touch.js',
prefix: 'src/module.prefix',
src: mergeFilesFor('karmaModules-ngTouch'),
suffix: 'src/module.suffix'
},
mocks: {
dest: 'build/angular-mocks.js',
src: util.wrap(files['angularModules']['ngMock'], 'module'),
@@ -218,18 +229,42 @@ module.exports = function(grunt) {
dest: 'build/angular-sanitize.js',
src: util.wrap(files['angularModules']['ngSanitize'], 'module')
},
sanitizeModuleTestBundle: {
dest: 'build/test-bundles/angular-sanitize.js',
prefix: 'src/module.prefix',
src: mergeFilesFor('karmaModules-ngSanitize'),
suffix: 'src/module.suffix'
},
resource: {
dest: 'build/angular-resource.js',
src: util.wrap(files['angularModules']['ngResource'], 'module')
},
resourceModuleTestBundle: {
dest: 'build/test-bundles/angular-resource.js',
prefix: 'src/module.prefix',
src: mergeFilesFor('karmaModules-ngResource'),
suffix: 'src/module.suffix'
},
messageformat: {
dest: 'build/angular-message-format.js',
src: util.wrap(files['angularModules']['ngMessageFormat'], 'module')
},
messageformatModuleTestBundle: {
dest: 'build/test-bundles/angular-message-format.js',
prefix: 'src/module.prefix',
src: mergeFilesFor('karmaModules-ngMessageFormat'),
suffix: 'src/module.suffix'
},
messages: {
dest: 'build/angular-messages.js',
src: util.wrap(files['angularModules']['ngMessages'], 'module')
},
messagesModuleTestBundle: {
dest: 'build/test-bundles/angular-messages.js',
prefix: 'src/module.prefix',
src: mergeFilesFor('karmaModules-ngMessages'),
suffix: 'src/module.suffix'
},
animate: {
dest: 'build/angular-animate.js',
src: util.wrap(files['angularModules']['ngAnimate'], 'module')
@@ -238,14 +273,32 @@ module.exports = function(grunt) {
dest: 'build/angular-route.js',
src: util.wrap(files['angularModules']['ngRoute'], 'module')
},
routeModuleTestBundle: {
dest: 'build/test-bundles/angular-route.js',
prefix: 'src/module.prefix',
src: mergeFilesFor('karmaModules-ngRoute'),
suffix: 'src/module.suffix'
},
cookies: {
dest: 'build/angular-cookies.js',
src: util.wrap(files['angularModules']['ngCookies'], 'module')
},
cookiesModuleTestBundle: {
dest: 'build/test-bundles/angular-cookies.js',
prefix: 'src/module.prefix',
src: mergeFilesFor('karmaModules-ngCookies'),
suffix: 'src/module.suffix'
},
aria: {
dest: 'build/angular-aria.js',
src: util.wrap(files['angularModules']['ngAria'], 'module')
},
ariaModuleTestBundle: {
dest: 'build/test-bundles/angular-aria.js',
prefix: 'src/module.prefix',
src: mergeFilesFor('karmaModules-ngAria'),
suffix: 'src/module.suffix'
},
parseext: {
dest: 'build/angular-parse-ext.js',
src: util.wrap(files['angularModules']['ngParseExt'], 'module')
@@ -277,9 +330,7 @@ module.exports = function(grunt) {
files: [
'src/**/*.js',
'test/**/*.js',
'!test/ngScenario/DescribeSpec.js',
'!src/ng/directive/attrs.js', // legitimate xit here
'!src/ngScenario/**/*.js',
'!test/helpers/privateMocks*.js'
],
options: {
@@ -311,7 +362,54 @@ module.exports = function(grunt) {
copy: {
i18n: {
files: [
{ src: 'src/ngLocale/**', dest: 'build/i18n/', expand: true, flatten: true }
{
src: 'src/ngLocale/**',
dest: 'build/i18n/',
expand: true,
flatten: true
}
]
},
deployFirebaseCode: {
files: [
// copy files that are not handled by compress
{
cwd: 'build',
src: '**/*.{zip,jpg,jpeg,png}',
dest: 'deploy/code/' + deployVersion + '/',
expand: true
}
]
},
deployFirebaseDocs: {
files: [
// The source files are needed by the embedded examples in the docs app.
{
src: ['build/angular*.{js,js.map,min.js}', 'build/sitemap.xml'],
dest: 'deploy/docs/',
expand: true,
flatten: true
},
{
cwd: 'build/docs',
src: ['**', '!ptore2e/**', '!index*.html'],
dest: 'deploy/docs/',
expand: true
},
{
src: 'build/docs/index-production.html',
dest: 'deploy/docs/index.html'
},
{
src: 'build/docs/index-production.html',
dest: docsScriptFolder + '/functions/content/index.html'
},
{
cwd: 'build/docs',
src: 'partials/**',
dest: docsScriptFolder + '/functions/content',
expand: true
}
]
}
},
@@ -325,6 +423,16 @@ module.exports = function(grunt) {
expand: true,
dot: true,
dest: dist + '/'
},
deployFirebaseCode: {
options: {
mode: 'gzip'
},
// Already compressed files should not be compressed again
src: ['**', '!**/*.{zip,png,jpeg,jpg}'],
cwd: 'build',
expand: true,
dest: 'deploy/code/' + deployVersion + '/'
}
},
@@ -359,24 +467,80 @@ module.exports = function(grunt) {
});
//alias tasks
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['eslint', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']);
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', [
'eslint',
'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 (latest) unit tests with Karma', ['tests:jquery']);
grunt.registerTask('test:jquery-2.2', 'Run the jQuery 2.2 unit tests with Karma', ['tests:jquery-2.2']);
grunt.registerTask('test:jquery-2.1', 'Run the jQuery 2.1 unit tests with Karma', ['tests:jquery-2.1']);
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', ['build', 'tests:modules']);
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', [
'build',
'tests:modules',
'tests:modules-ngAnimate',
'tests:modules-ngMock'
]);
grunt.registerTask('test:docs', 'Run the doc-page tests with Karma', ['package', 'tests:docs']);
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['test:jqlite', 'test:jquery', 'test:jquery-2.2', 'test:jquery-2.1', 'test:modules']);
grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'protractor:normal']);
grunt.registerTask('test:travis-protractor', 'Run the end to end tests with Protractor for Travis CI builds', ['connect:testserver', 'protractor:travis']);
grunt.registerTask('test:ci-protractor', 'Run the end to end tests with Protractor for Jenkins CI builds', ['webdriver', 'connect:testserver', 'protractor:jenkins']);
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', [
'test:jqlite',
'test:jquery',
'test:jquery-2.2',
'test:jquery-2.1',
'test:modules'
]);
grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', [
'webdriver',
'connect:testserver',
'protractor:normal'
]);
grunt.registerTask('test:travis-protractor', 'Run the end to end tests with Protractor for Travis CI builds', [
'connect:testserver',
'protractor:travis'
]);
grunt.registerTask('test:ci-protractor', 'Run the end to end tests with Protractor for Jenkins CI builds', [
'webdriver',
'connect:testserver',
'protractor:jenkins'
]);
grunt.registerTask('test:e2e', 'Alias for test:protractor', ['test:protractor']);
grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter', 'shell:promises-aplus-tests']);
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
grunt.registerTask('test:promises-aplus',[
'build:promises-aplus-adapter',
'shell:promises-aplus-tests'
]);
grunt.registerTask('minify', [
'clean',
'build',
'minall'
]);
grunt.registerTask('webserver', ['connect:devserver']);
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'write', 'docs', 'copy', 'compress']);
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']);
grunt.registerTask('package', [
'validate-angular-files',
'clean',
'buildall',
'minall',
'collect-errors',
'write',
'docs',
'copy:i18n',
'compress:build'
]);
grunt.registerTask('ci-checks', [
'ddescribe-iit',
'merge-conflict',
'eslint'
]);
grunt.registerTask('prepareDeploy', [
'package',
'compress:deployFirebaseCode',
'copy:deployFirebaseCode',
'firebaseDocsJsonForTravis',
'copy:deployFirebaseDocs'
]);
grunt.registerTask('default', ['package']);
};
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
Copyright (c) 2010-2018 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+1 -1
View File
@@ -7,7 +7,7 @@ in its `contrib/externs` directory.
The definitions contain externs for use with the Closure compiler (aka
JSCompiler). Passing these files to the --externs parameter of a compiler
pass allows using type annotations for AngularJS objects. For example,
Angular's $scope objects can be annotated as:
AngularJS's $scope objects can be annotated as:
```js
/** @type {angular.Scope} */
var scope = $scope;
+25 -26
View File
@@ -8,43 +8,42 @@ synchronizes data from your UI (view) with your JavaScript objects (model) throu
binding. To help you structure your application better and make it easy to test, AngularJS teaches
the browser how to do dependency injection and inversion of control.
It also helps with server-side communication, taming async callbacks with promises and deferreds,
and it makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
It also helps with server-side communication, taming async callbacks with promises and deferred objects,
and it makes client-side navigation and deep linking with hashbang urls or HTML5 pushState a
piece of cake. Best of all? It makes development fun!
--------------------
**On July 1, 2018 AngularJS entered a 3 year Long Term Support period:** [Find out more](https://docs.angularjs.org/misc/version-support-status)
**Looking for the new Angular? Go here:** https://github.com/angular/angular
--------------------
* Web site: https://angularjs.org
* Tutorial: https://docs.angularjs.org/tutorial
* API Docs: https://docs.angularjs.org/api
* Developer Guide: https://docs.angularjs.org/guide
* Contribution guidelines: [CONTRIBUTING.md](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
* Contribution guidelines: [CONTRIBUTING.md](CONTRIBUTING.md)
* Core Development: [DEVELOPERS.md](DEVELOPERS.md)
* Dashboard: https://dashboard.angularjs.org
##### Looking for Angular 2? Go here: https://github.com/angular/angular
Building AngularJS
---------
[Once you have set up your environment](https://docs.angularjs.org/misc/contribute), just run:
Documentation
--------------------
Go to https://docs.angularjs.org
grunt package
Running tests
-------------
To execute all unit tests, use:
grunt test:unit
To execute end-to-end (e2e) tests, use:
grunt package
grunt test:e2e
To learn more about the grunt tasks, run `grunt --help`
Contribute & Develop
Contribute
--------------------
We've set up a separate document for our [contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
We've set up a separate document for our
[contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
Develop
--------------------
We've set up a separate document for
[developers](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md).
[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/README.md?pixel)](https://github.com/igrigorik/ga-beacon)
@@ -80,7 +79,7 @@ HTML is also used to determine the wiring of the app. Special attributes in the
to load the app, which components or controllers to use for each element, etc. We specify "what"
gets loaded, but not "how". This declarative approach greatly simplifies app development in a sort
of WYSIWYG way. Rather than spending time on how the program flows and orchestrating the various
moving parts, we simply define what we want and Angular will take care of the dependencies.
moving parts, we simply define what we want and AngularJS will take care of the dependencies.
#### Data Handling made simple
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties
+98
View File
@@ -0,0 +1,98 @@
# AngularJS Release instructions
## Compare the list of commits between stable and unstable
There is a script - compare-master-to-stable.js - that helps with this.
We just want to make sure that good commits (low risk fixes + docs fixes) got cherry-picked into stable branch and nothing interesting got merged only into stable branch.
## Pick a release name (for this version)
A super-heroic power (adverb-verb phrase).
## Generate release notes
Example Commit: https://github.com/angular/angular.js/commit/7ab5098c14ee4f195dbfe2681e402fe2dfeacd78
1) Run
```bash
node_modules/.bin/changez -o changes.md -v <new version> <base branch>
```
2) Review the generated file and manually fix typos, group and reorder stuff if needed.
3) Move the content into CHANGELOG.md add release code-names to headers.
4) Push the changes to your private github repo and review.
5) cherry-pick the release notes commit to the appropriate branches.
## Pick a commit to release (for this version)
Usually this will be the commit containing the release notes, but it may also be in the past.
## Run "release" script
```bash
scripts/jenkins/release.sh --git-push-dryrun=false --commit-sha=8822a4f --version-number=1.7.6 --version-name=gravity-manipulation
```
1) The SHA is of the commit to release (could be in the past).
2) The version number and code-name that should be released, not the next version number (e.g. to release 1.2.12 you enter 1.2.12 as release version and the code-name that was picked for 1.2.12, cauliflower-eradication).
3) You will need to have write access to all the AngularJS github dist repositories and publish rights for the AngularJS packages on npm.
## Update GitHub milestones
1) Create the next milestone if it doesn't exist yet-giving ita due date.
2) Move all open issues and PRs for the current milestone to the next milestone<br>
You can do this by filtering the current milestone, selecting via checklist, and moving to the next milestone within the GH issues page.
3) Close the current milestone click the milestones tab and close from there.
4) Create a new holding milestone for the release after next-but don't give it a due date otherwise that will mess up the dashboard.
## Push build artifacts to CDN
Google CDNs are fed with data from google3 every day at 11:15am PT it takes only few minutes for the import to propagate).
If we want to make our files available, we need submit our CLs before this time on the day of the release.
## Don't update the package.json (branchVersion) until the CDN has updated
This is the version used to compute what version to link to in the CDN. If you update this too early then the CDN lookup fails and you end up with 'null, for the version, which breaks the docs.
## Verify angularjs.org download modal has latest version (updates via Travis job)
The versions in the modal are updated (based on the versions available on CDN) as part of the Travis deploy stage: https://github.com/angular/angularjs.org/blob/a4d25c5abcd39e8ce19d31cb1c78073d13c4c974/.travis.yml#L26
(You may need to explicitly trigger the Travis job. e.g. re-running the last job.)
## Announce the release (via official Google accounts)
Double check that angularjs.org is up to date with the new release version before sharing.
1) Collect a list of contributors
use: `git log --format='%aN' v1.2.12..v1.2.13 | sort -u`
2) Write a blog post (for minor releases, not patch releases) and publish it with the "release" tag
3) Post on twitter as yourself (tweet from your heart; there is no template for this), retweet as @AngularJS
## Party!
## Major Release Tasks
1) Update angularjs.org to use the latest branch.
2) Write up a migration document.
3) Create a new git branch for the version that has been released (e.g. 1.8.x).
4) Check that the build and release scripts still work.
5) Update the dist-tag of the old branch, see https://github.com/angular/angular.js/pull/12722.
6) Write a blog post.
+4 -4
View File
@@ -1,6 +1,6 @@
# Triage new issues/PRs on github
This document shows the steps the Angular team is using to triage issues.
This document shows the steps the AngularJS team is using to triage issues.
The labels are used later on for [planning releases](#assigning-work).
@@ -45,12 +45,12 @@ This process based on the idea of minimizing user pain
1. Label `frequency: *` How often does this issue come up? How many developers does this affect? Chose just one of the following:
* low - obscure issue affecting a handful of developers
* moderate - impacts a common usage pattern
* high - impacts most or all Angular apps
* high - impacts most or all AngularJS apps
1. Label `severity: *` - How bad is the issue? Chose just one of the following:
* security issue
* regression
* memory leak
* broken expected use - it's hard or impossible for a developer using Angular to accomplish something that Angular should be able to do
* broken expected use - it's hard or impossible for a developer using AngularJS to accomplish something that AngularJS should be able to do
* confusing - unexpected or inconsistent behavior; hard-to-debug
* inconvenience - causes ugly/boilerplate code in apps
1. Label `component: *`
@@ -95,7 +95,7 @@ You can mention him in the relevant thread like this: `@btford`.
> Thanks for submitting this issue!
> Unfortunately, we don't think this functionality belongs in core.
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or to the npm repository.
> The good news is that you could easily implement this as a third-party module and publish it to the npm registry.
## Assigning Work
+82 -44
View File
@@ -28,6 +28,7 @@ var angularFiles = {
'src/ng/httpBackend.js',
'src/ng/interpolate.js',
'src/ng/interval.js',
'src/ng/intervalFactory.js',
'src/ng/jsonpCallbacks.js',
'src/ng/locale.js',
'src/ng/location.js',
@@ -40,6 +41,7 @@ var angularFiles = {
'src/ng/sanitizeUri.js',
'src/ng/sce.js',
'src/ng/sniffer.js',
'src/ng/taskTrackerFactory.js',
'src/ng/templateRequest.js',
'src/ng/testability.js',
'src/ng/timeout.js',
@@ -74,6 +76,7 @@ var angularFiles = {
'src/ng/directive/ngNonBindable.js',
'src/ng/directive/ngOptions.js',
'src/ng/directive/ngPluralize.js',
'src/ng/directive/ngRef.js',
'src/ng/directive/ngRepeat.js',
'src/ng/directive/ngShowHide.js',
'src/ng/directive/ngStyle.js',
@@ -103,13 +106,13 @@ var angularFiles = {
'src/ngAnimate/animateJs.js',
'src/ngAnimate/animateJsDriver.js',
'src/ngAnimate/animateQueue.js',
'src/ngAnimate/animateCache.js',
'src/ngAnimate/animation.js',
'src/ngAnimate/ngAnimateSwap.js',
'src/ngAnimate/module.js'
],
'ngCookies': [
'src/ngCookies/cookies.js',
'src/ngCookies/cookieStore.js',
'src/ngCookies/cookieWriter.js'
],
'ngMessageFormat': [
@@ -131,6 +134,7 @@ var angularFiles = {
],
'ngRoute': [
'src/shallowCopy.js',
'src/routeToRegExp.js',
'src/ngRoute/route.js',
'src/ngRoute/routeParams.js',
'src/ngRoute/directive/ngView.js'
@@ -140,13 +144,13 @@ var angularFiles = {
'src/ngSanitize/filter/linky.js'
],
'ngMock': [
'src/routeToRegExp.js',
'src/ngMock/angular-mocks.js',
'src/ngMock/browserTrigger.js'
],
'ngTouch': [
'src/ngTouch/touch.js',
'src/ngTouch/swipe.js',
'src/ngTouch/directive/ngClick.js',
'src/ngTouch/directive/ngSwipe.js'
],
'ngAria': [
@@ -154,26 +158,8 @@ var angularFiles = {
]
},
'angularScenario': [
'src/ngScenario/Scenario.js',
'src/ngScenario/Application.js',
'src/ngScenario/Describe.js',
'src/ngScenario/Future.js',
'src/ngScenario/ObjectModel.js',
'src/ngScenario/Runner.js',
'src/ngScenario/SpecRunner.js',
'src/ngScenario/dsl.js',
'src/ngScenario/matchers.js',
'src/ngScenario/output/Html.js',
'src/ngScenario/output/Json.js',
'src/ngScenario/output/Xml.js',
'src/ngScenario/output/Object.js'
],
'angularTest': [
'test/helpers/*.js',
'test/ngScenario/*.js',
'test/ngScenario/output/*.js',
'test/*.js',
'test/auto/*.js',
'test/ng/**/*.js',
@@ -190,55 +176,97 @@ var angularFiles = {
],
'karma': [
'bower_components/jquery/dist/jquery.js',
'node_modules/jquery/dist/jquery.js',
'test/jquery_remove.js',
'@angularSrc',
'@angularSrcModules',
'@angularScenario',
'@angularTest'
],
'karmaExclude': [
'test/jquery_alias.js',
'src/angular-bootstrap.js',
'src/ngScenario/angular-bootstrap.js',
'src/angular.bind.js'
],
'karmaScenario': [
'build/angular-scenario.js',
'build/docs/docs-scenario.js'
'karmaModules-ngAnimate': [
'build/angular.js',
'build/angular-mocks.js',
'test/modules/no_bootstrap.js',
'test/helpers/matchers.js',
'test/helpers/privateMocks.js',
'test/helpers/support.js',
'test/helpers/testabilityPatch.js',
'@angularSrcModuleNgAnimate',
'test/ngAnimate/**/*.js'
],
'karmaModules': [
'karmaModules-ngAria': [
'@angularSrcModuleNgAria',
'test/ngAria/**/*.js'
],
'karmaModules-ngCookies': [
'@angularSrcModuleNgCookies',
'test/ngCookies/**/*.js'
],
'karmaModules-ngMessageFormat': [
'@angularSrcModuleNgMessageFormat',
'test/ngMessageFormat/**/*.js'
],
'karmaModules-ngMessages': [
'build/angular-animate.js',
'@angularSrcModuleNgMessages',
'test/ngMessages/**/*.js'
],
// ngMock doesn't include the base because it must use the ngMock src files
'karmaModules-ngMock': [
'build/angular.js',
'@angularSrcModules',
'src/ngMock/*.js',
'test/modules/no_bootstrap.js',
'test/helpers/*.js',
'test/ngAnimate/*.js',
'test/ngMessageFormat/*.js',
'test/ngMessages/*.js',
'test/ngMock/*.js',
'test/ngCookies/*.js',
'test/ngRoute/**/*.js',
'test/ngResource/*.js',
'test/ngSanitize/**/*.js',
'test/ngTouch/**/*.js',
'test/ngAria/*.js'
'test/helpers/matchers.js',
'test/helpers/privateMocks.js',
'test/helpers/support.js',
'test/helpers/testabilityPatch.js',
'src/routeToRegExp.js',
'build/angular-animate.js',
'test/ngMock/**/*.js'
],
'karmaModules-ngResource': [
'@angularSrcModuleNgResource',
'test/ngResource/**/*.js'
],
'karmaModules-ngRoute': [
'build/angular-animate.js',
'@angularSrcModuleNgRoute',
'test/ngRoute/**/*.js'
],
'karmaModules-ngSanitize': [
'@angularSrcModuleNgSanitize',
'test/ngSanitize/**/*.js'
],
'karmaModules-ngTouch': [
'@angularSrcModuleNgTouch',
'test/ngTouch/**/*.js'
],
'karmaJquery': [
'bower_components/jquery/dist/jquery.js',
'node_modules/jquery/dist/jquery.js',
'test/jquery_alias.js',
'@angularSrc',
'@angularSrcModules',
'@angularScenario',
'@angularTest'
],
'karmaJqueryExclude': [
'src/angular-bootstrap.js',
'src/ngScenario/angular-bootstrap.js',
'test/jquery_remove.js',
'src/angular.bind.js'
]
@@ -248,13 +276,23 @@ var angularFiles = {
angularFiles['karmaJquery' + jQueryVersion] = []
.concat(angularFiles.karmaJquery)
.map(function(path) {
if (path.startsWith('bower_components/jquery')) {
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
if (path.startsWith('node_modules/jquery')) {
return path.replace(/^node_modules\/jquery/, 'node_modules/jquery-' + jQueryVersion);
}
return path;
});
});
angularFiles['angularSrcModuleNgAnimate'] = angularFiles['angularModules']['ngAnimate'];
angularFiles['angularSrcModuleNgAria'] = angularFiles['angularModules']['ngAria'];
angularFiles['angularSrcModuleNgCookies'] = angularFiles['angularModules']['ngCookies'];
angularFiles['angularSrcModuleNgMessageFormat'] = angularFiles['angularModules']['ngMessageFormat'];
angularFiles['angularSrcModuleNgMessages'] = angularFiles['angularModules']['ngMessages'];
angularFiles['angularSrcModuleNgResource'] = angularFiles['angularModules']['ngResource'];
angularFiles['angularSrcModuleNgRoute'] = angularFiles['angularModules']['ngRoute'];
angularFiles['angularSrcModuleNgSanitize'] = angularFiles['angularModules']['ngSanitize'];
angularFiles['angularSrcModuleNgTouch'] = angularFiles['angularModules']['ngTouch'];
angularFiles['angularSrcModules'] = [].concat(
angularFiles['angularModules']['ngAnimate'],
angularFiles['angularModules']['ngMessageFormat'],
+44
View File
@@ -0,0 +1,44 @@
'use strict';
angular
.module('animationBenchmark', ['ngAnimate'], config)
.controller('BenchmarkController', BenchmarkController);
// Functions - Definitions
function config($compileProvider) {
$compileProvider
.commentDirectivesEnabled(false)
.cssClassDirectivesEnabled(false)
.debugInfoEnabled(false);
}
function BenchmarkController($scope) {
var self = this;
var itemCount = 1000;
var items = (new Array(itemCount + 1)).join('.').split('');
benchmarkSteps.push({
name: 'create',
fn: function() {
$scope.$apply(function() {
self.items = items;
});
}
});
benchmarkSteps.push({
name: '$digest',
fn: function() {
$scope.$root.$digest();
}
});
benchmarkSteps.push({
name: 'destroy',
fn: function() {
$scope.$apply(function() {
self.items = [];
});
}
});
}
+22
View File
@@ -0,0 +1,22 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [
{
id: 'jquery',
src: 'jquery-noop.js'
}, {
id: 'angular',
src: '/build/angular.js'
}, {
id: 'angular-animate',
src: '/build/angular-animate.js'
}, {
src: 'app.js'
}
]
});
};
+1
View File
@@ -0,0 +1 @@
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
+28
View File
@@ -0,0 +1,28 @@
<style>
[ng-cloak] { display: none !important; }
.animation-container .ng-enter,
.animation-container .ng-leave {
transition: all 0.1s;
}
.animation-container .ng-enter,
.animation-container .ng-leave.ng-leave-active {
opacity: 0;
}
.animation-container .ng-enter.ng-enter-active,
.animation-container .ng-leave {
opacity: 1;
}
</style>
<div ng-app="animationBenchmark" ng-cloak ng-controller="BenchmarkController as bm">
<div class="container-fluid">
<h2>Large collection of elements animated in and out with ngAnimate</h2>
<div class="animation-container">
<div ng-repeat="i in bm.items track by $index">
Just a plain ol' element
</div>
</div>
</div>
</div>
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
+108
View File
@@ -0,0 +1,108 @@
'use strict';
var app = angular.module('ngClassBenchmark', []);
app.controller('DataController', function DataController($scope) {
this.init = function() {
this.numberOfTodos = 1000;
this.implementation = 'tableOptimized';
this.completedPeriodicity = 3;
this.importantPeriodicity = 13;
this.urgentPeriodicity = 29;
this.createTodos(100);
this.setTodosValuesWithSeed(0);
};
this.clearTodos = function() {
this.todos = null;
};
this.createTodos = function(count) {
var i;
this.todos = [];
for (i = 0; i < count; i++) {
this.todos.push({
id: i + 1,
completed: false,
important: false,
urgent: false
});
}
};
this.setTodosValuesWithSeed = function(offset) {
var i, todo;
for (i = 0; i < this.todos.length; i++) {
todo = this.todos[i];
todo.completed = 0 === (i + offset) % this.completedPeriodicity;
todo.important = 0 === (i + offset) % this.importantPeriodicity;
todo.urgent = 0 === (i + offset) % this.urgentPeriodicity;
}
};
this.init();
benchmarkSteps.push({
name: 'setup',
fn: function() {
$scope.$apply();
this.clearTodos();
this.createTodos(this.numberOfTodos);
}.bind(this)
});
benchmarkSteps.push({
name: 'create',
fn: function() {
// initialize data for first time that will construct the DOM
this.setTodosValuesWithSeed(0);
$scope.$apply();
}.bind(this)
});
benchmarkSteps.push({
name: '$apply',
fn: function() {
$scope.$apply();
}
});
benchmarkSteps.push({
name: 'update',
fn: function() {
// move everything but completed
this.setTodosValuesWithSeed(3);
$scope.$apply();
}.bind(this)
});
benchmarkSteps.push({
name: 'unclass',
fn: function() {
// remove all classes
this.setTodosValuesWithSeed(NaN);
$scope.$apply();
}.bind(this)
});
benchmarkSteps.push({
name: 'class',
fn: function() {
// add all classes as the initial state
this.setTodosValuesWithSeed(0);
$scope.$apply();
}.bind(this)
});
benchmarkSteps.push({
name: 'destroy',
fn: function() {
this.clearTodos();
$scope.$apply();
}.bind(this)
});
});
+15
View File
@@ -0,0 +1,15 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [{
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
}]
});
};
+177
View File
@@ -0,0 +1,177 @@
<style>
.gold {
background: gold;
}
.silver {
background: silver;
}
.table tbody tr > td.success {
background-color: #dff0d8;
}
.table tbody tr > td.error {
background-color: #f2dede;
}
.table tbody tr > td.warning {
background-color: #fcf8e3;
}
.table tbody tr > td.info {
background-color: #d9edf7;
}
.completed {
text-decoration: line-through;
}
.important {
font-weight: bold;
}
.urgent {
color: red;
}
</style>
<div ng-app="ngClassBenchmark" ng-cloak class="container-fluid">
<div ng-controller="DataController as benchmark" class="row">
<div class="col-lg-12">
<div class="well">
<h3>Parameters</h3>
<br>
<p>
<label>Number of todos</label><br>
<input type="number" ng-model="benchmark.numberOfTodos">
</p>
<br>
<p>
<label>Implementation</label><br>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="tableOptimized"
type="radio" name="implementation">
Table optimized <br>
<code>ng-class="todo.completed && 'success'"</code>
</label>
</div>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="table"
type="radio" name="implementation">
Table <br>
<code>ng-class="{success: todo.completed}"</code>
</label>
</div>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="list"
type="radio" name="implementation">
List <br>
<code>ng-class="{completed: todo.completed, urgent: todo.urgent, important: todo.important"}</code>
</label>
</div>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="singleOptimized"
type="radio" name="implementation">
Single ngClass optimized <br>
<code>
ng-class="{'panel-success': !!benchmark.todos, 'panel-danger': !benchmark.todos}"
</code>
</label>
</div>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="single"
type="radio" name="implementation">
Single ngClass <br>
<code>
ng-class="{'panel-success': benchmark.todos, 'panel-danger': !benchmark.todos}"
</code>
</label>
</div>
</p>
</div>
<br>
<h3>Example</h3>
<div ng-switch="benchmark.implementation">
<table ng-switch-when="tableOptimized" class="table">
<thead>
<tr>
<th>todo #id</th>
<th>completed?</th>
<th>urgent?</th>
<th>important?</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="todo in benchmark.todos track by todo.id"
ng-class="todo.completed && 'active'"
ng-class-even="todo.completed && todo.important && 'gold'"
ng-class-odd="todo.completed && todo.important && 'silver'"
>
<td>#{{todo.id}}</td>
<td>{{todo.completed}}</td>
<td ng-class="todo.urgent && 'danger'">{{todo.urgent}}</td>
<td ng-class="todo.important && 'success'">{{todo.important}}</td>
</tr>
</tbody>
</table>
<table ng-switch-when="table" class="table">
<thead>
<tr>
<th>todo #id</th>
<th>completed?</th>
<th>urgent?</th>
<th>important?</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="todo in benchmark.todos track by todo.id"
ng-class="{active: todo.completed}"
ng-class-even="{gold: todo.completed && todo.important}"
ng-class-odd="{silver: todo.completed && todo.important}"
>
<td>#{{todo.id}}</td>
<td>{{todo.completed}}</td>
<td ng-class="{danger: todo.urgent}">{{todo.urgent}}</td>
<td ng-class="{success: todo.important}">{{todo.important}}</td>
</tr>
</tbody>
</table>
<ul ng-switch-when="list">
<li ng-repeat="todo in benchmark.todos track by todo.id"
ng-class="{
completed: todo.completed,
urgent: todo.urgent,
important: todo.important
}">#{{todo.id}}</li>
</ul>
<div ng-switch-when="singleOptimized"
class="panel"
ng-class="{'panel-success': !!benchmark.todos, 'panel-danger': !benchmark.todos}">
<div class="panel-heading">
<h3 class="panel-title">Information</h3>
</div>
<div class="panel-body"> The title is green because there are todos... </div>
</div>
<div ng-switch-when="single"
class="panel"
ng-class="{'panel-success': benchmark.todos, 'panel-danger': !benchmark.todos}">
<div class="panel-heading">
<h3 class="panel-title">Information</h3>
</div>
<div class="panel-body"> The title is green because there are todos... </div>
</div>
</div>
</div>
</div>
</div>
<br><br><br>
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
+7 -11
View File
@@ -29,19 +29,16 @@ app.directive('bmPeWatch', function() {
};
});
//Executes the specified expression as a watcher
//Adds a simple wrapper method to allow use of $watch instead of $watchCollection
app.directive('bmPeWatchLiteral', function($parse) {
function retZero() {
return 0;
}
//Executes the specified expression as a collection watcher
app.directive('bmPeWatchCollection', function() {
return {
restrict: 'A',
compile: function($element, $attrs) {
$element.text($attrs.bmPeWatchLiteral);
$element.text($attrs.bmPeWatchCollection);
return function($scope, $element, $attrs) {
$scope.$watch($parse($attrs.bmPeWatchLiteral, retZero));
$scope.$watchCollection($attrs.bmPeWatchCollection, function(val) {
$element.text(val);
});
};
}
};
@@ -72,8 +69,7 @@ app.controller('DataController', function($scope, $rootScope) {
date2: new Date(Math.random() * Date.now()),
func: function() { return star; },
obj: data[i - 1],
keys: data[i - 1] && (data[i - 1].keys || Object.keys(data[i - 1])),
constructor: data[i - 1]
keys: data[i - 1] && (data[i - 1].keys || Object.keys(data[i - 1]))
});
}
+45 -35
View File
@@ -16,12 +16,6 @@
<label for="complexPath">Complex Paths</label>
</li>
<li>
<input type="radio" ng-model="expressionType" value="constructorPath" id="constructorPath">
<label for="constructorPath">Constructor Paths</label>
($parse special cases "constructor" for security)
</li>
<li>
<input type="radio" ng-model="expressionType" value="fieldAccess" id="fieldAccess">
<label for="fieldAccess">Field Accessors</label>
@@ -66,6 +60,16 @@
<input type="radio" ng-model="expressionType" value="arrayLiterals" id="arrayLiterals">
<label for="arrayLiterals">Array Literals</label>
</li>
<li>
<input type="radio" ng-model="expressionType" value="watchCollection" id="watchCollection">
<label for="watchCollection">$watchCollection</label>
</li>
<li>
<input type="radio" ng-model="expressionType" value="watchCollectionLiterals" id="watchCollectionLiterals">
<label for="watchCollectionLiterals">$watchCollection Literals</label>
</li>
</ul>
<!--
@@ -88,17 +92,6 @@
<span bm-pe-watch="row.keys"></span>
</li>
<li ng-switch-when="constructorPath" ng-repeat="(rowIdx, row) in ::data">
<span bm-pe-watch="row.index"></span>
<span bm-pe-watch="row.constructor.index"></span>
<span bm-pe-watch="row.constructor.index"></span>
<span bm-pe-watch="row.constructor.index"></span>
<span bm-pe-watch="row.constructor.constructor.index"></span>
<span bm-pe-watch="row.constructor.constructor.index"></span>
<span bm-pe-watch="row.constructor.constructor.constructor.index"></span>
<span bm-pe-watch="row.constructor.constructor.constructor.index"></span>
</li>
<li ng-switch-when="complexPath" ng-repeat="(rowIdx, row) in ::data">
<span bm-pe-watch="row.index"></span>
<span bm-pe-watch="row.num0"></span>
@@ -215,27 +208,44 @@
</li>
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
<span bm-pe-watch-literal="{0: row, 1: rowIdx, 2: 3}"></span>
<span bm-pe-watch-literal="{str: 'foo', num: rowIdx, b: true}"></span>
<span bm-pe-watch-literal="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
<span bm-pe-watch-literal="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
<span bm-pe-watch="{foo: rowIdx}"></span>
<span bm-pe-watch="{foo: row, bar: rowIdx}"></span>
<span bm-pe-watch="{0: row, 1: rowIdx, 2: 3}"></span>
<span bm-pe-watch="{str: 'foo', num: rowIdx, b: true}"></span>
<span bm-pe-watch="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
<span bm-pe-watch="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
</li>
<li ng-switch-when="arrayLiterals" ng-repeat="(rowIdx, row) in ::data">
<span bm-pe-watch-literal="[rowIdx]"></span>
<span bm-pe-watch-literal="[rowIdx, 0]"></span>
<span bm-pe-watch-literal="[rowIdx, 0, 1]"></span>
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2]"></span>
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2, 3]"></span>
<span bm-pe-watch-literal="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
<span bm-pe-watch-literal="[rowIdx, undefined, null, true, false]"></span>
<span bm-pe-watch-literal="[[][0], [0][0], [][rowIdx]]"></span>
<span bm-pe-watch-literal="[0, rowIdx]"></span>
<span bm-pe-watch-literal="[0, 1, rowIdx]"></span>
<span bm-pe-watch-literal="[0, 1, 2, rowIdx]"></span>
<span bm-pe-watch-literal="[0, 1, 2, 3, rowIdx]"></span>
<span bm-pe-watch="[rowIdx]"></span>
<span bm-pe-watch="[rowIdx, 0]"></span>
<span bm-pe-watch="[rowIdx, 0, 1]"></span>
<span bm-pe-watch="[rowIdx, 0, 1, 2]"></span>
<span bm-pe-watch="[rowIdx, 0, 1, 2, 3]"></span>
<span bm-pe-watch="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
<span bm-pe-watch="[rowIdx, undefined, null, true, false]"></span>
<span bm-pe-watch="[[][0], [0][0], [][rowIdx]]"></span>
<span bm-pe-watch="[0, rowIdx]"></span>
<span bm-pe-watch="[0, 1, rowIdx]"></span>
<span bm-pe-watch="[0, 1, 2, rowIdx]"></span>
<span bm-pe-watch="[0, 1, 2, 3, rowIdx]"></span>
</li>
<li ng-switch-when="watchCollection" ng-repeat="(rowIdx, row) in data">
<span bm-pe-watch-collection="data"></span>
<span bm-pe-watch-collection="row.keys"></span>
<span bm-pe-watch-collection="thisProbablyDoesntHaveAValue"></span>
</li>
<li ng-switch-when="watchCollectionLiterals" ng-repeat="(rowIdx, row) in ::data">
<span bm-pe-watch-collection="[rowIdx, row]"></span>
<span bm-pe-watch-collection="[rowIdx, row, num0, str0, date0, obj, g, h, i, j, k, l, m, n, o, p]"></span>
<span bm-pe-watch-collection="{a: rowIdx, b: row, c: num0, d: str0, e: date0, f: obj, g: g, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p}"></span>
<!-- primitive/valueOf-compatible -->
<span bm-pe-watch-collection="[rowIdx, row]"></span>
<span bm-pe-watch-collection="[rowIdx, num0, str0, date0, date1, h, i, j, k, l, m, n, o, p]"></span>
<span bm-pe-watch-collection="{a: rowIdx, c: num0, d: str0, e: date0, g: date1, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p}"></span>
</li>
</ul>
</div>
@@ -0,0 +1,9 @@
'use strict';
angular.module('repeatAnimateBenchmark', ['ngAnimate'])
.config(function($animateProvider) {
$animateProvider.classNameFilter(/animate-/);
})
.run(function($rootScope) {
$rootScope.fileType = 'classfilter';
});
@@ -0,0 +1,6 @@
'use strict';
angular.module('repeatAnimateBenchmark', [])
.run(function($rootScope) {
$rootScope.fileType = 'noanimate';
});
+7
View File
@@ -0,0 +1,7 @@
'use strict';
angular.module('repeatAnimateBenchmark', ['ngAnimate'])
.run(function($rootScope) {
$rootScope.fileType = 'default';
});
+24
View File
@@ -0,0 +1,24 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [
{
id: 'angular',
src: '/build/angular.js'
},
{
id: 'angular-animate',
src: '/build/angular-animate.js'
},
{
id: 'app',
src: 'app.js'
},
{
src: 'common.js'
}]
});
};
+120
View File
@@ -0,0 +1,120 @@
'use strict';
(function() {
var app = angular.module('repeatAnimateBenchmark');
app.config(function($compileProvider, $animateProvider) {
if ($compileProvider.debugInfoEnabled) {
$compileProvider.debugInfoEnabled(false);
}
});
app.run(function($animate) {
if ($animate.enabled) {
$animate.enabled(true);
}
});
app.controller('DataController', function($scope, $rootScope, $animate) {
var totalRows = 500;
var totalColumns = 20;
var data = $scope.data = [];
function fillData() {
if ($animate.enabled) {
$animate.enabled($scope.benchmarkType !== 'globallyDisabled');
}
for (var i = 0; i < totalRows; i++) {
data[i] = [];
for (var j = 0; j < totalColumns; j++) {
data[i][j] = {
i: i
};
}
}
}
benchmarkSteps.push({
name: 'enter',
fn: function() {
$scope.$apply(function() {
fillData();
});
}
});
benchmarkSteps.push({
name: 'leave',
fn: function() {
$scope.$apply(function() {
data = $scope.data = [];
});
}
});
});
app.directive('disableAnimations', function($animate) {
return {
link: {
pre: function(s, e) {
$animate.enabled(e, false);
}
}
};
});
app.directive('noop', function($animate) {
return {
link: {
pre: angular.noop
}
};
});
app.directive('baseline', function($document) {
return {
restrict: 'E',
link: function($scope, $element) {
var document = $document[0];
var i, j, row, cell, comment;
var template = document.createElement('span');
template.setAttribute('ng-repeat', 'foo in foos');
template.classList.add('ng-scope');
template.appendChild(document.createElement('span'));
template.appendChild(document.createTextNode(':'));
function createList() {
for (i = 0; i < $scope.data.length; i++) {
row = document.createElement('div');
$element[0].appendChild(row);
for (j = 0; j < $scope.data[i].length; j++) {
cell = template.cloneNode(true);
row.appendChild(cell);
cell.childNodes[0].textContent = i;
cell.ng339 = 'xxx';
comment = document.createComment('ngRepeat end: bar in foo');
row.appendChild(comment);
}
comment = document.createComment('ngRepeat end: foo in foos');
$element[0].appendChild(comment);
}
}
$scope.$watch('data.length', function(newVal) {
if (newVal === 0) {
while ($element[0].firstChild) {
$element[0].removeChild($element[0].firstChild);
}
} else {
createList();
}
});
}
};
});
})();
+70
View File
@@ -0,0 +1,70 @@
<div ng-app="repeatAnimateBenchmark" ng-cloak>
<div ng-controller="DataController">
<div class="container-fluid">
<p>
Tests rendering of an ngRepeat with 500 elements.<br>
Animations can be enabled / disabled in different ways.<br>
Two tests require reloading the app with different module / app configurations.
</p>
<div><label><input type="radio" ng-model="benchmarkType" value="none">none: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="baseline">baseline (vanilla Javascript): </label></div>
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default'" value="enabled">enabled : </label> (requires <a href="./">app.js</a>)</div>
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default' && fileType !== 'classfilter'" value="globallyDisabled">globally disabled:</label> (requires <a href="./">app.js</a> or <a href="?app=app-classfilter.js">app-classfilter.js</a>)</div>
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default'" value="disabledParentElement">disabled by $animate.enabled() on parent element: </label> (requires <a href="./">app.js</a>)</div>
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'noanimate'" value="noanimate">Without ngAnimate:</label> (requires <a href="?app=app-noanimate.js">app-noanimate.js</a>)</div>
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'classfilter'" value="disabledClassFilter">disabled by classNameFilter on element:</label> (requires <a href="?app=app-classfilter.js">app-classfilter.js</a>)</div>
<ng-switch on="benchmarkType">
<baseline ng-switch-when="baseline">
</baseline>
<div ng-switch-when="noanimate">
<div noop>
<div ng-repeat="row in data">
<span ng-repeat="column in row">
<span>{{column.i}}</span>
</span>
</div>
</div>
</div>
<div ng-switch-when="enabled">
<div noop>
<div ng-repeat="row in data">
<span ng-repeat="column in row">
<span>{{column.i}}</span>
</span>
</div>
</div>
</div>
<div ng-switch-when="globallyDisabled">
<div noop>
<div ng-repeat="row in data">
<span ng-repeat="column in row">
<span>{{column.i}}</span>
</span>
</div>
</div>
</div>
<div ng-switch-when="disabledClassFilter">
<div noop>
<div ng-repeat="row in data">
<span class="disable-animations" ng-repeat="column in row">
<span>{{column.i}}</span>
</span>
</div>
</div>
</div>
<div ng-switch-when="disabledParentElement">
<div disable-animations>
<div ng-repeat="row in data">
<span ng-repeat="column in row">
<span>{{column.i}}</span>
</span>
</div>
</div>
</div>
</ng-switch>
</div>
</div>
</div>
-11
View File
@@ -1,11 +0,0 @@
{
"name": "angularjs",
"license": "MIT",
"devDependencies": {
"jquery": "3.1.0",
"jquery-2.2": "jquery#2.2.4",
"jquery-2.1": "jquery#2.1.4",
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.4/assets/ng-closure-runner.zip"
}
}
+2 -1
View File
@@ -13,7 +13,8 @@ body {
text-align: center;
}
#json, #xml {
#json,
#xml {
display: none;
}
+6 -2
View File
@@ -1,7 +1,11 @@
@charset "UTF-8";
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
.ng-cloak, .x-ng-cloak,
[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak,
.ng-hide:not(.ng-hide-animate) {
display: none !important;
}
+1
View File
@@ -0,0 +1 @@
.visible-phone{display:none}.visible-desktop{display:block}.navbar{display:block}.navbar .container{padding:0 16px;width:auto}.navbar .brand{float:left;margin:8px 80px 0 8px;padding:0}.navbar .brand a{display:block;height:30px;margin:6px 0 5px 0;overflow:hidden;padding:0;width:117px}.navbar .nav{float:right}.navbar .nav .dropdown-toggle{color:rgba(255,255,255,0.87);font-size:16px;font-weight:300;line-height:56px;padding:0 24px;text-transform:uppercase;transition:all .3s}.navbar .nav .dropdown-toggle:hover,.navbar .nav .dropdown-toggle:active,.navbar .nav .dropdown-toggle:focus{background:#37474F;color:#fff}.navbar .nav .dropdown-menu{background:#37474F;border:none;border-radius:0;box-shadow:0 0 16px rgba(0,0,0,0.12),0 16px 16px rgba(0,0,0,0.24);color:#fff;left:auto;margin:0;padding:0;right:0}.navbar .nav .dropdown-menu:after,.navbar .nav .dropdown-menu:before{display:none}.navbar .nav .dropdown-menu li{border-bottom:1px solid rgba(38,50,56,0.56);box-sizing:border-box;line-height:48px}.navbar .nav .dropdown-menu li:last-child{border:none}.navbar .nav .dropdown-menu a{background:#37474F;color:#fff;font-weight:300;line-height:48px;padding:0 16px;transition:all .2s}.navbar .nav .dropdown-menu a:hover,.navbar .nav .dropdown-menu a:focus{background:#455A64}.navbar .navbar-search{left:200px;margin:0;position:absolute;right:440px;top:8px;width:auto}.navbar .navbar-search i{color:#546E7A;font-size:16px;left:12px;position:absolute;top:11px}.navbar .navbar-search .search-query{background:#37474F;border:none;border-radius:2px;box-shadow:none;box-sizing:border-box;color:#546E7A;font-size:14px;height:40px;width:100%;padding:0 16px 0 32px;text-shadow:none;transition:all .3s}.navbar .navbar-search .search-query:-webkit-autofill,.navbar .navbar-search .search-query:-webkit-autofill:hover,.navbar .navbar-search .search-query:-webkit-autofill:focus{background-color:#fff;transition:background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#455A64}.navbar .navbar-search .search-query:hover,.navbar .navbar-search .search-query:active,.navbar .navbar-search .search-query:focus{background:#fff;box-shadow:inset 0 2px 4px rgba(0,0,0,0.24);color:#2196F3}.navbar .navbar-search .search-query::-webkit-input-placeholder{color:#546E7A}.navbar .navbar-search .search-query::-moz-placeholder{color:#546E7A}.navbar .navbar-search .search-query:-ms-input-placeholder{color:#546E7A}.navbar .navbar-search .search-query:-moz-placeholder{color:#546E7A}#navbar-main .navbar-inner{background:#263238;height:56px}#navbar-notice{z-index:1029;top:56px}#navbar-notice .navbar-inner{background:#ECEFF1;box-shadow:0 0 3px rgba(0,0,0,0.12),0 3px 3px rgba(0,0,0,0.24);height:auto}.site-notice{padding:4px 0;text-align:center;font-size:13px;margin:0}@media handheld and (max-width: 800px), screen and (max-device-width: 800px), screen and (max-width: 800px){.visible-phone{display:block}.visible-desktop{display:none}}@media handheld and (max-width: 800px), screen and (max-device-width: 800px), screen and (max-width: 800px){.homepage .container{padding:16px;width:auto}.homepage .span1{width:auto}.homepage .span2{width:auto}.homepage .span3{width:auto}.homepage .span4{width:auto}.homepage .span5{width:auto}.homepage .span6{width:auto}.homepage .span7{width:auto}.homepage .span8{width:auto}.homepage .span9{width:auto}.homepage .span10{width:auto}.homepage .navbar .container{padding:0 8px}.homepage #navbar-main .navbar-inner{height:40px}.homepage #navbar-main .brand{margin:6px 0 0 0}.homepage #navbar-main .brand a{margin:0}.homepage #navbar-main .nav{margin:0}.homepage #navbar-main .nav .dropdown-toggle{font-size:12px;line-height:40px;padding:0 8px}.homepage #navbar-main .dropdown-menu a{padding:0 8px}.homepage #navbar-main .navbar-search{background:#263238;border-bottom:1px solid #263238;left:0;right:0;top:100%}.homepage #navbar-main .navbar-search i{left:12px;top:7px}.homepage #navbar-main .navbar-search .search-query{border-radius:0;height:32px}.homepage #navbar-notice{top:40px}.homepage #navbar-notice .site-notice{font-size:11px}.homepage .hero{padding:80px 32px 32px 32px}.homepage .hero h2{background-size:230px 60px;height:60px;width:230px}}
+171 -9
View File
@@ -1,3 +1,37 @@
@font-face {
font-family: 'Open Sans';
src: url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.eot?v=1.1.0");
src: url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.eot?#iefix&v=1.1.0") format("embedded-opentype"),
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.woff?v=1.1.0") format("woff"),
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.ttf?v=1.1.0") format("truetype"),
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.svg?v=1.1.0#OpenSansBold") format("svg");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src: url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.eot?v=1.1.0");
src: url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.eot?#iefix&v=1.1.0") format("embedded-opentype"),
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.woff?v=1.1.0") format("woff"),
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.ttf?v=1.1.0") format("truetype"),
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.svg?v=1.1.0#OpenSansBold") format("svg");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src: url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.eot?v=1.1.0");
src: url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.eot?#iefix&v=1.1.0") format("embedded-opentype"),
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.woff?v=1.1.0") format("woff"),
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.ttf?v=1.1.0") format("truetype"),
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.svg?v=1.1.0#OpenSansBold") format("svg");
font-weight: bold;
font-style: normal;
}
html, body {
position: relative;
height: 100%;
@@ -53,13 +87,13 @@ h1,h2,h3,h4,h5,h6 {
}
.header .brand {
padding-top: 6px;
padding-bottom: 0px;
}
.header .brand img {
margin-top: 5px;
height: 30px;
margin-top: 0;
height: auto;
vertical-align: top;
}
.docs-search {
@@ -82,6 +116,11 @@ h1,h2,h3,h4,h5,h6 {
margin-right: 10px;
}
.navbar .navbar-search i {
top: 13px;
font-size: 12px;
}
.docs-search > .search-query:focus {
outline: 0;
}
@@ -297,6 +336,7 @@ iframe.example {
}
.search-results-container {
position: relative;
padding-bottom: 1em;
border-top: 1px solid #111;
background: #181818;
@@ -435,15 +475,17 @@ iframe.example {
background: #f1f1f1;
}
.sup-header {
#navbar-sub {
padding-top: 10px;
padding-bottom: 5px;
background: rgba(245,245,245,0.88);
box-shadow: 0 0 2px #999;
z-index: 1028;
top: 83px;
}
.main-body-grid {
margin-top: 120px;
margin-top: 144px;
position: relative;
}
@@ -454,7 +496,7 @@ iframe.example {
.main-body-grid > .grid-left {
position: fixed;
top: 120px;
top: 144px;
bottom: 0;
overflow: auto;
}
@@ -671,14 +713,14 @@ ul.events > li {
margin-right: 5px;
}
@media only screen and (min-width: 769px) {
@media only screen and (min-width: 768px) {
[ng-include="partialPath"].ng-hide {
display: block !important;
visibility: hidden;
}
}
@media only screen and (min-width: 769px) and (max-width: 991px) {
@media only screen and (min-width: 768px) and (max-width: 991px) {
.main-body-grid {
margin-top: 160px;
}
@@ -687,7 +729,7 @@ ul.events > li {
}
}
@media only screen and (max-width : 768px) {
@media only screen and (max-width: 767px) {
.picker, .picker select {
width: auto;
display: block;
@@ -827,3 +869,123 @@ ul.events > li {
iframe[name="example-anchoringExample"] {
height: 400px;
}
/*
angular-topnav.css and bootstrap overrides
*/
.navbar .navbar-inner .container {
padding: 0 16px;
width: auto;
height: auto;
}
.navbar .nav > li {
float: left;
}
.navbar-nav .open .dropdown-menu {
position: absolute;
float: left;
}
.navbar-nav .open .dropdown-menu > li > a {
line-height: 48px;
}
#navbar-main .navbar-inner, #navbar-notice .navbar-inner {
box-shadow: none;
}
#navbar-sub .container {
max-width: 970px;
}
.nav .open > a, .nav .open > a:hover, .nav .open > a:focus {
background-color: inherit;
}
toc-container {
display: block;
margin: 15px 10px;
}
toc-container b {
text-transform: uppercase;
}
toc-container .btn {
padding: 3px 6px;
font-size: 13px;
margin-left: 5px;
}
toc-container > div > toc-tree ul {
list-style: none;
padding-left: 15px;
padding-bottom: 2px;
}
toc-container > div > toc-tree > ul {
padding-left: 0;
}
toc-container > div > toc-tree > ul > li > toc-tree > ul > li toc-tree > ul li {
font-size: 13px;
}
.dev-status span {
padding: 2px 8px;
border-radius: 5px;
}
.security span { background-color: orange; }
.stable span { background-color: green; color: white; }
.current span { background-color: blue; color: white; }
@media handheld and (max-width:800px), screen and (max-device-width:800px), screen and (max-width:800px) {
.navbar {
min-height: auto;
}
.search-results-container {
top: 32px;
overflow: auto;
max-height: 85vh;
padding-bottom: 0;
position: static;
}
.search-close {
right: 1px;
margin-left: 0;
top: 41px;
padding: 5px 10px;
border-top-right-radius: 0;
border-top-left-radius: 0;
box-shadow: none;
width: auto;
bottom: auto;
left: auto;
}
.navbar-nav .open .dropdown-menu > li > a, .navbar-nav .open .dropdown-menu .dropdown-header {
padding: 0 8px;
}
.homepage #navbar-notice {
top: 72px;
}
#navbar-notice .navbar-inner {
box-shadow: 0 0 3px rgba(0, 0, 0, .12), 0 3px 3px rgba(0, 0, 0, .24)
}
#navbar-sub {
position: relative;
top: 17px;
margin-top: 80px;
padding-bottom: 0;
margin-bottom: 0;
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 183 B

+1 -1
View File
@@ -4,7 +4,7 @@
/* global importScripts, lunr */
// Load up the lunr library
importScripts('../components/lunr.js-0.5.12/lunr.min.js');
importScripts('../components/lunr-0.7.2/lunr.min.js');
// Create the lunr index - the docs should be an array of object, each object containing
// the path and search terms for a page
+4
View File
@@ -0,0 +1,4 @@
User-agent: *
# The map files are not required by the app
Disallow: /*.map$
+1
View File
@@ -9,6 +9,7 @@
},
"globals": {
"angular": false,
/* testabilityPatch / matchers */
"inject": false,
"module": false,
+30 -33
View File
@@ -1,51 +1,48 @@
'use strict';
describe('doc.angularjs.org', function() {
describe('API pages', function() {
describe('API pages', function() {
it('should display links to code on GitHub', function() {
browser.get('build/docs/index.html#!/api/ng/service/$http');
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
it('should display links to code on GitHub', function() {
browser.get('build/docs/index.html#!/api/ng/service/$http');
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
browser.get('build/docs/index.html#!/api/ng/service/$http');
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
});
browser.get('build/docs/index.html#!/api/ng/service/$http');
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
});
it('should change the page content when clicking a link to a service', function() {
browser.get('build/docs/index.html');
it('should change the page content when clicking a link to a service', function() {
browser.get('build/docs/index.html');
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
ngBindLink.click();
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
ngBindLink.click();
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('ngClick');
});
var mainHeader = element(by.css('.main-body h1 '));
expect(mainHeader.getText()).toEqual('ngClick');
});
it('should show the functioning input directive example', function() {
browser.get('build/docs/index.html#!/api/ng/directive/input');
it('should show the functioning input directive example', function() {
browser.get('build/docs/index.html#!/api/ng/directive/input');
// Ensure that the page is loaded before trying to switch frames.
browser.waitForAngular();
// Ensure that the page is loaded before trying to switch frames.
browser.waitForAngular();
browser.switchTo().frame('example-input-directive');
browser.switchTo().frame('example-input-directive');
var nameInput = element(by.model('user.name'));
nameInput.sendKeys('!!!');
var nameInput = element(by.model('user.name'));
nameInput.sendKeys('!!!');
var code = element.all(by.css('tt')).first();
expect(code.getText()).toContain('guest!!!');
});
var code = element.all(by.css('tt')).first();
expect(code.getText()).toContain('guest!!!');
});
it('should trim indentation from code blocks', function() {
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
it('should trim indentation from code blocks', function() {
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
var codeBlocks = element.all(by.css('pre > code.lang-js'));
codeBlocks.each(function(codeBlock) {
var firstSpan = codeBlock.all(by.css('span')).first();
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
});
var codeBlocks = element.all(by.css('pre > code.lang-js'));
codeBlocks.each(function(codeBlock) {
var firstSpan = codeBlock.all(by.css('span')).first();
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
});
});
});
@@ -0,0 +1,58 @@
'use strict';
describe('directives', function() {
describe('parameter section', function() {
it('should show the directive name only if it is a param (attribute) with a value', function() {
browser.get('build/docs/index.html#!/api/ng/directive/ngInclude');
expect(getParamNames().getText()).toContain('ngInclude | src');
browser.get('build/docs/index.html#!/api/ngRoute/directive/ngView');
expect(getParamNames().getText()).not.toContain('ngView');
});
});
describe('usage section', function() {
it('should show the directive name if it is a param (attribute) with a value', function() {
browser.get('build/docs/index.html#!/api/ng/directive/ngInclude');
expect(getUsageAs('element', 'ng-include').isPresent()).toBe(true);
expect(getUsageAs('attribute', 'ng-include').isPresent()).toBe(true);
expect(getUsageAs('CSS class', 'ng-include').isPresent()).toBe(true);
});
it('should show the directive name if it is a void param (attribute)', function() {
browser.get('build/docs/index.html#!/api/ngRoute/directive/ngView');
expect(getUsageAs('element', 'ng-view').isPresent()).toBe(true);
expect(getUsageAs('attribute', 'ng-view').isPresent()).toBe(true);
expect(getUsageAs('CSS class', 'ng-view').isPresent()).toBe(true);
});
});
});
function getParamNames() {
var argsSection = element(by.className('input-arguments'));
var paramNames = argsSection.all(by.css('tr td:nth-child(1)'));
return paramNames;
}
// Based on the type of directive usage, the directive name will show up in the code block
// with a specific class
var typeClassMap = {
element: 'tag',
attribute: 'atn',
'CSS class': 'atv'
};
function getUsageAs(type, directiveName) {
var usage = element(by.className('usage'));
var as = usage.element(by.cssContainingText('li', 'as ' + type));
return as.element(by.cssContainingText('span.' + typeClassMap[type], directiveName));
}
+93 -9
View File
@@ -21,6 +21,9 @@ describe('docs.angularjs.org', function() {
console.log('browser console errors: ' + require('util').inspect(filteredLog));
}
});
browser.ignoreSynchronization = false;
browser.clearMockModules();
});
@@ -44,30 +47,50 @@ describe('docs.angularjs.org', function() {
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
ngBindLink.click();
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('ngClick');
var mainHeader = element(by.css('.main-body h1 '));
expect(mainHeader.getText()).toEqual('ngClick');
});
it('should include the files for the embedded examples from the same domain', function() {
browser.get('build/docs/index-production.html#!api/ng/directive/ngClick');
var origin = browser.executeScript('return document.location.origin;');
var exampleIFrame = element(by.name('example-ng-click'));
// This is technically an implementation detail, but if this changes, then there's a good
// chance the deployment process changed
expect(exampleIFrame.getAttribute('src')).toContain('examples/example-ng-click/index.html');
browser.switchTo().frame('example-ng-click');
var scriptEl = element(by.tagName('script'));
// Ensure the included file is from the same domain
expect(scriptEl.getAttribute('src')).toContain(origin);
});
it('should be resilient to trailing slashes', function() {
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
var mainHeader = element(by.css('.main-body h1 '));
expect(mainHeader.getText()).toEqual('angular.noop');
});
it('should be resilient to trailing "index"', function() {
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
var mainHeader = element(by.css('.main-body h1 '));
expect(mainHeader.getText()).toEqual('angular.noop');
});
it('should be resilient to trailing "index/"', function() {
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index/');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
var mainHeader = element(by.css('.main-body h1 '));
expect(mainHeader.getText()).toEqual('angular.noop');
});
@@ -78,7 +101,68 @@ describe('docs.angularjs.org', function() {
it('should display an error if the page does not exist', function() {
browser.get('build/docs/index-production.html#!/api/does/not/exist');
expect(element(by.css('h1')).getText()).toBe('Oops!');
var mainHeader = element(by.css('.main-body h1 '));
expect(mainHeader.getText()).toEqual('Oops!');
});
it('should set "noindex" if the page does not exist', function() {
browser.get('build/docs/index-production.html#!/api/does/not/exist');
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
expect(robots.isPresent()).toBe(true);
expect(googleBot.isPresent()).toBe(true);
});
it('should remove "noindex" if the page exists', function() {
browser.get('build/docs/index-production.html#!/api');
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
expect(robots.isPresent()).toBe(false);
expect(googleBot.isPresent()).toBe(false);
});
describe('template request error', function() {
beforeEach(function() {
browser.addMockModule('httpMocker', function() {
angular.module('httpMocker', ['ngMock'])
.run(['$httpBackend', function($httpBackend) {
$httpBackend.whenGET('localhost:8000/build/docs/partials/api.html').respond(500, '');
}]);
});
});
it('should set "noindex" for robots if the request fails', function() {
// index-test includes ngMock
browser.get('build/docs/index-test.html#!/api');
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
expect(robots.isPresent()).toBe(true);
expect(googleBot.isPresent()).toBe(true);
});
});
describe('page bootstrap error', function() {
beforeEach(function() {
browser.addMockModule('httpMocker', function() {
// Require a module that does not exist to break the bootstrapping
angular.module('httpMocker', ['doesNotExist']);
});
});
it('should have "noindex" for robots if bootstrapping fails', function() {
browser.get('build/docs/index.html#!/api').catch(function() {
// get() will fail on AngularJS bootstrap, but if we continue here, protractor
// will assume the app is ready
browser.ignoreSynchronization = true;
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
expect(robots.isPresent()).toBe(true);
expect(googleBot.isPresent()).toBe(true);
});
});
});
});
+130
View File
@@ -0,0 +1,130 @@
'use strict';
/**
* This scenario checks the presence of the table of contents for a sample of pages - API and guide.
* The expectations are kept vague so that they can be easily adjusted when the docs change.
*/
describe('table of contents', function() {
it('on provider pages', function() {
browser.get('build/docs/index.html#!/api/ng/provider/$controllerProvider');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Methods');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(2);
expect(match[1].all(by.css('li')).count()).toBe(2);
});
});
it('on service pages', function() {
browser.get('build/docs/index.html#!/api/ng/service/$controller');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Usage');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(3);
expect(match[2].all(by.css('li')).count()).toBe(2);
});
});
it('on directive pages', function() {
browser.get('build/docs/index.html#!/api/ng/directive/input');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Usage');
expect(text.join('')).toContain('Directive Info');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(4);
expect(match[2].all(by.css('li')).count()).toBe(1);
});
});
it('on function pages', function() {
browser.get('build/docs/index.html#!/api/ng/function/angular.bind');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Usage');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(2);
expect(match[1].all(by.css('li')).count()).toBe(2);
});
});
it('on type pages', function() {
browser.get('build/docs/index.html#!/api/ng/type/ModelOptions');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Methods');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(2);
expect(match[1].all(by.css('li')).count()).toBe(2);
});
});
it('on filter pages', function() {
browser.get('build/docs/index.html#!/api/ng/filter/date');
var toc = element.all(by.css('toc-container > div > toc-tree'));
toc.getText().then(function(text) {
expect(text.join('')).toContain('Overview');
expect(text.join('')).toContain('Usage');
});
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(3);
expect(match[1].all(by.css('li')).count()).toBe(2);
});
});
it('on guide pages', function() {
browser.get('build/docs/index.html#!/guide/services');
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
tocFirstLevel.then(function(match) {
expect(match.length).toBe(5);
expect(match[1].all(by.css('li')).count()).toBe(3);
});
});
});
+135 -2
View File
@@ -1,7 +1,8 @@
'use strict';
angular.module('directives', [])
var directivesModule = angular.module('directives', []);
directivesModule
/**
* backToTop Directive
* @param {Function} $anchorScroll
@@ -47,4 +48,136 @@ angular.module('directives', [])
}
}
};
});
})
.directive('tocCollector', ['$rootScope', function($rootScope) {
return {
controller: ['$element', function($element) {
/* eslint-disable no-invalid-this */
var ctrl = this;
$rootScope.$on('$includeContentRequested', function() {
ctrl.hs = [];
ctrl.root = [];
});
this.hs = [];
this.root = [];
this.element = $element;
this.register = function(h) {
var previousLevel;
for (var i = ctrl.hs.length - 1; i >= 0; i--) {
if (ctrl.hs[i].level === (h.level - 1)) {
previousLevel = ctrl.hs[i];
break;
}
}
if (previousLevel) {
previousLevel.children.push(h);
} else {
this.root.push(h);
}
ctrl.hs.push(h);
/* eslint-enable no-invalid-this */
};
}]
};
}])
.component('tocTree', {
template: '<ul>' +
'<li ng-repeat="item in $ctrl.items">' +
'<a ng-href="{{ $ctrl.path }}#{{item.fragment}}">{{item.title}}</a>' +
'<toc-tree ng-if="::item.children.length > 0" items="item.children"></toc-tree>' +
'</li>' +
'</ul>',
bindings: {
items: '<'
},
controller: ['$location', /** @this */ function($location) {
this.path = $location.path().replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
}]
})
.directive('tocContainer', function() {
return {
scope: true,
restrict: 'E',
require: {
tocContainer: '',
tocCollector: '^^'
},
controller: function() {
this.showToc = true;
this.items = [];
},
controllerAs: '$ctrl',
link: function(scope, element, attrs, ctrls) {
ctrls.tocContainer.items = ctrls.tocCollector.root;
},
template: '<div ng-if="::$ctrl.items.length > 1">' +
'<b>Contents</b>' +
'<button class="btn" ng-click="$ctrl.showToc = !$ctrl.showToc">{{$ctrl.showToc ? \'Hide\' : \'Show\'}}</button><br>' +
'<toc-tree items="$ctrl.items" ng-show="$ctrl.showToc"></toc-tree>' +
'</div>'
};
})
.directive('header', function() {
return {
restrict: 'E',
controller: ['$element', function($element) {
// eslint-disable-next-line no-invalid-this
this.element = $element;
}]
};
})
.directive('h1', ['$compile', function($compile) {
return {
restrict: 'E',
require: {
tocCollector: '^^?',
header: '^^?'
},
link: function(scope, element, attrs, ctrls) {
if (!ctrls.tocCollector) return;
var tocContainer = angular.element('<toc-container></toc-container>');
var containerElement = ctrls.header ? ctrls.header.element : element;
containerElement.after(tocContainer);
$compile(tocContainer)(scope);
}
};
}]);
for (var i = 2; i <= 5; i++) {
registerHDirective(i);
}
function registerHDirective(i) {
directivesModule.directive('h' + i, function() {
return {
restrict: 'E',
require: {
'tocCollector': '^^?'
},
link: function(scope, element, attrs, ctrls) {
var toc = ctrls.tocCollector;
if (!toc || !attrs.id) return;
toc.register({
level: i,
fragment: attrs.id,
title: element.text(),
children: []
});
}
};
});
}
+11 -5
View File
@@ -8,6 +8,8 @@ angular.module('DocsController', ['currentVersionData'])
function($scope, $rootScope, $location, $window, $cookies,
NG_PAGES, NG_NAVIGATION, CURRENT_NG_VERSION) {
var errorPartialPath = 'Error404.html';
$scope.navClass = function(navItem) {
return {
active: navItem.href && this.currentPage && this.currentPage.path,
@@ -16,8 +18,6 @@ angular.module('DocsController', ['currentVersionData'])
};
};
$scope.$on('$includeContentLoaded', function() {
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
$window._gaq.push(['_trackPageview', pagePath]);
@@ -26,6 +26,7 @@ angular.module('DocsController', ['currentVersionData'])
$scope.$on('$includeContentError', function() {
$scope.loading = false;
$scope.loadingError = true;
});
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
@@ -35,6 +36,7 @@ angular.module('DocsController', ['currentVersionData'])
var currentPage = $scope.currentPage = NG_PAGES[path];
$scope.loading = true;
$scope.loadingError = false;
if (currentPage) {
$scope.partialPath = 'partials/' + path + '.html';
@@ -50,18 +52,22 @@ angular.module('DocsController', ['currentVersionData'])
} else {
$scope.currentArea = NG_NAVIGATION['api'];
$scope.breadcrumb = [];
$scope.partialPath = 'Error404.html';
$scope.partialPath = errorPartialPath;
}
});
$scope.hasError = function() {
return $scope.partialPath === errorPartialPath || $scope.loadingError;
};
/**********************************
Initialize
***********************************/
$scope.versionNumber = CURRENT_NG_VERSION.full;
$scope.version = CURRENT_NG_VERSION.full + ' ' + CURRENT_NG_VERSION.codeName;
$scope.loading = 0;
$scope.loading = false;
$scope.loadingError = false;
var INDEX_PATH = /^(\/|\/index[^.]*.html)$/;
if (!$location.path() || INDEX_PATH.test($location.path())) {
+5 -4
View File
@@ -159,10 +159,11 @@ angular.module('examples', [])
};
// Initialize the example data, so it's ready when clicking the open button.
// Otherwise pop-up blockers will prevent a new window from opening
ctrl.prepareExampleData(ctrl.example.path);
ctrl.$onInit = function() {
// Initialize the example data, so it's ready when clicking the open button.
// Otherwise pop-up blockers will prevent a new window from opening
ctrl.prepareExampleData(ctrl.example.path);
};
}]
};
}])
+6
View File
@@ -67,6 +67,12 @@ angular.module('search', [])
clearResults();
$scope.q = '';
};
$scope.handleResultClicked = function($event) {
if ($event.which === 1 && !$event.ctrlKey && !$event.metaKey) {
$scope.hideResults();
}
};
}])
+8 -2
View File
@@ -12,10 +12,16 @@ angular.module('versions', ['currentVersionData', 'allVersionsData'])
/** @this VersionPickerController */
function VersionPickerController($location, $window, CURRENT_NG_VERSION, ALL_NG_VERSIONS) {
var versionStr = CURRENT_NG_VERSION.isSnapshot ? 'snapshot' : CURRENT_NG_VERSION.version;
var versionStr = CURRENT_NG_VERSION.version;
if (CURRENT_NG_VERSION.isSnapshot) {
versionStr = CURRENT_NG_VERSION.distTag === 'latest' ? 'snapshot-stable' : 'snapshot';
}
this.versions = ALL_NG_VERSIONS;
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) { return value.version.version === versionStr; });
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) {
return value.version.version === versionStr;
});
this.jumpToDocsVersion = function(value) {
var currentPagePath = $location.path().replace(/\/$/, '');
+32 -22
View File
@@ -1,40 +1,50 @@
'use strict';
describe('code', function() {
var prettyPrintOne, oldPP;
describe('directives', function() {
var compile, scope;
var any = jasmine.any;
beforeEach(module('directives'));
beforeEach(inject(function($rootScope, $compile) {
// Provide stub for pretty print function
oldPP = window.prettyPrintOne;
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
beforeEach(module(function($compileProvider) {
$compileProvider.debugInfoEnabled(false);
}));
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope.$new();
compile = $compile;
}));
afterEach(function() {
window.prettyPrintOne = oldPP;
});
describe('code', function() {
var prettyPrintOne, oldPP;
var any = jasmine.any;
beforeEach(function() {
// Provide stub for pretty print function
oldPP = window.prettyPrintOne;
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
});
afterEach(function() {
window.prettyPrintOne = oldPP;
});
it('should pretty print innerHTML', function() {
compile('<code>var x;</code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
it('should pretty print innerHTML', function() {
compile('<code>var x;</code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
});
it('should allow language declaration', function() {
compile('<code class="lang-javascript"></code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
});
it('supports allow line numbers', function() {
compile('<code class="linenum"></code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
});
});
it('should allow language declaration', function() {
compile('<code class="lang-javascript"></code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
});
it('supports allow line numbers', function() {
compile('<code class="linenum"></code>')(scope);
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
});
});
-10
View File
@@ -1,10 +0,0 @@
{
"name": "AngularJS-docs-app",
"dependencies": {
"jquery": "2.2.3",
"lunr.js": "0.5.12",
"open-sans-fontface": "1.0.4",
"google-code-prettify": "1.0.1",
"bootstrap": "3.1.1"
}
}
+6 -1
View File
@@ -22,6 +22,7 @@ module.exports = new Package('angularjs', [
.factory(require('./services/deployments/debug'))
.factory(require('./services/deployments/default'))
.factory(require('./services/deployments/jquery'))
.factory(require('./services/deployments/test'))
.factory(require('./services/deployments/production'))
.factory(require('./inline-tag-defs/type'))
@@ -31,6 +32,7 @@ module.exports = new Package('angularjs', [
.processor(require('./processors/keywords'))
.processor(require('./processors/pages-data'))
.processor(require('./processors/versions-data'))
.processor(require('./processors/sitemap'))
.config(function(dgeni, log, readFilesProcessor, writeFilesProcessor) {
@@ -146,6 +148,7 @@ module.exports = new Package('angularjs', [
.config(function(checkAnchorLinksProcessor) {
checkAnchorLinksProcessor.base = '/';
checkAnchorLinksProcessor.errorOnUnmatchedLinks = true;
// We are only interested in docs that have an area (i.e. they are pages)
checkAnchorLinksProcessor.checkDoc = function(doc) { return doc.area; };
})
@@ -156,12 +159,14 @@ module.exports = new Package('angularjs', [
generateProtractorTestsProcessor,
generateExamplesProcessor,
debugDeployment, defaultDeployment,
jqueryDeployment, productionDeployment) {
jqueryDeployment, testDeployment,
productionDeployment) {
generateIndexPagesProcessor.deployments = [
debugDeployment,
defaultDeployment,
jqueryDeployment,
testDeployment,
productionDeployment
];
+23 -1
View File
@@ -5,18 +5,36 @@
* @description
* Process "error" docType docs and generate errorNamespace docs
*/
module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
module.exports = function errorDocsProcessor(log, errorNamespaceMap, getMinerrInfo) {
return {
$runAfter: ['tags-extracted'],
$runBefore: ['extra-docs-added'],
$process: function(docs) {
// Get the extracted min errors to compare with the error docs, and report any mismatch
var collectedErrors = require('../../../build/errors.json').errors;
var flatErrors = [];
for (var namespace in collectedErrors) {
for (var error in collectedErrors[namespace]) {
flatErrors.push(namespace + ':' + error);
}
}
// Create error namespace docs and attach error docs to each
docs.forEach(function(doc) {
var parts, namespaceDoc;
if (doc.docType === 'error') {
var matchingMinErr = flatErrors.indexOf(doc.name);
if (matchingMinErr === -1) {
log.warn('Error doc: ' + doc.name + ' has no matching min error');
} else {
flatErrors.splice(matchingMinErr, 1);
}
// Parse out the error info from the id
parts = doc.name.split(':');
doc.namespace = parts[0];
@@ -41,6 +59,10 @@ module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
}
});
flatErrors.forEach(function(value) {
log.warn('No error doc exists for min error: ' + value);
});
errorNamespaceMap.forEach(function(errorNamespace) {
docs.push(errorNamespace);
});
+25
View File
@@ -0,0 +1,25 @@
'use strict';
var exclusionRegex = /^index|examples\/|ptore2e\//;
module.exports = function createSitemap() {
return {
$runAfter: ['paths-computed'],
$runBefore: ['rendering-docs'],
$process: function(docs) {
docs.push({
id: 'sitemap.xml',
path: 'sitemap.xml',
outputPath: '../sitemap.xml',
template: 'sitemap.template.xml',
urls: docs.filter(function(doc) {
return doc.path &&
doc.outputPath &&
!exclusionRegex.test(doc.outputPath);
}).map(function(doc) {
return doc.path;
})
});
}
};
};
+40 -1
View File
@@ -47,6 +47,14 @@ module.exports = function generateVersionDocProcessor(gitData) {
var latestMap = {};
// When the docs are built on a tagged commit, yarn info won't include the latest release,
// so we add it manually based on the local version.json file.
var missesCurrentVersion = !currentVersion.isSnapshot && !versions.find(function(version) {
return version === currentVersion.version;
});
if (missesCurrentVersion) versions.push(currentVersion.version);
versions = versions
.filter(function(versionStr) {
return blacklist.indexOf(versionStr) === -1;
@@ -70,10 +78,28 @@ module.exports = function generateVersionDocProcessor(gitData) {
})
.reverse();
// List the latest version for each branch
var latest = sortObject(latestMap, reverse(semver.compare))
.map(function(version) { return makeOption(version, 'Latest'); });
return [makeOption({version: 'snapshot'}, 'Latest', 'master')]
// Get the stable release with the highest version
var highestStableRelease = versions.find(semverIsStable);
// Generate master and stable snapshots
var snapshots = [
makeOption(
{version: 'snapshot'},
'Latest',
'master-snapshot'
),
makeOption(
{version: 'snapshot-stable'},
'Latest',
createSnapshotStableLabel(highestStableRelease)
)
];
return snapshots
.concat(latest)
.concat(versions);
}
@@ -103,6 +129,19 @@ module.exports = function generateVersionDocProcessor(gitData) {
function sortObject(obj, cmp) {
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
}
// Adapted from
// https://github.com/kaelzhang/node-semver-stable/blob/34dd29842409295d49889d45871bec55a992b7f6/index.js#L25
function semverIsStable(version) {
var semverObj = version.version;
return semverObj === null ? false : !semverObj.prerelease.length;
}
function createSnapshotStableLabel(version) {
var label = version.label.replace(/.$/, 'x') + '-snapshot';
return label;
}
}
};
};
+3 -3
View File
@@ -17,9 +17,9 @@ module.exports = function debugDeployment(getVersion) {
'../angular-sanitize.js',
'../angular-touch.js',
'../angular-animate.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'components/marked-' + getVersion('marked') + '/lib/marked.js',
'js/angular-bootstrap/dropdown-toggle.js',
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.js',
'components/lunr-' + getVersion('lunr') + '/lunr.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/current-version-data.js',
@@ -30,8 +30,8 @@ module.exports = function debugDeployment(getVersion) {
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
'css/prettify-theme.css',
'css/angular-topnav.css',
'css/docs.css',
'css/animations.css'
]
+3 -3
View File
@@ -17,9 +17,9 @@ module.exports = function defaultDeployment(getVersion) {
'../angular-sanitize.min.js',
'../angular-touch.min.js',
'../angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'components/marked-' + getVersion('marked') + '/marked.min.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/lunr-' + getVersion('lunr') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/current-version-data.js',
@@ -30,8 +30,8 @@ module.exports = function defaultDeployment(getVersion) {
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
'css/prettify-theme.css',
'css/angular-topnav.css',
'css/docs.css',
'css/animations.css'
]
+3 -3
View File
@@ -21,9 +21,9 @@ module.exports = function jqueryDeployment(getVersion) {
'../angular-sanitize.min.js',
'../angular-touch.min.js',
'../angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'components/marked-' + getVersion('marked') + '/lib/marked.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/lunr-' + getVersion('lunr') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/current-version-data.js',
@@ -34,8 +34,8 @@ module.exports = function jqueryDeployment(getVersion) {
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
'css/prettify-theme.css',
'css/angular-topnav.css',
'css/docs.css',
'css/animations.css'
]
+15 -14
View File
@@ -7,24 +7,25 @@ var angularCodeUrl = '//code.angularjs.org/';
var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;
// The plnkr examples must use the code.angularjs.org repo for the snapshot,
// and the cdn for the tagged version and, if the build is not tagged, the currentVersion.
//
// The currentVersion may not be available on the cdn (e.g. if built locally, or hasn't been pushed
// yet). This will lead to a 404, but this is preferable to loading a version with which the example
// might not work (possibly in subtle ways).
var examplesCdnUrl = versionInfo.currentVersion.isSnapshot ?
(angularCodeUrl + 'snapshot') :
(googleCdnUrl + (versionInfo.currentVersion.version || versionInfo.currentVersion));
// The "examplesDependencyPath" here applies to the examples when they are opened in plnkr.co.
// The embedded examples instead always include the files from the *default* deployment,
// to ensure that the source files are always available.
// The plnkr examples must always use the code.angularjs.org source files.
// We cannot rely on the CDN files here, because they are not deployed by the time
// docs.angularjs.org and code.angularjs.org need them.
var versionPath = versionInfo.currentVersion.isSnapshot ?
'snapshot' :
versionInfo.currentVersion.version;
var examplesDependencyPath = angularCodeUrl + versionPath + '/';
module.exports = function productionDeployment(getVersion) {
return {
name: 'production',
examples: {
commonFiles: {
scripts: [examplesCdnUrl + '/angular.min.js']
scripts: [examplesDependencyPath + 'angular.min.js']
},
dependencyPath: examplesCdnUrl + '/'
dependencyPath: examplesDependencyPath
},
scripts: [
cdnUrl + '/angular.min.js',
@@ -34,9 +35,9 @@ module.exports = function productionDeployment(getVersion) {
cdnUrl + '/angular-sanitize.min.js',
cdnUrl + '/angular-touch.min.js',
cdnUrl + '/angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'components/marked-' + getVersion('marked') + '/marked.min.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/lunr-' + getVersion('lunr') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/current-version-data.js',
@@ -47,8 +48,8 @@ module.exports = function productionDeployment(getVersion) {
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
'css/prettify-theme.css',
'css/angular-topnav.css',
'css/docs.css',
'css/animations.css'
]
+40
View File
@@ -0,0 +1,40 @@
'use strict';
module.exports = function testDeployment(getVersion) {
return {
name: 'test',
examples: {
commonFiles: {
scripts: ['../../../angular.js']
},
dependencyPath: '../../../'
},
scripts: [
'../angular.js',
'../angular-resource.js',
'../angular-route.js',
'../angular-cookies.js',
'../angular-mocks.js',
'../angular-sanitize.js',
'../angular-touch.js',
'../angular-animate.js',
'components/marked-' + getVersion('marked') + '/lib/marked.js',
'js/angular-bootstrap/dropdown-toggle.js',
'components/lunr-' + getVersion('lunr') + '/lunr.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/current-version-data.js',
'js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.js'
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
'css/prettify-theme.css',
'css/angular-topnav.css',
'css/docs.css',
'css/animations.css'
]
};
};
+5 -6
View File
@@ -4,14 +4,13 @@ var path = require('canonical-path');
/**
* dgService getVersion
* @description
* Find the current version of the bower component (or node module)
* Find the current version of the node module
*/
module.exports = function getVersion(readFilesProcessor) {
var basePath = readFilesProcessor.basePath;
var sourceFolder = path.resolve(readFilesProcessor.basePath, 'node_modules');
var packageFile = 'package.json';
return function(component, sourceFolder, packageFile) {
sourceFolder = path.resolve(basePath, sourceFolder || 'docs/bower_components');
packageFile = packageFile || 'bower.json';
return require(path.join(sourceFolder,component,packageFile)).version;
return function(component) {
return require(path.join(sourceFolder, component, packageFile)).version;
};
};
@@ -9,7 +9,7 @@
<pre class="minerr-errmsg" error-display="{$ doc.formattedErrorMessage $}">{$ doc.formattedErrorMessage $}</pre>
</div>
<h2>Description</h2>
<h2 id="description">Description</h2>
<div class="description">
{$ doc.description | marked $}
</div>
+102 -94
View File
@@ -11,6 +11,18 @@
<meta name="fragment" content="!">
<title ng-bind-template="AngularJS: {{ currentArea.name }}: {{ currentPage.name || 'Error: Page not found'}}">AngularJS</title>
<script type="text/javascript">
(function() {
// Dynamically, pre-emptively, add `noindex`, which will be removed when the doc is ready and valid
['googlebot', 'robots'].forEach(function(bot) {
var tag = document.createElement('meta');
tag.name = bot;
tag.content = 'noindex';
tag.setAttribute('ng-if', 'hasError()');
document.head.appendChild(tag);
});
})();
</script>
<script type="text/javascript">
// dynamically add base tag as well as css and javascript files.
// we can't add css/js the usual way, because some browsers (FF) eagerly prefetch resources
@@ -68,101 +80,96 @@
})();
</script>
</head>
<body>
<body class="homepage">
<div id="wrapper">
<header scroll-y-offset-element class="header header-fixed">
<section class="navbar navbar-inverse docs-navbar-primary" ng-controller="DocsSearchCtrl">
<div class="container">
<div class="row">
<div class="col-md-9 header-branding">
<a class="brand navbar-brand" href="http://angularjs.org">
<img width="117" height="30" class="logo" alt="Link to Angular JS Homepage" ng-src="img/angularjs-for-header-only.svg">
</a>
<ul class="nav navbar-nav">
<li class="divider-vertical"></li>
<li><a href="http://angularjs.org"><i class="icon-home icon-white"></i> Home</a></li>
<li class="divider-vertical"></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="icon-eye-open icon-white"></i> Learn <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<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="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>
</li>
<li class="divider-vertical"></li>
<li class="dropdown active">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="icon-book icon-white"></i> Develop <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="tutorial">Tutorial</a></li>
<li><a href="guide">Developer Guide</a></li>
<li><a href="api">API Reference</a></li>
<li><a href="error">Error Reference</a></li>
<li><a href="misc/contribute">Contribute</a></li>
<li><a href="http://code.angularjs.org/">Download</a></li>
</ul>
</li>
<li class="divider-vertical"></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="icon-comment icon-white"></i> Discuss <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="http://blog.angularjs.org">Blog</a></li>
<li><a href="http://groups.google.com/group/angular">Mailing List</a></li>
<li><a href="http://webchat.freenode.net/?channels=angularjs&uio=d4">Chat Room</a></li>
<li class="divider"></li>
<li><a href="https://twitter.com/#!/angularjs">Twitter</a></li>
<li><a href="https://plus.google.com/110323587230527980117">Google+</a></li>
<li class="divider"></li>
<li><a href="https://github.com/angular/angular.js">GitHub</a></li>
<li><a href="https://github.com/angular/angular.js/issues">Issue Tracker</a></li>
</ul>
</li>
<li class="divider-vertical"></li>
</ul>
</div>
<form ng-class="{focus:focus}" class="navbar-search col-md-3 docs-search" ng-submit="submit()">
<span class="glyphicon glyphicon-search search-icon"></span>
<input type="text"
name="as_q"
class="search-query"
placeholder="Click or press / to search"
ng-focus="focus=true"
ng-blur="focus=false"
ng-change="search(q)"
ng-model="q"
docs-search-input
autocomplete="off" />
</form>
</div>
</div>
<div class="search-results-container" ng-show="hasResults">
<header class="header">
<nav id="navbar-main" class="navbar navbar-fixed-top">
<div class="navbar-inner" ng-controller="DocsSearchCtrl">
<div class="container">
<div class="search-results-frame">
<div ng-repeat="(key, value) in results track by key" class="search-results-group" ng-class="colClassName + ' col-group-' + key" ng-show="value.length > 0">
<h4 class="search-results-group-heading">{{ key }}</h4>
<ul class="search-results">
<!-- Do not insert a line break between li and a. Chrome will insert an actual line-break, which breaks the list item view.
TODO: use a html minifier instead -->
<li ng-repeat="item in value" class="search-result"><a ng-click="hideResults()" ng-href="{{ item.path }}">{{ item.name }}</a></li>
<h1 class="brand"><a href="http://angularjs.org"><img width="117" height="30" src="img/angularjs-for-header-only.svg" alt="AngularJS"></a></h1>
<form class="navbar-search" ng-submit="submit()">
<i class="glyphicon glyphicon-search search-icon"></i>
<input type="text" name="as_q" class="search-query" placeholder="SEARCH"
ng-focus="focus=true"
ng-blur="focus=false"
ng-change="search(q)"
ng-model="q"
ng-model-options="{debounce: 150}"
docs-search-input
autocomplete="off">
</form>
<ul class="nav navbar-nav">
<li class="dropdown" uib-dropdown>
<a href="#" class="dropdown-toggle" uib-dropdown-toggle>Learn</a>
<ul class="dropdown-menu" uib-dropdown-menu>
<li><a href="tutorial">Tutorial</a></li>
<li><a href="misc/faq">FAQ</a></li>
<li><a href="https://www.youtube.com/user/angularjs">Videos</a></li>
<li><a href="http://angular.codeschool.com/">Free Course</a></li>
<li><a href="https://www.madewithangular.com/">Case Studies</a></li>
</ul>
</li>
<li class="dropdown" uib-dropdown>
<a href="#" class="dropdown-toggle" uib-dropdown-toggle>Develop</a>
<ul class="dropdown-menu" uib-dropdown-menu>
<li><a href="guide">Developer Guide</a></li>
<li><a href="api">API Reference</a></li>
<li><a href="error">Error Reference</a></li>
<li><a href="misc/contribute">Contribute</a></li>
<li><a href="https://github.com/angular/angular-seed">Seed App project template</a></li>
<li><a href="https://github.com/angular/angular.js">GitHub</a></li>
<li><a href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md">Changelog</a></li>
<li><a href="http://code.angularjs.org/">Download</a></li>
</ul>
</li>
<li class="dropdown" uib-dropdown>
<a href="#" class="dropdown-toggle" uib-dropdown-toggle>Discuss</a>
<ul class="dropdown-menu" uib-dropdown-menu>
<li><a href="http://blog.angularjs.org">Blog</a></li>
<li><a href="https://twitter.com/angular">Twitter</a></li>
<li><a href="https://plus.google.com/110323587230527980117">Google+</a></li>
<li><a href="https://github.com/angular/angular.js/issues">Feature &amp; Bug Tracker</a></li>
<li><a href="http://groups.google.com/group/angular">Mailing List</a></li>
<li><a href="http://webchat.freenode.net/?channels=angularjs&uio=d4">IRC</a></li>
<li><a href="https://gitter.im/angular/angular.js">Gitter</a></li>
</ul>
</li>
</ul>
</div>
<div class="search-results-container" ng-show="hasResults" ng-cloak>
<div class="container">
<div class="search-results-frame">
<div ng-repeat="(key, value) in results track by key" class="search-results-group" ng-class="colClassName + ' col-group-' + key" ng-show="value.length > 0">
<h4 class="search-results-group-heading">{{ key }}</h4>
<ul class="search-results">
<li ng-repeat="item in value" class="search-result"><a ng-click="handleResultClicked($event)" ng-href="{{ item.path }}">{{ item.name }}</a></li>
</ul>
</div>
</div>
<a href="" ng-click="hideResults()" class="search-close">
<span class="glyphicon glyphicon-remove search-close-icon"></span> Close
</a>
</div>
<a href="" ng-click="hideResults()" class="search-close">
<span class="glyphicon glyphicon-remove search-close-icon"></span> Close
</a>
</div>
</div>
</section>
<section class="sup-header">
</nav>
<nav id="navbar-notice" class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<p class="site-notice visible-phone">
This site refers to AngularJS (v1.x). <a href="https://angular.io/">Go to the latest Angular</a>.
</p>
<p class="site-notice visible-desktop">
This site and all of its contents are referring to AngularJS (version 1.x),
if you are looking for the latest Angular, please visit <a href="https://angular.io/">angular.io</a>.
</p>
</div>
</div>
</nav>
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element ng-cloak>
<div class="container main-grid main-header-grid">
<div class="grid-left">
<version-picker></version-picker>
@@ -176,10 +183,10 @@
</ul>
</div>
</div>
</section>
</nav>
</header>
<section role="main" class="container main-body">
<section role="main" class="container main-body" ng-cloak>
<div class="main-grid main-body-grid">
<div class="grid-left">
<a class="btn toc-toggle visible-xs" ng-click="toc=!toc">Show / Hide Table of Contents</a>
@@ -203,8 +210,9 @@
</div>
</div>
<div class="grid-right">
<div id="loading" ng-show="loading">Loading...</div>
<div ng-hide="loading" ng-include="partialPath" autoscroll></div>
<div ng-show="loading">Loading &hellip;</div>
<div ng-show="loadingError">There was an error loading this resource. Please try again later.</div>
<div ng-hide="loading" ng-include="partialPath" toc-collector autoscroll></div>
</div>
</div>
</section>
@@ -214,10 +222,10 @@
<p class="pull-right"><a back-to-top>Back to top</a></p>
<p>
Super-powered by Google ©2010-2016
Super-powered by Google ©2010-2018
(<a id="version"
ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
ng-bind-template="v{{version}}" title="Changelog of this version of Angular JS">
ng-bind-template="v{{version}}" title="Changelog of this version of AngularJS">
</a>)
</p>
<p>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{%- for url in doc.urls %}
<url>
<loc>https://docs.angularjs.org/{$ url $}</loc>
</url>{% endfor %}
</urlset>
@@ -23,6 +23,7 @@
{% block description %}
<div class="api-profile-description">
<h2 id="overview">Overview</h2>
{$ doc.description | marked $}
</div>
{% endblock %}
@@ -51,7 +52,7 @@
{% block examples %}
{%- if doc.examples %}
<h2 id="example">Examples</h2>
<h2 id="examples">{$ "Examples" if doc.examples | length > 1 else "Example" $}</h2>
{%- for example in doc.examples -%}
{$ example | marked $}
{%- endfor -%}
@@ -2,7 +2,7 @@
{% extends "api/api.template.html" %}
{% block additional %}
<h2>Directive Info</h2>
<h2 id="{$ doc.name $}-info">Directive Info</h2>
<ul>
{% if doc.scope %}<li>This directive creates new scope.</li>{% endif %}
<li>This directive executes at priority level {$ doc.priority $}.</li>
@@ -18,9 +18,6 @@
<ul>
{% if doc.restrict.element %}
<li>as element:
{% if doc.name.indexOf('ng') == 0 -%}
(This directive can be used as custom element, but be aware of <a href="guide/ie">IE restrictions</a>).
{%- endif %}
{% code %}
<{$ doc.name | dashCase $}
{%- for param in doc.params %}
@@ -32,10 +29,23 @@
</li>
{% endif -%}
{% set hasNameAsParam = false %}
{# when a directive's name is not a parameter (i.e. doesn't take a value),
add the directive name to the list of attributes and/or css classes #}
{%- for param in doc.params %}
{% set hasNameAsParam = true if param.name === doc.name else hasNameAsParam %}
{%- endfor %}
{%- if doc.restrict.attribute -%}
<li>as attribute:
{% code %}
<{$ doc.element $}
{%- if not hasNameAsParam %}
{$ lib.directiveParam(doc.name, {}, '', '') $}
{%- endif -%}
{%- for param in doc.params %}
{$ lib.directiveParam(param.name, param.type, '="', '"') $}
{%- endfor %}>
@@ -46,10 +56,14 @@
{% endif -%}
{%- if doc.restrict.cssClass -%}
<li>as CSS class:
{% code %}
{% set sep = joiner(' ') %}
<{$ doc.element $} class="
{%- if not hasNameAsParam -%}
{$ sep() $}{$ lib.directiveParam(doc.name, {}, '', '') $}
{%- endif -%}
{%- for param in doc.params -%}
{$ sep() $}{$ lib.directiveParam(param.name, param.type, ': ', ';') $}
{%- endfor %}"> ... </{$ doc.element $}>
@@ -61,12 +75,12 @@
</div>
{% endblock -%}
{% include "lib/params.template.html" %}
{% include "lib/events.template.html" %}
{%- if doc.animations %}
<h2 id="animations">Animations</h2>
{$ doc.animations | marked $}
{$ 'module:ngAnimate.$animate' | link('Click here', doc) $} to learn more about the steps involved in the animation.
{%- endif -%}
{% include "lib/params.template.html" %}
{% include "lib/events.template.html" %}
{% endblock %}
@@ -2,7 +2,7 @@
{% extends "api/api.template.html" %}
{% block additional %}
<h2>Usage</h2>
<h2 id="usage">Usage</h2>
<h3>In HTML Template Binding</h3>
{% if doc.usage %}
{$ doc.usage | code $}
@@ -8,7 +8,7 @@
{$ x.deprecatedBlock(doc) $}
<h2>Installation</h2>
<h2 id="module-installation">Installation</h2>
{% if doc.installation or doc.installation == '' %}
{$ doc.installation | marked $}
{% else %}
@@ -76,7 +76,7 @@
{% if doc.componentGroups.length %}
<div class="component-breakdown">
<h2>Module Components</h2>
<h2 id="module-components">Module Components</h2>
{% for componentGroup in doc.componentGroups %}
<div>
<h3 class="component-heading" id="{$ componentGroup.groupType | dashCase $}">{$ componentGroup.groupType | title $}</h3>
@@ -98,7 +98,7 @@
{% endif %}
{% if doc.usage %}
<h2>Usage</h2>
<h2 id="module-usage">Usage</h2>
{$ doc.usage | marked $}
{% endif %}
@@ -2,11 +2,11 @@
{% import "lib/deprecated.html" as x -%}
{%- if doc.events %}
<h2>Events</h2>
<h2 id="events">Events</h2>
<ul class="events">
{%- for event in doc.events %}
<li id="{$ event.name $}">
<h3>{$ event.name $}</h3>
<h3 id="event-{$ event.name $}">{$ event.name $}</h3>
<div>{$ event.description | marked $}</div>
{$ x.deprecatedBlock(event) $}
@@ -27,7 +27,7 @@
{% endif -%}
{%- if event.params %}
<section class="api-section">
<h3>Parameters</h3>
<h4>Parameters</h4>
{$ lib.paramTable(event.params) $}
</section>
{%- endif -%}
@@ -2,11 +2,11 @@
{% import "lib/deprecated.html" as x -%}
{%- if doc.methods %}
<h2>Methods</h2>
<h2 id="{$ doc.name $}-methods">Methods</h2>
<ul class="methods">
{%- for method in doc.methods %}
<li id="{$ method.name $}">
<h3>{$ lib.functionSyntax(method) $}</h3>
<li>
<h3 id="{$ method.name $}">{$ lib.functionSyntax(method) $}</h3>
<div>{$ method.description | marked $}</div>
{$ x.deprecatedBlock(method) $}
@@ -17,7 +17,7 @@
{% endif %}
{% if method.this %}
<h4>Method's {% code %}this{% endcode %}</h4>
<h4>Method's `this`</h4>
{$ method.this | marked $}
{% endif %}
@@ -27,7 +27,7 @@
{% endif %}
{%- if method.examples %}
<h4 id="{$ doc.name $}.{$ method.name $}-examples">Examples</h4>
<h4 id="{$ doc.name $}.{$ method.name $}-examples">{$ "Examples" if method.examples | length > 1 else "Example" $}</h4>
{%- for example in method.examples -%}
{$ example | marked $}
{%- endfor -%}
@@ -1,7 +1,7 @@
{% import "lib/macros.html" as lib -%}
{%- if doc.params %}
<section class="api-section">
<h3>Arguments</h3>
<h3 id="{$ doc.name $}-arguments">Arguments</h3>
{$ lib.paramTable(doc.params) $}
</section>
{%- endif -%}
@@ -2,11 +2,11 @@
{% import "lib/deprecated.html" as x -%}
{%- if doc.properties %}
<h2>Properties</h2>
<h2 id="{$ doc.name $}-properties">Properties</h2>
<ul class="properties">
{%- for property in doc.properties %}
<li id="{$ property.name $}">
<h3>{$ property.name | code $}</h3>
<li>
<h3 id="{$ property.name $}">{$ property.name | code $}</h3>
{$ lib.typeInfo(property) $}
{$ x.deprecatedBlock(property) $}
</li>
@@ -1,5 +1,5 @@
{% import "lib/macros.html" as lib -%}
{% if doc.returns -%}
<h3>Returns</h3>
<h3 id="{$ doc.name $}-returns">Returns</h3>
{$ lib.typeInfo(doc.returns) $}
{%- endif %}
@@ -1,4 +1,4 @@
{% if doc.this %}
<h3>Method's {% code %}this{% endcode %}</h3>
<h3>Method's `this`</h3>
{$ doc.this | marked $}
{% endif %}
{% endif %}
+15 -11
View File
@@ -3,7 +3,15 @@
@description
# AngularJS API Docs
Welcome to the AngularJS API docs page. These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
<div class="alert alert-warning">
**On July 1, 2018 AngularJS entered a 3 year Long Term Support period:** [Find out more](misc/version-support-status).
</div>
## Welcome to the AngularJS API docs page.
These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
The documentation is organized into **{@link guide/module modules}** which contain various components of an AngularJS application.
These components are {@link guide/directive directives}, {@link guide/services services}, {@link guide/filter filters}, {@link guide/providers providers}, {@link guide/templates templates}, global APIs, and testing mocks.
@@ -11,14 +19,14 @@ These components are {@link guide/directive directives}, {@link guide/services s
There is also a {@link guide/index guide} with articles on various topics, and a list of external resources.
<div class="alert alert-info">
**Angular Prefixes `$` and `$$`**:
**AngularJS Prefixes `$` and `$$`**:
To prevent accidental name collisions with your code,
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
AngularJS prefixes names of public objects with `$` and names of private objects with `$$`.
Please do not use the `$` or `$$` prefix in your code.
</div>
## Angular Modules
## AngularJS Modules
## {@link ng ng (core module)}
@@ -83,7 +91,7 @@ This module is provided by default and contains the core components of AngularJS
</td>
<td>
<p>
The core global API functions are attached to the angular object. These core functions are useful for low level JavaScript operations within your application.
The core global API functions are attached to the `angular` object. These core functions are useful for low level JavaScript operations within your application.
</p>
<p>
Some examples include:
@@ -130,7 +138,7 @@ Use ngRoute to enable URL routing to your application. The ngRoute module suppor
## {@link ngAnimate ngAnimate}
Use ngAnimate to enable animation features within your application. Various core ng directives will provide
Use ngAnimate to enable animation features within your application. Various core AngularJS directives will provide
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
or JavaScript callbacks.
@@ -214,11 +222,7 @@ Use the ngCookies module to handle cookie management within your application.
{@link ngCookies#service Services / Factories}
</td>
<td>
The following services are used for cookie management:
<ul>
<li>The {@link ngCookies.$cookies $cookie} service is a convenient wrapper to store simple data within browser cookies.</li>
<li>{@link ngCookies.$cookieStore $cookieStore} is used to store more complex data using serialization.</li>
</ul>
The {@link ngCookies.$cookies $cookies} service is a convenient wrapper to store simple data within browser cookies.
</td>
</tr>
</table>
-12
View File
@@ -1,12 +0,0 @@
@ngdoc error
@name $animate:nocb
@fullName Do not pass a callback to animate methods
@description
Since Angular 1.3, the methods of {@link ng.$animate} do not accept a callback as the last parameter.
Instead, they return a promise to which you can attach `then` handlers to be run when the animation completes.
If you are getting this error then you need to update your code to use the promise-based API.
See https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9 for information about
the change to the animation API and the changes you need to make.
@@ -0,0 +1,8 @@
@ngdoc error
@name $animate:nongcls
@fullName `ng-animate` class not allowed
@description
This error occurs, when trying to set `$animateProvider.classNameFilter()` to a RegExp containing
the reserved `ng-animate` class. Since `.ng-animate` will be added/removed by `$animate` itself,
using it as part of the `classNameFilter` RegExp is not allowed.
@@ -5,7 +5,7 @@
This error occurs when the restrict property of a directive is not valid.
The directive restrict property must be a string including one of more of the following characters:
The directive restrict property must be a string including one or more of the following characters:
* E (element)
* A (attribute)
* C (class)
@@ -15,4 +15,4 @@ For example:
```javascript
restrict: 'E'
restrict: 'EAC'
```
```
@@ -0,0 +1,13 @@
@ngdoc error
@name $compile:ctxoverride
@fullName DOM Property Security Context Override
@description
This error occurs when the security context for a property is defined via {@link ng.$compileProvider#addPropertySecurityContext addPropertySecurityContext()} multiple times under different security contexts.
For example:
```js
$compileProvider.addPropertySecurityContext("my-element", "src", $sce.MEDIA_URL);
$compileProvider.addPropertySecurityContext("my-element", "src", $sce.RESOURCE_URL); //throws
```
+1 -1
View File
@@ -5,7 +5,7 @@
This error occurs when the application's model becomes unstable because some `$onChanges` hooks are causing updates which then trigger
further calls to `$onChanges` that can never complete.
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
For example, the situation can occur by setting up a `$onChanges()` hook which triggers an event on the component, which subsequently
triggers the component's bound inputs to be updated:
+9 -7
View File
@@ -10,13 +10,15 @@ myModule.directive('directiveName', function factory() {
return {
...
scope: {
'attrName': '@', // OK
'attrName2': '=localName', // OK
'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
'localName': '@', // OK
'localName2': '&attr', // OK
'localName3': '<?attr', // OK
'localName4': ' = attr', // OK
'localName5': ' =*attr', // OK
'localName6': 'attr', // ERROR: missing mode @&=<
'localName7': 'attr=', // ERROR: must be prefixed with @&=<
'localName8': '=attr?', // ERROR: ? must come directly after the mode
'localName9': '<*' // ERROR: * is only valid with =
}
...
}
@@ -0,0 +1,36 @@
@ngdoc error
@name $compile:missingattr
@fullName Missing required attribute
@description
This error may occur only when {@link $compileProvider#strictComponentBindingsEnabled `$compileProvider.strictComponentBindingsEnabled`} is set to `true`.
If that is the case, then all {@link $compileProvider#component component} controller bindings and
{@link $compileProvider#directive directive} scope / controller bindings that are non-optional,
must be provided when the directive is instantiated.
To make a binding optional, add '?' to the definition.
## Example:
```js
app.component('myTest', {
bindings: {
first: '=?', // optional
second: '='
},
controller: function() {
...
},
template: '...'
});
```
This component will throw `missingattr` for the `second` binding when used as follows:
```html
<my-test></my-test>
```
@@ -1,12 +1,12 @@
@ngdoc error
@name $compile:nodomevents
@fullName Interpolated Event Attributes
@fullName Event Attribute/Property Binding
@description
This error occurs when one tries to create a binding for event handler attributes like `onclick`, `onload`, `onsubmit`, etc.
This error occurs when one tries to create a binding for event handler attributes or properties like `onclick`, `onload`, `onsubmit`, etc.
There is no practical value in binding to these attributes and doing so only exposes your application to security vulnerabilities like XSS.
For these reasons binding to event handler attributes (all attributes that start with `on` and `formaction` attribute) is not supported.
There is no practical value in binding to these attributes/properties and doing so only exposes your application to security vulnerabilities like XSS.
For these reasons binding to event handler attributes and properties (`formaction` and all starting with `on`) is not supported.
An example code that would allow XSS vulnerability by evaluating user input in the window context could look like this:
@@ -17,4 +17,4 @@ An example code that would allow XSS vulnerability by evaluating user input in t
Since the `onclick` evaluates the value as JavaScript code in the window context, setting the `username` model to a value like `javascript:alert('PWND')` would result in script injection when the `div` is clicked.
Please use the `ng-*` or `ng-on-*` versions instead (such as `ng-click` or `ng-on-click` rather than `onclick`).
+38
View File
@@ -0,0 +1,38 @@
@ngdoc error
@name $compile:noslot
@fullName No matching slot in parent directive
@description
This error occurs when declaring a specific slot in a {@link ng.ngTransclude `ngTransclude`}
which does not map to a specific slot defined in the transclude property of the directive.
In this example the template has declared a slot missing from the transclude definition.
This example will generate a noslot error.
```js
var componentConfig = {
template: '<div>' +
'<div ng-transclude="slotProvided"></div>' +
'<div ng-transclude="noSlotProvided"></div>' +
'</div>',
transclude: {
// The key value pairs here are considered "slots" that are provided for components to slot into.
slotProvided: 'slottedComponent', // mandatory transclusion
// There is no slot provided here for the transclude 'noSlotProvided' declared in the above template.
}
};
```
If we make the following change we will no longer get the noslot error.
```js
var componentConfig = {
template: '<div>' +
'<div ng-transclude="slotProvided"></div>' +
'<div ng-transclude="noSlotProvided"></div>' +
'</div>',
transclude: {
slotProvided: 'slottedComponent',
noSlotProvided: 'otherComponent' // now it is declared and the error should cease
}
};
```
+12
View File
@@ -0,0 +1,12 @@
@ngdoc error
@name $compile:srcset
@fullName Invalid value passed to `attr.$set('srcset', value)`
@description
This error occurs if you try to programmatically set the `srcset` attribute with a non-string value.
This can be the case if you tried to avoid the automatic sanitization of the `srcset` value by
passing a "trusted" value provided by calls to `$sce.trustAsMediaUrl(value)`.
If you want to programmatically set explicitly trusted unsafe URLs, you should use `$sce.trustAsHtml`
on the whole `img` tag and inject it into the DOM using the `ng-bind-html` directive.
-11
View File
@@ -1,11 +0,0 @@
@ngdoc error
@name $compile:tpload
@fullName Error Loading Template
@description
This error occurs when {@link ng.$compile `$compile`} attempts to fetch a template from some URL, and the request fails.
To resolve this error, ensure that the URL of the template is spelled correctly and resolves to correct absolute URL.
The [Chrome Developer Tools](https://developers.google.com/chrome-developer-tools/docs/network#network_panel_overview) might also be helpful in determining why the request failed.
If you are using {@link ng.$templateCache} to pre-load templates, ensure that the cache was populated with the template.
+14
View File
@@ -0,0 +1,14 @@
@ngdoc error
@name $http:baddata
@fullName Bad JSON Data
@description
The default {@link ng.$http#default-transformations `transformResponse`} will try to parse the
response as JSON if the `Content-Type` header is `application/json`, or the response looks like a
valid JSON-stringified object or array.
This error occurs when that data is not a valid JSON object.
To resolve this error, make sure you pass valid JSON data to `transformResponse`. If the response
data looks like JSON, but has a different `Content-Type` header, you must
{@link ng.$http#overriding-the-default-transformations-per-request implement your own response
transformer on a per request basis}, or {@link ng.$http#default-transformations modify the default `$http` responseTransform}.
+2 -2
View File
@@ -9,9 +9,9 @@ value is `JSON_CALLBACK`.
`$http` JSONP requests need to attach a callback query parameter to the URL. The name of this
parameter is specified in the configuration object (or in the defaults) via the `jsonpCallbackParam`
property. You must not provide your own parameter with this name in the configuratio of the request.
property. You must not provide your own parameter with this name in the configuration of the request.
In previous versions of Angular, you specified where to add the callback parameter value via the
In previous versions of AngularJS, you specified where to add the callback parameter value via the
`JSON_CALLBACK` placeholder. This is no longer allowed.
To resolve this error, remove any parameters that have the same name as the `jsonpCallbackParam`;
+1 -1
View File
@@ -15,7 +15,7 @@ In AngularJS `1.2.0` and later, `ngRoute` has been moved to its own module.
If you are getting this error after upgrading to `1.2.x` or later, be sure that you've
installed {@link ngRoute `ngRoute`}.
### Monkey-patching Angular's `ng` module
### Monkey-patching AngularJS's `ng` module
This error can also occur if you have tried to add your own components to the `ng` module.
This has never been supported and from `1.3.0` it will actually trigger this error.
@@ -3,4 +3,4 @@
@fullName Expecting end operator
@description
The Angular expression is missing the corresponding closing operator.
The AngularJS expression is missing the corresponding closing operator.
@@ -8,4 +8,4 @@ extension in your interpolation expression. The different choices have to be un
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -9,4 +9,4 @@ bug mentioning the exact version of AngularJS used and we will fix it!
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -14,4 +14,4 @@ future commit and the github issue will help gauge urgency.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}

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