diff --git a/.ng-dev/config.ts b/.ng-dev/config.ts
index 6350332d5e..342b3f64f7 100644
--- a/.ng-dev/config.ts
+++ b/.ng-dev/config.ts
@@ -4,6 +4,7 @@ import {MergeConfig} from '../dev-infra/pr/merge/config';
const commitMessage = {
'maxLength': 120,
'minBodyLength': 100,
+ 'minBodyLengthExcludes': ['docs'],
'types': [
'build',
'ci',
@@ -56,8 +57,6 @@ const format = {
// TODO: burn down format failures and remove aio and integration exceptions.
'!aio/**',
'!integration/**',
- // TODO: remove this exclusion as part of IE deprecation.
- '!shims_for_IE.js',
// Both third_party and .yarn are directories containing copied code which should
// not be modified.
'!third_party/**',
diff --git a/BUILD.bazel b/BUILD.bazel
index 48e84cc328..73e67bea63 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -24,7 +24,7 @@ filegroup(
"//packages/zone.js/bundles:zone-testing.umd.js",
"//packages/zone.js/bundles:task-tracking.umd.js",
"//:test-events.js",
- "//:shims_for_IE.js",
+ "//:third_party/shims_for_IE.js",
# Including systemjs because it defines `__eval`, which produces correct stack traces.
"@npm//:node_modules/systemjs/dist/system.src.js",
"@npm//:node_modules/reflect-metadata/Reflect.js",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7f4739d4d..531ca66972 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,26 @@
+
+## [10.0.1](https://github.com/angular/angular/compare/10.0.0...10.0.1) (2020-06-26)
+
+
+### Bug Fixes
+
+* **core:** cleanup DOM elements when root view is removed ([#37600](https://github.com/angular/angular/issues/37600)) ([64f2ffa](https://github.com/angular/angular/commit/64f2ffa)), closes [#36449](https://github.com/angular/angular/issues/36449)
+* **forms:** change error message ([#37643](https://github.com/angular/angular/issues/37643)) ([c5bc2e7](https://github.com/angular/angular/commit/c5bc2e7))
+* **forms:** correct usage of `selectedOptions` ([#37620](https://github.com/angular/angular/issues/37620)) ([dfb58c4](https://github.com/angular/angular/commit/dfb58c4)), closes [#37433](https://github.com/angular/angular/issues/37433)
+* **http:** avoid abort a request when fetch operation is completed ([#37367](https://github.com/angular/angular/issues/37367)) ([a5d5f67](https://github.com/angular/angular/commit/a5d5f67))
+* **language-service:** reinstate getExternalFiles() ([#37750](https://github.com/angular/angular/issues/37750)) ([ad6680f](https://github.com/angular/angular/commit/ad6680f))
+* **migrations:** do not incorrectly add todo for @Injectable or @Pipe ([#37732](https://github.com/angular/angular/issues/37732)) ([13020b9](https://github.com/angular/angular/commit/13020b9)), closes [#37726](https://github.com/angular/angular/issues/37726)
+* **router:** `RouterLinkActive` should run CD when setting `isActive` ([#21411](https://github.com/angular/angular/issues/21411)) ([a8ea817](https://github.com/angular/angular/commit/a8ea817)), closes [#15943](https://github.com/angular/angular/issues/15943) [#19934](https://github.com/angular/angular/issues/19934)
+* **router:** add null support for RouterLink directive ([#32616](https://github.com/angular/angular/issues/32616)) ([69948ce](https://github.com/angular/angular/commit/69948ce))
+* **router:** fix error when calling ParamMap.get function ([#31599](https://github.com/angular/angular/issues/31599)) ([3190ccf](https://github.com/angular/angular/commit/3190ccf))
+
+
+### Performance Improvements
+
+* **compiler-cli:** fix regressions in incremental program reuse ([#37690](https://github.com/angular/angular/issues/37690)) ([96b96fb](https://github.com/angular/angular/commit/96b96fb))
+
+
+
# [10.0.0](https://github.com/angular/angular/compare/10.0.0-rc.6...10.0.0) (2020-06-24)
diff --git a/aio/content/examples/pipes/src/app/app.component.ts b/aio/content/examples/pipes/src/app/app.component.ts
index 2b739ed2a0..5b71cc53c7 100644
--- a/aio/content/examples/pipes/src/app/app.component.ts
+++ b/aio/content/examples/pipes/src/app/app.component.ts
@@ -6,5 +6,5 @@ import { Component } from '@angular/core';
templateUrl: './app.component.html'
})
export class AppComponent {
- birthday = new Date(1988, 3, 15); // April 15, 1988
+ birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
}
diff --git a/aio/content/examples/pipes/src/app/hero-birthday1.component.ts b/aio/content/examples/pipes/src/app/hero-birthday1.component.ts
index d51914550f..4b475e80d6 100644
--- a/aio/content/examples/pipes/src/app/hero-birthday1.component.ts
+++ b/aio/content/examples/pipes/src/app/hero-birthday1.component.ts
@@ -8,5 +8,5 @@ import { Component } from '@angular/core';
// #enddocregion hero-birthday-template
})
export class HeroBirthdayComponent {
- birthday = new Date(1988, 3, 15); // April 15, 1988
+ birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
}
diff --git a/aio/content/examples/pipes/src/app/hero-birthday2.component.ts b/aio/content/examples/pipes/src/app/hero-birthday2.component.ts
index ce71c2ab1e..f8ee3ca911 100644
--- a/aio/content/examples/pipes/src/app/hero-birthday2.component.ts
+++ b/aio/content/examples/pipes/src/app/hero-birthday2.component.ts
@@ -12,7 +12,7 @@ import { Component } from '@angular/core';
})
// #docregion class
export class HeroBirthday2Component {
- birthday = new Date(1988, 3, 15); // April 15, 1988
+ birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
toggle = true; // start with true == shortDate
get format() { return this.toggle ? 'shortDate' : 'fullDate'; }
diff --git a/dev-infra/commit-message/config.ts b/dev-infra/commit-message/config.ts
index 7a84edc488..2d9739cecf 100644
--- a/dev-infra/commit-message/config.ts
+++ b/dev-infra/commit-message/config.ts
@@ -11,6 +11,7 @@ import {assertNoErrors, getConfig, NgDevConfig} from '../utils/config';
export interface CommitMessageConfig {
maxLineLength: number;
minBodyLength: number;
+ minBodyLengthTypeExcludes?: string[];
types: string[];
scopes: string[];
}
@@ -19,7 +20,7 @@ export interface CommitMessageConfig {
export function getCommitMessageConfig() {
// List of errors encountered validating the config.
const errors: string[] = [];
- // The unvalidated config object.
+ // The non-validated config object.
const config: Partial> = getConfig();
if (config.commitMessage === undefined) {
diff --git a/dev-infra/commit-message/validate.spec.ts b/dev-infra/commit-message/validate.spec.ts
index e745fa7158..ad1bf5b1e9 100644
--- a/dev-infra/commit-message/validate.spec.ts
+++ b/dev-infra/commit-message/validate.spec.ts
@@ -10,19 +10,22 @@
import * as validateConfig from './config';
import {validateCommitMessage} from './validate';
+type CommitMessageConfig = validateConfig.CommitMessageConfig;
+
+
// Constants
-const config = {
- 'commitMessage': {
- 'maxLineLength': 120,
- 'minBodyLength': 0,
- 'types': [
+const config: {commitMessage: CommitMessageConfig} = {
+ commitMessage: {
+ maxLineLength: 120,
+ minBodyLength: 0,
+ types: [
'feat',
'fix',
'refactor',
'release',
'style',
],
- 'scopes': [
+ scopes: [
'common',
'compiler',
'core',
@@ -224,5 +227,42 @@ describe('validate-commit-message.js', () => {
});
});
});
+
+ describe('minBodyLength', () => {
+ const minBodyLengthConfig: {commitMessage: CommitMessageConfig} = {
+ commitMessage: {
+ maxLineLength: 120,
+ minBodyLength: 30,
+ minBodyLengthTypeExcludes: ['docs'],
+ types: ['fix', 'docs'],
+ scopes: ['core']
+ }
+ };
+
+ beforeEach(() => {
+ (validateConfig.getCommitMessageConfig as jasmine.Spy).and.returnValue(minBodyLengthConfig);
+ });
+
+ it('should fail validation if the body is shorter than `minBodyLength`', () => {
+ expect(validateCommitMessage(
+ 'fix(core): something\n\n Explanation of the motivation behind this change'))
+ .toBe(VALID);
+ expect(validateCommitMessage('fix(core): something\n\n too short')).toBe(INVALID);
+ expect(lastError).toContain(
+ 'The commit message body does not meet the minimum length of 30 characters');
+ expect(validateCommitMessage('fix(core): something')).toBe(INVALID);
+ expect(lastError).toContain(
+ 'The commit message body does not meet the minimum length of 30 characters');
+ });
+
+ it('should pass validation if the body is shorter than `minBodyLength` but the commit type is in the `minBodyLengthTypeExclusions` list',
+ () => {
+ expect(validateCommitMessage('docs: just fixing a typo')).toBe(VALID);
+ expect(validateCommitMessage('docs(core): just fixing a typo')).toBe(VALID);
+ expect(validateCommitMessage(
+ 'docs(core): just fixing a typo\n\nThis was just a silly typo.'))
+ .toBe(VALID);
+ });
+ });
});
});
diff --git a/dev-infra/commit-message/validate.ts b/dev-infra/commit-message/validate.ts
index 6148f6dfe2..a9b01f1c4d 100644
--- a/dev-infra/commit-message/validate.ts
+++ b/dev-infra/commit-message/validate.ts
@@ -148,7 +148,8 @@ export function validateCommitMessage(
// Checking commit body //
//////////////////////////
- if (commit.bodyWithoutLinking.trim().length < config.minBodyLength) {
+ if (!config.minBodyLengthTypeExcludes?.includes(commit.type) &&
+ commit.bodyWithoutLinking.trim().length < config.minBodyLength) {
printError(`The commit message body does not meet the minimum length of ${
config.minBodyLength} characters`);
return false;
@@ -157,7 +158,7 @@ export function validateCommitMessage(
const bodyByLine = commit.body.split('\n');
if (bodyByLine.some(line => line.length > config.maxLineLength)) {
printError(
- `The commit messsage body contains lines greater than ${config.maxLineLength} characters`);
+ `The commit message body contains lines greater than ${config.maxLineLength} characters`);
return false;
}
diff --git a/dev-infra/pr/discover-new-conflicts/index.ts b/dev-infra/pr/discover-new-conflicts/index.ts
index daa1873092..790d809438 100644
--- a/dev-infra/pr/discover-new-conflicts/index.ts
+++ b/dev-infra/pr/discover-new-conflicts/index.ts
@@ -63,8 +63,8 @@ export async function discoverNewConflictsForPr(
process.exit(1);
}
- /** The active github branch when the run began. */
- const originalBranch = git.getCurrentBranch();
+ /** The active github branch or revision before we performed any Git commands. */
+ const previousBranchOrRevision = git.getCurrentBranchOrRevision();
/* Progress bar to indicate progress. */
const progressBar = new Bar({format: `[{bar}] ETA: {eta}s | {value}/{total}`});
/* PRs which were found to be conflicting. */
@@ -103,7 +103,7 @@ export async function discoverNewConflictsForPr(
const result = exec(`git rebase FETCH_HEAD`);
if (result.code) {
error('The requested PR currently has conflicts');
- cleanUpGitState(originalBranch);
+ cleanUpGitState(previousBranchOrRevision);
process.exit(1);
}
@@ -130,7 +130,7 @@ export async function discoverNewConflictsForPr(
info();
info(`Result:`);
- cleanUpGitState(originalBranch);
+ cleanUpGitState(previousBranchOrRevision);
// If no conflicts are found, exit successfully.
if (conflicts.length === 0) {
@@ -147,14 +147,14 @@ export async function discoverNewConflictsForPr(
process.exit(1);
}
-/** Reset git back to the provided branch. */
-export function cleanUpGitState(branch: string) {
+/** Reset git back to the provided branch or revision. */
+export function cleanUpGitState(previousBranchOrRevision: string) {
// Ensure that any outstanding rebases are aborted.
exec(`git rebase --abort`);
// Ensure that any changes in the current repo state are cleared.
exec(`git reset --hard`);
// Checkout the original branch from before the run began.
- exec(`git checkout ${branch}`);
+ exec(`git checkout ${previousBranchOrRevision}`);
// Delete the generated branch.
exec(`git branch -D ${tempWorkingBranch}`);
}
diff --git a/dev-infra/pr/merge/strategies/autosquash-merge.ts b/dev-infra/pr/merge/strategies/autosquash-merge.ts
index 198eda3daf..e304ed98bd 100644
--- a/dev-infra/pr/merge/strategies/autosquash-merge.ts
+++ b/dev-infra/pr/merge/strategies/autosquash-merge.ts
@@ -59,7 +59,7 @@ export class AutosquashMergeStrategy extends MergeStrategy {
// is desired, we set the `GIT_SEQUENCE_EDITOR` environment variable to `true` so that
// the rebase seems interactive to Git, while it's not interactive to the user.
// See: https://github.com/git/git/commit/891d4a0313edc03f7e2ecb96edec5d30dc182294.
- const branchBeforeRebase = this.git.getCurrentBranch();
+ const branchOrRevisionBeforeRebase = this.git.getCurrentBranchOrRevision();
const rebaseEnv =
needsCommitMessageFixup ? undefined : {...process.env, GIT_SEQUENCE_EDITOR: 'true'};
this.git.run(
@@ -69,9 +69,9 @@ export class AutosquashMergeStrategy extends MergeStrategy {
// Update pull requests commits to reference the pull request. This matches what
// Github does when pull requests are merged through the Web UI. The motivation is
// that it should be easy to determine which pull request contained a given commit.
- // **Note**: The filter-branch command relies on the working tree, so we want to make
- // sure that we are on the initial branch where the merge script has been run.
- this.git.run(['checkout', '-f', branchBeforeRebase]);
+ // Note: The filter-branch command relies on the working tree, so we want to make sure
+ // that we are on the initial branch or revision where the merge script has been invoked.
+ this.git.run(['checkout', '-f', branchOrRevisionBeforeRebase]);
this.git.run(
['filter-branch', '-f', '--msg-filter', `${MSG_FILTER_SCRIPT} ${prNumber}`, revisionRange]);
diff --git a/dev-infra/pr/merge/task.ts b/dev-infra/pr/merge/task.ts
index e02815cbc0..7b9a76ead2 100644
--- a/dev-infra/pr/merge/task.ts
+++ b/dev-infra/pr/merge/task.ts
@@ -16,9 +16,6 @@ import {isPullRequest, loadAndValidatePullRequest,} from './pull-request';
import {GithubApiMergeStrategy} from './strategies/api-merge';
import {AutosquashMergeStrategy} from './strategies/autosquash-merge';
-/** Github OAuth scopes required for the merge task. */
-const REQUIRED_SCOPES = ['repo'];
-
/** Describes the status of a pull request merge. */
export const enum MergeStatus {
UNKNOWN_GIT_ERROR,
@@ -56,8 +53,19 @@ export class PullRequestMergeTask {
* @param force Whether non-critical pull request failures should be ignored.
*/
async merge(prNumber: number, force = false): Promise {
- // Assert the authenticated GitClient has access on the required scopes.
- const hasOauthScopes = await this.git.hasOauthScopes(...REQUIRED_SCOPES);
+ // Check whether the given Github token has sufficient permissions for writing
+ // to the configured repository. If the repository is not private, only the
+ // reduced `public_repo` OAuth scope is sufficient for performing merges.
+ const hasOauthScopes = await this.git.hasOauthScopes((scopes, missing) => {
+ if (!scopes.includes('repo')) {
+ if (this.config.remote.private) {
+ missing.push('repo');
+ } else if (!scopes.includes('public_repo')) {
+ missing.push('public_repo');
+ }
+ }
+ });
+
if (hasOauthScopes !== true) {
return {
status: MergeStatus.GITHUB_ERROR,
@@ -87,14 +95,14 @@ export class PullRequestMergeTask {
new GithubApiMergeStrategy(this.git, this.config.githubApiMerge) :
new AutosquashMergeStrategy(this.git);
- // Branch that is currently checked out so that we can switch back to it once
- // the pull request has been merged.
- let previousBranch: null|string = null;
+ // Branch or revision that is currently checked out so that we can switch back to
+ // it once the pull request has been merged.
+ let previousBranchOrRevision: null|string = null;
// The following block runs Git commands as child processes. These Git commands can fail.
// We want to capture these command errors and return an appropriate merge request status.
try {
- previousBranch = this.git.getCurrentBranch();
+ previousBranchOrRevision = this.git.getCurrentBranchOrRevision();
// Run preparations for the merge (e.g. fetching branches).
await strategy.prepare(pullRequest);
@@ -107,7 +115,7 @@ export class PullRequestMergeTask {
// Switch back to the previous branch. We need to do this before deleting the temporary
// branches because we cannot delete branches which are currently checked out.
- this.git.run(['checkout', '-f', previousBranch]);
+ this.git.run(['checkout', '-f', previousBranchOrRevision]);
await strategy.cleanup(pullRequest);
@@ -123,8 +131,8 @@ export class PullRequestMergeTask {
} finally {
// Always try to restore the branch if possible. We don't want to leave
// the repository in a different state than before.
- if (previousBranch !== null) {
- this.git.runGraceful(['checkout', '-f', previousBranch]);
+ if (previousBranchOrRevision !== null) {
+ this.git.runGraceful(['checkout', '-f', previousBranchOrRevision]);
}
}
}
diff --git a/dev-infra/pr/rebase/index.ts b/dev-infra/pr/rebase/index.ts
index 0b9fa9fe77..8c0af93324 100644
--- a/dev-infra/pr/rebase/index.ts
+++ b/dev-infra/pr/rebase/index.ts
@@ -50,10 +50,10 @@ export async function rebasePr(
}
/**
- * The branch originally checked out before this method performs any Git
- * operations that may change the working branch.
+ * The branch or revision originally checked out before this method performed
+ * any Git operations that may change the working branch.
*/
- const originalBranch = git.getCurrentBranch();
+ const previousBranchOrRevision = git.getCurrentBranchOrRevision();
/* Get the PR information from Github. */
const pr = await getPr(PR_SCHEMA, prNumber, config.github);
@@ -121,7 +121,7 @@ export async function rebasePr(
info();
info(`To abort the rebase and return to the state of the repository before this command`);
info(`run the following command:`);
- info(` $ git rebase --abort && git reset --hard && git checkout ${originalBranch}`);
+ info(` $ git rebase --abort && git reset --hard && git checkout ${previousBranchOrRevision}`);
process.exit(1);
} else {
info(`Cleaning up git state, and restoring previous state.`);
@@ -137,7 +137,7 @@ export async function rebasePr(
// Ensure that any changes in the current repo state are cleared.
git.runGraceful(['reset', '--hard'], {stdio: 'ignore'});
// Checkout the original branch from before the run began.
- git.runGraceful(['checkout', originalBranch], {stdio: 'ignore'});
+ git.runGraceful(['checkout', previousBranchOrRevision], {stdio: 'ignore'});
}
}
diff --git a/dev-infra/utils/config.ts b/dev-infra/utils/config.ts
index bcf6a82d60..bd08ee68e4 100644
--- a/dev-infra/utils/config.ts
+++ b/dev-infra/utils/config.ts
@@ -21,6 +21,8 @@ export interface GitClientConfig {
name: string;
/** If SSH protocol should be used for git interactions. */
useSsh?: boolean;
+ /** Whether the specified repository is private. */
+ private?: boolean;
}
/**
diff --git a/dev-infra/utils/git/index.ts b/dev-infra/utils/git/index.ts
index dbfb50c180..88c626dc20 100644
--- a/dev-infra/utils/git/index.ts
+++ b/dev-infra/utils/git/index.ts
@@ -21,6 +21,9 @@ type RateLimitResponseWithOAuthScopeHeader = Octokit.Response void;
+
/** Error for failed Git commands. */
export class GitCommandError extends Error {
constructor(client: GitClient, public args: string[]) {
@@ -119,9 +122,16 @@ export class GitClient {
return this.run(['branch', branchName, '--contains', sha]).stdout !== '';
}
- /** Gets the currently checked out branch. */
- getCurrentBranch(): string {
- return this.run(['rev-parse', '--abbrev-ref', 'HEAD']).stdout.trim();
+ /** Gets the currently checked out branch or revision. */
+ getCurrentBranchOrRevision(): string {
+ const branchName = this.run(['rev-parse', '--abbrev-ref', 'HEAD']).stdout.trim();
+ // If no branch name could be resolved. i.e. `HEAD` has been returned, then Git
+ // is currently in a detached state. In those cases, we just want to return the
+ // currently checked out revision/SHA.
+ if (branchName === 'HEAD') {
+ return this.run(['rev-parse', 'HEAD']).stdout.trim();
+ }
+ return branchName;
}
/** Gets whether the current Git repository has uncommitted changes. */
@@ -148,14 +158,11 @@ export class GitClient {
* Assert the GitClient instance is using a token with permissions for the all of the
* provided OAuth scopes.
*/
- async hasOauthScopes(...requestedScopes: string[]): Promise {
- const missingScopes: string[] = [];
+ async hasOauthScopes(testFn: OAuthScopeTestFunction): Promise {
const scopes = await this.getAuthScopesForToken();
- requestedScopes.forEach(scope => {
- if (!scopes.includes(scope)) {
- missingScopes.push(scope);
- }
- });
+ const missingScopes: string[] = [];
+ // Test Github OAuth scopes and collect missing ones.
+ testFn(scopes, missingScopes);
// If no missing scopes are found, return true to indicate all OAuth Scopes are available.
if (missingScopes.length === 0) {
return true;
diff --git a/docs/PUBLIC_API.md b/docs/PUBLIC_API.md
index be65edd1df..dc592c3788 100644
--- a/docs/PUBLIC_API.md
+++ b/docs/PUBLIC_API.md
@@ -53,40 +53,45 @@ If you modify any part of a public API in one of the supported public packages,
The public API guard provides a Bazel target that updates the current status of a given package. If you add to or modify the public API in any way, you must use [yarn](https://yarnpkg.com/) to execute the Bazel target in your terminal shell of choice (a recent version of `bash` is recommended).
```shell
-yarn bazel run //tools/public_api_guard:_api.accept
+yarn bazel run //packages/:_api.accept
```
Using yarn ensures that you are running the correct version of Bazel.
(Read more about building Angular with Bazel [here](./BAZEL.md).)
-Here is an example of a Circle CI test failure that resulted from adding a new allowed type to a public property in `forms.d.ts`. Error messages from the API guard use [`git-diff` formatting](https://git-scm.com/docs/git-diff#_combined_diff_format).
+Here is an example of a Circle CI test failure that resulted from adding a new allowed type to a public property in `core.d.ts`. Error messages from the API guard use [`git-diff` formatting](https://git-scm.com/docs/git-diff#_combined_diff_format).
```
-FAIL: //tools/public_api_guard:forms_api (see /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/testlogs/tools/public_api_guard/forms_api/test_attempts/attempt_1.log)
-FAIL: //tools/public_api_guard:forms_api (see /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/testlogs/tools/public_api_guard/forms_api/test.log)
+FAIL: //packages/core:core_api (see /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/testlogs/packages/core/core_api/test_attempts/attempt_1.log)
+INFO: From Action packages/compiler-cli/ngcc/test/fesm5_angular_core.js:
+[BABEL] Note: The code generator has deoptimised the styling of /b/f/w/bazel-out/k8-fastbuild/bin/packages/core/npm_package/fesm2015/core.js as it exceeds the max of 500KB.
+FAIL: //packages/core:core_api (see /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/testlogs/packages/core/core_api/test.log)
+
+FAILED: //packages/core:core_api (Summary)
+ /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/testlogs/packages/core/core_api/test.log
+ /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/testlogs/packages/core/core_api/test_attempts/attempt_1.log
+INFO: From Testing //packages/core:core_api:
+==================== Test output for //packages/core:core_api:
+/b/f/w/bazel-out/k8-fastbuild/bin/packages/core/core_api.sh.runfiles/angular/packages/core/npm_package/core.d.ts(7,1): error: No export declaration found for symbol "ComponentFactory"
+--- goldens/public-api/core/core.d.ts Golden file
++++ goldens/public-api/core/core.d.ts Generated API
+@@ -563,9 +563,9 @@
+ ngModule: Type;
+ providers?: Provider[];
+ }
+
+-export declare type NgIterable = Array | Iterable;
++export declare type NgIterable = Iterable;
+
+ export declare interface NgModule {
+ bootstrap?: Array | any[]>;
+ declarations?: Array | any[]>;
-FAILED: //tools/public_api_guard:forms_api (Summary)
- /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/testlogs/tools/public_api_guard/forms_api/test.log
- /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/testlogs/tools/public_api_guard/forms_api/test_attempts/attempt_1.log
-INFO: From Testing //tools/public_api_guard:forms_api:
-==================== Test output for //tools/public_api_guard:forms_api:
---- tools/public_api_guard/forms/forms.d.ts Golden file
-+++ tools/public_api_guard/forms/forms.d.ts Generated API
-@@ -4,9 +4,9 @@
- readonly disabled: boolean;
- readonly enabled: boolean;
- readonly errors: ValidationErrors | null;
- readonly invalid: boolean;
-- readonly parent: FormGroup | FormArray;
-+ readonly parent: FormGroup | FormArray | undefined;
- readonly pending: boolean;
- readonly pristine: boolean;
- readonly root: AbstractControl;
- readonly status: string;
If you modify a public API, you must accept the new golden file.
To do so, execute the following Bazel target:
- yarn bazel run //tools/public_api_guard:forms_api.accept
+ yarn bazel run //packages/core:core_api.accept
+
```
diff --git a/goldens/size-tracking/aio-payloads.json b/goldens/size-tracking/aio-payloads.json
index 3189fe1905..b2733035ab 100755
--- a/goldens/size-tracking/aio-payloads.json
+++ b/goldens/size-tracking/aio-payloads.json
@@ -12,7 +12,7 @@
"master": {
"uncompressed": {
"runtime-es2015": 2987,
- "main-es2015": 451406,
+ "main-es2015": 450883,
"polyfills-es2015": 52630
}
}
@@ -21,7 +21,7 @@
"master": {
"uncompressed": {
"runtime-es2015": 3097,
- "main-es2015": 429710,
+ "main-es2015": 429200,
"polyfills-es2015": 52195
}
}
diff --git a/goldens/size-tracking/integration-payloads.json b/goldens/size-tracking/integration-payloads.json
index bc40e78b62..cf8bdc7286 100644
--- a/goldens/size-tracking/integration-payloads.json
+++ b/goldens/size-tracking/integration-payloads.json
@@ -30,7 +30,7 @@
"master": {
"uncompressed": {
"runtime-es2015": 1485,
- "main-es2015": 136302,
+ "main-es2015": 135533,
"polyfills-es2015": 37248
}
}
@@ -39,7 +39,7 @@
"master": {
"uncompressed": {
"runtime-es2015": 2289,
- "main-es2015": 246085,
+ "main-es2015": 245488,
"polyfills-es2015": 36938,
"5-es2015": 751
}
@@ -62,7 +62,7 @@
"bundle": "TODO(i): we should define ngDevMode to false in Closure, but --define only works in the global scope.",
"bundle": "TODO(i): (FW-2164) TS 3.9 new class shape seems to have broken Closure in big ways. The size went from 169991 to 252338",
"bundle": "TODO(i): after removal of tsickle from ngc-wrapped / ng_package, we had to switch to SIMPLE optimizations which increased the size from 252338 to 1198917, see PR#37221 and PR#37317 for more info",
- "bundle": 1209688
+ "bundle": 1209659
}
}
}
diff --git a/karma-js.conf.js b/karma-js.conf.js
index ce31b84a83..bdab6ea463 100644
--- a/karma-js.conf.js
+++ b/karma-js.conf.js
@@ -43,7 +43,7 @@ module.exports = function(config) {
// Including systemjs because it defines `__eval`, which produces correct stack traces.
'test-events.js',
- 'shims_for_IE.js',
+ 'third_party/shims_for_IE.js',
'node_modules/systemjs/dist/system.src.js',
// Serve polyfills necessary for testing the `elements` package.
diff --git a/packages/compiler-cli/src/ngtsc/util/src/typescript.ts b/packages/compiler-cli/src/ngtsc/util/src/typescript.ts
index ee64a577ec..13a90d3a3e 100644
--- a/packages/compiler-cli/src/ngtsc/util/src/typescript.ts
+++ b/packages/compiler-cli/src/ngtsc/util/src/typescript.ts
@@ -125,10 +125,11 @@ export function resolveModuleName(
compilerHost: ts.ModuleResolutionHost&Pick,
moduleResolutionCache: ts.ModuleResolutionCache|null): ts.ResolvedModule|undefined {
if (compilerHost.resolveModuleNames) {
- // FIXME: Additional parameters are required in TS3.6, but ignored in 3.5.
- // Remove the any cast once google3 is fully on TS3.6.
- return (compilerHost as any)
- .resolveModuleNames([moduleName], containingFile, undefined, undefined, compilerOptions)[0];
+ return compilerHost.resolveModuleNames(
+ [moduleName], containingFile,
+ undefined, // reusedNames
+ undefined, // redirectedReference
+ compilerOptions)[0];
} else {
return ts
.resolveModuleName(
diff --git a/packages/core/src/render3/component_ref.ts b/packages/core/src/render3/component_ref.ts
index 58a22cd490..e12a2d854c 100644
--- a/packages/core/src/render3/component_ref.ts
+++ b/packages/core/src/render3/component_ref.ts
@@ -229,7 +229,7 @@ export class ComponentFactory extends viewEngine_ComponentFactory {
createElementRef(viewEngine_ElementRef, tElementNode, rootLView), rootLView, tElementNode);
// The host element of the internal root view is attached to the component's host view node.
- ngDevMode && assertNodeOfPossibleTypes(rootTView.node, TNodeType.View);
+ ngDevMode && assertNodeOfPossibleTypes(rootTView.node, [TNodeType.View]);
rootTView.node!.child = tElementNode;
return componentRef;
diff --git a/packages/core/src/render3/di.ts b/packages/core/src/render3/di.ts
index 0ce15a35ad..5aee59cdd6 100644
--- a/packages/core/src/render3/di.ts
+++ b/packages/core/src/render3/di.ts
@@ -99,8 +99,12 @@ let nextNgElementId = 0;
export function bloomAdd(
injectorIndex: number, tView: TView, type: Type|InjectionToken|string): void {
ngDevMode && assertEqual(tView.firstCreatePass, true, 'expected firstCreatePass to be true');
- let id: number|undefined =
- typeof type !== 'string' ? (type as any)[NG_ELEMENT_ID] : type.charCodeAt(0) || 0;
+ let id: number|undefined;
+ if (typeof type === 'string') {
+ id = type.charCodeAt(0) || 0;
+ } else if (type.hasOwnProperty(NG_ELEMENT_ID)) {
+ id = (type as any)[NG_ELEMENT_ID];
+ }
// Set a unique ID on the directive type, so if something tries to inject the directive,
// we can easily retrieve the ID and hash it into the bloom bit that should be checked.
@@ -267,7 +271,7 @@ export function diPublicInInjector(
export function injectAttributeImpl(tNode: TNode, attrNameToInject: string): string|null {
ngDevMode &&
assertNodeOfPossibleTypes(
- tNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
+ tNode, [TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer]);
ngDevMode && assertDefined(tNode, 'expecting tNode');
if (attrNameToInject === 'class') {
return tNode.classes;
@@ -584,7 +588,9 @@ export function bloomHashBitOrFactory(token: Type|InjectionToken|strin
if (typeof token === 'string') {
return token.charCodeAt(0) || 0;
}
- const tokenId: number|undefined = (token as any)[NG_ELEMENT_ID];
+ const tokenId: number|undefined =
+ // First check with `hasOwnProperty` so we don't get an inherited ID.
+ token.hasOwnProperty(NG_ELEMENT_ID) ? (token as any)[NG_ELEMENT_ID] : undefined;
// Negative token IDs are used for special objects such as `Injector`
return (typeof tokenId === 'number' && tokenId > 0) ? tokenId & BLOOM_MASK : tokenId;
}
diff --git a/packages/core/src/render3/i18n.ts b/packages/core/src/render3/i18n.ts
index 6c0c5ec7b1..1377482c80 100644
--- a/packages/core/src/render3/i18n.ts
+++ b/packages/core/src/render3/i18n.ts
@@ -9,7 +9,7 @@ import '../util/ng_i18n_closure_mode';
import {DEFAULT_LOCALE_ID, getPluralCase} from '../i18n/localization';
import {getTemplateContent, SRCSET_ATTRS, URI_ATTRS, VALID_ATTRS, VALID_ELEMENTS} from '../sanitization/html_sanitizer';
-import {InertBodyHelper} from '../sanitization/inert_body';
+import {getInertBodyHelper} from '../sanitization/inert_body';
import {_sanitizeUrl, sanitizeSrcset} from '../sanitization/url_sanitizer';
import {addAllToArray} from '../util/array_utils';
import {assertDataInRange, assertDefined, assertEqual} from '../util/assert';
@@ -1233,7 +1233,7 @@ function icuStart(
function parseIcuCase(
unsafeHtml: string, parentIndex: number, nestedIcus: IcuExpression[], tIcus: TIcu[],
expandoStartIndex: number): IcuCase {
- const inertBodyHelper = new InertBodyHelper(getDocument());
+ const inertBodyHelper = getInertBodyHelper(getDocument());
const inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
if (!inertBodyElement) {
throw new Error('Unable to generate inert body element');
diff --git a/packages/core/src/render3/instructions/di.ts b/packages/core/src/render3/instructions/di.ts
index ce4110fe21..075ed38037 100644
--- a/packages/core/src/render3/instructions/di.ts
+++ b/packages/core/src/render3/instructions/di.ts
@@ -9,8 +9,7 @@ import {InjectFlags, InjectionToken, resolveForwardRef} from '../../di';
import {ɵɵinject} from '../../di/injector_compatibility';
import {Type} from '../../interface/type';
import {getOrCreateInjectable, injectAttributeImpl} from '../di';
-import {TDirectiveHostNode, TNodeType} from '../interfaces/node';
-import {assertNodeOfPossibleTypes} from '../node_assert';
+import {TDirectiveHostNode} from '../interfaces/node';
import {getLView, getPreviousOrParentTNode} from '../state';
/**
diff --git a/packages/core/src/render3/instructions/listener.ts b/packages/core/src/render3/instructions/listener.ts
index 0ed0540288..3a8daffc70 100644
--- a/packages/core/src/render3/instructions/listener.ts
+++ b/packages/core/src/render3/instructions/listener.ts
@@ -128,7 +128,7 @@ function listenerInternal(
ngDevMode &&
assertNodeOfPossibleTypes(
- tNode, TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer);
+ tNode, [TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer]);
let processOutputs = true;
diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts
index 1ca8a714d7..0afae0d5e6 100644
--- a/packages/core/src/render3/instructions/shared.ts
+++ b/packages/core/src/render3/instructions/shared.ts
@@ -15,6 +15,7 @@ import {assertDataInRange, assertDefined, assertDomNode, assertEqual, assertGrea
import {createNamedArrayType} from '../../util/named_array_type';
import {initNgDevMode} from '../../util/ng_dev_mode';
import {normalizeDebugBindingName, normalizeDebugBindingValue} from '../../util/ng_reflect';
+import {stringify} from '../../util/stringify';
import {assertFirstCreatePass, assertLContainer, assertLView} from '../assert';
import {attachPatchData} from '../context_discovery';
import {getFactoryDef} from '../definition';
@@ -272,7 +273,7 @@ export function assignTViewNodeToLView(
let tNode = tView.node;
if (tNode == null) {
ngDevMode && tParentNode &&
- assertNodeOfPossibleTypes(tParentNode, TNodeType.Element, TNodeType.Container);
+ assertNodeOfPossibleTypes(tParentNode, [TNodeType.Element, TNodeType.Container]);
tView.node = tNode = createTNode(
tView,
tParentNode as TElementNode | TContainerNode | null, //
@@ -794,22 +795,6 @@ export function storeCleanupWithContext(
}
}
-/**
- * Saves the cleanup function itself in LView.cleanupInstances.
- *
- * This is necessary for functions that are wrapped with their contexts, like in renderer2
- * listeners.
- *
- * On the first template pass, the index of the cleanup function is saved in TView.
- */
-export function storeCleanupFn(tView: TView, lView: LView, cleanupFn: Function): void {
- getLCleanup(lView).push(cleanupFn);
-
- if (tView.firstCreatePass) {
- getTViewCleanup(tView).push(lView[CLEANUP]!.length - 1, null);
- }
-}
-
/**
* Constructs a TNode object from the arguments.
*
@@ -1278,7 +1263,7 @@ function instantiateAllDirectives(
const isComponent = isComponentDef(def);
if (isComponent) {
- ngDevMode && assertNodeOfPossibleTypes(tNode, TNodeType.Element);
+ ngDevMode && assertNodeOfPossibleTypes(tNode, [TNodeType.Element]);
addComponentLogic(lView, tNode as TElementNode, def as ComponentDef);
}
@@ -1366,7 +1351,7 @@ function findDirectiveDefMatches(
ngDevMode && assertFirstCreatePass(tView);
ngDevMode &&
assertNodeOfPossibleTypes(
- tNode, TNodeType.Element, TNodeType.ElementContainer, TNodeType.Container);
+ tNode, [TNodeType.Element, TNodeType.ElementContainer, TNodeType.Container]);
const registry = tView.directiveRegistry;
let matches: any[]|null = null;
if (registry) {
@@ -1377,6 +1362,12 @@ function findDirectiveDefMatches(
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, viewData), tView, def.type);
if (isComponentDef(def)) {
+ ngDevMode &&
+ assertNodeOfPossibleTypes(
+ tNode, [TNodeType.Element],
+ `"${tNode.tagName}" tags cannot be used as component hosts. ` +
+ `Please use a different tag to activate the ${
+ stringify(def.type)} component.`);
if (tNode.flags & TNodeFlags.isComponentHost) throwMultipleComponentError(tNode);
markAsComponentHost(tView, tNode);
// The component is always stored first with directives after.
diff --git a/packages/core/src/render3/node_assert.ts b/packages/core/src/render3/node_assert.ts
index 895c52397d..59714e88df 100644
--- a/packages/core/src/render3/node_assert.ts
+++ b/packages/core/src/render3/node_assert.ts
@@ -26,12 +26,14 @@ export function assertNodeType(tNode: TNode, type: TNodeType): asserts tNode is
assertEqual(tNode.type, type, `should be a ${typeName(type)}`);
}
-export function assertNodeOfPossibleTypes(tNode: TNode|null, ...types: TNodeType[]): void {
+export function assertNodeOfPossibleTypes(
+ tNode: TNode|null, types: TNodeType[], message?: string): void {
assertDefined(tNode, 'should be called with a TNode');
const found = types.some(type => tNode.type === type);
assertEqual(
found, true,
- `Should be one of ${types.map(typeName).join(', ')} but got ${typeName(tNode.type)}`);
+ message ??
+ `Should be one of ${types.map(typeName).join(', ')} but got ${typeName(tNode.type)}`);
}
export function assertNodeNotOfTypes(tNode: TNode, types: TNodeType[], message?: string): void {
diff --git a/packages/core/src/render3/node_manipulation.ts b/packages/core/src/render3/node_manipulation.ts
index 4717bb70fd..c7ce0d2542 100644
--- a/packages/core/src/render3/node_manipulation.ts
+++ b/packages/core/src/render3/node_manipulation.ts
@@ -552,7 +552,7 @@ function getRenderParent(tView: TView, tNode: TNode, currentView: LView): REleme
} else {
// We are inserting a root element of the component view into the component host element and
// it should always be eager.
- ngDevMode && assertNodeOfPossibleTypes(hostTNode, TNodeType.Element);
+ ngDevMode && assertNodeOfPossibleTypes(hostTNode, [TNodeType.Element]);
return currentView[HOST];
}
} else {
@@ -698,10 +698,10 @@ export function appendChild(
*/
function getFirstNativeNode(lView: LView, tNode: TNode|null): RNode|null {
if (tNode !== null) {
- ngDevMode &&
- assertNodeOfPossibleTypes(
- tNode, TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer,
- TNodeType.IcuContainer, TNodeType.Projection);
+ ngDevMode && assertNodeOfPossibleTypes(tNode, [
+ TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer, TNodeType.IcuContainer,
+ TNodeType.Projection
+ ]);
const tNodeType = tNode.type;
if (tNodeType === TNodeType.Element) {
@@ -778,10 +778,10 @@ function applyNodes(
renderParent: RElement|null, beforeNode: RNode|null, isProjection: boolean) {
while (tNode != null) {
ngDevMode && assertTNodeForLView(tNode, lView);
- ngDevMode &&
- assertNodeOfPossibleTypes(
- tNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer,
- TNodeType.Projection, TNodeType.Projection, TNodeType.IcuContainer);
+ ngDevMode && assertNodeOfPossibleTypes(tNode, [
+ TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer, TNodeType.Projection,
+ TNodeType.IcuContainer
+ ]);
const rawSlotValue = lView[tNode.index];
const tNodeType = tNode.type;
if (isProjection) {
@@ -798,7 +798,7 @@ function applyNodes(
applyProjectionRecursive(
renderer, action, lView, tNode as TProjectionNode, renderParent, beforeNode);
} else {
- ngDevMode && assertNodeOfPossibleTypes(tNode, TNodeType.Element, TNodeType.Container);
+ ngDevMode && assertNodeOfPossibleTypes(tNode, [TNodeType.Element, TNodeType.Container]);
applyToElementOrContainer(action, renderer, renderParent, rawSlotValue, beforeNode);
}
}
diff --git a/packages/core/src/render3/query.ts b/packages/core/src/render3/query.ts
index 0e73f530db..63eaf2bd7d 100644
--- a/packages/core/src/render3/query.ts
+++ b/packages/core/src/render3/query.ts
@@ -326,7 +326,7 @@ function createSpecialToken(lView: LView, tNode: TNode, read: any): any {
} else if (read === ViewContainerRef) {
ngDevMode &&
assertNodeOfPossibleTypes(
- tNode, TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer);
+ tNode, [TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer]);
return createContainerRef(
ViewContainerRef, ViewEngine_ElementRef,
tNode as TElementNode | TContainerNode | TElementContainerNode, lView);
diff --git a/packages/core/src/render3/view_engine_compatibility.ts b/packages/core/src/render3/view_engine_compatibility.ts
index f39721f7e4..42e69cea5a 100644
--- a/packages/core/src/render3/view_engine_compatibility.ts
+++ b/packages/core/src/render3/view_engine_compatibility.ts
@@ -340,7 +340,7 @@ export function createContainerRef(
ngDevMode &&
assertNodeOfPossibleTypes(
- hostTNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
+ hostTNode, [TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer]);
let lContainer: LContainer;
const slotValue = hostView[hostTNode.index];
diff --git a/packages/core/src/render3/view_ref.ts b/packages/core/src/render3/view_ref.ts
index 4da248498a..f4df71d91d 100644
--- a/packages/core/src/render3/view_ref.ts
+++ b/packages/core/src/render3/view_ref.ts
@@ -11,7 +11,7 @@ import {ChangeDetectorRef as viewEngine_ChangeDetectorRef} from '../change_detec
import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_container_ref';
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, InternalViewRef as viewEngine_InternalViewRef} from '../linker/view_ref';
import {assertDefined} from '../util/assert';
-import {checkNoChangesInRootView, checkNoChangesInternal, detectChangesInRootView, detectChangesInternal, markViewDirty, storeCleanupFn} from './instructions/shared';
+import {checkNoChangesInRootView, checkNoChangesInternal, detectChangesInRootView, detectChangesInternal, markViewDirty, storeCleanupWithContext} from './instructions/shared';
import {CONTAINER_HEADER_OFFSET} from './interfaces/container';
import {TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node';
import {isLContainer} from './interfaces/type_checks';
@@ -88,7 +88,7 @@ export class ViewRef implements viewEngine_EmbeddedViewRef, viewEngine_Int
}
onDestroy(callback: Function) {
- storeCleanupFn(this._lView[TVIEW], this._lView, callback);
+ storeCleanupWithContext(this._lView[TVIEW], this._lView, null, callback);
}
/**
@@ -324,10 +324,10 @@ function collectNativeNodes(
tView: TView, lView: LView, tNode: TNode|null, result: any[],
isProjection: boolean = false): any[] {
while (tNode !== null) {
- ngDevMode &&
- assertNodeOfPossibleTypes(
- tNode, TNodeType.Element, TNodeType.Container, TNodeType.Projection,
- TNodeType.ElementContainer, TNodeType.IcuContainer);
+ ngDevMode && assertNodeOfPossibleTypes(tNode, [
+ TNodeType.Element, TNodeType.Container, TNodeType.Projection, TNodeType.ElementContainer,
+ TNodeType.IcuContainer
+ ]);
const lNode = lView[tNode.index];
if (lNode !== null) {
diff --git a/packages/core/src/sanitization/html_sanitizer.ts b/packages/core/src/sanitization/html_sanitizer.ts
index 4f79d98927..ab7bbbe836 100644
--- a/packages/core/src/sanitization/html_sanitizer.ts
+++ b/packages/core/src/sanitization/html_sanitizer.ts
@@ -7,7 +7,7 @@
*/
import {isDevMode} from '../util/is_dev_mode';
-import {InertBodyHelper} from './inert_body';
+import {getInertBodyHelper, InertBodyHelper} from './inert_body';
import {_sanitizeUrl, sanitizeSrcset} from './url_sanitizer';
function tagSet(tags: string): {[k: string]: boolean} {
@@ -245,7 +245,7 @@ let inertBodyHelper: InertBodyHelper;
export function _sanitizeHtml(defaultDoc: any, unsafeHtmlInput: string): string {
let inertBodyElement: HTMLElement|null = null;
try {
- inertBodyHelper = inertBodyHelper || new InertBodyHelper(defaultDoc);
+ inertBodyHelper = inertBodyHelper || getInertBodyHelper(defaultDoc);
// Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
let unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
diff --git a/packages/core/src/sanitization/inert_body.ts b/packages/core/src/sanitization/inert_body.ts
index 46f76eb8f4..62c6598df8 100644
--- a/packages/core/src/sanitization/inert_body.ts
+++ b/packages/core/src/sanitization/inert_body.ts
@@ -7,89 +7,29 @@
*/
/**
- * This helper class is used to get hold of an inert tree of DOM elements containing dirty HTML
+ * This helper is used to get hold of an inert tree of DOM elements containing dirty HTML
* that needs sanitizing.
- * Depending upon browser support we must use one of three strategies for doing this.
- * Support: Safari 10.x -> XHR strategy
- * Support: Firefox -> DomParser strategy
- * Default: InertDocument strategy
+ * Depending upon browser support we use one of two strategies for doing this.
+ * Default: DOMParser strategy
+ * Fallback: InertDocument strategy
*/
-export class InertBodyHelper {
- private inertDocument: Document;
-
- constructor(private defaultDoc: Document) {
- this.inertDocument = this.defaultDoc.implementation.createHTMLDocument('sanitization-inert');
- let inertBodyElement = this.inertDocument.body;
-
- if (inertBodyElement == null) {
- // usually there should be only one body element in the document, but IE doesn't have any, so
- // we need to create one.
- const inertHtml = this.inertDocument.createElement('html');
- this.inertDocument.appendChild(inertHtml);
- inertBodyElement = this.inertDocument.createElement('body');
- inertHtml.appendChild(inertBodyElement);
- }
-
- inertBodyElement.innerHTML = '';
- if (inertBodyElement.querySelector && !inertBodyElement.querySelector('svg')) {
- // We just hit the Safari 10.1 bug - which allows JS to run inside the SVG G element
- // so use the XHR strategy.
- this.getInertBodyElement = this.getInertBodyElement_XHR;
- return;
- }
-
- inertBodyElement.innerHTML = '