Previously, the `angularInit()` tests assumed that the Safari browser
uses the `safari-extension:` protocol for browser extension URLs. This
is true for versions <15. However, since v15, Safari on iOS only
recognizes the `chrome-extension:` protocol, which causes the tests to
fail ([example failure][1]).
This commit updates the tests to use the correct protocol according to
the version of Safari used.
NOTE:
On macOS, Safari v15+ recognizes both `safari-extension:` and
`chrome-extension:`, so it is OK to always use the later with Safari
v15+ (regardless of the platform).
[1]: https://circleci.com/gh/angular/angular.js/3527
Co-authored-by: George Kalpakas <kalpakas.g@gmail.com>
Closes#17166
Since version 93, Firefox started more closely following the spec on
formatting `datetime-local` input values by removing trailing zeros from
the string representation of the value. This causes some of our tests to
fail ([example failure][1]).
For example, a value is reported by Firefox as `2009-01-06T16:25` while
the tests expect `2009-01-06T16:25:00.000`. I.e. Firefox started leaving
out seconds/milliseconds if they are zero.
According to [MDN][2], this is the correct behavior according to the
spec. Indeed the spec says that [if the value of the element is a valid
local date and time string, then it must be set to a **valid normalized
local date and time string**][3], where **valid normalized local date
and time string** is [defined as consisting of][4]:
> - A valid date string representing the date.
> - A U+0054 LATIN CAPITAL LETTER T character (T).
> - A valid time string representing the time, expressed as the
> **shortest possible string** for the given time (e.g. **omitting the
> seconds component** entirely if the given time is zero seconds past
> the minute).
This commit fixes the relevant tests by explicitly specifying non-zero
values for seconds and milliseconds.
[1]: https://circleci.com/gh/angular/angular.js/3527
[2]: https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats
#local_date_and_time_strings
[3]: https://html.spec.whatwg.org/multipage/input.html
#local-date-and-time-state-(type=datetime-local)
[4]: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html
#concept-datetime-local
Co-authored-by: George Kalpakas <kalpakas.g@gmail.com>
- the subdomain was switched to a path many months ago
- the angularjs.xlts.dev site will soon be used for hosting something else
and the redirect removed (ASAP)
Closes#17136
Previously, the `deploy-code-firebase` CI job was run on any build
corresponding to a git tag, the master branch or the stable branch.
Given that all runs of `deploy-code-firebase` deploy to the same
Firebase project (and overwrites previous deployments), there is no
point in deploying from multiple branches/tags.
This commit fixes this by ensuring that we only run the
`deploy-code-firebase` job on builds for the master branch, which
contains the most up-to-date code/configuration.
In #17114, the `deploy-code` CI job was modified to also run some
commands via `yarn`. It turns out that this breaks on CI, because the
`deploy-code` job uses the `cloud-sdk` executor that does not have
`yarn` installed. ([Example failure][1])
This commit fixes this by splitting the `deploy-code` job into two jobs:
- `deploy-code-files` uses the `cloud-sdk` and uploads the files to
Google Cloud.
(This is essentially the `deploy-code` job from before #17114.)
- `deploy-code-firebase` uses the `default` executor (which has `yarn`
installed) and deploys to Firebase.
(This essentially includes the new bits added in #17114.)
[1]: https://circleci.com/gh/angular/angular.js/2712
Previously, the `sendStoredFile()` Firebase function used `.split('/')`
to split the request path into segments and later used `path.join()` to
join them back together. This worked fine on *nix based systems, which
use `/` as the path separator. On Windows, however, where `\` is the
path separator, the re-constructed paths could not be retrieved from the
Google Cloud Storage bucket. This prevented the Firebase emulators from
working correctly when testing the function locally on Windows.
This commit fixes the issue by using `.join('/')` to join the path
segments back together.
Closes#17114
This commit updates `firebase-admin`, `firebase-functions` and
`firebase-tools` to latest versions to take advantage of the most recent
fixes and improvements.
Previously, when deploying `scripts/{code,docs}.angularjs.org-firebase/`
to Firebase, we explicitly specified the target projects. Since the
project IDs are also specified in the respective `.firebaserc` files,
this was unnecessary (and meant we had multiple places to update if the
IDs changed).
This commit simplifies the process by automatically targeting the
default projects (as configured in the `.firebaserc` files) when
deploying to Firebase in CI.
Previously, we only deployed the built files to Google Cloud Storage for
the `code-angularjs-org` Firebase project. This meant that the other
Firebase services (such as functions, hosting, storage) were not updated
when we made changes to their source code or configuration.
(This isn't a problem at the moment, since the code/configuration for
these service changes infrequently, but could bite us in the future.)
This commit fixes this by ensuring that we deploy to all enabled
Firebase services (currently functions, hosting and storage).
Previously, we only deployed to Firebase hosting for the
`docs-angularjs-org` Firebase project. This meant that the deployed
functions used an old version of Node.js and started failing once
support was dropped for that version. See #17111 for details.
This commit fixes this by ensuring that we deploy to all enabled
Firebase services (currently functions and hosting).
Fixes#17111Fixesangular/angularjs.org#251
Previously, in order to deploy to Firebase from
`scripts/docs.angularjs.org-firebase/`, we had to copy the
`firebase.json` file to the repository root and adjust the contained
paths accordingly.
By running the `firebase` CLI directly (instead of via `yarn`), we are
able to deploy from `docs.angularjs.org-firebase/` directly. This
simplifies the deployment (and local testing) process and paves the way
for also deploying from `code.angularjs.org-firebase/` in a subsequent
commit.
We have the `scripts/{code,docs}.angularjs.org-firebase/` directories,
which contain the necessary code and config for deploying built files to
the `code-angularjs-org` and `docs-angularjs-org` Firebase projects
respectively.
Previously, some of the files that needed to be deployed to Firebase (or
Google Cloud) were placed outside these directories (e.g. in
`deploy/{code,docs}/`).
Since these files are only used for deploying to Firebase/Google Cloud,
this commit changes the deployment process to instead copy the files
inside the directories. In a subsequent commit, this will allow
simplifying the deployment process, by running it from inside each
directory instead of having to copy the `firebase.json` files to the
repository root (and adjust the paths).
These are the destination directory changes:
| Before | After |
|--------------|---------------------------------------------|
| deploy/code/ | scripts/code.angularjs.org-firebase/deploy/ |
| deploy/docs/ | scripts/docs.angularjs.org-firebase/deploy/ |
In commit a206e2675c, `$sceDelegateProvider`'s
`resourceUrlWhitelist()` was deprecated in favor of the new
`trustedResourceUrlList()`. However, although both properties were
assigned the same value, it was possible for an app to break if one of
the properties was overwritten in one part of the app (or a 3rd-party
library) while another part of the app interacts with the other,
non-overwritten property.
This commit fixes it by making `resourceUrlWhitelist()` a getter/setter
that delegates to `trustedResourceUrlList()`, ensuring that the two
properties will remain in sync. This, also, makes it consistent with
other similar deprecated properties, such as `$sceDelegateProvider`'s
`resourceUrlBlacklist()`.
Closes#17090
In commits 9679e58ec4e9d9e4b743..3dd42cea688a7b6f7789, some properties
and methods names including the terms whitelist/blacklist were
deprecated in favor of new ones not including the terms.
This commit fixes some typos in docs related to these changes and adds
links to the new properties/methods in the changelog for easier access.
Fixes#17088
Since #17039, our docs Firebase functions' `package.json` specifies a
`node` engine version. This is required for configuring which version of
Node.js should Firebase use to execute the functions. However, since
Firebase is using an older version of Node.js than the one we use to
build the AngularJS project, yarn would error due to incompatible
Node.js engine versions ([example failure][1]).
This commit avoids the error by running yarn with the `--ignore-engines`
option.
[1]: https://app.circleci.com/pipelines/github/angular/angular.js/214/
workflows/ad2e9baf-7249-467d-bc71-bd98e6cd922c/jobs/2247
Changes aHrefSanitizationWhitelist to aHrefSanitizationTrustedUri and imgSrcSanitizationWhitelist
to imgSrcSanitizationTrustedUri updating references to use the new symbols.
For the purposes of backward compatibility, the previous symbols are aliased to
the new symbols.
Changes xsrfWhitelistedOrigins to xsrfTrustedOrigins updating references to use
this new symbol.
For the purposes of backward compatibility, the previous symbol is aliased to
the new symbol.
Changes resourceUrlWhitelist to trustedResourceUrlList and resourceUrlBlacklist
to bannedResourceUrlList, updating references to use this new symbol.
For the purposes of backward compatibility, the previous symbols are aliased to
their new symbol.
Previously, the `DIST_TAG` environment variable was failing to be
computed correctly in the `deploy-code` CI job, because it relied on the
non-existent `node` executable. It worked with the default executor
(which includes `node`), but not with the `cloud-sdk` executor used in
`deploy-code`, resulting in the following error:
```sh
./.circleci/env.sh: line 59: node: command not found
DIST_TAG=
```
You can see an example failure in the "Set up environment" step logs in
https://app.circleci.com/pipelines/github/angular/angular.js/
170/workflows/32fcacf9-c89b-4020-b3eb-15debe18bb67/jobs/1793
This commit fixes it by computing `$DIST_TAG` using unix tools (`cat`,
`grep`, `sed`) that _are_ available on the docker images of all
executors.
Closes#17067
Previously, the command used to deploy the docs to Firebase (as part of
the `deploy-docs` CI job) would fail, because no target project was
specified (either directly in the command or indirectly via a
`.firebaserc` file in the working directory).
Example failure:
https://app.circleci.com/pipelines/github/angular/angular.js/
166/workflows/34c692ec-18d4-4422-a1cf-108a91219fa5/jobs/1744
This commit fixes the command by specifying the project via the
`--project` cli argument. It also adds the commit SHA as message to make
it easier to associate a deployment with the corresponding commit.
Closes#17066
Previously, the `DIST_TAG` environment variable was failing to be
computed correctly, because it was using the non-existent `jq` tool. In
the past (when running on TravisCI), `jq` used to be available, but it
is not on the currently used CircleCI docker image, resulting in the
following error:
```sh
./.circleci/env.sh: line 59: jq: command not found
DIST_TAG=
```
You can see an example failure in the "Set up environment" step logs in
https://app.circleci.com/pipelines/github/angular/angular.js/
166/workflows/34c692ec-18d4-4422-a1cf-108a91219fa5/jobs/1742
This commit fixes it by using `node` (which _is_ available on the docker
image) to compute `$DIST_TAG`.
Previously, the `prepare-deployment` CI job, which requires all unit and
e2e test jobs to have succeeded before running, was ignoring the `lint`
job. As a result, deployments might happen even when there were linting
issues. This looks like an oversight.
This commit ensures that, in addition to unit and e2e tests passing,
linting must also pass before deploying the code or documentation.
Closes#17063
One step in the `deploy-docs` CI job contains a typo that causes it to
fail: `yarn -cwd ...` instead of `yarn --cwd ...`
This has been broken since a0488b30a7, but
has not been noticed because the job was not running. #17060 configured
the job to run as necessary, which brought up the error.
Example failure:
- On v1.8.x:
https://app.circleci.com/pipelines/github/angular/angular.js/
153/workflows/6a9826ac-d191-4042-8c39-0c969c81e381/jobs/1606
This commit fixes the typo in the command.
In #17060, the `deploy-code` job was updated to [include][1] the
`init_environment` custom command. This caused the job to start failing,
because the `init_environment` command was not compatible with the
`cloud-sdk` executor used in `deploy-code`. There were two problems:
1. The `init_environment` command assumes that the working directory is
`~/ng`. The `cloud-sdk` executor [did not specify][2] a working
directory.
Example failures:
- On master:
https://app.circleci.com/pipelines/github/angular/angular.js/
152/workflows/812df7b2-4bba-4e9e-a868-8c58db5d40d1/jobs/1594
- On v1.8.x:
https://app.circleci.com/pipelines/github/angular/angular.js/
153/workflows/6a9826ac-d191-4042-8c39-0c969c81e381/jobs/1607
2. The `install_java` step, which is part of the `init_environment`
command, relies on `sudo`, which is not available in the `cloud-sdk`
executor.
Example failure:
- [On a PR]:
https://app.circleci.com/pipelines/github/angular/angular.js/
160/workflows/2eed5cfa-751c-44ba-b825-1d6cd5ba3406/jobs/1660
This commit fixes the issues by:
1. Specifying a working directory for the `cloud-sdk` executor. It also
updates paths used in other steps of the `deploy-code` job to take
the working directory into account.
2. Removing the `install_java` step from the `init_environment` command
and adding it explicitly to jobs than require it.
[1]: https://github.com/angular/angular.js/blob/83f084e5db95768dcee5/.circleci/config.yml#L359
[2]: https://github.com/angular/angular.js/blob/83f084e5db95768dcee5/.circleci/config.yml#L34-L37
Previously, the `grunt prepareDeploy` command was run in both the
`prepare-deployment` and `deploy-docs` CI jobs. The reason was that not
all files affected by `grunt prepareDeploy` were persisted to the
workspace across jobs.
More specifically, the command would affect files in the `deploy/` and
`scripts/docs.angularjs.org-firebase/` directories and also create a
`firebase.json` file at the root directory, but only the `deploy/`
directory was [persisted to the workspace][1].
This commit avoids unnecessarily running the `grunt prepareDeploy`
command in the `deploy-docs` CI job by ensuring that all affected files
will be persisted to the workspace in the `prepare-deployment` CI job,
which always runs before `deploy-docs`.
[1]: https://github.com/angular/angular.js/blob/295213df953766625462/.circleci/config.yml#L265Closes#17060
Previously, the generated build artifacts and docs were only deployed
for builds associated with the master branch. There was also a `latest`
branch mentioned in the config, but there is normally no such branch, so
this had no effect.
This commit fixes the rules so that deployments happen when necessary.
More specifically:
- The `deploy-code` job now runs for builds associated with:
- The master branch.
- The stable branch (i.e. the branch from which the version tagged as
`@latest` on npm is released).
- Tags of the form `v1.X.Y(-Z)`. (This also required configuring
CircleCI to run builds for git tags, which does not happen by
default.)
- The `deploy-docs` job now runs for builds associated with:
- The stable branch (i.e. the branch from which the version tagged as
`@latest` on npm is released).
The new rules for when deployments should take place are based on the
logic previously in [.travis.yml][1] and [scripts/travis/build.sh][2]
(from before we switched from Travis to CircleCI).
[1]: https://github.com/angular/angular.js/blob/974700af7c1/.travis.yml#L54-L103
[2]: https://github.com/angular/angular.js/blob/974700af7c1/scripts/travis/build.sh#L66-L101
As mentioned in `RELEASE.md`, now that the [CDN][1] has been updated
with the 1.8.0 version, it is safe to bump the value of the
`branchVersion` property in `package.json` to `^1.8.0`. This will cause
the docs app to use the latest version, namely 1.8.0.
[1]: https://ajax.googleapis.com/ajax/libs/angularjs/1.8.0/angular.js
Due to COVID-19 affecting teams migrating from AngularJS, the Long Term Support period has been
extended by 6 months (until the end of 2021). See announcement on Twitter:
https://twitter.com/angular/status/1287780634572857357
This commit updates the "Version Support Status" page to also mention the extension.
Partially addresses #17058.
The `indexBy()` method was renamed to `keyBy()` in lodash v4 (see
lodash/lodash@b1d52ccd82). This commit
updates all usages of `indexBy()` to `keyBy()`.
If `ngSanitize` is added as a module dependency and a Content-Security-Policy
is set that does not allow inline styles then Firefox and Chrome show the
following message:
> Content Security Policy: The page’s settings observed the loading of a
resource at self (“default-src”). A CSP report is being sent.
This message is caused because AngularJS is creating an inline style tag
to test for a browser bug that we use to decide what sanitization strategy
to use, which causes CSP violation errors if inline CSS is prohibited.
This test is no longer necessary, since the `DOMParser` is now safe to use
and the `style` based check is redundant.
In this fix, we default to using `DOMParser` if it is available and fall back
to `createHTMLDocument()` if needed. This is the approach used by DOMPurify
too.
The related unit tests in `sanitizeSpec.js`, "should not allow JavaScript
execution when creating inert document" and "should not allow JavaScript
hidden in badly formed HTML to get through sanitization (Firefox bug)", are
left untouched to assert that the behavior hasn't changed in those scenarios.
Fixes#16463.
Previously, the docs app used `document.write()`, causing the following
warning on Chrome:
```
A parser-blocking, cross site (i.e. different eTLD+1) script,
https://ajax.googleapis.com/ajax/libs/angularjs/1.7.9/angular.min.js, is
invoked via document.write. The network request for this script MAY be
blocked by the browser in this or a future page load due to poor network
connectivity.
```
In the past, `document.write()` seems to have been used in order for
browsers (such as Firefox) to work correctly with our dynamically set
`<base>` tag and relative style/script URLs.
This commit replaces `document.write()` with regular
`<style>`/`<script>` tabs to avoid the warning (and potential issues due
to poor network connectivity). It seems that the latest versions of
Chrome, Firefox and IE can handle this fine (without naticeable delays).
Fixes#15396
Create style elements and modify their text content instead of using
innerHTML to create the whole `<style>` element with its content.
That way style insertion done at bootstrap time doesn't interfere with
Trusted Types restrictions in Chrome (https://bit.ly/trusted-types).
Remove the type attribute - `text/css` is default:
https://html.spec.whatwg.org/#update-a-style-block.
Closes#17014
This commit gets rid of all references to Travis and, belatedly, Jenkins.
Now all CI is done on CircleCI and releases are run locally.
The CI no longer updates the docs and code.angularjs.org for jobs that are
not on the `master` branch.
During releases, the docs and code should be uploaded manually.
Node.js 8 ends its support at the end of 2019. Node 12 will be supported
until April 2022 which is way past AngularJS end of support.
Some dependencies needed to be updated to make them work in Node.js 12.
The files served for the various versions on https://code.angularjs.org/
are retrieved by a Firebase function from a Firebase Storage bucket
(where they are deployed to from Travis CI). The files are stored
exactly as they are named on disk.
It turns out that some of the files have names with special characters
that get URI-encoded when sent to the Firebase function. For example,
`input[text].html` becomes `input%5Btext%5D.html`. As a result, the
actual file cannot be retrieved from the Storage bucket (since the name
does not match) and `index.html` is returned instead. Apparently, this
never worked, but nobody noticed or reported it until recently.
An example of a failing URL is:
https://code.angularjs.org/1.7.9/docs/api/ng/input/input%5Btext%5D
(NOTE: https://docs.angularjs.org/ works correctly, since the files are
deployed to Firebase hosting directly and not to a Storage bucket.)
This commit fixes the problem by decoding the request path before trying
to retrieve the corresponding file from the Storage bucket.
Closes#16943
The currently latest-1 version of desktop Safari (v12.0) on SauceLabs is
completely unstable. Switching to the latest version (currently v12.1),
which works fine.
Closes#16888
Since d6098eeb1, old styles were not removed if `newStyles` specified an
invalid value for the style (e.g. `false`). The assumption was that the
new style would overwrite the old style value, but using an invalid
value made browsers ignore the new value and thus keep the old style.
This would typically happen when guarding a style with a boolean flag;
e.g.: `ng-style="{backgroundColor: isError && 'red'}"`
This commit essentially revers commit d6098eeb1, whose main purpose was
to work around jquery/jquery#4185. The jQuery issue has been fixed in
3.4.0, so that should not be a problem any more.
Fixes#16860Closes#16868
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#16814Closes#16820
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
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#16799Closes#16800
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.
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#16778Closes#16779
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
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#14691Closes#16760
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.
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 #16100Closes#16606
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
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#16164Closes#16471
According to angular/protractor#3969, `browser.getLocationAbsUrl()` is
now deprecated and `browser.getCurrentUrl()` should be used instead.
Closes#16053
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: #16739Closes#16753
Protractor's `browser.getLocationAbsUrl()` has been deprecated and
`browser.getCurrentUrl()` is the recommended alternative.
Related: angular/angular-phonecat#430
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).
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#16692Closes#16715
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#16616Closes#16729
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
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
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#16697Closes#16699
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.
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#16652Fixes#16626
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#16653Closes#16656
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!
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#16428Fixes#16235Closes#16614
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
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#14673Closes#14674
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#16641Closes#16642
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.
`$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
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.
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#16592Closes#16611
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#16607Closes#16615
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#14165Closes#14166Closes#16613
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
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#14173Closes#16589
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#14665Closes#16604
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
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#16594Closes#16595
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#7925Closes#15002
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#14744Closes#15707Closes#16283Closes#16299Closes#16591
- Synced "animation aware" directives tables in API docs and "Animation"
guide.
- Sorted tables alphabetically.
- Added info about `ngAnimateSwap` directive.
References #16561Closes#16581
This could for example happen if updating the value is debounced (either
by asynchronously calling `$setViewValue()` or via `ngModelOptions`).
Fixes#16583Closes#16585
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-hooksCloses#16580
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#15554Closes#15555
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
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#16537Closes#16539
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
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
This change aligns jqLite with jQuery.
Fixes#15869Closes#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.
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 #11446Closes#16517
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
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
* 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
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
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.
```
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');
```
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.
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
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
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#6731Fixes#9334Closes#6865Closes#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!
```
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]`.
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
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
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#16448Closes#16449
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
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
- 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
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
Closes#14204Closes#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.
Closes#15533Closes#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.
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.
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#15294Closes#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
```
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.
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.
- 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#16332Closes#16334Closes#16397
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
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.
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#16268Fixes#14961
Ref yarnpkg/yarn#1483
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).
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#15018Closes#15085Closes#15105
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(...);
});
```
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.
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.
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#16135Closes#16161
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
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.
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-1Closes#15113Closes#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.
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#14292Closes#10076Closes#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.
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#16253Closes#16260
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
Closes#15411Closes#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 }
}
```
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#12761Closes#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);
};
}
}
```
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`.
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#7303Closes#9444Closes#16297
Browsers mutate attributes values such as ` 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
{} 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
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#16135Closes#16293
BREAKING CHANGE:
Recursively invoking `$emit` or `$broadcast` with the same event name is
no longer supported. This will now throw a `inevt` minErr.
"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
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.
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#14045Closes#16265
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.htmlCloses#4516Closes#14667Closes#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.
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
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
- 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
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.
- 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
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.
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
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`.
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
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.
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
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#15740Closes#16162
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.
Previously, `httpParamSerializerJQLike` stringified function properties without executing them.
This commit ensures function properties are executed and the return value is used.
Fixes#16138Closes#16139
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
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
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).
- 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#9674Closes#16093
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#15883Closes#16104
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
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 #14888Closes#16097
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#15741Closes#16099
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#16027Closes#16075
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#15924Closes#15847
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#16057Closes#16064
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#12653Closes#14941Closes#15180Closes#15992Closes#16036
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
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.
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#15952Closes#15953
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.
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 b277e3ead7Closes#15995
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#15868Closes#15872
If a user-provided comparator fails to differentiate between two items, fall
back to the built-in comparator (using the tie-breaker predicate).
Fixes#14881Closes#15914
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
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
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
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
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#15880Closes#15881
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#13172Closes#10127
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
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.
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#10596Closes#15928
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
- baddata error described incorrect http behavior, and workarounds
- httpProvider defaults were missing transformResponse / transformRequest
- http was not clear about JSON detection strategy
Closes#15897Closes#15906
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
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
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
- 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
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 #8695Closes#15846
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
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
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
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#10128Closes#12181
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
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.
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.
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#15758Closes#15765
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
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#15590Closes#15767
You can now check what version of AngularJS a core module is designed for:
```
var angularVersion = $injector.modules['myModule'].info().angularVersion;
```
This also removes the likewise deprecated `$controllerProvider.allowGlobals()` method.
Closes#15349Closes#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() {...});
});
```
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.
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.
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
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#15644Closes#15660
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#15675Closes#15676
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#15624Closes#15628
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.
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
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-348c2f3781ed66a24894c2046a52c628L2084Fixes#15629Closes#15631
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#15645Closes#15646
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
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
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#15474Closes#15633
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
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#15510Closes#15514
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).
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#15603Closes#15605
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 }}" />
```
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
`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
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
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: #15586Closes#15594
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#15144Closes#15145
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#11075Fixes#12571Fixes#15556Closes#15561
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.
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#15567Closes#15571
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#15504Closes#15506
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 #15523Closes#15532
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#15477Closes#15478
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#15492Closes#15493
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#14404Closes#15246
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
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#15422Closes#15424
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#15331Closes#15367Closes#15475
Support for IPv6 addresses (in b643f0d) was too aggressive and broke support for params in the
`hostname` part of a URL.
This commit restores support for params in the `hostname`, as long as it is not an IPv6 address.
Fixes#14542Closes#14906
When the "empty option" element contains a transclusion directive, the result of the compilation always includes a comment node. Since we are adding / removing the "selected" attribute on the empty option, we need to make sure it's an actual element.
To solve this, we take advantage of the fact the each option element has an option directive that tries to register the option with the selectController. With ngOptions, this registerOption function is normally noop'd since it's not possible to add dynamic options. Now if the result of the empty option compilation is a comment, we re-define the function so that it catches empty options when they are actually linked / rendered.
Closes#15454Closes#15459
Currently, ngdoc `@method` ignores `@example` tags and does not output them.
This is usually not a problem, as examples are mostly defined directly
in the `@description` via code blocks or `<example>`
elements. However, some methods still have `@example` tags (possibly
from a previous docs version).
While not absolutely necessary, having special markup for Examples
makes them a) easier to find visually in the docs, and b) easier
to link to as they will have a unique id.
Closes#14722Closes#15448
Since Chrome 53-57+, the reported size of `<foreignObject>` elements and their
descendants is affected by global display settings (e.g. font size) and browser
settings (e.g. default zoom level). This could cause tests incorrectly failing
due to such settings.
In order to avoid false negatives, we now compare against the size of the
equivalent, hand-written SVG instead of fixed widths/heights.
Fixes#15333Closes#15458
Deprecated boxes for APIs appear right under the header and were missing
a bit of margin. Boxes for methods still look good even with the
additional margin.
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
***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.**
# AngularJS is in LTS mode
We are no longer accepting changes that are not critical bug fixes into this project.
See https://blog.angular.io/stable-angularjs-and-long-term-support-7e077635ee9c for more detail.
**Do you want to request a *feature* or report a *bug*?**
<!--
IF YOU DON'T FILL OUT THE FOLLOWING INFORMATION WE MIGHT CLOSE YOUR ISSUE WITHOUT INVESTIGATION
- Before submitting, please **SEARCH GITHUB** for a similar issue or PR. -->
**I'm submitting a ...**
<!-- (check one with "x") -->
- [ ] regression from 1.7.0
- [ ] security issue
- [ ] issue caused by a new browser version
- [ ] other <!--(Please do not submit support requests here - see above)-->
**What is the current behavior?**
**Current behavior:**
<!-- Describe how the bug manifests / how the current features are insufficient. -->
**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).
-->
**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).**
**AngularJS version:** 1.8.x
<!-- Check whether this is still an issue in the most recent stable or in the snapshot AngularJS
version (https://code.angularjs.org/snapshot/) -->
**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 -->
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.
* **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 `npm run commit` in your terminal after staging your changes in git.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:
```
<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`,
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:circleci-protractor','Run the end to end tests with Protractor for CircleCI builds',[
'connect:testserver',
'protractor:circleci'
]);
grunt.registerTask('test:e2e','Alias for test:protractor',['test:protractor']);
## 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) 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 CI job)
The versions in the modal are updated (based on the versions available on CDN) as part of the CI deploy stage.
(You may need to explicitly trigger the CI job. e.g. re-running the last `deploy` job.)
## Announce the release (via official Google accounts)
Double check that angularjs.org is up to date with the new release version before sharing.
<div><label><inputtype="radio"ng-model="benchmarkType"ng-disabled="fileType !== 'classfilter'"value="disabledClassFilter">disabled by classNameFilter on element:</label> (requires <ahref="?app=app-classfilter.js">app-classfilter.js</a>)</div>
<ng-switchon="benchmarkType">
<baselineng-switch-when="baseline">
</baseline>
<divng-switch-when="noanimate">
<divnoop>
<divng-repeat="row in data">
<spanng-repeat="column in row">
<span>{{column.i}}</span>
</span>
</div>
</div>
</div>
<divng-switch-when="enabled">
<divnoop>
<divng-repeat="row in data">
<spanng-repeat="column in row">
<span>{{column.i}}</span>
</span>
</div>
</div>
</div>
<divng-switch-when="globallyDisabled">
<divnoop>
<divng-repeat="row in data">
<spanng-repeat="column in row">
<span>{{column.i}}</span>
</span>
</div>
</div>
</div>
<divng-switch-when="disabledClassFilter">
<divnoop>
<divng-repeat="row in data">
<spanclass="disable-animations"ng-repeat="column in row">
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">
AngularJS support has officially ended as of January 2022.
[See what ending support means](https://docs.angularjs.org/misc/version-support-status)
and [read the end of life announcement](https://goo.gle/angularjs-end-of-life).
Visit [angular.io](https://angular.io) for the actively supported Angular.
</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 +22,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 +94,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 +141,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 +225,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.
This error occurs when the security context for a property is defined via {@link ng.$compileProvider#addPropertySecurityContext addPropertySecurityContext()} multiple times under different security contexts.
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:
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`).
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.