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
The `indexBy()` method was renamed to `keyBy()` in lodash v4 (see
lodash/lodash@b1d52ccd82). This commit
updates all usages of `indexBy()` to `keyBy()`.
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.
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.
Many browsers have some extension URL scheme. It is unclear how many of
those have the security issue of allowing parser-inserted loads of
extension URLs.
To be conservative, this code whitelists the URL schemes that are known
to be subject to CSP, i.e. the ones that are expected and safe.
1. The conditions checking the msie variable value have been simplified.
There is e.g. no point to check if `msie <= 11` since there IE 12 won't ever
exist.
2. Edge UA-sniffing has been added to tests (only!) where appropriate
3. Support comments for IE/Edge have been added.
Closes#15407
1. Change all transition/transform/animation-related ss.addRule to
ss.addPossiblyPrefixedRule to account for the -webkit- prefix.
2. Remove manually added -webkit-prefixed rules in favor of automatically
handling them in ss.addPossiblyPrefixedRule.
Closes#15406
ngIf, ngInclude, ngSwitch, and ngView now use the `done` callback functions on animation runners returned
by leave/enter animations to do internal cleanup (and $anchorScroll for ngInclude and ngView).
Previously, they were using promise callbacks (`then`), which caused an unnessecary digest.
Background:
In https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9, animation
promises where introduced instead of animation callbacks. These promises were however not tied to
the digest cycle, so you had to manually call `$apply` inside them.
This was changed in https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef,
so animation promise callbacks would always trigger a `$digest`. This meant that several built-in
directives would now trigger additional digests on leave (ngIf, ngSwitch) or enter/leave (ngInclude,
ngView). The `done` callback, which receives a single argument indicating success / failure was
introduced to allow digest-less responses, but wasn't applied to these directives.
Note that this applies to all calls to $animate.enter/leave, even if ngAnimate isn't included, and
no actual animations are running, because the animation runner code is in the core ng module.
Fixes#15322Closes#15345
Expanded "test" to also mean test fixes.
Added a link to the help page about closing issues with commit
messages in the section about the footer.
Closes#15340
Previously, you had to apply a complete set of `ngModelOptions` at many places in
the DOM where you might want to modify just one or two settings.
This change allows more general settings to be applied nearer to the root of the DOM
and then for more specific settings to inherit those general settings further down
in the DOM.
To prevent unwanted inheritance you must opt-in on a case by case basis:
* To inherit as single property you simply provide the special value `"$inherit"`.
* To inherit all properties not specified locally then include a property `"*": "$inherit"`.
Closes#10922Closes#15389
BREAKING CHANGE:
The programmatic API for `ngModelOptions` has changed. You must now read options
via the `ngModelController.$options.getOption(name)` method, rather than accessing the
option directly as a property of the `ngModelContoller.$options` object. This does not
affect the usage in templates and only affects custom directives that might have been
reading options for their own purposes.
One benefit of these changes, though, is that the `ngModelControler.$options` property
is now guaranteed to be defined so there is no need to check before accessing.
So, previously:
```
var myOption = ngModelController.$options && ngModelController.$options['my-option'];
```
and now:
```
var myOption = ngModelController.$options.getOption('my-option');
```
"Shadows" should better convey the meaning of "overwriting the value of the property in the child
scope, while leaving the parent scope intact".
"Hides" could give the impression that it makes the property unavailable in the child scope and
leaving "overrides" only, could give the impression that the parent scope would be affected too,
especially to people not familiar with JavaScript's prototypal inheritance.
Closes#15375
Previously `$location` was rewriting such paths to remove not only the
double slashes but also the first segment of the path, leading to an invalid
path.
In this change, we deem leading double (back)slashes an invalid path and
now throw a `$location:badpath` error if that occurs.
Closes#15365
Closes#15283Closes#15288
BREAKING CHANGE:
When using input[radio], the checked status is now determined by doing
a strict comparison between the value of the input and the ngModel.$viewValue.
Previously, this was a non-strict comparison (==).
This means in the following examples the radio is no longer checked:
```
<!-- this.selected = 0 -->
<input type="radio" ng-model="$ctrl.selected" value="0" >
<!-- this.selected = 0; this.value = false; -->
<input type="radio" ng-model="$ctrl.selected" ng-value="$ctrl.value" >
```
The migration strategy is to convert values that matched with non-strict
conversion so that they will match with strict conversion.
- docs for the snapshot will include the snapshot files from code.angularjs.org
- docs for tagged versions will include the files from the (Google) CDN
- docs for local / untagged versions will try to include the files from the (Google) CDN, which will fail. This gives immediate feedback that something is broken.
Closes#15267Closes#15358
Add an example on how to set default values on `$cookiesProvider`. Many similar services support
overriding the `defaults` object with a new one, but this service only supports changing individual
properties.
Closes#15362
Fixes#15350Closes#15352
BREAKING CHANGE: Previously, $compileProvider.preAssignBindingsEnabled was
set to true by default. This means bindings were pre-assigned in component
constructors. In Angular 1.5+ the place to put the initialization logic
relying on bindings being present is the controller $onInit method.
To migrate follow the example below:
Before:
```js
angular.module('myApp', [])
.component('myComponent', {
bindings: {value: '<'},
controller: function() {
this.doubleValue = this.value * 2;
}
});
```
After:
```js
angular.module('myApp', [])
.component('myComponent', {
bindings: {value: '<'},
controller: function() {
this.$onInit = function() {
this.doubleValue = this.value * 2;
};
}
});
```
If you don't have time to migrate the code at the moment, you can flip the
setting back to true:
```js
angular.module('myApp', [])
.config(function($compileProvider) {
$compileProvider.preAssignBindingsEnabled(false);
})
.component('myComponent', {
bindings: {value: '<'},
controller: function() {
this.doubleValue = this.value * 2;
}
});
```
Don't do this if you're writing a library, though, as you shouldn't change
global configuration then.
Extension URIs (`resource://...`) bypass Content-Security-Policy in Chrome and
Firefox and can always be loaded. Now if a site already has a XSS bug, and uses
CSP to protect itself, but the user has an extension installed that uses
Angular, an attacked can load Angular from the extension, and Angular's
auto-bootstrapping can be used to bypass the victim site's CSP protection.
Notes:
- `isAutoBootstrapAllowed` must be initialized on load, so that `currentScript`
is set correctly.
- The tests are a bit indirect as reproducing the actual scenario is too
complicated to reproduce (requires signing an extension etc). I have confirmed
this to be working manually.
Closes#15346
Previously, the index would show the version of Angular that runs on
the page, not the version for which the docs are. This meant that in
that snapshot docs the stable version was displayed.
The `$scope.docsVersion` value was used in the plnkr opening code, but
has not been used since https://github.com/angular/angular.js/commit/bdec35cebc89e0d80a04eeffbd71ad999fc7e61a.
Closes#15265
In some cases IE11/Edge calls to `element.value` are very slow when the
`element.value` has not been set. Normally, these calls are usualy 0-3 ms
but in these cases it can take 200-300 ms. This can easily add 3 or more
seconds to the load time on a view that has 10 or more select tags using
`ngOptions`.
The line this pull request is changing not only suffers from the performance
issue described above but it also appears to be broken. The code is checking
that `option.value` does not equal `element.value` but then sets `element.value`
to `option.selectValue`.
I don't believe `option.value` is actually defined anywhere and likely it
was always intended to be `option.selectValue`. This means that check would
always be true and since this code has been this way for quite a while and
is causing a performance issue I've just removed the check. This way a call
to `element.value` is never made prior to it's value being set.
Closes#15344
In 1.6, urls accessed with jsonp must be whitelisted via sce.
However, the yahoo finance api used in the example allows CORS
access via Access-Control-Allow-Origin:"*", so we can simply use
`$http.get` instead.
Closes#15336
We have two fields in package.json for checking the current version:
* branchVersion
* branchPattern
The `branchVersion` field is used to work out what version to use in the
docs application, so we should not update this to the most recent version
until that version is on the Google CDN. Otherwise the docs app will break.
The `branchPattern` is used to determine what branch we are currently
working from and is generally used as a gate-keeper to prevent invalid
releases from the wrong branch.
The `getTaggedVersion()` method was using the `branchVersion` to check
that the tagged commit was valid but this fails when we are moving to a
new minor version with release candidates.
This fix avoids the problem by doing a custom comparison against the
`branchPattern` instead.
We specify the node version that is required to run the build in the `.nvmrc`
file. So let's check that the current node version satisfies this and report
a helpful message if it is not.
Previously, Angular tried to detect the CSS prefix the browser supports and
then use the saved one. This strategy is not ideal as currently some browsers
are supporting more than one vendor prefix. The best example is Microsoft Edge
that added -webkit- prefixes to be more Web-compatible; Firefox is doing
a similar thing on mobile. Some of the -webkit--prefixed things are now even
getting into specs to sanction that they're now required for Web compatibility.
In some cases Edge even supports only the -webkit--prefixed property; one
example is -webkit-appearance.
$sniffer.vendorPrefix is no longer used in Angular core outside of $sniffer
itself; taking that and the above problems into account, it's better to just
remove it. The only remaining use case was an internal use in detection of
support for transitions/animations but we can directly check the webkit prefix
there manually; no other prefix matters for them anyway.
$sniffer is undocumented API so this removal is not a breaking change. However,
if you've previously been using it in your code, just paste the following
to get the same function:
var vendorPrefix = (function() {
var prefix, prop, match;
var vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/;
for (prop in document.createElement('div').style) {
if ((match = vendorRegex.exec(prop))) {
prefix = match[0];
break;
}
}
return prefix;
})();
The vendorPrefix variable will contain what $sniffer.vendorPrefix used to.
Note that we advise to not check for vendor prefixes this way; if you have to
do it, it's better to check it separately for each CSS property used for the
reasons described at the beginning. If you use jQuery, you don't have to do
anything; it automatically adds vendor prefixes to CSS prefixes for you in
the .css() method.
Fixes#13690Closes#15287
By setting the current partial content to hidden, the current height
of the window is maintained until the new content is loaded.
This prevents flickering caused by the scrollbar (dis)appearing and
the footer coming into view.
This change aligns jqLite with jQuery 3.
The relevant bit of jQuery code is
https://github.com/jquery/jquery/blob/3.1.1/src/data/Data.jsClose#15126
BREAKING CHANGE: Previously, keys passed to the data method were left untouched.
Now they are internally camelCased similarly to how jQuery handles it, i.e.
only single (!) hyphens followed by a lowercase letter get converted to an
uppercase letter. This means keys `a-b` and `aB` represent the same data piece;
writing to one of them will also be reflected if you ask for the other one.
If you use Angular with jQuery, it already behaved in this way so no changes
are required on your part.
To migrate the code follow the examples below:
BEFORE:
/* 1 */
elem.data('my-key', 2);
elem.data('myKey', 3);
/* 2 */
elem.data('foo-bar', 42);
elem.data()['foo-bar']; // 42
elem.data()['fooBar']; // undefined
/* 3 */
elem.data()['foo-bar'] = 1;
elem.data()['fooBar'] = 2;
elem.data()['foo-bar']; // 1
AFTER:
/* 1 */
// Rename one of the keys as they would now map to the same data slot.
elem.data('my-key', 2);
elem.data('my-key2', 3);
/* 2 */
elem.data('foo-bar', 42);
elem.data()['foo-bar']; // undefined
elem.data()['fooBar']; // 42
/* 3 */
elem.data()['foo-bar'] = 1;
elem.data()['fooBar'] = 2;
elem.data()['foo-bar']; // 2
jqLite needs camelCase for it's css method; it should only convert one dash
followed by a lowercase letter to an uppercase one; it shouldn't touch
underscores, colons or collapse multiple dashes into one. This is behavior
of jQuery 3 as well.
Also, jqLite's css camelCasing logic was put in a separate function and
refactored: now the properties starting from an uppercase letter are used by
default (i.e. Webkit, not webkit) and the only exception is for the -ms- prefix
that is converted to ms, not Ms. This makes the logic clearer as we're just
always changing a dash followed by a lowercase letter by an uppercase one; this
is also how it works in jQuery.
The camelCasing for the $compile and $sce services retains the previous behaviour.
Ref #15126Fix#7744
BREAKING CHANGE: before, when Angular was used without jQuery, the key passed
to the css method was more heavily camelCased; now only a single (!) hyphen
followed by a lowercase letter is getting transformed. This also affects APIs
that rely on the css method, like ngStyle.
If you use Angular with jQuery, it already behaved in this way so no changes
are needed on your part.
To migrate the code follow the example below:
Before:
HTML:
// All five versions used to be equivalent.
<div ng-style={background_color: 'blue'}></div>
<div ng-style={'background:color': 'blue'}></div>
<div ng-style={'background-color': 'blue'}></div>
<div ng-style={'background--color': 'blue'}></div>
<div ng-style={backgroundColor: 'blue'}></div>
JS:
// All five versions used to be equivalent.
elem.css('background_color', 'blue');
elem.css('background:color', 'blue');
elem.css('background-color', 'blue');
elem.css('background--color', 'blue');
elem.css('backgroundColor', 'blue');
// All five versions used to be equivalent.
var bgColor = elem.css('background_color');
var bgColor = elem.css('background:color');
var bgColor = elem.css('background-color');
var bgColor = elem.css('background--color');
var bgColor = elem.css('backgroundColor');
After:
HTML:
// Previous five versions are no longer equivalent but these two still are.
<div ng-style={'background-color': 'blue'}></div>
<div ng-style={backgroundColor: 'blue'}></div>
JS:
// Previous five versions are no longer equivalent but these two still are.
elem.css('background-color', 'blue');
elem.css('backgroundColor', 'blue');
// Previous five versions are no longer equivalent but these two still are.
var bgColor = elem.css('background-color');
var bgColor = elem.css('backgroundColor');
jQuery has supported this form for a long time. As of jQuery 3.0 this form is
the preferred one and all others are deprecated so jqLite(f) is now also
supported.
All internal invocations of jqLite(document).ready(f) (& equivalent) have been
replaced by jqLite(f).
Tests for these methods have been added as jqLite#ready had no explicit tests
so far.
Due to the nature of some browser's PageCache/BFCache, returning to an Angular
app sometimes causes `input[hidden]` elements to retain the last value
that was stored before the page was navigated away from previously.
This is particularly problematic if the input has an interpolated value.
E.g. `<input type="hidden" value="{{ 1 + 2 }}">` since when the browser
returns, instead of the original interpolation template, the HTML contains
the previous value `<input type="hidden" value="3">`.
This commit instructs the browser not to attempt to reinstate the previous
value when navigating back in history by setting `autocomplete="off"` on
the hidden input element element.
Due to the nature of some browser's PageCache/BFCache, returning to an Angular
app sometimes causes `input[hidden]` elements to retain the last value
that was stored before the page was navigated away from previously.
This is particularly problematic if the input has an interpolated value.
E.g. `<input type="hidden" value="{{ 1 + 2 }}">` since when the browser
returns, instead of the original interpolation template, the HTML contains
the previous value `<input type="hidden" value="3">`.
This commit instructs the browser not to attempt to reinstate the previous
value when navigating back in history by setting `autocomplete="off"` on
the hidden input element element.
Protractor's by.binding selector selects the whole element in which the binding
is contained as otherwise it can't know which bit of text has been interpolated.
It's safer to wrap the binding in a span so that we're sure what the e2e tests
are exactly testing.
The parser always threw an error in the case of an invalid left-value
assignment but it was an unhelpful:
```
Cannot set property 'undefined' of undefined
```
This commit provides a more meaningful error message, so it is not a
breaking change.
Closes#15234
Refactor ngModelSpec to use internal helper function `valueFn`.
Use instead of multiple-defining a function called `curry`.
PR (#15231)
Addresses a quick change mentioned in PR 15208 from Issue #14734
Closes#15064
BREAKING CHANGE:
Previously, the `Deferred` object returned by `$q.defer()` delegated the
`resolve()`, `reject()` and `notify()` methods to `Deferred.prototype`. Thus, it
was possible to modify `Deferred.prototype` and have the changes reflect to all
`Deferred` objects.
This commit removes that delegation, so modifying the above three methods on
`Deferred.prototype` will no longer have an effect on `Deferred` objects.
The bind/unbind aliases to on/off were being assinged in every iteration
of the function assigning traversal methods to the prototype. Now it happens
only once.
The attr method was refactored to be divided into setter & getter parts
and to handle boolean attributes in each one of them separately instead of
dividing into boolean & non-boolean ones and then handling setter & getter
in both of them. This is because handling boolean & non-boolean attributes
has common parts; in particular handling of the `null` value or using
getAttribute to get the value in the getter.
This change aligns jqLite with jQuery.
Ref #15126
BREAKING CHANGE: Before, using the `attr` method with an empty string as a value
would remove the boolean attribute. Now it sets it to its lowercase name as
was happening for every non-empty string so far. The only two values that remove
the boolean attribute are now null & false, just like in jQuery.
To migrate the code follow the example below:
Before:
elem.attr(booleanAttrName, '');
After:
elem.attr(booleanAttrName, false);
or:
elem.attr(booleanAttrName, null);
This change aligns jqLite with jQuery.
Also, the extra `2` second parameter to `setAttribute` has been removed;
it was only needed for IE<9 and latest jQuery doesn't pass it either.
Ref #15126
BREAKING CHANGE: Invoking `elem.attr(attributeName, null)` would set the
`attributeName` atribute value to a string `"null"`, now it removes the
attribute instead.
To migrate the code follow the example below:
Before:
elem.attr(attributeName, null);
After:
elem.attr(attributeName, "null");
This is done automatically by browsers in cases where it's needed; the
workaround was only needed for IE<9. The new behavior means boolean attributes
will not be reflected on elements where browsers don't reflect them.
This change aligns jqLite with jQuery 3.
Fixes#14126
BREAKING CHANGE: Previously, all boolean attributes were reflected into
properties in a setter and from a property in a getter, even on elements that
don't treat those attributes in a special way. Now Angular doesn't do it
by itself but relies on browsers to know when to reflect the property. Note that
this browser-level conversions differs between browsers; if you need to change
dynamic state of an element you should modify the property, not the attribute.
See https://jquery.com/upgrade-guide/1.9/#attr-versus-prop- for a more detailed
description about a related change in jQuery 1.9.
To migrate the code follow the example below:
Before:
CSS:
input[checked="checked"] { ... }
JS:
elem1.attr('checked', 'checked');
elem2.attr('checked', false);
After:
CSS:
input:checked { ... }
JS:
elem1.prop('checked', true);
elem2.prop('checked', false);
Change synchronous validators to convert the return to boolean value.
Prevent unexpected behavior when returning `undefined`.
Closes#14734Closes#15208
BREAKING CHANGE: Previously, only a literal `false` return would resolve as the
synchronous validator failing. Now, all traditionally false JavaScript values
are treated as failing the validator, as one would naturally expect.
Specifically, the values `0` (the number zero), `null`, `NaN` and `''` (the
empty string) used to considered valid (passing) and they are now considered
invalid (failing). The value `undefined` was treated similarly to a pending
asynchronous validator, causing the validation to be pending. `undefined` is
also now considered invalid.
To migrate, make sure your synchronous validators are returning either a
literal `true` or a literal `false` value. For most code, we expect this to
already be the case. Only a very small subset of projects will be affected.
Namely, anyone using `undefined` or any falsy value as a return will now see
their validation failing, whereas previously falsy values other than `undefined`
would have been seen as passing and `undefined` would have been seen as pending.
Closes#15157
BREAKING CHANGE:
`$http`'s deprecated custom callback methods - `success()` and `error()` - have been removed.
You can use the standard `then()`/`catch()` promise methods instead, but note that the method
signatures and return values are different.
`success(fn)` can be replaced with `then(fn)`, and `error(fn)` can be replaced with either
`then(null, fn)` or `catch(fn)`.
Before:
```js
$http(...).
success(function onSuccess(data, status, headers, config) {
// Handle success
...
}).
error(function onError(data, status, headers, config) {
// Handle error
...
});
```
After:
```js
$http(...).
then(function onSuccess(response) {
// Handle success
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
...
}, function onError(response) {
// Handle error
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
...
});
// or
$http(...).
then(function onSuccess(response) {
// Handle success
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
...
}).
catch(function onError(response) {
// Handle error
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
...
});
```
**Note:**
There is a subtle difference between the variations showed above. When using
`$http(...).success(onSuccess).error(onError)` or `$http(...).then(onSuccess, onError)`, the
`onError()` callback will only handle errors/rejections produced by the `$http()` call. If the
`onSuccess()` callback produces an error/rejection, it won't be handled by `onError()` and might go
unnoticed. In contrast, when using `$http(...).then(onSuccess).catch(onError)`, `onError()` will
handle errors/rejections produced by both `$http()` _and_ `onSuccess()`.
The query parameter that will be used to transmit the JSONP callback to the
server is now specified via the `jsonpCallbackParam` config value, instead of
using the `JSON_CALLBACK` placeholder.
* Any use of `JSON_CALLBACK` in a JSONP request URL will cause an error.
* Any request that provides a parameter with the same name as that given
by the `jsonpCallbackParam` config property will cause an error.
This is to prevent malicious attack via the response from an app inadvertently
allowing untrusted data to be used to generate the callback parameter.
Closes#15161Closes#15143Closes#11352Closes#11328
BREAKING CHANGE
You can no longer use the `JSON_CALLBACK` placeholder in your JSONP requests.
Instead you must provide the name of the query parameter that will pass the
callback via the `jsonpCallbackParam` property of the config object, or app-wide via
the `$http.defaults.jsonpCallbackParam` property, which is `"callback"` by default.
Before this change:
```
$http.json('trusted/url?callback=JSON_CALLBACK');
$http.json('other/trusted/url', {params:cb:'JSON_CALLBACK'});
```
After this change:
```
$http.json('trusted/url');
$http.json('other/trusted/url', {callbackParam:'cb'});
```
The $http service will reject JSONP requests that are not trusted by
`$sce` as "ResourceUrl".
This change makes is easier for developers to see clearly where in their
code they are making JSONP calls that may be to untrusted endpoings and
forces them to think about how these URLs are generated.
Be aware that this commit does not put any constraint on the parameters
that will be appended to the URL. Developers should be mindful of what
parameters can be attached and how they are generated.
Closes#11352
BREAKING CHANGE
All JSONP requests now require the URL to be trusted as resource URLs.
There are two approaches to trust a URL:
**Whitelisting with the `$sceDelegateProvider.resourceUrlWhitelist()`
method.**
You configure this list in a module configuration block:
```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhiteList([
// Allow same origin resource loads.
'self',
// Allow JSONP calls that match this pattern
'https://some.dataserver.com/**.jsonp?**`
]);
}]);
```
**Explicitly trusting the URL via the `$sce.trustAsResourceUrl(url)`
method**
You can pass a trusted object instead of a string as a URL to the `$http`
service:
```
var promise = $http.jsonp($sce.trustAsResourceUrl(url));
```
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes#3174Fixes#14745Closes#15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
Previoulsy, when the value of an `ngAttrXyz` attribute did not contain any interpolation, then the
`xyz` attribute was never set.
BTW, this commit adds a negligible overhead (since we have to set up a one-time watcher for
example), but it is justifiable for someone that is using `ngAttrXyz` (instead of `xyz` directly).
(There is also some irrelevant refactoring to remove unnecessary dependencies from tests.)
Fixes#15133Closes#15149
Improve the explanation of what a "pure function" is in simple words. The previous explanation
could be confusing, especially since the term "idempotent" (here used in it's broader
"Computer Science" meaning) is overloaded and has much stricter semantics in Mathematics or pure
Functional Programming.
Closes#15173
`Resource.bind()`, which creates an new Resource class with the same propertiesexcept for the
additional bound default parameters, was not passing the original Resource class' `options`,
resulting in different behavior.
This commit fixes it by passing the `options` when creating the new Resource class.
Update the description of CSP, mainly regarding `unsafe-eval` and `unsafe-inline`. The way it was
presented previously was slightly misleading as it indicated that these were rules forbidding
certain things, when in fact it's a keyword in the CSP that disables the very rule that was
described. The updated text clarifies this better.
Closes#15142
If the transcluded content is only whitespace then we should use the
fallback content instead. This allows more flexibility in formatting
your HTML.
Closes#15077Closes#15140
BREAKING CHANGE:
Previously whitespace only transclusion would be treated as the transclusion
being "not empty", which meant that fallback content was not used in that
case.
Now if you only provide whitespace as the transclusion content, it will be
assumed to be empty and the fallback content will be used instead.
If you really do want whitespace then you can force it to be used by adding
a comment to the whitespace.
The angular expression parser (`$parse`) attempts to sandbox expressions
to prevent unrestricted access to the global context.
While the sandbox was not on the frontline of the security defense,
developers kept relying upon it as a security feature even though it was
always possible to access arbitrary JavaScript code if a malicious user
could control the content of Angular templates in applications.
This commit removes this sandbox, which has the following benefits:
* it sends a clear message to developers that they should not rely on
the sandbox to prevent XSS attacks; that they must prevent control of
expression and templates instead.
* it allows performance and size improvements in the core Angular 1
library.
* it simplifies maintenance and provides opportunities to make the
parser more capable.
Please see the [Sandbox Removal Blog Post](http://angularjs.blogspot.com/2016/09/angular-16-expression-sandbox-removal.html)
for more detail on what you should do to ensure that your application is
secure.
Closes#15094
This makes the largetable-bp ng-model benchmarks 10-15% faster (down 90-100ms for me). The actual controller instantiation doesn't change too much but the overall numbers seem consistently faster, I assume all due to reducing memory usage / gc. Specifically on creation there is ~40% less memory GCed, on destruction there is about ~25% less.
PR (#13286)
BREAKING CHANGE:
The use of prototype methods instead of new methods per instance removes the ability to pass
NgModelController and FormController methods without context.
For example
`$scope.$watch('something', myNgModelCtrl.$render)`
will no longer work because the `$render` method is passed without any context.
This must now be replaced with
```
$scope.$watch('something', function() {
myNgModelCtrl.$render();
})
```
or possibly by using `Function.prototype.bind` or `angular.bind`.
- Remove internal `makePromise()` helper.
- Remove unnecessary wrapper functions.
- Remove unnecessary check for promises resolving multiple times.
(By following the Promises/A+ spec, we know this will never happen.)
- Switch from function expressions to (named) function declarations.
Closes#15065
While sandboxed Chrome Packaged Apps (CPAs) have the same restrictions wrt
accessing `history.pushState` as "normal" CPAs, they can't be detected in the
same way, as they do not have access to the same APIs.
Previously, due to their differences from normal CPAs, `$sniffer` would fail to
detect sandboxed CPAs and incorrectly assume `history.pushState` is available
(which resulted in an error being thrown).
This commit fixes the detection of sandboxed CPAs in `$sniffer`.
See #11932 and #13945 for previous work.
Closes#15021
Fixes#14370
BREAKING CHANGE: For the jqLite element representing a select element in
the multiple variant with no options chosen the .val() getter used to return
null and now returns an empty array.
To migrate the code follow the example below:
Before:
HTML:
<select multiple>
<option>value 1</option>
<option>value 2</option>
</select>
JavaScript:
var value = $element.val();
if (value) {
/* do something */
}
After:
HTML:
<select multiple>
<option>value 1</option>
<option>value 2</option>
</select>
JavaScript:
var value = $element.val();
if (value.length > 0) {
/* do something */
}
A new option to enable/disable whether directive controllers are assigned bindings before
calling the controller's constructor.
If enabled (true), the compiler assigns the value of each of the bindings to the
properties of the controller object before the constructor of this object is called.
If disabled (false), the compiler calls the constructor first before assigning bindings.
The default value is enabled (true) in Angular 1.5.x but will switch to false in Angular 1.6.x.
See #14580Closes#15095
Update Internet Explorer-only helper function stripCustomNsAttrs to be less
recursive. Reduce stack height of function causing out of stack space error.
Closes#14928Closes#15030
window.isNaN(‘lol’); //=> true
Number.isNaN(‘lol’); //=> false
isNaN converts it’s arguments into a Number before checking if it’s NaN.
In various places in the code base, we are checking if a variable is a Number and
NaN (or not), so this can be simplified with this new method (which is not exported on the
global Angular object).
Closes#11242
Previously, you had to apply the complete set of ngModelOptions at every point where
you might want to modify just one or two settings.
This change allows more general settings to be applied nearer to the top of the DOM
and then for more specific settings to override those general settings further down
in the DOM.
Furher there is now a new service `$modelOptions` that acts as the top level options
that are inherited by all ngModelOptions directives that do not already have an
ngModelOptions ancestor directive.
Closes#10922
BREAKING CHANGE:
Previously, if a setting was not applied on ngModelOptions, then it would default
to undefined. Now the setting will be inherited from the nearest ngModelOptions
ancestor.
It is possible that an ngModelOptions directive that does not set a property,
has an ancestor ngModelOptions that does set this property to a value other than
undefined. This would cause the ngModel and input controls below this ngModelOptions
directive to display different behaviour. This is fixed by explictly setting the
property in the ngModelOptions to prevent it from inheriting from the ancestor.
For example if you had the following HTML:
```
<form ng-model-options="{updateOn: 'blur'}">
<input ng-model="...">
</form>
```
Then before this change the input would update on the default event not blur.
After this change the input will inherit the option to update on blur.
If you want the original behaviour then you will need to specify the option
on the input as well:
```
<form ng-model-options="{updateOn: 'blur'}">
<input ng-model="..." ng-model-options="{updateOn: 'default'}">
</form>
```
The programmatic API for `ngModelOptions` has changed. You must now read options
via the `getOption` method, rather than accessing the option directly as a property
of the options object. This does not affect the usage in templates and only
affects custom directives that might have been reading options for their own purposes.
This allows the removal of try/catch from addDirective to avoid V8 deopt.
Previously the directive.restrict property was not validated. This would
potentially cause exceptions on each compilation of the directive
requiring a try/catch and potentially causing repeated errors.
New validation when directive.restrict is specified:
* must be a string
* must contain at least one valid character (E, A, C, M)
Cases which previously silently failed (now throw an error):
* values with an indexOf method (such as strings, arrays) which returned
returned -1 for all valid restrict characters
Cases which previously worked unintentionally (now throw an error):
* arrays with single-character strings of valid restrict characters
PR (#13263)
Previously the following would invoke the element link function multiple
times, causing unknown and potentially buggy results:
var link = $compile(html);
link(scope);
link(scope);
This was always unsupported. Now this throws a multilink error.
PR (#13422)
- when the model does not match any option, the select generates an unknown option with the value
'? hashedModelVal ?' (select) or simply '?' (ngOptions) and inserts it into the select. This
option is then auto-selected by the browser. Once the user selects an option / the application sets
a matching model, the unknown option is removed from the select. It is therefore not user-selectable.
Alternatively, the application can provide an option with the value='', the so-called empty option.
The empty option takes over the role of the unknown option, in that it is selected when there's no
matching model, but it is not removed when a option and model match, and it can also be selected by
the user. The empty option has the value='' and sets the model to if selected.
Previously, these concepts where a bit mushy, especially in ngOptions.
This fix now delegates the bulk of the work to the selectCtrl, as the concept of unknown and empty
option are the same for both directives. Only the generation of the empty option is different.
The commit also adjusts a test for an officially unsupported use-case: multiple empty options.
The new behavior is that the empty option that is registered last is used. The other one is still
present. Otherwise, this behavior is unspecified, and the docs are clear that only a single empty
option is allowed. We support dynamically generated empty options, but not multiple ones. I've left
the test to highlight that this might be someone's use case, and the we are aware of it.
Previously, video, audio, and track sources were $sce.RESOURCE_URL. This is not justified as
no attacks are possible through these attributes as far as I can tell. This change is not
breaking, and uses of $sce.trustAsResourceUrl before assigning to src or ng-src attributes
will just be silently ignored.
This reverts commit 485320129d, because I did not author most of
this commit. I merged via Github and for some reason it used the last commit in a series of commits
to establish the author.
Previously, video, audio, source, and track sources were $sce.RESOURCE_URL. This is not justified as
no attacks (script execution) are possible through these attributes as far as we can tell. Angular2 also uses the same categorization.
This change is not breaking, and uses of $sce.trustAsResourceUrl before assigning to src or ng-src attributes will just be silently ignored.
This has also been given a LGTM by @mprobst via email.
PR (#15039)
Closes#14019
As explained in #11781 and #14924, IE11 can (under certain circumstances) break up a text node into
multiple consecutive ones, breaking interpolated expressions (e.g. `{{'foo'}}` would become
`{{` + `'foo'}}`). To work-around this IE11 bug, #11796 introduced extra logic to merge consecutive
text nodes (on IE11 only), which relies on the text nodes' having the same `parentNode`.
This approach works fine in the common case, where `compileNodes` is called with a live NodeList
object, because removing a text node from its parent will automatically update the latter's
`.childNodes` NodeList. It falls short though, when calling `compileNodes` with either a
jqLite/jQuery collection or an Array. In fails in two ways:
1. If the text nodes do not have a parent at the moment of compiling, there will be no merging.
(This happens for example on directives with `transclude: {...}`.)
2. If the text nodes do have a parent, just removing a text node from its parent does **not** remove
it from the collection/array, which means that the merged text nodes will still get compiled and
linked (and possibly be displayed in the view). E.g. `['{{text1}}', '{{text2}}', '{{text3}}']`
will become `['{{text1}}{{text2}}{{text3}}', '{{text2}}', '{{text3}}']`.
--
This commit works around the above problems by:
1. Merging consecutive text nodes in the provided list, even if they have no parent.
2. When merging a text node, explicitly remove it from the list (unless it is a live, auto-updating
list).
This can nonetheless have undesirable (albeit rare) side effects by overzealously merging text
nodes that are not meant to be merged (see the "BREAKING CHANGE" section below).
Fixes#14924Closes#15025
BREAKING CHANGE:
**Note:** Everything described below affects **IE11 only**.
Previously, consecutive text nodes would not get merged if they had no parent. They will now, which
might have unexpectd side effects in the following cases:
1. Passing an array or jqLite/jQuery collection of parent-less text nodes to `$compile` directly:
```js
// Assuming:
var textNodes = [
document.createTextNode('{{'),
document.createTextNode('"foo"'),
document.createTextNode('}}')
];
var compiledNodes = $compile(textNodes)($rootScope);
// Before:
console.log(compiledNodes.length); // 3
console.log(compiledNodes.text()); // {{'foo'}}
// After:
console.log(compiledNodes.length); // 1
console.log(compiledNodes.text()); // foo
// To get the old behavior, compile each node separately:
var textNodes = [
document.createTextNode('{{'),
document.createTextNode('"foo"'),
document.createTextNode('}}')
];
var compiledNodes = angular.element(textNodes.map(function (node) {
return $compile(node)($rootScope)[0];
}));
```
2. Using multi-slot transclusion with non-consecutive, default-content text nodes (that form
interpolated expressions when merged):
```js
// Assuming the following component:
.compoent('someThing', {
template: '<ng-transclude><!-- Default content goes here --></ng-transclude>'
transclude: {
ignored: 'veryImportantContent'
}
})
```
```html
<!-- And assuming the following view: -->
<some-thing>
{{
<very-important-content>Nooot</very-important-content>
'foo'}}
</some-thing>
<!-- Before: -->
<some-thing>
<ng-transclude>
{{ <-- Two separate
'foo'}} <-- text nodes
</ng-transclude>
</some-thing>
<!-- After: -->
<some-thing>
<ng-transclude>
foo <-- The text nodes were merged into `{{'foo'}}`, which was then interpolated
</ng-transclude>
</some-thing>
<!-- To (visually) get the old behavior, wrap top-level text nodes on -->
<!-- multi-slot transclusion directives into `<span>` elements; e.g.: -->
<some-thing>
<span>{{</span>
<very-important-content>Nooot</very-important-content>
<span>'foo'}}</span>
</some-thing>
<!-- Result: -->
<some-thing>
<ng-transclude>
<span>{{</span> <-- Two separate
<span>'foo'}}</span> <-- nodes
</ng-transclude>
</some-thing>
```
In HTML5 mode, links can now be selectively rewritten, by setting `mode.rewriteLinks` to a string
(denoting an attribute name). Anchor elements that have the specified attribute will be rewritten,
while other links will remain untouched.
This can be useful in situations where it is desirable to use HTML5 mode without a `<base>` tag, but
still support rewriting specific links only. See #14959 for more details on a possible usecase.
Closes#14976
The example seems to also be filtering by age. It threw me off a bit because I was getting results when I entered numbers in the input field.
PR (#15037)
input[number] will now set the step error if the input value
(ngModel $viewValue) does not fit the step constraint set in the step / ngStep attribute.
Fixes#10597
Step support works like min / max, but with the following caveat.
Currently, only Firefox fully implements the spec. Other browsers
(Chrome, Safari, Edge) have issues when the step value changes
after the input has been changed. They do not adjust the input value
to a valid value, but instead set the stepMismatch validity state.
Angular will take this validity state, and forward it as the ngModel
"step" error. Adjusting the error ourselves would add too much code,
as the logic is quite involved.
This commit fixes the handling of min/max, and removes support for ngMin/ngMax:
min/max:
Previously, interpolated min/max values on input range were not set when the first $render happens,
because the interpolation directive only sets the actual element attribute value after
a digest passes. That means that the browser would not adjust
the input value according to min/max and the range input and model would
not be initialzed as expected.
With this change, input range will set the actual element attribute value during its own
linking phase, as it is already available on the attrs argument passed to the link fn.
ngMin/ngMax
Since ng prefixed attributes do not set their corresponding element attribute, the range input would always have min = 0, and max = 100 (in supported browsers), regardless of the value
in ngMin/ngMax. This is confusing and not very useful, so it's better to not support these attributes at all.
The commit also fixes a test which used an interpolation inside an attribute that expects an expression.
Fixes#14982
PR (#14996)
Previously, it would throw the ng:areq error, which is less
specific and just informs that the requested controller is not defined.
Given how commonly controllers are used
in Angular, it makes sense to have a specific error.
The ng:areq error is still thrown when the registered controller
is not a function.
Closes#14980
PR (#15015)
During the `build` task, the version placeholders will be replaced with the actual values using a
RegExp, which expects the placeholders to be surrounded by double quotes. By replacing the quotes
from double to single in #15011, the RegExp was not able to match the placeholders.
(For reference, the RegExps that match and replace the version placeholders are in
[lib/grunt/utils.js][1].)
[1]: https://github.com/angular/angular.js/blob/859348c7f61ff5f93b9f81eb7f46842bd018d8e3/lib/grunt/utils.js#L125-L130Closes#15016
The quotes rule had to be disabled for e2e tests generated from ngdoc
because dgeni templates use double quotes as string delimiters.
Since we can't have guarantees that dgeni template wrappers will follow
the same JS code style the Angular 1 repo uses, we should find a way
to enforce our ESLint setup only for the parts in this repo, perhaps
via prepending a generated `/* eslint-enable OUR_RULES */` pragma.
Closes#15011
Input elements use the value attribute as their default value if the value property is not set.
Once the value property has been set (by adding input), it will not react to changes to
the value attribute anymore. Setting both attribute and property fixes this behavior, and
makes it possible to use ngValue as a one-way bind.
Closes#14031Closes#13984
POSSIBLE BREAKING CHANGE:
`ngValue` now also sets the value *property* of its element. Previously, it would only set the
value *attribute*. This allows `ngValue` to be used as a one-way binding mechanism on `input[text]`
and `textarea` elements without `ngModel`. Previously, these input types would not update correctly
when only the value attribute was changed.
This change should not affect any applications, as `ngValue` is mainly used on `input[radio]` and
`option` elements, both of which are unaffected by this change.
Previously, requests were flushed in the order in which they were made.
With this change, it is possible to flush requests in any order. This is useful for simulating more
realistic scenarios, where parallel requests may be completed in any order.
Partially addresses #13717.
Closes#14967
When using the [timeout attribute](https://xhr.spec.whatwg.org/#the-timeout-attribute) and an XHR
request times out, browsers trigger the `timeout` event (and execute the XHR's `ontimeout`
callback). Additionally, Safari 9 handles timed-out requests in the same way, even if no `timeout`
has been explicitly set on the XHR.
In the above cases, `$httpBackend` would fail to capture the XHR's completing (with an error), so
the corresponding `$http` promise would never get fulfilled.
Note that using `$http`'s `timeout` configuration option does **not** rely on the XHR's `timeout`
property (or its `ontimeout` callback).
Fixes#14969Closes#14972
Related to #14952. Fixed the following warnings/errors:
1. **Warning**: Closure Compiler complained about `/* @this */` (annotations in non-JSDoc comments).
Fixed by changing `/* @this */` to `/** @this */`.
2. **Warning**: Dgeni complained about `/** @this */` (invalid tags found).
Fixed by adding an empty `this` tag definition in `docs/config/tag-defs/`.
3. **Error**: ESLint complained about CRLF linebreaks in `build/docs/examples/`. These are generated
by dgeni and (apparently) use the system's default linebreak (e.g. CRLF on Windows).
Fixed by disabling the `linebreak-style` rule for `build/docs/examples/`.
Closes#14997
Previously, `ngAria` would overwrite the default `ngModelController.$isEmpty()` method for custom
`checkbox`-shaped controls (e.g. `role="checkbox"` or `role="menuitemcheckbox"`), using the same
implementation as `input[checkbox]` (i.e. `value === false`). While this makes sense for
`input[checkbox]` which also defines a custom parser, it doesn't make sense for a custom `checkbox`
out-of-the-box. For example, an unintialized value (`undefined`) would make the checkbox appear as
"checked".
If the user wants to provide a custom parser (e.g. setting falsy values to `false`), then they
should also provide a custom `$isEmpty()` method.
As a side effect, this commit solves issue #14621. (We could have solved it in different ways.)
Fixes#14621Closes#14625
BREAKING CHANGE:
Custom `checkbox`-shaped controls (e.g. checkboxes, menuitemcheckboxes), no longer have a custom
`$isEmpty()` method on their `NgModelController` that checks for `value === false`. Unless
overwritten, the default `$isEmpty()` method will be used, which treats `undefined`, `null`, `NaN`
and `''` as "empty".
**Note:** The `$isEmpty()` method is used to determine if the checkbox is checked ("not empty" means
"checked") and thus it can indirectly affect other things, such as the control's validity
with respect to the `required` validator (e.g. "empty" + "required" --> "invalid").
Before:
```js
var template = '<my-checkbox role="checkbox" ng-model="value"></my-checkbox>';
var customCheckbox = $compile(template)(scope);
var ctrl = customCheckbox.controller('ngModel');
scope.$apply('value = false');
console.log(ctrl.$isEmpty()); //--> true
scope.$apply('value = true');
console.log(ctrl.$isEmpty()); //--> false
scope.$apply('value = undefined'/* or null or NaN or '' */);
console.log(ctrl.$isEmpty()); //--> false
```
After:
```js
var template = '<my-checkbox role="checkbox" ng-model="value"></my-checkbox>';
var customCheckbox = $compile(template)(scope);
var ctrl = customCheckbox.controller('ngModel');
scope.$apply('value = false');
console.log(ctrl.$isEmpty()); //--> false
scope.$apply('value = true');
console.log(ctrl.$isEmpty()); //--> false
scope.$apply('value = undefined'/* or null or NaN or '' */);
console.log(ctrl.$isEmpty()); //--> true
```
--
If you want to have a custom `$isEmpty()` method, you need to overwrite the default. For example:
```js
.directive('myCheckbox', function myCheckboxDirective() {
return {
require: 'ngModel',
link: function myCheckboxPostLink(scope, elem, attrs, ngModelCtrl) {
ngModelCtrl.$isEmpty = function myCheckboxIsEmpty(value) {
return !value; // Any falsy value means "empty"
// Or to restore the previous behavior:
// return value === false;
};
}
};
})
```
There was a ~5% improvement in the added `parsed-expressions-bp/assignment` benchmark (which only
contains assignment expressions). In real-world applications, the time spent in assignment
expressions will be a tiny fragment of the overall processing time, though.
Closes#14957
Since the style directive is defined as a non-terminal element directive
with no behavior on link, we may as well not define anything at all.
PR (#14983)
When the functions `cssClassDirectivesEnabled()` / `commentDirectivesEnabled()` on the `$compileProvider` are called with `false`, then the compiler won't look for directives on css classes / comment elements.
This can result in a compilation speed-up of around 10%.
PR (#14850)
The Jenkins build.sh script has to be updated as the previous way of
specifying parameters to the code run in Grunt tasks stopped working
with the newest Grunt. This has been previously fixed for the Travis
build.sh but wasn't done for the Jenkins one.
Also, the contribute docs were updated to account for the new format.
If one uses nvm to manage Node.js versions, the .nvmrc file makes `nvm use`
switch to the version specified in .nvmrc. There are scripts that invoke
it automatically when cd'ing to directories containing .nvmrc so that you
never run build commands using a wrong Node version, see:
https://github.com/creationix/nvm/blob/v0.31.2/README.markdown#zsh
The Travis build.sh script has to be updated as the previous way of
specifying parameters to the code run in Grunt tasks stopped working
with the newest Grunt.
Thanks to @cironunes for the initial implementation in https://github.com/angular/angular.js/pull/9715
Adds support for binding to input[range] with the following behavior / features:
- Like input[number], it requires the model to be a Number, and will set the model to a Number
- it supports setting the min/max values via the min/max and ngMin/ngMax attributes
- it follows the browser behavior of never allowing an invalid value. That means, when the browser
converts an invalid value (empty: null, undefined, false ..., out of bounds: greater than max, less than min)
to a valid value, the input will in turn set the model to this new valid value via $setViewValue.
-- this means a range input will never be required and never have a non-Number model value, once the
ngModel directive is initialized.
-- this behavior is supported when the model changes and when the min/max attributes change in a way
that prompts the browser to update the input value.
-- ngMin / ngMax do not prompt the browser to update the values, as they don't set the attribute values.
Instead, they will set the min / max errors when appropriate
- browsers that do not support input[range] (IE9) handle the input like a number input (with validation etc.)
Closes#5892Closes#9715Close#14870
The docs for `$compile` were updated in e235f20 to include information about the recently
implemented `$doCheck` lifecycle hook for component controllers. The lifecycle hook documentation is
mirrored in the Component guide, and this change mirrors the update made to the `$compile` docs, to
the component guide docs.
Closes#14946
When the select model changes, we add the "selected" attribute to the selected option, so that
screen readers know which option is selected.
Previously, we failed to remove the attribute from the selected / empty option when the model changed
to match a different option, or the unknown / empty option.
When using "track by", the behavior would also show when a user selected an option, and then the
model was changed, because track by watches the tracked expression, and calls the $render function
on change.
This fix reads the current select value, finds the matching option and removes the "selected"
attribute.
IE9 had to be special cased, as it will report option.hasAttribute('selected') === true even
if the option's property and attribute have been unset (even the dev tools show not selected attribute).
I've added a custom matcher that accounts for this behavior. In all other browsers, property and
attribute should always be in the same state. Since few people will use screen readers with IE9, I
hope this is a satisfactory solution to the problem.
Fixes#14892Fixes#14419
Related #12731
PR (#14894)
The test currently fail on master, but should pass on 1.5.x.
A subsequent commit will fix the regressions on master.
(This commit should be backportable to 1.5.x.)
Related to #14837.
During its linking phase, `ngView` relies on the info provided in `$route.current` for
instantiating the initial view. `$route.current` is set in the callback of a listener to
`$locationChangeSuccess`, which is registered during the instantiation of the `$route` service.
Thus, it is crucial that the `$route` service is instantiated _before_ the initial
`$locationChangeSuccess` event is fired. Since `ngView` declares `$route` as a dependency, the
service is instantiated in time, if `ngView` is present during the initial load of the page.
Yet, in cases where `ngView` is included in a template that is loaded asynchronously (e.g. in
another directive's template), the directive factory might not be called soon enough for `$route`
to be instantiated before the initial `$locationChangeSuccess` event is fired.
This commit fixes it, by enabling eager instantiation of `$route` (during the initialization phase).
Eager instantiation can be disabled (restoring the old behavior), but is on by default.
Fixes#1213Closes#14893
BREAKING CHANGE:
In cases where `ngView` was loaded asynchronously, `$route` (and its dependencies; e.g. `$location`)
might also have been instantiated asynchronously. After this change, `$route` (and its dependencies)
will - by default - be instantiated early on.
Although this is not expected to have unwanted side-effects in normal application bebavior, it may
affect your unit tests: When testing a module that (directly or indirectly) depends on `ngRoute`, a
request will be made for the default route's template. If not properly "trained", `$httpBackend`
will complain about this unexpected request.
You can restore the previous behavior (and avoid unexpected requests in tests), by using
`$routeProvider.eagerInstantiationEnabled(false)`.
Calling `promise.finally(...)` creates a new promise. If we don't return this promise, the user
won't be able to attach an error handler to it and thus won't be able to prevent a potential PUR
error.
This commit also improves the test coverage for the increment/decrement `outstandingRequestCount`
fix.
Closes#13869Closes#14921
Calling `$http` will not increment `$browser.outstandingRequestCount` until after all (potentially)
asynchronous request interceptors have been processed and will decrement it before any (potentially)
asynchronous response interceptors have been processed.
This can lead to `$browser.notifyWhenNoOutstandingRequests` firing
prematurely, which can be problematic in end-to-end tests.
This commit fixes this, by synchronizing the increment/decrement
operations with `$http`'s internal interceptor promise chain.
Fixes#13782Closes#13862Closes#14921
BREAKING CHANGE:
HTTP requests now update the outstanding request count synchronously.
Previously the request count would not have been updated until the
request to the server is actually in flight. Now the request count is
updated before the async interceptor is called.
The new behaviour is correct but it may change the expected behaviour in
a small number of e2e test cases where an async request interceptor is
being used.
Add a section inside of the ngAnimate documentation to point to $animate.pin().
It was not clear in the documentation why animations were being disabled inside of
modals and popup menus. This documentation explains in what situations elements may
be dynamically placed outside of the application DOM and points to the API documentation
on how to enable animations for these types of elements.
Related #14907Closes#14918
Firing a digest at the beginning of the verification process, ensures that requests fired
asynchronously - e.g. in the `resolve` handler of a promise as happens with `$http` - will get
detected as well.
Previously, in order to reliably verify that there was no outstanding request, users needed to
manually trigger a digest, before calling `verifyNoOutstandingRequest()`. Failing to do so, could
prevent `verifyNoOutstandingRequest()` from detecting pending requests and cover bugs in application
code.
This is no longer the case, since a digest will always be fired autommatically as part of a call to
`verifyNoOutstandingRequest()`.
Fixes#13506Closes#13513
BREAKING CHANGE:
Calling `$httpBackend.verifyNoOutstandingRequest()` will trigger a digest. This will ensure that
requests fired asynchronously will also be detected (without the need to manually trigger a digest).
This is not expected to affect the majority of test-suites. Most of the time, a digest is (directly
or indirectly) triggered anyway, before calling `verifyNoOutstandingRequest()`.
In the unlikely case that a test needs to verify the timing of a request with respect to the digest
cycle, you should rely on other means, such as mocking and/or spying.
When option elements use ngValue, value or interpolated text to set
the option value, i.e. when the parent select doesn't have an ngModel,
there is no necessity in registering the options with the select controller.
The registration was usually not a problem, as the ngModelController is set to a noop controller,
so that all further interactions are aborted ($render etc)
However, since f02b707 ngValue sets a hashed value inside the option value
(to support arbitrary value types). This can cause issues with tests that expect unhashed values.
The issue was found in angular-material, which uses select + ngValue to populate mdSelect.
POSSIBLE BREAKING CHANGE:
Option elements will no longer set their value attribute from their text value when their select
element has no ngModel associated. Setting the value is only needed for the select directive to
match model values and options. If no ngModel is present, the select directive doesn't need it.
This should not affect many applications as the behavior was undocumented and not part of a public
API. It also has no effect on the usual HTML5 behavior that sets the select value to the option text
if the option does not provide a value attribute.
PR (#14864)
Previously, `ngAria` would provide keyboard support for non-native buttons (via `ngClick`), by
binding the `ngClick` handler to the `keypress` event. In an attempt to better emulate the behavior
of native buttons, `ngAria` will now bind to the `keydown` event (instead of `keypress`).
The configuration flag for this feature has been renamed from `bindKeypress` to `bindKeydown`, to
closer describe the underlying behavior.
Fixes#14063Closes#14065
BREAKING CHANGE:
If you were explicitly setting the value of the `bindKeypress` flag, you need to change your code to
use `bindKeydown` instead.
Before: `$ariaProvider.config({bindKeypress: xyz})`
After: `$ariaProvider.config({bindKeydown: xyz})`
**Note:**
If the element already has any of the `ngKeydown`/`ngKeyup`/`ngKeypress` directives, `ngAria` will
_not_ bind to the `keydown` event, since it assumes that the developer has already taken care of
keyboard interaction for that element.
Although it is not expected to affect many applications, it might be desirable to keep the previous
behavior of binding to the `keypress` event instead of the `keydown`. In that case, you need to
manually use the `ngKeypress` directive (in addition to `ngClick`).
Before:
```html
<div ng-click="onClick()">
I respond to `click` and `keypress` (not `keydown`)
</div>
```
After:
```html
<div ng-click="onClick()" ng-keypress="onClick()">
I respond to `click` and `keypress` (not `keydown`)
</div>
<!-- OR -->
<div ng-click="onClick()">
I respond to `click` and `keydown` (not `keypress`)
</div>
```
Finally, it is possible that this change affects your unit or end-to-end tests. If you are currently
expecting your custom buttons to automatically respond to the `keypress` event (due to `ngAria`),
you need to change the tests to trigger `keydown` events instead.
Previously, a property would not be passed as query param, if `Object.prototype` had a property with
the same name.
Fixes#14866Closes#14867
BREAKING CHANGE:
All owned properties of the `params` object that are not used to replace URL params, will be passed
to `$http` as `config.params` (to be used as query parameters in the URL), even if
`Object.prototype` has a property with same name. E.g.:
Before:
```js
var Foo = $resource('/foo/:id');
Foo.get({id: 42, bar: 'baz', toString: 'hmm'});
// URL: /foo/42?bar=baz
// Note that `toString` is _not_ included in the query,
// because `Object.prototype.toString` is defined :(
```
After:
```js
var Foo = $resource('/foo/:id');
Foo.get({id: 42, bar: 'baz', toString: 'hmm'});
// URL: /foo/42?bar=baz&toString=hmm
// Note that `toString` _is_ included in the query, as expected :)
```
Prior to this point, the docs do not mention returning a postLink function, and all the examples use
the definition object form. So, this message is confusing to new readers who may misinterpret
"returning a function" as returning the factory function mentioned in the previous section.
Since this page is only a "gentle introduction" to directives, and using the definition object is a
best practice, it is best to just remove the message altogether.
Closes#14871
Previously, it would return a copy of the whole original typed array, not its slice.
Now, the `byteOffset` and `length` are also preserved.
Fixes#14842Closes#14845
This also improves the example a bit:
- better code formatting
- initialization of `form` to an empty object
- avoid using `email`, which doesn't get coppied when invalid (and might confuse users)
Fixes#14853
These rules follow ngOptions behavior:
- when an option that is currently selected, is removed or its value changes, the model
is set to null.
- when an an option is added or its value changes to match the currently selected model,
this option is selected.
- when an option is disabled, the model is set to null.
- when the model value changes to a value that matches a disabled option,
this option is selected (analogue to ngOptions)
select elements with ngModel will now set ngModel to option values added by ngValue.
This allows setting values of any type (not only strings) without the use of ngOptions.
Interpolations inside attributes can only be strings, but the ngValue directive uses attrs.$set,
which does not have any type restriction. Any $observe on the value attribute will therefore receive
the original value (result of ngValue expression). However, when a user selects an option, the browser
sets the select value to the actual option's value attribute, which is still always a string.
For that reason, when options are added by ngValue, we set the hashed value of the original value in
the value attribute and store the actual value in an extra map. When the select value changes, we
read access the actual value via the hashed select value.
Since we only use a hashed value for ngValue, we will have extra checks for the hashed values:
- when options are read, for both single and multiple select
- when options are written, for multiple select
I don't expect this to have a performance impact, but it should be kept in mind.
Closes#9842Closes#6297
BREAKING CHANGE:
`<option>` elements added to `<select ng-model>` via `ngValue` now add their values in hash form, i.e.
`<option ng-value="myString">` becomes `<option ng-value="myString" value="string:myString">`.
This is done to support binding options with values of any type to selects.
This should rarely affect applications, as the values of options are usually not relevant to the
application logic, but it's possible that option values are checked in tests.
The official and external resources have been split into two different guide sections. Official stays at the index, external gets its own page.
The external resources have also been reorganized and updated, but
I haven't checked if all material is still relevant.
Change `ErrorAddingDeclarationLocationStack`'s prototype so test frameworks (such as Jasmine 2.x)
are able to recognize it as `Error`.
Fixes#13821Closes#14344
Fixes#11716
BREAKING CHANGE:
`ngBind` now uses the same logic as $interpolate (i.e. {{myString}}) when
binding, which means values other than strings are now transformed as following:
- null / undefined become empty string
- with an object's custom toString() function, except if the object is a Date, Array, or Number
- otherwise with JSON.stringify
Previously, ngBind would use always use toString().
The following examples show the different output:
```js
$scope.myPlainObject = {a: 1, b: 2};
$scope.myCustomObject = {a: 1, b: 2, toString: function() {return 'a+b';}};
```
Plain Object:
```html
<!-- Before: -->
<span ng-bind="myPlainObject">[object Object]</span>
<!-- After: -->
<span ng-bind="myPlainObject">{"a":1,"b":2}</span>
```
Object with custom toString():
```html
<!-- Before: -->
<span ng-bind="myCustomObject">[object Object]</span>
<!-- After: -->
<span ng-bind="myCustomObject">a+b</span>
```
If you want the output of `toString()`, you can use it directly on the value in ngBind:
```html
<span ng-bind="myObject.toString()">[object Object]</span>
```
Except on Numbers, Dates and Arrays.
Thanks to @danielkrainas for the initial implementation of this feature.
This behavior is consistent with implementations found in other languages such as Ruby, Python,
and CoffeeScript.
http://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basicshttps://docs.python.org/2/library/stdtypes.html#string-formatting-operationshttp://coffeescriptcookbook.com/chapters/strings/interpolation
The commit also exposes a private $$stringify method on the angular global, so that ngMessageFormat
can use the same logic without duplicating it.
Fixes#7317Closes#8350Fixes#11406
BREAKING CHANGE:
When converting values to strings, interpolation now uses a custom toString() function on objects
that are not Number, Array or Date (custom means that the `toString` function is not the same as
`Object.prototype.toString`). Otherwise, interpolation uses JSON.stringify() as usual.
Should you have a custom toString() function but still want the output of JSON.stringify(),
migrate as shown in the following examples:
Before:
```html
<span>{{myObject}}</span>
```
After - use the `json` filter to stringify the object:
```html
<span>{{myObject | json}}</span>
```
The unencoding happens in methods `encodeUriQuery`/`encodeUriSegment`. Both core and `ngResource`
used to have identical implementations of these methods. Due to this duplication, the
implementations got out-of-sync.
Specifically, the semicolon has been added to the whitelist of unencoded characters in core since
`v1.3.0-beta.18`. See 3625803 for more info.
This commit fixes the problem and the underlying cause by reusing core's methods in `ngResource`.
(The methods are exposed as private helpers on `window.angular`.)
Closes#14309
Also affects the reverse case, adding a class that is scheduled to be removed with rAF.
The following case can happen when ngClass updates an element's classes in very quick order in the following way:
- First animation adds class "a"
- A digest passes, but "a" is not yet added to the element
- Second animation adds class "b"
- No digest passes, and "a" is still not added to the element,
because requestAnimationFrame hasn't been flushed yet
- Third animation removes class "a"
- the third animation gets merged into the second animation
Before this change:
- Because the element doesn't have class "a" yet, ngAnimate
resolves that it cannot remove class "a". However,
the first animation is still running, and finally adds "a"
After this change:
- ngAnimate reacts to the temporary class "add-a", which indicates
that "a" is about to be added and decides that "a" can be removed
after all.
This is a very rare case where setting the element's class
is not fast enough, and subsequent animations operate on incorrect assumptions.
"In the wild", this is caused by rapidly updating ngClass,
which uses inidvidual addClass and removeClass calls when both operations happen in a single digest.
Fixes#14582
PR (#14760)
You can now override this service if you have specific requirements about
the behaviour and formatting of the JSON_CALLBACK that is sent to the server
for `$http.jsonp` requests.
Closes#14795
Some modules used to assume that the angular helpers would always be available when their script was
executed. This could be a problem when using `angular-loader` and the module file happened to get
loaded before the core `angular.js` file.
This commit fixes the issue by delaying the access to angular helpers, until they are guaranteed to
be available.
Affected modules:
- `ngAnimate`
- `ngMessageFormat`
- `ngMessages`
- `ngRoute`
- `ngSanitize`
Fixes#9140Closes#14794
Implement $q.race. $q.race takes in an array or hash of promises and
returns a promise that resolves or rejects as soon as one of those promises
resolves or rejects, with the value or reason from that promise.
Closes#12929Closes#14757
Previously, the special property name that would match against any
property was hard-coded to `$`.
With this commit, the user can specify an arbitrary property name,
by passing a 4th argument to `filterFilter()`. E.g.:
```js
var items = [{foo: 'bar'}, {baz: 'qux'}];
var expr = {'%': 'bar'};
console.log(filterFilter(items, expr, null, '%')); // [{foo: 'bar'}]
```
Fixes#13313
PR (#13356)
Since we cannot write to dev/null on Windows, don't write to a file at all, but simply use stdout and extract the output from --write-out from the process response. Credit to @petebacondarwin for the idea.
The commit also avoids a premature error when no cdnVersion could be found online, and improves the log wrt the origin of the versions.
PR (#14780)
If the instance of the directive does provide transcluded content, then the fallback
content should not be compiled and linked as it will never be used.
If the instance of the directive does not provide transcluded content, then the
transcluded scope that was created for this non-existent content is never used,
so it should be destroy in order to clean up unwanted memory use and digests.
Fixes#14768Fixes#14765Closes#14775
Previously it was slow and problematic to run builds if you were not connected
to the internet because the build scripts make requests to github and the
Google CDN to find out version information.
You can now disable these requests by setting the NG1_BUILD_NO_REMOTE_VERSION_REQUESTS
environment variable to a non-empty value
Closes#14769
We have had issues where the docs application has gone down because
our build included invalid URLs to the production angular libraries.
This change runs a subset of the docs e2e tests directly against these
production libraries to ensure that they are accessible. If not then these
tests will fail and the CI build will abort, preventing the docs app from
being updated.
Closes#14769
Some modules (ngMessageFormat, ngParseExt) don't have their own api surface
because they integrate with core services ($interpolate and $parse respectively).
Closes#14770
- Add note about using the value attribute for the progress tag with IE in the IE compat / interpolation guide
- Add note about placeholder attribute in textarea to the ie compat guide
Closes#7218
PR (#14753)
When the internet is not accessible build scripts are unnecessarily slow
because of failed attempts to download git tag and CDN version information
from remote servers.
This commit does a synchronous check of internet connectivity before attempting
any remote requests.
Closes#14759
While the `url` parameter is optional for `$httpBackend.when`,
`$httpBackend.expect` and related shortcut methods, it should not have the
value of `undefined` if it has been provided.
This change ensures that an error is thrown in those cases.
Closes#8442Closes#8462Closes#10934Closes#12777
BREAKING CHANGE
It is no longer valid to explicitly pass `undefined` as the `url` argument
to any of the `$httpBackend.when...()` and `$httpBackend.expect...()`
methods.
While this argument is optional, it must have a defined value if it is
provided.
Previously passing an explicit `undefined` value was ignored but this
lead to invalid tests passing unexpectedly.
Previously, ngMessage elements used the same scope as ngMessages. When ngMessage
has interpolation in the textContent, then removing the message would not remove
the watcher from the scope - it would only be removed when the whole ngMessages
element was removed.
This commit changes the ngMessage transclude function to create a new child scope
instead, which can be destroyed safely when the message element is removed and
the message is detached
Fixes#14307
PR (#14308)
`resolveRedirectTo` can be set to a function that will (eventually) return the new URL to redirect
to. The function supports dependency injection and should return the new URL either as a string or
as a promise that will be resolved to a string.
If the `resolveRedirectTo` function returns `undefined` or returns a promise that gets resolved to
`undefined`, no redirection will take place and the current route will be processed normally.
If the `resolveRedirectTo` function throws an error or the returned promise gets rejected, no
further processing will take place (e.g. no template fetched, no `resolve` functions run, no
controller instantiated) and a `$routeChangeError` will be broadcasted.
`redirectTo` takes precedence over `resolveRedirectTo`, so specifying both on the same route
definition, will cause the latter to be ignored.
Fixes#5150Closes#14695
BREAKING CHANGE:
Previously, if `redirectTo` was a function that threw an Error, execution was aborted without firing
a `$routeChangeError` event.
Now, if a `redirectTo` function throws an Error, a `$routeChangeError` event will be fired.
Deep-copying route definition objects can break specific custom implementations of `$sce` (used to
trust a `templateUrl` as RESOURCE_URL). The purpose of copying route definition objects was to guard
against the user's modifying the route definition object after route registration, while still
capturing inherited properties.
As suggested by @IgorMinar in https://github.com/angular/angular.js/pull/14699#discussion_r66480539,
we can achieve both _and_ support custom `$sce` implementations, by shallow-copying instead.
This is an alternative implementation for #14699, which avoids the breaking change.
Fixes#14478Closes#14699Closes#14750
User-controlled imports or stylesheets can run script in your origin,
which warrants that we require that they are safe `RESOURCE_URL`s.
Closes#14687
BREAKING CHANGE
`link[href]` attributes are now protected via `$sce`, which prevents interpolated
values that fail the `RESOURCE_URL` context tests from being used in interpolation.
For example if the application is running at `https://docs.angularjs.org` then the
following will fail:
```
<link href="{{ 'http://mydomain.org/unsafe.css' }}" rel="stylesheet">
```
By default, `RESOURCE_URL` safe URLs are only allowed from the same domain and protocol
as the application document.
To use URLs from other domains and/or protocols, you may either whitelist them or
wrap it into a trusted value by calling `$sce.trustAsResourceUrl(url)`.
`ngScenario` is deprecated, and we expect to remove it from the project in 1.6,
but we use the `browserTrigger` helper throughout our unit tests.
So in preparation for removing `ngScenario` we are relocating `browserTrigger`
to the `ngMock` folder.
Although many people are using browserTrigger in their own application testing
we are still not yet ready to make this a public API; so developers use
this helper at their own risk.
Closes#14718
BREAKING CHANGE
Although it is not a public API, many developers are using `browserTrigger`
in their own application testing. We have now moved this helper from
`ngScenario/browserTrigger.js` to `ngMock/browserTrigger.js`.
**Limit size of local-part and total path size in eMail addresses**
RFC 5321 §4.5.3.1.1 ⇒ local-part can have up to 64 octets
RFC 5321 §4.5.3.1.3 ⇒ path “including the punctuation and
element separators” can have up to 256 octets
RFC 5321 §4.1.2 specifies path as ‘<’ + mailbox¹ + ‘>’ in
the best case, leaving us 254 octets
The limitation of the total path size to 254 octets leaves
at most 252 octets (one local-part, one ‘@’) for the domain,
which means we don’t need to explicitly check the domain
size any more (removing the assertion after the ‘@’).
① RFC 821/5321 “mailbox” is the same as RFC 822 “addr-spec”
**Optimise eMail address regex for speed**
There is no need to make it case-insensitive; the local-part
already catches the entire range, and the host part is easily
done. Furthermore, this makes the regex locale-independent,
avoiding issues with e.g. turkish case conversions.
cf. http://www.mirbsd.org/cvs.cgi/contrib/hosted/tg/mailfrom.php?rev=HEAD
**Limit eMail address total host part length**
RFC 1035 §2.3.4 imposes a maximum length for any DNS object;
RFC 5321 §2.3.5 references this (and requires FQDNs, but there
have been cases where a TLD had an MX RR and thus eMail addresses
like “localpart@tld” are valid).
Credits: Natureshadow <d.george@tarent.de>
**Limit eMail address individual host part length**
A “label” (each of the things between the dots (‘.’) after the ‘@’ in
the eMail address) MUST NOT be longer than 63 characters.
cf. http://www.mirbsd.org/cvs.cgi/contrib/hosted/tg/mailfrom.php?rev=HEAD
and RFC 1035 §2.3.4
**Fix eMail address local-part validation**
A period (‘.’) may not begin or end a local-part
cf. http://www.mirbsd.org/cvs.cgi/contrib/hosted/tg/mailfrom.php?rev=HEAD
and RFC 822 / 5321
Closes#14719
This allows developers to use white-space in their attributes, for example as value for
input[type=radio], as a separator in ngList, or as a value in any custom directive binding.
It's also consistent with the HTML spec, which allows white-space in attributes, and consistent
with Angular2, which also allows white-space in attributes.
Fixes#5513Fixes#14539Closes#5597
BREAKING CHANGE:
White-space in attributes is no longer trimmed automatically. This includes leading and trailing
white-space, and attributes that are purely white-space.
To migrate, attributes that require trimming must now be trimmed manually.
A common cases where stray white-space can cause problems is when
attribute values are compared, for example in an $observer:
Before:
```
$attrs.$observe('myAttr', function(newVal) {
if (newVal === 'false') ...
});
```
To migrate, the attribute value should be trimmed manually:
```
$attrs.$observe('myAttr', function(newVal) {
if (newVal.trim() === 'false') ...
});
```
Note that `$parse` trims expressions automatically, so attributes with expressions (e.g. directive
bindings) are unlikely to be affected by stray white-space.
In replace directives, attribute values from the template are added twice
to the replaced element when both the replaced element and the template
element have the attribute. This does not affect the DOM, as it normalizes
duplicate values. The values are however duplicated in the $attrs object
that is available to directive link functions.
Fixes#8159Closes#14737
The decorated version of `$controller` is able to assign bindings to a controller instance prior to
instantiation, emulating the behavior of `$compile` with directive controllers.
There are cases, that the actual controller instance is different than the pre-populated one (e.g.
when the controller constructor function returns a value or when the controller is an ES2015 Class).
While `$compile` accounts for such situation, by re-asigning the bindings after the controller has
been instantiated, `ngMock`'s `$controller` didn't.
This commit fixes it, by re-applying the bindings if the actual controller instance is different
than the original one (similar to how `$compile` would do it).
Fixes#14437Closes#14439
Add an optional, 4th argument (`comparator`) for specifying a custom comparator function, used to
compare the values returned by the predicates. Omitting the argument, falls back to the default,
built-in comparator. The 3rd argument (`reverse`) can still be used for controlling the sorting
order (i.e. ascending/descending).
Additionally, the documentation has been expanded to cover the algorithm used by the built-in
comparator and a few more unit and e2e tests (unrelated to the change) have been added.
Helps with #12572 (maybe this is as close as we want to get).
Fixes#13238Fixes#14455Closes#5123Closes#8112Closes#10368Closes#14468
Initialize `$$absUrl` to an empty string, in order to avoid exception, when base href
and current location have different domains.
Fixes#11091Fixes#13565Closes#14488
In some browsers, events don't bubble when they are dispatched on node inside
a detached tree. When this is the case, the bubbling is made manually.
This may be convenient when unit testing directives, for example.
Closes#5178
Allow $httpBackend.passThrough() to work normally when ngMock is loaded
concurrently with ngMockE2E, as is typically the case when writing tests with
angular.mock.module()
Fixes#1434Closes#13124
The previous example overwrote the `$exceptionHandler` in order to re-throw the error. This is not
recommended, since it would leave the application in an inconsistent state and prevent proper
clean-up.
The new example simulates logging the error both to the backend and the console.
Fixes#14704
Previously, it was just `undefined` and had the same behavior (since we only check for falsy-ness).
Just making it explicit, that this property is also available on `defaults` and is "not true" by
default.
Closes#14711
In the Chrome issue (https://bugs.chromium.org/p/chromium/issues/detail?id=381459)
I noticed that the bug can't be reproduced in Chrome 45 and the issue was
closed subsequently. I've also tested again with Chrome 51 and it still works.
Additionally, the Chrome hack was kept in the select code, but wasn't ported to
the ngOptions code when the two split in 7fda214c4f,
and no regression happened.
Nevertheless, a test has been added to guard against a future regression.
Related: #6828
PR: #14705
If a $timeout handler calls $timeout itself, this new $timeout should be
added to the mock deferred queue with a "now" time based on when the original
handler was triggered.
Previously it was being added with a now time of when the `$timeout.flush`
method was originally called.
Closes#5420Closes#14686
Previously, if one of these hooks threw an error, then the compilation
was terminated unceremoniously. In particular any other `$onChanges`
hooks that had been scheduled were not executed, nor was the queue cleaned
up properly.
Closes#14444Closes#14463
ngMessageFormat test files were missing from angularTest
ngMessages and ngAnimate were missing from karmaModules.
This change highlighted a number of problems in the tests and code,
which are now fixed.
Closes#14314Closes#14669
Corrected formatting errors on lines 258, 695, 696, 1096, 1219, 1451, and 1536
by adding periods at the end of single line comments that were missing them
in order to be consistent with the formatting found in the file.
Capitalized the first letter in the first word of the comments on lines 695, 696, 1096,
to be consistent with the formatting of the rest of the file.
Added a space after the // in the comment on line 1536 to be
consistent with the formatting of the file.
Closes#11832
By using a pointer to the current start of the queue and only clearing
up the queue storage later, we save lots of time that was spent manipulating
arrays with `slice`
Closes#14545
Thanks to @spamdaemon for the original PR to make this improvement.
In naive tests on Chrome I got the following results:
```
Matches Misses
indexOf 33ms 1494ms
lastIndexOf 11ms 11ms
```
Closes#3711
If a route defines a `redirectTo` value, the current route should stop processing the route
and instead wait to process the route of the redirect.
Currently, what is happening is that Angular detects a redirectTo value and updates $location,
but then continues processing the route that was intended to be redirected.
Templates are loaded, resolves are processed, ng-view then updates the view with a new template
and instantiates the controller all for a route that should have been redirected.
A common use case for assigning a function to the redirectTo is to validation authentication,
permission check, or some other logic to determine if the route should continue or redirect
else where. In the end, this happens, but in between, unexpected results may occur by updating
the view and instantiating controllers for logic that wasn't expected to be executed.
http://plnkr.co/edit/8QlA0ouuePH3p35Ntmjy?p=preview
This commit checks for a url change after a potential redirect, it the url changed, and is
not `null` nor `undefined`, exit out and don't process current route change.
Closes#3332Closes#14658
BREAKING CHANGE
The $route service no longer instantiates controllers nor calls resolves or template functions
for routes that have a `redirectTo` unless the `redirectTo` is a function that returns
`undefined`.
1) First change - Whenever cloning into directory there are chances of some users using "sudo" without knowing what it does exactly and what's the purpose of using sudo, leading them into a confusion and this lead to changes in git config and permission issues of which users may not be able to figure out at one spot.
2) Second Change- There are chances of version unstability issues in node which at times causes npm error and warnings while installing packages, I too had undergone some issues with node version conflicts at times, users who are not aware of this will be benefited with a Note prior.
`module.decorator` is now processed via the configBlocks order of operations and:
1. no longer throws error if declared before the provider being decorated.
2. guarantees the correct provider will be decorated when multiple, same-name
providers are defined.
(1) Prior to this fix, declaring `module.decorator` before the provider that it
decorates results in throwing an error:
```js
angular
.module('theApp', [])
.decorator('theFactory', moduleDecoratorFn)
.factory('theFactory', theFactoryFn);
// Error: [$injector:modulerr] Failed to instantiate module theApp due to:
// Error: [$injector:unpr] Unknown provider: theFactoryProvider
```
The result of this fix now allows for the declaration order above.
(2) Prior to this fix, declaring `module.decorator` before the final, same-named
provider results in that provider **not** being decorated as expected:
**NOTE:** Angular does not use provider name spacing, so the final declared
provider is selected if multiple, same-named providers are declared.
```js
angular
.module('theApp', [])
.factory('theFactory', theFactoryFn)
.decorator('theFactory', moduleDecoratorFn)
.factory('theFactory', theOtherFactoryFn);
```
`theOtherFactoryFn` is selected as 'theFactory' provider, but prior to this fix it is **not**
decorated via `moduleDecoratorFn`. This fix ensures that `theOtherFactoryFn` will be decorated as
expected when using the declaration order above.
Closes#12382Closes#14348
BREAKING CHANGE:
`module.decorator` declarations are now processed as part of the `module.config`
queue and may result in providers being decorated in a different order if
`module.config` blocks are also used to decorate providers via
`$provide.decorator`.
For example, consider the following declaration order in which 'theFactory' is
decorated by both a `module.decorator` and a `$provide.decorator`:
```js
angular
.module('theApp', [])
.factory('theFactory', theFactoryFn)
.config(function($provide) {
$provide.decorator('theFactory', provideDecoratorFn);
})
.decorator('theFactory', moduleDecoratorFn);
```
Prior to this fix, 'theFactory' provider would be decorated in the following
order:
1. moduleDecoratorFn
2. provideDecoratorFn
The result of this fix changes the order in which 'theFactory' is decorated
because now `module.decorator` declarations are processed in the same order as
`module.config` declarations:
1. provideDecoratorFn
2. moduleDecoratorFn
This is a major re-structuring of the tutorial app's codebase, aiming at applying established best
practices (in terms of file naming/layout and code organization) and utilizing several new features
and enhancements (most notably components) introduced in recent versions of Angular (especially
v1.5).
Apart from the overall changes, two new chapters were introduced: one on components and one on code
organization.
--
In the process, several other things were (incidentally) taken care of, including:
* Dependencies were upgraded to latest versions.
* Animations were polished.
* Outdated links were updated.
* The app's base URL was changed to `/` (instead of `/app/`).
BTW, this has been tested with the following versions of Node (on Windows 10) and everything worked
fine:
* 0.11.16
* 4.2.6
* 4.4.2
* 5.10.0
* 6.2.0
--
This was inspired by (and loosely based on) #13834.
Again, mad props to @teropa for leading the way :)
--
**Note:**
The old version of the tutorial, that is compatible with Angular version 1.4 or older, has been
saved on the `pre-v1.5.0-snapshot` branch of
[angular-phonecat](https://github.com/angular/angular-phonecat). The `v1.4.x` version of the
tutorial should be pointed to that branch instead of `master`.
--
Related to angular/angular-phonecat#326.
Related to angular/angular-seed#341.
Closes#14416
Messages imported with `ngMessagesInclude` are loaded asynchronously and
they can arrive after the ngMessages element has already been removed from DOM.
Previously we tried to compile these messages and that caused a `$compile:ctreq`
error. Now they are silently ignored if `ngMessagesInclude`'s scope has already
been destroyed.
Closes#12695Closes#14640
If the `from` element of an animation does not actually have an animation
then there will be no animation runner on that element. This is possible
if the element has the `ng-animate-ref` attribute but does not have any
CSS animations or transitions defined.
In this case, it is not necessary to try to update the host of the
non-existent runner.
Fixes#14641Closes#14645
While $location expects that $browser stores the URL unchanged, "some browsers" transform the URL
when setting or defer the acutal update. To work around this, $browser.url() kept the unchanged
URL in pendingLocation.
However, it failed to update pendingLocation in all code paths, causing
$browser.url() to sometimes incorrectly report previous URLs, which horribly confused $location.
This fix ensures that pendingLocation is always updated if set, causing url() to report the
current url.
Fixes#14427Closes#14499
When an expression has the following:
- Bind-once
- A stateless filter at the end
- Optionally an expression interceptor
Then call the filter once.
Closes: #14583Closes: #14589
The watch handler was triggering on its first invocation, even though
its change had already been dealt with when setting up the binding.
Closes#14546Closes#14580
Previously `stripCommentsFromElement()` would return an empty Array (instead of a jqLite collection)
which would cause an exception to be thrown: "element.parent not a function".
This commit fixes it, by ensuring that the returned value is always a jqLite collection.
Closes#14558Closes#14559
+ explain decorators and how they are implemented in angular
+ explain how different types of services can be selected
+ explain `$delegate` objects and how they differ between services
+ warn of the risks/caveats of `$delegate` modification
+ note the exposure of `decorator` through the module api
+ show an example of decorating a core service
+ show an example of decorating a core directive
+ show an example of decorating a core filter
Closes#12163Closes#14372
Custom `$sce` implementations might not provide a `toString()` method on the wrapped object, or it
might be compiled away in non-debug mode. Watching the unwrapped value (retrieved using
`$sce.valueOf()`) fixes the problem.
The performance of this should be equivalent - `toString()` on objects usually touches all fields,
plus we will also avoid the (potentially big) string allocation.
Fixes#14526Closes#14527
perf(ngAnimate): listen for document visibility changes
Accessing the document for the hidden state is costly for
platforms like Electron. Instead, listen for visibilitychange
and store the state.
(#14071)
Closes#14066
Previously, calling `Attributes#$set('srcset', value)` on an `<img>` element would throw if `value`
were undefined, as it assumed `value` is always a string.
This commit fixes the issue, by skipping the unnecessary string manipulation when `value` is not
defined.
Closes#14470Closes#14493
Add explanation for error status codes in `$http` and mention negative codes normalization.
This alleviates confusion about which status codes will trigger the error callback and what values
to expect in such callbacks.
Fixes#11945Closes#14459
Remove 'Breaking Changes' label where there are no breaking changes.
Only for '1.4.0-rc.2', breaking changes have different styling (bold without bulleted list). Change to be consistent with others
(#14482)
- Add support for computed property names
- Add support for short notation in properties definitions
Eg. The expressions `{x}` and `{[x + 'foo']: 1}` are now valid.
When csp is disabled, evaluating `-undefined` is `-0` and when csp is enabled
the evaluation is `0`. In most cases this is not an issue as `0 === -0`, but
there is an edge case as `1/0 === Infinity` and `1/-0 === -Infinity`
Close: #14451
This changes the way option elements are generated when the ngOption collection changes.
Previously, we would re-use option elements when possible (updating their text and
label). Now, we first remove all currently displayed options and the create new options for the
collection. The new options are first appended to a documentFragment, which is in the end appended
to the selectElement.
Using documentFragment improves render performance in IE with large option collections
(> 100 elements) considerably.
Creating new options from scratch fixes issues in IE where the select would become unresponsive
to user input.
Fixes#13607Fixes#13239Fixes#12076
This reverts commit 5e37b2a7fd.
Eagerly loading `$route`, could break tests, because it might request the root or default route
template (something `$httpBackend` would know nothing about).
It will be re-applied for `v1.6.x`, with a breaking change notice and possibly a way to disable
the feature is tests.
Fixes#14337
Currently, custom annotations are copied from the CDO onto the controller constructor.
Using `noop()` when no controller has been specified, pollutes it with custom annotations and
makes one component's annotations available to all other components that have `noop()` as their
controller.
Fixes#14391Closes#14402
Add support for collecting current stack trace information in browsers
(e.g. IE10+, PhantomJS) that do not automatically store the current stack trace
information in a newly created `Error` object's `stack` property, but
only add it there once the `Error` gets thrown.
The original implementation works fine in Firefox & Chrome, but fails on IE10+
and PhantomJS where it, for example, breaks Karma's error reporting in cases
when an exception is thrown in a test like the following:
```
it('the holy crusade', inject(function() {
var x = {};
x.holyGrail();
}));
```
In this case, the ngMock `inject()` implementation would incorrectly add the
word `undefined` at the end of the collected error stack trace information,
thus causing the main error description to be reported back to Karma as
`undefined`.
The added test makes sure this functionality:
- works as expected in browsers supporting JavaScript stack trace
collection, e.g. Chrome, Firefox, IE10+, Opera & PhantomJS
- does not add any bogus stack track information in browsers that do
not support JavaScript stack trace collection, e.g. IE9
Fixes#13591Closes#13592Closes#13593
Jasmine 2.4 (maybe earlier) does not support returning an array containing both the "normal" and the
negative error messages. It will always concatenate them.
Closes#14275
This makes the two interpolation errors consistent and avoids checking the same thing per link
(which previously would log the same error per link).
The test changes are not necessary but do make them stricter and more like the selmulti error tests.
Closes#13267
BREAKING CHANGE:
Using interpolation in any on* event attributes (e.g. `<button onclick="{{myVar}}">`) will now throw
the "nodomevents" error at compile time.
Previously the nodomevents was thrown at link time. The new behavior makes it consistent with
the "selmulti" error.
The breaking change should be rare, as it relates to incorrect API use that should not make it to
production apps in the first place.
prevent ngAria from attaching roles to textarea, button, select, summary, details, a, and input
Closes #14076Closes#14145
BREAKING CHANGE:
ngAria will no longer add the "role" attribute to native control elements
(textarea, button, select, summary, details, a, and input). Previously, "role" was not added to
input, but all others in the list.
This should not affect accessibility, because native inputs are accessible by default, but it might
affect applications that relied on the "role" attribute being present (e.g. for styling or as
directive attributes).
The fix for removing the event callbacks on destroy introduced in
ce7f400011 removed the events too early, so that the event callbacks
for the "close" phase in "leave" animations were not called.
This commit fixes the behavior so that the event callbacks are only removed during on('$destroy')
when no animation is currently active on the element. When an animation is active, the event callbacks
will be removed after all callbacks have run, and if the element has no parent (has been removed from
the DOM).
Closes#14321
Since commit a3a7afd3aa, animations are not run
when the document is hidden (only their structural or class change effects are executed).
However, some libraries rely on the $animate.on() callbacks to be called even when no actual animation
runs.
This commit restores the behavior for the ngAnimate.$animate functions.
Note that callbacks still won't be called if animations are disabled, because this would be be a potential
breaking change, as some applications might rely on this implementation.
Fixes#14120
Add additional line from example which demonstrates using the snake cased attribute binding in
parent component template.
Add note clarifying camelCase to snake-case requirement to use the Output binding callback feature.
Closes#14365
Updated docs to reflect that response data can either be an array, object _or_ a string
Technically, response data can be anything that can be handled by angular.copy,
but since string and JSON data is most commonly mocked, the main types are sufficient.
Closes#14346
The e2e tests were set up to be run twice; once with the latest supported
jQuery and once with jQuery 2.1. However, the latest jQuery was used in both
cases. The initial plan was to just run integration tests with the latest
jQuery and leave regression testing for jQuery 2.1 to unit tests as they're
way faster. This commit removes the jQuery 2.1 e2e tests entry.
Due to the way that we instantiate controllers, the `$onChanges` hook
was not always available at the time we were trying to trigger the initial
call to this hook. For instance, if the hook was actually defined inside
the constructor function.
This commit fixes that but also fixes the fact that the initial call was
being made in the postDigest anyway, which was incorrect because the
it should have been made before the `$onInit` call.
Closes#14355Closes#14359
When ngModel is set to a value that matches a disabled option, ngOptions will now select the option
in the select element, which will set select.val() to the option hash value and visually
show the option value / label as selected in the select box. Previously, disabled
options forced the unknown value.
The previous behavior is inconsistent with both default HTML behavior and select with
ngModel but without ngOptions. Both allow disabled values to be selected programmatically.
A common use case for this behavior is an option that was previously valid, but has
been disabled, and cannot be selected again.
This commit removes a duplicate test, and all other tests that previously checked that disabled
options are not set have been adjusted to the ensure the opposite.
Fixes#12756
Rejected promises that do not have a callback to handle the rejection report
this to $exceptionHandler so they can be logged to the console.
BREAKING CHANGE
Unhandled rejected promises will be logged to $exceptionHandler.
Tests that depend on specific order or number of messages in $exceptionHandler
will need to handle rejected promises report.
Closes: #13653Closes: #7992
Inline constants definitions in function calls, array definitions
and object values.
For the expression [1, {foo: "bar"}, 1 + 2] it changes it from
```js
// After some reordering and cleanup
var v1 = 1;
var v2 = "bar";
var v3 = {foo: v2};
var v4 = 1;
var v5 = 2;
var v6 = plus(v4, v5);
var v7 = [v1, v3, v6];
return v7;
```
to
```js
return [1, {foo: "bar"}, plus(1, 2)];
```
Expression parts that are not constants did not change, and still generate a lot
of intermediate variables.
Closes: #14293
Add jshint "eqeqeq" and "eqnull" rules (to allow == null comparisons).
Only adds it to files under src/, because we these files are unit-tested.
Files in src/ngLocale are excluded, because the code is imported.
Closes#14287
Add exceptions to the rule in input, ngAria, and parse.
For input and ngAria, the exception is to prevent a breaking change in the radio directive.
A test for the input behavior has been added.
For parse, the exception covers non-strict expression comparison.
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:
* `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
are the names of the bound properties that have changed, and the values are an object of the form
`{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
cloning the bound value to prevent accidental mutation of the outer value.
* `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
external resources, watches and event handlers.
* `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
they are waiting for their template to load asynchronously and their own compilation and linking has been
suspended until that occurs.
Closes#14127Closes#14030Closes#14020Closes#13991Closes#14302
When multiple animations on the same element are queued before a $digest passes,
the animator tries to create as few actual animations as possible by joining / canceling
redundant animations. Class-based animations for example are cancelled when the classes that
are added and removed are the same, and the result is no class-change. This however must only
happen if there's no structural animation currently queued.
Fixes#14249
Under specific circumstances, ngMessages would go into an infinite loop and crash the
browser / page:
- At least two ngMessage elements are wrapped inside another element (e.g. ngTransclude)
- The first message is currently visible
- The first message is removed (e.g. when the whole ngMessages element is removed by an ngIf)
When a message is removed, it looks for a previous message - in this specific case it would misidentify
the second message for a previous message, which would then cause the first message to be marked as the
second message's next message, resulting in an infinite loop, and crash.
This fix ensures that when searching for previous messages, ngMessage walks the DOM in a way so
that messages that come after the current message are never identified as previous messages.
This commit also detaches and destroys all child ngMessage elements when the ngMessages element is
destroyed, which should improve performance slightly.
Fixes#14183Closes#14242
In the version of V8 used in Chrome < 50, the parent of template nodes for
`transclude: "element"` directives would be improperly garbage collected
despite still having been referenced via `parentNode`.
This bug surfaced due to the introduction of lazy transclusion (652b83e),
and appears under certain circumstances when using directive start and end elements.
It should be removed some time after Chrome 50 has been released.
Fixes#14041Closes#14286
In the DDO, controller can be '@', which means the controller name
is taken from the directive attribute. This is undocumented and internally
only used by ngController. There seems to be no case where converting the
controller function to a string would actually be necessary.
Related #14268
Although `window.history` is present in the context of Chrome Packaged Apps, it is not allowed to
access `window.history.pushState` or `window.history.state`, resulting in errors when trying to
"sniff" history support.
This commit fixes it by detecting a Chrome Packaged App (through the presence of
`window.chrome.app.runtime`). Note that `window.chrome.app` is present in the context of "normal"
webpages as well, but it doesn't have the `runtime` property, which is only available to packaged
apps (e.g. see https://developer.chrome.com/apps/api_index).
(It also also contains some style changes for making the structure and layout of `$sniffer` tests
more consistent.)
Fixes#11932Closes#13945
By using `>=` when comparing the number length to `lgSize`, we'll provide the correct value, when
formatting numbers with different `lgSize` than `gSize`.
Fixes#14289Closes#14290
Probably due to implementation differences in browsers for pre-DST period (see
https://github.com/angular/angular.js/issues/5017 and especially
https://github.com/angular/angular.js/issues/5017#issuecomment-90775226 for context), some
`TzDate` tests had different behavior on different Timezones/Regions (e.g. failed in Australia,
which started to observe DST in 1971).
Since the used year (`1970`) didn't have any particular significance, this commit fixes the issue
by using a year that is more consistently handled by browsers (`2000`).
Fixes#14272Closes#14285
The $location service is designed to support hash prefixed URLs
for cases where the browser does not support HTML5 push-state navigation.
The Google Ajax Crawling Scheme expects that local paths within a SPA start
with a hash-bang (e.g. `somedomain.com/base/path/#!/client/side/path`).
The `$locationProvide` allows the application developer to configure the
hashPrefix, and it is normal to set this to a bang '!', but the default
has always been the empty string ''.
This has caused some confusion where a user is not aware of this feature
and wonders why adding a hash value to the location (e.g. `$location.hash('xxx')`)
results in a double hash: `##xxx`.
This commit changes the default value of the prefix to '!', which is more
natural and expected.
See https://developers.google.com/webmasters/ajax-crawling/docs/getting-startedCloses#13812Closes#14202
BREAKING CHANGE
The hash-prefix for `$location` hash-bang URLs has changed from the empty
string "" to the bang "!". If your application does not use HTML5 mode
or is being run on browsers that do not support HTML5 mode, and you have
not specified your own hash-prefix then client side URLs will now contain
a "!" prefix. For example, rather than `mydomain.com/#/a/b/c` will become
`mydomain/#!/a/b/c`.
If you actually wanted to have no hash-prefix then you should configure
this by adding a configuration block to you application:
```
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix("");
}]);
```
Moved the `v1.5.1` section above the `v1.4.10` one, so that it is right below the `v1.5.2` section
for easier reference. Also removed an empty "Breaking Changes" sub-section.
Closes#14283
The test for this didn't actually test the listener removal. The addClass animation after
the element removal didn't start because the enter animation was still in progress.
Highlights:
New mechanism to run async tests as Jasmine 2 removed `runs`, `waits` and `waitsFor`
The functions `iit`, `ddescribe` and `tthey` were renamed `fit`, `fdescribe` and
`fthey` as the originals came from Karma, Karma no longer bundles Jasmine and the
new function name comes from Jasmine.
Closes#14226
Component Router should come after the menu topic Components as Components should be understood first
before Component Routers. This made it easier to read the Component Routers topic.
Closes#14214
When an error message contains an HTML string (e.g. `$location:nobase` containing `<base>`), it was
interpreted as a literal HTML element, instead of text. Error messages are not expected to render
as HTML, but we still need to use `.html()` in `errorDisplay`, so that the links created by
`errorLinkFilter` are properly displayed.
This commit solves this issue by replacing `<`/`>` with `<`/`>`.
Related to #14016.
We don't set selected property / attribute on options that are already selected.
That happens for example if the browser has automatically selected the first
option in a select. In that case, the selected property is set automatically, but
the selected attribute is not. This doesn't impact the functionality of the select,
but it can be problematic if option elements are selected with `option[selected]` in tests.
Closes#14115Closes#14125
docs(guide/Components): add missing $ctrl
The new component example does not work as is. It needs a missing reference to $ctrl.
Closes#14138Closes#14143
When debugInfoEnabled is `false` when comments generated by transclusions, ngIf,
ngRepeat and ngSwitch will not contain any information about the directive nor
the expression associated with it.
Closes: #8722
During it's linking phase, `ngView` relies on the info provided in `$route.current` for
instantiating the initial view. `$route.current` is set in the callback of a listener to
`$locationChangeSuccess`, which is registered during the instantiation of the `$route` service.
Thus, it is crucial that the `$route` service is instantiated before the initial
`$locationChangeSuccess` is fired. Since `ngView` declares `$route` as a dependency, the service is
instantiated in time if `ngView` is present during the initial load of the page.
Yet, in cases where `ngView` is included in a template that is loaded asynchronously (e.g. in
another directive's template), the directive factory might not be called soon enough for `$route`
to be instantiated before the initial `$locationChangeSuccess` event is fired.
This commit fixes it, by always instantiating `$route` up front, during the initialization phase.
Fixes#1213Fixes#6812Closes#14088
Previously, `angular-mocks` was calling `$rootScope.$destroy()` after each test as part of it's
cleaning up, assuming that it was always available. This could break if `$rootScope` was mocked
and the mocked version didn't provide the `$destroy()` method.
This commit prevents the error by first checking that `$rootScope.$destroy` is present.
Fixes#14106Closes#14107
Starting with 88bb551, `ngMock` will attach the `$injector` to the `$rootElement`, but will never
clean it up, resulting in a memory leak. Since a new `$rootElement` is created for every test,
this leak causes Karma to crash on large test-suites.
The problem was not detected by our internal tests, because we do our own clean-up in
`testabilityPatch.js`.
88bb551 was revert with 1b8590a.
This commit incorporates the changes from 88bb551 and prevents the memory leak, by cleaning up all
data attached to `$rootElement` after each test.
Fixes#14094Closes#14098
Included changes:
* Point out that only GET & JSONP requests are cached.
* Explain that the URL+search params are used as cache keys (headers not considered).
* Add note about cache-control headers on response not affecting Angular caching.
* Mention `$httpProvider.defaults.cache` (in addition to `$http.defaults.cache`).
* Clear up how `defaults.cache` and `config.cache` are taken into account for determining the
caching behavior for each request.
Fixes#11101Closes#13003
Although `copy()` does not need to (and never will) support all kinds of objects, there is a
(not uncommon) usecase for supporting `Blob` objects:
`ngMock`'s `$httpBackend` will return a copy of the response data (so that changes in one test won't
affect others). Since returning `Blob` objects in response to HTTP requests is a valid usecase and
since `ngMocks`'s `$httpBackend` will use `copy()` to create a copy of that data, it is reasonable
to support `Blob` objects.
(I didn't run any benchmarks, but the additional check for the type of the copied element should
have negligible impact, compared to the other stuff that `copy()` is doing.)
Fixes#9669Closes#14064
The `ngMockE2E` `$httpBackend` has a mechanism to allow requests to pass through, if one wants to
send a real HTTP request instead of mocking. The specified `responseType` of the request was never
passed through to the "real" `$httpBackend` (of the `ng` module), resulting in it being effectively
ignored.
Fixes#5415Closes#5783
When Angular is loaded more than once (by including the script multiple times),
a warning is logged in the console. IE9 only makes the console available when
the dev tools are open, so before this fix, the browser would throw an error
Note that Protractor doesn't actually support IE9.
BREAKING CHANGE:
Text nodes at the root of transcluded content will no longer be wrapped into <span>
elements. If there is a need for this <span> element to be present, then this should
be added to the content to be transcluded.
Before:
```html
<div directive-that-will-transclude-the-content>
I expect this content to e wrapped
</div>
```
After:
```html
<div directive-that-will-transclude-the-content>
<span>I expect this content to e wrapped</span>
</div>
```
Previously, the date-related regular expressions only matched years with no more than 4 digits.
This commit adds support for years with more than 4 digits. It also resolves an ambiguity in
`ISO_DATE_REGEXP` by matching the whole string (when it previosuly allowed extra characters around
the date string).
Fixes#13735Closes#13905
The `parentNode` property is well supported between all browsers. Since
no other functionality was required here other than traversing upwards
using `.parent()`, we can use the DOM API directly.
Closes: #13879
Unlike jqLite, jquery scrapes the attributes of an element looking for
data- keys that match the requested property. When many elements are
being animated due to something like `ngRepeat` unrolling within one
digest cycle, the amount of time spent in that one function quickly adds
up.
By changing our API to use the lower level data API, we can cut the time
spent in this function by half when jQuery is loaded.
- Note that bootstrapping on elements with transclusion directives
is dangerous and not recommended.
- group info on limitations, and add them to the guide
Closes#11421Closes#13572Closes#12583
- how to enable / disable animations
Closes#8812
- how to handle conflicts with existing animations
Closes#8033Closes#11820
- what happens on boostrap / how to enable animations on bootstrap
BREAKING CHANGE: Where appropriate, ngAria now applies ARIA to custom controls only, not native inputs. Because of this, support for `aria-multiline` on textareas has been removed.
New support added for ngValue, ngChecked, and ngRequired, along with updated documentation.
Closes#13078Closes#11374Closes#11830Closes#13483
This change allows the developer to bind an isolate scope / controller property
to an expression, using a `<` binding, in such a way that if the value of the
expression changes, the scope/controller property is updated but not the
converse.
The binding is implemented as a single simple watch, which can also provide
performance benefits over two way bindings.
Closes#13928Closes#13854Closes#12835Closes#13900
Previous version emphasised "gaining user's private data".
While this perfectly describes JSON vulnerability (which is based on XSRF),
data theft suits XSS more.
Pure XSRF is more about performing requests that have side effects.
Closes#13901
When `Date.parse`-ing a date string, IE and Edge don't recognize the timezone offset in the format
`+HH:mm` (but only without the `:`). According to [the spec][1], the timezone offset should
contain `:`. The [ISO 8601 Standard][2] allows both forms (with and without `:`).
Although the `Date` implementation in JavaScript does not 100% follow the ISO 8601 Standard (it's
just _based on it_), all other browsers seem to recognize both forms as well.
[1]: http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
[2]: https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTCFixes#13880Closes#13887
The wrong field name was being passed into the `$ctrl.update` call in `heroDetail.html` resulting
in the wrong behavior (`name` was being updated instead of `location`)
Closes#13890
Under specific circumstances (e.g. adding options via a directive with `replace: true` and a
structural directive in its template), an error occurred when trying to call `hasAttribute()` on a
comment node (which doesn't support that method).
This commit fixes it by filtering out comment nodes in the `addOption()` method.
Fixes#13874Closes#13878
Previously, ngAnimateChildren would set the data on the element
in an $observe listener, which means the data was available after one digest happend.
This is too late when the element is animated immediately after compilation, as happens with ngIf.
Now the data is also set right in the linking function.
Fixes#13865Closes#13876
- introduce components
- component types are based on Angular2 docs
- conceptually, we promote parent -> child data flow and clear inputs and outputs
- the info about multi-transclusion / requiring controllers, and components as route templates
has been moved from the component docs to the guide
This commit deprecates the ngClick directive from the ngTouch module.
Additionally, it disables it by default. It can be enabled in the new $touchProvider with
the $touchProvider.ngClickOverrideEnabled() method.
The directive was conceived to remove the 300ms delay
for click events on mobile browsers, by sending a synthetic click event on touchstart.
It also tried to make sure that the original click event that the browser sends after 300ms
was "busted", so that no redundant "ghost-clicks" appear.
There are various reasons why the directive is being deprecated.
- "This is an ugly, terrible hack!" (says so in the source)
- It is plagued by various bugs that are hard to fix / test for all platforms (see below)
- Simply including ngTouch activates the ngClick override, which means even if you simply want
to use ngSwipe, you may break parts of your app
- There exist alternatives for removing the 300ms delay, that can be used very well with Angular:
[FastClick](https://github.com/ftlabs/fastclick), [Tappy!](https://github.com/filamentgroup/tappy/)
(There's also hammer.js for touch events / gestures)
- The 300ms delay itself is on the way out - Chrome and Firefox for Android remove the 300ms delay
when the usual `<meta name="viewport" content="width=device-width">` is set. In IE, the
`touch-action` css property can be set to `none` or `manipulation` to remove the delay. Finally,
since iOs 8, Safari doesn't delay "slow" taps anymore. There are some caveats though, which can be
found in this excellent article on which this summary is based: http://developer.telerik.com/featured/300-ms-click-delay-ios-8/
Note that this change does not affect the `ngSwipe` directive.
Issues with interactive elements (input, a etc.) when parent element has ngClick:
Closes#4030Closes#5307Closes#6001Closes#6432Closes#7231Closes#11358Closes#12082Closes#12153Closes#12392Closes#12545Closes#12867Closes#13213Closes#13558
Other issues:
- incorrect event order
- incorrect event propagation
- ghost-clicks / failing clickbusting with corner cases
- browser specific bugs
- et al.
Closes#3296Closes#3347Closes#3447Closes#3999Closes#4428Closes#6251Closes#6330Closes#7134Closes#7935Closes#9724Closes#9744Closes#9872Closes#10211Closes#10366Closes#10918Closes#11197Closes#11261Closes#11342Closes#11577Closes#12150Closes#12317Closes#12455Closes#12734Closes#13122Closes#13272Closes#13447
BREAKING CHANGE:
The `ngClick` override directive from the `ngTouch` module is **deprecated and disabled by default**.
This means that on touch-based devices, users might now experience a 300ms delay before a click event is fired.
If you rely on this directive, you can still enable it with the `$touchProvider.ngClickOverrideEnabled()`method:
```js
angular.module('myApp').config(function($touchProvider) {
$touchProvider.ngClickOverrideEnabled(true);
});
```
For migration, we recommend using [FastClick](https://github.com/ftlabs/fastclick).
Also note that modern browsers remove the 300ms delay under some circumstances:
- Chrome and Firefox for Android remove the 300ms delay when the well-known `<meta name="viewport" content="width=device-width">` is set
- Internet Explorer removes the delay when `touch-action` css property is set to `none` or `manipulation`
- Since iOs 8, Safari removes the delay on so-called "slow taps"
See this [article by Telerik](http://developer.telerik.com/featured/300-ms-click-delay-ios-8/) for more info on the topic.
Note that this change does not affect the `ngSwipe` directive.
Previously, css animations would not cancel the timeout when the
animation ends normally (calling end explicitly / transitionEnd event).
This meant that the timeout callback fn was always called after 150% of
the animation time was over. Since the animation was already closed at this
point, it would not do any work twice, but simply remove the timer data
from the element.
This commit changes the behavior to cancel the timeout and remove the data
when it is found during animation closing.
Closes#13787
The change is only to concepts.graffle/data.plist to fix 'World' spelling.
Another PR, #13724, already fixed the actual image.
Closes#13704Closes#13734
When running an expression with expensive checks, there is a call to `$eval` or `$evalAsync`
then that expression is also evaluated using expensive checks
Closes: #13850
Previously, if either of the start/end interpolation symbols remained unchanged (i.e. `{{` or `}}`),
then directive templates would not be denormalized properly. Changing only one of the start/end
symbols (but not both) is an uncommon but legitimate usecase.
Closes#13848
Old behavior: actions can be either cancellable or have a numeric timeout.
When having both defined, cancellable was ignored.
With this commit: it's possible for actions to have both cancellable:true
and numeric timeout defined.
Example usage:
```js
var Post = $resource('/posts/:id', {id: '@id'}, {
get: {
method: 'GET',
cancellable: true,
timeout: 10000
}
});
var currentPost = Post.get({id: 1});
...
// the next request can cancel the previous one
currentPost.$cancelRequest();
currentPost = Post.get({id: 2});
// any of those requests will also timeout, if the response
// doesn't come within 10 seconds
```
Closes#13824
Most systems use *IETF language tag* codes which are typically a combination
of the ISO 639 language code and ISO 3166-1 country code with an underscore
or hyphen delimiter. For example `en_US`, `en_AU`, etc.
Whilst the `$locale.id` comes close, the lowercase format makes it impossible
to transform to an IETF tag reliably. For example, it would be impossible
to deduce `en_Dsrt_US` from `en-dsrt-us`.
Closes#13390
This change edits syntax for code consistency.
It removes whitespace to match the style of the rest of the code,
and changes double quotes to single quotes to conform with
Google's JavaScript Style Guide.
Closes#12889
The unknown provider error often happens when code is minified and one
did not use the correct syntax that supports minification. It's
frustrating to have to hunt for a bug in minified code, so adding the
simple hint that `ngStrictDi` will tell you what is wrong in the original
code will save you quite some trouble.
Closes#12717
Prior to this fix the addition and removal of a CSS class via
ngAnimate would cause flicker effects because $animate was unable
to keep track of the CSS classes once they were applied to the
element. This fix ensures that ngAnimate always keeps a reference
to the classes in the currently running animation so that cancelling
works accordingly.
The commit also adds a test for a previously untested animation merge path.
Closes#10156Closes#13822
In the description of the example, you use `element` to refer to the container parameter and
`listenerFn` to refer to the callback parameter.
Closes#12716
If directives are required through an object hash, rather than a string or array,
the required directives' controllers are bound to the current directive's controller
in much the same way as the properties are bound to using `bindToController`.
This only happens if `bindToController` is truthy.
The binding is done after the controller has been constructed and all the bindings
are guaranteed to be complete by the time the controller's `$onInit` method
is called.
This change makes it much simpler to access require controllers without the
need for manually wiring them up in link functions. In particular this
enables support for `require` in directives defined using `mod.component()`
Closes#6040Closes#5893Closes#13763
This provides an elegant alternative to the array form of the `require`
property but also helps to support binding of `require`d controllers
to directive controllers.
Closes#8401Closes#13763
This commit positively affects performance in two main ways:
1, When wrapping text nodes in the compile step, we do not need the overhead
of the `forEach` function versus a normal for loop since we do not make
use of the closure for anything.
2. When actually wrapping the node, we can completely bypass jqLite which
avoids several function calls and the overhead of cloning the wrapper node
which we already know to be unique.
Tests in applications show about an 83% decrease in time spent in this
specific loop.
This commit speeds up the code that checks if an element can
be animated, for the following two cases:
The checks will be sped up in cases where the animation
is disabled via $animate.enabled(element, false) on any parent element.
A minor speed-up is also included for cases where the $rootElement of the
app (the bootstrap element) is on the body or lower in the DOM tree.
This commit fixes two bugs:
1) Previously, animate would assume that a found host element
was part of the $rootElement (while it's possible that it is also outside the root).
2) Previously, if a parent of the animated element was pinned to a host element, the
host would not be checked regarding animations enabled status etc.
Closes#13783
Prior to this fix any promise/callback chained on a call to the $animate
methods would only flush if and when the browser page is visible. This
fix ensures that a timeout will be used instead when the document
is hidden.
Prior to this fix, ngAnimate would always trigger animations even if
the browser tab or browser window was not visible. This would cause
issues with class updates / DOM operations even if elements were not
using animations. The root cause is that browsers do not flush calls to
requestAnimationFrame when browser windows / tabs are not visible.
This fix disables animations if `document.hidden` is `true`.
Closes#12842Closes#13776
A bug in material has exposed that ngAnimate makes a copy of
the provided animation options twice. By making two copies,
the same DOM operations are performed during and at the end
of the animation. If the CSS classes being added/
removed contain existing transition code, then this will lead
to rendering issues.
Closes#13722Closes#13578
Includes the following fixes (per component):
* `$sniffer`: Properly determine the expected `vendorPrefix` for MS Edge
* `input`: MS Edge does not support dates with years with more than 4 digits.
Trying to set the value of an `input[datetime-local]` to `9999-12-31T23.59.59.999` throws an
error (probably related to converting the date to one with a year with more than 4 digits,
due to timezone offset).
* `$sanitize`: Fix failing tests on MS Edge
* `$animateCss`: Although the detected `vendorPrefix` for MS Edge is "ms", it doesn't seem to
recognize some vendor-prefixed CSS rules (e.g. `-ms-animation-*`). Other browsers (currently)
recognize either vendor-prefixed rules only or both.
Fixed by adding and retrieving styles using both prefixed and un-prefixed names.
* `$compile`: Skip failing `foreignObject` test on MS Edge.
For unknown reasons, an `<svg>` element inside a `<foreignObject>` element on MS Edge has no
size, causing the included `<circle>` element to also have no size and thus fails an
assertion (relying on the element having a non-zero size).
This seems to be an MS Edge issue; i.e. it is also reproducible without Angular.
(Tested with MS Edge version 25.10586.0.0 on Windows 10.)
Closes#13686
Prior to this fix if a parent container disabled animations for
itself then no children could be enabled explicity via
`$animate.enabled`. This patch allows for that to work.
Closes#13179Closes#13695
The `Module.component()` helper now delegates to `$compileProvider.component()`.
This has the following benefits:
- when using only the loader, we are not accessing out of scope variables / functions
- components can be registered via $compileProvider
- docs are a bit easier to find
- it is easier to keep the Batarang version of the loader up to date if there is minimal
code in that file.
Closes#13692
BREAKING CHANGE:
Before this change, the filter assumed that the input (if not undefined/null) was of type 'string'
and that certain methods (such as `.match()`) would be available on it. Passing a non-string value
would most likely result in a not-very-useful error being thrown (trying to call a method that does
not exist) or in unexpected behavior (if the input happened to have the assumed methods).
After this change, a proper (informative) error will be thrown. If you want to pass non-string
values through `linky`, you need to explicitly convert them to strings first.
Since input values could be initialized asynchronously, `undefined` or `null` will still be
returned unchanged (without throwing an error).
Closes#13547Closes#13693
Previously, the `$render` function was re-defined in the `select` directive's
`preLink` function. When a `select` element is compiled, every `option`
element inside it is linked and registered with the `selectCtrl`, which
calls `$render` to update the selected `option`. `$render` calls `selectCtrl.writeValue`,
which adds an unknown `option` in case no option is selected. In cases where
`optgroup` elements are followed by a line-break, adding the unknown `option`
confuses the html compiler and makes it call the link function of the following
`option` with a wrong element, which means this option is not correctly
registered.
Since manipulation of the DOM in the `preLink` function is wrong API usage,
the problem cannot be fixed in the compiler.
With this commit, the `$render` function is not re-defined until the `select` directive's
`postLink` function, at which point all `option` elements have been linked
already.
The commit also changes the `toEqualSelectWithOptions` matcher to
take selected options in groups into account.
Closes#13583Closes#13583Closes#13663
Due to recent changes in Chrome, Firefox and Webkit use of the
event.timeStamp value will lead to unpredictable behaviour due to
precision changes. Therefore it's best to stick entirely to use
`Date.now()` when it comes to confirming the end of transition-
ending values. See #13494 for more info.
Applies to 1.2, 1.3, 1.4 and 1.5.
Closes#13494Closes#13495
Previously, when an animation was closed because no animation styles
where found, it would call .off() with an empty string as the argument.
For both jquery/jqlite this is the same as calling .off() without any
argument, which deregisters all event listeners on an element.
Closes#13514
The default value of for transclude in component helper is now `false`.
The change is motivated by the fact that using `transclude: true` when not necessary
made component unusable in conjunction with structural directives that also require
transclusion such as `ng-switch-when` and `ng-repeat`.
Closes#13566Closes#13581
BREAKING CHANGE:
Angular 1.5.0.beta.2 introduced the `module.component` helper where `transclude` was true by default.
This changes the default for `transclude` to `false`. If you created components that expected
transclusion then you must change your code to specify `transclude: true`.
- Move interpolation info from Directive guide into new interpolation guide
- Add information about boolean attributes to interpolation guide
- remove wroong examples from prefixed boolean attribute docs, link
to interpolation guide instead
- mention additional examples for attributes that benefit from ngAttr
- add docs for ngRequired directive
With slow internet connection scope may be destroyed before template is loaded.
Previously in this case ngInclude compiled template that leaded to memory leaks
and errors in some cases.
Closes: #13515Closes: #13543
Background:
Prior to ffb6b2f, there was a bug in `URL_REGEXP`, trying to match the hostname as `\S+` (meaning
any non-space character). This resulted in never actually validating the structure of the URL (e.g.
segments such as port, path, query, fragment).
Then ffb6b2f and subsequently e4bb838 fixed that bug, but revealed `URL_REGEXP`'s "strictness" wrt
certain parts of the URL.
Since browsers are too lenient when it comes to URL validation anyway, it doesn't make sense for
Angular to be much stricter, so this commit relaxes the "strictness" of `URL_REGEXP`, focusing more
on the general structure, than on the specific characters allowed in each segment.
Note 1: `URL_REGEXP` still seems to be stricter than browsers in some cases.
Note 2: Browsers don't always agree on what is a valid URL and what isn't.
Fixes#13528Closes#13544
`baseThey` used to construct the testcase description by replacing `$prop` using a RegExp.
If the replacement string contained `$&` (which has a special meaning with RegExps), the resulting
string was not as expected.x
Previously, ddescribe, merge-conflicts, jshint, and jscs would run
after unit & e2e tests ran. The order was orginally changed as part of
https://github.com/angular/angular.js/pull/9792.
While the logic is sound that style errors shouldn't block tests from
running, ddescribe should always run. This was not guaraneteed; when
Travis exits with a warning after some browsers have run, ddescribe
doesn't get run and it doesn't become apparent that not
all tests have run.
Additionally, a separate job clearly separates style from test errors,
which e.g. means you can open a PR that includes an iit to speed up
the job, and see immediately if the test passes, because the ddescribe
error is in another job.
ES6's `class Foo {}` constructors cannot be instantiated using
`fn.apply`. This change extracts injection argument collection and then
uses new (Function.bind.apply(ctor, args)) to instantiate the service
instance.
Closes: #12598Closes: #12597
Previously, the animate queue would only detect pinned elements when
they were the same element as the to-be-animated element.
Related #12617Closes#13466
Internet Explorer 11 returns '' for optgroup elements without a value
attribute. We only want to skip option elements with value ''
Fixes#13487Closes#13489
Previously the transition/animation end events were not removed when the
animation was closed. This normally didn't matter, because
the close function knows the animations are closed and won't do work
twice.
However, the listeners themselves do computation that could fail when
the event was missing some data, for example when the event was
triggered instead of natural.
Closes#10387
Previously, $animateCss wouldn't use transition styles that were on the element
before the animation process started. Precisely, transition property, timing-function
and delay were overwritten in the process.
Closes#12656Closes#13333
Updated example which manually injects the filter.
It matches sibling example in functionality.
Also put html, js and css into separate files.
Also change anchors to buttons.
Closes#13402
The original statement is in the past tense (as if it were referring to a previous step of the
tutorial). The mentioned changes, however, are being done in this setp.
Closes#13452
The use element can reference external svg's (same origin) and can include
xlink javascript urls or foreign object that can execute xss.
This change disallows `<use>` elements in sanitized SVG markup.
An example of a malicious SVG document would be:
SVG to sanitize:
```
<svg><use xlink:href="test.svg#xss" /></svg>
```
External SVG file (test.svg)
```
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" width="100"
height="100"
id="xss">
<a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="javascript:alert(1)">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</a>
</svg>
```
Here the SVG to sanitize loads in the `test.svg` file via the `<use>` element.
The sanitizer is not able to parse this file, which contains malicious
executable mark-up.
This can only be taken advantage of if the external file is available via the
same origin restrictions in place.
Closes#13453
BREAKING CHANGE:
The `<use>` element is now removed from SVG passed to the `$sanitize` service.
This element is only used to import external SVG resources, which is a security
risk as the `$sanitize` service does not have access to the resource in order
to sanitize it.
Previously the contents of the `ngTransclude` element would always be emptied,
even if there was no transclusion to replace it.
Now, optional slots that have not been filled with content will not cause
the `ngTransclude` contents to be emptied.
Closes#13426
"any of the parameter value" contains plural (any of the) as well as singular (value).
Fixed to be singular to match the rest of the text block.
Closes#13448
Previously $rootScope would be new for each test, but old $rootScopes would never be destroyed.
Now that we are able to destroy the $rootScope, doing so provides an opportunity for code to clean
up things like long-lived event handlers between tests.
Closes#13433
All the resolves for a route are now attached to the route's local scope,
as the property whose name is given by the `resolveAs` property on the
route definition.
If `resolveAs` is not specified it defaults to `$resolve`.
This will make it easier to use `ngRoute`, by being able to reference all
the resolve values for the route, directly on the scope, rather than having
to implement a controller just to copy the resolves across manually.
For example, rather than
```js
$routeProvider.when('/', {
resolve: {
item1: ($http) => $http.get(...),
item2: ($http) => $http.get(...)
},
template: '<my-app item1="vm.item1" item2="vm.item2">'</my-app>`,
controllerAs: 'vm',
controller: ['item1', 'item2', function(item1, item2) {
this.item1 = item1;
this.item2 = item2;
}]
});
```
one can now do
```js
$routeProvider.when('/', {
resolve: {
item1: ($http) => $http.get(...),
item2: ($http) => $http.get(...)
},
template: '<my-app item1="$resolve.item1" item2="$resolve.item2">'</my-app>`
});
```
BREAKING CHANGE:
A new property is being attached to the scope of the route. The default name
for this property is `$resolve`. If your scope already contains a property
with this name then it will be hidden or overwritten.
In this case, you should choose a custom name for this property, that will
not collide with other properties on the scope, by specifying the `resolveAs`
property on the route.
Closes#13400
The example has been expanded to make it easier to provoke the
behavior that the description is talking about (rollbackViewValue
and programmatic model updates)
Related #13340
The new prepare class is added before the animation is pushed to the
queue and removed before the animation runs, i.e. it is immediately
available when a structural animation (enter, leave, move)
is initialized.
The class can be used to apply CSS to explicitly hide these elements
to prevent a flash of content before the animation runs.
This can happen if a structural animation (such as ng-if) sits at the
bottom of a tree which has ng-class animations on the parents.
Because child animations are spaced out with requestAnimationFrame,
the ng-enter class might not be applied in time, so the ng.if element is
briefly visible before its animation starts.
During parent structural animations, ongoing animations on child elements
are closed. These child elements are identified by their data-ng-animate
attribute. If an element is the clone of an animating element,
it might have this attribute, but no animation runner associated with it,
so we need to ignore it.
Fixes#11992Closes#13424
Prior to this fix the provided options object would be
altered as the animation kicks off due to the underlying
mechanics of ngAnimate. This patch ensures that a
copy of the provided options is used instead. This patch
also works for when `$animateCss` is used by itself.
Fixes#13040Closes#13175
Previously, options.delay was only considered when a class added an
extra transition style (which leads to style recalculation).
Fixes#13355Closes#13363
Some preprocessors such as Jade will automatically provide a value for an attribute
rather than leave it empty. E.g. `<div ng-transclude="ng-transclude">`.
In these situations we still want to use the default transclusion slot.
Closes#12934Closes#13383
When calling `$parse` with `undefined` as the expression and with
an interceptor, then when the function is evaluated, then call the
interceptor
Closes: #13367Closes: #13373
Introduced changes:
- Deprecate passing a promise as `timeout` (for `$resource` actions).
It never worked correctly anyway.
Now a warning is logged (using `$log.debug()`) and the property is
removed.
- Add support for a boolean `cancellable` property in actions'
configuration, the `$resource` factory's `options` parameter and the
`$resourceProvider`'s `defaults` property.
If true, the `$cancelRequest` method (added to all returned values for
non-instance calls) will abort the request (if it's not already
completed or aborted).
If there is a numeric `timeout` specified on the action's configuration,
the value of `cancellable` will be ignored.
Example usage:
```js
var Post = $resource('/posts/:id', {id: '@id'}, {
get: {
method: 'GET',
cancellable: true
}
});
var currentPost = Post.get({id: 1});
...
// A moment later the user selects another post, so
// we don't need the previous request any more
currentPost.$cancelRequest();
currentPost = Post.get({id: 2});
...
```
BREAKING CHANGE:
Using a promise as `timeout` is no longer supported and will log a
warning. It never worked the way it was supposed to anyway.
Before:
```js
var deferred = $q.defer();
var User = $resource('/api/user/:id', {id: '@id'}, {
get: {method: 'GET', timeout: deferred.promise}
});
var user = User.get({id: 1}); // sends a request
deferred.resolve(); // aborts the request
// Now, we need to re-define `User` passing a new promise as `timeout`
// or else all subsequent requests from `someAction` will be aborted
User = $resource(...);
user = User.get({id: 2});
```
After:
```js
var User = $resource('/api/user/:id', {id: '@id'}, {
get: {method: 'GET', cancellable: true}
});
var user = User.get({id: 1}); // sends a request
instance.$cancelRequest(); // aborts the request
user = User.get({id: 2});
```
Fixes#9332Closes#13050Closes#13058Closes#13210
This is needed for languages for which the month on its own has a
different format (case) than when used as part of a date.
Closes#3744Fixes#10247Fixes#12642Closes#12844
The $$AnimateRunner class is now the same for the core $animate service
and the ngAnimate $animate service. Previously, the core used a different
implementation that didn't match the ngAnimate behavior with regard
to callbacks.
Closes#13205Closes#13347
When compiling a `replace` directive, the compiler merges the attributes from
the replaced element onto the template element.
Unfortunately, `setAttribute` and other related DOM methods do not allow certain
attribute names - in particular Angular 2 style names such as `(click)` and `[value]`.
This is relevant when using ngForward with Angular Material, since the `mgButton`
directive uses `replace` and in the former you often use `(click)`.
This fixes the problem but for those special attributes the speed is considerably
slow.
Closes#13317Closes#13318
Previously, the directive bindings were evaluated against the directive's
new (non-isolate) scope, instead of the correct (parent) scope.
This went unnoticed most of the time, since a property would be eventually
looked up in the parent scope due to prototypal inheritance. The incorrect
behaviour was exhibited when a property on the child scope was shadowing
that on the parent scope.
This commit fixes it.
Fixes#13021Closes#13025
Previously, we would check if an attribute indicates a multi-element
directive, now we only do this check if the attribute name actually
matches the multi-element name pattern.
Closes#12365
The API section now uses a multi-column list. This preserves the actual
order of items. Note that only browser that support @supports and
columns get the new behavior.
The line-breaking behavior of search results is also improved. Previously,
long words would break onto new lines or run into the second column.
Fixes#8089Closes#13074
BREAKING CHANGE:
ngMessage is now compiled with a priority of 1, which means directives
on the same element as ngMessage with a priority lower than 1 will
be applied when ngMessage calls the $transclude function.
Previously, they were applied during the initial compile phase and were
passed the comment element created by the transclusion of ngMessage.
To restore this behavior, custom directives need to have
their priority increased to at least "1".
BREAKING CHANGE:
Previously, an non array-like input would pass through the orderBy filter
unchanged.
Now, an error is thrown. This can be worked around by converting an object
to an array, either manually or using a filter such as
https://github.com/petebacondarwin/angular-toArrayFilter.
(`null` and `undefined` still pass through without an error, in order to
support asynchronous loading of resources.)
Closes#11255Closes#11719
Since we are promoting component directives as the building blocks of
Angular applications, this new helper provides a simpler method for
defining such directives. By using sensible, widely accepted, conventions
the number of parameters needed has been cut down dramatically.
Many component directives can now be defined by simply providing a `name`,
`template`/`templateUrl`, a `controller`, and `bindings`:
```js
myMod.component('myComp', {
template: '<div>My name is {{myComp.name}}</div>',
controller: function() {
},
bindings: { name: '=' }
});
```
Closes#10007Closes#12933
Previously, there was no check for the existence of an item in the
cache when calling `$cacheFactory.remove()` before modifying the cache size
count.
Closes#12321Closes#12329
It is now possible to configure the options sent to $http for template requests.
If no value is configured then the request will use the default $http options.
Thanks to @luckycadow for help on this feature
Closes#13188Closes#11868Closes#6860
Note, that (as a by-product of the previous implementation) only non-empty
data was passed through the `transformResponse` pipeline. This is no
longer the case.
When using a custom `transformResponse` function, one should make sure it
can also handle an empty (i.e. falsy) `data` argument appropriately.
Fixes#12976Closes#12979
In the updateOn:blur example, there is an input for user.data but the
result is missing and nowhere to see how the value changes compared to user.name.
Closes#13129
Changes:
* Modify warning message to indicate that `track by` can be used with `select as`,
but subject to certain limitations.
* Provide both a working and an non-working example.
* Explain why the latter does not work.
Closes#13007
The URL_REGEXP in use to perform validation in ngInput is too restrictive and fails to
follow RFC3987. In particular, it only accepts ftp, http, and https scheme components and
rejects perfectly valid schemes such as "file", "mailto", "chrome-extension",
etc. The regex also requires the scheme to be followed by two "/" but the RFC says
0 to n are acceptable. This change fixes both of these issues to better align to
the standard.
Closes#11341Closes#11381
Based on the current configuration, Karma will run the tests on both
Chrome and Firefox, which will result in an error if either browser is not
available on the user's machine. This commit adds a note and directions on
how to solve this.
Closes#13114
For simple expressions without filters that have a stateless interceptor
then handle the 2nd phase parse evaluation using `inputs`.
TL;DR
This fixes the issue that interpolated simple expressions were evaluated twice
within one digest loop.
Long version, things happen in the following order:
* There was an overhaul on $interpolate, this overhaul changed $parse and
incorporated the concept of an interceptor.
* Optimization on $parse landed so expressions that have filters without
parameters (or the parameters are constants) would be evaluated in 2 phases,
first to evaluate the expression sans the filter evaluation and then with
the filter evaluation. This also used interceptors [the second evaluation
issue was added here]
* More optimizations on $parse landed and now expressions could be evaluated
in 2 phases. One to get all the possible values that could change (lets call
this state), the state was checked by $watch to know if an expression changed.
The second to continue the evaluation (as long as this state is provided).
This, once again, used interceptors
The last change, was supposed to fix the issue, but there was an assumption in
the existing code that the code would always generate the 2 phases functions,
but that is not true. If the expression is simple enough (just like the one in
your case) then the 2-phase evaluations functions are not generated. In this
case, if a stateless interceptor was added (just like what $interpolate adds)
then the state was not used and you see the function being evaluated twice.
This explains why, if you change the expression from
`Hello {{log('A')}} {{log('B')}}!` to `Hello {{log('A') + ' ' + log('B')}}!`,
then the repetition is not there.
Closes#12983Closes#13002
The `controller` and `transclude` parameters of the linking function were not
mentioned in the description, but used in the examples.
This commit improves the description and links to the `$compile` API docs
for more details.
Closes#13028
Optional extra attributes may be defined either as:
- a map of attributes and values
- a function that takes the url as a parameter and returns a map
Closes#12558Closes#13061
Add `params` argument to the `when()` and `expect()` functions to give map regex
groups to keys on a new `params` argument of the `respond()` callback.
Add `whenRoute` and `expectRoute` methods to `$httpBackend` to support matching
URLs by patterns similar to those defined for `ngRoute`.
Closes#12406
Previously we assigned `noop` if there was no function but there is no
performance advantage in doing this since the check would have to happen
either at assignment time or at call time.
Removing this use of `noop` makes the code clearer, IMO :-)
Closes#12528
Since only one of three invocations of `initializeDirectiveBindings` actually
adds a `$destroy` handler to the scope (the others just manually call unwatch
as needed), we can move that code out of this method.
This also has the benefit of simplifying what parameters need to be passed
through to the linking functions
Closes#12528
We don't need to have values in the cache from previous tests. This was
causing failures in all subsequent tests when a single test failed due
to a memory leak.
Now that we reset the cache each time we do not need to store the cache
size at the start of each test
Closes#13013
When ngOptions is present on a select, the option directive should not be able to
register options on the selectCtrl since this may cause errors during the
ngOptions lifecycle.
This can happen in the following cases:
- there is a blank option below the select element, an ngModel
directive, an ngOptions directive and some other directive on the select
element, which compiles the children of the select
(i.e. the option elements) before ngOptions is has finished linking.
- there is a blank option below the select element, an ngModel
directive, an ngOptions directive and another directive, which uses
templateUrl and replace:true.
What happens is:
- the option directive is compiled and adds an element `$destroy` listener
that will call `ngModel.$render` when the option element is removed.
- when `ngOptions` processes the option, it removes the element, and
triggers the `$destroy` listener on the option.
- the registered `$destroy` listener calls `$render` on `ngModel`.
- $render calls `selectCtrl.writeValue()`, which accesses the `options`
object in the `ngOptions` directive.
- Since `ngOptions` has not yet completed linking the `options` has not
yet been defined and we get an error.
This fix moves the registration code for the `option` directive into the
`SelectController.registerOption()` method, which is then overridden by
the `ngOptions` directive as a `noop`.
Fixes#11685Closes#12972Closes#12968Closes#13012
Previously, specifying a negative `begin` whose abs value exceeds the
input's length, would behave unexpectedly (depending on the value of
`limit` relative to `begin`). E.g.:
```
limitToFilter('12345', 3, -7) === '1'
// but
limitToFilter('12345', 10, -7) === '123'
```
This commit fixes the unexpected behaviour, by setting `begin` to 0 in the
aforementioned cases. Thus, the previous examples become:
```
limitToFilter('12345', 3, -7) === limitToFilter('12345', 3, 0) === '123'
// and
limitToFilter('12345', 10, -7) === limitToFilter('12345', 10, 0) === '12345'
```
Fixes#12775Closes#12781
Before 1.3, it was possible to call `angular.mock.module()` from inside
another module. After this version additional calls were just ignored.
It is helpful to be able to do this since a test may have helper functions
that need to access "config"-time things such as constants or providers,
and without this change it is difficult to get hold of the `$provide`
object from within those helpers.
Closes#12887
`$interpolateProvider.startSymbol` & friends are often used dangerously, to embed Angular templating in other templating languages. This change documents that that is a very dangerous practice.
Linking to usage section makes it easier for beginners to find out what the config object looks like.
The General Usage section now features an example that actually uses $http(config), and the Shortcut Methods section has been moved so that it appears directly after.
Closes#12949Closes#12950
When the empty/blank option has a directive that transcludes, ngIf for example,
a comment will be added into the select. Previously, ngOptions used this
comment as the empty option, which would mess up the displayed options.
Closes#12190
This improves the search results for certain terms.
For example, previously guide/scope was unfindable with the search
term 'scope', now it's the first hit.
Closes#12937
Some animations make use of the `from` and `to` styling only for the
lifetime of the animation. This patch allows for those styles to be
removed once the animation is closed automatically within `$animateCss`.
Closes#12930
Prior to this fix anchoring would allow for a container to be a document
node or something higher beyond the body tag. This patch makes it fall
back to body incase the rootElement node exists as a parent ancestor.
Closes#12872
Relying on the body node to be present right at injection has
caused issues with unit testing as well as some animations on
the body element. Reverting this patch fixes these issues.
Closes#12874
Callbacks are detected within the internals of ngAnimate whenever an
animation starts and ends. In order to allow the user to set callbacks
the callback detection needs to happen during the next tick. Prior to
this fix we used $$rAF to do the tick detection, however, with this
patch we intelligently use $$postDigest to do that for us and then
only issue a call to `$$rAF` if necessary.
If `ngMessage` tried to add a message back in that was about to be removed
after an animation, the NgMessageController got confused and tried to detach
the newly added message, when the pending node was destroyed.
This change applies a unique `attachId` to the message object and its DOM
node when it is attached. This is then checked when a DOM node is being
destroyed to prevent unwanted calls to `detach`.
Closes#12856Closes#12903
In certain scenarios, IE10/11/Edge create unresponsive select elements.
The following contribute to the bug:
- There need to be at least 2 selects next to each other
- The option elements are added via javascript
- the option.value is accessed before it is set
- the option.label is added after the option.value has been set
- The first select is wrappend in an element with display: inline or
display: inline-block,
This cannot be tested in a unit-test or e2e test.
Closes#11314Closes#11795
If the `$viewValue` is empty then the `ng-empty` CSS class is applied
to the input. Conversely, if it is not empty the `ng-not-empty` CSS class
is applied. Emptiness is ascertained by calling `NgModelController.$isEmpty()`
Closes#10050Closes#12848
with arrow functions parenthesis are optional in case you have exactly
one argument to the function. the previous regexp assumed function
arguments are always inside parenthesis and so it didn't annotate
functions like `$http => $http.get(...)` correctly
Closes#12890
Now one can use `''`, `0`, `false` and `null` as option groups. Previously
all of these falsy values were treated as the option not being a member of
a group.
Closes#7015Closes#7024Closes#12888
BREAKING CHANGES
If your data contains falsy values for option groups, then these options
will now be placed into option groups. Only option groups that are `undefined`
will result in the option being put in no group. If you have data that
contains falsy values that should not be used as groups then you must
filter the values before passing them to `ngOptions` converting falsy
values to `undefined`.
For transcluded directives, the transclude function can be lazily compiled
most of the time since the contents will not be needed until the
`transclude` function was actually invoked. For example, the `transclude`
function that is passed to `ng-if` or `ng-switch-when` does not need to be
invoked until the condition that it's bound to has been matched. For
complex trees or switch statements, this can represent significant
performance gains since compilation of branches is deferred, and that
compilation may never actually happen if it isn't needed.
There are two instances where compilation will not be lazy; when we scan
ahead in the array of directives to be processed and find at least two of
the following:
* A directive that is transcluded and does not allow multiple transclusion
* A directive that has templateUrl and replace: true
* A directive that has a template and replace: true
In both of those cases, we will need to continue eager compilation in
order to generate the multiple transclusion exception at the correct time.
Closes#7047Closes#12840
BREAKING CHANGE:
`ngOptions` will now throw if `ngModel` is not present on the `select`
element. Previously, having no `ngModel` let `ngOptions` silently
fail, which could lead to hard to debug errors. The change should
therefore not affect any applications, as it simply makes the
requirement more strict and alerts the developer explicitly.
Leaner, more forceful style.
Fixes a grammatical problems with subject number doesn't agrees with the verb. (originally "We have built many features into
Angular which makes...", which reduces to "features...which makes").
More authoritative use of commas, such as the Oxford comma in lists of three or more.
Sentences that are sentences, not fragments. (Yes, that was a fragment just now. I'm not writing docs now that reflect the polish of the project.)
The English grammatical/stylistic notion of parallelism.
Etc. This is just polish. The ideas are fine.
Closes#10478
the script and style tag are explicitly blacklisted, so this doesn't change any functionality.
the change is done to improve code clarity.
Closes#12524
Closes#12524
BREAKING CHANGE: The svg support in is now an opt-in option
Applications that depend on this option can use to turn the option back on,
but while doing so, please read the warning provided in the documentation for
information on preventing click-hijacking attacks when this option is turned on.
Previously, even when `ng-jq` was empty (which should force the use of
jqLite), Angular tried to find jQuery on `window['']`. If it didn't find
anything there, it would fall back to jqLite (as expected).
Nonetheless, trying to access `window['']` calls `getElementById('')`,
which issues a warning in Firefox (maybe others).
This fix properly detects when `ng-jq` is empty and avoids trying to
access `window['']`.
Fixes#12741
Both browser reloads and iOS 9 bugs cause the window.location to report
a different href that which we have just set. The change does not become
available until the next tick.
This change generalises previous work to deal with reloads to deal with
the iOS 9 bug in the UIWebView component.
Closes#12241Closes#12819
There is an mismatch for status in controller and test.
In controller $scope.status = 'ERROR!' and in test we
expect($rootScope.status).toBe('Failed...') so the test will fail;
Closes#12834
When the min/max attributes are empty (i.e. `attrs.min/max === ''`), there
should be no min/max validation applied (i.e. all values should be valid
wrt min/max). This works correctly for `input[number]`, but not for date
input family (`input[date/datetime-local/time/week/month]`).
In the case on `input[number]`, an empty string for `attrs.min/max` is
translated to `undefined` for `minVal/maxVal` and a check for
`isUndefined(minVal/maxVal)` ensures that no min/max validation takes
place.
For the data input family, an empty string for `attrs.min/max` is
translated to `NaN` (by `parseDate()`), so an additional check (for
`isNaN(minVal/maxVal)`) is required.
Fixes#12363Closes#12785
As discussed in #10085, the original replacement string can be treated
as html when displayed by the browser so it replaces it with '...' string.
Closes#10103
Test that re-added controls propagate validity changes to the parent form.
Ensure that when a form / control that was removed and then attached
to a different parent, is renamed / deleted, the new parent will
be notified of the change.
Document that dynamic adding / removing of controls may require manually
propagating the current state of the control to the parent form.
This fixes cases where the control gets removed, but the control's
element stays in the DOM.
Previously, if the removed control's validity changed, a reference to
it would again be stored on its former parent form.
Fixes#12263
This delegates setting the control's parentForm to the parentForm's
$addControl method. This way, the model controller saves one instance
of looking up the parentForm controller. The form controller keeps two
lookups (one for its own ctrl, one for the optional parent).
This also fixes adding the parentForm in the following case:
- a control is removed from a parent, but its corresponding DOM
element is not destroyed
- the control is then re-added to the form
Before the fix, the control's parentForm was only set once during
controller initialization, so the the parentForm would not be set on
the control in that specific case.
IE11 (and maybe others) converts an `undefined` argument to `xhr.send()` to
string (`'undefined'`) for certain request methods (e.g. DELETE). This
causes the request to appear having a body, when it shouldn't.
Fixes#12141Fixes#12739
Closes
The postDigest handler was not being added if the first element in
to modify the CSS classes contained invalid CSS class names. This meant
that subsequent valid CSS class changes were not being handled since we
were not then adding the handler for those correct cases.
Closes#12674Closes#12725
- reorder the paragraphs to highlight more important info
- clarify what can / should be passed to the method,
and what to (not) expect from it
- clarify when the method will trigger a digest
Closes#12713Closes#11121Closes#12498
- add tests to ensure options with interpolated text are added / updated
- refactor tests for interpolated option values to use the
standard compile helper defined in the spec file.
- rephrase some test descriptions for clarity
Closes#12580
This is for options added without ngOptions.
Previously, an option with an interpolated value attribute would
not be updated if the binding changed, i.e. the select controller would
not recognize the changed option. Now the value attribute will
be observed if it contains an interpolation.
Closes#12005Closes#12582
Referring to the `user` as `form` in the previews is confusing,
since it makes it seem as though the data being displayed is attached
to the `form` object, when the `form` object is separate.
Closes#12687
`ng(Pattern|Minlength|Maxlength)` directives will now validate the
`ngModel` when on an element that is not an `input` or
a `textarea`. Previously, only their HTML5 counterparts worked on
every element.
This is because the three validators were extracted
into separate directives (see 26d91b653a
and 1be9bb9d35), whereas the aliased
attribute handling assumes the validators will only exist on
`input|textarea` (see d9b90d7c10 and
25541c1f87).
Since `ngMin` and `ngMax` are also aliased attributes, this means
observers of `min` and `max` will be fired if `ngMin` and `ngMax`
change. This will happen on any element, even if it does not have
an `ngModel`. However, since min/max validators are only ever added
as part of the `input[number|textarea]` types, even if the element
has an `ngModel`, no validators will be added.
Finally the commit also tests that `ng-required` works on any element,
although that validator worked on all elements before this fix.
Fixes#12158Closes#12658
This reverts the previous behaviour of using foreced reflows to deal
with preparation classes in favour of a system that uses
requestAnimationFrame (RAF).
Closes#12669Closes#12594Closes#12655Closes#12631Closes#12612Closes#12187
Since the HTML5 pattern validation constraint validates the input value,
we should also validate against the viewValue. While this worked in
core up to Angular 1.2, in 1.3, we changed not only validation,
but the way `input[date]` and `input[number]` are handled - they parse
their input values into `Date` and `Number` respectively, which cannot
be validated by a regex.
Fixes#12344
BREAKING CHANGE:
The `ngPattern` and `pattern` directives will validate the regex
against the `viewValue` of `ngModel`, i.e. the value of the model
before the $parsers are applied. Previously, the modelValue
(the result of the $parsers) was validated.
This fixes issues where `input[date]` and `input[number]` cannot
be validated because the viewValue string is parsed into
`Date` and `Number` respectively (starting with Angular 1.3).
It also brings the directives in line with HTML5 constraint
validation, which validates against the input value.
This change is unlikely to cause applications to fail, because even
in Angular 1.2, the value that was validated by pattern could have
been manipulated by the $parsers, as all validation was done
inside this pipeline.
If you rely on the pattern being validated against the modelValue,
you must create your own validator directive that overwrites
the built-in pattern validator:
```
.directive('patternModelOverwrite', function patternModelOverwriteDirective() {
return {
restrict: 'A',
require: '?ngModel',
priority: 1,
compile: function() {
var regexp, patternExp;
return {
pre: function(scope, elm, attr, ctrl) {
if (!ctrl) return;
attr.$observe('pattern', function(regex) {
/**
* The built-in directive will call our overwritten validator
* (see below). We just need to update the regex.
* The preLink fn guaranetees our observer is called first.
*/
if (isString(regex) && regex.length > 0) {
regex = new RegExp('^' + regex + '$');
}
if (regex && !regex.test) {
//The built-in validator will throw at this point
return;
}
regexp = regex || undefined;
});
},
post: function(scope, elm, attr, ctrl) {
if (!ctrl) return;
regexp, patternExp = attr.ngPattern || attr.pattern;
//The postLink fn guarantees we overwrite the built-in pattern validator
ctrl.$validators.pattern = function(value) {
return ctrl.$isEmpty(value) ||
isUndefined(regexp) ||
regexp.test(value);
};
}
};
}
};
});
```
Prior to this fix if `$animateCss` was called multiple on the same
element with new animation data then the preceeding fallback timout
would cause the animation to cancel midway. This fix ensures that
`$animateCss` can be triggered multiple times and only when the final
timeout has passed then all animations will be closed.
Closes#12490Closes#12359
- Change some wordings to make them more understandable
- Reorder the paragraphs so they can be read more easily as a coherent text
- Add examples for static single / multiple selects, and non-selected option
- Add example for select with repeated options
- Remove form-related info from ngOptions select (doesn't apply)
Setting the default value in a select is a real trap for beginners, questions about how to do this on StackExchange have been view more than 40000 times in the last year. This changes updates the documentation to make it clearer.
Closes#12546
When `options.delay` is passed into `$animateCss`the delay style would be
applied after the add/remove CSS classes are evaluated (for transitions).
At this point it is too late for the delay to be picked up (this
functionality however does work with keyfarme animations).
This patch ensures that the provided `options.delay` value is
applied before the CSS classes are applied to the element.
Closes#12584
Unnecessary split. The url returns a string without the hash,
resulting in an undefined value and making the test fails.
Matches the phonecat app more closely, too.
Closes#12590
A core version of `$animateCss` can now be injected when
ngAnimate is not present. This core version doesn't trigger any
animations in any way. All that it does is apply the provided from
and/or to styles as well as the addClass and removeClass values.
The motivation for this feature is to allow for directives to activate
animations automatically when ngAnimate is included without the need to
use `$animate`.
Closes#12509Closes#12570
It's unpredictable sometimes to ensure that a browser triggers a reflow
for an animation. Prior to this patch, reflows would be applied
carefully in between parent/child DOM structure, but that doesn't seem
to be enough for animations that contain complex CSS styling rules.
Closes#12553Closes#12554Closes#12267Closes#12554
Fix markdown quotation of a `;` so that it is properly rendered in the docs.
Makes it more consistent with the other codeblocked characters in the
list.
Closes#12549
Remove the `new` from the minErr assignment, so the closure compiler
can detect the errors correctly. Also removes the leading $ from the
variable name to be consistent with the Angular.js file.
Closes#12386Closes#12416
Summary:
- Use properly capitalized GitHub brand name
- Correctly negate two clauses using "nor" (caitp feels this may confuse
non-english speakers and need to be revised, but hopefully not)
- Correctly end sentence with period
Closes#12497
The removed line pointed to a removed example. Re-adding the example
would have been of questionable value, as it introduced several
concepts without context. It's therefore better to link to the guide,
which provides a better introduction.
Closes#12167
The original file included a code sample using `angular.injector(['myModule', 'ng'])`,
which appears to be incorrect when trying to retrieve anything attached to `myModule`.
Reversing the args fixes this.
Closes#12292
It will be good to have the binding results in the CSS classes /
binding to form / control state example, similar to the Simple Form
example.
Closes#12326
When users accidentally just pass a single string, e.g.
`angular.injector('myModule')`, this change give them a better error message.
Currently Angular just reports that the module with the name 'm' is missing,
as it's iterating through all characters in the string, instead of all strings
in the module.
Closes#12285
The legacy methods, `success` and `error`, have been deprecated.
Set this to `false` to cause `$http` to throw an error if these methods are
used in the application.
For now it defaults to `true`. In a future release we will remove these
methods altogether.
DEPRECATION NOTICE:
The legacy methods 'success' and 'error' on promises returned by $http
are now deprecated.
Closes#12112Closes#10508
Previously there was a custom built en-us locale that was included with
angular.js. This made likely that it would get out of sync with the real
en-us locale that is generated from the closure library.
This change removes that custom one and uses the generated one instead.
This also has the benefit of preventing the unwanted caught error on trying
to load `ngLocale` during angular bootstrap.
Closes#12462Closes#12444Closes#12134Closes#8174
The previous explanation in parentheses created a bit of confusion because the documentation stated to leave off the `listener`, but then said "be prepared for multiple calls to your listener". The new explanation clarifies that it is indeed the `watchExpression` that will be executed multiple times.
Closes#12429
Previously, optional empty '='-bound expressions were ignored ---
erroneously they stopped being ignored, and no tests were caused to
fail for this reason. This change restores the original ignoring
behaviour while still preventing other errors fixed by 8a1eb16Closes#12144Closes#12259Closes#12290
In some cases people will not follow all URL standards and may have
unescaped = characters in their GET parameter values. Currently $location
will not parse them correctly dropping everything after the unescaped =.
This change includes all characters after the first `=` up to the next `&`.
Closes#12351
This reverts commit 70ce425e6a.
There are internal projects in Google that generate their own version
of angular.js and so this commit caused those projects to break.
We are going to look into a more satisfactory way of getting this change
in.
In Chrome, if two alert boxes pop up, without enough time between them,
Protractor (or possibly ChromeDriver) sometimes fails to recognize the
second alert.
Do not trigger Firefox validation on form initialization.
- Do not set a value to an <input> field if the field already has the same value
Closes#12102
We cannot re-enter a `$apply` block while already in a `$apply` or `$digest`
phase.
Before this change such an invalid call to `$apply` was incorrectly clearing
the phase, which meant that a second invalid `$apply` call was being allowed.
Closes#12174
This fix ensures that a structural child animation will never close a
parent class based early so that the CSS classes for the child are ready
for it to perform its CSS animation. The reasoning for the past for this
was because their is a one frame delay before the classes were applied.
If a parent and a child animation happen at the same time then the
animations may not be picked up for the element since the CSS classes
may not have been applied yet.
This fix ensures that parent CSS classes are applied in a synchronous
manner without the need to run a one RAF wait. The solution to this was
to apply the preparation classes during the pre-digest phase and then
apply the CSS classes right after with a forced reflow paint.
BREAKING CHANGE: CSS classes added/removed by ngAnimate are now applied
synchronously once the first digest has passed.
The previous behavior involved ngAnimate having to wait for one
requestAnimationFrame before CSS classes were added/removed. The CSS classes
are now applied directly after the first digest that is triggered after
`$animate.addClass`, `$animate.removeClass` or `$animate.setClass` is
called. If any of your code relies on waiting for one frame before
checking for CSS classes on the element then please change this
behavior. If a parent class-based animation, however, is run through a
JavaScript animation which triggers an animation for `beforeAddClass`
and/or `beforeRemoveClass` then the CSS classes will not be applied
in time for the children (and the parent class-based animation will not
be cancelled by any child animations).
Closes#11975Closes#12276
Use `extend` on `Promise.prototype` and `Deferred.prototype`, to avoid having to
manually set `constructor` on the overwritten prototypes.
Closes#10697
Instead of merging existing animation option to new animation options we can
merge in reverse and utilize old animation runner.
Closes#12266Closes#12007
This change calls $timeout with the invokeApply
parameter set to false which stops ngAnimate
from invoking its changes inside an $apply block
Closes#12281Closes#12282
Line 548: Remove duplicate 'not' and clarify wording
Line 556: Remove period within parenthetical statement
Line 560: Clarify wording
Line 570: Capitalize 'E.g.' at the start of a sentence
Closes#12252
This regeneration takes into account the changes due to:
* update to closure library 27.0.1
* fix to default position of negative sign in currency formats
Closes#12307Closes#12362
Previously there was a custom built en-us locale that was included with
angular.js. This made likely that it would get out of sync with the real
en-us locale that is generated from the closure library.
This change removes that custom one and uses the generated one instead.
This also has the benefit of preventing the unwanted caught error on trying
to load `ngLocale` during angular bootstrap.
Closes#12134Closes#8174
Previously, if you navigate outside of the Angular application, say be clicking
the back button, the $location service would try to handle the url change
and error due to the URL not being valid for the application.
This fixes that issue by ensuring that a reload happens when you navigate
to a URL that is not within the application.
Closes #11667
There are two different features in Angular that can break CSP rules:
use of `eval` to execute a string as JavaScript and dynamic injection of
CSS style rules into the DOM.
This change allows us to configure which of these features should be turned
off to allow a more fine grained set of CSP rules to be supported.
Closes#11933Closes#8459Closes#12346
`$animateCss` is a fan of transition animations, but it turns out that
if only a keyframeStyle is provided into the animation upon constrution
then it will quit because it assumes that nothing will be animated
(since no classes or styles are being applied). This patch ensures that
a keyframe style can solely be applied to an animation triggered with
`$animateCss`.
```js
// this will now work as expected
$animateCss(element, { keyframeStyle: '1s rotate' }).start();
```
Closes#12124Closes#12340
This fix ensures that both `$animateCss` and `$animate` swallow the error
when an animation takes place in the sitation that the element is removed
from the parent element sometime before or during the preparation stages of the
animation.
Closes#11975Closes#12338
A controller is a instantiated object created **from** a constructor function.
It was not accurate to describe a Controller **as** a constructor function.
Closes#11888
This reverts commit 8a1eb1625c.
This commit broke the tabs component on the material project,
which caused internal breakages. Will open a separate issue to
look into the issue.
Move all the calls to $sce.getTrustedUrl inside $templateRequest, and
also trust the contents of the cache. This allows prefetching templates
and to bypass the checks on things where they make no sense, like
templates specified in script tags.
Closes#12219Closes#12220Closes#12240
If you previously returned a object from a controller constructor function,
it would not be bound to the scope. As of 1.4 it does, and can cause
unexpected objects as the scope.
Closes#12227
While directives are not allowed to request both a new (normal) and an
isolate scope on the same element, the relevant check was not performed
correctly when the directive requesting the isolate scope had a lower
priority and specified a `templateUrl`.
In that case, the check was deferred until the template was fetched, but
the info about other directives requesting a new (normal) scope was not
properly preserved (in `previousCompileContext`).
This commit fixes this, so now an error is thrown (as expected).
Fixes#12215Closes#12217
It turns out that the options that are displayed are more constrained than
just whether the property starts with a $ character.
If the values collection is array-like then we only display the options that
are identified by numerical properties - it's an array right?
So this commit aligns `getWatchables` with `getOptions`.
See #12010
Previously, if you navigated outside of the current base URL angular
crashed with a `Cannot call method 'charAt' of undefined` error.
Closes#11302Closes#4776
By refactoring to use a Schwartzian transform, we can ensure that objects
with no custom `toString` or `toValue` methods are just ordered using
their position in the original collection.
Closes#11866Closes#11312Closes#4282
Shadows only when attributes are non-optional and not own properties,
only stores the observed '@' values when they are indeed strings.
Partial revert of 6339d30d1379689da5eec9647a953f64821f8b0
Closes#12151Closes#12144
The `window.location.hash' setter will strip of a single leading hash character
if it exists from the fragment before joining the fragment value to the href
with a new hash character.
This meant that if we want the fragment to lead with a hash character, we
must do `window.location.hash = '##test'` to ensure that the first hash
character in the fragment is not lost.
The `$location.hash` setter works differently and assumes that the value
passed is the the full fragment, i.e. it does not attempt to strip off a
single leading hash character.
Previously, if you called, `$location.hash('#test')`, the leading hash was
being stripped and the resulting url fragment did not contain this hash:
`$location.hash()`, then became 'test' rather than `#test`, which led to
an infinite digest.
Closes#10423Closes#12145
As of Angular 1.3 `$setViewValue` already calls `$apply` and triggers a
digest cycle, so now there is no need wrapping the `$setViewValue`
function call with `$apply`, which will just trigger an additional digest
cycle.
2015-06-16 13:20:57 +03:00
1692 changed files with 255257 additions and 84936 deletions
# **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.)
- 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)-->
**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).
-->
**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) -->
**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.
Comment on an issue to let others know what you're working on, or create a new issue if your work
doesn't fit within the scope of any of the existing doc fix projects.
minimize duplication of effort. Create a new issue (or comment on a related existing one) to let
others know what you're working on.
For large fixes, please build and test the documentation before submitting the PR to be sure you haven't
accidentally introduced any layout or formatting issues. You should also make sure that your commit message
is labeled "docs:" and follows the **Git Commit Guidelines** outlined below.
If you're making a small change (typo, phrasing) don't worry about filing an issue first. Use the
friendly blue "Improve this doc" button at the top right of the doc page to fork the repository
in-place and make a quick change on the fly. The commit message is preformatted to the right type
and scope, so you only have to add the description.
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue "Improve this doc" button at the top right of the doc page to fork the repository in-place and make a quick change on the fly. When naming the commit, it is advised to still label it according to the commit guidelines below, by starting the commit message with **docs** and referencing the filename. Since this is not obvious and some changes are made on the fly, this is not strictly necessary and we will understand if this isn't done the first few times.
For large fixes, please build and test the documentation before submitting the PR to be sure you
haven't accidentally introduced any layout or formatting issues. You should also make sure that your
commit message follows the **[Commit Message Guidelines][developers.commits]**.
grunt.registerTask('test','Run unit, docs and e2e tests with Karma',['jshint','jscs','package','test:unit','test:promises-aplus','tests:docs','test:protractor']);
grunt.registerTask('test','Run unit, docs and e2e tests with Karma',[
'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 unit tests with Karma',['tests:jquery']);
grunt.registerTask('test:modules','Run the Karma module tests with Karma',['build','tests:modules']);
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',
'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: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.
<p>Note: If you're viewing this page via a <code>file://</code> URL, the "next" and "previous" Glyphicon buttons on the left and right might not load/display properly due to web browser security rules.</p>
<p><aclass="btn btn-lg btn-primary"href="#"role="button">Sign up today</a></p>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p>Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna.</p>
<p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.</p>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<h2class="featurette-heading">First featurette heading. <spanclass="text-muted">It'll blow your mind.</span></h2>
<pclass="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
<h2class="featurette-heading">Oh yeah, it's that good. <spanclass="text-muted">See for yourself.</span></h2>
<pclass="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
<h2class="featurette-heading">And lastly, this one. <spanclass="text-muted">Checkmate.</span></h2>
<pclass="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
<!-- Main jumbotron for a primary marketing message or call to action -->
<divclass="jumbotron">
<h1>Theme example</h1>
<p>This is a template showcasing the optional theme stylesheet included in Bootstrap. Use it as a starting point to create something more unique by building on or modifying it.</p>
<liclass="list-group-item">Dapibus ac facilisis in</li>
<liclass="list-group-item">Morbi leo risus</li>
<liclass="list-group-item">Porta ac consectetur ac</li>
<liclass="list-group-item">Vestibulum at eros</li>
</ul>
</div><!-- /.col-sm-4 -->
<divclass="col-sm-4">
<divclass="list-group">
<ahref="#"class="list-group-item active">
Cras justo odio
</a>
<ahref="#"class="list-group-item">Dapibus ac facilisis in</a>
<ahref="#"class="list-group-item">Morbi leo risus</a>
<ahref="#"class="list-group-item">Porta ac consectetur ac</a>
<ahref="#"class="list-group-item">Vestibulum at eros</a>
</div>
</div><!-- /.col-sm-4 -->
<divclass="col-sm-4">
<divclass="list-group">
<ahref="#"class="list-group-item active">
<h4class="list-group-item-heading">List group item heading</h4>
<pclass="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
<ahref="#"class="list-group-item">
<h4class="list-group-item-heading">List group item heading</h4>
<pclass="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
<ahref="#"class="list-group-item">
<h4class="list-group-item-heading">List group item heading</h4>
<pclass="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
</div>
</div><!-- /.col-sm-4 -->
</div>
<divclass="page-header">
<h1>Panels</h1>
</div>
<divclass="row">
<divclass="col-sm-4">
<divclass="panel panel-default">
<divclass="panel-heading">
<h3class="panel-title">Panel title</h3>
</div>
<divclass="panel-body">
Panel content
</div>
</div>
<divclass="panel panel-primary">
<divclass="panel-heading">
<h3class="panel-title">Panel title</h3>
</div>
<divclass="panel-body">
Panel content
</div>
</div>
</div><!-- /.col-sm-4 -->
<divclass="col-sm-4">
<divclass="panel panel-success">
<divclass="panel-heading">
<h3class="panel-title">Panel title</h3>
</div>
<divclass="panel-body">
Panel content
</div>
</div>
<divclass="panel panel-info">
<divclass="panel-heading">
<h3class="panel-title">Panel title</h3>
</div>
<divclass="panel-body">
Panel content
</div>
</div>
</div><!-- /.col-sm-4 -->
<divclass="col-sm-4">
<divclass="panel panel-warning">
<divclass="panel-heading">
<h3class="panel-title">Panel title</h3>
</div>
<divclass="panel-body">
Panel content
</div>
</div>
<divclass="panel panel-danger">
<divclass="panel-heading">
<h3class="panel-title">Panel title</h3>
</div>
<divclass="panel-body">
Panel content
</div>
</div>
</div><!-- /.col-sm-4 -->
</div>
<divclass="page-header">
<h1>Wells</h1>
</div>
<divclass="well">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed diam eget risus varius blandit sit amet non magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Aenean lacinia bibendum nulla sed consectetur.</p>
<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">
// Some rules are not that important in tests and conflict with
// Jasmine or would make it easier to write some tests; we disable
// those ones here.
"no-invalid-this":"off",
"no-throw-literal":"off",
"no-unused-vars":"off"
},
"globals":{
// ngMocks
"module":false,
"inject":true
}
}
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.