Compare commits
288 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c71d687db4 | |||
| 8c9b7110c3 | |||
| e2b99806ac | |||
| 014fac8ec4 | |||
| dbf1d9361e | |||
| f205fe384e | |||
| 33a6686806 | |||
| b283c0c6ac | |||
| 647f2a886d | |||
| b70a286f27 | |||
| 35e9257226 | |||
| ab529c6ded | |||
| 28e76d7c91 | |||
| 7ef0dab427 | |||
| 4b00690cea | |||
| 405e4dda92 | |||
| c7ede8b2f5 | |||
| 9f5a17138e | |||
| 609f6053c5 | |||
| f6475344a8 | |||
| 629fee8418 | |||
| a107cc5006 | |||
| a73687016c | |||
| ab38861e9a | |||
| 33b0d25bfd | |||
| a23850fa6f | |||
| 7b6d7764df | |||
| a33d85dcb7 | |||
| 988e51a2a0 | |||
| c3f2c67fa0 | |||
| 6abfe3b1a9 | |||
| d95019d487 | |||
| c05d50cd6f | |||
| 64170f1021 | |||
| e849855f0b | |||
| 159c97ec69 | |||
| 290a47d842 | |||
| 4cd546571d | |||
| 2a440e1064 | |||
| 616cdef474 | |||
| 7659dffa3f | |||
| c144e507f1 | |||
| a9075875c8 | |||
| 0e3e6d4336 | |||
| 0c39a46a88 | |||
| 989a8e126e | |||
| d44c8ee98c | |||
| 5ee235729c | |||
| 78cf9bfc0e | |||
| b70b80ba55 | |||
| 88732f0ca4 | |||
| 94726a49d9 | |||
| 50f8191fbf | |||
| d390041e5a | |||
| 1726b0308d | |||
| ba85d08158 | |||
| 4fdc93bcd5 | |||
| 3b1a25c433 | |||
| f8726052d9 | |||
| fd61a4628b | |||
| dd7e837f17 | |||
| 37b0bad470 | |||
| fa4bcf3621 | |||
| 0b6018b755 | |||
| 35148426f6 | |||
| c790e77146 | |||
| 4e6ea0e19c | |||
| 3edd07fa11 | |||
| e5948905d2 | |||
| ce76408a86 | |||
| 823ae417f5 | |||
| e19849e707 | |||
| 3e02e8fe95 | |||
| 57bd5b5480 | |||
| 7fdd0d773e | |||
| 47b7ba0d5e | |||
| 6ddd1e41be | |||
| 89e48aac4e | |||
| 01a19f33b5 | |||
| 4c7efc005a | |||
| ef81cf8400 | |||
| 419ffa2026 | |||
| 17d4b61905 | |||
| d73a0175cb | |||
| d57257514d | |||
| cc12be47ed | |||
| 45d6865c22 | |||
| c122f07149 | |||
| a27600c463 | |||
| b960aad863 | |||
| ed5065e958 | |||
| 9f63df9d1b | |||
| 985a215b10 | |||
| 774b4239ac | |||
| e67cb09404 | |||
| 5d64589e4c | |||
| d6391eed23 | |||
| e3aa2b59ba | |||
| a6eedbc2e8 | |||
| b7f2fd4739 | |||
| f8a2ad6e99 | |||
| 3ac0511aad | |||
| ef96158899 | |||
| e598634c10 | |||
| 58b2fc4f81 | |||
| b79b6c14de | |||
| 999bfac737 | |||
| cbe3a029fa | |||
| 81c99ac5b9 | |||
| 0c75267ebf | |||
| a44a4689ca | |||
| 33d0102304 | |||
| 5052d4c998 | |||
| 77eb4ca061 | |||
| 4f4f41016e | |||
| c881c3e0c6 | |||
| 0cbd73c6e9 | |||
| e923a76400 | |||
| 9f7227cb8f | |||
| 3657358270 | |||
| b7f67b4453 | |||
| 239d4f0c9e | |||
| a78144ac21 | |||
| f0f85dbe2f | |||
| 0147e0b85a | |||
| 8d93597a82 | |||
| 0e16654be4 | |||
| f8a6ebd977 | |||
| 69a83993b3 | |||
| 6025424fea | |||
| eba92cfa55 | |||
| 3055b924af | |||
| a768c90ee7 | |||
| 69085ea26e | |||
| e6d8f7459e | |||
| e76bebd409 | |||
| 88fb94693a | |||
| 2e27ca9ddf | |||
| 5775fd245e | |||
| 762f97e153 | |||
| a141478940 | |||
| c15965721e | |||
| eda86d5347 | |||
| c4b2f18709 | |||
| 43525988b8 | |||
| 3b1b4e20c1 | |||
| 6850ff18b6 | |||
| 55d694275b | |||
| 1fd63e9cff | |||
| e7782d4d04 | |||
| e205dcb21b | |||
| bb4a4016a9 | |||
| beedb685bf | |||
| 8902312e0f | |||
| bfb5f2ba59 | |||
| 89e860cc30 | |||
| 9d1acd6e92 | |||
| dc0c55c930 | |||
| a028943895 | |||
| 179c678e6b | |||
| 5f3742de6c | |||
| db4e46684b | |||
| 574a7bc666 | |||
| 6906ff0131 | |||
| cd96464335 | |||
| 028a1d0af7 | |||
| db8fb02f6a | |||
| eb31f2c775 | |||
| 7c9d37d798 | |||
| 897e8dbf08 | |||
| 72b107b2a7 | |||
| d00f9e85bb | |||
| 61007dced0 | |||
| 28a24b6f79 | |||
| f9aac834f5 | |||
| 84f16391a5 | |||
| dc6a02fa48 | |||
| a9dd754ad5 | |||
| e70167217b | |||
| 129639359a | |||
| a916047a83 | |||
| 6b97aec621 | |||
| 9eb7478e5d | |||
| 42263e167a | |||
| 1b631ae52e | |||
| bdd6d3c4d8 | |||
| 2646c4050d | |||
| 232ec657e8 | |||
| fdf4941d4b | |||
| a5f29f9127 | |||
| b721e5d9c8 | |||
| 56a21da3ce | |||
| 8483721f32 | |||
| 0510930a25 | |||
| a040fb720a | |||
| 5c8c2eb60c | |||
| b74a17e1e2 | |||
| 5a83e61c2a | |||
| e71e869112 | |||
| 4a01e5a532 | |||
| 073b168677 | |||
| d9b339fdbc | |||
| 8459ee46cb | |||
| 3de1bc6866 | |||
| 6baa3bcc57 | |||
| f1dc74fd1b | |||
| 0a8f6a71d8 | |||
| fd9bf3a214 | |||
| a97ac32241 | |||
| 9a6a4cca2f | |||
| 05fa8e23cd | |||
| a733525f70 | |||
| 3b2dbf5a65 | |||
| 23f914f101 | |||
| 333a925475 | |||
| bf884270af | |||
| 6e02e50fa1 | |||
| eb91efa80a | |||
| b8c0084c50 | |||
| 93dc65a674 | |||
| 73de8b6f8d | |||
| 662bca47f6 | |||
| 8dbeafea47 | |||
| 91b007e58f | |||
| da5ef5213a | |||
| 4a45910904 | |||
| 8432d75b9a | |||
| 243f573797 | |||
| d5edfde6ee | |||
| 36130b2e72 | |||
| ce672c6829 | |||
| 9aa47c1983 | |||
| ccc0902dd2 | |||
| 4837621df8 | |||
| 7dce62bb05 | |||
| d1721c3d51 | |||
| e58ff4a6dd | |||
| 92a1e59529 | |||
| 78e4af0f0a | |||
| 122478c202 | |||
| 354cd9cd57 | |||
| 43b604bedf | |||
| e7225dd06d | |||
| 76fd874039 | |||
| 0c82c10e59 | |||
| 8226327799 | |||
| 8f99946d1d | |||
| 09613c194a | |||
| aefee87074 | |||
| f7ba9d26cf | |||
| 3113d8414c | |||
| 1595c9dbc2 | |||
| 3eadaf0f2a | |||
| 3c46d3f518 | |||
| d3dce326d7 | |||
| 0dcae69aaf | |||
| 89dfb24b3a | |||
| 9d898982ad | |||
| 26ad8dd9f4 | |||
| b5ec30a929 | |||
| f93e5180be | |||
| 21532f8eb8 | |||
| 1e87b7b8c0 | |||
| 0c7fd4ac91 | |||
| 890cccfd49 | |||
| 7a976784c0 | |||
| a39f2ff92d | |||
| 85feab2053 | |||
| c5c7ec9cfb | |||
| 621f59897d | |||
| 9ec01367b7 | |||
| a80fa8d1a5 | |||
| a20cf31a39 | |||
| 83e9d68c43 | |||
| c130f25cec | |||
| 516e5b5c3e | |||
| ce0a1cbd46 | |||
| e4b0989cb2 | |||
| ae29f04f7b | |||
| a177abef1b | |||
| a5c57c7484 | |||
| 5ad2f5f18b | |||
| 242fec847e | |||
| 10040e99e9 | |||
| 1e58aa00b8 | |||
| dcf737ee56 | |||
| 44c0ed83a6 | |||
| 2a3db67cdf |
@@ -17,6 +17,7 @@ integration/cli-hello-world-ivy-i18n/node_modules
|
||||
integration/cli-hello-world-lazy/node_modules
|
||||
integration/cli-hello-world-mocha/node_modules
|
||||
integration/cli-signal-inputs/node_modules
|
||||
integration/platform-server-hydration/node_modules
|
||||
integration/defer/node_modules
|
||||
integration/dynamic-compiler/node_modules
|
||||
integration/forms/node_modules
|
||||
|
||||
@@ -60,6 +60,13 @@ build:release --stamp
|
||||
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
|
||||
build:snapshot-build --stamp
|
||||
|
||||
# Angular DevTools for Firefox releases *cannot* be stamped and `--config snapshot-build-firefox` is a no-op.
|
||||
# This is because Mozilla requires add-on source code to be uploaded and then they manually reproduce the build.
|
||||
# If we stamp the build based on Git information such as the current commit, then reproducing the build would require
|
||||
# uploading the entire `.git` directory. We already must upload the entire monorepo, and uploading `.git` as well
|
||||
# exceeds the max source file size. To address this, we just *don't* stamp Firefox builds of Angular DevTools.
|
||||
build:snapshot-build-firefox --nostamp
|
||||
|
||||
##########################################################
|
||||
# AIO architect build configuration #
|
||||
# See aio/angular.json for available configurations. #
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
load("//tools:defaults.bzl", "esbuild_checked_in")
|
||||
|
||||
exports_files([
|
||||
"tsconfig.json",
|
||||
])
|
||||
|
||||
esbuild_checked_in(
|
||||
name = "main",
|
||||
entry_point = "//.github/actions/deploy-docs-site/lib:main.ts",
|
||||
external = [
|
||||
"undici",
|
||||
],
|
||||
platform = "node",
|
||||
target = "node14",
|
||||
deps = [
|
||||
"//.github/actions/deploy-docs-site/lib",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
name: 'Deploy angular.dev site'
|
||||
description: 'Automatically deploy and set up redirects for angular.dev'
|
||||
author: 'Angular'
|
||||
inputs:
|
||||
serviceKey:
|
||||
description: 'The service key used for firebase deployments.'
|
||||
required: true
|
||||
configPath:
|
||||
description: 'The path to the firebase config file.'
|
||||
required: true
|
||||
distDir:
|
||||
description: 'The path to the firebase dist directory.'
|
||||
required: true
|
||||
runs:
|
||||
using: 'node20'
|
||||
main: 'main.js'
|
||||
@@ -0,0 +1,23 @@
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
|
||||
package(default_visibility = ["//.github/actions/deploy-docs-site:__subpackages__"])
|
||||
|
||||
exports_files([
|
||||
"main.ts",
|
||||
])
|
||||
|
||||
ts_library(
|
||||
name = "lib",
|
||||
srcs = glob(
|
||||
["*.ts"],
|
||||
),
|
||||
#tsconfig = "//.github/actions/deploy-docs-site:tsconfig.json",
|
||||
deps = [
|
||||
"@npm//@actions/core",
|
||||
"@npm//@actions/github",
|
||||
"@npm//@angular/ng-dev",
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/tmp",
|
||||
"@npm//tmp",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
import {fileSync} from 'tmp';
|
||||
import {writeSync} from 'fs';
|
||||
import {getInput, setSecret} from '@actions/core';
|
||||
|
||||
let credentialFilePath: undefined | string;
|
||||
|
||||
export function getCredentialFilePath(): string {
|
||||
if (credentialFilePath === undefined) {
|
||||
const tmpFile = fileSync({postfix: '.json'});
|
||||
writeSync(tmpFile.fd, getInput('serviceKey', {required: true}));
|
||||
setSecret(tmpFile.name);
|
||||
credentialFilePath = tmpFile.name;
|
||||
}
|
||||
return credentialFilePath;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import {cp, mkdtemp, readFile, rm, writeFile} from 'fs/promises';
|
||||
import {Deployment} from './deployments';
|
||||
import {join} from 'path';
|
||||
|
||||
import {tmpdir} from 'os';
|
||||
import {spawnSync} from 'child_process';
|
||||
import {getCredentialFilePath} from './credential';
|
||||
|
||||
export async function deployToFirebase(
|
||||
deployment: Deployment,
|
||||
configPath: string,
|
||||
distDirPath: string,
|
||||
) {
|
||||
if (deployment.destination == undefined) {
|
||||
console.log(`No deployment necessary for docs created from: ${deployment.branch}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Preparing for deployment to firebase...');
|
||||
|
||||
const tmpDeployDir = await mkdtemp(join(tmpdir(), 'deploy-directory'));
|
||||
const deployConfigPath = join(tmpDeployDir, 'firebase.json');
|
||||
|
||||
const config = JSON.parse(await readFile(configPath, {encoding: 'utf-8'})) as {
|
||||
hosting: {public: string};
|
||||
};
|
||||
config['hosting']['public'] = './dist';
|
||||
|
||||
await writeFile(deployConfigPath, JSON.stringify(config, null, 2));
|
||||
|
||||
await cp(distDirPath, join(tmpDeployDir, 'dist'), {recursive: true});
|
||||
spawnSync(`chmod 777 -R ${tmpDeployDir}`, {encoding: 'utf-8', shell: true});
|
||||
|
||||
firebase(
|
||||
`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`,
|
||||
tmpDeployDir,
|
||||
);
|
||||
firebase(
|
||||
`target:apply --config ${deployConfigPath} --project angular-dev-site hosting angular-docs ${deployment.destination}`,
|
||||
tmpDeployDir,
|
||||
);
|
||||
firebase(
|
||||
`deploy --config ${deployConfigPath} --project angular-dev-site --only hosting --non-interactive`,
|
||||
tmpDeployDir,
|
||||
);
|
||||
firebase(
|
||||
`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`,
|
||||
tmpDeployDir,
|
||||
);
|
||||
|
||||
await rm(tmpDeployDir, {recursive: true});
|
||||
}
|
||||
|
||||
export async function setupRedirect(deployment: Deployment) {
|
||||
if (deployment.redirect === undefined) {
|
||||
console.log(`No redirect necessary for docs created from: ${deployment.branch}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Preparing to set up redirect on firebase...');
|
||||
|
||||
const redirectConfig = JSON.stringify(
|
||||
{
|
||||
hosting: {
|
||||
target: 'angular-docs',
|
||||
redirects: [
|
||||
{
|
||||
type: 302,
|
||||
regex: '^(.*)$',
|
||||
destination: `${deployment.redirect.to}:1`,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
|
||||
const tmpRedirectDir = await mkdtemp(join(tmpdir(), 'redirect-directory'));
|
||||
const redirectConfigPath = join(tmpRedirectDir, 'firebase.json');
|
||||
|
||||
await writeFile(redirectConfigPath, redirectConfig);
|
||||
spawnSync(`chmod 777 -R ${tmpRedirectDir}`, {encoding: 'utf-8', shell: true});
|
||||
|
||||
firebase(
|
||||
`target:clear --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs`,
|
||||
tmpRedirectDir,
|
||||
);
|
||||
firebase(
|
||||
`target:apply --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs ${deployment.redirect.from}`,
|
||||
tmpRedirectDir,
|
||||
);
|
||||
firebase(
|
||||
`deploy --config ${redirectConfigPath} --project angular-dev-site --only hosting --non-interactive`,
|
||||
tmpRedirectDir,
|
||||
);
|
||||
firebase(
|
||||
`target:clear --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs`,
|
||||
tmpRedirectDir,
|
||||
);
|
||||
|
||||
await rm(tmpRedirectDir, {recursive: true});
|
||||
}
|
||||
|
||||
function firebase(cmd: string, cwd?: string) {
|
||||
spawnSync('npx', `-y firebase-tools@latest ${cmd}`.split(' '), {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
shell: true,
|
||||
stdio: 'inherit',
|
||||
env: {
|
||||
...process.env,
|
||||
GOOGLE_APPLICATION_CREDENTIALS: getCredentialFilePath(),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import {fetchLongTermSupportBranchesFromNpm, ActiveReleaseTrains} from '@angular/ng-dev';
|
||||
import {ReleaseConfig} from '@angular/ng-dev';
|
||||
import {GitClient} from '@angular/ng-dev';
|
||||
|
||||
export interface Deployment {
|
||||
branch: string;
|
||||
redirect?: {
|
||||
from: string;
|
||||
to: string;
|
||||
};
|
||||
destination?: string;
|
||||
}
|
||||
|
||||
export type Deployments = Map<string, Deployment>;
|
||||
|
||||
export async function getDeployments(): Promise<Deployments> {
|
||||
const {github} = await GitClient.get();
|
||||
const releaseTrains = await ActiveReleaseTrains.fetch({
|
||||
api: github,
|
||||
name: 'angular',
|
||||
owner: 'angular',
|
||||
nextBranchName: 'main',
|
||||
});
|
||||
const ltsBranches = await fetchLongTermSupportBranchesFromNpm({
|
||||
representativeNpmPackage: '@angular/core',
|
||||
} as ReleaseConfig);
|
||||
|
||||
const docSites = new Map<string, Deployment>();
|
||||
|
||||
[...ltsBranches.active, ...ltsBranches.inactive].forEach((branch) => {
|
||||
docSites.set(branch.name, {
|
||||
branch: branch.name,
|
||||
destination: `v${branch.version.major}-angular-dev`,
|
||||
});
|
||||
});
|
||||
|
||||
docSites.set(releaseTrains.latest.branchName, {
|
||||
branch: releaseTrains.latest.branchName,
|
||||
redirect: {
|
||||
from: `v${releaseTrains.latest.version.major}-angular-dev`,
|
||||
to: 'https://angular.dev',
|
||||
},
|
||||
destination: 'angular-dev-site',
|
||||
});
|
||||
|
||||
if (releaseTrains.releaseCandidate) {
|
||||
docSites.set(releaseTrains.next.branchName, {
|
||||
branch: releaseTrains.next.branchName,
|
||||
});
|
||||
|
||||
docSites.set(releaseTrains.releaseCandidate.branchName, {
|
||||
branch: releaseTrains.releaseCandidate.branchName,
|
||||
destination: 'next-angular-dev',
|
||||
redirect: {
|
||||
from: `v${releaseTrains.releaseCandidate.version.major}-angular-dev`,
|
||||
to: 'https://next.angular.dev',
|
||||
},
|
||||
});
|
||||
} else {
|
||||
docSites.set(releaseTrains.next.branchName, {
|
||||
branch: releaseTrains.next.branchName,
|
||||
destination: 'next-angular-dev',
|
||||
});
|
||||
}
|
||||
|
||||
return docSites;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import {getInput, setFailed} from '@actions/core';
|
||||
import {context} from '@actions/github';
|
||||
import {deployToFirebase, setupRedirect} from './deploy';
|
||||
import {getDeployments} from './deployments';
|
||||
import {GithubConfig, setConfig} from '@angular/ng-dev';
|
||||
|
||||
const refMatcher = /refs\/heads\/(.*)/;
|
||||
|
||||
async function deployDocs() {
|
||||
setConfig({
|
||||
github: <GithubConfig>{
|
||||
mainBranchName: 'main',
|
||||
name: 'angular',
|
||||
owner: 'angular',
|
||||
},
|
||||
});
|
||||
if (context.eventName !== 'push') {
|
||||
throw Error();
|
||||
}
|
||||
const matchedRef = context.ref.match(refMatcher);
|
||||
if (matchedRef === null) {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
const currentBranch = matchedRef[1];
|
||||
const configPath = getInput('configPath');
|
||||
const distDir = getInput('distDir');
|
||||
|
||||
const deployment = (await getDeployments()).get(currentBranch);
|
||||
if (deployment === undefined) {
|
||||
console.log(`Current branch (${currentBranch}) does not deploy a documentation site.`);
|
||||
console.log(`Exiting...`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log('Doc site deployment information');
|
||||
console.log('');
|
||||
console.log('Current Branch:');
|
||||
console.log(` ${deployment.branch}`);
|
||||
console.log('');
|
||||
console.log('Firebase Site:');
|
||||
if (deployment.destination === undefined) {
|
||||
console.log(' No deployment of a documenation site is necessary');
|
||||
} else {
|
||||
console.log(` Deploying to: ${deployment.destination}`);
|
||||
}
|
||||
console.log('');
|
||||
console.log('Redirect Configuration:');
|
||||
if (deployment.redirect === undefined) {
|
||||
console.log(' No redirects are necessary');
|
||||
} else {
|
||||
console.log(` From: ${deployment.redirect.from}`);
|
||||
console.log(` To: ${deployment.redirect.to}`);
|
||||
}
|
||||
|
||||
await deployToFirebase(deployment, configPath, distDir);
|
||||
await setupRedirect(deployment);
|
||||
}
|
||||
|
||||
// Only run if the action is executed in a repository with is in the Angular org. This is in place
|
||||
// to prevent the action from actually running in a fork of a repository with this action set up.
|
||||
if (context.repo.owner === 'angular') {
|
||||
deployDocs().catch((e: Error) => {
|
||||
setFailed(e.message);
|
||||
console.error(e);
|
||||
});
|
||||
} else {
|
||||
console.warn(
|
||||
'The action was skipped as this action is only meant to run in repos belonging to the Angular organization.',
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "Node16",
|
||||
"target": "es2020",
|
||||
"lib": ["es2021", "dom"],
|
||||
"experimentalDecorators": true,
|
||||
"strict": true,
|
||||
"outDir": "../../../dist/tsc-non-bazel-out",
|
||||
"skipLibCheck": true,
|
||||
"noImplicitOverride": true,
|
||||
// TODO(ESM): Remove this when Bazel also uses the Node resolution.
|
||||
"esModuleInterop": true,
|
||||
"noImplicitReturns": true,
|
||||
"jsx": "react",
|
||||
"jsxFactory": "h",
|
||||
"jsxFragmentFactory": "Fragment"
|
||||
},
|
||||
"exclude": []
|
||||
}
|
||||
@@ -21,16 +21,16 @@ jobs:
|
||||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'adev: preview'))
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build //adev:build
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
run: yarn bazel build //adev:build --config=release
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
pull-number: '${{github.event.pull_request.number}}'
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
|
||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
|
||||
with:
|
||||
token: '${{secrets.GITHUB_TOKEN}}'
|
||||
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs
|
||||
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs ${{env.PREVIEW_SITE}}
|
||||
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
github-token: '${{secrets.GITHUB_TOKEN}}'
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
|
||||
@@ -13,9 +13,9 @@ jobs:
|
||||
assistant_to_the_branch_manager:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
# Specify repository as the PR branch might be from a fork.
|
||||
repository: ${{steps.comment-branch.outputs.head_owner}}/${{steps.comment-branch.outputs.head_repo}}
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/yarn-install
|
||||
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
bazelrc: ./.bazelrc.user
|
||||
|
||||
|
||||
@@ -5,9 +5,6 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- '[0-9]+.[0-9]+.x'
|
||||
- 'browser-update-test'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -20,27 +17,160 @@ defaults:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Check code lint
|
||||
run: yarn -s tslint
|
||||
- name: Check for circular dependencies
|
||||
run: yarn -s ts-circular-deps:check
|
||||
- name: Validate pull approve configuration
|
||||
run: yarn -s ng-dev pullapprove verify
|
||||
- name: Validate angular robot configuration
|
||||
run: yarn -s ng-dev ngbot verify
|
||||
- name: Confirm code builds with typescript as expected
|
||||
run: yarn -s check-tooling-setup
|
||||
|
||||
devtools:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Run unit tests
|
||||
run: yarn devtools:test
|
||||
- name: Test build
|
||||
run: yarn devtools:build:chrome
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
run: yarn test:ci
|
||||
|
||||
adev:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev in fast mode to ensure it continues to work
|
||||
run: yarn bazel build //adev:build --fast_adev --config=release
|
||||
- name: Run tests
|
||||
run: yarn bazel test //adev:test
|
||||
|
||||
publish-snapshots:
|
||||
runs-on:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
|
||||
- run: yarn build
|
||||
- run: ./scripts/ci/publish-build-artifacts.sh
|
||||
|
||||
zone-js:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./node_modules
|
||||
./packages/zone.js/node_modules
|
||||
./packages/zone.js/test/typings/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: |
|
||||
yarn bazel build \
|
||||
//packages/zone.js/bundles:zone.umd.js \
|
||||
//packages/zone.js:npm_package \
|
||||
//packages/zone.js/test/closure:closure_js \
|
||||
|
||||
- run: |
|
||||
rm -Rf packages/zone.js/build
|
||||
rm -Rf packages/zone.js/test/extra/*.umd.js
|
||||
|
||||
mkdir -p packages/zone.js/build/
|
||||
mkdir -p packages/zone.js/build/test/
|
||||
|
||||
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs
|
||||
|
||||
# Install
|
||||
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
|
||||
# Run zone.js tools tests
|
||||
- run: yarn --cwd packages/zone.js promisefinallytest
|
||||
- run: yarn --cwd packages/zone.js jest:test
|
||||
- run: yarn --cwd packages/zone.js jest:nodetest
|
||||
- run: yarn --cwd packages/zone.js electrontest
|
||||
- run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive
|
||||
- run: yarn --cwd packages/zone.js/test/typings test
|
||||
|
||||
bazel-saucelabs:
|
||||
# TODO: Replace legacy job with Bazel saucelabs job.
|
||||
if: github.event_name == 'push'
|
||||
runs-on: ubuntu-latest-4core
|
||||
env:
|
||||
JOBS: 2
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
with:
|
||||
cache-node-modules: true
|
||||
# Checking out the pull request commit is intended here as we need to run the changed code tests.
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/saucelabs@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Set up Sauce Tunnel Daemon
|
||||
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
|
||||
env:
|
||||
@@ -50,50 +180,24 @@ jobs:
|
||||
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "fixme-saucelabs", ...)')
|
||||
yarn bazel test --config=saucelabs --jobs=$JOBS ${TESTS}
|
||||
|
||||
saucelabs:
|
||||
runs-on: ubuntu-latest-4core
|
||||
env:
|
||||
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
|
||||
adev-deploy:
|
||||
needs: [adev]
|
||||
if: needs.adev.result == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
cache-node-modules: true
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Starting Saucelabs tunnel service
|
||||
run: ./tools/saucelabs/sauce-service.sh run &
|
||||
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
|
||||
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
|
||||
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
|
||||
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
|
||||
# test in all supported browsers on Saucelabs anyway until this job can be removed.
|
||||
- name: Preparing Bazel-generated fixtures required in legacy tests
|
||||
run: |
|
||||
yarn bazel build //packages/core/test:downleveled_es5_fixture //packages/common/locales
|
||||
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
|
||||
mkdir -p dist/legacy-test-out/core/test/reflection/
|
||||
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
|
||||
dist/legacy-test-out/core/test/reflection/es5_downleveled_inheritance_fixture.js
|
||||
# Locale files are needed for i18n tests running within Saucelabs. These are added
|
||||
# directly as sources so that the TypeScript compilation of `/packages/tsconfig.json`
|
||||
# can succeed. Note that the base locale and currencies files are checked-in, so
|
||||
# we do not need to re-generate those through Bazel.
|
||||
mkdir -p packages/common/locales/extra
|
||||
cp dist/bin/packages/common/locales/*.ts packages/common/locales
|
||||
cp dist/bin/packages/common/locales/extra/*.ts packages/common/locales/extra
|
||||
- name: Build bundle of tests to run on Saucelabs
|
||||
run: node tools/legacy-saucelabs/build-saucelabs-test-bundle.mjs
|
||||
- name: Wait and confirm Saucelabs tunnel has connected
|
||||
run: ./tools/saucelabs/sauce-service.sh ready-wait
|
||||
timeout-minutes: 3
|
||||
- name: Running tests on Saucelabs.
|
||||
run: KARMA_WEB_TEST_MODE=SL_REQUIRED yarn karma start ./karma-js.conf.js --single-run
|
||||
- name: Stop Saucelabs tunnel service
|
||||
run: ./tools/saucelabs/sauce-service.sh stop
|
||||
|
||||
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build //adev:build --config=release
|
||||
- name: Deploy to firebase
|
||||
uses: ./.github/actions/deploy-docs-site
|
||||
with:
|
||||
serviceKey: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
|
||||
configPath: 'adev/firebase.json'
|
||||
distDir: 'dist/bin/adev/build/browser'
|
||||
|
||||
@@ -12,14 +12,14 @@ jobs:
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
post_approval_changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -13,8 +13,8 @@ jobs:
|
||||
statuses: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
run-tests-guide-url: http://go/angular-g3sync-start
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -9,6 +9,6 @@ jobs:
|
||||
status:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -22,15 +22,15 @@ jobs:
|
||||
version: ['https://next.angular.io/', 'https://angular.io/']
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Run basic e2e and deployment config tests.
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
name: Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Check code lint
|
||||
run: yarn -s tslint
|
||||
- name: Check for circular dependencies
|
||||
run: yarn -s ts-circular-deps:check
|
||||
- name: Validate pull approve configuration
|
||||
run: yarn -s ng-dev pullapprove verify
|
||||
- name: Validate angular robot configuration
|
||||
run: yarn -s ng-dev ngbot verify
|
||||
- name: Confirm code builds with typescript as expected
|
||||
run: yarn -s check-tooling-setup
|
||||
- name: Check commit message
|
||||
run: yarn ng-dev commit-message validate-range ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
|
||||
- name: Check code format
|
||||
run: yarn ng-dev format changed --check ${{ github.event.pull_request.base.sha }}
|
||||
|
||||
devtools:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Run unit tests
|
||||
run: yarn devtools:test
|
||||
- name: Test build
|
||||
run: yarn devtools:build:chrome
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
run: yarn test:ci
|
||||
|
||||
adev:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev in fast mode to ensure it continues to work
|
||||
run: yarn bazel build //adev:build --fast_adev --config=release
|
||||
- name: Run tests
|
||||
run: yarn bazel test //adev:test
|
||||
|
||||
zone-js:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./node_modules
|
||||
./packages/zone.js/node_modules
|
||||
./packages/zone.js/test/typings/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: |
|
||||
yarn bazel build \
|
||||
//packages/zone.js/bundles:zone.umd.js \
|
||||
//packages/zone.js:npm_package \
|
||||
//packages/zone.js/test/closure:closure_js \
|
||||
|
||||
- run: |
|
||||
rm -Rf packages/zone.js/build
|
||||
rm -Rf packages/zone.js/test/extra/*.umd.js
|
||||
|
||||
mkdir -p packages/zone.js/build/
|
||||
mkdir -p packages/zone.js/build/test/
|
||||
|
||||
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs
|
||||
|
||||
# Install
|
||||
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
|
||||
# Run zone.js tools tests
|
||||
- run: yarn --cwd packages/zone.js promisefinallytest
|
||||
- run: yarn --cwd packages/zone.js jest:test
|
||||
- run: yarn --cwd packages/zone.js jest:nodetest
|
||||
- run: yarn --cwd packages/zone.js electrontest
|
||||
- run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive
|
||||
- run: yarn --cwd packages/zone.js/test/typings test
|
||||
|
||||
saucelabs:
|
||||
runs-on: ubuntu-latest-4core
|
||||
env:
|
||||
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
- name: Starting Saucelabs tunnel service
|
||||
run: ./tools/saucelabs/sauce-service.sh run &
|
||||
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
|
||||
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
|
||||
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
|
||||
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
|
||||
# test in all supported browsers on Saucelabs anyway until this job can be removed.
|
||||
- name: Preparing Bazel-generated fixtures required in legacy tests
|
||||
run: |
|
||||
yarn bazel build //packages/core/test:downleveled_es5_fixture //packages/common/locales
|
||||
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
|
||||
mkdir -p dist/legacy-test-out/core/test/reflection/
|
||||
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
|
||||
dist/legacy-test-out/core/test/reflection/es5_downleveled_inheritance_fixture.js
|
||||
# Locale files are needed for i18n tests running within Saucelabs. These are added
|
||||
# directly as sources so that the TypeScript compilation of `/packages/tsconfig.json`
|
||||
# can succeed. Note that the base locale and currencies files are checked-in, so
|
||||
# we do not need to re-generate those through Bazel.
|
||||
mkdir -p packages/common/locales/extra
|
||||
cp dist/bin/packages/common/locales/*.ts packages/common/locales
|
||||
cp dist/bin/packages/common/locales/extra/*.ts packages/common/locales/extra
|
||||
- name: Build bundle of tests to run on Saucelabs
|
||||
run: node tools/legacy-saucelabs/build-saucelabs-test-bundle.mjs
|
||||
- name: Wait and confirm Saucelabs tunnel has connected
|
||||
run: ./tools/saucelabs/sauce-service.sh ready-wait
|
||||
timeout-minutes: 3
|
||||
- name: Running tests on Saucelabs.
|
||||
run: KARMA_WEB_TEST_MODE=SL_REQUIRED yarn karma start ./karma-js.conf.js --single-run
|
||||
- name: Stop Saucelabs tunnel service
|
||||
run: ./tools/saucelabs/sauce-service.sh stop
|
||||
@@ -25,12 +25,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout code'
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: 'Run analysis'
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -47,6 +47,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3
|
||||
uses: github/codeql-action/upload-sarif@f079b8493333aace61c81488f8bd40919487bd9f # v3.25.7
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
# Setting `persist-credentials: false` prevents the github-action account from being the
|
||||
# account that is attempted to be used for authentication, instead the remote is set to
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
env:
|
||||
ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN }}
|
||||
- name: Create a PR (if necessary)
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@1ebf18a3a60b182a3dbad12e9a149fd93af5c29b
|
||||
with:
|
||||
branch-prefix: update-cli-help
|
||||
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
|
||||
|
||||
@@ -24,6 +24,9 @@ export const format: FormatConfig = {
|
||||
'!packages/compiler-cli/test/compliance/test_cases/**/*.{js,ts}',
|
||||
// Ignore AIO as its pending removal.
|
||||
'!aio/**/*.{js,ts}',
|
||||
|
||||
// Ignore generated javascript file(s)
|
||||
'!.github/actions/deploy-docs-site/main.js',
|
||||
],
|
||||
},
|
||||
'buildifier': true,
|
||||
|
||||
@@ -1342,9 +1342,6 @@ groups:
|
||||
- dylhunn # Dylan Hunn
|
||||
- AndrewKushnir # Andrew Kushnir
|
||||
- atscott # Andrew Scott
|
||||
reviews:
|
||||
required: 1
|
||||
reviewed_for: optional
|
||||
labels:
|
||||
pending: 'requires: TGP'
|
||||
approved: 'requires: TGP'
|
||||
@@ -1370,13 +1367,9 @@ groups:
|
||||
- mturco # Matt Turco
|
||||
- neonstalwart # Ben Hockey
|
||||
- nicholasyu-google # Nicholas Yu
|
||||
- emspishak # Eric Spishak-Thomas
|
||||
- iteriani # Thomas Nguyen
|
||||
- tbondwilkinson # Tom Wilkinson
|
||||
- rahatarmanahmed # Rahat Ahmed
|
||||
reviews:
|
||||
required: 1
|
||||
reviewed_for: optional
|
||||
labels:
|
||||
pending: 'requires: TGP'
|
||||
approved: 'requires: TGP'
|
||||
|
||||
@@ -1,269 +1,71 @@
|
||||
<a name="18.0.0-rc.0"></a>
|
||||
# 18.0.0-rc.0 (2024-05-01)
|
||||
<a name="18.0.2"></a>
|
||||
# 18.0.2 (2024-06-05)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [44c0ed83a6](https://github.com/angular/angular/commit/44c0ed83a6499fa96f65a27bc5c926579c06b6d2) | fix | hide implementation details of ExperimentalPendingTasks ([#55516](https://github.com/angular/angular/pull/55516)) |
|
||||
| [a177abef1b](https://github.com/angular/angular/commit/a177abef1b0a0edc46dcca2d8c5c67669c55ff8f) | fix | render hooks should not specifically run outside the Angular zone ([#55399](https://github.com/angular/angular/pull/55399)) |
|
||||
| [a5c57c7484](https://github.com/angular/angular/commit/a5c57c7484f1dc3afab4ece4e969a4a7308cdeca) | fix | resolve error for multiple component instances that use fallback content ([#55478](https://github.com/angular/angular/pull/55478)) |
|
||||
| [78cf9bfc0e](https://github.com/angular/angular/commit/78cf9bfc0eb1e78c1f6d3a562e65982579698896) | fix | Do not migrate `HttpClientModule` imports on components. ([#56067](https://github.com/angular/angular/pull/56067)) |
|
||||
| [616cdef474](https://github.com/angular/angular/commit/616cdef4748d5112460cf58200832585856777d6) | fix | don't coerce all producers to consumers on liveness change ([#56140](https://github.com/angular/angular/pull/56140)) |
|
||||
| [2a440e1064](https://github.com/angular/angular/commit/2a440e1064bddc839df91dbe77fc27bb8bd15641) | fix | Fix shouldPreventDefaultBeforeDispatching bug ([#56188](https://github.com/angular/angular/pull/56188)) |
|
||||
| [290a47d842](https://github.com/angular/angular/commit/290a47d8427f4854234cb2b4244871eaf1f82c19) | fix | handle missing `withI18nSupport()` call for components that use i18n blocks ([#56175](https://github.com/angular/angular/pull/56175)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [f93e5180be](https://github.com/angular/angular/commit/f93e5180be1e20a59ff68f12853653f4f3282846) | fix | resolve multiple structural issues with HttpClient migration ([#55557](https://github.com/angular/angular/pull/55557)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [aefee87074](https://github.com/angular/angular/commit/aefee87074f4a5b2531f989a1876ace6e6616da4) | fix | Scroller should scroll as soon as change detection completes ([#55105](https://github.com/angular/angular/pull/55105)) |
|
||||
| [b70b80ba55](https://github.com/angular/angular/commit/b70b80ba55ff16a5dd10e07c7120b0d3aecd5d2d) | fix | do not generate aliased variables with the same name ([#56154](https://github.com/angular/angular/pull/56154)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.7"></a>
|
||||
# 17.3.7 (2024-05-01)
|
||||
<a name="18.0.1"></a>
|
||||
# 18.0.1 (2024-05-29)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [419ffa2026](https://github.com/angular/angular/commit/419ffa20265e4b9b5b1d92045ec40f59f5c4de2e) | fix | optimize track function that only passes $index ([#55872](https://github.com/angular/angular/pull/55872)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [51ac883167](https://github.com/angular/angular/commit/51ac8831670637b562dfa135bec1e27a0b49f21d) | fix | don't type check the bodies of control flow nodes in basic mode ([#55558](https://github.com/angular/angular/pull/55558)) |
|
||||
| [4c7efc005a](https://github.com/angular/angular/commit/4c7efc005a8d0d343f437007740254b1d35c718b) | fix | interpolatedSignalNotInvoked diagnostic for class, style, attribute and animation bindings ([#55969](https://github.com/angular/angular/pull/55969)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [af0eb846a5](https://github.com/angular/angular/commit/af0eb846a572d0e9de2c6bb7016ddd339473dc00) | fix | render hooks should not specifically run outside the Angular zone ([#55399](https://github.com/angular/angular/pull/55399)) |
|
||||
### router
|
||||
| [4e6ea0e19c](https://github.com/angular/angular/commit/4e6ea0e19c52c9aceb635accb379572c78a457da) | fix | handle elements with local refs in event replay serialization logic ([#56076](https://github.com/angular/angular/pull/56076)) |
|
||||
| [d73a0175cb](https://github.com/angular/angular/commit/d73a0175cb2d8c74e6bb877dc30eec07fd484fff) | fix | link errors to ADEV ([#55554](https://github.com/angular/angular/pull/55554)) |
|
||||
| [985a215b10](https://github.com/angular/angular/commit/985a215b102be2a58dd4d13e1c05399f58f3078e) | fix | typo in zoneless warning ([#55974](https://github.com/angular/angular/pull/55974)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [3eea50da64](https://github.com/angular/angular/commit/3eea50da644f6023e7f001b8738c54cb89aece4c) | fix | Scroller should scroll as soon as change detection completes ([#55105](https://github.com/angular/angular/pull/55105)) |
|
||||
| [ba85d08158](https://github.com/angular/angular/commit/ba85d081583277a5b7a04bc349a3a8d528467c52) | fix | handle empty ngSwitchCase ([#56105](https://github.com/angular/angular/pull/56105)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-next.6"></a>
|
||||
# 18.0.0-next.6 (2024-04-25)
|
||||
<a name="18.0.0"></a>
|
||||
# 18.0.0 (2024-05-22)
|
||||
|
||||
[Blog post "Angular v18 is now available"](http://goo.gle/angular-v18).
|
||||
|
||||
## Breaking Changes
|
||||
### animations
|
||||
- Deprecated `matchesElement` method has been removed from `AnimationDriver` as it is unused.
|
||||
### core
|
||||
- `async` has been removed, use `waitForAsync` instead.
|
||||
### http
|
||||
- By default we now prevent caching of HTTP requests that require authorization . To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`.
|
||||
|
||||
Example:
|
||||
```ts
|
||||
withHttpTransferCache({
|
||||
includeRequestsWithAuthHeaders: true,
|
||||
})
|
||||
```
|
||||
### platform-browser
|
||||
- Deprecated `StateKey`, `TransferState` and `makeStateKey` have been removed from `@angular/platform-browser`, use the same APIs from `@angular/core`.
|
||||
## Deprecations
|
||||
### common
|
||||
- `getCurrencySymbol`, `getLocaleCurrencyCode`, `getLocaleCurrencyName`, `getLocaleCurrencySymbol`, `getLocaleDateFormat`, `getLocaleDateTimeFormat`, `getLocaleDayNames`, `getLocaleDayPeriods`, `getLocaleDirection`, `getLocaleEraNames`, `getLocaleExtraDayPeriodRules`, `getLocaleExtraDayPeriods`, `getLocaleFirstDayOfWeek`, `getLocaleId`, `getLocaleMonthNames`, `getLocaleNumberFormat`, `getLocaleNumberSymbol`, `getLocalePluralCase`, `getLocaleTimeFormat`, `getLocaleWeekEndRange`, `getNumberOfCurrencyDigits`
|
||||
### http
|
||||
- `HttpClientModule`, `HttpClientXsrfModule` and `HttpClientJsonpModule`
|
||||
|
||||
As mentionned, those modules can be replaced by provider function only.
|
||||
### animations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [bcce85af72](https://github.com/angular/angular/commit/bcce85af72a82634f60b31d66a5ef42ecd844ce8) | refactor | remove deprecated `matchesElement` from `AnimationDriver` ([#55479](https://github.com/angular/angular/pull/55479)) |
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d34c033902](https://github.com/angular/angular/commit/d34c033902b4e7543796de6c57d0cfd09093eb43) | refactor | Deprecate Local Data API functions ([#54483](https://github.com/angular/angular/pull/54483)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [7a16d7e969](https://github.com/angular/angular/commit/7a16d7e969eaf5a9475ffdd21a4bf637ce523856) | fix | don't type check the bodies of control flow nodes in basic mode ([#55360](https://github.com/angular/angular/pull/55360)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a730f09ae9](https://github.com/angular/angular/commit/a730f09ae9e729da79a3e0951e15e0139ef67713) | feat | Add a public API to establish events to be replayed and an attribute to mark an element with an event handler. ([#55356](https://github.com/angular/angular/pull/55356)) |
|
||||
| [5f06ca8f55](https://github.com/angular/angular/commit/5f06ca8f5539ed208bae0b110887b5538ac4041f) | feat | add HOST_TAG_NAME token ([#54751](https://github.com/angular/angular/pull/54751)) |
|
||||
| [ac863ded48](https://github.com/angular/angular/commit/ac863ded4818af3426ef5888c706a2bd8c79c0be) | feat | provide ExperimentalPendingTasks API ([#55487](https://github.com/angular/angular/pull/55487)) |
|
||||
| [5a10f405d3](https://github.com/angular/angular/commit/5a10f405d315a28b9a000c669e9b1cb3fa24a7f1) | fix | complete the removal of deprecation `async` function ([#55491](https://github.com/angular/angular/pull/55491)) |
|
||||
| [c175bca364](https://github.com/angular/angular/commit/c175bca36432b26851adb4ea9d850c2d07fba864) | fix | DeferBlockFixture.render should not wait for stability ([#55271](https://github.com/angular/angular/pull/55271)) |
|
||||
| [9894278e71](https://github.com/angular/angular/commit/9894278e712a50079af87898a63e1d19a462d015) | fix | make `ActivatedRoute` inject correct instance inside `@defer` blocks ([#55374](https://github.com/angular/angular/pull/55374)) |
|
||||
| [5948193e13](https://github.com/angular/angular/commit/5948193e1368eec86647b4c1c0b337a387b27087) | fix | skip defer timers on the server ([#55480](https://github.com/angular/angular/pull/55480)) |
|
||||
### http
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [6f88d80758](https://github.com/angular/angular/commit/6f88d8075895bd80592b1b7e0fba8202a58a5417) | feat | allow caching requests with different origins between server and client ([#55274](https://github.com/angular/angular/pull/55274)) |
|
||||
| [8eacb6e4b9](https://github.com/angular/angular/commit/8eacb6e4b982a5aa23cfbf9078dc4e19d9466d73) | feat | exclude caching for authenticated HTTP requests ([#55034](https://github.com/angular/angular/pull/55034)) |
|
||||
| [ef665a40a5](https://github.com/angular/angular/commit/ef665a40a580ff4df79617084ac83738f28ae924) | refactor | Deprecate `HttpClientModule` & related modules ([#54020](https://github.com/angular/angular/pull/54020)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [f914f6a362](https://github.com/angular/angular/commit/f914f6a3628847c06cbdde9c90cd417fb2f4c61f) | feat | Migration schematics for `HttpClientModule` ([#54020](https://github.com/angular/angular/pull/54020)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [cba336d4f1](https://github.com/angular/angular/commit/cba336d4f1badd601b24a58fc51bde995f45682d) | refactor | remove deprecated transfer state APIs ([#55474](https://github.com/angular/angular/pull/55474)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [5674c644ab](https://github.com/angular/angular/commit/5674c644abf51ae8764befd3011742ff1febdf29) | fix | add `nonce` attribute to event record script ([#55495](https://github.com/angular/angular/pull/55495)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [4a42961393](https://github.com/angular/angular/commit/4a42961393b3abf40f34374df059d3959dadecc0) | feat | `withNavigationErrorHandler` can convert errors to redirects ([#55370](https://github.com/angular/angular/pull/55370)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.6"></a>
|
||||
# 17.3.6 (2024-04-25)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [826861b1fa](https://github.com/angular/angular/commit/826861b1fa7693010743f5dd881fb31ec33eee52) | fix | DeferBlockFixture.render should not wait for stability ([#55271](https://github.com/angular/angular/pull/55271)) |
|
||||
| [5cf14da35c](https://github.com/angular/angular/commit/5cf14da35cce1ea4456bae4365d3dbe6667b1881) | fix | make `ActivatedRoute` inject correct instance inside `@defer` blocks ([#55374](https://github.com/angular/angular/pull/55374)) |
|
||||
| [8979fba2c5](https://github.com/angular/angular/commit/8979fba2c5813673767a133caeec9ac768d17329) | fix | skip defer timers on the server ([#55480](https://github.com/angular/angular/pull/55480)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-next.5"></a>
|
||||
# 18.0.0-next.5 (2024-04-17)
|
||||
## Breaking Changes
|
||||
### common
|
||||
- The deprecated `isPlatformWorkerUi` and `isPlatformWorkerApp` have been removed without replacement, as they serve no purpose since the removal of the WebWorker platform.
|
||||
### compiler
|
||||
- Angular only supports writable expressions inside of two-way bindings.
|
||||
### core
|
||||
- Angular will ensure change detection runs, even when the state update originates from
|
||||
outside the zone, tests may observe additional rounds of change
|
||||
detection compared to the previous behavior.
|
||||
|
||||
This change will be more likely to impact existing unit tests.
|
||||
This should usually be seen as more correct and the test should be updated,
|
||||
but in cases where it is too much effort to debug, the test can revert to the old behavior by adding
|
||||
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
|
||||
to the `TestBed` providers.
|
||||
|
||||
Similarly, applications which may want to update state outside the zone
|
||||
and _not_ trigger change detection can add
|
||||
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
|
||||
to the providers in `bootstrapApplication` or add
|
||||
`schedulingMode: NgZoneSchedulingMode.NgZoneOnly` to the
|
||||
`BootstrapOptions` of `bootstrapModule`.
|
||||
- Testability methods `increasePendingRequestCount`,
|
||||
`decreasePendingRequestCount` and `getPendingRequestCount` have been
|
||||
removed. This information is tracked with zones.
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [3b0de30b37](https://github.com/angular/angular/commit/3b0de30b37f558d4815ca9a61db1010aaf3df068) | refactor | remove deprecated `isPlatformWorkerApp` and `isPlatformWorkerUi` API ([#55302](https://github.com/angular/angular/pull/55302)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [7d5bc1c628](https://github.com/angular/angular/commit/7d5bc1c62870d9c68e06eddec229a9b8988e92ee) | fix | remove container index from conditional instruction ([#55190](https://github.com/angular/angular/pull/55190)) |
|
||||
| [4eb0165750](https://github.com/angular/angular/commit/4eb0165750d8c65812502343a70ef4cc35c725b9) | fix | remove support for unassignable expressions in two-way bindings ([#55342](https://github.com/angular/angular/pull/55342)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [fdd560ea14](https://github.com/angular/angular/commit/fdd560ea14f2f35608e26102c7fac0471a634b3e) | feat | Add ability to configure zone change detection to use zoneless scheduler ([#55252](https://github.com/angular/angular/pull/55252)) |
|
||||
| [bce5e2344f](https://github.com/angular/angular/commit/bce5e2344f312dc3a8a30d54e412958bd07180c1) | feat | Add build target for jsaction contract binary. ([#55319](https://github.com/angular/angular/pull/55319)) |
|
||||
| [f09c5a7bc4](https://github.com/angular/angular/commit/f09c5a7bc455a59aea133264cbf9fd9ef7509a7f) | feat | Add zoneless change detection provider as experimental ([#55329](https://github.com/angular/angular/pull/55329)) |
|
||||
| [d28614b90e](https://github.com/angular/angular/commit/d28614b90eff835639747e8961fe61e874c44666) | feat | Modify EventType from an enum to an object. ([#55323](https://github.com/angular/angular/pull/55323)) |
|
||||
| [1ee9f32621](https://github.com/angular/angular/commit/1ee9f32621f6d72e8038a08f5ad4a0cfe8bd6a13) | feat | Synchronize changes from internal JSAction codebase. ([#55182](https://github.com/angular/angular/pull/55182)) |
|
||||
| [de7447d15e](https://github.com/angular/angular/commit/de7447d15ed964ae26f0dace4cb3b08f5cccb1c1) | fix | Angular should not ignore changes that happen outside the zone ([#55102](https://github.com/angular/angular/pull/55102)) |
|
||||
| [0cec9e4f9a](https://github.com/angular/angular/commit/0cec9e4f9a90ec59f0e9838dcbd82705b1709fc0) | fix | Fix null dereference error `addEvent` ([#55353](https://github.com/angular/angular/pull/55353)) |
|
||||
| [6534c035c0](https://github.com/angular/angular/commit/6534c035c099b30987d6fd1346aea454b79cc79d) | fix | Remove deprecated Testability methods ([#53768](https://github.com/angular/angular/pull/53768)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [3bc63eaaf3](https://github.com/angular/angular/commit/3bc63eaaf344712ac6de1c9618d4558d9443c848) | fix | avoid running CDs on `controllerchange` ([#54222](https://github.com/angular/angular/pull/54222)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.5"></a>
|
||||
# 17.3.5 (2024-04-17)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-next.4"></a>
|
||||
# 18.0.0-next.4 (2024-04-10)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2a6f809507](https://github.com/angular/angular/commit/2a6f80950756530d5fb1147addabcb31025b0a78) | fix | invalid ImageKit quality parameter ([#55193](https://github.com/angular/angular/pull/55193)) |
|
||||
| [11705f58a7](https://github.com/angular/angular/commit/11705f58a77e9390163b0bc99439fb4c8928e531) | fix | skip transfer cache on client ([#55012](https://github.com/angular/angular/pull/55012)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [39624c6b12](https://github.com/angular/angular/commit/39624c6b129252af352c22c6d6f12ef153477bfc) | fix | output input flags as a literal ([#55215](https://github.com/angular/angular/pull/55215)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [bd236cc150](https://github.com/angular/angular/commit/bd236cc150e1b21932612ecf91678be77a503d18) | fix | implement getDefinitionAtPosition for Angular templates ([#55269](https://github.com/angular/angular/pull/55269)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.4"></a>
|
||||
# 17.3.4 (2024-04-10)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [53427d875d](https://github.com/angular/angular/commit/53427d875d33de16b1dbb04e76a9fe32a2b8a445) | fix | invalid ImageKit quality parameter ([#55193](https://github.com/angular/angular/pull/55193)) |
|
||||
| [766548c3ec](https://github.com/angular/angular/commit/766548c3ecc06ffd8f06ed9a7d0cbb3db6f1b0f6) | fix | skip transfer cache on client ([#55012](https://github.com/angular/angular/pull/55012)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-next.3"></a>
|
||||
# 18.0.0-next.3 (2024-04-03)
|
||||
## Breaking Changes
|
||||
### router
|
||||
- Providers available to the routed components always
|
||||
come from the injector heirarchy of the routes and never inherit from
|
||||
the `RouterOutlet`. This means that providers available only to the
|
||||
component that defines the `RouterOutlet` will no longer be available to
|
||||
route components in any circumstances. This was already the case
|
||||
whenever routes defined providers, either through lazy loading an
|
||||
`NgModule` or through explicit `providers` on the route config.
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [f824911510](https://github.com/angular/angular/commit/f8249115102204dbb957a0d292ed5342ea5108e9) | fix | For `FatalDiagnosticError`, hide the `message` field without affecting the emit ([#55160](https://github.com/angular/angular/pull/55160)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c04ffb1fa6](https://github.com/angular/angular/commit/c04ffb1fa61f5164ee5eb7c05b7d76292042ff0b) | fix | use switch statements to narrow Angular switch blocks ([#55168](https://github.com/angular/angular/pull/55168)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [666d646575](https://github.com/angular/angular/commit/666d646575800e9326eebd513776f8e92b0357e9) | feat | Add event delegation library to queue up events and replay them when the application is ready ([#55121](https://github.com/angular/angular/pull/55121)) |
|
||||
| [146306a141](https://github.com/angular/angular/commit/146306a1417c378920d80a6d91fd847f22e407ab) | feat | add support for i18n hydration ([#54823](https://github.com/angular/angular/pull/54823)) |
|
||||
| [840c375255](https://github.com/angular/angular/commit/840c375255dc381674bb27746d9ababd14567c33) | fix | do not save point-in-time `setTimeout` and `rAF` references ([#55124](https://github.com/angular/angular/pull/55124)) |
|
||||
| [231e0a3528](https://github.com/angular/angular/commit/231e0a3528e152cb1de3a215d437f5104191445c) | fix | handle `ChainedInjector`s in injector debug utils ([#55144](https://github.com/angular/angular/pull/55144)) |
|
||||
| [a5fa279b6e](https://github.com/angular/angular/commit/a5fa279b6e9f5ab4005d6d33107f0e1bb48d05de) | fix | prevent i18n hydration from cleaning projected nodes ([#54823](https://github.com/angular/angular/pull/54823)) |
|
||||
| [f44a5e4604](https://github.com/angular/angular/commit/f44a5e460491a29e5c0cad5577bade8347d52e11) | fix | support content projection and VCRs in i18n ([#54823](https://github.com/angular/angular/pull/54823)) |
|
||||
| [914e4530b0](https://github.com/angular/angular/commit/914e4530b036eb20eb553dbb47f89183458066f4) | fix | test cleanup should not throw if Zone is not present ([#55096](https://github.com/angular/angular/pull/55096)) |
|
||||
| [a99cb7ce5b](https://github.com/angular/angular/commit/a99cb7ce5b77a125ab660da8ebef23ecb158e2e3) | fix | zoneless scheduler should check if Zone is defined before accessing it ([#55118](https://github.com/angular/angular/pull/55118)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [1c736dc3b2](https://github.com/angular/angular/commit/1c736dc3b258a502360cda40b3a00c07102ccbf5) | feat | Unified Control State Change Events ([#54579](https://github.com/angular/angular/pull/54579)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a48afe0d94](https://github.com/angular/angular/commit/a48afe0d9478aca314e68552f4af77f4123563cd) | fix | avoid generating TS syntactic diagnostics for templates ([#55091](https://github.com/angular/angular/pull/55091)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0c20c4075a](https://github.com/angular/angular/commit/0c20c4075af753d8e5eaecb5f7114a48ced5ad96) | fix | avoid conflicts with some greek letters in control flow migration ([#55113](https://github.com/angular/angular/pull/55113)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [45ae7a6b60](https://github.com/angular/angular/commit/45ae7a6b60019bd49b8a58122a0d5bcbda7e245b) | feat | add withI18nSupport() in developer preview ([#55130](https://github.com/angular/angular/pull/55130)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [87f3f27f90](https://github.com/angular/angular/commit/87f3f27f9087d757e18e8e2a0f2fca6f2a2c7edf) | feat | Allow resolvers to return `RedirectCommand` ([#54556](https://github.com/angular/angular/pull/54556)) |
|
||||
| [3839cfbb18](https://github.com/angular/angular/commit/3839cfbb18fcc70cae5a6ba4ba7676b1c4acf7a0) | fix | Routed components never inherit `RouterOutlet` `EnvironmentInjector` ([#54265](https://github.com/angular/angular/pull/54265)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-next.2"></a>
|
||||
# 18.0.0-next.2 (2024-03-28)
|
||||
## Breaking Changes
|
||||
### compiler-cli
|
||||
- * Angular no longer supports TypeScript versions older than 5.4.
|
||||
### core
|
||||
- `OnPush` views at the root of the application need to
|
||||
be marked dirty for their host bindings to refresh. Previously, the host
|
||||
bindings were refreshed for all root views without respecting the
|
||||
`OnPush` change detection strategy.
|
||||
- `OnPush` views at the root of the application need to
|
||||
be marked dirty for their host bindings to refresh. Previously, the host
|
||||
bindings were refreshed for all root views without respecting the
|
||||
`OnPush` change detection strategy.
|
||||
- The `ComponentFixture` `autoDetect` feature will no
|
||||
longer refresh the component's host view when the component is `OnPush`
|
||||
and not marked dirty. This exposes existing issues in components which
|
||||
claim to be `OnPush` but do not correctly call `markForCheck` when they
|
||||
need to be refreshed. If this change causes test failures, the easiest
|
||||
fix is to change the component to `ChangeDetectionStrategy.Default`.
|
||||
- `ComponentFixture.whenStable` now matches the
|
||||
`ApplicationRef.isStable` observable. Prior to this change, stability
|
||||
of the fixture did not include everything that was considered in
|
||||
@@ -280,19 +82,142 @@
|
||||
|
||||
In addition, `ComponentFixture.isStable` would synchronously switch to
|
||||
true in some scenarios but will now always be asynchronous.
|
||||
- Angular will ensure change detection runs, even when the state update originates from
|
||||
outside the zone, tests may observe additional rounds of change
|
||||
detection compared to the previous behavior.
|
||||
|
||||
This change will be more likely to impact existing unit tests.
|
||||
This should usually be seen as more correct and the test should be updated,
|
||||
but in cases where it is too much effort to debug, the test can revert to the old behavior by adding
|
||||
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
|
||||
to the `TestBed` providers.
|
||||
|
||||
Similarly, applications which may want to update state outside the zone
|
||||
and _not_ trigger change detection can add
|
||||
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
|
||||
to the providers in `bootstrapApplication` or add
|
||||
`schedulingMode: NgZoneSchedulingMode.NgZoneOnly` to the
|
||||
`BootstrapOptions` of `bootstrapModule`.
|
||||
- When Angular runs change detection, it will continue to
|
||||
refresh any views attached to `ApplicationRef` that are still marked for
|
||||
check after one round completes. In rare cases, this can result in infinite
|
||||
loops when certain patterns continue to mark views for check using
|
||||
`ChangeDetectorRef.detectChanges`. This will be surfaced as a runtime
|
||||
error with the `NG0103` code.
|
||||
- `async` has been removed, use `waitForAsync` instead.
|
||||
- The `ComponentFixture.autoDetect` feature now executes
|
||||
change detection for the fixture within `ApplicationRef.tick`. This more
|
||||
closely matches the behavior of how a component would refresh in
|
||||
production. The order of component refresh in tests may be slightly
|
||||
affected as a result, especially when dealing with additional components
|
||||
attached to the application, such as dialogs. Tests sensitive to this
|
||||
type of change (such as screenshot tests) may need to be updated.
|
||||
Concretely, this change means that the component will refresh _before_
|
||||
additional views attached to `ApplicationRef` (i.e. dialog components).
|
||||
Prior to this change, the fixture component would refresh _after_ other
|
||||
views attached to the application.
|
||||
- The exact timing of change detection execution when
|
||||
using event or run coalescing with `NgZone` is now the first of either
|
||||
`setTimeout` or `requestAnimationFrame`. Code which relies on this
|
||||
timing (usually by accident) will need to be adjusted. If a callback
|
||||
needs to execute after change detection, we recommend `afterNextRender`
|
||||
instead of something like `setTimeout`.
|
||||
- Newly created and views marked for check and reattached
|
||||
during change detection are now guaranteed to be refreshed in that same
|
||||
change detection cycle. Previously, if they were attached at a location
|
||||
in the view tree that was already checked, they would either throw
|
||||
`ExpressionChangedAfterItHasBeenCheckedError` or not be refreshed until
|
||||
some future round of change detection. In rare circumstances, this
|
||||
correction can cause issues. We identified one instance that relied on
|
||||
the previous behavior by reading a value on initialization which was
|
||||
queued to be updated in a microtask instead of being available in the
|
||||
current change detection round. The component only read this value during
|
||||
initialization and did not read it again after the microtask updated it.
|
||||
- Testability methods `increasePendingRequestCount`,
|
||||
`decreasePendingRequestCount` and `getPendingRequestCount` have been
|
||||
removed. This information is tracked with zones.
|
||||
### http
|
||||
- By default we now prevent caching of HTTP requests that require authorization . To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`.
|
||||
|
||||
Example:
|
||||
```ts
|
||||
withHttpTransferCache({
|
||||
includeRequestsWithAuthHeaders: true,
|
||||
})
|
||||
```
|
||||
### platform-browser
|
||||
- Deprecated `StateKey`, `TransferState` and `makeStateKey` have been removed from `@angular/platform-browser`, use the same APIs from `@angular/core`.
|
||||
### platform-browser-dynamic
|
||||
- No longer used `RESOURCE_CACHE_PROVIDER` APIs have been removed.
|
||||
### platform-server
|
||||
- deprecated `platformDynamicServer` has been removed. Add an `import @angular/compiler` and replace the usage with `platformServer`
|
||||
- deprecated `ServerTransferStateModule` has been removed. `TransferState` can be use without providing this module.
|
||||
- deprecated `useAbsoluteUrl` and `baseUrl` been removed from `PlatformConfig`. Provide and absolute `url` instead.
|
||||
- Legacy handling or Node.js URL parsing has been removed from `ServerPlatformLocation`.
|
||||
|
||||
The main differences are;
|
||||
- `pathname` is always suffixed with a `/`.
|
||||
- `port` is empty when `http:` protocol and port in url is `80`
|
||||
- `port` is empty when `https:` protocol and port in url is `443`
|
||||
### router
|
||||
- Guards can now return `RedirectCommand` for redirects
|
||||
in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree`
|
||||
values in `Route` types will need to be adjusted.
|
||||
- This change allows `Route.redirectTo` to be a function
|
||||
in addition to the previous string. Code which expects `redirectTo` to
|
||||
only be a string on `Route` objects will need to be adjusted.
|
||||
- When a a guard returns a `UrlTree` as a redirect, the
|
||||
redirecting navigation will now use `replaceUrl` if the initial
|
||||
navigation was also using the `replaceUrl` option. If this is not
|
||||
desirable, the redirect can configure new `NavigationBehaviorOptions` by
|
||||
returning a `RedirectCommand` with the desired options instead of `UrlTree`.
|
||||
- Providers available to the routed components always
|
||||
come from the injector heirarchy of the routes and never inherit from
|
||||
the `RouterOutlet`. This means that providers available only to the
|
||||
component that defines the `RouterOutlet` will no longer be available to
|
||||
route components in any circumstances. This was already the case
|
||||
whenever routes defined providers, either through lazy loading an
|
||||
`NgModule` or through explicit `providers` on the route config.
|
||||
- Providers available to the routed components always
|
||||
come from the injector heirarchy of the routes and never inherit from
|
||||
the `RouterOutlet`. This means that providers available only to the
|
||||
component that defines the `RouterOutlet` will no longer be available to
|
||||
route components in any circumstances. This was already the case
|
||||
whenever routes defined providers, either through lazy loading an
|
||||
`NgModule` or through explicit `providers` on the route config.
|
||||
## Deprecations
|
||||
### common
|
||||
- `getCurrencySymbol`, `getLocaleCurrencyCode`, `getLocaleCurrencyName`, `getLocaleCurrencySymbol`, `getLocaleDateFormat`, `getLocaleDateTimeFormat`, `getLocaleDayNames`, `getLocaleDayPeriods`, `getLocaleDirection`, `getLocaleEraNames`, `getLocaleExtraDayPeriodRules`, `getLocaleExtraDayPeriods`, `getLocaleFirstDayOfWeek`, `getLocaleId`, `getLocaleMonthNames`, `getLocaleNumberFormat`, `getLocaleNumberSymbol`, `getLocalePluralCase`, `getLocaleTimeFormat`, `getLocaleWeekEndRange`, `getNumberOfCurrencyDigits`
|
||||
### core
|
||||
- `@Component.interpolation` is deprecated. Use Angular's
|
||||
delimiters instead.
|
||||
### http
|
||||
- `HttpClientModule`, `HttpClientXsrfModule` and `HttpClientJsonpModule`
|
||||
|
||||
As mentionned, those modules can be replaced by provider function only.
|
||||
### animations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [bcce85af72](https://github.com/angular/angular/commit/bcce85af72a82634f60b31d66a5ef42ecd844ce8) | refactor | remove deprecated `matchesElement` from `AnimationDriver` ([#55479](https://github.com/angular/angular/pull/55479)) |
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d34c033902](https://github.com/angular/angular/commit/d34c033902b4e7543796de6c57d0cfd09093eb43) | refactor | Deprecate Local Data API functions ([#54483](https://github.com/angular/angular/pull/54483)) |
|
||||
| [3b0de30b37](https://github.com/angular/angular/commit/3b0de30b37f558d4815ca9a61db1010aaf3df068) | refactor | remove deprecated `isPlatformWorkerApp` and `isPlatformWorkerUi` API ([#55302](https://github.com/angular/angular/pull/55302)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [91b007e58f](https://github.com/angular/angular/commit/91b007e58ffb91f7c396cbc0333a91d18f02bd27) | fix | add math elements to schema ([#55631](https://github.com/angular/angular/pull/55631)) |
|
||||
| [33d0102304](https://github.com/angular/angular/commit/33d0102304e2213ee0af0bc86028a4f564c81ed4) | fix | allow comments between connected blocks ([#55966](https://github.com/angular/angular/pull/55966)) |
|
||||
| [7fc7f3f05f](https://github.com/angular/angular/commit/7fc7f3f05f0139dd773032fd5ad308f8d2a9fcf5) | fix | capture all control flow branches for content projection in if blocks ([#54921](https://github.com/angular/angular/pull/54921)) |
|
||||
| [a369f43fbd](https://github.com/angular/angular/commit/a369f43fbdf45456bbae1caf71ef7becd15d1e90) | fix | capture switch block cases for content projection ([#54921](https://github.com/angular/angular/pull/54921)) |
|
||||
| [eb625d3783](https://github.com/angular/angular/commit/eb625d37839c3b9f20a2ffb3af06426f9910c8ac) | fix | declare for loop aliases in addition to new name ([#54942](https://github.com/angular/angular/pull/54942)) |
|
||||
| [bfd0bd574e](https://github.com/angular/angular/commit/bfd0bd574e9a2e1489a007393caae266512c0f04) | fix | invoke method-based tracking function with context ([#54960](https://github.com/angular/angular/pull/54960)) |
|
||||
| [f824911510](https://github.com/angular/angular/commit/f8249115102204dbb957a0d292ed5342ea5108e9) | fix | For `FatalDiagnosticError`, hide the `message` field without affecting the emit ([#55160](https://github.com/angular/angular/pull/55160)) |
|
||||
| [a040fb720a](https://github.com/angular/angular/commit/a040fb720af7db08b328a9f78511c9881f50482d) | fix | maintain multiline CSS selectors during CSS scoping ([#55509](https://github.com/angular/angular/pull/55509)) |
|
||||
| [39624c6b12](https://github.com/angular/angular/commit/39624c6b129252af352c22c6d6f12ef153477bfc) | fix | output input flags as a literal ([#55215](https://github.com/angular/angular/pull/55215)) |
|
||||
| [eba92cfa55](https://github.com/angular/angular/commit/eba92cfa55500f3558c02edd0aa348ae118794e0) | fix | prevent usage of reserved control flow symbol in custom interpolation context. ([#55809](https://github.com/angular/angular/pull/55809)) |
|
||||
| [7d5bc1c628](https://github.com/angular/angular/commit/7d5bc1c62870d9c68e06eddec229a9b8988e92ee) | fix | remove container index from conditional instruction ([#55190](https://github.com/angular/angular/pull/55190)) |
|
||||
| [4eb0165750](https://github.com/angular/angular/commit/4eb0165750d8c65812502343a70ef4cc35c725b9) | fix | remove support for unassignable expressions in two-way bindings ([#55342](https://github.com/angular/angular/pull/55342)) |
|
||||
| [e1650e3b13](https://github.com/angular/angular/commit/e1650e3b13556ab09c919cfdf97913fa0291622c) | fix | throw error if item name and context variables conflict ([#55045](https://github.com/angular/angular/pull/55045)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
@@ -300,36 +225,147 @@
|
||||
| [5bd188a394](https://github.com/angular/angular/commit/5bd188a394d30053099e2c83fe79136d590e5399) | feat | add partial compilation support for deferred blocks ([#54908](https://github.com/angular/angular/pull/54908)) |
|
||||
| [b02b31a915](https://github.com/angular/angular/commit/b02b31a915333e680cf96de5d0f965a6e2639028) | feat | drop support for TypeScript older than 5.4 ([#54961](https://github.com/angular/angular/pull/54961)) |
|
||||
| [78188e877a](https://github.com/angular/angular/commit/78188e877a4db8655bdd3dc5012b70b12a7234de) | fix | add diagnostic if initializer API is used outside of an initializer ([#54993](https://github.com/angular/angular/pull/54993)) |
|
||||
| [69a83993b3](https://github.com/angular/angular/commit/69a83993b3772dd98cc10d3e12b0ca6c66293cf2) | fix | do not throw when retrieving TCB symbol for signal input with restricted access ([#55774](https://github.com/angular/angular/pull/55774)) |
|
||||
| [4f4f41016e](https://github.com/angular/angular/commit/4f4f41016e897c3fab77ffc23fcfeddadaa782c1) | fix | dom property binding check in signal extended diagnostic ([#54324](https://github.com/angular/angular/pull/54324)) |
|
||||
| [7a16d7e969](https://github.com/angular/angular/commit/7a16d7e969eaf5a9475ffdd21a4bf637ce523856) | fix | don't type check the bodies of control flow nodes in basic mode ([#55360](https://github.com/angular/angular/pull/55360)) |
|
||||
| [8d93597a82](https://github.com/angular/angular/commit/8d93597a82860112a5398828745653a7e27dcef0) | fix | fix type narrowing of `@if` with aliases ([#55835](https://github.com/angular/angular/pull/55835)) |
|
||||
| [9b424d7224](https://github.com/angular/angular/commit/9b424d7224db46edb16c81979c7e231d5e3db5e9) | fix | preserve original reference to non-deferrable dependency ([#54759](https://github.com/angular/angular/pull/54759)) |
|
||||
| [694ba79cbf](https://github.com/angular/angular/commit/694ba79cbf7aaed1079b1fabf53ea446162fc933) | fix | report cases where initializer APIs are used in a non-directive class ([#54993](https://github.com/angular/angular/pull/54993)) |
|
||||
| [6219341d26](https://github.com/angular/angular/commit/6219341d267ae7689299835b90f0afa0fe61e213) | fix | report errors when initializer APIs are used on private fields ([#54981](https://github.com/angular/angular/pull/54981)) |
|
||||
| [c04ffb1fa6](https://github.com/angular/angular/commit/c04ffb1fa61f5164ee5eb7c05b7d76292042ff0b) | fix | use switch statements to narrow Angular switch blocks ([#55168](https://github.com/angular/angular/pull/55168)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a730f09ae9](https://github.com/angular/angular/commit/a730f09ae9e729da79a3e0951e15e0139ef67713) | feat | Add a public API to establish events to be replayed and an attribute to mark an element with an event handler. ([#55356](https://github.com/angular/angular/pull/55356)) |
|
||||
| [fdd560ea14](https://github.com/angular/angular/commit/fdd560ea14f2f35608e26102c7fac0471a634b3e) | feat | Add ability to configure zone change detection to use zoneless scheduler ([#55252](https://github.com/angular/angular/pull/55252)) |
|
||||
| [bce5e2344f](https://github.com/angular/angular/commit/bce5e2344f312dc3a8a30d54e412958bd07180c1) | feat | Add build target for jsaction contract binary. ([#55319](https://github.com/angular/angular/pull/55319)) |
|
||||
| [666d646575](https://github.com/angular/angular/commit/666d646575800e9326eebd513776f8e92b0357e9) | feat | Add event delegation library to queue up events and replay them when the application is ready ([#55121](https://github.com/angular/angular/pull/55121)) |
|
||||
| [5f06ca8f55](https://github.com/angular/angular/commit/5f06ca8f5539ed208bae0b110887b5538ac4041f) | feat | add HOST_TAG_NAME token ([#54751](https://github.com/angular/angular/pull/54751)) |
|
||||
| [a600a39d0c](https://github.com/angular/angular/commit/a600a39d0cf9bb8fc2b6786e6f31acb78b7acc6e) | feat | add support for fallback content in ng-content ([#54854](https://github.com/angular/angular/pull/54854)) |
|
||||
| [146306a141](https://github.com/angular/angular/commit/146306a1417c378920d80a6d91fd847f22e407ab) | feat | add support for i18n hydration ([#54823](https://github.com/angular/angular/pull/54823)) |
|
||||
| [f09c5a7bc4](https://github.com/angular/angular/commit/f09c5a7bc455a59aea133264cbf9fd9ef7509a7f) | feat | Add zoneless change detection provider as experimental ([#55329](https://github.com/angular/angular/pull/55329)) |
|
||||
| [d28614b90e](https://github.com/angular/angular/commit/d28614b90eff835639747e8961fe61e874c44666) | feat | Modify EventType from an enum to an object. ([#55323](https://github.com/angular/angular/pull/55323)) |
|
||||
| [ac863ded48](https://github.com/angular/angular/commit/ac863ded4818af3426ef5888c706a2bd8c79c0be) | feat | provide ExperimentalPendingTasks API ([#55487](https://github.com/angular/angular/pull/55487)) |
|
||||
| [1ee9f32621](https://github.com/angular/angular/commit/1ee9f32621f6d72e8038a08f5ad4a0cfe8bd6a13) | feat | Synchronize changes from internal JSAction codebase. ([#55182](https://github.com/angular/angular/pull/55182)) |
|
||||
| [d888da4606](https://github.com/angular/angular/commit/d888da460696ee74bb4c10a19ac49e3fa1948399) | fix | `ApplicationRef.tick` should respect OnPush for host bindings ([#53718](https://github.com/angular/angular/pull/53718)) |
|
||||
| [64f870c12b](https://github.com/angular/angular/commit/64f870c12bae1ad66509f0d65f8d3e051aae6eaa) | fix | `ApplicationRef.tick` should respect OnPush for host bindings ([#53718](https://github.com/angular/angular/pull/53718)) ([#53718](https://github.com/angular/angular/pull/53718)) |
|
||||
| [8cad4e8cbe](https://github.com/angular/angular/commit/8cad4e8cbe2baf20dae7b7ef1f4253a4940cbba0) | fix | `ComponentFixture` `autoDetect` respects `OnPush` flag of host view ([#54824](https://github.com/angular/angular/pull/54824)) |
|
||||
| [658cf8c384](https://github.com/angular/angular/commit/658cf8c3840b637284a5bb6c9751226d24ccbf9f) | fix | `ComponentFixture` stability should match `ApplicationRef` ([#54949](https://github.com/angular/angular/pull/54949)) |
|
||||
| [2fc11eae9e](https://github.com/angular/angular/commit/2fc11eae9ea65160866bf7ba46c10520ae9a141f) | fix | account for re-projected ng-content elements with fallback content ([#54854](https://github.com/angular/angular/pull/54854)) |
|
||||
| [0cbd73c6e9](https://github.com/angular/angular/commit/0cbd73c6e9931dc4938054fc6f7831bdee2606a4) | fix | add warning when using zoneless but zone.js is still loaded ([#55769](https://github.com/angular/angular/pull/55769)) |
|
||||
| [d5edfde6ee](https://github.com/angular/angular/commit/d5edfde6ee3d65bf7f938ecfeac9f30633f8731b) | fix | afterRender hooks registered outside change detection can mark views dirty ([#55623](https://github.com/angular/angular/pull/55623)) |
|
||||
| [de7447d15e](https://github.com/angular/angular/commit/de7447d15ed964ae26f0dace4cb3b08f5cccb1c1) | fix | Angular should not ignore changes that happen outside the zone ([#55102](https://github.com/angular/angular/pull/55102)) |
|
||||
| [ba8e465974](https://github.com/angular/angular/commit/ba8e46597435a827670f10b971b2c58f7033b180) | fix | Change Detection will continue to refresh views while marked for check ([#54734](https://github.com/angular/angular/pull/54734)) |
|
||||
| [5a10f405d3](https://github.com/angular/angular/commit/5a10f405d315a28b9a000c669e9b1cb3fa24a7f1) | fix | complete the removal of deprecation `async` function ([#55491](https://github.com/angular/angular/pull/55491)) |
|
||||
| [24bc0ed4f2](https://github.com/angular/angular/commit/24bc0ed4f2de47bd998338d73cba394fb45dd497) | fix | ComponentFixture autodetect should detect changes within ApplicationRef.tick ([#54733](https://github.com/angular/angular/pull/54733)) |
|
||||
| [1c0ec56c46](https://github.com/angular/angular/commit/1c0ec56c462cf18fb38aae29858165a08b5a2a82) | fix | correctly project single-root content inside control flow ([#54921](https://github.com/angular/angular/pull/54921)) |
|
||||
| [86a359b399](https://github.com/angular/angular/commit/86a359b399456e62335a0bcfe7c7fb48b7c2b781) | fix | establish proper injector resolution order for `@defer` blocks ([#55079](https://github.com/angular/angular/pull/55079)) |
|
||||
| [840c375255](https://github.com/angular/angular/commit/840c375255dc381674bb27746d9ababd14567c33) | fix | do not save point-in-time `setTimeout` and `rAF` references ([#55124](https://github.com/angular/angular/pull/55124)) |
|
||||
| [10c5cdb49c](https://github.com/angular/angular/commit/10c5cdb49c51c95086febd37f4d88a9b944d7e1c) | fix | ensure change detection runs in a reasonable timeframe with zone coalescing ([#54578](https://github.com/angular/angular/pull/54578)) |
|
||||
| [ad045efd4b](https://github.com/angular/angular/commit/ad045efd4b1565e01c14399998143538ebfbfd99) | fix | Ensure views marked for check are refreshed during change detection ([#54735](https://github.com/angular/angular/pull/54735)) |
|
||||
| [69085ea26e](https://github.com/angular/angular/commit/69085ea26e11f372578999337b2d8f099600b630) | fix | error about provideExperimentalCheckNoChangesForDebug uses wrong name ([#55824](https://github.com/angular/angular/pull/55824)) |
|
||||
| [0147e0b85a](https://github.com/angular/angular/commit/0147e0b85a4f1201b1ae5edaa0d2bc708a13673e) | fix | exhaustive checkNoChanges should only do a single pass ([#55839](https://github.com/angular/angular/pull/55839)) |
|
||||
| [e02bcf89cf](https://github.com/angular/angular/commit/e02bcf89cf77c3118c649a7db68e66a78f16155c) | fix | Fix clearing of pending task in zoneless cleanup implementation ([#55074](https://github.com/angular/angular/pull/55074)) |
|
||||
| [0cec9e4f9a](https://github.com/angular/angular/commit/0cec9e4f9a90ec59f0e9838dcbd82705b1709fc0) | fix | Fix null dereference error `addEvent` ([#55353](https://github.com/angular/angular/pull/55353)) |
|
||||
| [44c0ed83a6](https://github.com/angular/angular/commit/44c0ed83a6499fa96f65a27bc5c926579c06b6d2) | fix | hide implementation details of ExperimentalPendingTasks ([#55516](https://github.com/angular/angular/pull/55516)) |
|
||||
| [314112de99](https://github.com/angular/angular/commit/314112de99bb97475a0d8bdbddf84a3b3ce4a8fb) | fix | Prevent `markForCheck` during change detection from causing infinite loops ([#54900](https://github.com/angular/angular/pull/54900)) |
|
||||
| [a5fa279b6e](https://github.com/angular/angular/commit/a5fa279b6e9f5ab4005d6d33107f0e1bb48d05de) | fix | prevent i18n hydration from cleaning projected nodes ([#54823](https://github.com/angular/angular/pull/54823)) |
|
||||
| [6534c035c0](https://github.com/angular/angular/commit/6534c035c099b30987d6fd1346aea454b79cc79d) | fix | Remove deprecated Testability methods ([#53768](https://github.com/angular/angular/pull/53768)) |
|
||||
| [a5c57c7484](https://github.com/angular/angular/commit/a5c57c7484f1dc3afab4ece4e969a4a7308cdeca) | fix | resolve error for multiple component instances that use fallback content ([#55478](https://github.com/angular/angular/pull/55478)) |
|
||||
| [f44a5e4604](https://github.com/angular/angular/commit/f44a5e460491a29e5c0cad5577bade8347d52e11) | fix | support content projection and VCRs in i18n ([#54823](https://github.com/angular/angular/pull/54823)) |
|
||||
| [0510930a25](https://github.com/angular/angular/commit/0510930a257e610460c875dbbc5566fd06547814) | fix | TestBed should not override NgZone from initTestEnvironment ([#55226](https://github.com/angular/angular/pull/55226)) |
|
||||
| [e9a0c86766](https://github.com/angular/angular/commit/e9a0c86766ab15c896e026120f0c63c2fb1f9e04) | fix | TestBed should not override NgZone from initTestEnvironment ([#55226](https://github.com/angular/angular/pull/55226)) |
|
||||
| [700c0520bb](https://github.com/angular/angular/commit/700c0520bb638952ba41a8d8260cf12afb078c0e) | fix | Update ApplicationRef.tick loop to only throw in dev mode ([#54848](https://github.com/angular/angular/pull/54848)) |
|
||||
| [a99cb7ce5b](https://github.com/angular/angular/commit/a99cb7ce5b77a125ab660da8ebef23ecb158e2e3) | fix | zoneless scheduler should check if Zone is defined before accessing it ([#55118](https://github.com/angular/angular/pull/55118)) |
|
||||
| [1fd63e9cff](https://github.com/angular/angular/commit/1fd63e9cff9159a8c10c35a0af43bc986e4e8e26) | refactor | deprecate `@Component.interpolation` ([#55778](https://github.com/angular/angular/pull/55778)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [1c736dc3b2](https://github.com/angular/angular/commit/1c736dc3b258a502360cda40b3a00c07102ccbf5) | feat | Unified Control State Change Events ([#54579](https://github.com/angular/angular/pull/54579)) |
|
||||
| [61007dced0](https://github.com/angular/angular/commit/61007dced0f3396c40efcd2617c130633fb9837a) | fix | Add event for forms submitted & reset ([#55667](https://github.com/angular/angular/pull/55667)) |
|
||||
| [2e27ca9ddf](https://github.com/angular/angular/commit/2e27ca9ddfc1f3f0387cd720071e85ff46f19db6) | fix | Allow canceled async validators to emit. ([#55134](https://github.com/angular/angular/pull/55134)) |
|
||||
### http
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [cf73983fdc](https://github.com/angular/angular/commit/cf73983fdc5fca955fbe729b231a207fc5cd70fd) | fix | include transferCache when cloning HttpRequest ([#54939](https://github.com/angular/angular/pull/54939)) |
|
||||
| [13554f9637](https://github.com/angular/angular/commit/13554f9637c222671253e733114cfbc815c6d33d) | fix | manage different body types for caching POST requests ([#54980](https://github.com/angular/angular/pull/54980)) |
|
||||
| [6f88d80758](https://github.com/angular/angular/commit/6f88d8075895bd80592b1b7e0fba8202a58a5417) | feat | allow caching requests with different origins between server and client ([#55274](https://github.com/angular/angular/pull/55274)) |
|
||||
| [8eacb6e4b9](https://github.com/angular/angular/commit/8eacb6e4b982a5aa23cfbf9078dc4e19d9466d73) | feat | exclude caching for authenticated HTTP requests ([#55034](https://github.com/angular/angular/pull/55034)) |
|
||||
| [d9b339fdbc](https://github.com/angular/angular/commit/d9b339fdbc0f8d1e9bb7b1e4190e7d80e68542f9) | fix | resolve `withRequestsMadeViaParent` behavior with `withFetch` ([#55652](https://github.com/angular/angular/pull/55652)) |
|
||||
| [ef665a40a5](https://github.com/angular/angular/commit/ef665a40a580ff4df79617084ac83738f28ae924) | refactor | Deprecate `HttpClientModule` & related modules ([#54020](https://github.com/angular/angular/pull/54020)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [6d1b82df32](https://github.com/angular/angular/commit/6d1b82df32049cfaba2f6a50b9639b6e3b722170) | fix | allow external projects to use provided compiler options ([#55035](https://github.com/angular/angular/pull/55035)) |
|
||||
| [a48afe0d94](https://github.com/angular/angular/commit/a48afe0d9478aca314e68552f4af77f4123563cd) | fix | avoid generating TS syntactic diagnostics for templates ([#55091](https://github.com/angular/angular/pull/55091)) |
|
||||
| [bd236cc150](https://github.com/angular/angular/commit/bd236cc150e1b21932612ecf91678be77a503d18) | fix | implement getDefinitionAtPosition for Angular templates ([#55269](https://github.com/angular/angular/pull/55269)) |
|
||||
| [4166dfc1b6](https://github.com/angular/angular/commit/4166dfc1b62a83b60203bfe45a6d4aa7148a0b23) | fix | prevent underlying TS Service from handling template files ([#55003](https://github.com/angular/angular/pull/55003)) |
|
||||
| [b7f2fd4739](https://github.com/angular/angular/commit/b7f2fd473988a561bfd032386d8955e90c8d91ed) | fix | use type-only import in plugin factory ([#55996](https://github.com/angular/angular/pull/55996)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [63688714ae](https://github.com/angular/angular/commit/63688714aeb788a24b030f9f9cdcc55e7fb0d758) | fix | account for variables in imports initializer ([#55081](https://github.com/angular/angular/pull/55081)) |
|
||||
| [f914f6a362](https://github.com/angular/angular/commit/f914f6a3628847c06cbdde9c90cd417fb2f4c61f) | feat | Migration schematics for `HttpClientModule` ([#54020](https://github.com/angular/angular/pull/54020)) |
|
||||
| [8459ee46cb](https://github.com/angular/angular/commit/8459ee46cba7f63966c41a2fb7199ec295a91cbb) | fix | handle more cases in HttpClientModule migration ([#55640](https://github.com/angular/angular/pull/55640)) |
|
||||
| [c4b2f18709](https://github.com/angular/angular/commit/c4b2f18709076f8c400bd26226be37ae07e5e83d) | fix | migrate HttpClientTestingModule in test modules ([#55803](https://github.com/angular/angular/pull/55803)) |
|
||||
| [bb4a4016a9](https://github.com/angular/angular/commit/bb4a4016a9a29a9c56342ee01d866b0c8a3fb419) | fix | preserve existing properties in HttpClientModule migration ([#55777](https://github.com/angular/angular/pull/55777)) |
|
||||
| [f93e5180be](https://github.com/angular/angular/commit/f93e5180be1e20a59ff68f12853653f4f3282846) | fix | resolve multiple structural issues with HttpClient migration ([#55557](https://github.com/angular/angular/pull/55557)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [45ae7a6b60](https://github.com/angular/angular/commit/45ae7a6b60019bd49b8a58122a0d5bcbda7e245b) | feat | add withI18nSupport() in developer preview ([#55130](https://github.com/angular/angular/pull/55130)) |
|
||||
| [23f914f101](https://github.com/angular/angular/commit/23f914f1012545330f6a5aeed4e862bf0e66117b) | fix | Use the right namespace for mathML. ([#55622](https://github.com/angular/angular/pull/55622)) |
|
||||
| [cba336d4f1](https://github.com/angular/angular/commit/cba336d4f1badd601b24a58fc51bde995f45682d) | refactor | remove deprecated transfer state APIs ([#55474](https://github.com/angular/angular/pull/55474)) |
|
||||
### platform-browser-dynamic
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [eb20c1a8b1](https://github.com/angular/angular/commit/eb20c1a8b18e2e080c856e3e1bf7bcd02f3bfd28) | refactor | unused `RESOURCE_CACHE_PROVIDER` API has been removed ([#54875](https://github.com/angular/angular/pull/54875)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [5674c644ab](https://github.com/angular/angular/commit/5674c644abf51ae8764befd3011742ff1febdf29) | fix | add `nonce` attribute to event record script ([#55495](https://github.com/angular/angular/pull/55495)) |
|
||||
| [e71e869112](https://github.com/angular/angular/commit/e71e869112af1c0ee7a9dd64a963ad7af14a40e2) | fix | remove event dispatch script from HTML when hydration is disabled ([#55681](https://github.com/angular/angular/pull/55681)) |
|
||||
| [07ac017731](https://github.com/angular/angular/commit/07ac017731f0e08ea3736f1f212093a28648a304) | refactor | remove deprecated `platformDynamicServer` API ([#54874](https://github.com/angular/angular/pull/54874)) |
|
||||
| [e8b588d8b7](https://github.com/angular/angular/commit/e8b588d8b7fc014aaef99d4b0c1e4567b4aa195d) | refactor | remove deprecated `ServerTransferStateModule` API ([#54874](https://github.com/angular/angular/pull/54874)) |
|
||||
| [3b1967ca64](https://github.com/angular/angular/commit/3b1967ca64479df9137b3ad7a0d04dbaff6496f4) | refactor | remove deprecated `useAbsoluteUrl` and `baseUrl` from `PlatformConfig` ([#54874](https://github.com/angular/angular/pull/54874)) |
|
||||
| [2357d3566c](https://github.com/angular/angular/commit/2357d3566c4d18dc40cbda6644ed459ef7703893) | refactor | remove legacy URL handling logic ([#54874](https://github.com/angular/angular/pull/54874)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [4a42961393](https://github.com/angular/angular/commit/4a42961393b3abf40f34374df059d3959dadecc0) | feat | `withNavigationErrorHandler` can convert errors to redirects ([#55370](https://github.com/angular/angular/pull/55370)) |
|
||||
| [8735af08b9](https://github.com/angular/angular/commit/8735af08b976b30cf236a83f9e8b64b5ff62e9f3) | feat | Add ability to return `UrlTree` with `NavigationBehaviorOptions` from guards ([#45023](https://github.com/angular/angular/pull/45023)) |
|
||||
| [87f3f27f90](https://github.com/angular/angular/commit/87f3f27f9087d757e18e8e2a0f2fca6f2a2c7edf) | feat | Allow resolvers to return `RedirectCommand` ([#54556](https://github.com/angular/angular/pull/54556)) |
|
||||
| [2b802587f2](https://github.com/angular/angular/commit/2b802587f27186baa493c1dd01f42d568b652f38) | feat | Allow Route.redirectTo to be a function which returns a string or UrlTree ([#52606](https://github.com/angular/angular/pull/52606)) |
|
||||
| [60f1d681e0](https://github.com/angular/angular/commit/60f1d681e0ba66d3d94b0819f2c612f095c2d3d3) | fix | preserve replaceUrl when returning a urlTree from CanActivate ([#54042](https://github.com/angular/angular/pull/54042)) |
|
||||
| [eae75ff3f9](https://github.com/angular/angular/commit/eae75ff3f9f564b919debe3f9fa41ed1b073a22c) | fix | RouterLinkActive will always remove active classes when links are not active ([#54982](https://github.com/angular/angular/pull/54982)) |
|
||||
| [3839cfbb18](https://github.com/angular/angular/commit/3839cfbb18fcc70cae5a6ba4ba7676b1c4acf7a0) | fix | Routed components never inherit `RouterOutlet` `EnvironmentInjector` ([#54265](https://github.com/angular/angular/pull/54265)) |
|
||||
| [da906fdafc](https://github.com/angular/angular/commit/da906fdafcbb302fa280a162d1c1f04369be2efa) | fix | Routed components never inherit `RouterOutlet` `EnvironmentInjector` ([#54265](https://github.com/angular/angular/pull/54265)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [3bc63eaaf3](https://github.com/angular/angular/commit/3bc63eaaf344712ac6de1c9618d4558d9443c848) | fix | avoid running CDs on `controllerchange` ([#54222](https://github.com/angular/angular/pull/54222)) |
|
||||
| [e598634c10](https://github.com/angular/angular/commit/e598634c10a60936ec4199b221eca4e901220763) | fix | remove `controllerchange` listener when app is destroyed ([#55365](https://github.com/angular/angular/pull/55365)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.6"></a>
|
||||
# 17.3.6 (2024-04-25)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [826861b1fa](https://github.com/angular/angular/commit/826861b1fa7693010743f5dd881fb31ec33eee52) | fix | DeferBlockFixture.render should not wait for stability ([#55271](https://github.com/angular/angular/pull/55271)) |
|
||||
| [5cf14da35c](https://github.com/angular/angular/commit/5cf14da35cce1ea4456bae4365d3dbe6667b1881) | fix | make `ActivatedRoute` inject correct instance inside `@defer` blocks ([#55374](https://github.com/angular/angular/pull/55374)) |
|
||||
| [8979fba2c5](https://github.com/angular/angular/commit/8979fba2c5813673767a133caeec9ac768d17329) | fix | skip defer timers on the server ([#55480](https://github.com/angular/angular/pull/55480)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.5"></a>
|
||||
# 17.3.5 (2024-04-17)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.4"></a>
|
||||
# 17.3.4 (2024-04-10)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [53427d875d](https://github.com/angular/angular/commit/53427d875d33de16b1dbb04e76a9fe32a2b8a445) | fix | invalid ImageKit quality parameter ([#55193](https://github.com/angular/angular/pull/55193)) |
|
||||
| [766548c3ec](https://github.com/angular/angular/commit/766548c3ecc06ffd8f06ed9a7d0cbb3db6f1b0f6) | fix | skip transfer cache on client ([#55012](https://github.com/angular/angular/pull/55012)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
@@ -363,55 +399,6 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-next.1"></a>
|
||||
# 18.0.0-next.1 (2024-03-20)
|
||||
## Breaking Changes
|
||||
### platform-browser-dynamic
|
||||
- No longer used `RESOURCE_CACHE_PROVIDER` APIs have been removed.
|
||||
### platform-server
|
||||
- deprecated `platformDynamicServer` has been removed. Add an `import @angular/compiler` and replace the usage with `platformServer`
|
||||
- deprecated `ServerTransferStateModule` has been removed. `TransferState` can be use without providing this module.
|
||||
- deprecated `useAbsoluteUrl` and `baseUrl` been removed from `PlatformConfig`. Provide and absolute `url` instead.
|
||||
- Legacy handling or Node.js URL parsing has been removed from `ServerPlatformLocation`.
|
||||
|
||||
The main differences are;
|
||||
- `pathname` is always suffixed with a `/`.
|
||||
- `port` is empty when `http:` protocol and port in url is `80`
|
||||
- `port` is empty when `https:` protocol and port in url is `443`
|
||||
### router
|
||||
- This change allows `Route.redirectTo` to be a function
|
||||
in addition to the previous string. Code which expects `redirectTo` to
|
||||
only be a string on `Route` objects will need to be adjusted.
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [879bd80b57](https://github.com/angular/angular/commit/879bd80b571368bdc6e65c5415d98ad0f546267a) | fix | capture data bindings for content projection purposes in blocks ([#54876](https://github.com/angular/angular/pull/54876)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [6aff144232](https://github.com/angular/angular/commit/6aff14423238f8995da8104e60c0baca26df2020) | fix | symbol feature detection for the compiler ([#54711](https://github.com/angular/angular/pull/54711)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [314112de99](https://github.com/angular/angular/commit/314112de99bb97475a0d8bdbddf84a3b3ce4a8fb) | fix | Prevent `markForCheck` during change detection from causing infinite loops ([#54900](https://github.com/angular/angular/pull/54900)) |
|
||||
### platform-browser-dynamic
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [eb20c1a8b1](https://github.com/angular/angular/commit/eb20c1a8b18e2e080c856e3e1bf7bcd02f3bfd28) | refactor | unused `RESOURCE_CACHE_PROVIDER` API has been removed ([#54875](https://github.com/angular/angular/pull/54875)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [07ac017731](https://github.com/angular/angular/commit/07ac017731f0e08ea3736f1f212093a28648a304) | refactor | remove deprecated `platformDynamicServer` API ([#54874](https://github.com/angular/angular/pull/54874)) |
|
||||
| [e8b588d8b7](https://github.com/angular/angular/commit/e8b588d8b7fc014aaef99d4b0c1e4567b4aa195d) | refactor | remove deprecated `ServerTransferStateModule` API ([#54874](https://github.com/angular/angular/pull/54874)) |
|
||||
| [3b1967ca64](https://github.com/angular/angular/commit/3b1967ca64479df9137b3ad7a0d04dbaff6496f4) | refactor | remove deprecated `useAbsoluteUrl` and `baseUrl` from `PlatformConfig` ([#54874](https://github.com/angular/angular/pull/54874)) |
|
||||
| [2357d3566c](https://github.com/angular/angular/commit/2357d3566c4d18dc40cbda6644ed459ef7703893) | refactor | remove legacy URL handling logic ([#54874](https://github.com/angular/angular/pull/54874)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2b802587f2](https://github.com/angular/angular/commit/2b802587f27186baa493c1dd01f42d568b652f38) | feat | Allow Route.redirectTo to be a function which returns a string or UrlTree ([#52606](https://github.com/angular/angular/pull/52606)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.1"></a>
|
||||
# 17.3.1 (2024-03-20)
|
||||
### compiler
|
||||
@@ -425,79 +412,6 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-next.0"></a>
|
||||
# 18.0.0-next.0 (2024-03-14)
|
||||
## Breaking Changes
|
||||
### core
|
||||
- `OnPush` views at the root of the application need to
|
||||
be marked dirty for their host bindings to refresh. Previously, the host
|
||||
bindings were refreshed for all root views without respecting the
|
||||
`OnPush` change detection strategy.
|
||||
- The `ComponentFixture` `autoDetect` feature will no
|
||||
longer refresh the component's host view when the component is `OnPush`
|
||||
and not marked dirty. This exposes existing issues in components which
|
||||
claim to be `OnPush` but do not correctly call `markForCheck` when they
|
||||
need to be refreshed. If this change causes test failures, the easiest
|
||||
fix is to change the component to `ChangeDetectionStrategy.Default`.
|
||||
- When Angular runs change detection, it will continue to
|
||||
refresh any views attached to `ApplicationRef` that are still marked for
|
||||
check after one round completes. In rare cases, this can result in infinite
|
||||
loops when certain patterns continue to mark views for check using
|
||||
`ChangeDetectorRef.detectChanges`. This will be surfaced as a runtime
|
||||
error with the `NG0103` code.
|
||||
- The `ComponentFixture.autoDetect` feature now executes
|
||||
change detection for the fixture within `ApplicationRef.tick`. This more
|
||||
closely matches the behavior of how a component would refresh in
|
||||
production. The order of component refresh in tests may be slightly
|
||||
affected as a result, especially when dealing with additional components
|
||||
attached to the application, such as dialogs. Tests sensitive to this
|
||||
type of change (such as screenshot tests) may need to be updated.
|
||||
Concretely, this change means that the component will refresh _before_
|
||||
additional views attached to `ApplicationRef` (i.e. dialog components).
|
||||
Prior to this change, the fixture component would refresh _after_ other
|
||||
views attached to the application.
|
||||
- The exact timing of change detection execution when
|
||||
using event or run coalescing with `NgZone` is now the first of either
|
||||
`setTimeout` or `requestAnimationFrame`. Code which relies on this
|
||||
timing (usually by accident) will need to be adjusted. If a callback
|
||||
needs to execute after change detection, we recommend `afterNextRender`
|
||||
instead of something like `setTimeout`.
|
||||
- Newly created and views marked for check and reattached
|
||||
during change detection are now guaranteed to be refreshed in that same
|
||||
change detection cycle. Previously, if they were attached at a location
|
||||
in the view tree that was already checked, they would either throw
|
||||
`ExpressionChangedAfterItHasBeenCheckedError` or not be refreshed until
|
||||
some future round of change detection. In rare circumstances, this
|
||||
correction can cause issues. We identified one instance that relied on
|
||||
the previous behavior by reading a value on initialization which was
|
||||
queued to be updated in a microtask instead of being available in the
|
||||
current change detection round. The component only read this value during
|
||||
initialization and did not read it again after the microtask updated it.
|
||||
### router
|
||||
- Guards can now return `RedirectCommand` for redirects
|
||||
in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree`
|
||||
values in `Route` types will need to be adjusted.
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [9b424d7224](https://github.com/angular/angular/commit/9b424d7224db46edb16c81979c7e231d5e3db5e9) | fix | preserve original reference to non-deferrable dependency ([#54759](https://github.com/angular/angular/pull/54759)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [64f870c12b](https://github.com/angular/angular/commit/64f870c12bae1ad66509f0d65f8d3e051aae6eaa) | fix | `ApplicationRef.tick` should respect OnPush for host bindings ([#53718](https://github.com/angular/angular/pull/53718)) ([#53718](https://github.com/angular/angular/pull/53718)) |
|
||||
| [8cad4e8cbe](https://github.com/angular/angular/commit/8cad4e8cbe2baf20dae7b7ef1f4253a4940cbba0) | fix | `ComponentFixture` `autoDetect` respects `OnPush` flag of host view ([#54824](https://github.com/angular/angular/pull/54824)) |
|
||||
| [ba8e465974](https://github.com/angular/angular/commit/ba8e46597435a827670f10b971b2c58f7033b180) | fix | Change Detection will continue to refresh views while marked for check ([#54734](https://github.com/angular/angular/pull/54734)) |
|
||||
| [24bc0ed4f2](https://github.com/angular/angular/commit/24bc0ed4f2de47bd998338d73cba394fb45dd497) | fix | ComponentFixture autodetect should detect changes within ApplicationRef.tick ([#54733](https://github.com/angular/angular/pull/54733)) |
|
||||
| [10c5cdb49c](https://github.com/angular/angular/commit/10c5cdb49c51c95086febd37f4d88a9b944d7e1c) | fix | ensure change detection runs in a reasonable timeframe with zone coalescing ([#54578](https://github.com/angular/angular/pull/54578)) |
|
||||
| [ad045efd4b](https://github.com/angular/angular/commit/ad045efd4b1565e01c14399998143538ebfbfd99) | fix | Ensure views marked for check are refreshed during change detection ([#54735](https://github.com/angular/angular/pull/54735)) |
|
||||
| [700c0520bb](https://github.com/angular/angular/commit/700c0520bb638952ba41a8d8260cf12afb078c0e) | fix | Update ApplicationRef.tick loop to only throw in dev mode ([#54848](https://github.com/angular/angular/pull/54848)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [8735af08b9](https://github.com/angular/angular/commit/8735af08b976b30cf236a83f9e8b64b5ff62e9f3) | feat | Add ability to return `UrlTree` with `NavigationBehaviorOptions` from guards ([#45023](https://github.com/angular/angular/pull/45023)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.0"></a>
|
||||
# 17.3.0 (2024-03-13)
|
||||
### compiler
|
||||
|
||||
@@ -75,7 +75,7 @@ yarn_install(
|
||||
"//:.yarnrc",
|
||||
"//:tools/npm-patches/@bazel+jasmine+5.8.1.patch",
|
||||
"//tools:postinstall-patches.js",
|
||||
"//tools/esm-interop:patches/npm/@angular+build-tooling+0.0.0-56d0b1f597b9e4b5d99f289f6904a220802164c1.patch",
|
||||
"//tools/esm-interop:patches/npm/@angular+build-tooling+0.0.0-239d56b71911f9fa1eeefb6e4505dbe7b0cd81a7.patch",
|
||||
"//tools/esm-interop:patches/npm/@bazel+concatjs+5.8.1.patch",
|
||||
"//tools/esm-interop:patches/npm/@bazel+esbuild+5.7.1.patch",
|
||||
"//tools/esm-interop:patches/npm/@bazel+protractor+5.7.1.patch",
|
||||
@@ -167,10 +167,10 @@ cldr_xml_data_repository(
|
||||
# sass rules
|
||||
http_archive(
|
||||
name = "io_bazel_rules_sass",
|
||||
sha256 = "845061fad5cb42a353ac394fe6450ec9f21d337acf5b98011ef29ddcb33e3671",
|
||||
strip_prefix = "rules_sass-9f8be59f5175d0dd3438d7da994b2782299e0c2c",
|
||||
sha256 = "4f9be14f1132126c4bd7335e7d9eb70ed7273303e3966bbec1744c14d20d10df",
|
||||
strip_prefix = "rules_sass-61dde525066c4e17cfe8d404748dbc7195c10bde",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_sass/archive/9f8be59f5175d0dd3438d7da994b2782299e0c2c.zip",
|
||||
"https://github.com/bazelbuild/rules_sass/archive/61dde525066c4e17cfe8d404748dbc7195c10bde.zip",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -79,9 +79,8 @@ APPLICATION_DEPS = [
|
||||
"@npm//@lezer/javascript",
|
||||
"@npm//@lezer/common",
|
||||
"@npm//@xterm/xterm",
|
||||
"@npm//@xterm/addon-fit",
|
||||
"@npm//algoliasearch",
|
||||
"@npm//xterm",
|
||||
"@npm//xterm-addon-fit",
|
||||
"@npm//angular-split",
|
||||
"@npm//zone.js",
|
||||
]
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": ["src/favicon.ico", "src/robots.txt", "src/assets"],
|
||||
"styles": ["@angular/docs/styles/global-styles.scss"],
|
||||
"styles": ["@angular/docs/styles/global-styles.scss", "./src/local-styles.scss"],
|
||||
"scripts": [],
|
||||
"webWorkerTsConfig": "tsconfig.worker.json",
|
||||
"optimization": {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@defer (when isBrowser) {
|
||||
<adev-progress-bar />
|
||||
<adev-progress-bar />
|
||||
}
|
||||
<button (click)="focusFirstHeading()" class="adev-skip">Skip to main content</button>
|
||||
|
||||
<div class="adev-nav"></div>
|
||||
@if (displaySecondaryNav()) {
|
||||
<adev-secondary-navigation />
|
||||
<adev-secondary-navigation />
|
||||
}
|
||||
<div class="docs-app-main-content">
|
||||
<!--
|
||||
@@ -22,9 +22,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
<router-outlet />
|
||||
<router-outlet />
|
||||
|
||||
@if (displayFooter()) {
|
||||
<footer adev-footer></footer>
|
||||
<footer adev-footer></footer>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -11,10 +11,12 @@ import {AppComponent} from './app.component';
|
||||
import {provideRouter} from '@angular/router';
|
||||
import {routes} from './routes';
|
||||
import {Search, WINDOW} from '@angular/docs';
|
||||
import {CURRENT_MAJOR_VERSION} from './core/providers/current-version';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
const fakeSearch = {};
|
||||
const fakeWindow = {};
|
||||
const fakeWindow = {location: {hostname: 'angular.dev'}};
|
||||
const fakeCurrentMajorVersion = 19;
|
||||
|
||||
it('should create the app', () => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -28,6 +30,10 @@ describe('AppComponent', () => {
|
||||
provide: Search,
|
||||
useValue: fakeSearch,
|
||||
},
|
||||
{
|
||||
provide: CURRENT_MAJOR_VERSION,
|
||||
useValue: fakeCurrentMajorVersion,
|
||||
},
|
||||
],
|
||||
});
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
import {DOCUMENT, isPlatformBrowser} from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
inject,
|
||||
NgZone,
|
||||
@@ -32,8 +33,9 @@ import {ProgressBarComponent} from './core/layout/progress-bar/progress-bar.comp
|
||||
import {ESCAPE, SEARCH_TRIGGER_KEY} from './core/constants/keys';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'adev-root',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [
|
||||
CookiePopup,
|
||||
Navigation,
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
ApplicationConfig,
|
||||
ENVIRONMENT_INITIALIZER,
|
||||
ErrorHandler,
|
||||
VERSION,
|
||||
inject,
|
||||
provideZoneChangeDetection,
|
||||
} from '@angular/core';
|
||||
@@ -44,6 +45,7 @@ import {ExampleContentLoader} from './core/services/example-content-loader.servi
|
||||
import {ReuseTutorialsRouteStrategy} from './features/tutorial/tutorials-route-reuse-strategy';
|
||||
import {routes} from './routes';
|
||||
import {ReferenceScrollHandler} from './features/references/services/reference-scroll-handler.service';
|
||||
import {CURRENT_MAJOR_VERSION} from './core/providers/current-version';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
@@ -71,6 +73,10 @@ export const appConfig: ApplicationConfig = {
|
||||
provideClientHydration(),
|
||||
provideHttpClient(withFetch()),
|
||||
provideAnimationsAsync(),
|
||||
{
|
||||
provide: CURRENT_MAJOR_VERSION,
|
||||
useValue: Number(VERSION.major),
|
||||
},
|
||||
{provide: ENVIRONMENT, useValue: environment},
|
||||
{
|
||||
provide: ENVIRONMENT_INITIALIZER,
|
||||
|
||||
@@ -8,5 +8,6 @@
|
||||
|
||||
export const GITHUB = 'https://github.com/angular/angular';
|
||||
export const X = 'https://x.com/angular';
|
||||
export const MEDIUM = 'https://blog.angular.io';
|
||||
export const YOUTUBE = 'https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw';
|
||||
export const MEDIUM = 'https://blog.angular.dev';
|
||||
export const YOUTUBE = 'https://www.youtube.com/angular';
|
||||
export const DISCORD = 'https://discord.gg/angular';
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
*/
|
||||
|
||||
export const VERSIONS_CONFIG = {
|
||||
currentVersion: 'stable',
|
||||
historicalVersionsLinkPattern: 'https://v{{version}}.angular.dev',
|
||||
mainVersions: [
|
||||
aDevVersionsLinkPattern: 'https://{{prefix}}{{version}}angular.dev',
|
||||
aioVersions: [
|
||||
{
|
||||
version: 'stable',
|
||||
url: 'https://angular.dev',
|
||||
version: 'v17',
|
||||
url: 'https://v17.angular.io/docs',
|
||||
},
|
||||
{
|
||||
version: 'v16',
|
||||
|
||||
@@ -17,6 +17,7 @@ export enum PagePrefix {
|
||||
PLAYGROUND = 'playground',
|
||||
REFERENCE = 'reference',
|
||||
TUTORIALS = 'tutorials',
|
||||
UPDATE = 'update-guide',
|
||||
}
|
||||
|
||||
// The enum with the default pages for each main tab
|
||||
@@ -25,4 +26,5 @@ export enum DefaultPage {
|
||||
REFERENCE = 'api',
|
||||
TUTORIALS = 'tutorials',
|
||||
PLAYGROUND = 'playground',
|
||||
UPDATE = 'update-guide',
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
}
|
||||
|
||||
.adev-version-picker {
|
||||
overflow-y: auto;
|
||||
max-height: 90vh;
|
||||
top: 30px;
|
||||
left: 10px;
|
||||
position: absolute;
|
||||
|
||||
@@ -82,7 +82,8 @@
|
||||
>
|
||||
<a aria-label="Angular homepage" routerLink="/">
|
||||
<!-- Logo Symbol -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
|
||||
@if(!isUwu) {
|
||||
<svg class="angular-logo" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
|
||||
<g clip-path="url(#a)">
|
||||
<path
|
||||
fill="url(#b)"
|
||||
@@ -125,6 +126,14 @@
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
} @else {
|
||||
<img
|
||||
src="assets/images/uwu.png"
|
||||
style="width: auto; margin: 0"
|
||||
class="uwu-logo"
|
||||
alt="Angular logo"
|
||||
height="34"/>
|
||||
}
|
||||
</a>
|
||||
|
||||
<!-- Version picker for v18+ -->
|
||||
@@ -371,6 +380,24 @@
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [href]="DISCORD" cdkMenuItem title="Angular Discord" target="_blank" rel="noopener">
|
||||
<!-- Discord Icon -->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 127.14 96.36"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,110.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
padding-block-end: 2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
&.adev-nav-primary--next,
|
||||
&.adev-nav-primary--rc {
|
||||
// change nav background to indicate this is the rc docs
|
||||
background: linear-gradient(
|
||||
@@ -79,11 +80,6 @@
|
||||
color-mix(in srgb, var(--bright-blue), transparent 60%) 90%,
|
||||
);
|
||||
}
|
||||
|
||||
&.adev-nav-primary--next {
|
||||
// change nav background to indicate this is the rc docs
|
||||
background-color: color-mix(in srgb, var(--orange-red), transparent 60%);
|
||||
}
|
||||
|
||||
&.adev-nav-primary--deprecated {
|
||||
// change nav background to indicate this is an outdated version of the docs
|
||||
@@ -251,6 +247,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.adev-nav-item--logo a {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.adev-close-nav {
|
||||
display: none;
|
||||
@include mq.for-phone-only {
|
||||
|
||||
@@ -27,10 +27,10 @@ import {
|
||||
isApple,
|
||||
IS_SEARCH_DIALOG_OPEN,
|
||||
} from '@angular/docs';
|
||||
import {NavigationEnd, Router, RouterLink} from '@angular/router';
|
||||
import {ActivatedRoute, NavigationEnd, Router, RouterLink} from '@angular/router';
|
||||
import {filter, map, startWith} from 'rxjs/operators';
|
||||
import {DOCS_ROUTES, REFERENCE_ROUTES, TUTORIALS_ROUTES} from '../../../routes';
|
||||
import {GITHUB, MEDIUM, X, YOUTUBE} from '../../constants/links';
|
||||
import {GITHUB, MEDIUM, X, YOUTUBE, DISCORD} from '../../constants/links';
|
||||
import {PagePrefix} from '../../enums/pages';
|
||||
import {Theme, ThemeManager} from '../../services/theme-manager.service';
|
||||
import {VersionManager} from '../../services/version-manager.service';
|
||||
@@ -79,10 +79,14 @@ export class Navigation implements OnInit {
|
||||
readonly X = X;
|
||||
readonly MEDIUM = MEDIUM;
|
||||
readonly YOUTUBE = YOUTUBE;
|
||||
readonly DISCORD = DISCORD;
|
||||
|
||||
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
|
||||
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
|
||||
|
||||
// We can't use the ActivatedRouter queryParams as we're outside the router outlet
|
||||
readonly isUwu = 'location' in globalThis ? location.search.includes('uwu') : false;
|
||||
|
||||
miniMenuPositions = [
|
||||
new ConnectionPositionPair(
|
||||
{originX: 'end', originY: 'center'},
|
||||
@@ -199,7 +203,8 @@ export class Navigation implements OnInit {
|
||||
this.activeRouteItem.set(PagePrefix.DOCS);
|
||||
} else if (
|
||||
urlAfterRedirects.startsWith(PagePrefix.REFERENCE) ||
|
||||
urlAfterRedirects.startsWith(PagePrefix.API)
|
||||
urlAfterRedirects.startsWith(PagePrefix.API) ||
|
||||
urlAfterRedirects.startsWith(PagePrefix.UPDATE)
|
||||
) {
|
||||
this.activeRouteItem.set(PagePrefix.REFERENCE);
|
||||
} else if (urlAfterRedirects === PagePrefix.PLAYGROUND) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div [attr.id]="SECONDARY_NAV_ID" class="adev-secondary-nav-mask" [class.docs-nav-secondary--open]="isSecondaryNavVisible()" (docsClickOutside)="close()" [docsClickOutsideIgnore]="[PRIMARY_NAV_ID]">
|
||||
<div class="docs-nav-secondary docs-scroll-track-transparent" [style.transform]="translateX()" [style.transition]="transition">
|
||||
<div class="docs-nav-secondary docs-scroll-track-transparent" [style.transform]="translateX()" [style.transition]="transition()">
|
||||
<!-- Secondary Nav -->
|
||||
@if (navigationItems && navigationItems.length > 0) {
|
||||
<docs-navigation-list
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
PLATFORM_ID,
|
||||
computed,
|
||||
inject,
|
||||
signal,
|
||||
} from '@angular/core';
|
||||
import {takeUntilDestroyed, toObservable} from '@angular/core/rxjs-interop';
|
||||
import {
|
||||
@@ -64,19 +65,19 @@ export class SecondaryNavigation implements OnInit {
|
||||
private readonly router = inject(Router);
|
||||
private readonly window = inject(WINDOW);
|
||||
|
||||
isSecondaryNavVisible = this.navigationState.isMobileNavVisible;
|
||||
primaryActiveRouteItem = this.navigationState.primaryActiveRouteItem;
|
||||
maxVisibleLevelsOnSecondaryNav = computed(() =>
|
||||
readonly isSecondaryNavVisible = this.navigationState.isMobileNavVisible;
|
||||
readonly primaryActiveRouteItem = this.navigationState.primaryActiveRouteItem;
|
||||
readonly maxVisibleLevelsOnSecondaryNav = computed(() =>
|
||||
this.primaryActiveRouteItem() === PagePrefix.REFERENCE ? 1 : 2,
|
||||
);
|
||||
navigationItemsSlides = this.navigationState.expandedItems;
|
||||
readonly navigationItemsSlides = this.navigationState.expandedItems;
|
||||
navigationItems: NavigationItem[] | undefined;
|
||||
|
||||
translateX = computed(() => {
|
||||
const level = this.navigationState.expandedItems()?.length ?? 0;
|
||||
return `translateX(${-level * 100}%)`;
|
||||
});
|
||||
transition: string = '0ms';
|
||||
transition = signal('0ms');
|
||||
|
||||
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
|
||||
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
|
||||
@@ -182,7 +183,7 @@ export class SecondaryNavigation implements OnInit {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.transition = `${ANIMATION_DURATION}ms`;
|
||||
this.transition.set(`${ANIMATION_DURATION}ms`);
|
||||
}, ANIMATION_DURATION);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import {InjectionToken} from '@angular/core';
|
||||
|
||||
export const CURRENT_MAJOR_VERSION = new InjectionToken<number>('CURRENT_MAJOR_VERSION');
|
||||
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {Component, Inject} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
|
||||
import {MAT_SNACK_BAR_DATA, MatSnackBarAction, MatSnackBarRef} from '@angular/material/snack-bar';
|
||||
|
||||
export interface ErrorSnackBarData {
|
||||
@@ -16,6 +16,7 @@ export interface ErrorSnackBarData {
|
||||
|
||||
@Component({
|
||||
selector: 'error-snack-bar',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: `
|
||||
{{ message }}
|
||||
<button
|
||||
@@ -28,8 +29,8 @@ export interface ErrorSnackBarData {
|
||||
{{ actionText }}
|
||||
</button>
|
||||
`,
|
||||
imports: [MatSnackBarAction],
|
||||
standalone: true,
|
||||
imports: [MatSnackBarAction],
|
||||
styles: `:host { display: flex; align-items: center; button { margin-left: 16px }}`,
|
||||
})
|
||||
export class ErrorSnackBar {
|
||||
|
||||
@@ -8,17 +8,52 @@
|
||||
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
import {VersionManager} from './version-manager.service';
|
||||
import {INITIAL_ADEV_DOCS_VERSION, VersionManager} from './version-manager.service';
|
||||
import {WINDOW} from '@angular/docs';
|
||||
import {CURRENT_MAJOR_VERSION} from '../providers/current-version';
|
||||
|
||||
describe('VersionManager', () => {
|
||||
const fakeWindow = {location: {hostname: 'angular.dev'}};
|
||||
const fakeCurrentMajorVersion = 19;
|
||||
|
||||
let service: VersionManager;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: WINDOW,
|
||||
useValue: fakeWindow,
|
||||
},
|
||||
{
|
||||
provide: CURRENT_MAJOR_VERSION,
|
||||
useValue: fakeCurrentMajorVersion,
|
||||
},
|
||||
],
|
||||
});
|
||||
service = TestBed.inject(VersionManager);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should contain correct number of Angular Docs versions', () => {
|
||||
// Note: From v2 to v17 (inclusive), there were no v3
|
||||
const expectedAioDocsVersionsCount = 15;
|
||||
|
||||
// Last stable version and next
|
||||
const expectedRecentDocsVersionCount = 2;
|
||||
|
||||
const expectedPreviousAdevVersionsCount = fakeCurrentMajorVersion - INITIAL_ADEV_DOCS_VERSION;
|
||||
|
||||
expect(service['getAioVersions']().length).toBe(expectedAioDocsVersionsCount);
|
||||
expect(service['getRecentVersions']().length).toBe(expectedRecentDocsVersionCount);
|
||||
expect(service['getAdevVersions']().length).toBe(expectedPreviousAdevVersionsCount);
|
||||
expect(service.versions().length).toBe(
|
||||
expectedAioDocsVersionsCount +
|
||||
expectedRecentDocsVersionCount +
|
||||
expectedPreviousAdevVersionsCount,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {Injectable, VERSION, computed, signal} from '@angular/core';
|
||||
import {Injectable, computed, inject, signal} from '@angular/core';
|
||||
import {VERSIONS_CONFIG} from '../constants/versions';
|
||||
import {WINDOW} from '@angular/docs';
|
||||
import {CURRENT_MAJOR_VERSION} from '../providers/current-version';
|
||||
|
||||
export interface Version {
|
||||
displayName: string;
|
||||
@@ -17,39 +19,84 @@ export interface Version {
|
||||
|
||||
export type VersionMode = 'stable' | 'deprecated' | 'rc' | 'next' | number;
|
||||
|
||||
export const INITIAL_DOCS_VERSION = 17;
|
||||
export const VERSION_PATTERN_PLACEHOLDER = '{{version}}';
|
||||
export const INITIAL_ADEV_DOCS_VERSION = 18;
|
||||
export const VERSION_PLACEHOLDER = '{{version}}';
|
||||
export const MODE_PLACEHOLDER = '{{prefix}}';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class VersionManager {
|
||||
private readonly currentMajorVersion = inject(CURRENT_MAJOR_VERSION);
|
||||
private readonly window = inject(WINDOW);
|
||||
|
||||
// Note: We can assume that if the URL starts with v{{version}}, it is documentation for previous versions of Angular.
|
||||
// Based on URL we can indicate as well if it's rc or next Docs version.
|
||||
private get currentVersionMode(): VersionMode {
|
||||
const hostname = this.window.location.hostname;
|
||||
if (hostname.startsWith('v')) return 'deprecated';
|
||||
if (hostname.startsWith('rc')) return 'rc';
|
||||
if (hostname.startsWith('next')) return 'next';
|
||||
|
||||
return 'stable';
|
||||
}
|
||||
|
||||
versions = signal<Version[]>([
|
||||
...VERSIONS_CONFIG.mainVersions.map((item) =>
|
||||
this.mapToVersion(item as Pick<Version, 'url' | 'version'>),
|
||||
),
|
||||
...this.getHistoricalVersions(),
|
||||
...this.getRecentVersions(),
|
||||
...this.getAdevVersions(),
|
||||
...this.getAioVersions(),
|
||||
]);
|
||||
|
||||
currentDocsVersion = computed(() => {
|
||||
return this.versions().find(
|
||||
(version) => version.version.toString() === VERSIONS_CONFIG.currentVersion,
|
||||
(version) => version.version.toString() === this.currentVersionMode,
|
||||
);
|
||||
});
|
||||
|
||||
private getHistoricalVersions(): Version[] {
|
||||
const historicalVersions: Version[] = [];
|
||||
for (let version = Number(VERSION.major) - 1; version >= INITIAL_DOCS_VERSION; version--) {
|
||||
historicalVersions.push({
|
||||
url: VERSIONS_CONFIG.historicalVersionsLinkPattern.replace(
|
||||
VERSION_PATTERN_PLACEHOLDER,
|
||||
version.toString(),
|
||||
),
|
||||
// List of Angular Docs versions which includes current version, next and rc.
|
||||
private getRecentVersions(): Version[] {
|
||||
return [
|
||||
{
|
||||
url: this.getAdevDocsUrl('next'),
|
||||
displayName: `next`,
|
||||
version: 'next',
|
||||
},
|
||||
// Note: 'rc' should not be visible for now
|
||||
// {
|
||||
// url: this.getAdevDocsUrl('rc'),
|
||||
// displayName: `rc`,
|
||||
// version: 'rc',
|
||||
// },
|
||||
{
|
||||
url: this.getAdevDocsUrl(this.currentMajorVersion),
|
||||
displayName: this.getVersion(this.currentMajorVersion),
|
||||
version: this.currentVersionMode,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// List of Angular Docs versions hosted on angular.dev domain.
|
||||
private getAdevVersions(): Version[] {
|
||||
const adevVersions: Version[] = [];
|
||||
for (
|
||||
let version = this.currentMajorVersion - 1;
|
||||
version >= INITIAL_ADEV_DOCS_VERSION;
|
||||
version--
|
||||
) {
|
||||
adevVersions.push({
|
||||
url: this.getAdevDocsUrl(version),
|
||||
displayName: this.getVersion(version),
|
||||
version,
|
||||
version: 'deprecated',
|
||||
});
|
||||
}
|
||||
return historicalVersions;
|
||||
return adevVersions;
|
||||
}
|
||||
|
||||
// List of Angular Docs versions hosted on angular.io domain.
|
||||
private getAioVersions(): Version[] {
|
||||
return VERSIONS_CONFIG.aioVersions.map((item) =>
|
||||
this.mapToVersion(item as Pick<Version, 'url' | 'version'>),
|
||||
);
|
||||
}
|
||||
|
||||
private mapToVersion(value: Pick<Version, 'url' | 'version'>): Version {
|
||||
@@ -60,14 +107,23 @@ export class VersionManager {
|
||||
}
|
||||
|
||||
private getVersion(versionMode: VersionMode): string {
|
||||
if (versionMode === 'stable') {
|
||||
return 'v17';
|
||||
// Temporarily commenting out till this works correctly
|
||||
// return `v${VERSION.major}`;
|
||||
if (versionMode === 'stable' || versionMode === 'deprecated') {
|
||||
return `v${this.currentMajorVersion}`;
|
||||
}
|
||||
if (Number.isInteger(versionMode)) {
|
||||
return `v${versionMode}`;
|
||||
}
|
||||
return versionMode.toString();
|
||||
}
|
||||
|
||||
private getAdevDocsUrl(version: VersionMode): string {
|
||||
const docsUrlPrefix = isNaN(Number(version)) ? `` : 'v';
|
||||
|
||||
return VERSIONS_CONFIG.aDevVersionsLinkPattern
|
||||
.replace(MODE_PLACEHOLDER, docsUrlPrefix)
|
||||
.replace(
|
||||
VERSION_PLACEHOLDER,
|
||||
`${version.toString() === 'stable' ? '' : `${version.toString()}.`}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ $width-breakpoint: 950px;
|
||||
container-name: embedded-editor;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
border: 1px solid var(--senary-contrast);
|
||||
}
|
||||
|
||||
// The entire thing - editor, terminal, console
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import {NgIf, isPlatformBrowser} from '@angular/common';
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
@@ -44,11 +45,12 @@ export const LARGE_EDITOR_WIDTH_BREAKPOINT = 950;
|
||||
export const LARGE_EDITOR_HEIGHT_BREAKPOINT = 550;
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: EMBEDDED_EDITOR_SELECTOR,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [AngularSplitModule, CodeEditor, Preview, Terminal, NgIf, MatTabsModule, IconComponent],
|
||||
templateUrl: './embedded-editor.component.html',
|
||||
styleUrls: ['./embedded-editor.component.scss'],
|
||||
imports: [AngularSplitModule, CodeEditor, Preview, Terminal, NgIf, MatTabsModule, IconComponent],
|
||||
providers: [EditorUiState],
|
||||
})
|
||||
export class EmbeddedEditor implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Terminal} from '@xterm/xterm';
|
||||
import {FitAddon} from 'xterm-addon-fit';
|
||||
import {FitAddon} from '@xterm/addon-fit';
|
||||
import {InteractiveTerminal} from './interactive-terminal';
|
||||
|
||||
export enum TerminalType {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SASS imports, here we're importing a CSS asset
|
||||
//
|
||||
// stylelint-disable-next-line @angular/no-import
|
||||
@import 'xterm/css/xterm.css';
|
||||
@import '@xterm/xterm/css/xterm.css';
|
||||
|
||||
.docs-tutorial-terminal {
|
||||
display: block;
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {DocContent, DocViewer} from '@angular/docs';
|
||||
import {Component, inject} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
|
||||
import {toSignal} from '@angular/core/rxjs-interop';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
import {map} from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'docs-docs',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [CommonModule, DocViewer],
|
||||
styleUrls: ['./docs.component.scss'],
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
EnvironmentInjector,
|
||||
@@ -20,6 +21,7 @@ import {EmbeddedEditor, EmbeddedTutorialManager} from '../../../editor';
|
||||
|
||||
@Component({
|
||||
selector: 'adev-code-editor',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [EmbeddedEditor],
|
||||
template: `
|
||||
|
||||
@@ -2,60 +2,70 @@
|
||||
<div class="adev-top">
|
||||
<div class="adev-top-content">
|
||||
<!-- Banner(s) can be edited here! -->
|
||||
<a href="https://goo.gle/angular-dot-dev" class="adev-banner" target="_blank">
|
||||
<h1 tabindex="-1">Welcome to Angular.dev — the new home for Angular!</h1>
|
||||
<p class="adev-banner-cta">Read about our launch</p>
|
||||
<a href="https://goo.gle/angular-v18" class="adev-banner" target="_blank">
|
||||
<h1 tabindex="-1">Angular v18 is now available!</h1>
|
||||
<p class="adev-banner-cta">Read about our newest release</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="adev-canvas"></div>
|
||||
<div class="adev-logo">
|
||||
<div class="adev-logo-wordmark">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 982 241"
|
||||
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
|
||||
>
|
||||
<g clip-path="url(#wordmark_a)">
|
||||
<path
|
||||
fill="url(#wordmark_b)"
|
||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#wordmark_c)"
|
||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<radialGradient
|
||||
id="wordmark_c"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#FF41F8" />
|
||||
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
|
||||
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="wordmark_b"
|
||||
x1="0"
|
||||
x2="982"
|
||||
y1="192"
|
||||
y2="192"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#F0060B" />
|
||||
<stop offset="0" stop-color="#F0070C" />
|
||||
<stop offset=".526" stop-color="#CC26D5" />
|
||||
<stop offset="1" stop-color="#7702FF" />
|
||||
</linearGradient>
|
||||
<clipPath id="wordmark_a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
@if (!isUwu) {
|
||||
<svg
|
||||
class="angular-logo"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 982 241"
|
||||
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
|
||||
>
|
||||
<g clip-path="url(#wordmark_a)">
|
||||
<path
|
||||
fill="url(#wordmark_b)"
|
||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#wordmark_c)"
|
||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<radialGradient
|
||||
id="wordmark_c"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#FF41F8" />
|
||||
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
|
||||
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="wordmark_b"
|
||||
x1="0"
|
||||
x2="982"
|
||||
y1="192"
|
||||
y2="192"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#F0060B" />
|
||||
<stop offset="0" stop-color="#F0070C" />
|
||||
<stop offset=".526" stop-color="#CC26D5" />
|
||||
<stop offset="1" stop-color="#7702FF" />
|
||||
</linearGradient>
|
||||
<clipPath id="wordmark_a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
} @else {
|
||||
<img
|
||||
src="assets/images/uwu.png"
|
||||
class="uwu-logo"
|
||||
alt="Angular logo"
|
||||
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="adev-scale">
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
import {WINDOW, shouldReduceMotion, isIos} from '@angular/docs';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {ActivatedRoute, RouterLink} from '@angular/router';
|
||||
|
||||
import {injectAsync} from '../../core/services/inject-async';
|
||||
|
||||
@@ -48,8 +48,10 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
private readonly ngZone = inject(NgZone);
|
||||
private readonly platformId = inject(PLATFORM_ID);
|
||||
private readonly window = inject(WINDOW);
|
||||
private readonly activatedRoute = inject(ActivatedRoute);
|
||||
|
||||
protected readonly tutorialFiles = TUTORIALS_HOMEPAGE_DIRECTORY;
|
||||
protected readonly isUwu = 'uwu' in this.activatedRoute.snapshot.queryParams;
|
||||
private element!: HTMLDivElement;
|
||||
private homeAnimation?: HomeAnimation;
|
||||
private intersectionObserver: IntersectionObserver | undefined;
|
||||
@@ -74,7 +76,7 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
// at the end of the page, and to load the embedded editor.
|
||||
this.initIntersectionObserver();
|
||||
|
||||
if (this.isWebGLAvailable() && !shouldReduceMotion()) {
|
||||
if (this.isWebGLAvailable() && !shouldReduceMotion() && !this.isUwu) {
|
||||
this.ngZone.runOutsideAngular(async () => {
|
||||
await this.loadHomeAnimation();
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
display: block;
|
||||
padding: var(--layout-padding);
|
||||
padding-block-end: 100px;
|
||||
height: calc(98vh);
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
|
||||
margin-block-start: var(--layout-padding);
|
||||
cursor: col-resize;
|
||||
align-self: stretch;
|
||||
height: var(--fixed-content-height);
|
||||
height: 100vh;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
@@ -133,7 +133,7 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
|
||||
width: 100%;
|
||||
min-width: 300px;
|
||||
padding-block-start: var(--layout-padding);
|
||||
height: var(--fixed-content-height);
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.adev-split-tutorial {
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
<div class="page docs-viewer">
|
||||
<h1 tabindex="-1">Update Guide</h1>
|
||||
<div class="wizard">
|
||||
<div>
|
||||
<h2>Select the options that match your update</h2>
|
||||
|
||||
<h3>Angular versions</h3>
|
||||
|
||||
<div class="adev-version-selector">
|
||||
<span class="adev-template-select">
|
||||
From v.
|
||||
|
||||
<button [cdkMenuTriggerFor]="templatesMenuFrom">
|
||||
<span>{{ from.name }}</span>
|
||||
<docs-icon>expand_more</docs-icon>
|
||||
</button>
|
||||
|
||||
<ng-template #templatesMenuFrom>
|
||||
<ul class="adev-template-dropdown" cdkMenu>
|
||||
@for (version of versions; track $index) {
|
||||
<li>
|
||||
<button cdkMenuItem type="button" (click)="from=version; showUpdatePath()">
|
||||
<span>{{ version.name }}</span>
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</ng-template>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<span class="adev-template-select">
|
||||
To v.
|
||||
<button [cdkMenuTriggerFor]="templatesMenuTo">
|
||||
<span>{{ to.name }}</span>
|
||||
<docs-icon>expand_more</docs-icon>
|
||||
</button>
|
||||
|
||||
<ng-template #templatesMenuTo>
|
||||
<ul class="adev-template-dropdown" cdkMenu>
|
||||
@for (version of versions; track $index) {
|
||||
<li>
|
||||
<button cdkMenuItem type="button" (click)="to=version; showUpdatePath()">
|
||||
<span>{{ version.name }}</span>
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</ng-template>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@if (from.number >= futureVersion || to.number >= futureVersion) {
|
||||
<div class="docs-alert docs-alert-critical">
|
||||
<p>
|
||||
<strong>Warning:</strong>
|
||||
Plans for releases after the current major release are not finalized and may change.
|
||||
These recommendations are based on scheduled deprecations.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (from.number > to.number) {
|
||||
<div class="docs-alert docs-alert-critical">
|
||||
<p>
|
||||
<strong>Warning:</strong>
|
||||
We do not support downgrading versions of Angular.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if ((to.number - from.number > 150) && from.number > 240) {
|
||||
<div class="docs-alert docs-alert-critical">
|
||||
<p>
|
||||
<strong>Warning:</strong>
|
||||
Be sure to follow the guide below to migrate your application to the new version. You
|
||||
can't run
|
||||
<code>ng update</code>
|
||||
to update Angular applications more than one major version at a time.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
<h3>Application complexity</h3>
|
||||
<mat-button-toggle-group
|
||||
(change)="level = $event.value;"
|
||||
[value]="level"
|
||||
style="margin-bottom:16px;"
|
||||
>
|
||||
<mat-button-toggle [value]="1">Basic</mat-button-toggle>
|
||||
<mat-button-toggle [value]="2">Medium</mat-button-toggle>
|
||||
<mat-button-toggle [value]="3">Advanced</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
@if (level === 1) {
|
||||
<p>Shows information for all Angular developers.</p>
|
||||
} @else if (level === 2) {
|
||||
<p>Shows information that's of interest to more advanced Angular developers.</p>
|
||||
} @else if (level === 3) {
|
||||
<p>Shows all the information we have about this update.</p>
|
||||
}
|
||||
|
||||
<h3>Other dependencies</h3>
|
||||
@for (option of optionList; track $index) {
|
||||
<p>
|
||||
<mat-checkbox
|
||||
(change)="options[option.id] = $event.checked; showUpdatePath()"
|
||||
[checked]="options[option.id]"
|
||||
>I use {{option.name}} {{option.description}}</mat-checkbox
|
||||
>
|
||||
</p>
|
||||
}
|
||||
|
||||
@if (from.number < 600) {
|
||||
<h4>Package Manager</h4>
|
||||
<mat-button-toggle-group
|
||||
(change)="packageManager = $event.value; showUpdatePath()"
|
||||
[value]="packageManager"
|
||||
>
|
||||
<mat-button-toggle value="npm install">npm</mat-button-toggle>
|
||||
<mat-button-toggle value="yarn add">yarn</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
}
|
||||
|
||||
<button
|
||||
type="button"
|
||||
(click)="showUpdatePath()"
|
||||
class="docs-primary-btn show-button"
|
||||
[attr.text]="'Show me how to update!'"
|
||||
>
|
||||
Show me how to update!
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<!-- RECOMMENDATIONS SECTION -->
|
||||
|
||||
@if (
|
||||
beforeRecommendations.length > 0 || duringRecommendations.length > 0 || afterRecommendations.length > 0
|
||||
) {
|
||||
<div class="recommendations">
|
||||
<h2>{{title}}</h2>
|
||||
|
||||
<h3>Before you update</h3>
|
||||
@for (r of beforeRecommendations; track $index) {
|
||||
<div class="adev-recommentation-item">
|
||||
<mat-checkbox></mat-checkbox>
|
||||
<div [innerHTML]="r.renderedStep"></div>
|
||||
</div>
|
||||
}
|
||||
@if (beforeRecommendations.length <= 0) {
|
||||
<div>
|
||||
<em>You don't need to do anything before moving between these versions.</em>
|
||||
</div>
|
||||
}
|
||||
|
||||
<h3>Update to the new version</h3>
|
||||
@if (duringRecommendations.length > 0) {
|
||||
<div>
|
||||
<em>Review these changes and perform the actions to update your application.</em>
|
||||
</div>
|
||||
}
|
||||
|
||||
@for (r of duringRecommendations; track $index) {
|
||||
<div class="adev-recommentation-item">
|
||||
<mat-checkbox></mat-checkbox>
|
||||
<div [innerHTML]="r.renderedStep"></div>
|
||||
</div>
|
||||
}
|
||||
@if (duringRecommendations.length <= 0) {
|
||||
<div>
|
||||
<em>There aren't any recommendations for moving between these versions.</em>
|
||||
</div>
|
||||
}
|
||||
|
||||
<h3>After you update</h3>
|
||||
@for (r of afterRecommendations; track $index) {
|
||||
<div class="adev-recommentation-item">
|
||||
<mat-checkbox></mat-checkbox>
|
||||
<div [innerHTML]="r.renderedStep"></div>
|
||||
</div>
|
||||
}
|
||||
@if (afterRecommendations.length <= 0) {
|
||||
<div>
|
||||
<em>You don't need to do anything after moving between these versions.</em>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -0,0 +1,100 @@
|
||||
.page {
|
||||
padding: var(--layout-padding);
|
||||
max-width: var(--page-width);
|
||||
container: update-guide-page / inline-size;
|
||||
}
|
||||
|
||||
h3,
|
||||
h4 {
|
||||
margin-block-start: 2em;
|
||||
}
|
||||
|
||||
.wizard {
|
||||
padding-inline: 1rem;
|
||||
|
||||
.show-button {
|
||||
display: block;
|
||||
margin-block-start: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.adev-version-selector {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.adev-template-dropdown {
|
||||
border: 1px solid var(--senary-contrast);
|
||||
border-radius: 0.25rem;
|
||||
padding: 0;
|
||||
transform: translateY(-0.7rem);
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
width: 198px;
|
||||
box-sizing: border-box;
|
||||
|
||||
button {
|
||||
background: var(--page-background);
|
||||
font-size: 0.875rem;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding-block: 0.5rem;
|
||||
color: var(--quaternary-contrast);
|
||||
transition:
|
||||
color 0.3s ease,
|
||||
background 0.3s ease;
|
||||
font-weight: 400;
|
||||
|
||||
&:hover {
|
||||
background: var(--senary-contrast);
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.adev-template-select {
|
||||
margin-block-end: 0.5rem;
|
||||
|
||||
// cdk select button
|
||||
button {
|
||||
font-size: 0.875rem;
|
||||
border: 1px solid var(--senary-contrast);
|
||||
border-radius: 0.25rem;
|
||||
width: 200px;
|
||||
display: inline-flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-block: 0.5rem;
|
||||
font-weight: 400;
|
||||
transition: border 0.3s ease;
|
||||
span {
|
||||
color: var(--primary-contrast);
|
||||
transition: color 0.3s ease;
|
||||
margin-inline-start: 0.1rem;
|
||||
}
|
||||
|
||||
docs-icon {
|
||||
font-size: 1.3rem;
|
||||
color: var(--quaternary-contrast);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.adev-recommentation-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> div {
|
||||
margin-inline-start: 2rem;
|
||||
}
|
||||
|
||||
// Code blocks are generable from the markdown, we need to opt-out of the scoping
|
||||
::ng-deep code {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
import {ChangeDetectionStrategy, Component, HostListener, inject} from '@angular/core';
|
||||
import {Step, RECOMMENDATIONS} from './recommendations';
|
||||
import {Clipboard} from '@angular/cdk/clipboard';
|
||||
import {CdkMenuModule} from '@angular/cdk/menu';
|
||||
import {MatCheckboxModule} from '@angular/material/checkbox';
|
||||
import {MatInputModule} from '@angular/material/input';
|
||||
import {MatCardModule} from '@angular/material/card';
|
||||
import {MatGridListModule} from '@angular/material/grid-list';
|
||||
import {MatButtonToggleModule} from '@angular/material/button-toggle';
|
||||
import {IconComponent} from '@angular/docs';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {marked} from 'marked';
|
||||
|
||||
interface Option {
|
||||
id: keyof Step;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'adev-update-guide',
|
||||
templateUrl: './update.component.html',
|
||||
styleUrl: './update.component.scss',
|
||||
imports: [
|
||||
MatCheckboxModule,
|
||||
MatInputModule,
|
||||
MatCardModule,
|
||||
MatGridListModule,
|
||||
MatButtonToggleModule,
|
||||
CdkMenuModule,
|
||||
IconComponent,
|
||||
],
|
||||
standalone: true,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export default class AppComponent {
|
||||
protected title = '';
|
||||
|
||||
protected level = 1;
|
||||
protected options: Record<string, boolean> = {
|
||||
ngUpgrade: false,
|
||||
material: false,
|
||||
windows: isWindows(),
|
||||
};
|
||||
|
||||
protected readonly optionList: Option[] = [
|
||||
{id: 'ngUpgrade', name: 'ngUpgrade', description: 'to combine AngularJS & Angular'},
|
||||
{id: 'material', name: 'Angular Material', description: ''},
|
||||
{id: 'windows', name: 'Windows', description: ''},
|
||||
];
|
||||
|
||||
protected packageManager: 'npm install' | 'yarn add' = 'npm install';
|
||||
|
||||
protected beforeRecommendations: Step[] = [];
|
||||
protected duringRecommendations: Step[] = [];
|
||||
protected afterRecommendations: Step[] = [];
|
||||
|
||||
protected readonly versions = [
|
||||
{name: '18.0', number: 1800},
|
||||
{name: '17.0', number: 1700},
|
||||
{name: '16.0', number: 1600},
|
||||
{name: '15.0', number: 1500},
|
||||
{name: '14.0', number: 1400},
|
||||
{name: '13.0', number: 1300},
|
||||
{name: '12.0', number: 1200},
|
||||
{name: '11.0', number: 1100},
|
||||
{name: '10.2', number: 1020},
|
||||
{name: '10.1', number: 1010},
|
||||
{name: '10.0', number: 1000},
|
||||
{name: '9.1', number: 910},
|
||||
{name: '9.0', number: 900},
|
||||
{name: '8.2', number: 820},
|
||||
{name: '8.1', number: 810},
|
||||
{name: '8.0', number: 800},
|
||||
{name: '7.2', number: 720},
|
||||
{name: '7.1', number: 710},
|
||||
{name: '7.0', number: 700},
|
||||
{name: '6.1', number: 610},
|
||||
{name: '6.0', number: 600},
|
||||
{name: '5.2', number: 520},
|
||||
{name: '5.1', number: 510},
|
||||
{name: '5.0', number: 500},
|
||||
{name: '4.4', number: 440},
|
||||
{name: '4.3', number: 430},
|
||||
{name: '4.2', number: 420},
|
||||
{name: '4.1', number: 410},
|
||||
{name: '4.0', number: 400},
|
||||
{name: '2.4', number: 204},
|
||||
{name: '2.3', number: 203},
|
||||
{name: '2.2', number: 202},
|
||||
{name: '2.1', number: 201},
|
||||
{name: '2.0', number: 200},
|
||||
];
|
||||
protected from = this.versions.find((version) => version.name === '17.0')!;
|
||||
protected to = this.versions.find((version) => version.name === '18.0')!;
|
||||
protected futureVersion = 1900;
|
||||
|
||||
protected readonly steps: Step[] = RECOMMENDATIONS;
|
||||
|
||||
private readonly clipboard = inject(Clipboard);
|
||||
private readonly router = inject(Router);
|
||||
private readonly activatedRoute = inject(ActivatedRoute);
|
||||
|
||||
constructor() {
|
||||
const queryMap = this.activatedRoute.snapshot.queryParamMap;
|
||||
// Detect settings in URL
|
||||
this.level = parseInt(queryMap.get('l')!, 10) || this.level;
|
||||
|
||||
// Detect versions of from and to
|
||||
const versions = queryMap.get('v');
|
||||
if (versions) {
|
||||
const [from, to] = versions.split('-');
|
||||
this.from = this.versions.find((version) => version.name === from)!;
|
||||
this.to = this.versions.find((version) => version.name === to)!;
|
||||
this.showUpdatePath();
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event.target'])
|
||||
copyCode({tagName, textContent}: Element) {
|
||||
if (tagName === 'CODE') {
|
||||
// TODO: add a toast notification
|
||||
this.clipboard.copy(textContent!);
|
||||
}
|
||||
}
|
||||
|
||||
async showUpdatePath() {
|
||||
this.beforeRecommendations = [];
|
||||
this.duringRecommendations = [];
|
||||
this.afterRecommendations = [];
|
||||
|
||||
// Refuse to generate recommendations for downgrades
|
||||
if (this.to.number < this.from.number) {
|
||||
alert('We do not support downgrading versions of Angular.');
|
||||
return;
|
||||
}
|
||||
|
||||
const labelTitle = 'Guide to update your Angular application';
|
||||
const labelBasic = 'basic applications';
|
||||
const labelMedium = 'medium applications';
|
||||
const labelAdvanced = 'advanced applications';
|
||||
|
||||
this.title = `${labelTitle} v${this.from.name} -> v${this.to.name}
|
||||
for
|
||||
${this.level < 2 ? labelBasic : this.level < 3 ? labelMedium : labelAdvanced}`;
|
||||
|
||||
// Find applicable steps and organize them into before, during, and after upgrade
|
||||
for (const step of this.steps) {
|
||||
if (step.level <= this.level && step.necessaryAsOf > this.from.number) {
|
||||
// Check Options
|
||||
// Only show steps that don't have a required option
|
||||
// Or when the user has a matching option selected
|
||||
let skip = false;
|
||||
for (const option of this.optionList) {
|
||||
// Skip steps which require an option not set by the user.
|
||||
if (step[option.id] && !this.options[option.id]) {
|
||||
skip = true;
|
||||
}
|
||||
|
||||
// Skip steps which require **not** using an option which **is** set
|
||||
// by the user.
|
||||
if (step[option.id] === false && this.options[option.id]) {
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
if (skip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Render and replace variables
|
||||
step.renderedStep = await marked(this.replaceVariables(step.action));
|
||||
|
||||
// If you could do it before now, but didn't have to finish it before now
|
||||
if (step.possibleIn <= this.from.number && step.necessaryAsOf >= this.from.number) {
|
||||
this.beforeRecommendations.push(step);
|
||||
// If you couldn't do it before now, and you must do it now
|
||||
} else if (step.possibleIn > this.from.number && step.necessaryAsOf <= this.to.number) {
|
||||
this.duringRecommendations.push(step);
|
||||
} else if (step.possibleIn <= this.to.number) {
|
||||
this.afterRecommendations.push(step);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the URL so users can link to this transition
|
||||
this.router.navigate([], {
|
||||
relativeTo: this.activatedRoute,
|
||||
queryParams: {v: `${this.from.name}-${this.to.name}`, l: this.level},
|
||||
queryParamsHandling: 'merge',
|
||||
});
|
||||
|
||||
// Tell everyone how to upgrade for v6 or earlier
|
||||
this.renderPreV6Instructions();
|
||||
}
|
||||
|
||||
private getAdditionalDependencies(version: number): string {
|
||||
if (version < 500) {
|
||||
return `typescript@'>=2.1.0 <2.4.0'`;
|
||||
} else if (version < 600) {
|
||||
return `typescript@2.4.2 rxjs@^5.5.2`;
|
||||
} else {
|
||||
return `typescript@2.7.x rxjs@^6.0.0`;
|
||||
}
|
||||
}
|
||||
|
||||
private getAngularVersion(version: number): string {
|
||||
if (version < 400) {
|
||||
return `'^2.0.0'`;
|
||||
} else {
|
||||
const major = Math.floor(version / 100);
|
||||
const minor = Math.floor((version - major * 100) / 10);
|
||||
return `^${major}.${minor}.0`;
|
||||
}
|
||||
}
|
||||
|
||||
private async renderPreV6Instructions(): Promise<void> {
|
||||
let upgradeStep: Step;
|
||||
const isWindows = /win/i.test(navigator.platform);
|
||||
const additionalDeps = this.getAdditionalDependencies(this.to.number);
|
||||
const angularVersion = this.getAngularVersion(this.to.number);
|
||||
const angularPackages = [
|
||||
'animations',
|
||||
'common',
|
||||
'compiler',
|
||||
'compiler-cli',
|
||||
'core',
|
||||
'forms',
|
||||
'http',
|
||||
'platform-browser',
|
||||
'platform-browser-dynamic',
|
||||
'platform-server',
|
||||
'router',
|
||||
];
|
||||
|
||||
// Provide npm/yarn instructions for versions before 6
|
||||
if (this.to.number < 600) {
|
||||
const actionMessage = `Update all of your dependencies to the latest Angular and the right version of TypeScript.`;
|
||||
|
||||
if (isWindows) {
|
||||
const packages =
|
||||
angularPackages
|
||||
.map((packageName) => `@angular/${packageName}@${angularVersion}`)
|
||||
.join(' ') +
|
||||
' ' +
|
||||
additionalDeps;
|
||||
|
||||
upgradeStep = {
|
||||
step: 'General Update',
|
||||
action: `${actionMessage}
|
||||
If you are using Windows, you can use:
|
||||
|
||||
\`${this.packageManager} ${packages}\``,
|
||||
} as Step;
|
||||
} else {
|
||||
const packages = `@angular/{${angularPackages.join(',')}}@${angularVersion} ${additionalDeps}`;
|
||||
upgradeStep = {
|
||||
step: 'General update',
|
||||
action: `${actionMessage}
|
||||
If you are using Linux/Mac, you can use:
|
||||
|
||||
\`${this.packageManager} ${packages}\``,
|
||||
} as Step;
|
||||
}
|
||||
|
||||
// Npm installs typescript wrong in v5, let's manually specify
|
||||
// https://github.com/npm/npm/issues/16813
|
||||
if (this.packageManager === 'npm install' && this.to.number === 500) {
|
||||
upgradeStep.action += `
|
||||
|
||||
\`npm install typescript@2.4.2 --save-exact\``;
|
||||
}
|
||||
|
||||
upgradeStep.renderedStep = await marked(upgradeStep.action);
|
||||
|
||||
this.duringRecommendations.push(upgradeStep);
|
||||
}
|
||||
}
|
||||
|
||||
private replaceVariables(action: string): string {
|
||||
let newAction = action;
|
||||
newAction = newAction.replace(
|
||||
'${packageManagerGlobalInstall}',
|
||||
this.packageManager === 'npm install' ? 'npm install -g' : 'yarn global add',
|
||||
);
|
||||
newAction = newAction.replace('${packageManagerInstall}', this.packageManager);
|
||||
return newAction;
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether or not the user is running on a Windows OS. */
|
||||
function isWindows(): boolean {
|
||||
const platform = navigator.platform.toLowerCase();
|
||||
return platform.includes('windows') || platform.includes('win32');
|
||||
}
|
||||
@@ -41,6 +41,12 @@ const referencePageRoutes = mapNavigationItemsToRoutes(
|
||||
},
|
||||
);
|
||||
|
||||
const updateGuidePageRoute: Route = {
|
||||
path: referenceNavigationItems.find((r) => r.path === DefaultPage.UPDATE)!.path,
|
||||
loadComponent: () => import('./features/update/update.component'),
|
||||
data: commonReferenceRouteData,
|
||||
};
|
||||
|
||||
const cliReferencePageRoutes = mapNavigationItemsToRoutes(
|
||||
referenceNavigationItems.filter((r) => r.path?.startsWith(`${PagePrefix.CLI}/`)),
|
||||
{
|
||||
@@ -61,6 +67,7 @@ const docsReferencePageRoutes = mapNavigationItemsToRoutes(
|
||||
referenceNavigationItems.filter(
|
||||
(r) =>
|
||||
r.path !== DefaultPage.REFERENCE &&
|
||||
r.path !== DefaultPage.UPDATE &&
|
||||
!r.path?.startsWith(`${PagePrefix.API}/`) &&
|
||||
!r.path?.startsWith(`${PagePrefix.CLI}/`),
|
||||
),
|
||||
@@ -143,6 +150,7 @@ export const routes: Route[] = [
|
||||
...SUB_NAVIGATION_ROUTES,
|
||||
...API_REFERENCE_ROUTES,
|
||||
...FOOTER_ROUTES,
|
||||
updateGuidePageRoute,
|
||||
],
|
||||
},
|
||||
// Error page
|
||||
|
||||
@@ -640,6 +640,12 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Experimental features',
|
||||
children: [
|
||||
{label: 'Zoneless', path: 'guide/experimental/zoneless', contentPath: 'guide/zoneless'},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -679,9 +685,9 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
contentPath: 'tools/cli/end-to-end',
|
||||
},
|
||||
{
|
||||
label: 'ESBuild',
|
||||
path: 'tools/cli/esbuild',
|
||||
contentPath: 'tools/cli/esbuild',
|
||||
label: 'Migrating to new build system',
|
||||
path: 'tools/cli/build-system-migration',
|
||||
contentPath: 'tools/cli/build-system-migration',
|
||||
},
|
||||
{
|
||||
label: 'Build environments',
|
||||
@@ -1233,6 +1239,11 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
path: 'errors/NG0507',
|
||||
contentPath: 'reference/errors/NG0507',
|
||||
},
|
||||
{
|
||||
label: 'NG0602: HTML content was altered after server-side rendering',
|
||||
path: 'errors/NG0602',
|
||||
contentPath: 'reference/errors/NG0602',
|
||||
},
|
||||
{
|
||||
label: 'NG05104: Root element was not found',
|
||||
path: 'errors/NG05104',
|
||||
@@ -1248,6 +1259,16 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
path: 'errors/NG0912',
|
||||
contentPath: 'reference/errors/NG0912',
|
||||
},
|
||||
{
|
||||
label: 'NG0950: Required input is accessed before a value is set.',
|
||||
path: 'errors/NG0950',
|
||||
contentPath: 'reference/errors/NG0950',
|
||||
},
|
||||
{
|
||||
label: 'NG0951: Child query result is required but no value is available.',
|
||||
path: 'errors/NG0951',
|
||||
contentPath: 'reference/errors/NG0951',
|
||||
},
|
||||
{
|
||||
label: 'NG0955: Track expression resulted in duplicated keys for a given collection',
|
||||
path: 'errors/NG0955',
|
||||
@@ -1370,6 +1391,10 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
path: 'reference/versions',
|
||||
contentPath: 'reference/versions',
|
||||
},
|
||||
{
|
||||
label: 'Update guide',
|
||||
path: 'update-guide',
|
||||
},
|
||||
{
|
||||
label: 'Configurations',
|
||||
children: [
|
||||
|
||||
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 676 B |
|
After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "Angular",
|
||||
"short_name": "Angular",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/assets/icons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/assets/icons/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
"name": "Angular",
|
||||
"short_name": "Angular",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/assets/icons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/assets/icons/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 311 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 211 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 323 KiB |
@@ -35,7 +35,7 @@ class AppComponent implements OnInit {
|
||||
|
||||
The preceding snippet instructs Angular to call `setInterval` outside the Angular Zone and skip running change detection after `pollForUpdates` runs.
|
||||
|
||||
Third-party libraries commonly trigger unnecessary change detection cycles because they weren't authored with Zone.js in mind. Avoid these extra cycles by calling library APIs outside the Angular zone:
|
||||
Third-party libraries commonly trigger unnecessary change detection cycles when their APIs are invoked within the Angular zone. This phenomenon particularly affects libraries that setup event listeners or initiate other tasks (such as timers, XHR requests, etc.). Avoid these extra cycles by calling library APIs outside the Angular zone:
|
||||
|
||||
<docs-code header="Move the plot initialization outside of the Zone" language='ts' linenums>
|
||||
import { Component, NgZone, OnInit } from '@angular/core';
|
||||
@@ -57,3 +57,67 @@ class AppComponent implements OnInit {
|
||||
Running `Plotly.newPlot('chart', data);` within `runOutsideAngular` instructs the framework that it shouldn’t run change detection after the execution of tasks scheduled by the initialization logic.
|
||||
|
||||
For example, if `Plotly.newPlot('chart', data)` adds event listeners to a DOM element, Angular does not run change detection after the execution of their handlers.
|
||||
|
||||
But sometimes, you may need to listen to events dispatched by third-party APIs. In such cases, it's important to remember that those event listeners will also execute outside of the Angular zone if the initialization logic was done there:
|
||||
|
||||
<docs-code header="Check whether the handler is called outside of the Zone" language='ts' linenums>
|
||||
import { Component, NgZone, OnInit, output } from '@angular/core';
|
||||
import * as Plotly from 'plotly.js-dist-min';
|
||||
|
||||
@Component(...)
|
||||
class AppComponent implements OnInit {
|
||||
plotlyClick = output<Plotly.PlotMouseEvent>();
|
||||
|
||||
constructor(private ngZone: NgZone) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.createPlotly();
|
||||
});
|
||||
}
|
||||
|
||||
private async createPlotly() {
|
||||
const plotly = await Plotly.newPlot('chart', data);
|
||||
|
||||
plotly.on('plotly_click', (event: Plotly.PlotMouseEvent) => {
|
||||
// This handler will be called outside of the Angular zone because
|
||||
// the initialization logic is also called outside of the zone. To check
|
||||
// whether we're in the Angular zone, we can call the following:
|
||||
console.log(NgZone.isInAngularZone());
|
||||
this.plotlyClick.emit(event);
|
||||
});
|
||||
}
|
||||
}
|
||||
</docs-code>
|
||||
|
||||
If you need to dispatch events to parent components and execute specific view update logic, you should consider re-entering the Angular zone to instruct the framework to run change detection or run change detection manually:
|
||||
|
||||
<docs-code header="Re-enter the Angular zone when dispatching event" language='ts' linenums>
|
||||
import { Component, NgZone, OnInit, output } from '@angular/core';
|
||||
import * as Plotly from 'plotly.js-dist-min';
|
||||
|
||||
@Component(...)
|
||||
class AppComponent implements OnInit {
|
||||
plotlyClick = output<Plotly.PlotMouseEvent>();
|
||||
|
||||
constructor(private ngZone: NgZone) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.createPlotly();
|
||||
});
|
||||
}
|
||||
|
||||
private async createPlotly() {
|
||||
const plotly = await Plotly.newPlot('chart', data);
|
||||
|
||||
plotly.on('plotly_click', (event: Plotly.PlotMouseEvent) => {
|
||||
this.ngZone.run(() => {
|
||||
this.plotlyClick.emit(event);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
</docs-code>
|
||||
|
||||
The scenario of dispatching events outside of the Angular zone may also arise. It's important to remember that triggering change detection (for example, manually) may result to the creation/update of views outside of the Angular zone.
|
||||
@@ -730,7 +730,7 @@ If the property is hard to construct a default value for, use `?` to explicitly
|
||||
|
||||
You may want to have a required `@Input` field, meaning all your component users are required to pass that attribute.
|
||||
In such cases, use a default value.
|
||||
Just suppressing the TypeScript error with `!` is insufficient and should be avoided because it will prevent the type checker ensure the input value is provided.
|
||||
Just suppressing the TypeScript error with `!` is insufficient and should be avoided because it will prevent the type checker from ensuring the input value is provided.
|
||||
|
||||
<docs-code header="app/heroes/hero/hero.component.ts" path="adev/src/content/examples/styleguide/src/05-18/app/heroes/hero/hero.component.avoid.ts" visibleRegion="example"/>
|
||||
|
||||
|
||||
@@ -13,11 +13,11 @@ HELPFUL: If you are currently using AngularJS, see [Upgrading from AngularJS](ht
|
||||
|
||||
## Getting notified of new releases
|
||||
|
||||
To be notified when new releases are available, follow [@angular](https://twitter.com/angular "@angular on Twitter") on Twitter or subscribe to the [Angular blog](https://blog.angular.io "Angular blog").
|
||||
To be notified when new releases are available, follow [@angular](https://twitter.com/angular "@angular on Twitter") on Twitter or subscribe to the [Angular blog](https://blog.angular.dev "Angular blog").
|
||||
|
||||
## Learning about new features
|
||||
|
||||
What's new? What's changed? We share the most important things you need to know on the Angular blog in [release announcements]( https://blog.angular.io/ "Angular blog - release announcements").
|
||||
What's new? What's changed? We share the most important things you need to know on the Angular blog in [release announcements]( https://blog.angular.dev/ "Angular blog - release announcements").
|
||||
|
||||
To review a complete list of changes, organized by version, see the [Angular change log](https://github.com/angular/angular/blob/main/CHANGELOG.md "Angular change log").
|
||||
|
||||
@@ -49,7 +49,7 @@ It also describes supported update paths.
|
||||
## Resource summary
|
||||
|
||||
* Release announcements:
|
||||
[Angular blog - release announcements](https://blog.angular.io/ "Angular blog announcements about recent releases")
|
||||
[Angular blog - release announcements](https://blog.angular.dev/ "Angular blog announcements about recent releases")
|
||||
|
||||
* Release details:
|
||||
[Angular change log](https://github.com/angular/angular/blob/main/CHANGELOG.md "Angular change log")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"branchName": "refs/heads/main",
|
||||
"sha": "5bcfd647fd2a4224c03514c852fd0386bce2fbad"
|
||||
"branchName": "refs/heads/18.0.x",
|
||||
"sha": "219dbb2efde238fe2cd4bd9e5ac463ba9908220a"
|
||||
}
|
||||
@@ -142,7 +142,7 @@
|
||||
"name": "optimization",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Enables optimization of the build output. Including minification of scripts and styles, tree-shaking, dead-code elimination, inlining of critical CSS and fonts inlining. For more information, see https://angular.io/guide/workspace-config#optimization-configuration."
|
||||
"description": "Enables optimization of the build output. Including minification of scripts and styles, tree-shaking, dead-code elimination, inlining of critical CSS and fonts inlining. For more information, see https://angular.dev/reference/configs/workspace-config#optimization-configuration."
|
||||
},
|
||||
{
|
||||
"name": "output-hashing",
|
||||
@@ -208,7 +208,7 @@
|
||||
"name": "source-map",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Output source maps for scripts and styles. For more information, see https://angular.io/guide/workspace-config#source-map-configuration."
|
||||
"description": "Output source maps for scripts and styles. For more information, see https://angular.dev/reference/configs/workspace-config#source-map-configuration."
|
||||
},
|
||||
{
|
||||
"name": "ssr",
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
{
|
||||
"name": "proxy-config",
|
||||
"type": "string",
|
||||
"description": "Proxy configuration file. For more information, see https://angular.io/guide/build#proxying-to-a-backend-server."
|
||||
"description": "Proxy configuration file. For more information, see https://angular.dev/tools/cli/serve#proxying-to-a-backend-server."
|
||||
},
|
||||
{
|
||||
"name": "public-host",
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
"name": "source-map",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Output source maps for scripts and styles. For more information, see https://angular.io/guide/workspace-config#source-map-configuration."
|
||||
"description": "Output source maps for scripts and styles. For more information, see https://angular.dev/reference/configs/workspace-config#source-map-configuration."
|
||||
},
|
||||
{
|
||||
"name": "ts-config",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "update",
|
||||
"command": "ng update [packages..]",
|
||||
"shortDescription": "Updates your workspace and its dependencies. See https://update.angular.io/.",
|
||||
"shortDescription": "Updates your workspace and its dependencies. See https://update.angular.dev/.",
|
||||
"longDescriptionRelativePath": "@angular/cli/src/commands/update/long-description.md",
|
||||
"longDescription": "Perform a basic update to the current stable release of the core framework and CLI by running the following command.\n\n```\nng update @angular/cli @angular/core\n```\n\nTo update to the next beta or pre-release version, use the `--next` option.\n\nTo update from one major version to another, use the format\n\n```\nng update @angular/cli@^<major_version> @angular/core@^<major_version>\n```\n\nWe recommend that you always update to the latest patch version, as it contains fixes we released since the initial major release.\nFor example, use the following command to take the latest 10.x.x version and use that to update.\n\n```\nng update @angular/cli@^10 @angular/core@^10\n```\n\nFor detailed information and guidance on updating your application, see the interactive [Angular Update Guide](https://update.angular.io/).\n",
|
||||
"longDescription": "Perform a basic update to the current stable release of the core framework and CLI by running the following command.\n\n```\nng update @angular/cli @angular/core\n```\n\nTo update to the next beta or pre-release version, use the `--next` option.\n\nTo update from one major version to another, use the format\n\n```\nng update @angular/cli@^<major_version> @angular/core@^<major_version>\n```\n\nWe recommend that you always update to the latest patch version, as it contains fixes we released since the initial major release.\nFor example, use the following command to take the latest 10.x.x version and use that to update.\n\n```\nng update @angular/cli@^10 @angular/core@^10\n```\n\nFor detailed information and guidance on updating your application, see the interactive [Angular Update Guide](https://update.angular.dev/).\n",
|
||||
"aliases": [],
|
||||
"deprecated": false,
|
||||
"options": [
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
|
||||
<h2><a target="_blank" rel="noopener" href="https://blog.angular.dev/">Angular blog</a></h2>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -70,7 +70,7 @@ as `::shadow` or `::part`.
|
||||
|
||||
#### `::ng-deep`
|
||||
|
||||
Angular's emulated encapsulation mode supports a custom pseudo class, `:ng-deep`. Applying this
|
||||
Angular's emulated encapsulation mode supports a custom pseudo class, `::ng-deep`. Applying this
|
||||
pseudo class to a CSS rule disables encapsulation for that rule, effectively turning it into a
|
||||
global style. **The Angular team strongly discourages new use of `::ng-deep`**. These APIs remain
|
||||
exclusively for backwards compatibility.
|
||||
|
||||
@@ -128,7 +128,7 @@ Keep in mind that adding the `ngSkipHydration` attribute to your root applicatio
|
||||
|
||||
## I18N
|
||||
|
||||
HELPFUL: Support for internationalization with hydration is currently in [developer preview](/guide/releases#developer-preview). By default, Angular will skip hydration for components that use i18n blocks, effectively re-rendering those components from scratch.
|
||||
HELPFUL: Support for internationalization with hydration is currently in [developer preview](/reference/releases#developer-preview). By default, Angular will skip hydration for components that use i18n blocks, effectively re-rendering those components from scratch.
|
||||
|
||||
To enable hydration for i18n blocks, you can add [`withI18nSupport`](/api/platform-browser/withI18nSupport) to your `provideClientHydration` call.
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ its `set` or `update` methods.
|
||||
## Customizing model inputs
|
||||
|
||||
You can mark a model input as required or provide an alias in the same way as a
|
||||
[standard input](guide/signal-inputs).
|
||||
[standard input](guide/signals/inputs).
|
||||
|
||||
Model inputs do not support input transforms.
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ In this test suite, the *only* provider of `UserService` is the root testing mod
|
||||
|
||||
<docs-code header="TestBed injector" path="adev/src/content/examples/testing/src/app/welcome/welcome.component.spec.ts" visibleRegion="inject-from-testbed" />
|
||||
|
||||
HELPFUL: For a use case in which `TestBed.inject()` does not work, see the [*Override component providers*](#component-override) section that explains when and why you must get the service from the component's injector instead.
|
||||
HELPFUL: For a use case in which `TestBed.inject()` does not work, see the [*Override component providers*](#override-component-providers) section that explains when and why you must get the service from the component's injector instead.
|
||||
|
||||
### Final setup and tests
|
||||
|
||||
|
||||
@@ -28,28 +28,6 @@ platformBrowser().bootstrapModule(AppModule, {ngZone: 'noop'});
|
||||
export class AppModule {}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
The zoneless provider function can also be used with `TestBed` to help
|
||||
ensure the components under test are compatible with a Zoneless
|
||||
Angular application.
|
||||
|
||||
```typescript
|
||||
TestBed.configureTestingModule({
|
||||
providers: [provideExperimentalZonelessChangeDetection()]
|
||||
});
|
||||
|
||||
const fixture = TestBed.createComponent(MyComponent);
|
||||
await fixture.whenStable();
|
||||
```
|
||||
|
||||
To ensure tests have the most similar behavior to production code,
|
||||
avoid using `fixture.detectChanges()` when possibe. This forces
|
||||
change detection to run when Angular might otherwise have not
|
||||
scheduled change detection. Tests should ensure these notifications
|
||||
are happening and allow Angular to handle when to synchronize
|
||||
state rather than manually forcing it to happen in the test.
|
||||
|
||||
## Requirements for Zoneless compatibility
|
||||
|
||||
Angular relies on notifications from core APIs in order to determine when to run change detection and on which views.
|
||||
@@ -106,3 +84,35 @@ taskCleanup();
|
||||
The framework uses this service internally as well to prevent serialization until asynchronous tasks are complete. These include, but are not limited to,
|
||||
an ongoing Router navigation and an incomplete `HttpClient` request.
|
||||
|
||||
## Testing and Debugging
|
||||
|
||||
### Using Zoneless in `TestBed`
|
||||
|
||||
The zoneless provider function can also be used with `TestBed` to help
|
||||
ensure the components under test are compatible with a Zoneless
|
||||
Angular application.
|
||||
|
||||
```typescript
|
||||
TestBed.configureTestingModule({
|
||||
providers: [provideExperimentalZonelessChangeDetection()]
|
||||
});
|
||||
|
||||
const fixture = TestBed.createComponent(MyComponent);
|
||||
await fixture.whenStable();
|
||||
```
|
||||
|
||||
To ensure tests have the most similar behavior to production code,
|
||||
avoid using `fixture.detectChanges()` when possibe. This forces
|
||||
change detection to run when Angular might otherwise have not
|
||||
scheduled change detection. Tests should ensure these notifications
|
||||
are happening and allow Angular to handle when to synchronize
|
||||
state rather than manually forcing it to happen in the test.
|
||||
|
||||
### Debug-mode check to ensure updates are detected
|
||||
|
||||
Angular also provides an additional tool to help verify that an application is making
|
||||
updates to state in a zoneless-compatible way. `provideExperimentalCheckNoChangesForDebug`
|
||||
can be used to periodically check to ensure that no bindings have been updated
|
||||
without a notification. Angular will throw `ExpressionChangedAfterItHasBeenCheckedError`
|
||||
if there is an updated binding that would not have refreshed by the zoneless change
|
||||
detection.
|
||||
|
||||
@@ -9,14 +9,13 @@
|
||||
| [`completion`](cli/completion) | | Set up Angular CLI autocompletion for your terminal. |
|
||||
| [`config`](cli/config) | | Retrieves or sets Angular configuration values in the angular.json file for the workspace. |
|
||||
| [`deploy`](cli/deploy) | | Invokes the deploy builder for a specified project or for the default project in the workspace. |
|
||||
| [`doc`](cli/doc) | `d` | Opens the official Angular documentation (angular.io) in a browser, and searches for a given keyword. |
|
||||
| [`e2e`](cli/e2e) | `e` | Builds and serves an Angular application, then runs end-to-end tests. |
|
||||
| [`extract-i18n`](cli/extract-i18n)| | Extracts i18n messages from source code. |
|
||||
| [`generate`](cli/generate) | `g` | Generates and/or modifies files based on a schematic. |
|
||||
| [`lint`](cli/lint) | | Runs linting tools on Angular application code in a given project folder. |
|
||||
| [`new`](cli/new) | `n` | Creates a new Angular workspace. |
|
||||
| [`run`](cli/run) | | Runs an Architect target with an optional custom builder configuration defined in your project. |
|
||||
| [`serve`](cli/serve) | `s` | Builds and serves your application, rebuilding on file changes. |
|
||||
| [`serve`](cli/serve) | `s`, `dev` | Builds and serves your application, rebuilding on file changes. |
|
||||
| [`test`](cli/test) | `t` | Runs unit tests in a project. |
|
||||
| [`update`](cli/update) | | Updates your workspace and its dependencies. See https://update.angular.io/. |
|
||||
| [`version`](cli/version) | `v` | Outputs Angular CLI version. |
|
||||
|
||||
@@ -64,7 +64,7 @@ Subfolders contain the application source and application-specific configuration
|
||||
| Application support files | Purpose |
|
||||
|:--- |:--- |
|
||||
| `app/` | Contains the component files in which your application logic and data are defined. See details [below](#app-src). |
|
||||
| `assets/` | Contains image and other asset files to be served as static files by the dev server and copied as-is when you build your application. |
|
||||
| `public/` | Contains image and other asset files to be served as static files by the dev server and copied as-is when you build your application. |
|
||||
| `favicon.ico` | An icon to use for this application in the bookmark bar. |
|
||||
| `index.html` | The main HTML page that is served when someone visits your site. The CLI automatically adds all JavaScript and CSS files when building your app, so you typically don't need to add any `<script>` or`<link>` tags here manually. |
|
||||
| `main.ts` | The main entry point for your application. |
|
||||
|
||||
@@ -139,7 +139,7 @@ Each target under `architect` has the following properties:
|
||||
|:--- |:--- |
|
||||
| `builder` | The CLI builder used to create this target in the form of `<package-name>:<builder-name>`. |
|
||||
| `options` | Build target default options. |
|
||||
| `configurations`| Alternative configurations for executing the target. Each configuration sets the default options for that intended environment, overriding the associated value under `options`. See [Alternate build configurations](#alternate-build-configs) below. |
|
||||
| `configurations`| Alternative configurations for executing the target. Each configuration sets the default options for that intended environment, overriding the associated value under `options`. See [Alternate build configurations](#alternate-build-configurations) below. |
|
||||
|
||||
For example, to configure a build with optimizations disabled:
|
||||
|
||||
@@ -220,7 +220,7 @@ For details of those options and their possible values, see the [Angular CLI Ref
|
||||
| `scripts` | An object containing JavaScript files to add to the application. The scripts are loaded exactly as if you had added them in a `<script>` tag inside `index.html`. See more in the [Styles and scripts configuration](#styles-and-scripts-configuration) section. |
|
||||
| `budgets` | Default size-budget type and thresholds for all or parts of your application. You can configure the builder to report a warning or an error when the output reaches or exceeds a threshold size. See [Configure size budgets](tools/cli/build#configure-size-budgets). |
|
||||
| `fileReplacements` | An object containing files and their compile-time replacements. See more in [Configure target-specific file replacements](tools/cli/build#configure-target-specific-file-replacements). |
|
||||
| `index` | A base HTML document which loads the application. See more in [Index configuration](#index-config). |
|
||||
| `index` | A base HTML document which loads the application. See more in [Index configuration](#index-configuration). |
|
||||
|
||||
## Complex configuration values
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
@name Disallowed function call inside reactive context
|
||||
@category runtime
|
||||
@shortDescription A disallowed function is called inside a reactive context
|
||||
# Disallowed function call inside reactive context
|
||||
|
||||
@description
|
||||
A function that is not allowed to run inside a reactive context was called from within a reactive context.
|
||||
|
||||
For example, an `effect` cannot be scheduled from within a `computed` or an actively executing effect.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Required input is accessed before a value is set.
|
||||
|
||||
@description
|
||||
A required input was accessed but no value was bound.
|
||||
|
||||
This can happen when a required input is accessed too early in your directive or component.
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
@name Child query result is required but no value is available.
|
||||
@category runtime
|
||||
@shortDescription Required child query result was accessed before query results were calculated or query has no matches.
|
||||
# Child query result is required but no value is available.
|
||||
|
||||
@description
|
||||
Required child query (`contentChild.required` or `viewChild.required`) result was accessed before query results were calculated or query has no matches.
|
||||
|
||||
This can happen in two distinct situations:
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
@name Track expression resulted in duplicated keys for a given collection.
|
||||
@category runtime
|
||||
@shortDescription A track expression specified in the `@for` loop evaluated to duplicated keys for a given collection. Duplicate keys are problematic from the correctness point of view and the tracking expression should be updated.
|
||||
# Track expression resulted in duplicated keys for a given collection.
|
||||
|
||||
@description
|
||||
A track expression specified in the `@for` loop evaluated to duplicated keys for a given collection, ex.:
|
||||
|
||||
```typescript
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
@name Tracking expression caused re-creation of the DOM structure.
|
||||
@category runtime
|
||||
@shortDescription The configured tracking expression (track by identity) caused re-creation of the DOM structure for the entire collection, which is problematic from the performance and correctness point of view.
|
||||
# Tracking expression caused re-creation of the DOM structure.
|
||||
|
||||
@description
|
||||
The identity track expression specified in the `@for` loop caused re-creation of the DOM corresponding to _all_ items. This is very expensive operation that commonly occurs when working with immutable data structures, Example:
|
||||
|
||||
```typescript
|
||||
|
||||
@@ -94,11 +94,11 @@ The following table provides the status for Angular versions under support.
|
||||
|
||||
| Version | Status | Released | Active ends | LTS ends |
|
||||
|:--------|:-------|:-----------|:------------|:-----------|
|
||||
| ^17.0.0 | Active | 2023-11-08 | 2024-05-08 | 2025-05-15 |
|
||||
| ^18.0.0 | Active | 2024-05-22 | 2024-11-xx | 2025-11-xx |
|
||||
| ^17.0.0 | LTS | 2023-11-08 | 2024-05-08 | 2025-05-15 |
|
||||
| ^16.0.0 | LTS | 2023-05-03 | 2023-11-08 | 2024-11-08 |
|
||||
| ^15.0.0 | LTS | 2022-11-18 | 2023-05-03 | 2024-05-18 |
|
||||
|
||||
Angular versions v2 to v14 are no longer supported.
|
||||
Angular versions v2 to v15 are no longer supported.
|
||||
|
||||
### LTS fixes
|
||||
|
||||
@@ -163,3 +163,9 @@ Occasionally we introduce new APIs under the label of "Developer Preview". These
|
||||
This may be because we want to gather feedback from real applications before stabilization, or because the associated documentation or migration tooling is not fully complete.
|
||||
|
||||
The policies and practices that are described in this document do not apply to APIs marked as Developer Preview. Such APIs can change at any time, even in new patch versions of the framework. Teams should decide for themselves whether the benefits of using Developer Preview APIs are worth the risk of breaking changes outside of our normal use of semantic versioning.
|
||||
|
||||
## Experimental
|
||||
|
||||
These are APIs might not become stable at all or have significant changes before becoming stable.
|
||||
|
||||
The policies and practices that are described in this document do not apply to APIs marked as experimental. Such APIs can change at any time, even in new patch versions of the framework. Teams should decide for themselves whether the benefits of using experimental APIs are worth the risk of breaking changes outside of our normal use of semantic versioning.
|
||||
|
||||