Compare commits

...

107 Commits

Author SHA1 Message Date
Mike Brocchi d8f77817eb chore: update post LTS links (#17187)
Co-authored-by: Mike Brocchi <brocco@users.noreply.github.com>
2024-04-12 11:43:13 -06:00
Jeremy Elbourn 47bf11ee94 docs(changelog): fix wrong date in changelog for 1.8.3 2022-04-12 08:48:22 -07:00
Jeremy Elbourn b5aa42586e docs(changelog): fix typo in changelog for 1.8.3 2022-04-11 13:26:36 -07:00
Jeremy Elbourn cf16b241e1 docs(changelog): add release notes for 1.8.3
We're doing this final release to update poackage README files for npm.
2022-04-07 09:13:37 -07:00
Jeremy Elbourn 757d56ea9c docs(*): update end-of-life messages (#17177)
* Docs homepage
* Docs banner
* Security and support pages
* GitHub README
* CHANGELOG
2022-03-18 12:04:55 -07:00
Ed Clement f3624374e4 docs(eol): add EOL options text and link to template header used in every page
Closes #17164
2021-12-10 01:00:31 +02:00
Ed Clement fb04e424bb test(Angular): fix angularInit() tests on Safari v15+
Previously, the `angularInit()` tests assumed that the Safari browser
uses the `safari-extension:` protocol for browser extension URLs. This
is true for versions <15. However, since v15, Safari on iOS only
recognizes the `chrome-extension:` protocol, which causes the tests to
fail ([example failure][1]).

This commit updates the tests to use the correct protocol according to
the version of Safari used.

NOTE:
On macOS, Safari v15+ recognizes both `safari-extension:` and
`chrome-extension:`, so it is OK to always use the later with Safari
v15+ (regardless of the platform).

[1]: https://circleci.com/gh/angular/angular.js/3527

Co-authored-by: George Kalpakas <kalpakas.g@gmail.com>

Closes #17166
2021-12-09 22:20:18 +02:00
Ed Clement 6a52c4f90c test(input): fix tests on Firefox v93+
Since version 93, Firefox started more closely following the spec on
formatting `datetime-local` input values by removing trailing zeros from
the string representation of the value. This causes some of our tests to
fail ([example failure][1]).

For example, a value is reported by Firefox as `2009-01-06T16:25` while
the tests expect `2009-01-06T16:25:00.000`. I.e. Firefox started leaving
out seconds/milliseconds if they are zero.

According to [MDN][2], this is the correct behavior according to the
spec. Indeed the spec says that [if the value of the element is a valid
local date and time string, then it must be set to a **valid normalized
local date and time string**][3], where **valid normalized local date
and time string** is [defined as consisting of][4]:
> - A valid date string representing the date.
> - A U+0054 LATIN CAPITAL LETTER T character (T).
> - A valid time string representing the time, expressed as the
>   **shortest possible string** for the given time (e.g. **omitting the
>   seconds component** entirely if the given time is zero seconds past
>   the minute).

This commit fixes the relevant tests by explicitly specifying non-zero
values for seconds and milliseconds.

[1]: https://circleci.com/gh/angular/angular.js/3527
[2]: https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats
  #local_date_and_time_strings
[3]: https://html.spec.whatwg.org/multipage/input.html
  #local-date-and-time-state-(type=datetime-local)
[4]: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html
  #concept-datetime-local

Co-authored-by: George Kalpakas <kalpakas.g@gmail.com>
2021-12-09 22:19:58 +02:00
Gage Guzman ed30c4d0ea docs(README.md): add wiki link to MVC
Add a wiki link to MVC in case people have not heard of it before and
want to read about it more.

Closes #17152
2021-08-24 11:24:46 +03:00
dependabot[bot] 4032655100 chore(deps): bump js-yaml from 3.5.5 to 3.14.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.5.5 to 3.14.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.5.5...3.14.1)

Closes #17147
2021-06-12 16:25:47 +03:00
dependabot[bot] 47f8c65aca chore(deps): bump normalize-url from 4.5.0 to 4.5.1
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

Closes #17145
2021-06-12 15:26:29 +03:00
Michael Prentice 56b0ee3275 chore(e2e): run tests against Chrome 91 on macOS Catalina
Closes #17144
2021-06-12 15:25:34 +03:00
Michael Prentice 58cd897420 chore(e2e): run tests against Firefox 85 on macOS Catalina
Closes #17142
2021-06-12 15:22:18 +03:00
Michael Prentice c3769a6b5b chore(functions): support NodeJS LTS v14. fix audit issues
- update firebase scripts
- from: 6 vulnerabilities found - Severity: 6 High
- to: 0 vulnerabilities found

Closes #17140
2021-06-07 20:02:55 +03:00
Michael Prentice c140d89583 chore(build): support NodeJS LTS v14. fix audit issues
- from:483 vulnerabilities found - 273 Low | 38 Moderate | 168 High | 4 Critical
- to: 389 vulnerabilities found - 259 Low | 28 Moderate | 98 High | 4 Critical

Closes #17139
2021-06-05 20:46:59 +03:00
Michael Prentice 1a5b0517d0 docs(misc/Version Support Status): update URL for XLTS.dev
- the subdomain was switched to a path many months ago
- the angularjs.xlts.dev site will soon be used for hosting something else
  and the redirect removed (ASAP)

Closes #17136
2021-06-01 16:23:10 +03:00
Ikko Ashimine e29900c78f docs($parse): fix typo in parse.js
Propogate -> Propagate
2021-04-22 09:49:07 +01:00
dependabot[bot] 02545a8bab chore(deps): bump y18n from 3.2.1 to 3.2.2
Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17122
2021-03-31 19:45:19 +03:00
Ikko Ashimine 9bff2ce8fb docs($parse): fix typo in lval.ngdoc
assigment -> assignment

Closes #17120
2021-03-09 13:27:46 +02:00
dependabot[bot] d463206d0a chore(deps): bump elliptic from 6.5.3 to 6.5.4
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17119
2021-03-09 13:25:06 +02:00
dependabot[bot] ae8e903edf chore(deps): bump bl from 1.2.2 to 1.2.3
Bumps [bl](https://github.com/rvagg/bl) from 1.2.2 to 1.2.3.
- [Release notes](https://github.com/rvagg/bl/releases)
- [Commits](https://github.com/rvagg/bl/compare/v1.2.2...v1.2.3)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17116
2021-02-06 21:31:35 +02:00
dependabot[bot] 89c7794b21 chore(deps): bump https-proxy-agent from 2.2.1 to 2.2.4
Bumps [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) from 2.2.1 to 2.2.4.
- [Release notes](https://github.com/TooTallNate/node-https-proxy-agent/releases)
- [Commits](https://github.com/TooTallNate/node-https-proxy-agent/compare/2.2.1...2.2.4)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17115
2021-02-06 21:30:54 +02:00
dependabot[bot] 8a941b8ea9 chore(deps): bump ini from 1.3.4 to 1.3.7
Bumps [ini](https://github.com/isaacs/ini) from 1.3.4 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.4...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17099
2021-02-06 21:30:11 +02:00
George Kalpakas 30a4424da2 chore(ci): only run deploy-code-firebase on master
Previously, the `deploy-code-firebase` CI job was run on any build
corresponding to a git tag, the master branch or the stable branch.
Given that all runs of `deploy-code-firebase` deploy to the same
Firebase project (and overwrites previous deployments), there is no
point in deploying from multiple branches/tags.

This commit fixes this by ensuring that we only run the
`deploy-code-firebase` job on builds for the master branch, which
contains the most up-to-date code/configuration.
2021-02-06 19:46:27 +02:00
George Kalpakas a6fa1ce76e chore(ci): fix failing deploy-code job
In #17114, the `deploy-code` CI job was modified to also run some
commands via `yarn`. It turns out that this breaks on CI, because the
`deploy-code` job uses the `cloud-sdk` executor that does not have
`yarn` installed. ([Example failure][1])

This commit fixes this by splitting the `deploy-code` job into two jobs:
- `deploy-code-files` uses the `cloud-sdk` and uploads the files to
  Google Cloud.
  (This is essentially the `deploy-code` job from before #17114.)
- `deploy-code-firebase` uses the `default` executor (which has `yarn`
  installed) and deploys to Firebase.
  (This essentially includes the new bits added in #17114.)

[1]: https://circleci.com/gh/angular/angular.js/2712
2021-02-06 13:42:28 +02:00
George Kalpakas 63d613fccf fix(code.angularjs.org): correctly re-construct paths on Windows in sendStoredFile()
Previously, the `sendStoredFile()` Firebase function used `.split('/')`
to split the request path into segments and later used `path.join()` to
join them back together. This worked fine on *nix based systems, which
use `/` as the path separator. On Windows, however, where `\` is the
path separator, the re-constructed paths could not be retrieved from the
Google Cloud Storage bucket. This prevented the Firebase emulators from
working correctly when testing the function locally on Windows.

This commit fixes the issue by using `.join('/')` to join the path
segments back together.

Closes #17114
2021-02-06 11:50:11 +02:00
George Kalpakas ed7d506b7d chore(build): update Firebase dependencies to latest versions
This commit updates `firebase-admin`, `firebase-functions` and
`firebase-tools` to latest versions to take advantage of the most recent
fixes and improvements.
2021-02-06 11:50:06 +02:00
George Kalpakas 12df4d6a00 chore(build): use Node.js v12 for Firebase functions on {code,docs}-angularjs-org 2021-02-06 11:50:06 +02:00
George Kalpakas 4267ad65a5 chore(ci): use default project from config when deploying to Firebase
Previously, when deploying `scripts/{code,docs}.angularjs.org-firebase/`
to Firebase, we explicitly specified the target projects. Since the
project IDs are also specified in the respective `.firebaserc` files,
this was unnecessary (and meant we had multiple places to update if the
IDs changed).

This commit simplifies the process by automatically targeting the
default projects (as configured in the `.firebaserc` files) when
deploying to Firebase in CI.
2021-02-06 11:50:06 +02:00
George Kalpakas 66ada20d1b chore(ci): also deploy code-angularjs-org to Firebase
Previously, we only deployed the built files to Google Cloud Storage for
the `code-angularjs-org` Firebase project. This meant that the other
Firebase services (such as functions, hosting, storage) were not updated
when we made changes to their source code or configuration.
(This isn't a problem at the moment, since the code/configuration for
these service changes infrequently, but could bite us in the future.)

This commit fixes this by ensuring that we deploy to all enabled
Firebase services (currently functions, hosting and storage).
2021-02-06 11:50:06 +02:00
George Kalpakas c7d68fa044 chore(ci): also deploy Firebase functions to docs-angularjs-org
Previously, we only deployed to Firebase hosting for the
`docs-angularjs-org` Firebase project. This meant that the deployed
functions used an old version of Node.js and started failing once
support was dropped for that version. See #17111 for details.

This commit fixes this by ensuring that we deploy to all enabled
Firebase services (currently functions and hosting).

Fixes #17111
Fixes angular/angularjs.org#251
2021-02-06 11:50:06 +02:00
George Kalpakas 667ff87ab5 chore(ci): deploy to docs.angularjs.org from within the corresponding directory
Previously, in order to deploy to Firebase from
`scripts/docs.angularjs.org-firebase/`, we had to copy the
`firebase.json` file to the repository root and adjust the contained
paths accordingly.

By running the `firebase` CLI directly (instead of via `yarn`), we are
able to deploy from `docs.angularjs.org-firebase/` directly. This
simplifies the deployment (and local testing) process and paves the way
for also deploying from `code.angularjs.org-firebase/` in a subsequent
commit.
2021-02-06 11:50:06 +02:00
George Kalpakas b481a16576 chore(ci): copy deployment files inside the respective Firebase directories
We have the `scripts/{code,docs}.angularjs.org-firebase/` directories,
which contain the necessary code and config for deploying built files to
the `code-angularjs-org` and `docs-angularjs-org` Firebase projects
respectively.

Previously, some of the files that needed to be deployed to Firebase (or
Google Cloud) were placed outside these directories (e.g. in
`deploy/{code,docs}/`).

Since these files are only used for deploying to Firebase/Google Cloud,
this commit changes the deployment process to instead copy the files
inside the directories. In a subsequent commit, this will allow
simplifying the deployment process, by running it from inside each
directory instead of having to copy the `firebase.json` files to the
repository root (and adjust the paths).

These are the destination directory changes:

| Before       | After                                       |
|--------------|---------------------------------------------|
| deploy/code/ | scripts/code.angularjs.org-firebase/deploy/ |
| deploy/docs/ | scripts/docs.angularjs.org-firebase/deploy/ |
2021-02-06 11:50:06 +02:00
George Kalpakas 6e052a4243 chore(code.angularjs.org): check in yarn.lock file (and remove package-lock.json)
Since we are using `yarn` to install dependencies, it makes sense to use
`yarn.lock` as the lockfile (and get rid of the unused
`package-lock.json`).
2021-02-06 11:50:05 +02:00
George Kalpakas 2e72ea13fa docs(changelog): fix typos in 1.8.1/1.8.2 notes
- Remove stray backtick.
- Add missing preposition (`identical` --> `identical to`).
- Remove 1.8.1 change from the 1.8.2 section.

Closes #17093
2020-10-25 11:42:13 +02:00
Pete Bacon Darwin 9b3b6f7f79 docs(changelog): add release notes for 1.8.2 2020-10-21 12:48:47 +01:00
George Kalpakas e41f018959 fix($sceDelegate): make resourceUrlWhitelist() is identical trustedResourceUrlList()
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
2020-10-14 15:44:24 +03:00
George Kalpakas 71d19f120a docs(*): fix docs on recently deprecated properties/methods
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
2020-10-14 15:44:24 +03:00
frosty 8aa3389ed6 docs(version-support-status): add link to extended long term support 2020-10-08 19:16:57 +01:00
Pete Bacon Darwin bb480064b9 docs(changelog): add release notes for 1.8.1 2020-10-05 14:04:33 +01:00
George Kalpakas 6b86a888cb chore(CircleCI): fix deploy-docs job
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
2020-10-01 02:15:59 +03:00
dependabot[bot] f17c7d8f66 chore(deps): bump node-fetch from 2.6.0 to 2.6.1
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17073
2020-10-01 00:54:33 +03:00
dependabot[bot] e7c105c592 chore(deps): bump node-fetch
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17072
2020-10-01 00:53:44 +03:00
dependabot[bot] d0e7dc14bb chore(deps): bump node-fetch
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17071
2020-10-01 00:52:21 +03:00
dependabot[bot] 0a746a2521 chore(deps): bump http-proxy from 1.16.2 to 1.18.1
Bumps [http-proxy](https://github.com/http-party/node-http-proxy) from 1.16.2 to 1.18.1.
- [Release notes](https://github.com/http-party/node-http-proxy/releases)
- [Changelog](https://github.com/http-party/node-http-proxy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/http-party/node-http-proxy/compare/1.16.2...1.18.1)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17070
2020-10-01 00:50:49 +03:00
Michael Prentice 2f73f6a8c0 chore(copyright): update to Google LLC
- fix minor typo in comment

Relates to angular/angular#27880

Closes #17062
2020-10-01 00:49:43 +03:00
George Kalpakas e1ecd184c5 chore(SauceLabs): update sauce-connect to version 4.6.2
Closes #17078
2020-10-01 00:47:23 +03:00
Martin Staffa abff650016 chore(ci): add engines to docs firebase deployment
According to the Firebase docs, this field is necessary: https://firebase.google.com/docs/functions/manage-functions#set_nodejs_version
It's also a good idea to set it because NodeJS 8 is end-of-life, and Firebase will require Node 10 for all functions by  March 15, 2021.
2020-09-30 19:41:06 +01:00
dependabot[bot] b96a1de842 chore(deps): bump is-my-json-valid from 2.15.0 to 2.20.5
Bumps [is-my-json-valid](https://github.com/mafintosh/is-my-json-valid) from 2.15.0 to 2.20.5.
- [Release notes](https://github.com/mafintosh/is-my-json-valid/releases)
- [Commits](https://github.com/mafintosh/is-my-json-valid/compare/v2.15.0...v2.20.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-30 19:35:46 +01:00
Michael Prentice b42ab51ad9 docs(security): add SECURITY.md 2020-09-30 19:34:45 +01:00
Joey Perrott 3dd42cea68 refactor(misc): remove usages of whitelist and blacklist
Remove miscellaneous usages and references to usages of whitelist and blacklist
throughout the repository.
2020-09-30 18:46:45 +01:00
Joey Perrott 767381020d refactor(SanitizeUriProvider): remove usages of whitelist
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.
2020-09-30 18:46:45 +01:00
Joey Perrott c953af6b8c refactor(httpProvider): remove usages of whitelist and blacklist
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.
2020-09-30 18:46:45 +01:00
Joey Perrott a206e2675c refactor(sceDelegateProvider): remove usages of whitelist and blacklist
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.
2020-09-30 18:46:45 +01:00
George Kalpakas 9679e58ec4 chore(ci): correctly compute $DIST_TAG in the deploy-code CI job
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
2020-08-22 22:03:58 +03:00
George Kalpakas 26e13e5797 chore(ci): fix docs deployment to Firebase (deploy-docs CI job)
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
2020-08-22 18:50:06 +03:00
George Kalpakas 4428dd0c0f chore(ci): correctly compute the DIST_TAG environment variable
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`.
2020-08-22 18:50:05 +03:00
George Kalpakas a6a6c16195 chore(ci): avoid deploying if linting fails
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
2020-08-21 17:32:55 +03:00
George Kalpakas 744862ac31 chore(ci): fix deploy-docs CI job
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.
2020-08-21 17:32:25 +03:00
George Kalpakas 3e62832680 chore(ci): fix deploy-code CI job
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
2020-08-21 17:32:25 +03:00
George Kalpakas 83f084e5db chore(ci): avoid unnecessarily running grunt prepareDeploy in deploy-docs CI job
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#L265

Closes #17060
2020-08-13 14:57:18 +03:00
George Kalpakas 046887048a chore(ci): correctly deploy code and docs on version branches and tags
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
2020-08-13 14:56:34 +03:00
George Kalpakas f9b5cbfcf7 chore(package.json): update docs app to use version 1.8 of AngularJS
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
2020-08-13 14:56:34 +03:00
dependabot[bot] 0d14993d75 chore(deps): bump elliptic from 6.3.3 to 6.5.3
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.3.3 to 6.5.3.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.3.3...v6.5.3)

Signed-off-by: dependabot[bot] <support@github.com>

Closes #17059
2020-07-30 18:44:04 +03:00
Ewa G 5541828ff4 docs(misc/Version Support Status): mention LTS extension by 6 months due to COVID
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.
2020-07-30 12:25:28 +03:00
George Kalpakas 4099279426 fix(doc-gen): use the correct lodash method in dgeni processor (indexBy --> keyBy)
The `indexBy()` method was renamed to `keyBy()` in lodash v4 (see
lodash/lodash@b1d52ccd82). This commit
updates all usages of `indexBy()` to `keyBy()`.
2020-07-16 19:32:02 +03:00
dependabot[bot] 01ed44efd6 chore(deps-dev): bump lodash from 2.4.2 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 2.4.2 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/2.4.2...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-16 19:32:02 +03:00
dependabot[bot] 49655fac26 chore(deps): bump lodash
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-16 15:48:27 +03:00
dependabot[bot] 42abc8270a chore(deps): bump lodash
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-16 12:15:17 +03:00
dependabot[bot] d6ae0ee772 Merge pull request #17043 from angular/dependabot/npm_and_yarn/scripts/docs.angularjs.org-firebase/functions/websocket-extensions-0.1.4
chore(deps): bump websocket-extensions from 0.1.3 to 0.1.4 in /scripts/docs.angularjs.org-firebase/functions
2020-06-11 11:47:40 +01:00
dependabot[bot] 94dc1d0e6d chore(deps): bump websocket-extensions
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-06-11 11:46:25 +01:00
Harri Lehtola 2fab3d4e00 fix($sanitize): do not trigger CSP alert/report in Firefox and Chrome
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.
2020-06-11 11:41:27 +01:00
Pete Bacon Darwin 72fbd48f2a chore: update changelog with vulnerability credits 2020-06-05 13:35:32 +01:00
Pete Bacon Darwin e55d352e94 docs(*): update changelog for 1.8.0 2020-06-04 16:12:37 +01:00
Pete Bacon Darwin 78ab691072 chore(*): prep for 1.8.0 2020-06-04 16:11:00 +01:00
Eran Nussbaum 59b5651d82 docs(ngRepeat): missing closing backtick 2020-06-02 14:52:51 +03:00
Michał Gołębiowski-Owczarek c8b7c16b78 fix(jqLite): improve documentation 2020-05-26 22:21:32 +02:00
Michał Gołębiowski-Owczarek 05cf60677b fix(jqLite): apply suggestions from code review
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2020-05-26 22:08:46 +02:00
Michał Gołębiowski-Owczarek 2df43c0777 fix(jqLite): prevent possible XSS due to regex-based HTML replacement
This also splits the wrapping logic to one for modern browsers & one for IE 9
as IE 9 has restrictions that make it impossible to make it as secure.
2020-05-26 18:58:01 +02:00
George Kalpakas 295213df95 chore(*): clean up package.json and CircleCI config
This is a follow-up to #16915, cleaning up `package.json` and
`.circleci/config.yml` and making release scripts executable.
2020-05-26 17:39:51 +03:00
George Kalpakas a31c207bf1 chore(docs-app): remove document.write() from docs index.html
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
2020-05-25 16:41:54 +01:00
Krzysztof Kotowicz 2518966153 fix(grunt-utils): insert the core CSS styles without using innerHTML
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
2020-05-25 11:17:53 +03:00
Pete Bacon Darwin 7de25c8e41 chore(ci): ensure that deployment files are ready for deployment 2020-05-24 19:57:58 +01:00
Pete Bacon Darwin 566a552645 chore(ci): update and deploy firebase function for code.angularjs.org 2020-05-24 19:57:57 +01:00
Pete Bacon Darwin 3c75a89906 chore(ci): attempt to fix up code deployment 2020-05-24 07:19:13 +01:00
Pete Bacon Darwin d9e68b157b chore(ci): use correct executor for deploying code 2020-05-23 14:57:48 +01:00
Pete Bacon Darwin a0488b30a7 chore(ci): move over to CircleCi config
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.
2020-05-23 13:22:56 +01:00
Pete Bacon Darwin 974700af7c test(*): fix up some tests for Firefox 2020-05-22 18:09:15 +01:00
Pete Bacon Darwin 9c810ebb2c chore(*): update saucelabs browsers 2020-05-22 18:09:15 +01:00
Pete Bacon Darwin c4b79d59b4 chore(*): update protractor to latest version 2020-05-22 18:09:07 +01:00
Michał Gołębiowski-Owczarek 43c3e5b11b chore(*): update Node.js from 8 to 12, update some dependencies
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.
2020-05-22 18:08:04 +01:00
Michał Gołębiowski-Owczarek 8e941f42e4 chore(*): update jQuery from 3.4.0 to 3.5.1 2020-05-20 05:17:05 +01:00
George Kalpakas 418355f1cf chore(docs.angularjs.org): upgrade Firebase libraries 2020-04-14 16:12:17 +03:00
George Kalpakas 94c288b125 chore(code.angularjs.org): upgrade Firebase libraries 2020-04-14 16:11:59 +03:00
Nishant Mittal 123c5a0a3e docs(misc/Version Support Status): Minor Typo Fix
Closes #17012
2020-04-13 15:48:57 +03:00
Sam Katakouzinos f6986f8e52 docs(developers): commit message format typo
Any line of the commit message cannot be longer *than* 100 characters!

Closes #17006
2020-03-11 13:29:49 +02:00
Chives ff963de73a docs($aria): get the docs working for the service
Closes #16945
2020-02-07 16:23:12 +02:00
comet 2b28c540ad docs(*): fix spelling errors
Closes #16942
2020-02-02 11:28:55 +02:00
George Kalpakas 68701efb9e chore(*): fix serving of URI-encoded files on code.angularjs.org
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
2020-02-02 11:19:17 +02:00
George Kalpakas c8a6e8450f chore(package): fix scripts for latest Node 10.x on Windows 2020-02-02 11:19:11 +02:00
thatshubham 0cd592f49f docs(angular.errorHandlingConfig): fix typo (wether --> whether)
Closes #16935
2020-01-14 12:22:44 +02:00
thatshubham a4daf1f767 docs(angular.copy): fix getter/setter formatting
Fix the formatting of `getter`/`setter` in the known limitations section
of the `angular.copy()` docs.

Closes #16934
2020-01-14 12:19:52 +02:00
Angel_Kitty be6a6d80e0 chore(*): update copyright year to 2020
Closes #16930
2020-01-14 12:16:06 +02:00
Pete Bacon Darwin 36f17c9262 docs: add mention to changelog 2019-11-19 14:37:18 +00:00
Pete Bacon Darwin ff5f782b20 docs: add mention to changelog 2019-11-19 14:35:59 +00:00
Pete Bacon Darwin 27460db1db docs: release notes for 1.7.9 2019-11-19 08:23:28 +00:00
Pete Bacon Darwin add78e6200 fix(angular.merge): do not merge __proto__ property
By blocking `__proto__` on deep merging, this commit
prevents the `Object` prototype from being polluted.
2019-11-07 15:39:21 +00:00
109 changed files with 10343 additions and 10572 deletions
+509
View File
@@ -0,0 +1,509 @@
# Configuration file for https://circleci.com/gh/angular/angular.js
# Note: YAML anchors allow an object to be re-used, reducing duplication.
# The ampersand declares an alias for an object, then later the `<<: *name`
# syntax dereferences it.
# See http://blog.daemonl.com/2016/02/yaml.html
# To validate changes, use an online parser, eg.
# http://yaml-online-parser.appspot.com/
# CircleCI configuration version
# Version 2.1 allows for extra config reuse features
# https://circleci.com/docs/2.0/reusing-config/#getting-started-with-config-reuse
version: 2.1
# Workspace persisted by the `setup` job to share build artifacts with other jobs.
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
# https://circleci.com/blog/deep-diving-into-circleci-workspaces/
var_workspace_location: &workspace_location ~/
# Executor Definitions
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-executors
# **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.)
executors:
default-executor:
parameters:
resource_class:
type: string
default: medium
docker:
- image: circleci/node:14.16.1@sha256:b094e85848b43209ca83d9bb114d406fe62c75cb73b18c9d8eb1a9c6462c97d4
resource_class: << parameters.resource_class >>
working_directory: ~/ng
cloud-sdk:
description: The docker container to use when running gcp-gcs commands
docker:
- image: google/cloud-sdk:alpine@sha256:7d0cae28cb282b76f2d9babe278c63c910d54f0cceca7a65fdf6806e2b43882e
working_directory: ~/ng
# Filter Definitions
# Filter to run a job on all branches and any `v1.X.Y(-Z)` tags.
# Since the jobs need to run on tagged builds too, a `tags` section has to be explicitly specified.
# (The `branches` section could be omitted, since it defaults to all branches - just being explicit
# here).
# See also https://circleci.com/docs/2.0/workflows/#executing-workflows-for-a-git-tag.
var-filter-run-always: &run-always
filters:
branches:
only: /.*/
tags:
only: /v1\.\d+\.\d.*/
# Filter to run a job when code might need to be deployed - i.e. on builds for the `master` branch.
# (Further checks are needed to determine whether a deployment is actually needed, but these are not
# possible via filters.)
var-filter-run-on-master: &run-on-master
filters:
branches:
only:
- master
tags:
ignore: /.*/
# Filter to run a job when code/docs might need to be deployed - i.e. on tagged builds and on builds
# for master and `v1.*.x` branches.
# (Further checks are needed to determine whether a deployment is actually needed, but these are not
# possible via filters.)
var-filter-run-on-tags-and-master-and-version-branches: &run-on-tags-and-master-and-version-branches
filters:
branches:
only:
- master
- /v1\.\d+\.x/
tags:
only: /v1\.\d+\.\d.*/
# Filter to run a job when docs might need to be deployed - i.e. on builds for `v1.*.x` branches,
# which might correspond to the stable branch.
# (Further checks are needed to determine whether a deployment is actually needed, but these are not
# possible via filters.)
var-filter-run-on-version-branches: &run-on-version-branches
filters:
branches:
only:
- /v1\.\d+\.x/
tags:
ignore: /.*/
# Command Definitions
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-commands
commands:
skip_on_pr_and_fork_builds:
description: Skip a job on pull request and fork builds
steps:
- run:
name: Skip this job if this is a pull request or fork build
# Note: Using `CIRCLE_*` env variables (instead of those defined in `env.sh` so that this
# step can be run before `init_environment`.
command: >
if [[ -n "$CIRCLE_PR_NUMBER" ]] ||
[[ "$CIRCLE_PROJECT_USERNAME" != "angular" ]] ||
[[ "$CIRCLE_PROJECT_REPONAME" != "angular.js" ]]; then
echo "Skipping this job, because this is either a pull request or a fork build."
circleci step halt
fi
skip_unless_stable_branch:
description: Skip a job unless this is the stable branch
steps:
- run:
name: Skip this job unless this is the stable branch
command: >
if [[ "$DIST_TAG" != "latest" ]]; then
echo "Skipping deployment, because this is not the stable branch."
circleci step halt
fi
skip_unless_tag_or_master_or_stable_branch:
description: Skip a job unless this is a tag or the master or stable branch
steps:
- run:
name: Skip this job unless this is a tag or the master or stable branch
command: >
if [[ "$CI_GIT_TAG" == "false" ]] &&
[[ "$CI_BRANCH" != "master" ]] &&
[[ "$DIST_TAG" != "latest" ]]; then
echo "Skipping this job, because this is neither a tag nor the master or stable branch."
circleci step halt
fi
custom_attach_workspace:
description: Attach workspace at a predefined location
steps:
- attach_workspace:
at: *workspace_location
# Java is needed for running the Closure Compiler (during the `minall` task).
install_java:
description: Install java
steps:
- run:
name: Install java
command: |
sudo apt-get update
# Install java runtime
sudo apt-get install default-jre
# Initializes the CI environment by setting up common environment variables.
init_environment:
description: Initializing environment (setting up variables)
steps:
- run:
name: Set up environment
environment:
CIRCLE_GIT_BASE_REVISION: << pipeline.git.base_revision >>
CIRCLE_GIT_REVISION: << pipeline.git.revision >>
command: ./.circleci/env.sh
- run:
# Configure git as the CircleCI `checkout` command does.
# This is needed because we only checkout on the setup job.
# Add GitHub to known hosts
name: Configure git
command: |
mkdir -p ~/.ssh
echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
git config --global gc.auto 0 || true
init_saucelabs_environment:
description: Sets up a domain that resolves to the local host.
steps:
- run:
name: Preparing environment for running tests on Saucelabs.
command: |
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
# the tunnel. We do this because devices are sometimes not able to properly resolve
# `localhost` or `127.0.0.1` through the SauceLabs tunnel. Using a domain that does not
# resolve to anything on SauceLabs VMs ensures that such requests are always resolved
# through the tunnel, and resolve to the actual tunnel host machine (i.e. the CircleCI VM).
# More context can be found in: https://github.com/angular/angular/pull/35171.
setPublicVar SAUCE_LOCALHOST_ALIAS_DOMAIN "angular-ci.local"
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- run:
# Sets up a local domain in the machine's host file that resolves to the local
# host. This domain is helpful in Saucelabs tests where devices are not able to
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
name: Setting up alias domain for local host.
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
start_saucelabs:
steps:
- run:
name: Starting Saucelabs tunnel service
command: ./lib/saucelabs/sauce-service.sh start-ready-wait
stop_saucelabs:
steps:
- run:
name: Stopping Saucelabs tunnel service
command: ./lib/saucelabs/sauce-service.sh stop
run_e2e_tests:
parameters:
specs:
type: string
steps:
- custom_attach_workspace
- init_environment
- init_saucelabs_environment
- start_saucelabs
- run:
command: yarn grunt test:circleci-protractor --specs="<< parameters.specs >>"
no_output_timeout: 30m
- stop_saucelabs
run_e2e_tests_jquery:
parameters:
specs:
type: string
steps:
- custom_attach_workspace
- init_environment
- init_saucelabs_environment
- start_saucelabs
- run:
environment:
USE_JQUERY: 1
command: yarn grunt test:circleci-protractor --specs="<< parameters.specs >>"
no_output_timeout: 30m
- stop_saucelabs
# Job definitions
# Jobs can include parameters that are passed in the workflow job invocation.
# https://circleci.com/docs/2.0/reusing-config/#authoring-parameterized-jobs
jobs:
setup:
executor: default-executor
steps:
- checkout
- init_environment
- install_java
- run:
name: Running Yarn install
command: yarn install --frozen-lockfile --non-interactive
# Yarn's requests sometimes take more than 10mins to complete.
no_output_timeout: 45m
- run: yarn grunt package
# Persist any changes at this point to be reused by further jobs.
# **NOTE**: To add new content to the workspace, always persist on the same root.
- persist_to_workspace:
root: *workspace_location
paths:
- ./ng
lint:
executor: default-executor
steps:
- custom_attach_workspace
- init_environment
- run: yarn grunt ci-checks
- run: yarn commitplease "$CI_COMMIT_RANGE"
- run: yarn grunt validate-angular-files
unit-test:
executor:
name: default-executor
steps:
- custom_attach_workspace
- init_environment
- install_java
- init_saucelabs_environment
- run: yarn grunt test:promises-aplus
- run:
command: yarn grunt test:jqlite --browsers="$BROWSERS" --reporters=spec
no_output_timeout: 10m
- run:
command: yarn grunt test:modules --browsers="$BROWSERS" --reporters=spec
no_output_timeout: 10m
- run:
command: yarn grunt test:docs --browsers="$BROWSERS" --reporters=spec
no_output_timeout: 10m
unit-test-jquery:
executor:
name: default-executor
steps:
- custom_attach_workspace
- init_environment
- init_saucelabs_environment
- run:
command: yarn grunt test:jquery --browsers="$BROWSERS" --reporters=spec
no_output_timeout: 10m
- run:
command: yarn grunt test:jquery-2.2 --browsers="$BROWSERS" --reporters=spec
no_output_timeout: 10m
- run:
command: yarn grunt test:jquery-2.1 --browsers="$BROWSERS" --reporters=spec
no_output_timeout: 10m
e2e-test-1:
executor:
name: default-executor
steps:
- run_e2e_tests:
specs: test/e2e/tests/**/*.js
e2e-test-2a:
executor:
name: default-executor
steps:
- run_e2e_tests:
specs: build/docs/ptore2e/example-ng*/**/default_test.js
e2e-test-2b:
executor:
name: default-executor
steps:
- run_e2e_tests:
specs: "build/docs/ptore2e/!(example-ng*)/**/default_test.js"
e2e-test-jquery-1:
executor:
name: default-executor
steps:
- run_e2e_tests_jquery:
specs: test/e2e/tests/**/*.js
e2e-test-jquery-2a:
executor:
name: default-executor
steps:
- run_e2e_tests_jquery:
specs: build/docs/ptore2e/example-ng*/**/jquery_test.js
e2e-test-jquery-2b:
executor:
name: default-executor
steps:
- run_e2e_tests_jquery:
specs: build/docs/ptore2e/!(example-ng*)/**/jquery_test.js
prepare-deployment:
executor:
name: default-executor
steps:
- skip_on_pr_and_fork_builds
- custom_attach_workspace
- init_environment
- run: yarn grunt prepareDeploy
# Write the deployment files to the workspace to be used by deploy-docs and deploy-code
- persist_to_workspace:
root: *workspace_location
paths:
- ./ng
# The `deploy-code-files` job should only run when all of these conditions are true for the build:
# - It is for the `angular/angular.js` repository (not a fork).
# - It is not for a pull request.
# - It is for a tag or the master branch or the stable branch(*).
#
# *: The stable branch is the one that has the value `latest` in `package.json > distTag`.
deploy-code-files:
executor:
name: cloud-sdk
steps:
- skip_on_pr_and_fork_builds
- custom_attach_workspace
- init_environment
- skip_unless_tag_or_master_or_stable_branch
- run: ls scripts/code.angularjs.org-firebase/deploy
- run:
name: Authenticate and configure Docker
command: |
echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
- run:
name: Sync files to code.angularjs.org
command: |
gsutil -m rsync -r scripts/code.angularjs.org-firebase/deploy gs://code-angularjs-org-338b8.appspot.com
# The `deploy-code-firebase` job should only run when all of these conditions are true for the build:
# - It is for the `angular/angular.js` repository (not a fork).
# - It is not for a pull request.
# - It is for the master branch.
# (This is enforced via job filters, so we don't need to a step to check it here.)
deploy-code-firebase:
executor:
name: default-executor
steps:
- skip_on_pr_and_fork_builds
- custom_attach_workspace
- init_environment
# Install dependencies for Firebase functions to prevent parsing errors during deployment.
# See https://github.com/angular/angular.js/pull/16453.
- run:
name: Install dependencies in `scripts/code.angularjs.org-firebase/functions/`.
working_directory: scripts/code.angularjs.org-firebase/functions
command: yarn install --frozen-lockfile --ignore-engines --non-interactive
- run:
name: Deploy to Firebase from `scripts/code.angularjs.org-firebase/`.
working_directory: scripts/code.angularjs.org-firebase
command: |
# Do not use `yarn firebase` as that causes the Firebase CLI to look for `firebase.json`
# in the root directory, even if run from inside `scripts/code.angularjs.org-firebase/`.
firebase=$(yarn bin)/firebase
$firebase use
$firebase deploy --message "Commit:\ $CI_COMMIT" --non-interactive --token "$FIREBASE_TOKEN"
# The `deploy-docs` job should only run when all of these conditions are true for the build:
# - It is for the `angular/angular.js` repository (not a fork).
# - It is not for a pull request.
# - It is for the stable branch(*).
#
# *: The stable branch is the one that has the value `latest` in `package.json > distTag`.
deploy-docs:
executor:
name: default-executor
steps:
- skip_on_pr_and_fork_builds
- custom_attach_workspace
- init_environment
- skip_unless_stable_branch
# Install dependencies for Firebase functions to prevent parsing errors during deployment.
# See https://github.com/angular/angular.js/pull/16453.
- run:
name: Install dependencies in `scripts/docs.angularjs.org-firebase/functions/`.
working_directory: scripts/docs.angularjs.org-firebase/functions
command: yarn install --frozen-lockfile --ignore-engines --non-interactive
- run:
name: Deploy to Firebase from `scripts/docs.angularjs.org-firebase/`.
working_directory: scripts/docs.angularjs.org-firebase
command: |
# Do not use `yarn firebase` as that causes the Firebase CLI to look for `firebase.json`
# in the root directory, even if run from inside `scripts/docs.angularjs.org-firebase/`.
firebase=$(yarn bin)/firebase
$firebase use
$firebase deploy --message "Commit:\ $CI_COMMIT" --non-interactive --token "$FIREBASE_TOKEN"
workflows:
version: 2
default_workflow:
jobs:
- setup:
<<: *run-always
- lint:
<<: *run-always
requires:
- setup
- unit-test:
<<: *run-always
requires:
- setup
- unit-test-jquery:
<<: *run-always
requires:
- setup
- e2e-test-1:
<<: *run-always
requires:
- setup
- e2e-test-2a:
<<: *run-always
requires:
- setup
- e2e-test-2b:
<<: *run-always
requires:
- setup
- e2e-test-jquery-1:
<<: *run-always
requires:
- setup
- e2e-test-jquery-2a:
<<: *run-always
requires:
- setup
- e2e-test-jquery-2b:
<<: *run-always
requires:
- setup
- prepare-deployment:
<<: *run-on-tags-and-master-and-version-branches
requires:
- setup
- lint
- unit-test
- unit-test-jquery
- e2e-test-1
- e2e-test-2a
- e2e-test-2b
- e2e-test-jquery-1
- e2e-test-jquery-2a
- e2e-test-jquery-2b
- deploy-code-files:
<<: *run-on-tags-and-master-and-version-branches
requires:
- prepare-deployment
- deploy-code-firebase:
<<: *run-on-master
requires:
- prepare-deployment
- deploy-docs:
<<: *run-on-version-branches
requires:
- prepare-deployment
+73
View File
@@ -0,0 +1,73 @@
####################################################################################################
# Helpers for defining environment variables for CircleCI.
#
# In CircleCI, each step runs in a new shell. The way to share ENV variables across steps is to
# export them from `$BASH_ENV`, which is automatically sourced at the beginning of every step (for
# the default `bash` shell).
#
# See also https://circleci.com/docs/2.0/env-vars/#using-bash_env-to-set-environment-variables.
####################################################################################################
# Set and print an environment variable.
#
# Use this function for setting environment variables that are public, i.e. it is OK for them to be
# visible to anyone through the CI logs.
#
# Usage: `setPublicVar <name> <value>`
function setPublicVar() {
setSecretVar $1 "$2";
echo "$1=$2";
}
# Set (without printing) an environment variable.
#
# Use this function for setting environment variables that are secret, i.e. should not be visible to
# everyone through the CI logs.
#
# Usage: `setSecretVar <name> <value>`
function setSecretVar() {
# WARNING: Secrets (e.g. passwords, access tokens) should NOT be printed.
# (Keep original shell options to restore at the end.)
local -r originalShellOptions=$(set +o);
set +x -eu -o pipefail;
echo "export $1=\"${2:-}\";" >> $BASH_ENV;
# Restore original shell options.
eval "$originalShellOptions";
}
# Create a function to set an environment variable, when called.
#
# Use this function for creating setter for public environment variables that require expensive or
# time-consuming computaions and may not be needed. When needed, you can call this function to set
# the environment variable (which will be available through `$BASH_ENV` from that point onwards).
#
# Arguments:
# - `<name>`: The name of the environment variable. The generated setter function will be
# `setPublicVar_<name>`.
# - `<code>`: The code to run to compute the value for the variable. Since this code should be
# executed lazily, it must be properly escaped. For example:
# ```sh
# # DO NOT do this:
# createPublicVarSetter MY_VAR "$(whoami)"; # `whoami` will be evaluated eagerly
#
# # DO this isntead:
# createPublicVarSetter MY_VAR "\$(whoami)"; # `whoami` will NOT be evaluated eagerly
# ```
#
# Usage: `createPublicVarSetter <name> <code>`
#
# Example:
# ```sh
# createPublicVarSetter MY_VAR 'echo "FOO"';
# echo $MY_VAR; # Not defined
#
# setPublicVar_MY_VAR;
# source $BASH_ENV;
# echo $MY_VAR; # FOO
# ```
function createPublicVarSetter() {
echo "setPublicVar_$1() { setPublicVar $1 \"$2\"; }" >> $BASH_ENV;
}
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# Variables
readonly projectDir=$(realpath "$(dirname ${BASH_SOURCE[0]})/..")
readonly envHelpersPath="$projectDir/.circleci/env-helpers.inc.sh";
# Load helpers and make them available everywhere (through `$BASH_ENV`).
source $envHelpersPath;
echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
# Define PUBLIC environment variables for CircleCI.
####################################################################################################
# See https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables for more info.
####################################################################################################
setPublicVar CI "$CI"
setPublicVar PROJECT_ROOT "$projectDir";
# This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL";
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
setPublicVar CI_GIT_BASE_REVISION "${CIRCLE_GIT_BASE_REVISION}";
setPublicVar CI_GIT_REVISION "${CIRCLE_GIT_REVISION}";
setPublicVar CI_GIT_TAG "${CIRCLE_TAG:-false}";
setPublicVar CI_COMMIT_RANGE "$CIRCLE_GIT_BASE_REVISION..$CIRCLE_GIT_REVISION";
setPublicVar CI_PULL_REQUEST "${CIRCLE_PR_NUMBER:-false}";
setPublicVar CI_REPO_NAME "$CIRCLE_PROJECT_REPONAME";
setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
setPublicVar CI_PR_REPONAME "$CIRCLE_PR_REPONAME";
setPublicVar CI_PR_USERNAME "$CIRCLE_PR_USERNAME";
####################################################################################################
# Define SauceLabs environment variables for CircleCI.
####################################################################################################
setPublicVar BROWSER_PROVIDER "saucelabs"
# The currently latest-1 version of desktop Safari on Saucelabs (v12.0) is unstable and disconnects
# consistently. The latest version (v12.1) works fine.
# TODO: Add `SL_Safari-1` back, once it no longer corresponds to v12.0.
setPublicVar BROWSERS "SL_Chrome,SL_Chrome-1,\
SL_Firefox,SL_Firefox-1,\
SL_Safari,\
SL_iOS,SL_iOS-1,\
SL_IE_9,SL_IE_10,SL_IE_11,\
SL_EDGE,SL_EDGE-1"
setPublicVar SAUCE_LOG_FILE /tmp/angular/sauce-connect.log
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
setPublicVar SAUCE_TUNNEL_IDENTIFIER "angularjs-framework-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX}"
# Amount of seconds we wait for sauceconnect to establish a tunnel instance. In order to not
# acquire CircleCI instances for too long if sauceconnect failed, we need a connect timeout.
setPublicVar SAUCE_READY_FILE_TIMEOUT 120
####################################################################################################
# Define additional environment variables
####################################################################################################
# NOTE: Make sure the tools used to compute this are available in all executors in `config.yml`.
setPublicVar DIST_TAG $( cat package.json | grep distTag | sed -E 's/^\s*"distTag"\s*:\s*"([^"]+)"\s*,\s*$/\1/' )
####################################################################################################
####################################################################################################
## Source `$BASH_ENV` to make the variables available immediately. ##
## *** NOTE: This must remain the last command in this script. *** ##
####################################################################################################
####################################################################################################
source $BASH_ENV;
+1 -1
View File
@@ -15,7 +15,7 @@
// Stylistic issues
"block-spacing": ["error", "always"],
"comma-spacing": "error",
"id-blacklist": ["error", "event"],
"id-denylist": ["error", "event"],
"indent": ["error", 2],
"key-spacing": ["error", { "beforeColon": false, "afterColon": true, "mode": "minimum" }],
"object-curly-spacing": ["error", "never"],
+1 -1
View File
@@ -31,7 +31,7 @@ please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:yBpEi4).
-->
**AngularJS version:** 1.7.x
**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/) -->
+4 -1
View File
@@ -1,5 +1,4 @@
/build/
/deploy/
/benchpress-build/
.DS_Store
gen_docs.disable
@@ -12,6 +11,7 @@ performance/temp*.html
angular.js.tmproj
node_modules/
angular.xcodeproj
.firebase/
.idea
*.iml
.agignore
@@ -22,3 +22,6 @@ npm-debug.log
.vscode
*.log
*.stackdump
scripts/code.angularjs.org-firebase/deploy
scripts/docs.angularjs.org-firebase/deploy
scripts/docs.angularjs.org-firebase/functions/content
+1 -1
View File
@@ -1 +1 @@
8
14.16.1
-104
View File
@@ -1,104 +0,0 @@
language: node_js
sudo: false
node_js:
- '8'
cache:
yarn: true
branches:
except:
- "/^g3_.*$/"
env:
matrix:
- JOB=ci-checks
- JOB=unit-core BROWSER_PROVIDER=saucelabs
- JOB=unit-jquery BROWSER_PROVIDER=saucelabs
- JOB=unit-modules BROWSER_PROVIDER=saucelabs
- JOB=docs-app BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs
global:
- SAUCE_USERNAME=angular-ci
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
- LOGS_DIR=/tmp/angular-build/logs
- BROWSER_PROVIDER_READY_FILE=/tmp/browsersprovider-tunnel-ready
- secure: oTBjhnOKhs0qDSKTf7fE4f6DYiNDPycvB7qfSF5QRIbJK/LK/J4UtFwetXuXj79HhUZG9qnoT+5e7lPaiaMlpsIKn9ann7ffqFWN1E8TMtpJF+AGigx3djYElwfgf5nEnFUFhwjFzvbfpZNnxVGgX5YbIZpe/WUbHkP4ffU0Wks=
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.10.1
- export PATH="$HOME/.yarn/bin:$PATH"
before_script:
- du -sh ./node_modules || true
- "./scripts/travis/before_build.sh"
script:
- "./scripts/travis/build.sh"
after_script:
- "./scripts/travis/tear_down_browser_provider.sh"
- "./scripts/travis/print_logs.sh"
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/d2120f3f2bb39a4531b2
- http://104.197.9.155:8484/hubot/travis/activity #hubot-server
on_success: always # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: always # default: false
jobs:
include:
- stage: deploy
# Don't deploy from PRs. Only deploy from our default branches, or if commit is tagged.
# This is a Travis-specific boolean language: https://docs.travis-ci.com/user/conditional-builds-stages-jobs#Specifying-conditions
# The deployment logic for pushed branches is further defined in scripts\travis\build.sh
if: type != pull_request and (branch =~ ^(v1\.\d+\.x|master)$ or tag IS present)
env:
- JOB=deploy
before_script: skip
script:
# Export the variables into the current process
- . ./scripts/travis/build.sh
- "echo DEPLOY_DOCS: $DEPLOY_DOCS, DEPLOY_CODE: $DEPLOY_CODE"
after_script: skip
# Work around the 10min Travis timeout so the code.angularjs firebase+gcs code deploy can complete
# Only run the keep_alive once (before_deploy is run for each provider)
before_deploy: |
if ! [ "$BEFORE_DEPLOY_RUN" ]; then
export BEFORE_DEPLOY_RUN=1;
function keep_alive() {
while true; do
echo -en "\a"
sleep 10
done
}
keep_alive &
fi
deploy:
- provider: firebase
# the upload folder for firebase is configured in /firebase.json
skip_cleanup: true
project: docs-angularjs-org-9p2
token:
secure: $FIREBASE_TOKEN
on:
repo: angular/angular.js
all_branches: true
condition: "$DEPLOY_DOCS == true"
- provider: gcs
skip_cleanup: true
access_key_id: GOOGLDB7W2J3LFHICF3R
secret_access_key:
secure: tHIFdSq55qkyZf9zT/3+VkhUrTvOTMuswxXU3KyWaBrSieZqG0UnUDyNm+n3lSfX95zEl/+rJAWbfvhVSxZi13ndOtvRF+MdI1cvow2JynP0aDSiPffEvVrZOmihD6mt2SlMfhskr5FTduQ69kZG6DfLcve1PPDaIwnbOv3phb8=
bucket: code-angularjs-org-338b8.appspot.com
local-dir: deploy/code
detect_encoding: true # detects gzip compression
on:
repo: angular/angular.js
all_branches: true
condition: "$DEPLOY_CODE == true"
+99
View File
@@ -1,3 +1,102 @@
**AngularJS support has officially ended as of January 2022.
[See what ending support means](https://docs.angularjs.org/misc/version-support-status)
and [read the end of life announcement](https://goo.gle/angularjs-end-of-life).**
**Visit [angular.io](https://angular.io) for the actively supported Angular.**
<a name="1.8.3"></a>
# 1.8.3 ultimate-farewell (2022-04-07)
One final release of AngularJS in order to update package README files on npm.
<a name="1.8.2"></a>
# 1.8.2 meteoric-mining (2020-10-21)
## Bug Fixes
- **$sceDelegate:** ensure that `resourceUrlWhitelist()` is identical to `trustedResourceUrlList()`
([e41f01](https://github.com/angular/angular.js/commit/e41f018959934bfbf982ba996cd654b1fce88d43),
[#17090](https://github.com/angular/angular.js/issues/17090))
<a name="1.8.1"></a>
# 1.8.1 mutually-supporting (2020-09-30)
## Bug Fixes
- **$sanitize:** do not trigger CSP alert/report in Firefox and Chrome
([2fab3d](https://github.com/angular/angular.js/commit/2fab3d4e00f4fe35bfa3cf255160cb97404baf24))
## Refactorings
- **SanitizeUriProvider:** remove usages of whitelist
([76738102](https://github.com/angular/angular.js/commit/767381020d88bda2855ac87ca6f00748907e14ff))
- **httpProvider:** remove usages of whitelist and blacklist
([c953af6b](https://github.com/angular/angular.js/commit/c953af6b8cfeefe4acc0ca358550eed5da8cfe00))
- **sceDelegateProvider:** remove usages of whitelist and blacklist
([a206e267](https://github.com/angular/angular.js/commit/a206e2675c351c3cdcde3402978126774c1c5df9))
## Deprecation Notices
- Deprecated ~~`$compileProvider.aHrefSanitizationWhitelist`~~.
It is now [`aHrefSanitizationTrustedUrlList`](https://docs.angularjs.org/api/ng/provider/$compileProvider#aHrefSanitizationTrustedUrlList).
- Deprecated ~~`$compileProvider.imgSrcSanitizationWhitelist`~~.
It is now [`imgSrcSanitizationTrustedUrlList`](https://docs.angularjs.org/api/ng/provider/$compileProvider#imgSrcSanitizationTrustedUrlList).
- Deprecated ~~`$httpProvider.xsrfWhitelistedOrigins`~~.
It is now [`xsrfTrustedOrigins`](https://docs.angularjs.org/api/ng/provider/$httpProvider#xsrfTrustedOrigins).
- Deprecated ~~`$sceDelegateProvider.resourceUrlWhitelist`~~.
It is now [`trustedResourceUrlList`](https://docs.angularjs.org/api/ng/provider/$sceDelegateProvider#trustedResourceUrlList).
- Deprecated ~~`$sceDelegateProvider.resourceUrlBlacklist`~~.
It is now [`bannedResourceUrlList`](https://docs.angularjs.org/api/ng/provider/$sceDelegateProvider#bannedResourceUrlList).
For the purposes of backward compatibility, the previous symbols are aliased to their new symbol.
<a name="1.8.0"></a>
# 1.8.0 nested-vaccination (2020-06-01)
_This release contains a breaking change to resolve a security issue which was discovered by
Krzysztof Kotowicz(@koto); and independently by Esben Sparre Andreasen (@esbena) while
performing a Variant Analysis of [CVE-2020-11022](https://github.com/advisories/GHSA-gxr4-xjj5-5px2)
which itself was found and reported by Masato Kinugawa (@masatokinugawa)._
## Bug Fixes
- **jqLite:**
- prevent possible XSS due to regex-based HTML replacement
([2df43c](https://github.com/angular/angular.js/commit/2df43c07779137d1bddf7f3b282a1287a8634acd))
## Breaking Changes
### **jqLite** due to:
- **[2df43c](https://github.com/angular/angular.js/commit/2df43c07779137d1bddf7f3b282a1287a8634acd)**: prevent possible XSS due to regex-based HTML replacement
JqLite no longer turns XHTML-like strings like `<div /><span />` to sibling elements `<div></div><span></span>`
when not in XHTML mode. Instead it will leave them as-is. The browser, in non-XHTML mode, will convert these to:
`<div><span></span></div>`.
This is a security fix to avoid an XSS vulnerability if a new jqLite element is created from a user-controlled HTML string.
If you must have this functionality and understand the risk involved then it is posible to restore the original behavior by calling
```js
angular.UNSAFE_restoreLegacyJqLiteXHTMLReplacement();
```
But you should adjust your code for this change and remove your use of this function as soon as possible.
Note that this only patches jqLite. If you use jQuery 3.5.0 or newer, please read the [jQuery 3.5 upgrade guide](https://jquery.com/upgrade-guide/3.5/) for more details about the workarounds.
<a name="1.7.9"></a>
# 1.7.9 pollution-eradication (2019-11-19)
## Bug Fixes
- **angular.merge:** do not merge __proto__ property
([726f49](https://github.com/angular/angular.js/commit/726f49dcf6c23106ddaf5cfd5e2e592841db743a))
<br>(Thanks to the [Snyk Security Research Team](https://snyk.io/blog/snyk-research-team-discovers-severe-prototype-pollution-security-vulnerabilities-affecting-all-versions-of-lodash/) for identifyng this issue.)
- **ngStyle:** correctly remove old style when new style value is invalid
([5edd25](https://github.com/angular/angular.js/commit/5edd25364f617083363dc2bd61f9230b38267578),
[#16860](https://github.com/angular/angular.js/issues/16860),
[#16868](https://github.com/angular/angular.js/issues/16868))
<a name="1.7.8"></a>
# 1.7.8 enthusiastic-oblation (2019-03-11)
+5 -5
View File
@@ -125,8 +125,8 @@ Before you submit your pull request consider the following guidelines:
* Follow our [Coding Rules][developers.rules].
* If the changes affect public APIs, change or add relevant [documentation][developers.documentation].
* Run the AngularJS [unit][developers.tests-unit] and [E2E test][developers.tests-e2e] suites, and ensure that all tests
pass. It is generally sufficient to run the tests only on Chrome, as our Travis integration will
run the tests on all supported browsers.
pass. It is generally sufficient to run the tests only on Chrome, as our continuous integration test will
run the tests on additional browsers.
* Run `yarn grunt eslint` to check that you have followed the automatically enforced coding rules
* Commit your changes using a descriptive commit message that follows our
[commit message conventions][developers.commits]. Adherence to the
@@ -151,9 +151,9 @@ Before you submit your pull request consider the following guidelines:
```
* In GitHub, send a pull request to `angular.js:master`. This will trigger the check of the
[Contributor License Agreement](#cla) and the Travis integration.
[Contributor License Agreement](#cla) and the continuous integration tests.
* If you find that the Travis integration has failed, look into the logs on Travis to find out
* If you find that the continuous integration tests have failed, look into the logs to find out
if your changes caused test failures, the commit message was malformed etc. If you find that the
tests failed or times out for unrelated reasons, you can ping a team member so that the build can be
restarted.
@@ -172,7 +172,7 @@ restarted.
git push origin my-fix-branch -f
```
This is generally easier to follow, but seperate commits are useful if the Pull Request contains
This is generally easier to follow, but separate commits are useful if the Pull Request contains
iterations that might be interesting to see side-by-side.
That's it! Thank you for your contribution!
+2 -2
View File
@@ -249,7 +249,7 @@ format that includes a **type**, a **scope** and a **subject**:
The **header** is mandatory and the **scope** of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
Any line of the commit message cannot be longer than 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
### Revert
@@ -428,7 +428,7 @@ if it is enclosed in &lt;pre&gt;...&lt;/pre&gt; tags and the code lines themselv
It is possible to embed examples in the documentation along with appropriate e2e tests. These
examples and scenarios will be converted to runnable code within the documentation. So it is
important that they work correctly. To ensure this, all these e2e scenarios are run as part of the
automated Travis tests.
continuous integration tests.
If you are adding an example with an e2e test, you should [run the test locally](#e2e-tests) first
to ensure it passes. You can change `it(...)` to `fit(...)` to run only your test,
+18 -39
View File
@@ -14,7 +14,8 @@ var semver = require('semver');
var exec = require('shelljs').exec;
var pkg = require(__dirname + '/package.json');
var docsScriptFolder = 'scripts/docs.angularjs.org-firebase';
var codeScriptFolder = util.codeScriptFolder;
var docsScriptFolder = util.docsScriptFolder;
// Node.js version checks
if (!semver.satisfies(process.version, pkg.engines.node)) {
@@ -45,7 +46,7 @@ if (!match) {
}
// Ensure Node.js dependencies have been installed
if (!process.env.TRAVIS && !process.env.JENKINS_HOME) {
if (!process.env.CI) {
var yarnOutput = exec('yarn install');
if (yarnOutput.code !== 0) {
throw new Error('Yarn install failed: ' + yarnOutput.stderr);
@@ -109,16 +110,14 @@ module.exports = function(grunt) {
},
testserver: {
options: {
// We use end2end task (which does not start the webserver)
// and start the webserver as a separate process (in travis_build.sh)
// to avoid https://github.com/joyent/libuv/issues/826
// We start the webserver as a separate process from the E2E tests
port: 8000,
hostname: '0.0.0.0',
middleware: function(connect, options) {
var base = Array.isArray(options.base) ? options.base[options.base.length - 1] : options.base;
return [
function(req, resp, next) {
// cache get requests to speed up tests on travis
// cache GET requests to speed up tests
if (req.method === 'GET') {
resp.setHeader('Cache-control', 'public, max-age=3600');
}
@@ -160,8 +159,7 @@ module.exports = function(grunt) {
protractor: {
normal: 'protractor-conf.js',
travis: 'protractor-travis-conf.js',
jenkins: 'protractor-jenkins-conf.js'
circleci: 'protractor-circleci-conf.js'
},
@@ -169,9 +167,9 @@ module.exports = function(grunt) {
build: ['build'],
tmp: ['tmp'],
deploy: [
'deploy/docs',
'deploy/code',
docsScriptFolder + '/functions/html'
codeScriptFolder + '/deploy',
docsScriptFolder + '/deploy',
docsScriptFolder + '/functions/content'
]
},
@@ -372,11 +370,10 @@ module.exports = function(grunt) {
},
deployFirebaseCode: {
files: [
// copy files that are not handled by compress
{
cwd: 'build',
src: '**/*.{zip,jpg,jpeg,png}',
dest: 'deploy/code/' + deployVersion + '/',
src: '**',
dest: codeScriptFolder + '/deploy/' + deployVersion + '/',
expand: true
}
]
@@ -386,19 +383,19 @@ module.exports = function(grunt) {
// The source files are needed by the embedded examples in the docs app.
{
src: ['build/angular*.{js,js.map,min.js}', 'build/sitemap.xml'],
dest: 'deploy/docs/',
dest: docsScriptFolder + '/deploy/',
expand: true,
flatten: true
},
{
cwd: 'build/docs',
src: ['**', '!ptore2e/**', '!index*.html'],
dest: 'deploy/docs/',
dest: docsScriptFolder + '/deploy/',
expand: true
},
{
src: 'build/docs/index-production.html',
dest: 'deploy/docs/index.html'
dest: docsScriptFolder + '/deploy/index.html'
},
{
src: 'build/docs/index-production.html',
@@ -407,7 +404,7 @@ module.exports = function(grunt) {
{
cwd: 'build/docs',
src: 'partials/**',
dest: docsScriptFolder + '/functions/content',
dest: docsScriptFolder + '/functions/content/',
expand: true
}
]
@@ -423,16 +420,6 @@ module.exports = function(grunt) {
expand: true,
dot: true,
dest: dist + '/'
},
deployFirebaseCode: {
options: {
mode: 'gzip'
},
// Already compressed files should not be compressed again
src: ['**', '!**/*.{zip,png,jpeg,jpg}'],
cwd: 'build',
expand: true,
dest: 'deploy/code/' + deployVersion + '/'
}
},
@@ -498,14 +485,9 @@ module.exports = function(grunt) {
'connect:testserver',
'protractor:normal'
]);
grunt.registerTask('test:travis-protractor', 'Run the end to end tests with Protractor for Travis CI builds', [
grunt.registerTask('test:circleci-protractor', 'Run the end to end tests with Protractor for CircleCI 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'
'protractor:circleci'
]);
grunt.registerTask('test:e2e', 'Alias for test:protractor', ['test:protractor']);
grunt.registerTask('test:promises-aplus',[
@@ -535,10 +517,7 @@ module.exports = function(grunt) {
'eslint'
]);
grunt.registerTask('prepareDeploy', [
'package',
'compress:deployFirebaseCode',
'copy:deployFirebaseCode',
'firebaseDocsJsonForTravis',
'copy:deployFirebaseDocs'
]);
grunt.registerTask('default', ['package']);
@@ -546,7 +525,7 @@ module.exports = function(grunt) {
function reportOrFail(message) {
if (process.env.TRAVIS || process.env.JENKINS_HOME) {
if (process.env.CI) {
throw new Error(message);
} else {
console.log('===============================================================================');
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2019 Google, Inc. http://angularjs.org
Copyright (c) 2010-2020 Google LLC. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+11 -8
View File
@@ -1,4 +1,4 @@
AngularJS [![Build Status](https://travis-ci.org/angular/angular.js.svg?branch=master)](https://travis-ci.org/angular/angular.js)
AngularJS [![CircleCI](https://circleci.com/gh/angular/angular.js/tree/master.svg?style=shield)](https://circleci.com/gh/angular/workflows/angular.js/tree/master)
=========
AngularJS lets you write client-side web applications as if you had a smarter browser. It lets you
@@ -14,9 +14,11 @@ piece of cake. Best of all? It makes development fun!
--------------------
**On July 1, 2018 AngularJS entered a 3 year Long Term Support period:** [Find out more](https://docs.angularjs.org/misc/version-support-status)
**AngularJS support has officially ended as of January 2022.
[See what ending support means](https://docs.angularjs.org/misc/version-support-status)
and [read the end of life announcement](https://goo.gle/angularjs-end-of-life).**
**Looking for the new Angular? Go here:** https://github.com/angular/angular
**Visit [angular.io](https://angular.io) for the actively supported Angular.**
--------------------
@@ -55,11 +57,12 @@ component in an interconnected way like a well-oiled machine. AngularJS is JavaS
and done right. (Well it is not really MVC, read on, to understand what this means.)
#### MVC, no, MV* done the right way!
MVC, short for Model-View-Controller, is a design pattern, i.e. how the code should be organized and
how the different parts of an application separated for proper readability and debugging. Model is
the data and the database. View is the user interface and what the user sees. Controller is the main
link between Model and View. These are the three pillars of major programming frameworks present on
the market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The
[MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), short for
Model-View-Controller, is a design pattern, i.e. how the code should be organized and how the
different parts of an application separated for proper readability and debugging. Model is the data
and the database. View is the user interface and what the user sees. Controller is the main link
between Model and View. These are the three pillars of major programming frameworks present on the
market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The
_Whatever_ is AngularJS's way of telling that you may create any kind of linking between the Model
and the View here.
+4 -4
View File
@@ -36,7 +36,7 @@ Usually this will be the commit containing the release notes, but it may also be
## Run "release" script
```bash
scripts/jenkins/release.sh --git-push-dryrun=false --commit-sha=8822a4f --version-number=1.7.6 --version-name=gravity-manipulation
scripts/release/release.sh --git-push-dryrun=false --commit-sha=8822a4f --version-number=1.7.6 --version-name=gravity-manipulation
```
1) The SHA is of the commit to release (could be in the past).
@@ -67,10 +67,10 @@ If we want to make our files available, we need submit our CLs before this time
This is the version used to compute what version to link to in the CDN. If you update this too early then the CDN lookup fails and you end up with 'null, for the version, which breaks the docs.
## Verify angularjs.org download modal has latest version (updates via Travis job)
## 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 Travis deploy stage: https://github.com/angular/angularjs.org/blob/a4d25c5abcd39e8ce19d31cb1c78073d13c4c974/.travis.yml#L26
(You may need to explicitly trigger the Travis job. e.g. re-running the last job.)
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)
+16
View File
@@ -0,0 +1,16 @@
# Security Policy
## Supported Versions
**AngularJS support has officially ended as of January 2022.**
[See what ending support means](https://docs.angularjs.org/misc/version-support-status)
and [read the end of life announcement](https://goo.gle/angularjs-end-of-life).
Visit [angular.io](https://angular.io) for the actively supported Angular.
| Version | Supported | Status | Comments |
| ----------- | ------------------ | --------------------- | ------------------------------------ |
| 1.8.x | :x: | All support ended | |
| 1.3.x-1.7.x | :x: | All support ended | |
| 1.2.x | :x: | All support ended | Last version to provide IE 8 support |
| <1.2.0 | :x: | All support ended | |
+3 -3
View File
@@ -478,10 +478,10 @@ iframe.example {
#navbar-sub {
padding-top: 10px;
padding-bottom: 5px;
background: rgba(245,245,245,0.88);
background: rgba(245,245,245,1);
box-shadow: 0 0 2px #999;
z-index: 1028;
top: 83px;
top: 57px;
}
.main-body-grid {
@@ -982,7 +982,7 @@ toc-container > div > toc-tree > ul > li > toc-tree > ul > li toc-tree > ul li {
#navbar-sub {
position: relative;
top: 17px;
top: 0;
margin-top: 80px;
padding-bottom: 0;
margin-bottom: 0;
+2 -2
View File
@@ -55,7 +55,7 @@ angular.module('examples', [])
return function(url, newWindow, fields) {
/**
* If the form posts to target="_blank", pop-up blockers can cause it not to work.
* If a user choses to bypass pop-up blocker one time and click the link, they will arrive at
* If a user chooses to bypass pop-up blocker one time and click the link, they will arrive at
* a new default plnkr, not a plnkr with the desired template. Given this undesired behavior,
* some may still want to open the plnk in a new window by opting-in via ctrl+click. The
* newWindow param allows for this possibility.
@@ -74,7 +74,7 @@ angular.module('examples', [])
}])
.factory('createCopyrightNotice', function() {
var COPYRIGHT = 'Copyright ' + (new Date()).getFullYear() + ' Google Inc. All Rights Reserved.\n'
var COPYRIGHT = 'Copyright ' + (new Date()).getFullYear() + ' Google LLC. All Rights Reserved.\n'
+ 'Use of this source code is governed by an MIT-style license that\n'
+ 'can be found in the LICENSE file at http://angular.io/license';
var COPYRIGHT_JS_CSS = '\n\n/*\n' + COPYRIGHT + '\n*/';
+4 -4
View File
@@ -47,13 +47,13 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
}
areasToSearch = _.indexBy(this.areasToSearch);
propertiesToIgnore = _.indexBy(this.propertiesToIgnore);
areasToSearch = _.keyBy(this.areasToSearch);
propertiesToIgnore = _.keyBy(this.propertiesToIgnore);
log.debug('Properties to ignore', propertiesToIgnore);
docTypesToIgnore = _.indexBy(this.docTypesToIgnore);
docTypesToIgnore = _.keyBy(this.docTypesToIgnore);
log.debug('Doc types to ignore', docTypesToIgnore);
var ignoreWordsMap = _.indexBy(wordsToIgnore);
var ignoreWordsMap = _.keyBy(wordsToIgnore);
// If the title contains a name starting with ng, e.g. "ngController", then add the module name
// without the ng to the title text, e.g. "controller".
+1 -1
View File
@@ -224,7 +224,7 @@ module.exports = function generatePagesDataProcessor(log) {
.map(function(doc) {
return _.pick(doc, ['name', 'area', 'path']);
})
.indexBy('path')
.keyBy('path')
.value();
docs.push({
+4 -4
View File
@@ -13,11 +13,11 @@ module.exports = function generateVersionDocProcessor(gitData) {
return {
$runAfter: ['generatePagesDataProcessor'],
$runBefore: ['rendering-docs'],
// the blacklist is to remove rogue builds that are in the npm repository but not on code.angularjs.org
blacklist: ['1.3.4-build.3588'],
// Remove rogue builds that are in the npm repository but not on code.angularjs.org
ignoredBuilds: ['1.3.4-build.3588'],
$process: function(docs) {
var blacklist = this.blacklist;
var ignoredBuilds = this.ignoredBuilds;
var currentVersion = require('../../../build/version.json');
var output = exec('yarn info angular versions --json', { silent: true }).stdout.split('\n')[0];
var allVersions = processAllVersionsResponse(JSON.parse(output).data);
@@ -57,7 +57,7 @@ module.exports = function generateVersionDocProcessor(gitData) {
versions = versions
.filter(function(versionStr) {
return blacklist.indexOf(versionStr) === -1;
return ignoredBuilds.indexOf(versionStr) === -1;
})
.map(function(versionStr) {
return semver.parse(versionStr);
@@ -1,3 +1,12 @@
{# Macros #}
{%- macro addTag(name, attributes) %}
<{$ name $}
{%- for attrName, attrValue in attributes -%}
{$ ' ' + attrName $}="{$ attrValue $}"
{%- endfor -%}
></{$ name $}>
{%- endmacro -%}
<!doctype html>
<html lang="en" ng-app="docsApp" ng-strict-di ng-controller="DocsController">
<head>
@@ -24,50 +33,27 @@
})();
</script>
<script type="text/javascript">
// dynamically add base tag as well as css and javascript files.
// we can't add css/js the usual way, because some browsers (FF) eagerly prefetch resources
// before the base attribute is added, causing 404 and terribly slow loading of the docs app.
// Dynamically add `<base>` tag.
(function() {
var indexFile = (location.pathname.match(/\/(index[^\.]*\.html)/) || ['', ''])[1],
rUrl = /(#!\/|api|guide|misc|tutorial|error|index[^\.]*\.html).*$/,
var indexFile = (location.pathname.match(/\/(index[^.]*\.html)/) || ['', ''])[1],
rUrl = /(#!\/|api|guide|misc|tutorial|error|index[^.]*\.html).*$/,
baseUrl = location.href.replace(rUrl, indexFile),
production = location.hostname === 'docs.angularjs.org',
headEl = document.getElementsByTagName('head')[0],
sync = true;
baseEl = document.createElement('base');
addTag('base', {href: baseUrl});
{% for stylesheet in doc.stylesheets %}addTag('link', {rel: 'stylesheet', href: '{$ stylesheet $}', type: 'text/css'});
{% endfor %}
{% for script in doc.scripts %}addTag('script', {src: '{$ script $}' }, sync);
{% endfor %}
function addTag(name, attributes, sync) {
var el = document.createElement(name),
attrName;
for (attrName in attributes) {
el.setAttribute(attrName, attributes[attrName]);
}
sync ? document.write(outerHTML(el)) : headEl.appendChild(el);
}
function outerHTML(node){
// if IE, Chrome take the internal method otherwise build one
return node.outerHTML || (
function(n){
var div = document.createElement('div'), h;
div.appendChild(n);
h = div.innerHTML;
div = null;
return h;
})(node);
}
baseEl.setAttribute('href', baseUrl);
headEl.appendChild(baseEl);
})();
</script>
{% for stylesheet in doc.stylesheets %}
{$- addTag('link', {rel: 'stylesheet', href: stylesheet, type: 'text/css'}) -$}
{% endfor %}
{% for script in doc.scripts %}
{$- addTag('script', {src: script}) -$}
{% endfor %}
<script type="text/javascript">
// GA asynchronous tracker
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-8594346-3']);
@@ -156,21 +142,18 @@
</div>
</div>
</nav>
<nav id="navbar-notice" class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<p class="site-notice visible-phone">
This site refers to AngularJS (v1.x). <a href="https://angular.io/">Go to the latest Angular</a>.
</p>
<p class="site-notice visible-desktop">
This site and all of its contents are referring to AngularJS (version 1.x),
if you are looking for the latest Angular, please visit <a href="https://angular.io/">angular.io</a>.
</p>
</div>
</div>
</nav>
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element ng-cloak>
<div class="container main-grid main-header-grid">
<p class="site-notice">
AngularJS support has officially ended as of January 2022.
<a href="https://docs.angularjs.org/misc/version-support-status">
See what ending support means
</a> and
<a href="https://goo.gle/angularjs-end-of-life">
read the end of life announcement</a>.<br>
Visit <a href="https://angular.io">angular.io</a> for the actively supported
Angular.
</p>
<div class="grid-left">
<version-picker></version-picker>
</div>
@@ -222,7 +205,7 @@
<p class="pull-right"><a back-to-top>Back to top</a></p>
<p>
Super-powered by Google ©2010-2018
Super-powered by Google ©2010-2020
(<a id="version"
ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
ng-bind-template="v{{version}}" title="Changelog of this version of AngularJS">
+5 -2
View File
@@ -3,9 +3,12 @@
@description
# AngularJS API Docs
<div class="alert alert-warning">
**On July 1, 2018 AngularJS entered a 3 year Long Term Support period:** [Find out more](misc/version-support-status).
AngularJS support has officially ended as of January 2022.
[See what ending support means](https://docs.angularjs.org/misc/version-support-status)
and [read the end of life announcement](https://goo.gle/angularjs-end-of-life).
Visit [angular.io](https://angular.io) for the actively supported Angular.
</div>
## Welcome to the AngularJS API docs page.
+1 -1
View File
@@ -5,7 +5,7 @@
Occurs when an expression is trying to assign a value to a non-assignable expression.
This can happen if the left side of an assigment is not a valid reference to a variable
This can happen if the left side of an assignment is not a valid reference to a variable
or property. E.g. In the following snippet `1+2` is not assignable.
```
+3 -3
View File
@@ -3,7 +3,7 @@
@fullName Invalid matcher (only string patterns and RegExp instances are supported)
@description
Please see {@link $sceDelegateProvider#resourceUrlWhitelist
$sceDelegateProvider.resourceUrlWhitelist} and {@link
$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} for the
Please see {@link $sceDelegateProvider#trustedResourceUrlList
$sceDelegateProvider.trustedResourceUrlList} and {@link
$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList} for the
list of acceptable items.
+2 -2
View File
@@ -15,8 +15,8 @@ By default, only URLs that belong to the same origin are trusted. These are urls
The {@link ng.directive:ngInclude ngInclude} directive and {@link guide/directive directives} that specify a `templateUrl` require a trusted resource URL.
To load templates from other domains and/or protocols, either adjust the {@link
ng.$sceDelegateProvider#resourceUrlWhitelist whitelist}/ {@link
ng.$sceDelegateProvider#resourceUrlBlacklist blacklist} or wrap the URL with a call to {@link
ng.$sceDelegateProvider#trustedResourceUrlList trusted resource URL list}/ {@link
ng.$sceDelegateProvider#bannedResourceUrlList banned resource URL list} or wrap the URL with a call to {@link
ng.$sce#trustAsResourceUrl $sce.trustAsResourceUrl}.
**Note**: The browser's [Same Origin
+3 -3
View File
@@ -3,7 +3,7 @@
@fullName The sequence *** is not a valid pattern wildcard
@description
The strings in {@link $sceDelegateProvider#resourceUrlWhitelist
$sceDelegateProvider.resourceUrlWhitelist} and {@link
$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} may not
The strings in {@link $sceDelegateProvider#trustedResourceUrlList
$sceDelegateProvider.trustedResourceUrlList} and {@link
$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList} may not
contain the undefined sequence `***`. Only `*` and `**` wildcard patterns are defined.
+3 -2
View File
@@ -327,7 +327,7 @@ The default CSS for `ngHide`, the inverse method to `ngShow`, makes ngAria redun
<h2><span id="ngclick">ngClick</span> and <span id="ngdblclick">ngDblclick</span></h2>
If `ng-click` or `ng-dblclick` is encountered, ngAria will add `tabindex="0"` to any element not in
a node blacklist:
the list of built in aria nodes:
* Button
* Anchor
@@ -337,7 +337,8 @@ a node blacklist:
* Details/Summary
To fix widespread accessibility problems with `ng-click` on `div` elements, ngAria will
dynamically bind a keypress event by default as long as the element isn't in the node blacklist.
dynamically bind a keypress event by default as long as the element isn't in a node from the list of
built in aria nodes.
You can turn this functionality on or off with the `bindKeypress` configuration option.
ngAria will also add the `button` role to communicate to users of assistive technologies. This can
+2 -3
View File
@@ -17,9 +17,8 @@ attributes and tags. Read this document if you are planning on deploying your An
on IE.
The project currently supports and will attempt to fix bugs for IE9 and above. The continuous
integration server runs all the tests against IE9, IE10, and IE11. See
[Travis CI](https://travis-ci.org/angular/angular.js) and
[ci.angularjs.org](https://ci.angularjs.org).
integration server runs all unit tests against IE9, IE10, and IE11. See
[CircleCI](https://circleci.com/gh/angular/workflows/angular.js/tree/master).
We do not run tests on IE8 and below. A subset of the AngularJS functionality may work on these
browsers, but it is up to you to test and decide whether it works for your particular app.
+40 -14
View File
@@ -15,6 +15,30 @@ which drives many of these changes.
* Several new features, especially animations, would not be possible without a few changes.
* Finally, some outstanding bugs were best fixed by changing an existing API.
## Migrating from 1.7 to 1.8
Generally updating to 1.8.0 from 1.7.x should be a straightforward process and is highly recommended.
AngularJS 1.8 is a breaking change release from 1.7 to mitigate a security issue.
JqLite no longer turns XHTML-like strings like `<div /><span />` to sibling elements when not in XHTML
mode: `<div></div><span></span>`.
Instead it will leave the elements alone. In non-XHTML mode the browser will convert these to nested
elements: `<div><span></span></div>`.
This is a security fix to avoid an XSS vulnerability if a new jqLite element is created from a
user-controlled HTML string. If you must have this functionality and understand the risk involved
then it is posible to restore the original behavior by calling
```js
angular.UNSAFE_restoreLegacyJqLiteXHTMLReplacement();
```
But you should adjust your code for this change and remove your use of this function as soon as
possible.
Note that this only patches jqLite. If you use jQuery 3.5.0 or newer, please read the
[jQuery 3.5 upgrade guide](https://jquery.com/upgrade-guide/3.5/) for more details about the workarounds.
## Migrating from 1.6 to 1.7
@@ -252,15 +276,16 @@ statement.
**Due to [6ccbfa](https://github.com/angular/angular.js/commit/6ccbfa65d60a3dc396d0cf6da21b993ad74653fd)**,
the `xlink:href` security context for SVG's `a` and `image` elements has been lowered.
In the unlikely case that an app relied on `RESOURCE_URL` whitelisting for the
In the unlikely case that an app relied on `RESOURCE_URL` trusted list 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).
`xlink:href` contexts are considered safe URLs, e.g. by trusting them in
`$compileProvider`'s `aHrefSanitizationWhitelist` (called `aHrefSanitizationTrustedUrlList` form
1.8.1 onwards) (for `<a>` elements) or `imgSrcSanitizationWhitelist` (called
`imgSrcSanitizationTrustedUrlList` from 1.8.1 onwards) (for `<image>` elements).
<hr />
@@ -1285,7 +1310,7 @@ running at `https://docs.angularjs.org` then the following will fail:
By default, only URLs with the same domain and protocol as the application document are considered
safe in the `RESOURCE_URL` context. To use URLs from other domains and/or protocols, you may either
whitelist them or wrap them into a trusted value by calling `$sce.trustAsResourceUrl(url)`.
add them to the trusted source URL list or wrap them into a trusted value by calling `$sce.trustAsResourceUrl(url)`.
<hr />
<minor />
@@ -1363,7 +1388,7 @@ $http.json('other/trusted/url', {jsonpCallbackParam: 'cb'});
all JSONP requests now require the URL to be trusted as a resource URL. There are two approaches to
trust a URL:
1. **Whitelisting with the `$sceDelegateProvider.resourceUrlWhitelist()` method.**
1. **Setting trusted resource URLs with the `$sceDelegateProvider.resourceUrlWhitelist()` (called `trustedResourceUrlList()` from 1.8.1 onwards) method.**
You configure this list in a module configuration block:
```js
@@ -2183,7 +2208,7 @@ service does not have access to the resource in order to sanitize it.
Similarly, due to [234053fc](https://github.com/angular/angular.js/commit/234053fc9ad90e0d05be7e8359c6af66be94c094),
the `$sanitize` service will now also remove instances of the `usemap` attribute from any elements
passed to it. This attribute is used to reference another element by `name` or `id`. Since the
`name` and `id` attributes are already blacklisted, a sanitized `usemap` attribute could only
`name` and `id` attributes are already banned, a sanitized `usemap` attribute could only
reference unsanitized content, which is a security risk.
Due to [98c2db7f](https://github.com/angular/angular.js/commit/98c2db7f9c2d078a408576e722407d518c7ee10a),
@@ -2623,8 +2648,8 @@ $scope.findTemplate = function(templateName) {
};
```
To migrate, either cache the result of `trustAsResourceUrl()`, or put the template url in the resource
whitelist in the `config()` function:
To migrate, either cache the result of `trustAsResourceUrl()`, or put the template url in the trusted resource
URL list in the `config()` function:
After:
@@ -2638,7 +2663,8 @@ $scope.findTemplate = function(templateName) {
return templateCache[templateName];
};
// Alternatively, use `$sceDelegateProvider.resourceUrlWhitelist()`, which means you don't
// Alternatively, use `$sceDelegateProvider.resourceUrlWhitelist()` (called
// `trustedResourceUrlList()` from 1.8.1 onwards), which means you don't
// have to use `$sce.trustAsResourceUrl()` at all:
angular.module('myApp', []).config(function($sceDelegateProvider) {
@@ -3329,7 +3355,7 @@ below should still apply, but you may want to consult the
<li>{@link guide/migration#directive-priority Directive priority}</li>
<li>{@link guide/migration#ngscenario ngScenario}</li>
<li>{@link guide/migration#nginclude-and-ngview-replace-its-entire-element-on-update ngInclude and ngView replace its entire element on update}</li>
<li>{@link guide/migration#urls-are-now-sanitized-against-a-whitelist URLs are now sanitized against a whitelist}</li>
<li>{@link guide/migration#urls-are-now-sanitized-against-a-trusted-uri-matcher URLs are now sanitized against a trusted URI matcher}</li>
<li>{@link guide/migration#isolate-scope-only-exposed-to-directives-with-scope-property Isolate scope only exposed to directives with <code>scope</code> property}</li>
<li>{@link guide/migration#change-to-interpolation-priority Change to interpolation priority}</li>
<li>{@link guide/migration#underscore-prefixed-suffixed-properties-are-non-bindable Underscore-prefixed/suffixed properties are non-bindable}</li>
@@ -3819,10 +3845,10 @@ See [7d69d52a](https://github.com/angular/angular.js/commit/7d69d52acff8578e0f7d
[aa2133ad](https://github.com/angular/angular.js/commit/aa2133ad818d2e5c27cbd3933061797096356c8a).
### URLs are now sanitized against a whitelist
### URLs are now sanitized against a trusted URI matcher
A whitelist configured via `$compileProvider` can be used to configure what URLs are considered safe.
By default all common protocol prefixes are whitelisted including `data:` URIs with mime types `image/*`.
A trusted URI matcher configured via `$compileProvider` can be used to configure what URLs are considered safe.
By default all common protocol prefixes are trusted including `data:` URIs with mime types `image/*`.
This change shouldn't impact apps that don't contain malicious image links.
See [1adf29af](https://github.com/angular/angular.js/commit/1adf29af13890d61286840177607edd552a9df97),
+3 -2
View File
@@ -174,8 +174,9 @@ Yes, AngularJS can use [jQuery](http://jquery.com/) if it's present in your app
application is being bootstrapped. If jQuery is not present in your script path, AngularJS falls back
to its own implementation of the subset of jQuery that we call {@link angular.element jQLite}.
AngularJS 1.3 only supports jQuery 2.1 or above. jQuery 1.7 and newer might work correctly with AngularJS
but we don't guarantee that.
For AngularJS 1.8 we support jQuery 2.1+ but we suggest jQuery 3.5.1 or above to avoid a potential
security issue. Earlier versions of jQuery might work correctly with AngularJS but we don't guarantee
that.
### What is testability like in AngularJS?
+14 -33
View File
@@ -4,44 +4,25 @@
# Version Support Status
This page describes the support status of the significant versions of AngularJS.
**AngularJS support has officially ended as of January 2022.**
<div class="alert alert-info">
On July 1, 2018 AngularJS entered a 3 year Long Term Support period.
</div>
Visit [angular.io](https://angular.io) for the actively supported Angular.
Any version branch not shown in the following table (e.g. 1.6.x) is no longer being developed.
## What does end of support mean?
<table class="dev-status table table-bordered">
<thead>
<tr><th>Version</th><th>Status</th><th>Comments</th></tr>
</thead>
<tbody>
<tr class="security">
<td><span>1.2.x</span></td>
<td>Security patches only</td>
<td>Last version to provide IE 8 support</td>
</tr>
<tr class="stable">
<td><span>1.7.x</span></td>
<td>Long Term Support</td>
<td>See {@link version-support-status#long-term-support Long Term Support} section below.</td>
</tr>
</tbody>
</table>
The code will remain accessible on [GitHub](https://github.com/angular/angular.js),
[npm](https://www.npmjs.com/package/angular),
[Bower](https://github.com/angular/bower-angular), and
[Release archive](https://code.angularjs.org/1.8.2).
This website will remain here indefinitely.
### Long Term Support
The GitHub repository will be in an archived state, meaning that no new issues or pull requests
can be submitted.
On July 1st 2018, AngularJS entered a Long Term Support period for AngularJS.
See https://goo.gle/angularjs-end-of-life for the full details.
We now focus exclusively on providing fixes to bugs that satisfy at least one of the following criteria:
### Extended Long Term Support
* A security flaw is detected in the 1.7.x branch of the framework
* One of the major browsers releases a version that will cause current production applications using AngularJS 1.7.x to stop working
* The jQuery library releases a version that will cause current production applications using AngularJS 1.7.x to stop working.
If you need extended support for AngularJS, you should consider:
AngularJS 1.2.x will get a new version if and only if a new severe security issue is discovered.
### Blog Post
You can read more about these plans in our [blog post announcement](https://blog.angular.io/stable-angularjs-and-long-term-support-7e077635ee9c).
* [HeroDevs](https://www.herodevs.com/support/nes-angularjs)
+4 -4
View File
@@ -34,16 +34,16 @@ Since we are using [npm][npm] to install client-side dependencies, this step upd
"name": "angular-phonecat",
...
"dependencies": {
"angular": "1.7.x",
"angular-route": "1.7.x",
"angular": "1.8.x",
"angular-route": "1.8.x",
"bootstrap": "3.3.x"
},
...
}
```
The new dependency `"angular-route": "1.7.x"` tells npm to install a version of the angular-route
module that is compatible with version 1.7.x of AngularJS. We must tell npm to download and install
The new dependency `"angular-route": "1.8.x"` tells npm to install a version of the angular-route
module that is compatible with version 1.8.x of AngularJS. We must tell npm to download and install
this dependency.
```
+5 -5
View File
@@ -32,17 +32,17 @@ Since we are using [npm][npm] to install client-side dependencies, this step upd
"name": "angular-phonecat",
...
"dependencies": {
"angular": "1.7.x",
"angular-resource": "1.7.x",
"angular-route": "1.7.x",
"angular": "1.8.x",
"angular-resource": "1.8.x",
"angular-route": "1.8.x",
"bootstrap": "3.3.x"
},
...
}
```
The new dependency `"angular-resource": "1.7.x"` tells npm to install a version of the
angular-resource module that is compatible with version 1.7.x of AngularJS. We must tell npm to
The new dependency `"angular-resource": "1.8.x"` tells npm to install a version of the
angular-resource module that is compatible with version 1.8.x of AngularJS. We must tell npm to
download and install this dependency.
```
+8 -8
View File
@@ -36,20 +36,20 @@ Since we are using [npm][npm] to install client-side dependencies, this step upd
"name": "angular-phonecat",
...
"dependencies": {
"angular": "1.7.x",
"angular-animate": "1.7.x",
"angular-resource": "1.7.x",
"angular-route": "1.7.x",
"angular": "1.8.x",
"angular-animate": "1.8.x",
"angular-resource": "1.8.x",
"angular-route": "1.8.x",
"bootstrap": "3.3.x",
"jquery": "3.3.x"
"jquery": "^3.5.1"
},
...
}
```
* `"angular-animate": "1.7.x"` tells npm to install a version of the angular-animate module that
is compatible with version 1.7.x of AngularJS.
* `"jquery": "3.3.x"` tells npm to install the latest patch release of the 3.3 version of jQuery.
* `"angular-animate": "1.8.x"` tells npm to install a version of the angular-animate module that
is compatible with version 1.8.x of AngularJS.
* `"jquery": "^3.5.1"` tells npm to install a version of jQuery that is compatible with 3.5.x and at least 3.5.1.
Note that this is not an AngularJS library; it is the standard jQuery library. We can use npm to
install a wide range of 3rd party libraries.
+3 -36
View File
@@ -169,42 +169,9 @@ module.exports = function(config, specificOptions) {
});
if (process.env.TRAVIS) {
var buildLabel = 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')';
// Karma (with socket.io 1.x) buffers by 50 and 50 tests can take a long time on IEs;-)
config.browserNoActivityTimeout = 120000;
config.browserStack.build = buildLabel;
config.browserStack.startTunnel = false;
config.browserStack.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
config.sauceLabs.build = buildLabel;
config.sauceLabs.startConnect = false;
config.sauceLabs.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
config.sauceLabs.recordScreenshots = true;
// Try 'websocket' for a faster transmission first. Fallback to 'polling' if necessary.
config.transports = ['websocket', 'polling'];
// Debug logging into a file, that we print out at the end of the build.
config.loggers.push({
type: 'file',
filename: process.env.LOGS_DIR + '/' + (specificOptions.logFile || 'karma.log')
});
if (process.env.BROWSER_PROVIDER === 'saucelabs' || !process.env.BROWSER_PROVIDER) {
// Allocating a browser can take pretty long (eg. if we are out of capacity and need to wait
// for another build to finish) and so the `captureTimeout` typically kills
// an in-queue-pending request, which makes no sense.
config.captureTimeout = 0;
}
}
// Terrible hack to workaround inflexibility of log4js:
// - ignore web-server's 404 warnings,
// - ignore DEBUG logs (on Travis), we log them into a file instead.
// - ignore DEBUG logs (on CI), we log them into a file instead.
var IGNORED_404 = [
'/favicon.ico',
'/%7B%7BtestUrl%7D%7D',
@@ -230,8 +197,8 @@ module.exports = function(config, specificOptions) {
return;
}
// on Travis, ignore DEBUG statements
if (process.env.TRAVIS && log.level.levelStr === config.LOG_DEBUG) {
// on CI, ignore DEBUG statements
if (process.env.CI && log.level.levelStr === config.LOG_DEBUG) {
return;
}
-50
View File
@@ -1,50 +0,0 @@
'use strict';
var fs = require('fs');
var http = require('http');
var BrowserStackTunnel = require('browserstacktunnel-wrapper');
var HOSTNAME = 'localhost';
var PORTS = [9876, 8000];
var ACCESS_KEY = process.env.BROWSER_STACK_ACCESS_KEY;
var READY_FILE = process.env.BROWSER_PROVIDER_READY_FILE;
var TUNNEL_IDENTIFIER = process.env.TRAVIS_JOB_NUMBER;
// We need to start fake servers, otherwise the tunnel does not start.
var fakeServers = [];
var hosts = [];
PORTS.forEach(function(port) {
fakeServers.push(http.createServer(function() {}).listen(port));
hosts.push({
name: HOSTNAME,
port: port,
sslFlag: 0
});
});
var tunnel = new BrowserStackTunnel({
key: ACCESS_KEY,
localIdentifier: TUNNEL_IDENTIFIER,
hosts: hosts
});
console.log('Starting tunnel on ports', PORTS.join(', '));
tunnel.start(function(error) {
if (error) {
console.error('Can not establish the tunnel', error);
} else {
console.log('Tunnel established.');
fakeServers.forEach(function(server) {
server.close();
});
if (READY_FILE) {
fs.writeFile(READY_FILE, '');
}
}
});
tunnel.on('error', function(error) {
console.error(error);
});
-3
View File
@@ -1,3 +0,0 @@
export BROWSER_STACK_ACCESS_KEY=`echo $BROWSER_STACK_ACCESS_KEY | rev`
node ./lib/browserstack/start_tunnel.js &
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
set -e -o pipefail
echo "Shutting down Browserstack tunnel"
echo "TODO: implement me"
exit 1
+2 -2
View File
@@ -63,8 +63,8 @@ module.exports = function(grunt) {
util.collectErrors();
});
grunt.registerTask('firebaseDocsJsonForTravis', function() {
util.firebaseDocsJsonForTravis();
grunt.registerTask('firebaseDocsJsonForCI', function() {
util.firebaseDocsJsonForCI();
});
};
+8 -18
View File
@@ -7,9 +7,12 @@ var spawn = require('npm-run').spawn;
var CSP_CSS_HEADER = '/* Include this file in your html if you are using the CSP mode. */\n\n';
module.exports = {
codeScriptFolder: 'scripts/code.angularjs.org-firebase',
docsScriptFolder: 'scripts/docs.angularjs.org-firebase',
startKarma: function(config, singleRun, done) {
var browsers = grunt.option('browsers');
var reporters = grunt.option('reporters');
@@ -32,8 +35,8 @@ module.exports = {
updateWebdriver: function(done) {
if (process.env.TRAVIS) {
// Skip the webdriver-manager update on Travis, since the browsers will
if (process.env.CI) {
// Skip the webdriver-manager update on CI, since the browsers will
// be provided remotely.
done();
return;
@@ -110,7 +113,7 @@ module.exports = {
.replace(/\\/g, '\\\\')
.replace(/'/g, '\\\'')
.replace(/\r?\n/g, '\\n');
js = '!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend(\'<style type="text/css">' + css + '</style>\');';
js = '!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend(window.angular.element(\'<style>\').text(\'' + css + '\'));';
state.js.push(js);
return state;
@@ -300,19 +303,6 @@ module.exports = {
}
next();
};
},
// Our Firebase projects are in subfolders, but Travis expects them in the root,
// so we need to modify the upload folder path and copy the file into the root
firebaseDocsJsonForTravis: function() {
var docsScriptFolder = 'scripts/docs.angularjs.org-firebase';
var fileName = docsScriptFolder + '/firebase.json';
var json = grunt.file.readJSON(fileName);
(json.hosting || (json.hosting = {})).public = 'deploy/docs';
(json.functions || (json.functions = {})).source = docsScriptFolder + '/functions';
grunt.file.write('firebase.json', JSON.stringify(json));
}
};
+459
View File
@@ -0,0 +1,459 @@
#!/usr/bin/env bash
set -u -e -o pipefail
####################################################################################################
# Some helper funtions
@echo() {
echo "# $*"
}
@warn() {
@echo "Warning: $*" >&2
}
@fail() {
@echo "Error! $*" >&2
exit 1
}
@remove() {
local f="$1"
if [[ -f ${f} ]]; then
@echo "Removing ${f}"
rm -f "${f}" || @fail "Can not delete ${f} file"
fi
}
@kill() {
for p in $1; do
if kill -0 ${p} >/dev/null 2>&1; then
kill ${p}
sleep 2
if kill -0 ${p} >/dev/null 2>&1; then
kill -9 ${p}
sleep 2
fi
fi
done
}
@wait_for() {
local m="$1"
local f="$2"
if [[ ! -f "${f}" ]]; then
printf "# ${m} (${f})"
while [[ ! -f "${f}" ]]; do
printf "."
sleep 0.5
done
printf "\n"
fi
}
####################################################################################################
# Sauce service functions
readonly SCRIPT_DIR=$(cd $(dirname $0); pwd)
readonly TMP_DIR="/tmp/angular/sauce-service"
mkdir -p ${TMP_DIR}
# Location for the saucelabs log file.
readonly SAUCE_LOG_FILE="${TMP_DIR}/sauce-connect.log"
# Location for the saucelabs ready to connection process id lock file.
readonly SAUCE_PID_FILE="${TMP_DIR}/sauce-connect.pid"
# Location for the saucelabs ready to connect lock file.
readonly SAUCE_READY_FILE="${TMP_DIR}/sauce-connect.lock"
# Location for the saucelabs params file for use by test runner.
readonly SAUCE_PARAMS_JSON_FILE="${TMP_DIR}/sauce-connect-params.json"
# Amount of seconds we wait for sauceconnect to establish a tunnel instance. In order to not
# acquire CircleCI instances for too long if sauceconnect fails, we need a connect timeout.
readonly SAUCE_READY_FILE_TIMEOUT=120
readonly SERVICE_LOCK_FILE="${TMP_DIR}/service.lock"
readonly SERVICE_START_FILE="${TMP_DIR}/service.start"
readonly SERVICE_PID_FILE="${TMP_DIR}/service.pid"
readonly SERVICE_LOG_FILE="${TMP_DIR}/service.log"
service-setup-command() {
if [[ -z "${SAUCE_USERNAME:-}" ]]; then
@fail "SAUCE_USERNAME environment variable required"
fi
if [[ -z "${SAUCE_ACCESS_KEY:-}" ]]; then
@fail "SAUCE_ACCESS_KEY environment variable required"
fi
if [[ -z "${SAUCE_TUNNEL_IDENTIFIER:-}" ]]; then
@fail "SAUCE_TUNNEL_IDENTIFIER environment variable required"
fi
local unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) local machine=linux ;;
Darwin*) local machine=darwin ;;
CYGWIN*) local machine=windows ;;
MINGW*) local machine=windows ;;
MSYS_NT*) local machine=windows ;;
*) local machine=linux
printf "\nUnrecongized uname '${unameOut}'; defaulting to use node for linux.\n" >&2
printf "Please file an issue to https://github.com/bazelbuild/rules_nodejs/issues if \n" >&2
printf "you would like to add your platform to the supported rules_nodejs node platforms.\n\n" >&2
;;
esac
case "${machine}" in
# Path to sauce connect executable
linux)
if [[ -z "${BUILD_WORKSPACE_DIRECTORY:-}" ]]; then
# Started manually
SAUCE_CONNECT="${SCRIPT_DIR}/../../node_modules/sauce-connect/bin/sc"
else
# Started via `bazel run`
SAUCE_CONNECT="${BUILD_WORKSPACE_DIRECTORY}/node_modules/sauce-connect/bin/sc"
fi
;;
*)
if [[ -z "${SAUCE_CONNECT:-}" ]]; then
@fail "SAUCE_CONNECT environment variable is required on non-linux environments"
exit 1
fi
;;
esac
if [[ ! -f ${SAUCE_CONNECT} ]]; then
@fail "sc binary not found at ${SAUCE_CONNECT}"
fi
echo "{ \"SAUCE_USERNAME\": \"${SAUCE_USERNAME}\", \"SAUCE_ACCESS_KEY\": \"${SAUCE_ACCESS_KEY}\", \"SAUCE_TUNNEL_IDENTIFIER\": \"${SAUCE_TUNNEL_IDENTIFIER}\", \"SAUCE_LOCALHOST_ALIAS_DOMAIN\": \"${SAUCE_LOCALHOST_ALIAS_DOMAIN:-}\" }" > ${SAUCE_PARAMS_JSON_FILE}
# Command arguments that will be passed to sauce-connect.
# By default we disable SSL bumping for all requests. This is because SSL bumping is
# not needed for our test setup and in order to perform the SSL bumping, Saucelabs
# intercepts all HTTP requests in the tunnel VM and modifies them. This can cause
# flakiness as it makes all requests dependent on the SSL bumping middleware.
# See: https://wiki.saucelabs.com/display/DOCS/Troubleshooting+Sauce+Connect#TroubleshootingSauceConnect-DisablingSSLBumping
local sauce_args=(
"--no-ssl-bump-domains all"
"--logfile ${SAUCE_LOG_FILE}"
"--pidfile ${SAUCE_PID_FILE}"
"--readyfile ${SAUCE_READY_FILE}"
"--tunnel-identifier ${SAUCE_TUNNEL_IDENTIFIER}"
"--user ${SAUCE_USERNAME}"
# Don't add the --api-key here so we don't echo it out in service-pre-start
)
if [[ -n "${SAUCE_LOCALHOST_ALIAS_DOMAIN:-}" ]]; then
# Ensures that requests to the localhost alias domain are always resolved through the tunnel.
# This environment variable is usually configured on CI, and refers to a domain that has been
# locally configured in the current machine's hosts file (e.g. `/etc/hosts`). The domain should
# resolve to the current machine in Saucelabs VMs, so we need to ensure that it is resolved
# through the tunnel we going to create.
sauce_args+=("--tunnel-domains ${SAUCE_LOCALHOST_ALIAS_DOMAIN}")
fi
@echo "Sauce connect will be started with:"
echo " ${SAUCE_CONNECT} ${sauce_args[@]}"
SERVICE_COMMAND="${SAUCE_CONNECT} ${sauce_args[@]} --api-key ${SAUCE_ACCESS_KEY}"
}
# Called by pre-start & post-stop
service-cleanup() {
if [[ -f "${SAUCE_PID_FILE}" ]]; then
local p=$(cat "${SAUCE_PID_FILE}")
@echo "Stopping Sauce Connect (pid $p)..."
@kill $p
fi
@remove "${SAUCE_PID_FILE}"
@remove "${SAUCE_READY_FILE}"
@remove "${SAUCE_PARAMS_JSON_FILE}"
}
# Called before service is setup
service-pre-setup() {
service-cleanup
}
# Called after service is setup
service-post-setup() {
@echo " sauce params : ${SAUCE_PARAMS_JSON_FILE}"
}
# Called before service is started
service-pre-start() {
return
}
# Called after service is started
service-post-start() {
if [[ ! -f "${SAUCE_PID_FILE}" ]]; then
printf "# Waiting for Sauce Connect Proxy process (${SAUCE_PID_FILE})"
while [[ ! -f "${SAUCE_PID_FILE}" ]]; do
if ! @serviceStatus >/dev/null 2>&1; then
printf "\n"
@serviceStop
@echo "Service failed to start!"
service-failed-setup
exit 1
fi
printf "."
sleep 0.5
done
printf "\n"
fi
@echo "Sauce Connect Proxy started (pid $(cat "${SAUCE_PID_FILE}"))"
}
# Called if service fails to start
service-failed-setup() {
if [[ -f "${SERVICE_LOG_FILE}" ]]; then
@echo "tail ${SERVICE_LOG_FILE}:"
echo "--------------------------------------------------------------------------------"
tail "${SERVICE_LOG_FILE}"
echo "--------------------------------------------------------------------------------"
echo "^^^^^ ${SERVICE_LOG_FILE} ^^^^^"
fi
}
# Called by ready-wait action
service-ready-wait() {
if [[ ! -f "${SAUCE_PID_FILE}" ]]; then
@fail "Sauce Connect not running"
fi
if [[ ! -f "${SAUCE_READY_FILE}" ]]; then
# Wait for saucelabs tunnel to connect
printf "# Waiting for saucelabs tunnel to connect (${SAUCE_READY_FILE})"
counter=0
while [[ ! -f "${SAUCE_READY_FILE}" ]]; do
counter=$((counter + 1))
# Counter needs to be multiplied by two because the while loop only sleeps a half second.
# This has been made in favor of better progress logging (printing dots every half second)
if [ $counter -gt $[${SAUCE_READY_FILE_TIMEOUT} * 2] ]; then
@echo "Timed out after ${SAUCE_READY_FILE_TIMEOUT} seconds waiting for tunnel ready file."
if [[ -f "${SAUCE_LOG_FILE}" ]]; then
echo "================================================================================"
echo "${SAUCE_LOG_FILE}:"
cat "${SAUCE_LOG_FILE}"
fi
exit 5
fi
printf "."
sleep 0.5
done
printf "\n"
@echo "Saucelabs tunnel connected"
else
@echo "Saucelabs tunnel already connected"
fi
}
# Called before service is stopped
service-pre-stop() {
return
}
# Called after service is stopped
service-post-stop() {
service-cleanup
}
####################################################################################################
# Generic service functions
# This uses functions setup above but nothing below should be specific to saucelabs
@serviceLock() {
# Check is Lock File exists, if not create it and set trap on exit
printf "# Waiting for service action lock (${SERVICE_LOCK_FILE})"
while true; do
if { set -C; 2>/dev/null >"${SERVICE_LOCK_FILE}"; }; then
trap "rm -f \"${SERVICE_LOCK_FILE}\"" EXIT
printf "\n"
break
fi
printf "."
sleep 0.5
done
@echo "Acquired service action lock"
}
@serviceStatus() {
if [ -f "${SERVICE_PID_FILE}" ] && [ ! -z "$(cat "${SERVICE_PID_FILE}")" ]; then
local p=$(cat "${SERVICE_PID_FILE}")
if kill -0 $p >/dev/null 2>&1; then
@echo "Service is running (pid $p)"
return 0
else
@echo "Service is not running (process PID $p not exists)"
return 1
fi
else
@echo "Service is not running"
return 2
fi
}
@serviceSetup() {
if @serviceStatus >/dev/null 2>&1; then
@echo "Service already running (pid $(cat "${SERVICE_PID_FILE}"))"
return 0
fi
@echo "Setting up service..."
@remove "${SERVICE_PID_FILE}"
@remove "${SERVICE_START_FILE}"
touch "${SERVICE_LOG_FILE}" >/dev/null 2>&1 || @fail "Can not create ${SERVICE_LOG_FILE} file"
@echo " service pid : ${SERVICE_PID_FILE}"
@echo " service logs : ${SERVICE_LOG_FILE}"
service-pre-setup
service-setup-command
(
(
if [[ -z "${SERVICE_COMMAND:-}" ]]; then
@fail "No SERVICE_COMMAND is set"
fi
@wait_for "Waiting for start file" "${SERVICE_START_FILE}"
${SERVICE_COMMAND}
) >>"${SERVICE_LOG_FILE}" 2>&1
) &
echo $! >"${SERVICE_PID_FILE}"
if @serviceStatus >/dev/null 2>&1; then
@echo "Service setup (pid $(cat "${SERVICE_PID_FILE}"))"
service-post-setup
else
@echo "Error setting up Service!"
service-failed-setup
exit 1
fi
return $?
}
@serviceStart() {
if @serviceStatus >/dev/null 2>&1; then
@echo "Service already setup (pid $(cat "${SERVICE_PID_FILE}"))"
else
@serviceSetup
fi
if [[ -f "${SERVICE_START_FILE}" ]]; then
@echo "Service already started"
else
@echo "Starting service..."
service-pre-start
touch "${SERVICE_START_FILE}" >/dev/null 2>&1 || @err "Can not create ${SERVICE_START_FILE} file"
service-post-start
@echo "Service started"
fi
}
@serviceStop() {
if @serviceStatus >/dev/null 2>&1; then
touch "${SERVICE_PID_FILE}" >/dev/null 2>&1 || @fail "Can not touch ${SERVICE_PID_FILE} file"
service-pre-stop
@echo "Stopping sevice (pid $(cat "${SERVICE_PID_FILE}"))..."
@kill $(cat "${SERVICE_PID_FILE}")
if @serviceStatus >/dev/null 2>&1; then
@fail "Error stopping Service! Service already running with PID $(cat "${SERVICE_PID_FILE}")"
else
@echo "Service stopped"
@remove "${SERVICE_PID_FILE}"
@remove "${SERVICE_START_FILE}"
service-post-stop
fi
return 0
else
@warn "Service is not running"
@remove "${SERVICE_PID_FILE}"
@remove "${SERVICE_START_FILE}"
service-post-stop
fi
}
@serviceStartReadyWait() {
@serviceStart
@serviceReadyWait
}
@serviceReadyWait() {
service-ready-wait
}
@serviceRestart() {
@serviceStop
@serviceStart
}
@serviceTail() {
@echo "tail ${SERVICE_LOG_FILE}:"
tail -f "${SERVICE_LOG_FILE}"
}
@serviceLog() {
@echo "cat ${SERVICE_LOG_FILE}:"
echo "--------------------------------------------------------------------------------"
cat "${SERVICE_LOG_FILE}"
echo "--------------------------------------------------------------------------------"
echo "^^^^^ ${SERVICE_LOG_FILE} ^^^^^"
}
case "${1:-}" in
setup)
@serviceLock
@serviceSetup
;;
start)
@serviceLock
@serviceStart
;;
start-ready-wait)
@serviceLock
@serviceStartReadyWait
;;
ready-wait)
@serviceLock
@serviceReadyWait
;;
stop)
@serviceLock
@serviceStop
;;
restart)
@serviceLock
@serviceRestart
;;
status)
@serviceLock
@serviceStatus
;;
run)
(
service-setup-command
if [[ -z "${SERVICE_COMMAND:-}" ]]; then
@fail "No SERVICE_COMMAND is set"
fi
${SERVICE_COMMAND}
)
;;
log)
@serviceLog
;;
tail)
@serviceTail
;;
*)
@echo "Actions: [setup|start|start-read-wait|ready-wait|stop|restart|status|run|tail]"
exit 1
;;
esac
-47
View File
@@ -1,47 +0,0 @@
#!/bin/bash
set -e
# Setup and start Sauce Connect for your TravisCI build
# This script requires your .travis.yml to include the following two private env variables:
# SAUCE_USERNAME
# SAUCE_ACCESS_KEY
# Follow the steps at https://saucelabs.com/opensource/travis to set that up.
#
# Curl and run this script as part of your .travis.yml before_script section:
# before_script:
# - curl https://gist.github.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash
SC_VERSION="4.5.4"
CONNECT_URL="https://saucelabs.com/downloads/sc-$SC_VERSION-linux.tar.gz"
CONNECT_DIR="/tmp/sauce-connect-$RANDOM"
CONNECT_DOWNLOAD="sc-$SC_VERSION-linux.tar.gz"
# We don't want to create a log file because sauceconnect always logs in verbose mode. This seems
# to be overwhelming Travis and causing flakes when we are cat-ing the log in "print_logs.sh"
CONNECT_LOG="/dev/null"
# Get Connect and start it
mkdir -p $CONNECT_DIR
cd $CONNECT_DIR
curl $CONNECT_URL -o $CONNECT_DOWNLOAD 2> /dev/null 1> /dev/null
mkdir sauce-connect
tar --extract --file=$CONNECT_DOWNLOAD --strip-components=1 --directory=sauce-connect > /dev/null
rm $CONNECT_DOWNLOAD
SAUCE_ACCESS_KEY=`echo $SAUCE_ACCESS_KEY | rev`
ARGS=""
# Set tunnel-id only on Travis, to make local testing easier.
if [ ! -z "$TRAVIS_JOB_NUMBER" ]; then
ARGS="$ARGS --tunnel-identifier $TRAVIS_JOB_NUMBER"
fi
if [ ! -z "$BROWSER_PROVIDER_READY_FILE" ]; then
ARGS="$ARGS --readyfile $BROWSER_PROVIDER_READY_FILE"
fi
echo "Starting Sauce Connect in the background"
sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY $ARGS \
--logfile $CONNECT_LOG &
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
set -e -o pipefail
echo "Shutting down Sauce Connect tunnel"
killall sc
while [[ -n `ps -ef | grep "sauce-connect-" | grep -v "grep"` ]]; do
printf "."
sleep .5
done
echo ""
echo "Sauce Connect tunnel has been shut down"
+3 -3
View File
@@ -65,7 +65,7 @@ var getCodeName = function(tagName) {
/**
* Compute a build segment for the version, from the Jenkins build number and current commit SHA
* Compute a build segment for the version, from the CI build number and current commit SHA
* @return {String} The build segment of the version
*/
function getBuild() {
@@ -189,7 +189,7 @@ var getSnapshotVersion = function() {
// We need to clone to ensure that we are not modifying another version
version = semver(version.raw);
var jenkinsBuild = process.env.TRAVIS_BUILD_NUMBER || process.env.BUILD_NUMBER;
var ciBuild = process.env.CIRCLE_BUILD_NUM || process.env.BUILD_NUMBER;
if (!version.prerelease || !version.prerelease.length) {
// last release was a non beta release. Increment the patch level to
// indicate the next release that we will be doing.
@@ -203,7 +203,7 @@ var getSnapshotVersion = function() {
// as this is bigger than 1.3.0-beta.2 according to semver
version.patch++;
}
version.prerelease = jenkinsBuild ? ['build', jenkinsBuild] : ['local'];
version.prerelease = ciBuild ? ['build', ciBuild] : ['local'];
version.build = getBuild();
version.codeName = 'snapshot';
version.isSnapshot = true;
+28 -24
View File
@@ -1,16 +1,16 @@
{
"name": "angular",
"license": "MIT",
"branchVersion": "^1.7.0",
"branchPattern": "1.7.*",
"branchVersion": "^1.8.0",
"branchPattern": "1.8.*",
"distTag": "next",
"repository": {
"type": "git",
"url": "https://github.com/angular/angular.js.git"
},
"engines": {
"node": ">=8.12.0",
"yarn": ">=1.10.1",
"node": ">=12.14.1",
"yarn": ">=1.21.1",
"grunt-cli": "^1.2.0"
},
"scripts": {
@@ -22,12 +22,12 @@
"angular-benchpress": "0.x.x",
"benchmark": "1.x.x",
"bootstrap": "3.1.1",
"browserstacktunnel-wrapper": "2.0.0",
"browserstacktunnel-wrapper": "2.0.4",
"canonical-path": "0.0.2",
"changez": "^2.1.1",
"changez-angular": "^2.1.2",
"cheerio": "^0.17.0",
"commitizen": "^2.3.0",
"commitizen": "^4.2.4",
"commitplease": "^2.7.10",
"cross-spawn": "^4.0.0",
"cz-conventional-changelog": "1.1.4",
@@ -35,9 +35,10 @@
"dgeni-packages": "^0.26.5",
"eslint-plugin-promise": "^3.6.0",
"event-stream": "~3.1.0",
"firebase-tools": "^9.3.0",
"glob": "^6.0.1",
"google-code-prettify": "1.0.1",
"grunt": "^1.0.1",
"grunt": "^1.4.1",
"grunt-bump": "^0.8.0",
"grunt-cli": "^1.2.0",
"grunt-contrib-clean": "^1.0.0",
@@ -54,28 +55,28 @@
"gulp-foreach": "0.0.1",
"gulp-rename": "^1.2.0",
"gulp-sourcemaps": "^1.2.2",
"gulp-uglify": "^1.0.1",
"gulp-uglify": "^3.0.2",
"gulp-util": "^3.0.1",
"jasmine-core": "^2.8.0",
"jasmine-node": "^2.0.0",
"jasmine-reporters": "^2.2.0",
"jquery": "3.4.0",
"jquery": "3.5.1",
"jquery-2.1": "npm:jquery@2.1.4",
"jquery-2.2": "npm:jquery@2.2.4",
"karma": "^3.1.4",
"karma-browserstack-launcher": "^1.3.0",
"karma-chrome-launcher": "^2.2.0",
"karma-edge-launcher": "^0.4.2",
"karma-firefox-launcher": "^1.1.0",
"karma-ie-launcher": "^1.0.0",
"karma": "4.4.1",
"karma-browserstack-launcher": "1.5.1",
"karma-chrome-launcher": "3.1.0",
"karma-edge-launcher": "0.4.2",
"karma-firefox-launcher": "1.2.0",
"karma-ie-launcher": "1.0.0",
"karma-jasmine": "^1.1.2",
"karma-junit-reporter": "^1.2.0",
"karma-safari-launcher": "^1.0.0",
"karma-sauce-launcher": "^2.0.2",
"karma-script-launcher": "^1.0.0",
"karma-spec-reporter": "^0.0.32",
"karma-junit-reporter": "2.0.1",
"karma-safari-launcher": "1.0.0",
"karma-sauce-launcher": "2.0.2",
"karma-script-launcher": "1.0.0",
"karma-spec-reporter": "0.0.32",
"load-grunt-tasks": "^3.5.0",
"lodash": "~2.4.1",
"lodash": "~4.17.21",
"log4js": "^0.6.27",
"lunr": "^0.7.2",
"marked": "~0.3.0",
@@ -83,11 +84,12 @@
"npm-run": "^4.1.0",
"open-sans-fontface": "^1.4.0",
"promises-aplus-tests": "~2.1.0",
"protractor": "^5.4.1",
"protractor": "^7.0.0",
"q": "~1.0.0",
"q-io": "^1.10.9",
"qq": "^0.3.5",
"rewire": "~2.1.0",
"sauce-connect": "https://saucelabs.com/downloads/sc-4.6.2-linux.tar.gz",
"sax": "^1.1.1",
"selenium-webdriver": "^4.0.0-alpha.1",
"semver": "^5.4.1",
@@ -101,8 +103,10 @@
"dependencies": {},
"resolutions": {
"//1": "`natives@1.1.0` does not work with Node.js 10.x on Windows 10",
"//2": "(E.g. see https://github.com/gulpjs/gulp/issues/2162.)",
"natives": "1.1.3"
"//2": "(E.g. see https://github.com/gulpjs/gulp/issues/2162 and https://github.com/nodejs/node/issues/25132.)",
"natives": "1.1.6",
"//3": "`graceful-fs` needs to be pinned to support gulp 3, on Node v12+",
"graceful-fs": "^4.2.3"
},
"commitplease": {
"style": "angular",
+44
View File
@@ -0,0 +1,44 @@
'use strict';
var config = require('./protractor-shared-conf').config;
// Using SauceLabs.
config.capabilities = undefined;
config.sauceUser = process.env.SAUCE_USERNAME;
config.sauceKey = process.env.SAUCE_ACCESS_KEY;
config.multiCapabilities = [
capabilitiesForSauceLabs({
browserName: 'chrome',
platform: 'OS X 10.15',
version: '91'
}),
capabilitiesForSauceLabs({
browserName: 'firefox',
platform: 'OS X 10.15',
version: '85'
})
];
config.allScriptsTimeout = 30000;
config.getPageTimeout = 30000;
exports.config = config;
function capabilitiesForSauceLabs(capabilities) {
return {
'tunnel-identifier': process.env.SAUCE_TUNNEL_IDENTIFIER,
'name': 'AngularJS E2E',
'build': `${process.env.CIRCLE_BUILD_NUM}-${process.env.CIRCLE_NODE_INDEX}`,
'browserName': capabilities.browserName,
'platform': capabilities.platform,
'version': capabilities.version,
'elementScrollBehavior': 1,
// Allow e2e test sessions to run for a maximum of 40 minutes, instead of the default 30 minutes.
'maxDuration': 2400
};
}
-42
View File
@@ -1,42 +0,0 @@
'use strict';
exports.config = {
allScriptsTimeout: 11000,
specs: [
'test/e2e/tests/**/*.js',
'build/docs/ptore2e/**/*.js',
'docs/app/e2e/*.scenario.js'
],
capabilities: {
'browserName': 'chrome'
},
baseUrl: 'http://localhost:8000/',
framework: 'jasmine2',
onPrepare: function() {
/* global angular: false, browser: false, jasmine: false */
// Disable animations so e2e tests run more quickly
var disableNgAnimate = function() {
angular.module('disableNgAnimate', []).run(['$animate', function($animate) {
$animate.enabled(false);
}]);
};
browser.addMockModule('disableNgAnimate', disableNgAnimate);
var reporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new reporters.JUnitXmlReporter({
savePath: 'test_out/docs-e2e-' + exports.config.capabilities.browserName + '-'
}));
},
jasmineNodeOpts: {
defaultTimeoutInterval: 30000,
showColors: false
}
};
-86
View File
@@ -1,86 +0,0 @@
'use strict';
var config = require('./protractor-shared-conf').config;
if (process.env.BROWSER_PROVIDER === 'browserstack') {
// Using BrowserStack.
config.seleniumAddress = 'http://hub.browserstack.com/wd/hub';
config.multiCapabilities = [
capabilitiesForBrowserStack({
browserName: 'chrome',
platform: 'MAC',
version: '49'
}),
capabilitiesForBrowserStack({
browserName: 'firefox',
version: '47'
}),
capabilitiesForBrowserStack({
browserName: 'safari',
platform: 'MAC',
version: '9'
})
];
} else {
// Using SauceLabs.
config.sauceUser = process.env.SAUCE_USERNAME;
config.sauceKey = process.env.SAUCE_ACCESS_KEY;
config.multiCapabilities = [
capabilitiesForSauceLabs({
browserName: 'chrome',
platform: 'OS X 10.11',
version: '48'
}),
capabilitiesForSauceLabs({
browserName: 'firefox',
version: '47'
}),
capabilitiesForSauceLabs({
browserName: 'safari',
platform: 'OS X 10.11',
version: '9'
})
];
}
config.allScriptsTimeout = 30000;
config.getPageTimeout = 30000;
exports.config = config;
function capabilitiesForBrowserStack(capabilities) {
return {
'browserstack.user': process.env.BROWSER_STACK_USERNAME,
'browserstack.key': process.env.BROWSER_STACK_ACCESS_KEY,
'browserstack.local': 'true',
'browserstack.debug': 'true',
'browserstack.tunnelIdentifier': process.env.TRAVIS_JOB_NUMBER,
'tunnelIdentifier': process.env.TRAVIS_JOB_NUMBER,
'name': 'AngularJS E2E',
'build': process.env.TRAVIS_BUILD_NUMBER,
'browserName': capabilities.browserName,
'platform': capabilities.platform,
'version': capabilities.version,
'elementScrollBehavior': 1
};
}
function capabilitiesForSauceLabs(capabilities) {
return {
'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
'name': 'AngularJS E2E',
'build': process.env.TRAVIS_BUILD_NUMBER,
'browserName': capabilities.browserName,
'platform': capabilities.platform,
'version': capabilities.version,
'elementScrollBehavior': 1,
// Allow e2e test sessions to run for a maximum of 35 minutes, instead of the default 30 minutes.
'maxDuration': 2100
};
}
-1
View File
@@ -1,7 +1,6 @@
#!/bin/bash
# Tags a release
# so that travis can do the actual release.
echo "#################################"
echo "## Tag angular.js for a release #"
@@ -1,16 +1,20 @@
'use strict';
const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
const path = require('path');
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const gcsBucketId = `${process.env.GCLOUD_PROJECT}.appspot.com`;
const BROWSER_CACHE_DURATION = 60 * 10;
const CDN_CACHE_DURATION = 60 * 60 * 12;
function sendStoredFile(request, response) {
const requestPath = request.path || '/';
// Request paths will be URI-encoded, so we need to decode them to match the file names in the
// storage bucket. Failing to do so will result in a 404 error from the bucket and `index.html`
// will be returned instead.
// Example of path requiring decoding: `.../input%5Btext%5D.html` --> `.../input[text].html`
const requestPath = decodeURI(request.path || '/');
let filePathSegments = requestPath.split('/').filter((segment) => {
// Remove empty leading or trailing path parts
return segment !== '';
@@ -19,7 +23,7 @@ function sendStoredFile(request, response) {
const version = filePathSegments[0];
const isDocsPath = filePathSegments[1] === 'docs';
const lastSegment = filePathSegments[filePathSegments.length - 1];
const bucket = gcs.bucket(gcsBucketId);
const bucket = storage.bucket(gcsBucketId);
let downloadSource;
let fileName;
@@ -36,13 +40,13 @@ function sendStoredFile(request, response) {
return getDirectoryListing('/').catch(sendErrorResponse);
}
downloadSource = path.join.apply(null, filePathSegments);
downloadSource = filePathSegments.join('/');
downloadAndSend(downloadSource).catch(error => {
if (isDocsPath && error.code === 404) {
fileName = 'index.html';
filePathSegments = [version, 'docs', fileName];
downloadSource = path.join.apply(null, filePathSegments);
downloadSource = filePathSegments.join('/');
return downloadAndSend(downloadSource);
}
@@ -195,12 +199,12 @@ const snapshotRegex = /^snapshot(-stable)?\//;
* When a new zip file is uploaded into snapshot or snapshot-stable,
* delete the previous zip file.
*/
function deleteOldSnapshotZip(object, context) {
function deleteOldSnapshotZip(object) {
const bucketId = object.bucket;
const filePath = object.name;
const contentType = object.contentType;
const bucket = gcs.bucket(bucketId);
const bucket = storage.bucket(bucketId);
const snapshotFolderMatch = filePath.match(snapshotRegex);
File diff suppressed because it is too large Load Diff
@@ -1,10 +1,13 @@
{
"name": "functions-firebase-code.angularjs.org",
"description": "Cloud Functions to serve files from gcs to code.angularjs.org",
"engines": {
"node": "14"
},
"dependencies": {
"@google-cloud/storage": "^1.1.1",
"firebase-admin": "^5.11.0",
"firebase-functions": "^1.0.4"
"@google-cloud/storage": "^5.8.5",
"firebase-admin": "^9.9.0",
"firebase-functions": "^3.14.1"
},
"private": true
}
File diff suppressed because it is too large Load Diff
@@ -1,15 +1,15 @@
Firebase for code.angularjs.org
===============================
This folder contains the Google Firebase scripts for the code.angularjs.org setup.
This folder contains the Google Firebase scripts for the `code.angularjs.org` setup.
firebase.json contains the rewrite rules that route every subdirectory request to the cloud function
in functions/index.js that serves the docs from the Firebase Google Cloud Storage bucket.
`firebase.json` contains the rewrite rules that route every subdirectory request to the cloud function in `functions/index.js` that serves the docs from the Firebase Google Cloud Storage bucket.
functions/index.js also contains a rule that deletes outdated build zip files
from the snapshot and snapshot-stable folders when new zip files are uploaded.
`functions/index.js` also contains a rule that deletes outdated build zip files from the snapshot and snapshot-stable folders when new zip files are uploaded.
The deployment to the Google Cloud Storage bucket happens automatically via Travis. See the travis.yml
file in the repository root.
See `/scripts/docs.angularjs.org-firebase/readme.firebase.code.md` for the Firebase deployment to `docs.angularjs.org`.
See /readme.firebase.docs.md for the firebase deployment to docs.angularjs.org
# Continuous integration
The code is deployed to Google Firebase hosting and functions as well as to the Google Cloud Storage bucket automatically via CI.
See `.circleci/config.yml` for the complete deployment config and build steps.
+1 -1
View File
@@ -63,7 +63,7 @@ function _update_code() {
function publish {
# publish updates the code.angularjs.org Github repository
# the deployment to Firebase happens via Travis
# the deployment to Firebase happens via CI
_update_code
}
@@ -1,6 +1,6 @@
{
"hosting": {
"public": "../../deploy/docs",
"public": "deploy",
"redirects": [
{
"source": "/error/:namespace\\::error*",
File diff suppressed because it is too large Load Diff
@@ -1,21 +1,24 @@
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"engines": {
"node": "14"
},
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase experimental:functions:shell",
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"firebase-admin": "~5.8.1",
"firebase-functions": "^0.8.1"
"firebase-admin": "^9.9.0",
"firebase-functions": "^3.14.1"
},
"devDependencies": {
"eslint": "^4.12.0",
"eslint-plugin-promise": "^3.6.0"
"eslint": "^7.28.0",
"eslint-plugin-promise": "^5.1.0"
},
"private": true
}
File diff suppressed because it is too large Load Diff
@@ -1,23 +1,26 @@
Firebase for docs.angularjs.org
===============================
This folder contains the Google Firebase scripts for the `docs.angularjs.org` setup.
See `/scripts/code.angularjs.org-firebase/readme.firebase.code.md` for the Firebase deployment to `code.angularjs.org`.
# Continuous integration
The docs are deployed to Google Firebase hosting via Travis deployment config, which expects
firebase.json in the repository root, which is done by a Grunt task (firebaseDocsJsonForTravis)
that modifies the paths in the firebase.json and copies it into the repository root.
The docs are deployed to Google Firebase hosting and functions automatically via CI.
See travis.yml for the complete deployment config, and scripts/travis/build.sh for the full deployment
build steps.
See `.circleci/config.yml` for the complete deployment config and build steps.
# Serving locally:
- Run `grunt:prepareDeploy`.
This copies docs content files into deploy/docs and the partials for Search Engine AJAX
Crawling into ./functions/content.
- Run `cd scripts/docs.angularjs.org-firebase`.
This changes the current working directory.
- Run `firebase serve --only functions,hosting`
Creates a server at localhost:5000 that serves from deploy/docs and uses the local function
- Run `yarn grunt package`.
This builds the files that will be deployed.
See /scripts/code.angularjs.org-firebase/readme.firebase.code.md for the firebase deployment to
code.angularjs.org
- Run `yarn grunt prepareDeploy`.
This copies docs content files into `./deploy` and the partials for Search Engine AJAX Crawling into `./functions/content`.
- Run `$(yarn bin)/firebase emulators:start` (or `..\..\node_modules\.bin\firebase emulators:start` on Windows).
Creates a server at http://localhost:5000 that serves from `./deploy` and uses the local function.
-44
View File
@@ -1,44 +0,0 @@
#!/bin/bash
echo "#################################"
echo "#### Jenkins Build ############"
echo "#################################"
source scripts/jenkins/init-node.sh
# Enable tracing and exit on first failure
set -xe
# This is the default set of browsers to use on the CI server unless overridden via env variable
if [[ -z "$BROWSERS" ]]
then
BROWSERS="Chrome"
fi
# CLEAN #
rm -f angular.min.js.gzip.size
rm -f angular.js.size
# BUILD #
yarn grunt ci-checks package --no-color
mkdir -p test_out
# UNIT TESTS #
yarn grunt test:unit --browsers="$BROWSERS" --reporters=dots,junit --no-colors --no-color
# END TO END TESTS #
yarn grunt test:ci-protractor
# DOCS APP TESTS #
yarn grunt test:docs --browsers="$BROWSERS" --reporters=dots,junit --no-colors --no-color
# Promises/A+ TESTS #
yarn grunt test:promises-aplus --no-color
# CHECK SIZE #
gzip -c < build/angular.min.js > build/angular.min.js.gzip
echo "YVALUE=`ls -l build/angular.min.js | cut -d" " -f 8`" > angular.min.js.size
echo "YVALUE=`ls -l build/angular.min.js.gzip | cut -d" " -f 8`" > angular.min.js.gzip.size
-18
View File
@@ -1,18 +0,0 @@
#!/bin/bash
# Install nvm for this shell
source ~/.nvm/nvm.sh
# Use version of node.js found in .nvmrc
nvm install
# clean out and install yarn
rm -rf ~/.yarn
curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.10.1
export PATH="$HOME/.yarn/bin:$PATH"
# Ensure that we have the local dependencies installed
yarn install
echo testing grunt version
yarn grunt --version
-38
View File
@@ -1,38 +0,0 @@
#!/bin/bash
echo "#################################"
echo "#### Update master ##############"
echo "#################################"
ARG_DEFS=()
function init {
if [[ ! $VERBOSE ]]; then
VERBOSE=false
fi
VERBOSE_ARG="--verbose=$VERBOSE"
}
function build {
cd ../..
scripts/jenkins/build.sh
cd $SCRIPT_DIR
}
function phase {
ACTION_ARG="--action=$1"
../code.angularjs.org/publish.sh $ACTION_ARG $VERBOSE_ARG
../bower/publish.sh $ACTION_ARG $VERBOSE_ARG
}
function run {
build
# First prepare all scripts (build, test, commit, tag, ...),
# so we are sure everything is all right
phase prepare
# only then publish to github
phase publish
}
source $(dirname $0)/../utils.inc
@@ -36,7 +36,6 @@ function init {
function build {
cd ../..
source scripts/jenkins/init-node.sh
yarn grunt ci-checks package --no-color
cd $SCRIPT_DIR
@@ -65,4 +64,4 @@ function run {
phase publish
}
source $(dirname $0)/../utils.inc
source $(dirname $0)/../utils.inc
@@ -38,4 +38,4 @@ function run {
phase publish
}
source $(dirname $0)/../utils.inc
source $(dirname $0)/../utils.inc
-28
View File
@@ -1,28 +0,0 @@
#!/bin/bash
set -e
mkdir -p "$LOGS_DIR"
if [ "$JOB" != "ci-checks" ]; then
echo "start_browser_provider"
./scripts/travis/start_browser_provider.sh
fi
# ci-checks and unit tests do not run against the packaged code
if [[ "$JOB" != "ci-checks" ]] && [[ "$JOB" != unit-* ]]; then
yarn grunt package
fi
# unit runs the docs tests too which need a built version of the code
if [[ "$JOB" = unit-* ]]; then
yarn grunt validate-angular-files
yarn grunt build
fi
# check this after the package, because at this point the browser_provider
# has probably arrived
if [ "$JOB" != "ci-checks" ]; then
echo "wait_for_browser_provider"
./scripts/travis/wait_for_browser_provider.sh
fi
-114
View File
@@ -1,114 +0,0 @@
#!/bin/bash
set -e
readonly THIS_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
readonly ROOT_DIR="$THIS_DIR/../.."
export BROWSER_STACK_ACCESS_KEY
export SAUCE_ACCESS_KEY
BROWSER_STACK_ACCESS_KEY=$(echo "$BROWSER_STACK_ACCESS_KEY" | rev)
SAUCE_ACCESS_KEY=$(echo "$SAUCE_ACCESS_KEY" | rev)
# The currently latest-1 version of desktop Safari on Saucelabs (v12.0) is unstable and disconnects
# consistently. The latest version (v12.1) works fine.
# TODO: Add `SL_Safari-1` back, once it no longer corresponds to v12.0.
BROWSERS="SL_Chrome,SL_Chrome-1,\
SL_Firefox,SL_Firefox-1,\
SL_Safari,\
SL_iOS,SL_iOS-1,\
SL_IE_9,SL_IE_10,SL_IE_11,\
SL_EDGE,SL_EDGE-1"
case "$JOB" in
"ci-checks")
grunt ci-checks
if [[ $TRAVIS_PULL_REQUEST != 'false' ]]; then
# validate commit messages of all commits in the PR
# convert commit range to 2 dots, as commitplease uses `git log`.
# See https://github.com/travis-ci/travis-ci/issues/4596 for more info
echo "Validate commit messages in PR:"
yarn run commitplease "${TRAVIS_COMMIT_RANGE/.../..}"
fi
;;
"unit-core")
grunt test:promises-aplus
grunt test:jqlite --browsers="$BROWSERS" --reporters=spec
;;
"unit-jquery")
grunt test:jquery --browsers="$BROWSERS" --reporters=spec
grunt test:jquery-2.2 --browsers="$BROWSERS" --reporters=spec
grunt test:jquery-2.1 --browsers="$BROWSERS" --reporters=spec
;;
"unit-modules")
grunt test:modules --browsers="$BROWSERS" --reporters=spec
;;
"docs-app")
grunt tests:docs --browsers="$BROWSERS" --reporters=spec
grunt test:travis-protractor --specs="docs/app/e2e/**/*.scenario.js"
;;
"e2e")
if [[ $TEST_TARGET == jquery* ]]; then
export USE_JQUERY=1
fi
if [[ "$TEST_TARGET" == jquery* ]]; then
TARGET_SPECS="build/docs/ptore2e/**/jquery_test.js"
else
TARGET_SPECS="build/docs/ptore2e/**/default_test.js"
fi
TARGET_SPECS="test/e2e/tests/**/*.js,$TARGET_SPECS"
grunt test:travis-protractor --specs="$TARGET_SPECS"
;;
"deploy")
export DEPLOY_DOCS
export DEPLOY_CODE
DIST_TAG=$( jq ".distTag" "package.json" | tr -d "\"[:space:]" )
# upload docs if the branch distTag from package.json is "latest" (i.e. stable branch)
if [[ "$DIST_TAG" == latest ]]; then
DEPLOY_DOCS=true
else
DEPLOY_DOCS=false
fi
# upload the build (code + docs) if ...
# the commit is tagged
# - or the branch is "master"
# - or the branch distTag from package.json is "latest" (i.e. stable branch)
if [[ "$TRAVIS_TAG" != '' || "$TRAVIS_BRANCH" == master || "$DIST_TAG" == latest ]]; then
DEPLOY_CODE=true
else
DEPLOY_CODE=false
fi
if [[ "$DEPLOY_DOCS" == true || "$DEPLOY_CODE" == true ]]; then
grunt prepareDeploy
if [[ "$DEPLOY_DOCS" == true ]]; then
# Install npm dependencies for Firebase functions.
(
cd "$ROOT_DIR/scripts/docs.angularjs.org-firebase/functions"
npm install
)
fi
else
echo "Skipping deployment build because conditions have not been met."
fi
;;
*)
echo "Unknown job type. Please set JOB to one of\
'ci-checks',\
'unit-core',\
'unit-jquery',\
'unit-modules',\
'docs-app',\
'e2e',\
or\
'deploy'."
;;
esac
-11
View File
@@ -1,11 +0,0 @@
#!/bin/bash
LOG_FILES=$LOGS_DIR/*
for FILE in $LOG_FILES; do
echo -e "\n\n\n"
echo "================================================================================"
echo " $FILE"
echo "================================================================================"
cat $FILE || true
done
-14
View File
@@ -1,14 +0,0 @@
#!/bin/bash
# Has to be run from project root directory.
if [ "$BROWSER_PROVIDER" == "browserstack" ]; then
echo "Using BrowserStack"
elif [ "$BROWSER_PROVIDER" == "saucelabs" ]; then
echo "Using SauceLabs"
else
echo "Invalid BROWSER_PROVIDER. Please set env var BROWSER_PROVIDER to 'saucelabs' or 'browserstack'."
exit 1
fi
./lib/${BROWSER_PROVIDER}/start_tunnel.sh
@@ -1,4 +0,0 @@
#!/bin/bash
# Has to be run from project root directory.
./lib/${BROWSER_PROVIDER}/teardown_tunnel.sh
@@ -1,19 +0,0 @@
#!/bin/bash
# Wait for Connect to be ready before exiting
# Time out if we wait for more than 2 minutes, so that we can print logs.
let "counter=0"
while [ ! -f $BROWSER_PROVIDER_READY_FILE ]; do
let "counter++"
if [ $counter -gt 240 ]; then
echo "Timed out after 2 minutes waiting for browser provider ready file"
# We must manually print logs here because travis will not run
# after_script commands if the failure occurs before the script
# phase.
./scripts/travis/print_logs.sh
exit 5
fi
sleep .5
done
+1
View File
@@ -100,6 +100,7 @@
"VALIDITY_STATE_PROPERTY": false,
"reloadWithDebugInfo": false,
"stringify": false,
"UNSAFE_restoreLegacyJqLiteXHTMLReplacement": false,
"NODE_TYPE_ELEMENT": false,
"NODE_TYPE_ATTRIBUTE": false,
+28 -5
View File
@@ -93,6 +93,7 @@
hasOwnProperty,
createMap,
stringify,
UNSAFE_restoreLegacyJqLiteXHTMLReplacement,
NODE_TYPE_ELEMENT,
NODE_TYPE_ATTRIBUTE,
@@ -342,8 +343,10 @@ function baseExtend(dst, objs, deep) {
} else if (isElement(src)) {
dst[key] = src.clone();
} else {
if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
baseExtend(dst[key], [src], true);
if (key !== '__proto__') {
if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
baseExtend(dst[key], [src], true);
}
}
} else {
dst[key] = src;
@@ -818,8 +821,8 @@ function arrayRemove(array, value) {
* - [`MediaStream`](https://developer.mozilla.org/docs/Web/API/MediaStream)
* - [`Set`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Set)
* - [`WeakMap`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)
* - ['getter'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)/
* [`setter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set)`
* - [`getter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)/
* [`setter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set)
*
* @param {*} source The source that will be used to make a copy. Can be any type, including
* primitives, `null`, and `undefined`.
@@ -1529,7 +1532,7 @@ function allowAutoBootstrap(document) {
link.href = src.value;
if (document.location.origin === link.origin) {
// Same-origin resources are always allowed, even for non-whitelisted schemes.
// Same-origin resources are always allowed, even for banned URL schemes.
return true;
}
// Disabled bootstrapping unless angular.js was loaded from a known scheme used on the web.
@@ -1947,6 +1950,26 @@ function bindJQuery() {
bindJQueryFired = true;
}
/**
* @ngdoc function
* @name angular.UNSAFE_restoreLegacyJqLiteXHTMLReplacement
* @module ng
* @kind function
*
* @description
* Restores the pre-1.8 behavior of jqLite that turns XHTML-like strings like
* `<div /><span />` to `<div></div><span></span>` instead of `<div><span></span></div>`.
* The new behavior is a security fix. Thus, if you need to call this function, please try to adjust
* your code for this change and remove your use of this function as soon as possible.
* Note that this only patches jqLite. If you use jQuery 3.5.0 or newer, please read the
* [jQuery 3.5 upgrade guide](https://jquery.com/upgrade-guide/3.5/) for more details
* about the workarounds.
*/
function UNSAFE_restoreLegacyJqLiteXHTMLReplacement() {
JQLite.legacyXHTMLReplacement = true;
}
/**
* throw error if the argument is falsy.
*/
+1
View File
@@ -156,6 +156,7 @@ function publishExternalAPI(angular) {
'callbacks': {$$counter: 0},
'getTestability': getTestability,
'reloadWithDebugInfo': reloadWithDebugInfo,
'UNSAFE_restoreLegacyJqLiteXHTMLReplacement': UNSAFE_restoreLegacyJqLiteXHTMLReplacement,
'$$minErr': minErr,
'$$csp': csp,
'$$encodeUriSegment': encodeUriSegment,
+1 -1
View File
@@ -1,6 +1,6 @@
/**
* @license AngularJS v"NG_VERSION_FULL"
* (c) 2010-2018 Google, Inc. http://angularjs.org
* (c) 2010-2020 Google LLC. http://angularjs.org
* License: MIT
*/
(function(window) {
+58 -15
View File
@@ -90,6 +90,16 @@
* - [`val()`](http://api.jquery.com/val/)
* - [`wrap()`](http://api.jquery.com/wrap/)
*
* jqLite also provides a method restoring pre-1.8 insecure treatment of XHTML-like tags.
* This legacy behavior turns input like `<div /><span />` to `<div></div><span></span>`
* instead of `<div><span></span></div>` like version 1.8 & newer do. To restore it, invoke:
* ```js
* angular.UNSAFE_restoreLegacyJqLiteXHTMLReplacement();
* ```
* Note that this only patches jqLite. If you use jQuery 3.5.0 or newer, please read the
* [jQuery 3.5 upgrade guide](https://jquery.com/upgrade-guide/3.5/) for more details
* about the workarounds.
*
* ## jQuery/jqLite Extras
* AngularJS also provides the following additional methods and events to both jQuery and jqLite:
*
@@ -169,20 +179,36 @@ var HTML_REGEXP = /<|&#?\w+;/;
var TAG_NAME_REGEXP = /<([\w:-]+)/;
var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi;
// Table parts need to be wrapped with `<table>` or they're
// stripped to their contents when put in a div.
// XHTML parsers do not magically insert elements in the
// same way that tag soup parsers do, so we cannot shorten
// this by omitting <tbody> or other required elements.
var wrapMap = {
'option': [1, '<select multiple="multiple">', '</select>'],
'thead': [1, '<table>', '</table>'],
'col': [2, '<table><colgroup>', '</colgroup></table>'],
'tr': [2, '<table><tbody>', '</tbody></table>'],
'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
'_default': [0, '', '']
thead: ['table'],
col: ['colgroup', 'table'],
tr: ['tbody', 'table'],
td: ['tr', 'tbody', 'table']
};
wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;
// Support: IE <10 only
// IE 9 requires an option wrapper & it needs to have the whole table structure
// set up in advance; assigning `"<td></td>"` to `tr.innerHTML` doesn't work, etc.
var wrapMapIE9 = {
option: [1, '<select multiple="multiple">', '</select>'],
_default: [0, '', '']
};
for (var key in wrapMap) {
var wrapMapValueClosing = wrapMap[key];
var wrapMapValue = wrapMapValueClosing.slice().reverse();
wrapMapIE9[key] = [wrapMapValue.length, '<' + wrapMapValue.join('><') + '>', '</' + wrapMapValueClosing.join('></') + '>'];
}
wrapMapIE9.optgroup = wrapMapIE9.option;
function jqLiteIsTextNode(html) {
return !HTML_REGEXP.test(html);
@@ -203,7 +229,7 @@ function jqLiteHasData(node) {
}
function jqLiteBuildFragment(html, context) {
var tmp, tag, wrap,
var tmp, tag, wrap, finalHtml,
fragment = context.createDocumentFragment(),
nodes = [], i;
@@ -214,13 +240,30 @@ function jqLiteBuildFragment(html, context) {
// Convert html into DOM nodes
tmp = fragment.appendChild(context.createElement('div'));
tag = (TAG_NAME_REGEXP.exec(html) || ['', ''])[1].toLowerCase();
wrap = wrapMap[tag] || wrapMap._default;
tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, '<$1></$2>') + wrap[2];
finalHtml = JQLite.legacyXHTMLReplacement ?
html.replace(XHTML_TAG_REGEXP, '<$1></$2>') :
html;
// Descend through wrappers to the right content
i = wrap[0];
while (i--) {
tmp = tmp.lastChild;
if (msie < 10) {
wrap = wrapMapIE9[tag] || wrapMapIE9._default;
tmp.innerHTML = wrap[1] + finalHtml + wrap[2];
// Descend through wrappers to the right content
i = wrap[0];
while (i--) {
tmp = tmp.firstChild;
}
} else {
wrap = wrapMap[tag] || [];
// Create wrappers & descend into them
i = wrap.length;
while (--i > -1) {
tmp.appendChild(window.document.createElement(wrap[i]));
tmp = tmp.firstChild;
}
tmp.innerHTML = finalHtml;
}
nodes = concat(nodes, tmp.childNodes);
+1 -1
View File
@@ -1,6 +1,6 @@
/**
* @license AngularJS v"NG_VERSION_FULL"
* (c) 2010-2018 Google, Inc. http://angularjs.org
* (c) 2010-2020 Google LLC. http://angularjs.org
* License: MIT
*/
'use strict';
+2 -2
View File
@@ -32,7 +32,7 @@ var minErrConfig = {
* non-positive or non-numeric value, removes the max depth limit.
* Default: 5
*
* * `urlErrorParamsEnabled` **{Boolean}** - Specifies wether the generated error url will
* * `urlErrorParamsEnabled` **{Boolean}** - Specifies whether the generated error url will
* contain the parameters of the thrown error. Disabling the parameters can be useful if the
* generated error url is very long.
*
@@ -82,7 +82,7 @@ function isValidObjectMaxDepth(maxDepth) {
* Since data will be parsed statically during a build step, some restrictions
* are applied with respect to how minErr instances are created and called.
* Instances should have names of the form namespaceMinErr for a minErr created
* using minErr('namespace') . Error codes, namespaces and template strings
* using minErr('namespace'). Error codes, namespaces and template strings
* should all be static strings, not variables or general expressions.
*
* @param {string} module The namespace to use for the new minErr instance.
+1 -1
View File
@@ -1,6 +1,6 @@
/**
* @license AngularJS v"NG_VERSION_FULL"
* (c) 2010-2018 Google, Inc. http://angularjs.org
* (c) 2010-2020 Google LLC. http://angularjs.org
* License: MIT
*/
(function(window, angular) {
+73 -31
View File
@@ -1026,7 +1026,7 @@
*
* When the original node and the replace template declare the same directive(s), they will be
* {@link guide/compiler#double-compilation-and-how-to-avoid-it compiled twice} because the compiler
* does not deduplicate them. In many cases, this is not noticable, but e.g. {@link ngModel} will
* does not deduplicate them. In many cases, this is not noticeable, but e.g. {@link ngModel} will
* attach `$formatters` and `$parsers` twice.
*
* See issue [#2573](https://github.com/angular/angular.js/issues/2573).
@@ -1106,8 +1106,8 @@
*
* Based on the context, other options may exist to mark a value as trusted / configure the behavior
* of {@link ng.$sce}. For example, to restrict the `RESOURCE_URL` context to specific origins, use
* the {@link $sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist()}
* and {@link $sceDelegateProvider#resourceUrlBlacklist resourceUrlBlacklist()}.
* the {@link $sceDelegateProvider#trustedResourceUrlList trustedResourceUrlList()}
* and {@link $sceDelegateProvider#bannedResourceUrlList bannedResourceUrlList()}.
*
* {@link ng.$sce#what-trusted-context-types-are-supported- Find out more about the different context types}.
*
@@ -1116,7 +1116,7 @@
* By default, `$sce` will throw an error if it detects untrusted HTML content, and will not bind the
* content.
* However, if you include the {@link ngSanitize ngSanitize module}, it will try to sanitize the
* potentially dangerous HTML, e.g. strip non-whitelisted tags and attributes when binding to
* potentially dangerous HTML, e.g. strip non-trusted tags and attributes when binding to
* `innerHTML`.
*
* @example
@@ -1698,30 +1698,81 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
/**
* @ngdoc method
* @name $compileProvider#aHrefSanitizationWhitelist
* @name $compileProvider#aHrefSanitizationTrustedUrlList
* @kind function
*
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* Retrieves or overrides the default regular expression that is used for determining trusted safe
* urls during a[href] sanitization.
*
* The sanitization is a security measure aimed at preventing XSS attacks via html links.
*
* Any url about to be assigned to a[href] via data-binding is first normalized and turned into
* an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
* an absolute url. Afterwards, the url is matched against the `aHrefSanitizationTrustedUrlList`
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @param {RegExp=} regexp New regexp to trust urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.aHrefSanitizationWhitelist = function(regexp) {
this.aHrefSanitizationTrustedUrlList = function(regexp) {
if (isDefined(regexp)) {
$$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);
$$sanitizeUriProvider.aHrefSanitizationTrustedUrlList(regexp);
return this;
} else {
return $$sanitizeUriProvider.aHrefSanitizationWhitelist();
return $$sanitizeUriProvider.aHrefSanitizationTrustedUrlList();
}
};
/**
* @ngdoc method
* @name $compileProvider#aHrefSanitizationWhitelist
* @kind function
*
* @deprecated
* sinceVersion="1.8.1"
*
* This method is deprecated. Use {@link $compileProvider#aHrefSanitizationTrustedUrlList
* aHrefSanitizationTrustedUrlList} instead.
*/
Object.defineProperty(this, 'aHrefSanitizationWhitelist', {
get: function() {
return this.aHrefSanitizationTrustedUrlList;
},
set: function(value) {
this.aHrefSanitizationTrustedUrlList = value;
}
});
/**
* @ngdoc method
* @name $compileProvider#imgSrcSanitizationTrustedUrlList
* @kind function
*
* @description
* Retrieves or overrides the default regular expression that is used for determining trusted safe
* urls during img[src] sanitization.
*
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
*
* Any url about to be assigned to img[src] via data-binding is first normalized and turned into
* an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationTrustedUrlList`
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
*
* @param {RegExp=} regexp New regexp to trust urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.imgSrcSanitizationTrustedUrlList = function(regexp) {
if (isDefined(regexp)) {
$$sanitizeUriProvider.imgSrcSanitizationTrustedUrlList(regexp);
return this;
} else {
return $$sanitizeUriProvider.imgSrcSanitizationTrustedUrlList();
}
};
@@ -1731,29 +1782,20 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
* @name $compileProvider#imgSrcSanitizationWhitelist
* @kind function
*
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* urls during img[src] sanitization.
* @deprecated
* sinceVersion="1.8.1"
*
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
*
* Any url about to be assigned to img[src] via data-binding is first normalized and turned into
* an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
* This method is deprecated. Use {@link $compileProvider#imgSrcSanitizationTrustedUrlList
* imgSrcSanitizationTrustedUrlList} instead.
*/
this.imgSrcSanitizationWhitelist = function(regexp) {
if (isDefined(regexp)) {
$$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);
return this;
} else {
return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();
Object.defineProperty(this, 'imgSrcSanitizationWhitelist', {
get: function() {
return this.imgSrcSanitizationTrustedUrlList;
},
set: function(value) {
this.imgSrcSanitizationTrustedUrlList = value;
}
};
});
/**
* @ngdoc method
+3 -3
View File
@@ -13,9 +13,9 @@
* By default, the template URL is restricted to the same domain and protocol as the
* application document. This is done by calling {@link $sce#getTrustedResourceUrl
* $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols
* you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or
* {@link $sce#trustAsResourceUrl wrap them} as trusted values. Refer to AngularJS's {@link
* ng.$sce Strict Contextual Escaping}.
* you may either add them to your {@link ng.$sceDelegateProvider#trustedResourceUrlList trusted
* resource URL list} or {@link $sce#trustAsResourceUrl wrap them} as trusted values. Refer to
* AngularJS's {@link ng.$sce Strict Contextual Escaping}.
*
* In addition, the browser's
* [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)
+1 -1
View File
@@ -332,7 +332,7 @@
* For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
* the items have been processed through the filter.
*
* Please note that `as [variable name] is not an operator but rather a part of ngRepeat
* Please note that `as [variable name]` is not an operator but rather a part of ngRepeat
* micro-syntax so it can be used only after all filters (and not as operator, inside an expression).
*
* For example: `item in items | filter : x | orderBy : order | limitTo : limit as results track by item.id` .
+3 -3
View File
@@ -42,11 +42,11 @@
var colorSpan = element(by.css('span'));
it('should check ng-style', function() {
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
expect(colorSpan.getCssValue('color')).toMatch(/rgba\(0, 0, 0, 1\)|rgb\(0, 0, 0\)/);
element(by.css('input[value=\'set color\']')).click();
expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
expect(colorSpan.getCssValue('color')).toMatch(/rgba\(255, 0, 0, 1\)|rgb\(255, 0, 0\)/);
element(by.css('input[value=clear]')).click();
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
expect(colorSpan.getCssValue('color')).toMatch(/rgba\(0, 0, 0, 1\)|rgb\(0, 0, 0\)/);
});
</file>
</example>
+34 -14
View File
@@ -388,7 +388,7 @@ function $HttpProvider() {
/**
* @ngdoc property
* @name $httpProvider#xsrfWhitelistedOrigins
* @name $httpProvider#xsrfTrustedOrigins
* @description
*
* Array containing URLs whose origins are trusted to receive the XSRF token. See the
@@ -402,7 +402,7 @@ function $HttpProvider() {
* Examples: `http://example.com`, `https://api.example.com:9876`
*
* <div class="alert alert-warning">
* It is not possible to whitelist specific URLs/paths. The `path`, `query` and `fragment` parts
* It is not possible to trust specific URLs/paths. The `path`, `query` and `fragment` parts
* of a URL will be ignored. For example, `https://foo.com/path/bar?query=baz#fragment` will be
* treated as `https://foo.com`, meaning that **all** requests to URLs starting with
* `https://foo.com/` will include the XSRF token.
@@ -413,9 +413,9 @@ function $HttpProvider() {
* ```js
* // App served from `https://example.com/`.
* angular.
* module('xsrfWhitelistedOriginsExample', []).
* module('xsrfTrustedOriginsExample', []).
* config(['$httpProvider', function($httpProvider) {
* $httpProvider.xsrfWhitelistedOrigins.push('https://api.example.com');
* $httpProvider.xsrfTrustedOrigins.push('https://api.example.com');
* }]).
* run(['$http', function($http) {
* // The XSRF token will be sent.
@@ -426,7 +426,27 @@ function $HttpProvider() {
* }]);
* ```
*/
var xsrfWhitelistedOrigins = this.xsrfWhitelistedOrigins = [];
var xsrfTrustedOrigins = this.xsrfTrustedOrigins = [];
/**
* @ngdoc property
* @name $httpProvider#xsrfWhitelistedOrigins
* @description
*
* @deprecated
* sinceVersion="1.8.1"
*
* This property is deprecated. Use {@link $httpProvider#xsrfTrustedOrigins xsrfTrustedOrigins}
* instead.
*/
Object.defineProperty(this, 'xsrfWhitelistedOrigins', {
get: function() {
return this.xsrfTrustedOrigins;
},
set: function(origins) {
this.xsrfTrustedOrigins = origins;
}
});
this.$get = ['$browser', '$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector', '$sce',
function($browser, $httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector, $sce) {
@@ -454,7 +474,7 @@ function $HttpProvider() {
/**
* A function to check request URLs against a list of allowed origins.
*/
var urlIsAllowedOrigin = urlIsAllowedOriginFactory(xsrfWhitelistedOrigins);
var urlIsAllowedOrigin = urlIsAllowedOriginFactory(xsrfTrustedOrigins);
/**
* @ngdoc service
@@ -828,16 +848,16 @@ function $HttpProvider() {
* The header will &mdash; by default &mdash; **not** be set for cross-domain requests. This
* prevents unauthorized servers (e.g. malicious or compromised 3rd-party APIs) from gaining
* access to your users' XSRF tokens and exposing them to Cross Site Request Forgery. If you
* want to, you can whitelist additional origins to also receive the XSRF token, by adding them
* to {@link ng.$httpProvider#xsrfWhitelistedOrigins xsrfWhitelistedOrigins}. This might be
* want to, you can trust additional origins to also receive the XSRF token, by adding them
* to {@link ng.$httpProvider#xsrfTrustedOrigins xsrfTrustedOrigins}. This might be
* useful, for example, if your application, served from `example.com`, needs to access your API
* at `api.example.com`.
* See {@link ng.$httpProvider#xsrfWhitelistedOrigins $httpProvider.xsrfWhitelistedOrigins} for
* See {@link ng.$httpProvider#xsrfTrustedOrigins $httpProvider.xsrfTrustedOrigins} for
* more details.
*
* <div class="alert alert-danger">
* **Warning**<br />
* Only whitelist origins that you have control over and make sure you understand the
* Only trusted origins that you have control over and make sure you understand the
* implications of doing so.
* </div>
*
@@ -964,8 +984,8 @@ function $HttpProvider() {
<file name="script.js">
angular.module('httpExample', [])
.config(['$sceDelegateProvider', function($sceDelegateProvider) {
// We must whitelist the JSONP endpoint that we are using to show that we trust it
$sceDelegateProvider.resourceUrlWhitelist([
// We must add the JSONP endpoint that we are using to the trusted list to show that we trust it
$sceDelegateProvider.trustedResourceUrlList([
'self',
'https://angularjs.org/**'
]);
@@ -1222,8 +1242,8 @@ function $HttpProvider() {
*
* Note that, since JSONP requests are sensitive because the response is given full access to the browser,
* the url must be declared, via {@link $sce} as a trusted resource URL.
* You can trust a URL by adding it to the whitelist via
* {@link $sceDelegateProvider#resourceUrlWhitelist `$sceDelegateProvider.resourceUrlWhitelist`} or
* You can trust a URL by adding it to the trusted resource URL list via
* {@link $sceDelegateProvider#trustedResourceUrlList `$sceDelegateProvider.trustedResourceUrlList`} or
* by explicitly trusting the URL via {@link $sce#trustAsResourceUrl `$sce.trustAsResourceUrl(url)`}.
*
* You should avoid generating the URL for the JSONP request from user provided data.
+2 -2
View File
@@ -1900,7 +1900,7 @@ function $ParseProvider() {
var useInputs = parsedExpression.inputs && !exp.inputs;
// Propogate the literal/inputs/constant attributes
// Propagate the literal/inputs/constant attributes
// ... but not oneTime since we are handling it
oneTimeWatch.literal = parsedExpression.literal;
oneTimeWatch.constant = parsedExpression.constant;
@@ -1987,7 +1987,7 @@ function $ParseProvider() {
fn.$$intercepted = parsedExpression;
fn.$$interceptor = interceptorFn;
// Propogate the literal/oneTime/constant attributes
// Propagate the literal/oneTime/constant attributes
fn.literal = parsedExpression.literal;
fn.oneTime = parsedExpression.oneTime;
fn.constant = parsedExpression.constant;
+16 -15
View File
@@ -7,12 +7,12 @@
*/
function $$SanitizeUriProvider() {
var aHrefSanitizationWhitelist = /^\s*(https?|s?ftp|mailto|tel|file):/,
imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file|blob):|data:image\/)/;
var aHrefSanitizationTrustedUrlList = /^\s*(https?|s?ftp|mailto|tel|file):/,
imgSrcSanitizationTrustedUrlList = /^\s*((https?|ftp|file|blob):|data:image\/)/;
/**
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* Retrieves or overrides the default regular expression that is used for determining trusted safe
* urls during a[href] sanitization.
*
* The sanitization is a security measure aimed at prevent XSS attacks via HTML anchor links.
@@ -21,27 +21,27 @@ function $$SanitizeUriProvider() {
* the $sce.URL security context. When interpolation occurs a call is made to `$sce.trustAsUrl(url)`
* which in turn may call `$$sanitizeUri(url, isMedia)` to sanitize the potentially malicious URL.
*
* If the URL matches the `aHrefSanitizationWhitelist` regular expression, it is returned unchanged.
* If the URL matches the `aHrefSanitizationTrustedUrlList` regular expression, it is returned unchanged.
*
* If there is no match the URL is returned prefixed with `'unsafe:'` to ensure that when it is written
* to the DOM it is inactive and potentially malicious code will not be executed.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @param {RegExp=} regexp New regexp to trust urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.aHrefSanitizationWhitelist = function(regexp) {
this.aHrefSanitizationTrustedUrlList = function(regexp) {
if (isDefined(regexp)) {
aHrefSanitizationWhitelist = regexp;
aHrefSanitizationTrustedUrlList = regexp;
return this;
}
return aHrefSanitizationWhitelist;
return aHrefSanitizationTrustedUrlList;
};
/**
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* Retrieves or overrides the default regular expression that is used for determining trusted safe
* urls during img[src] sanitization.
*
* The sanitization is a security measure aimed at prevent XSS attacks via HTML image src links.
@@ -51,27 +51,28 @@ function $$SanitizeUriProvider() {
* `$sce.trustAsMediaUrl(url)` which in turn may call `$$sanitizeUri(url, isMedia)` to sanitize
* the potentially malicious URL.
*
* If the URL matches the `aImgSanitizationWhitelist` regular expression, it is returned unchanged.
* If the URL matches the `imgSrcSanitizationTrustedUrlList` regular expression, it is returned
* unchanged.
*
* If there is no match the URL is returned prefixed with `'unsafe:'` to ensure that when it is written
* to the DOM it is inactive and potentially malicious code will not be executed.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @param {RegExp=} regexp New regexp to trust urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.imgSrcSanitizationWhitelist = function(regexp) {
this.imgSrcSanitizationTrustedUrlList = function(regexp) {
if (isDefined(regexp)) {
imgSrcSanitizationWhitelist = regexp;
imgSrcSanitizationTrustedUrlList = regexp;
return this;
}
return imgSrcSanitizationWhitelist;
return imgSrcSanitizationTrustedUrlList;
};
this.$get = function() {
return function sanitizeUri(uri, isMediaUrl) {
// if (!uri) return uri;
var regex = isMediaUrl ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
var regex = isMediaUrl ? imgSrcSanitizationTrustedUrlList : aHrefSanitizationTrustedUrlList;
var normalizedVal = urlResolve(uri && uri.trim()).href;
if (normalizedVal !== '' && !normalizedVal.match(regex)) {
return 'unsafe:' + normalizedVal;
+118 -77
View File
@@ -118,10 +118,10 @@ function adjustMatchers(matchers) {
* The default instance of `$sceDelegate` should work out of the box with little pain. While you
* can override it completely to change the behavior of `$sce`, the common case would
* involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting
* your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as
* templates. Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist
* $sceDelegateProvider.resourceUrlWhitelist} and {@link
* ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
* your own trusted and banned resource lists for trusting URLs used for loading AngularJS resources
* such as templates. Refer {@link ng.$sceDelegateProvider#trustedResourceUrlList
* $sceDelegateProvider.trustedResourceUrlList} and {@link
* ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList}
*/
/**
@@ -134,12 +134,12 @@ function adjustMatchers(matchers) {
* The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
* $sceDelegate service}, used as a delegate for {@link ng.$sce Strict Contextual Escaping (SCE)}.
*
* The `$sceDelegateProvider` allows one to get/set the whitelists and blacklists used to ensure
* that the URLs used for sourcing AngularJS templates and other script-running URLs are safe (all
* places that use the `$sce.RESOURCE_URL` context). See
* {@link ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist}
* and
* {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist},
* The `$sceDelegateProvider` allows one to get/set the `trustedResourceUrlList` and
* `bannedResourceUrlList` used to ensure that the URLs used for sourcing AngularJS templates and
* other script-running URLs are safe (all places that use the `$sce.RESOURCE_URL` context). See
* {@link ng.$sceDelegateProvider#trustedResourceUrlList
* $sceDelegateProvider.trustedResourceUrlList} and
* {@link ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList},
*
* For the general details about this service in AngularJS, read the main page for {@link ng.$sce
* Strict Contextual Escaping (SCE)}.
@@ -155,64 +155,117 @@ function adjustMatchers(matchers) {
*
* ```
* angular.module('myApp', []).config(function($sceDelegateProvider) {
* $sceDelegateProvider.resourceUrlWhitelist([
* $sceDelegateProvider.trustedResourceUrlList([
* // Allow same origin resource loads.
* 'self',
* // Allow loading from our assets domain. Notice the difference between * and **.
* 'http://srv*.assets.example.com/**'
* ]);
*
* // The blacklist overrides the whitelist so the open redirect here is blocked.
* $sceDelegateProvider.resourceUrlBlacklist([
* // The banned resource URL list overrides the trusted resource URL list so the open redirect
* // here is blocked.
* $sceDelegateProvider.bannedResourceUrlList([
* 'http://myapp.example.com/clickThru**'
* ]);
* });
* ```
* Note that an empty whitelist will block every resource URL from being loaded, and will require
* Note that an empty trusted resource URL list will block every resource URL from being loaded, and will require
* you to manually mark each one as trusted with `$sce.trustAsResourceUrl`. However, templates
* requested by {@link ng.$templateRequest $templateRequest} that are present in
* {@link ng.$templateCache $templateCache} will not go through this check. If you have a mechanism
* to populate your templates in that cache at config time, then it is a good idea to remove 'self'
* from that whitelist. This helps to mitigate the security impact of certain types of issues, like
* for instance attacker-controlled `ng-includes`.
* from the trusted resource URL lsit. This helps to mitigate the security impact of certain types
* of issues, like for instance attacker-controlled `ng-includes`.
*/
function $SceDelegateProvider() {
this.SCE_CONTEXTS = SCE_CONTEXTS;
// Resource URLs can also be trusted by policy.
var resourceUrlWhitelist = ['self'],
resourceUrlBlacklist = [];
var trustedResourceUrlList = ['self'],
bannedResourceUrlList = [];
/**
* @ngdoc method
* @name $sceDelegateProvider#trustedResourceUrlList
* @kind function
*
* @param {Array=} trustedResourceUrlList When provided, replaces the trustedResourceUrlList with
* the value provided. This must be an array or null. A snapshot of this array is used so
* further changes to the array are ignored.
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
* allowed in this array.
*
* @return {Array} The currently set trusted resource URL array.
*
* @description
* Sets/Gets the list trusted of resource URLs.
*
* The **default value** when no `trustedResourceUrlList` has been explicitly set is `['self']`
* allowing only same origin resource requests.
*
* <div class="alert alert-warning">
* **Note:** the default `trustedResourceUrlList` of 'self' is not recommended if your app shares
* its origin with other apps! It is a good idea to limit it to only your application's directory.
* </div>
*/
this.trustedResourceUrlList = function(value) {
if (arguments.length) {
trustedResourceUrlList = adjustMatchers(value);
}
return trustedResourceUrlList;
};
/**
* @ngdoc method
* @name $sceDelegateProvider#resourceUrlWhitelist
* @kind function
*
* @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
* provided. This must be an array or null. A snapshot of this array is used so further
* changes to the array are ignored.
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
* allowed in this array.
* @deprecated
* sinceVersion="1.8.1"
*
* @return {Array} The currently set whitelist array.
* This method is deprecated. Use {@link $sceDelegateProvider#trustedResourceUrlList
* trustedResourceUrlList} instead.
*/
Object.defineProperty(this, 'resourceUrlWhitelist', {
get: function() {
return this.trustedResourceUrlList;
},
set: function(value) {
this.trustedResourceUrlList = value;
}
});
/**
* @ngdoc method
* @name $sceDelegateProvider#bannedResourceUrlList
* @kind function
*
* @param {Array=} bannedResourceUrlList When provided, replaces the `bannedResourceUrlList` with
* the value provided. This must be an array or null. A snapshot of this array is used so
* further changes to the array are ignored.</p><p>
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
* allowed in this array.</p><p>
* The typical usage for the `bannedResourceUrlList` is to **block
* [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
* these would otherwise be trusted but actually return content from the redirected domain.
* </p><p>
* Finally, **the banned resource URL list overrides the trusted resource URL list** and has
* the final say.
*
* @return {Array} The currently set `bannedResourceUrlList` array.
*
* @description
* Sets/Gets the whitelist of trusted resource URLs.
* Sets/Gets the `bannedResourceUrlList` of trusted resource URLs.
*
* The **default value** when no whitelist has been explicitly set is `['self']` allowing only
* same origin resource requests.
*
* <div class="alert alert-warning">
* **Note:** the default whitelist of 'self' is not recommended if your app shares its origin
* with other apps! It is a good idea to limit it to only your application's directory.
* </div>
* The **default value** when no trusted resource URL list has been explicitly set is the empty
* array (i.e. there is no `bannedResourceUrlList`.)
*/
this.resourceUrlWhitelist = function(value) {
this.bannedResourceUrlList = function(value) {
if (arguments.length) {
resourceUrlWhitelist = adjustMatchers(value);
bannedResourceUrlList = adjustMatchers(value);
}
return resourceUrlWhitelist;
return bannedResourceUrlList;
};
/**
@@ -220,32 +273,20 @@ function $SceDelegateProvider() {
* @name $sceDelegateProvider#resourceUrlBlacklist
* @kind function
*
* @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
* provided. This must be an array or null. A snapshot of this array is used so further
* changes to the array are ignored.</p><p>
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
* allowed in this array.</p><p>
* The typical usage for the blacklist is to **block
* [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
* these would otherwise be trusted but actually return content from the redirected domain.
* </p><p>
* Finally, **the blacklist overrides the whitelist** and has the final say.
* @deprecated
* sinceVersion="1.8.1"
*
* @return {Array} The currently set blacklist array.
*
* @description
* Sets/Gets the blacklist of trusted resource URLs.
*
* The **default value** when no whitelist has been explicitly set is the empty array (i.e. there
* is no blacklist.)
* This method is deprecated. Use {@link $sceDelegateProvider#bannedResourceUrlList
* bannedResourceUrlList} instead.
*/
this.resourceUrlBlacklist = function(value) {
if (arguments.length) {
resourceUrlBlacklist = adjustMatchers(value);
Object.defineProperty(this, 'resourceUrlBlacklist', {
get: function() {
return this.bannedResourceUrlList;
},
set: function(value) {
this.bannedResourceUrlList = value;
}
return resourceUrlBlacklist;
};
});
this.$get = ['$injector', '$$sanitizeUri', function($injector, $$sanitizeUri) {
@@ -270,17 +311,17 @@ function $SceDelegateProvider() {
function isResourceUrlAllowedByPolicy(url) {
var parsedUrl = urlResolve(url.toString());
var i, n, allowed = false;
// Ensure that at least one item from the whitelist allows this url.
for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {
if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {
// Ensure that at least one item from the trusted resource URL list allows this url.
for (i = 0, n = trustedResourceUrlList.length; i < n; i++) {
if (matchUrl(trustedResourceUrlList[i], parsedUrl)) {
allowed = true;
break;
}
}
if (allowed) {
// Ensure that no item from the blacklist blocked this url.
for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {
if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {
// Ensure that no item from the banned resource URL list has blocked this url.
for (i = 0, n = bannedResourceUrlList.length; i < n; i++) {
if (matchUrl(bannedResourceUrlList[i], parsedUrl)) {
allowed = false;
break;
}
@@ -401,9 +442,9 @@ function $SceDelegateProvider() {
* The contexts that can be sanitized are $sce.MEDIA_URL, $sce.URL and $sce.HTML. The first two are available
* by default, and the third one relies on the `$sanitize` service (which may be loaded through
* the `ngSanitize` module). Furthermore, for $sce.RESOURCE_URL context, a plain string may be
* accepted if the resource url policy defined by {@link ng.$sceDelegateProvider#resourceUrlWhitelist
* `$sceDelegateProvider.resourceUrlWhitelist`} and {@link ng.$sceDelegateProvider#resourceUrlBlacklist
* `$sceDelegateProvider.resourceUrlBlacklist`} accepts that resource.
* accepted if the resource url policy defined by {@link ng.$sceDelegateProvider#trustedResourceUrlList
* `$sceDelegateProvider.trustedResourceUrlList`} and {@link ng.$sceDelegateProvider#bannedResourceUrlList
* `$sceDelegateProvider.bannedResourceUrlList`} accepts that resource.
*
* This function will throw if the safe type isn't appropriate for this context, or if the
* value given cannot be accepted in the context (which might be caused by sanitization not
@@ -497,9 +538,9 @@ function $SceDelegateProvider() {
*
* To systematically block XSS security bugs, AngularJS treats all values as untrusted by default in
* HTML or sensitive URL bindings. When binding untrusted values, AngularJS will automatically
* run security checks on them (sanitizations, whitelists, depending on context), or throw when it
* cannot guarantee the security of the result. That behavior depends strongly on contexts: HTML
* can be sanitized, but template URLs cannot, for instance.
* run security checks on them (sanitizations, trusted URL resource, depending on context), or throw
* when it cannot guarantee the security of the result. That behavior depends strongly on contexts:
* HTML can be sanitized, but template URLs cannot, for instance.
*
* To illustrate this, consider the `ng-bind-html` directive. It renders its value directly as HTML:
* we call that the *context*. When given an untrusted input, AngularJS will attempt to sanitize it
@@ -578,8 +619,8 @@ function $SceDelegateProvider() {
* By default, AngularJS only loads templates from the same domain and protocol as the application
* document. This is done by calling {@link ng.$sce#getTrustedResourceUrl
* $sce.getTrustedResourceUrl} on the template URL. To load templates from other domains and/or
* protocols, you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist
* them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value.
* protocols, you may either add them to the {@link ng.$sceDelegateProvider#trustedResourceUrlList
* trustedResourceUrlList} or {@link ng.$sce#trustAsResourceUrl wrap them} into trusted values.
*
* *Please note*:
* The browser's
@@ -607,8 +648,8 @@ function $SceDelegateProvider() {
* templates in `ng-include` from your application's domain without having to even know about SCE.
* It blocks loading templates from other domains or loading templates over http from an https
* served document. You can change these by setting your own custom {@link
* ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link
* ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs.
* ng.$sceDelegateProvider#trustedResourceUrlList trusted resource URL list} and {@link
* ng.$sceDelegateProvider#bannedResourceUrlList banned resource URL list} for matching such URLs.
*
* This significantly reduces the overhead. It is far easier to pay the small overhead and have an
* application that's secure and can be audited to verify that with much more ease than bolting
@@ -623,7 +664,7 @@ function $SceDelegateProvider() {
* | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. |
* | `$sce.MEDIA_URL` | For URLs that are safe to render as media. Is automatically converted from string by sanitizing when needed. |
* | `$sce.URL` | For URLs that are safe to follow as links. Is automatically converted from string by sanitizing when needed. Note that `$sce.URL` makes a stronger statement about the URL than `$sce.MEDIA_URL` does and therefore contexts requiring values trusted for `$sce.URL` can be used anywhere that values trusted for `$sce.MEDIA_URL` are required.|
* | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` or `$sce.MEDIA_URL` do and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` or `$sce.MEDIA_URL` are required. <br><br> The {@link $sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider#resourceUrlWhitelist()} and {@link $sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider#resourceUrlBlacklist()} can be used to restrict trusted origins for `RESOURCE_URL` |
* | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` or `$sce.MEDIA_URL` do and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` or `$sce.MEDIA_URL` are required. <br><br> The {@link $sceDelegateProvider#trustedResourceUrlList $sceDelegateProvider#trustedResourceUrlList()} and {@link $sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider#bannedResourceUrlList()} can be used to restrict trusted origins for `RESOURCE_URL` |
* | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently unused. Feel free to use it in your own directives. |
*
*
@@ -641,7 +682,7 @@ function $SceDelegateProvider() {
* There are no CSS or JS context bindings in AngularJS currently, so their corresponding `$sce.trustAs`
* functions aren't useful yet. This might evolve.
*
* ### Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist} <a name="resourceUrlPatternItem"></a>
* ### Format of items in {@link ng.$sceDelegateProvider#trustedResourceUrlList trustedResourceUrlList}/{@link ng.$sceDelegateProvider#bannedResourceUrlList bannedResourceUrlList} <a name="resourceUrlPatternItem"></a>
*
* Each element in these arrays must be one of the following:
*
@@ -655,7 +696,7 @@ function $SceDelegateProvider() {
* match themselves.
* - `*`: matches zero or more occurrences of any character other than one of the following 6
* characters: '`:`', '`/`', '`.`', '`?`', '`&`' and '`;`'. It's a useful wildcard for use
* in a whitelist.
* for matching resource URL lists.
* - `**`: matches zero or more occurrences of *any* character. As such, it's not
* appropriate for use in a scheme, domain, etc. as it would match too much. (e.g.
* http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might
+4 -4
View File
@@ -73,10 +73,10 @@ function $TemplateRequestProvider() {
handleRequestFn.totalPendingRequests++;
// We consider the template cache holds only trusted templates, so
// there's no need to go through whitelisting again for keys that already
// are included in there. This also makes AngularJS accept any script
// directive, no matter its name. However, we still need to unwrap trusted
// types.
// there's no need to go through adding the template again to the trusted
// resources for keys that already are included in there. This also makes
// AngularJS accept any script directive, no matter its name. However, we
// still need to unwrap trusted types.
if (!isString(tpl) || isUndefined($templateCache.get(tpl))) {
tpl = $sce.getTrustedResourceUrl(tpl);
}
+5 -5
View File
@@ -125,20 +125,20 @@ function urlIsSameOriginAsBaseUrl(requestUrl) {
}
/**
* Create a function that can check a URL's origin against a list of allowed/whitelisted origins.
* Create a function that can check a URL's origin against a list of allowed/trusted origins.
* The current location's origin is implicitly trusted.
*
* @param {string[]} whitelistedOriginUrls - A list of URLs (strings), whose origins are trusted.
* @param {string[]} trustedOriginUrls - A list of URLs (strings), whose origins are trusted.
*
* @returns {Function} - A function that receives a URL (string or parsed URL object) and returns
* whether it is of an allowed origin.
*/
function urlIsAllowedOriginFactory(whitelistedOriginUrls) {
var parsedAllowedOriginUrls = [originUrl].concat(whitelistedOriginUrls.map(urlResolve));
function urlIsAllowedOriginFactory(trustedOriginUrls) {
var parsedAllowedOriginUrls = [originUrl].concat(trustedOriginUrls.map(urlResolve));
/**
* Check whether the specified URL (string or parsed URL object) has an origin that is allowed
* based on a list of whitelisted-origin URLs. The current location's origin is implicitly
* based on a list of trusted-origin URLs. The current location's origin is implicitly
* trusted.
*
* @param {string|Object} requestUrl - The URL to be checked (provided as a string that will be
+16 -17
View File
@@ -64,7 +64,7 @@ var ngAriaModule = angular.module('ngAria', ['ng']).
/**
* Internal Utilities
*/
var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS', 'SUMMARY'];
var nativeAriaNodeNames = ['BUTTON', 'A', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS', 'SUMMARY'];
var isNodeOneOf = function(elem, nodeTypeArray) {
if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
@@ -136,12 +136,12 @@ function $AriaProvider() {
config = angular.extend(config, newConfig);
};
function watchExpr(attrName, ariaAttr, nodeBlackList, negate) {
function watchExpr(attrName, ariaAttr, nativeAriaNodeNames, negate) {
return function(scope, elem, attr) {
if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
var ariaCamelName = attr.$normalize(ariaAttr);
if (config[ariaCamelName] && !isNodeOneOf(elem, nodeBlackList) && !attr[ariaCamelName]) {
if (config[ariaCamelName] && !isNodeOneOf(elem, nativeAriaNodeNames) && !attr[ariaCamelName]) {
scope.$watch(attr[attrName], function(boolVal) {
// ensure boolean value
boolVal = negate ? !boolVal : !!boolVal;
@@ -155,7 +155,6 @@ function $AriaProvider() {
* @name $aria
*
* @description
* @priority 200
*
* The $aria service contains helper methods for applying common
* [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives.
@@ -166,7 +165,7 @@ function $AriaProvider() {
*
*```js
* ngAriaModule.directive('ngDisabled', ['$aria', function($aria) {
* return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nodeBlackList, false);
* return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nativeAriaNodeNames, false);
* }])
*```
* Shown above, the ngAria module creates a directive with the same signature as the
@@ -218,31 +217,31 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
return $aria.$$watchExpr('ngHide', 'aria-hidden', [], false);
}])
.directive('ngValue', ['$aria', function($aria) {
return $aria.$$watchExpr('ngValue', 'aria-checked', nodeBlackList, false);
return $aria.$$watchExpr('ngValue', 'aria-checked', nativeAriaNodeNames, false);
}])
.directive('ngChecked', ['$aria', function($aria) {
return $aria.$$watchExpr('ngChecked', 'aria-checked', nodeBlackList, false);
return $aria.$$watchExpr('ngChecked', 'aria-checked', nativeAriaNodeNames, false);
}])
.directive('ngReadonly', ['$aria', function($aria) {
return $aria.$$watchExpr('ngReadonly', 'aria-readonly', nodeBlackList, false);
return $aria.$$watchExpr('ngReadonly', 'aria-readonly', nativeAriaNodeNames, false);
}])
.directive('ngRequired', ['$aria', function($aria) {
return $aria.$$watchExpr('ngRequired', 'aria-required', nodeBlackList, false);
return $aria.$$watchExpr('ngRequired', 'aria-required', nativeAriaNodeNames, false);
}])
.directive('ngModel', ['$aria', function($aria) {
function shouldAttachAttr(attr, normalizedAttr, elem, allowBlacklistEls) {
function shouldAttachAttr(attr, normalizedAttr, elem, allowNonAriaNodes) {
return $aria.config(normalizedAttr) &&
!elem.attr(attr) &&
(allowBlacklistEls || !isNodeOneOf(elem, nodeBlackList)) &&
(allowNonAriaNodes || !isNodeOneOf(elem, nativeAriaNodeNames)) &&
(elem.attr('type') !== 'hidden' || elem[0].nodeName !== 'INPUT');
}
function shouldAttachRole(role, elem) {
// if element does not have role attribute
// AND element type is equal to role (if custom element has a type equaling shape) <-- remove?
// AND element is not in nodeBlackList
return !elem.attr('role') && (elem.attr('type') === role) && !isNodeOneOf(elem, nodeBlackList);
// AND element is not in nativeAriaNodeNames
return !elem.attr('role') && (elem.attr('type') === role) && !isNodeOneOf(elem, nativeAriaNodeNames);
}
function getShape(attr, elem) {
@@ -350,7 +349,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
};
}])
.directive('ngDisabled', ['$aria', function($aria) {
return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nodeBlackList, false);
return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nativeAriaNodeNames, false);
}])
.directive('ngMessages', function() {
return {
@@ -374,7 +373,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
var fn = $parse(attr.ngClick);
return function(scope, elem, attr) {
if (!isNodeOneOf(elem, nodeBlackList)) {
if (!isNodeOneOf(elem, nativeAriaNodeNames)) {
if ($aria.config('bindRoleForClick') && !elem.attr('role')) {
elem.attr('role', 'button');
@@ -390,7 +389,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
if (keyCode === 13 || keyCode === 32) {
// If the event is triggered on a non-interactive element ...
if (nodeBlackList.indexOf(event.target.nodeName) === -1 && !event.target.isContentEditable) {
if (nativeAriaNodeNames.indexOf(event.target.nodeName) === -1 && !event.target.isContentEditable) {
// ... prevent the default browser behavior (e.g. scrolling when pressing spacebar)
// See https://github.com/angular/angular.js/issues/16664
event.preventDefault();
@@ -412,7 +411,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
return function(scope, elem, attr) {
if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
if ($aria.config('tabindex') && !elem.attr('tabindex') && !isNodeOneOf(elem, nodeBlackList)) {
if ($aria.config('tabindex') && !elem.attr('tabindex') && !isNodeOneOf(elem, nativeAriaNodeNames)) {
elem.attr('tabindex', 0);
}
};
+18 -40
View File
@@ -41,12 +41,12 @@ var htmlSanitizeWriter;
* @description
* Sanitizes an html string by stripping all potentially dangerous tokens.
*
* The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are
* The input is sanitized by parsing the HTML into tokens. All safe tokens (from a trusted URI list) are
* then serialized back to a properly escaped HTML string. This means that no unsafe input can make
* it into the returned string.
*
* The whitelist for URL sanitization of attribute values is configured using the functions
* `aHrefSanitizationWhitelist` and `imgSrcSanitizationWhitelist` of {@link $compileProvider}.
* The trusted URIs for URL sanitization of attribute values is configured using the functions
* `aHrefSanitizationTrustedUrlList` and `imgSrcSanitizationTrustedUrlList` of {@link $compileProvider}.
*
* The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}.
*
@@ -277,8 +277,8 @@ function $SanitizeProvider() {
* **Note**:
* The new attributes will not be treated as URI attributes, which means their values will not be
* sanitized as URIs using `$compileProvider`'s
* {@link ng.$compileProvider#aHrefSanitizationWhitelist aHrefSanitizationWhitelist} and
* {@link ng.$compileProvider#imgSrcSanitizationWhitelist imgSrcSanitizationWhitelist}.
* {@link ng.$compileProvider#aHrefSanitizationTrustedUrlList aHrefSanitizationTrustedUrlList} and
* {@link ng.$compileProvider#imgSrcSanitizationTrustedUrlList imgSrcSanitizationTrustedUrlList}.
*
* <div class="alert alert-info">
* This method must be called during the {@link angular.Module#config config} phase. Once the
@@ -421,50 +421,28 @@ function $SanitizeProvider() {
}
/**
* Create an inert document that contains the dirty HTML that needs sanitizing
* Depending upon browser support we use one of three strategies for doing this.
* Support: Safari 10.x -> XHR strategy
* Support: Firefox -> DomParser strategy
* Create an inert document that contains the dirty HTML that needs sanitizing.
* We use the DOMParser API by default and fall back to createHTMLDocument if DOMParser is not
* available.
*/
var getInertBodyElement /* function(html: string): HTMLBodyElement */ = (function(window, document) {
var inertDocument;
if (document && document.implementation) {
inertDocument = document.implementation.createHTMLDocument('inert');
} else {
if (isDOMParserAvailable()) {
return getInertBodyElement_DOMParser;
}
if (!document || !document.implementation) {
throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document');
}
var inertDocument = document.implementation.createHTMLDocument('inert');
var inertBodyElement = (inertDocument.documentElement || inertDocument.getDocumentElement()).querySelector('body');
return getInertBodyElement_InertDocument;
// Check for the Safari 10.1 bug - which allows JS to run inside the SVG G element
inertBodyElement.innerHTML = '<svg><g onload="this.parentNode.remove()"></g></svg>';
if (!inertBodyElement.querySelector('svg')) {
return getInertBodyElement_XHR;
} else {
// Check for the Firefox bug - which prevents the inner img JS from being sanitized
inertBodyElement.innerHTML = '<svg><p><style><img src="</style><img src=x onerror=alert(1)//">';
if (inertBodyElement.querySelector('svg img')) {
return getInertBodyElement_DOMParser;
} else {
return getInertBodyElement_InertDocument;
}
}
function getInertBodyElement_XHR(html) {
// We add this dummy element to ensure that the rest of the content is parsed as expected
// e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the `<head>` tag.
html = '<remove></remove>' + html;
function isDOMParserAvailable() {
try {
html = encodeURI(html);
return !!getInertBodyElement_DOMParser('');
} catch (e) {
return undefined;
return false;
}
var xhr = new window.XMLHttpRequest();
xhr.responseType = 'document';
xhr.open('GET', 'data:text/html;charset=utf-8,' + html, false);
xhr.send(null);
var body = xhr.response.body;
body.firstChild.remove();
return body;
}
function getInertBodyElement_DOMParser(html) {
+19 -1
View File
@@ -814,6 +814,19 @@ describe('angular', function() {
expect(isElement(dst.jqObject)).toBeTruthy();
expect(dst.jqObject.nodeName).toBeUndefined(); // i.e it is a jqLite/jQuery object
});
it('should not merge the __proto__ property', function() {
var src = JSON.parse('{ "__proto__": { "xxx": "polluted" } }');
var dst = {};
merge(dst, src);
if (typeof dst.__proto__ !== 'undefined') { // eslint-disable-line
// Should not overwrite the __proto__ property or pollute the Object prototype
expect(dst.__proto__).toBe(Object.prototype); // eslint-disable-line
}
expect(({}).xxx).toBeUndefined();
});
});
@@ -1780,7 +1793,12 @@ describe('angular', function() {
} else if (/Chrome\//.test(userAgent)) {
protocol = 'chrome-extension:';
} else if (/Safari\//.test(userAgent)) {
protocol = 'safari-extension:';
// On iOS, Safari versions <15 recognize `safari-extension:`, while versions >=15 only
// recognize `chrome-extension:`.
// (On macOS, Safari v15 recognizes both protocols, so it is fine to use either.)
var majorVersionMatch = /Version\/(\d+)/.exec(userAgent);
var majorVersion = majorVersionMatch ? parseInt(majorVersionMatch[1], 10) : 0;
protocol = (majorVersion < 15) ? 'safari-extension:' : 'chrome-extension:';
} else {
protocol = 'browserext:'; // Upcoming standard scheme.
}
+2
View File
@@ -123,6 +123,8 @@ describe('$anchorScroll', function() {
var lastAnchor = anchors.last();
var lastAnchorId = 'anchor-5';
if (browser.params.browser === 'firefox') return;
// Make sure there is not enough room to scroll the last anchor to the top
lastAnchor.getSize().then(function(size) {
var tempHeight = size.height + (yOffset / 2);
+2 -4
View File
@@ -9,14 +9,12 @@ describe('ngRoute promises', function() {
expect(element.all(by.tagName('li')).count()).toBe(5);
});
it('should time out if the promise takes long enough', function() {
it('should time out if the promise takes long enough', function(done) {
// Don't try this at home kids, I'm a protractor dev
browser.manage().timeouts().setScriptTimeout(1000);
browser.waitForAngular().then(function() {
fail('waitForAngular() should have timed out, but didn\'t');
}, function(error) {
expect(error.message).toContain('Timed out waiting for asynchronous Angular tasks to finish');
});
}, done);
});
it('should wait for route promises when navigating to another route', function() {
+9
View File
@@ -9,4 +9,13 @@ describe('Sample', function() {
it('should have the interpolated text', function() {
expect(element(by.binding('text')).getText()).toBe('Hello, world!');
});
it('should insert the ng-cloak styles', function() {
browser.executeScript(`
var span = document.createElement('span');
span.className = 'ng-cloak foo';
document.body.appendChild(span);
`);
expect(element(by.className('foo')).isDisplayed()).toBe(false);
});
});
+96
View File
@@ -147,6 +147,13 @@ describe('jqLite', function() {
expect(nodes[0].nodeName.toLowerCase()).toBe('option');
});
it('should allow construction of multiple <option> elements', function() {
var nodes = jqLite('<option></option><option></option>');
expect(nodes.length).toBe(2);
expect(nodes[0].nodeName.toLowerCase()).toBe('option');
expect(nodes[1].nodeName.toLowerCase()).toBe('option');
});
// Special tests for the construction of elements which are restricted (in the HTML5 spec) to
// being children of specific nodes.
@@ -169,6 +176,95 @@ describe('jqLite', function() {
expect(nodes[0].nodeName.toLowerCase()).toBe(name);
});
});
describe('security', function() {
it('shouldn\'t crash at attempts to close the table wrapper', function() {
// jQuery doesn't pass this test yet.
if (!_jqLiteMode) return;
// Support: IE <10
// In IE 9 we still need to use the old-style innerHTML assignment
// as that's the only one that works.
if (msie < 10) return;
expect(function() {
// This test case attempts to close the tags which wrap input
// based on matching done in wrapMap, escaping the wrapper & thus
// triggering an error when descending.
var el = jqLite('<td></td></tr></tbody></table><td></td>');
expect(el.length).toBe(2);
expect(el[0].nodeName.toLowerCase()).toBe('td');
expect(el[1].nodeName.toLowerCase()).toBe('td');
}).not.toThrow();
});
it('shouldn\'t unsanitize sanitized code', function(done) {
// jQuery <3.5.0 fail those tests.
if (isJQuery2x()) {
done();
return;
}
var counter = 0,
assertCount = 13,
container = jqLite('<div></div>');
function donePartial() {
counter++;
if (counter === assertCount) {
container.remove();
delete window.xss;
done();
}
}
jqLite(document.body).append(container);
window.xss = jasmine.createSpy('xss');
// Thanks to Masato Kinugawa from Cure53 for providing the following test cases.
// Note: below test cases need to invoke the xss function with consecutive
// decimal parameters for the assertions to be correct.
forEach([
'<img alt="<x" title="/><img src=url404 onerror=xss(0)>">',
'<img alt="\n<x" title="/>\n<img src=url404 onerror=xss(1)>">',
'<style><style/><img src=url404 onerror=xss(2)>',
'<xmp><xmp/><img src=url404 onerror=xss(3)>',
'<title><title /><img src=url404 onerror=xss(4)>',
'<iframe><iframe/><img src=url404 onerror=xss(5)>',
'<noframes><noframes/><img src=url404 onerror=xss(6)>',
'<noscript><noscript/><img src=url404 onerror=xss(7)>',
'<foo" alt="" title="/><img src=url404 onerror=xss(8)>">',
'<img alt="<x" title="" src="/><img src=url404 onerror=xss(9)>">',
'<noscript/><img src=url404 onerror=xss(10)>',
'<noembed><noembed/><img src=url404 onerror=xss(11)>',
'<option><style></option></select><img src=url404 onerror=xss(12)></style>'
], function(htmlString, index) {
var element = jqLite('<div></div>');
container.append(element);
element.append(jqLite(htmlString));
window.setTimeout(function() {
expect(window.xss).not.toHaveBeenCalledWith(index);
donePartial();
}, 1000);
});
});
it('should allow to restore legacy insecure behavior', function() {
// jQuery doesn't have this API.
if (!_jqLiteMode) return;
// eslint-disable-next-line new-cap
angular.UNSAFE_restoreLegacyJqLiteXHTMLReplacement();
var elem = jqLite('<div/><span/>');
expect(elem.length).toBe(2);
expect(elem[0].nodeName.toLowerCase()).toBe('div');
expect(elem[1].nodeName.toLowerCase()).toBe('span');
});
});
});
describe('_data', function() {
+25 -25
View File
@@ -151,30 +151,30 @@ describe('$compile', function() {
describe('configuration', function() {
it('should use $$sanitizeUriProvider for reconfiguration of the `aHrefSanitizationWhitelist`', function() {
it('should use $$sanitizeUriProvider for reconfiguration of the `aHrefSanitizationTrustedUrlList`', function() {
module(function($compileProvider, $$sanitizeUriProvider) {
var newRe = /safe:/, returnVal;
expect($compileProvider.aHrefSanitizationWhitelist()).toBe($$sanitizeUriProvider.aHrefSanitizationWhitelist());
returnVal = $compileProvider.aHrefSanitizationWhitelist(newRe);
expect($compileProvider.aHrefSanitizationTrustedUrlList()).toBe($$sanitizeUriProvider.aHrefSanitizationTrustedUrlList());
returnVal = $compileProvider.aHrefSanitizationTrustedUrlList(newRe);
expect(returnVal).toBe($compileProvider);
expect($$sanitizeUriProvider.aHrefSanitizationWhitelist()).toBe(newRe);
expect($compileProvider.aHrefSanitizationWhitelist()).toBe(newRe);
expect($$sanitizeUriProvider.aHrefSanitizationTrustedUrlList()).toBe(newRe);
expect($compileProvider.aHrefSanitizationTrustedUrlList()).toBe(newRe);
});
inject(function() {
// needed to the module definition above is run...
});
});
it('should use $$sanitizeUriProvider for reconfiguration of the `imgSrcSanitizationWhitelist`', function() {
it('should use $$sanitizeUriProvider for reconfiguration of the `imgSrcSanitizationTrustedUrlList`', function() {
module(function($compileProvider, $$sanitizeUriProvider) {
var newRe = /safe:/, returnVal;
expect($compileProvider.imgSrcSanitizationWhitelist()).toBe($$sanitizeUriProvider.imgSrcSanitizationWhitelist());
returnVal = $compileProvider.imgSrcSanitizationWhitelist(newRe);
expect($compileProvider.imgSrcSanitizationTrustedUrlList()).toBe($$sanitizeUriProvider.imgSrcSanitizationTrustedUrlList());
returnVal = $compileProvider.imgSrcSanitizationTrustedUrlList(newRe);
expect(returnVal).toBe($compileProvider);
expect($$sanitizeUriProvider.imgSrcSanitizationWhitelist()).toBe(newRe);
expect($compileProvider.imgSrcSanitizationWhitelist()).toBe(newRe);
expect($$sanitizeUriProvider.imgSrcSanitizationTrustedUrlList()).toBe(newRe);
expect($compileProvider.imgSrcSanitizationTrustedUrlList()).toBe(newRe);
});
inject(function() {
// needed to the module definition above is run...
@@ -11334,9 +11334,9 @@ describe('$compile', function() {
// IE9 rejects the `video` / `audio` tags with "Error: Not implemented"
if (msie !== 9 || tag === 'img') {
describe(tag + '[src] context requirement', function() {
it('should NOT require trusted values for whitelisted URIs', inject(function($rootScope, $compile) {
it('should NOT require trusted values for trusted URIs', inject(function($rootScope, $compile) {
element = $compile('<' + tag + ' src="{{testUrl}}"></' + tag + '>')($rootScope);
$rootScope.testUrl = 'http://example.com/image.mp4'; // `http` is whitelisted
$rootScope.testUrl = 'http://example.com/image.mp4'; // `http` is trusted
$rootScope.$digest();
expect(element.attr('src')).toEqual('http://example.com/image.mp4');
}));
@@ -11372,9 +11372,9 @@ describe('$compile', function() {
if (msie !== 9) {
['source', 'track'].forEach(function(tag) {
describe(tag + '[src]', function() {
it('should NOT require trusted values for whitelisted URIs', inject(function($rootScope, $compile) {
it('should NOT require trusted values for trusted URIs', inject(function($rootScope, $compile) {
element = $compile('<video><' + tag + ' src="{{testUrl}}"></' + tag + '></video>')($rootScope);
$rootScope.testUrl = 'http://example.com/image.mp4'; // `http` is whitelisted
$rootScope.testUrl = 'http://example.com/image.mp4'; // `http` is trusted
$rootScope.$digest();
expect(element.find(tag).attr('src')).toEqual('http://example.com/image.mp4');
}));
@@ -11509,14 +11509,14 @@ describe('$compile', function() {
});
});
it('should NOT require trusted values for whitelisted values', inject(function($rootScope, $compile, $sce) {
it('should NOT require trusted values for trusted URI values', inject(function($rootScope, $compile, $sce) {
element = $compile('<img srcset="{{testUrl}}"></img>')($rootScope);
$rootScope.testUrl = 'http://example.com/image.png'; // `http` is whitelisted
$rootScope.testUrl = 'http://example.com/image.png'; // `http` is trusted
$rootScope.$digest();
expect(element.attr('srcset')).toEqual('http://example.com/image.png');
}));
it('should accept trusted values, if they are also whitelisted', inject(function($rootScope, $compile, $sce) {
it('should accept trusted values, if they are also trusted URIs', inject(function($rootScope, $compile, $sce) {
element = $compile('<img srcset="{{testUrl}}"></img>')($rootScope);
$rootScope.testUrl = $sce.trustAsUrl('http://example.com');
$rootScope.$digest();
@@ -11602,8 +11602,8 @@ describe('$compile', function() {
});
describe('a[href] sanitization', function() {
it('should NOT require trusted values for whitelisted values', inject(function($rootScope, $compile) {
$rootScope.testUrl = 'http://example.com/image.png'; // `http` is whitelisted
it('should NOT require trusted values for trusted URI values', inject(function($rootScope, $compile) {
$rootScope.testUrl = 'http://example.com/image.png'; // `http` is trusted
element = $compile('<a href="{{testUrl}}"></a>')($rootScope);
$rootScope.$digest();
expect(element.attr('href')).toEqual('http://example.com/image.png');
@@ -11613,8 +11613,8 @@ describe('$compile', function() {
expect(element.attr('ng-href')).toEqual('http://example.com/image.png');
}));
it('should accept trusted values for non-whitelisted values', inject(function($rootScope, $compile, $sce) {
$rootScope.testUrl = $sce.trustAsUrl('javascript:foo()'); // `javascript` is not whitelisted
it('should accept trusted values for non-trusted URI values', inject(function($rootScope, $compile, $sce) {
$rootScope.testUrl = $sce.trustAsUrl('javascript:foo()'); // `javascript` is not trusted
element = $compile('<a href="{{testUrl}}"></a>')($rootScope);
$rootScope.$digest();
expect(element.attr('href')).toEqual('javascript:foo()');
@@ -11624,8 +11624,8 @@ describe('$compile', function() {
expect(element.attr('ng-href')).toEqual('javascript:foo()');
}));
it('should sanitize non-whitelisted values', inject(function($rootScope, $compile) {
$rootScope.testUrl = 'javascript:foo()'; // `javascript` is not whitelisted
it('should sanitize non-trusted values', inject(function($rootScope, $compile) {
$rootScope.testUrl = 'javascript:foo()'; // `javascript` is not trusted
element = $compile('<a href="{{testUrl}}"></a>')($rootScope);
$rootScope.$digest();
expect(element.attr('href')).toEqual('unsafe:javascript:foo()');
@@ -11678,7 +11678,7 @@ describe('$compile', function() {
$provide.value('$$sanitizeUri', $$sanitizeUri);
});
inject(function($compile, $rootScope) {
// This URL would fail the RESOURCE_URL whitelist, but that test shouldn't be run
// This URL would fail the RESOURCE_URL trusted list, but that test shouldn't be run
// because these interpolations will be resolved against the URL context instead
$rootScope.testUrl = 'https://bad.example.org';
@@ -11700,7 +11700,7 @@ describe('$compile', function() {
$provide.value('$$sanitizeUri', $$sanitizeUri);
});
inject(function($compile, $rootScope) {
// This URL would fail the RESOURCE_URL whitelist, but that test shouldn't be run
// This URL would fail the RESOURCE_URL trusted list, but that test shouldn't be run
// because these interpolations will be resolved against the URL context instead
$rootScope.testUrl = 'https://bad.example.org';
+24 -24
View File
@@ -1271,10 +1271,10 @@ describe('input', function() {
var inputElm = helper.compileInput('<input type="datetime-local" ng-model="breakMe"/>');
$rootScope.$apply(function() {
$rootScope.breakMe = new Date(2009, 0, 6, 16, 25, 0);
$rootScope.breakMe = new Date(2009, 0, 6, 16, 25, 1, 337);
});
expect(inputElm.val()).toBe('2009-01-06T16:25:00.000');
expect(inputElm.val()).toBe('2009-01-06T16:25:01.337');
//set to text for browsers with datetime-local validation.
inputElm[0].setAttribute('type', 'text');
@@ -1324,32 +1324,32 @@ describe('input', function() {
it('should use UTC if specified in the options', function() {
var inputElm = helper.compileInput('<input type="datetime-local" ng-model="value" ng-model-options="{timezone: \'UTC\'}" />');
helper.changeInputValueTo('2000-01-01T01:02');
expect(+$rootScope.value).toBe(Date.UTC(2000, 0, 1, 1, 2, 0));
helper.changeInputValueTo('2000-01-01T01:02:03.456');
expect(+$rootScope.value).toBe(Date.UTC(2000, 0, 1, 1, 2, 3, 456));
$rootScope.$apply(function() {
$rootScope.value = new Date(Date.UTC(2001, 0, 1, 1, 2, 0));
$rootScope.value = new Date(Date.UTC(2001, 0, 1, 1, 2, 3, 456));
});
expect(inputElm.val()).toBe('2001-01-01T01:02:00.000');
expect(inputElm.val()).toBe('2001-01-01T01:02:03.456');
});
it('should be possible to override the timezone', function() {
var inputElm = helper.compileInput('<input type="datetime-local" ng-model="value" ng-model-options="{timezone: \'UTC\'}" />');
helper.changeInputValueTo('2000-01-01T01:02');
expect(+$rootScope.value).toBe(Date.UTC(2000, 0, 1, 1, 2, 0));
helper.changeInputValueTo('2000-01-01T01:02:03.456');
expect(+$rootScope.value).toBe(Date.UTC(2000, 0, 1, 1, 2, 3, 456));
inputElm.controller('ngModel').$overrideModelOptions({timezone: '+0500'});
$rootScope.$apply(function() {
$rootScope.value = new Date(Date.UTC(2001, 0, 1, 1, 2, 0));
$rootScope.value = new Date(Date.UTC(2001, 0, 1, 1, 2, 3, 456));
});
expect(inputElm.val()).toBe('2001-01-01T06:02:00.000');
expect(inputElm.val()).toBe('2001-01-01T06:02:03.456');
inputElm.controller('ngModel').$overrideModelOptions({timezone: 'UTC'});
helper.changeInputValueTo('2000-01-01T01:02');
expect(+$rootScope.value).toBe(Date.UTC(2000, 0, 1, 1, 2, 0));
helper.changeInputValueTo('2000-01-01T01:02:03.456');
expect(+$rootScope.value).toBe(Date.UTC(2000, 0, 1, 1, 2, 3, 456));
});
@@ -1360,13 +1360,13 @@ describe('input', function() {
var inputElm = helper.compileInput(
'<input type="datetime-local" ng-model="value" ng-model-options="' + ngModelOptions + '" />');
helper.changeInputValueTo('2000-01-01T06:02');
expect(+$rootScope.value).toBe(Date.UTC(2000, 0, 1, 1, 2, 0));
helper.changeInputValueTo('2000-01-01T06:02:03.456');
expect(+$rootScope.value).toBe(Date.UTC(2000, 0, 1, 1, 2, 3, 456));
$rootScope.$apply(function() {
$rootScope.value = new Date(Date.UTC(2001, 0, 1, 1, 2, 0));
$rootScope.value = new Date(Date.UTC(2001, 0, 1, 1, 2, 3, 456));
});
expect(inputElm.val()).toBe('2001-01-01T06:02:00.000');
expect(inputElm.val()).toBe('2001-01-01T06:02:03.456');
}
);
@@ -1401,13 +1401,13 @@ describe('input', function() {
it('should allow to specify the seconds', function() {
var inputElm = helper.compileInput('<input type="datetime-local" ng-model="value"" />');
helper.changeInputValueTo('2000-01-01T01:02:03');
expect(+$rootScope.value).toBe(+new Date(2000, 0, 1, 1, 2, 3));
helper.changeInputValueTo('2000-01-01T01:02:03.456');
expect(+$rootScope.value).toBe(+new Date(2000, 0, 1, 1, 2, 3, 456));
$rootScope.$apply(function() {
$rootScope.value = new Date(2001, 0, 1, 1, 2, 3);
$rootScope.value = new Date(2001, 0, 1, 1, 2, 3, 456);
});
expect(inputElm.val()).toBe('2001-01-01T01:02:03.000');
expect(inputElm.val()).toBe('2001-01-01T01:02:03.456');
});
@@ -1425,13 +1425,13 @@ describe('input', function() {
it('should allow four or more digits in year', function() {
var inputElm = helper.compileInput('<input type="datetime-local" ng-model="value" />');
helper.changeInputValueTo('10123-01-01T01:02');
expect(+$rootScope.value).toBe(+new Date(10123, 0, 1, 1, 2, 0));
helper.changeInputValueTo('10123-01-01T01:02:03.456');
expect(+$rootScope.value).toBe(+new Date(10123, 0, 1, 1, 2, 3, 456));
$rootScope.$apply(function() {
$rootScope.value = new Date(20456, 1, 1, 1, 2, 0);
$rootScope.value = new Date(20456, 1, 1, 1, 2, 3, 456);
});
expect(inputElm.val()).toBe('20456-02-01T01:02:00.000');
expect(inputElm.val()).toBe('20456-02-01T01:02:03.456');
}
);
}
+1 -1
View File
@@ -349,7 +349,7 @@ describe('select', function() {
});
it('should only call selectCtrl.writeValue after a digest has occured', function() {
it('should only call selectCtrl.writeValue after a digest has occurred', function() {
scope.mySelect = 'B';
scope.$apply();

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