mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 98de185e53 |
+3
-1
@@ -5,6 +5,9 @@
|
||||
.git
|
||||
node_modules
|
||||
dist
|
||||
aio/node_modules
|
||||
aio/tools/examples/shared/node_modules
|
||||
aio/tools/examples/shared/example-scaffold
|
||||
|
||||
# All integration test node_modules folders
|
||||
integration/animations/node_modules
|
||||
@@ -14,7 +17,6 @@ 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,12 +60,14 @@ 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. #
|
||||
# To build with a partiular configuration: #
|
||||
# bazel build //aio:build --aio_build_config=<config> #
|
||||
# Default config is `stable``. #
|
||||
##########################################################
|
||||
build --flag_alias=aio_build_config=//aio:flag_aio_build_config
|
||||
|
||||
###############################
|
||||
# Output #
|
||||
|
||||
@@ -44,7 +44,7 @@ function setSecretVar() {
|
||||
# Create a function to set an environment variable, when called.
|
||||
#
|
||||
# Use this function for creating setter for public environment variables that require expensive or
|
||||
# time-consuming computations and may not be needed. When needed, you can call this function to set
|
||||
# time-consuming computaions and may not be needed. When needed, you can call this function to set
|
||||
# the environment variable (which will be available through `$BASH_ENV` from that point onwards).
|
||||
#
|
||||
# Arguments:
|
||||
|
||||
@@ -16,6 +16,7 @@ echo "source $envHelpersPath;" >> $BASH_ENV;
|
||||
####################################################################################################
|
||||
setPublicVar CI "$CI"
|
||||
setPublicVar PROJECT_ROOT "$projectDir";
|
||||
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
|
||||
# This is the branch being built; e.g. `pull/12345` for PR builds.
|
||||
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
|
||||
setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL";
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
"postCreateCommand": "yarn install",
|
||||
"extensions": [
|
||||
"devondcarew.bazel-code",
|
||||
"ms-vscode.vscode-typescript-tslint-plugin"
|
||||
"gkalpak.aio-docs-utils",
|
||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||
// The following extensions are useful when working on angular.io (i.e. inside the `aio/` directory).
|
||||
//"angular.ng-template",
|
||||
//"dbaeumer.vscode-eslint",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
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",
|
||||
],
|
||||
)
|
||||
@@ -1,19 +0,0 @@
|
||||
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
|
||||
githubReleaseTrainReadToken:
|
||||
description: 'GitHub access token for reading release trains without rate limits.'
|
||||
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'
|
||||
@@ -1,23 +0,0 @@
|
||||
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",
|
||||
],
|
||||
)
|
||||
@@ -1,20 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
/** Github access token. Used for querying the active release trains. */
|
||||
export const githubReleaseTrainReadToken: string = getInput('githubReleaseTrainReadToken', {
|
||||
required: true,
|
||||
});
|
||||
@@ -1,116 +0,0 @@
|
||||
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(),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
import {fetchLongTermSupportBranchesFromNpm, ActiveReleaseTrains} from '@angular/ng-dev';
|
||||
import {ReleaseConfig} from '@angular/ng-dev';
|
||||
import {AuthenticatedGitClient} 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 AuthenticatedGitClient.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;
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import {getInput, setFailed} from '@actions/core';
|
||||
import {context} from '@actions/github';
|
||||
import {deployToFirebase, setupRedirect} from './deploy';
|
||||
import {getDeployments} from './deployments';
|
||||
import {AuthenticatedGitClient, GithubConfig, setConfig} from '@angular/ng-dev';
|
||||
import {githubReleaseTrainReadToken} from './credential';
|
||||
|
||||
const refMatcher = /refs\/heads\/(.*)/;
|
||||
|
||||
async function deployDocs() {
|
||||
setConfig({
|
||||
github: <GithubConfig>{
|
||||
mainBranchName: 'main',
|
||||
name: 'angular',
|
||||
owner: 'angular',
|
||||
},
|
||||
});
|
||||
|
||||
AuthenticatedGitClient.configure(githubReleaseTrainReadToken);
|
||||
|
||||
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.',
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build //adev:build --config=release
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
run: yarn bazel build //adev:build
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
bazelrc: ./.bazelrc.user
|
||||
|
||||
|
||||
+54
-157
@@ -5,6 +5,9 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- '[0-9]+.[0-9]+.x'
|
||||
- 'browser-update-test'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -17,158 +20,27 @@ defaults:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
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
|
||||
|
||||
devtools:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/saucelabs@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Set up Sauce Tunnel Daemon
|
||||
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
|
||||
env:
|
||||
@@ -178,25 +50,50 @@ 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}
|
||||
|
||||
adev-deploy:
|
||||
needs: [adev]
|
||||
if: needs.adev.result == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- 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 }}
|
||||
githubReleaseTrainReadToken: ${{ secrets.DOCS_DEPLOY_GITHUB_RELEASE_TRAIN_TOKEN }}
|
||||
configPath: 'adev/firebase.json'
|
||||
distDir: 'dist/bin/adev/build/browser'
|
||||
- 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
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ jobs:
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@11bd341a82719997a59039363f716bea76b88459
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
post_approval_changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -13,8 +13,8 @@ jobs:
|
||||
statuses: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
name: Monitoring
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run at 10:00AM every day.
|
||||
- cron: '0 10 * * *'
|
||||
|
||||
permissions: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check_aio:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MINIMUM_PWA_SCORE: 95
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ['https://next.angular.io/', 'https://angular.io/']
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Run basic e2e and deployment config tests.
|
||||
run: yarn --cwd aio test-production-url --test_env=TARGET_URL="${{ matrix.version }}"
|
||||
- name: Run PWA-score tests.
|
||||
run: yarn --cwd aio test-pwa-score "${{ matrix.version }}" "${{ env.MINIMUM_PWA_SCORE }}"
|
||||
- name: Run a11y tests.
|
||||
run: yarn --cwd aio test-a11y-score "${{ matrix.version }}"
|
||||
|
||||
check_contributor_links:
|
||||
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
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Check website provided in contributors.json file
|
||||
run: node aio/scripts/test-external-urls.js
|
||||
@@ -1,208 +0,0 @@
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
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 }}
|
||||
- name: Check Package Licenses
|
||||
uses: angular/dev-infra/github-actions/linting/licenses@515b575bd6650a12353b6039b618cdb808280ad7
|
||||
|
||||
devtools:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
run: yarn test:ci
|
||||
|
||||
artifacts:
|
||||
needs: [test]
|
||||
if: needs.test.result == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
run: yarn tsx ./scripts/build/build-packages-dist.mts
|
||||
- name: Archive build artifacts
|
||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
|
||||
with:
|
||||
name: pr-artifacts-${{ github.event.number }}
|
||||
path: dist/packages-dist/
|
||||
|
||||
adev:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
- 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: 'Run analysis'
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
|
||||
# Upload the results as artifacts.
|
||||
- name: 'Upload artifact'
|
||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.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@2d790406f505036ef40ecba973cc774a50395aac # v3.25.13
|
||||
uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Update ADEV Angular CLI help
|
||||
name: Update AIO Angular CLI help
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
branch-prefix: update-cli-help
|
||||
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
|
||||
|
||||
+2
-5
@@ -56,11 +56,8 @@ baseline.json
|
||||
|
||||
# Husky
|
||||
.husky/_
|
||||
aio/content/examples/.DS_Store
|
||||
|
||||
|
||||
# Ignore cache created with the Angular CLI.
|
||||
.angular/
|
||||
|
||||
# Ignore AIO files, useful when changing branches
|
||||
aio/node_modules
|
||||
aio/out-tsc
|
||||
.angular/
|
||||
+2
-3
@@ -22,9 +22,8 @@ export const format: FormatConfig = {
|
||||
'!packages/common/src/i18n/currencies.ts',
|
||||
// Test cases contain non valid code.
|
||||
'!packages/compiler-cli/test/compliance/test_cases/**/*.{js,ts}',
|
||||
|
||||
// Ignore generated javascript file(s)
|
||||
'!.github/actions/deploy-docs-site/main.js',
|
||||
// Ignore AIO as its pending removal.
|
||||
'!aio/**/*.{js,ts}',
|
||||
],
|
||||
},
|
||||
'buildifier': true,
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ export const release: ReleaseConfig = {
|
||||
return performNpmReleaseBuild();
|
||||
},
|
||||
releaseNotes: {
|
||||
hiddenScopes: ['bazel', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'],
|
||||
hiddenScopes: ['aio', 'bazel', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'],
|
||||
},
|
||||
releasePrLabels: ['area: build & ci', 'action: merge', 'PullApprove: disable'],
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"tabs": false,
|
||||
"embeddedLanguageFormatting": "off",
|
||||
"singleQuote": true,
|
||||
"semi": true,
|
||||
"semicolon": true,
|
||||
"quoteProps": "preserve",
|
||||
"bracketSpacing": false
|
||||
}
|
||||
|
||||
+552
-9
@@ -121,6 +121,19 @@ groups:
|
||||
contains_any_globs(files, [
|
||||
'packages/animations/**/{*,.*}',
|
||||
'packages/platform-browser/animations/**/{*,.*}',
|
||||
'aio/content/guide/animations.md',
|
||||
'aio/content/guide/add-an-animation.md',
|
||||
'aio/content/guide/animate-state-style.md',
|
||||
'aio/content/guide/animation-api-summary.md',
|
||||
'aio/content/guide/understanding-angular-animation.md',
|
||||
'aio/content/examples/animations/**/{*,.*}',
|
||||
'aio/content/images/guide/animations/**/{*,.*}',
|
||||
'aio/content/guide/complex-animation-sequences.md',
|
||||
'aio/content/guide/reusable-animations.md',
|
||||
'aio/content/guide/route-animations.md',
|
||||
'aio/content/guide/transition-and-triggers.md',
|
||||
'aio/content/guide/animations-attach-to-html-template.md',
|
||||
'aio/content/guide/animation-transition-timing.md'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -139,7 +152,13 @@ groups:
|
||||
contains_any_globs(files, [
|
||||
'packages/compiler/**/{*,.*}',
|
||||
'packages/examples/compiler/**/{*,.*}',
|
||||
'aio/content/examples/angular-compiler-options/**/{*,.*}',
|
||||
'packages/compiler-cli/**/{*,.*}',
|
||||
'aio/content/guide/angular-compiler-options.md',
|
||||
'aio/content/guide/aot-compiler.md',
|
||||
'aio/content/guide/aot-metadata-errors.md',
|
||||
'aio/content/guide/template-typecheck.md',
|
||||
'aio/content/extended-diagnostics/*.md'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -181,6 +200,155 @@ groups:
|
||||
'packages/examples/platform-browser/**/{*,.*}',
|
||||
'packages/platform-browser-dynamic/**/{*,.*}',
|
||||
'packages/docs/**/{*,.*}',
|
||||
'aio/content/guide/accessibility.md',
|
||||
'aio/content/examples/accessibility/**/{*,.*}',
|
||||
'aio/content/guide/architecture-components.md',
|
||||
'aio/content/guide/architecture-modules.md',
|
||||
'aio/content/guide/architecture-next-steps.md',
|
||||
'aio/content/guide/architecture-services.md',
|
||||
'aio/content/guide/architecture.md',
|
||||
'aio/content/examples/architecture/**/{*,.*}',
|
||||
'aio/content/guide/rxjs-interop.md',
|
||||
'aio/content/images/guide/architecture/**/{*,.*}',
|
||||
'aio/content/guide/attribute-directives.md',
|
||||
'aio/content/examples/attribute-directives/**/{*,.*}',
|
||||
'aio/content/images/guide/attribute-directives/**/{*,.*}',
|
||||
'aio/content/guide/bootstrapping.md',
|
||||
'aio/content/examples/bootstrapping/**/{*,.*}',
|
||||
'aio/content/guide/change-detection.md',
|
||||
'aio/content/guide/change-detection-zone-pollution.md',
|
||||
'aio/content/guide/change-detection-slow-computations.md',
|
||||
'aio/content/guide/change-detection-skipping-subtrees.md',
|
||||
'aio/content/images/guide/change-detection/**/{*,.*}',
|
||||
'aio/content/guide/class-binding.md',
|
||||
'aio/content/guide/cheatsheet.md',
|
||||
'aio/content/guide/component-interaction.md',
|
||||
'aio/content/examples/component-interaction/**/{*,.*}',
|
||||
'aio/content/images/guide/component-interaction/**/{*,.*}',
|
||||
'aio/content/guide/component-overview.md',
|
||||
'aio/content/errors/*.md',
|
||||
'aio/content/examples/errors/**/{*,.*}',
|
||||
'aio/content/examples/component-overview/**/{*,.*}',
|
||||
'aio/content/guide/component-styles.md',
|
||||
'aio/content/guide/developer-guide-overview.md',
|
||||
'aio/content/guide/view-encapsulation.md',
|
||||
'aio/content/examples/component-styles/**/{*,.*}',
|
||||
'aio/content/examples/content-projection/**/{*,.*}',
|
||||
'aio/content/guide/content-projection.md',
|
||||
'aio/content/guide/creating-injectable-service.md',
|
||||
'aio/content/guide/dependency-injection-overview.md',
|
||||
'aio/content/guide/dependency-injection.md',
|
||||
'aio/content/examples/dependency-injection/**/{*,.*}',
|
||||
'aio/content/images/guide/dependency-injection/**/{*,.*}',
|
||||
'aio/content/guide/dependency-injection-in-action.md',
|
||||
'aio/content/examples/dependency-injection-in-action/**/{*,.*}',
|
||||
'aio/content/images/guide/dependency-injection-in-action/**/{*,.*}',
|
||||
'aio/content/guide/dependency-injection-navtree.md',
|
||||
'aio/content/guide/dependency-injection-providers.md',
|
||||
'aio/content/guide/dependency-injection-context.md',
|
||||
'aio/content/guide/lightweight-injection-tokens.md',
|
||||
'aio/content/guide/displaying-data.md',
|
||||
'aio/content/examples/displaying-data/**/{*,.*}',
|
||||
'aio/content/images/guide/displaying-data/**/{*,.*}',
|
||||
'aio/content/guide/dynamic-component-loader.md',
|
||||
'aio/content/examples/dynamic-component-loader/**/{*,.*}',
|
||||
'aio/content/images/guide/dynamic-component-loader/**/{*,.*}',
|
||||
'aio/content/guide/example-apps-list.md',
|
||||
'aio/content/guide/feature-modules.md',
|
||||
'aio/content/examples/feature-modules/**/{*,.*}',
|
||||
'aio/content/images/guide/feature-modules/**/{*,.*}',
|
||||
'aio/content/guide/frequent-ngmodules.md',
|
||||
'aio/content/images/guide/frequent-ngmodules/**/{*,.*}',
|
||||
'aio/content/guide/hierarchical-dependency-injection.md',
|
||||
'aio/content/examples/hierarchical-dependency-injection/**/{*,.*}',
|
||||
'aio/content/guide/image-directive.md',
|
||||
'aio/content/guide/image-directive-setup.md',
|
||||
'aio/content/examples/providers-viewproviders/**/{*,.*}',
|
||||
'aio/content/examples/resolution-modifiers/**/{*,.*}',
|
||||
'aio/content/guide/lazy-loading-ngmodules.md',
|
||||
'aio/content/examples/lazy-loading-ngmodules/**/{*,.*}',
|
||||
'aio/content/images/guide/lazy-loading-ngmodules/**/{*,.*}',
|
||||
'aio/content/guide/lifecycle-hooks.md',
|
||||
'aio/content/examples/lifecycle-hooks/**/{*,.*}',
|
||||
'aio/content/images/guide/lifecycle-hooks/**/{*,.*}',
|
||||
'aio/content/examples/ngcontainer/**/{*,.*}',
|
||||
'aio/content/guide/ngmodules.md',
|
||||
'aio/content/examples/ngmodules/**/{*,.*}',
|
||||
'aio/content/guide/ngmodule-api.md',
|
||||
'aio/content/guide/ngmodule-faq.md',
|
||||
'aio/content/guide/ngmodule-vs-jsmodule.md',
|
||||
'aio/content/guide/module-types.md',
|
||||
'aio/content/guide/template-overview.md',
|
||||
'aio/content/guide/template-syntax.md',
|
||||
'aio/content/guide/built-in-template-functions.md',
|
||||
'aio/content/examples/built-in-template-functions/**/{*,.*}',
|
||||
'aio/content/guide/event-binding.md',
|
||||
'aio/content/guide/event-binding-concepts.md',
|
||||
'aio/content/examples/event-binding/**/{*,.*}',
|
||||
'aio/content/guide/interpolation.md',
|
||||
'aio/content/examples/interpolation/**/{*,.*}',
|
||||
'aio/content/examples/template-syntax/**/{*,.*}',
|
||||
'aio/content/images/guide/template-syntax/**/{*,.*}',
|
||||
'aio/content/guide/binding-overview.md',
|
||||
'aio/content/guide/binding-syntax.md',
|
||||
'aio/content/examples/binding-syntax/**/{*,.*}',
|
||||
'aio/content/guide/property-binding.md',
|
||||
'aio/content/examples/property-binding/**/{*,.*}',
|
||||
'aio/content/guide/property-binding-best-practices.md',
|
||||
'aio/content/guide/attribute-binding.md',
|
||||
'aio/content/examples/attribute-binding/**/{*,.*}',
|
||||
'aio/content/guide/two-way-binding.md',
|
||||
'aio/content/examples/two-way-binding/**/{*,.*}',
|
||||
'aio/content/guide/built-in-directives.md',
|
||||
'aio/content/guide/directive-composition-api.md',
|
||||
'aio/content/examples/built-in-directives/**/{*,.*}',
|
||||
'aio/content/images/guide/built-in-directives/**/{*,.*}',
|
||||
'aio/content/guide/template-reference-variables.md',
|
||||
'aio/content/examples/template-reference-variables/**/{*,.*}',
|
||||
'aio/content/guide/inputs-outputs.md',
|
||||
'aio/content/examples/inputs-outputs/**/{*,.*}',
|
||||
'aio/content/images/guide/inputs-outputs/**/{*,.*}',
|
||||
'aio/content/guide/understanding-template-expr-overview.md',
|
||||
'aio/content/guide/template-expression-operators.md',
|
||||
'aio/content/examples/template-expression-operators/**/{*,.*}',
|
||||
'aio/content/guide/pipes.md',
|
||||
'aio/content/guide/pipes-custom-data-trans.md',
|
||||
'aio/content/guide/pipes-overview.md',
|
||||
'aio/content/guide/pipe-precedence.md',
|
||||
'aio/content/guide/pipes-transform-data.md',
|
||||
'aio/content/guide/pipe-template.md',
|
||||
'aio/content/examples/pipes/**/{*,.*}',
|
||||
'aio/content/images/guide/pipes/**/{*,.*}',
|
||||
'aio/content/guide/providers.md',
|
||||
'aio/content/examples/providers/**/{*,.*}',
|
||||
'aio/content/images/guide/providers/**/{*,.*}',
|
||||
'aio/content/guide/signal-queries.md',
|
||||
'aio/content/guide/singleton-services.md',
|
||||
'aio/content/guide/signal-inputs.md',
|
||||
'aio/content/guide/sharing-ngmodules.md',
|
||||
'aio/content/guide/standalone-components.md',
|
||||
'aio/content/guide/standalone-migration.md',
|
||||
'aio/content/guide/structural-directives.md',
|
||||
'aio/content/examples/structural-directives/**/{*,.*}',
|
||||
'aio/content/guide/svg-in-templates.md',
|
||||
'aio/content/guide/style-precedence.md',
|
||||
'aio/content/images/guide/structural-directives/**/{*,.*}',
|
||||
'aio/content/guide/template-statements.md',
|
||||
'aio/content/guide/understanding-angular-overview.md',
|
||||
'aio/content/guide/user-input.md',
|
||||
'aio/content/examples/user-input/**/{*,.*}',
|
||||
'aio/content/images/guide/user-input/**/{*,.*}',
|
||||
'aio/content/guide/view-encapsulation.md',
|
||||
'aio/content/examples/view-encapsulation/**/{*,.*}',
|
||||
'aio/content/images/guide/view-encapsulation/**/{*,.*}',
|
||||
'aio/content/special-elements/**/{*,.*}',
|
||||
'aio/content/blocks/**/{*,.*}',
|
||||
'aio/content/guide/hydration.md',
|
||||
'aio/content/guide/defer.md',
|
||||
'aio/content/guide/signals.md',
|
||||
'aio/content/guide/control_flow.md',
|
||||
'aio/content/guide/model-inputs.md',
|
||||
'aio/content/examples/injection-token/**/{*,.*}',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -223,6 +391,23 @@ groups:
|
||||
contains_any_globs(files, [
|
||||
'packages/common/http/**/{*,.*}',
|
||||
'packages/examples/http/**/{*,.*}',
|
||||
'aio/content/guide/understanding-communicating-with-http.md',
|
||||
'aio/content/guide/http-configure-http-url-parameters.md',
|
||||
'aio/content/guide/http-handle-request-errors.md',
|
||||
'aio/content/guide/http-intercept-requests-and-responses.md',
|
||||
'aio/content/guide/http-interceptor-use-cases.md',
|
||||
'aio/content/guide/http-make-jsonp-request.md',
|
||||
'aio/content/guide/http-optimize-server-interaction.md',
|
||||
'aio/content/guide/http-pass-metadata-to-interceptors.md',
|
||||
'aio/content/guide/http-request-data-from-server.md',
|
||||
'aio/content/guide/http-security-xsrf-protection.md',
|
||||
'aio/content/guide/http-send-data-to-server.md',
|
||||
'aio/content/guide/http-server-communication.md',
|
||||
'aio/content/guide/http-setup-server-communication.md',
|
||||
'aio/content/guide/http-test-requests.md',
|
||||
'aio/content/guide/http-track-show-request-progress.md',
|
||||
'aio/content/examples/http/**/{*,.*}',
|
||||
'aio/content/images/guide/http/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -242,6 +427,9 @@ groups:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'packages/elements/**/{*,.*}',
|
||||
'aio/content/examples/elements/**/{*,.*}',
|
||||
'aio/content/images/guide/elements/**/{*,.*}',
|
||||
'aio/content/guide/elements.md'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -263,6 +451,22 @@ groups:
|
||||
contains_any_globs(files, [
|
||||
'packages/forms/**/{*,.*}',
|
||||
'packages/examples/forms/**/{*,.*}',
|
||||
'aio/content/guide/forms.md',
|
||||
'aio/content/examples/forms/**/{*,.*}',
|
||||
'aio/content/images/guide/forms/**/{*,.*}',
|
||||
'aio/content/guide/forms-overview.md',
|
||||
'aio/content/examples/forms-overview/**/{*,.*}',
|
||||
'aio/content/images/guide/forms-overview/**/{*,.*}',
|
||||
'aio/content/guide/form-validation.md',
|
||||
'aio/content/guide/typed-forms.md',
|
||||
'aio/content/examples/form-validation/**/{*,.*}',
|
||||
'aio/content/images/guide/form-validation/**/{*,.*}',
|
||||
'aio/content/guide/dynamic-form.md',
|
||||
'aio/content/examples/dynamic-form/**/{*,.*}',
|
||||
'aio/content/images/guide/dynamic-form/**/{*,.*}',
|
||||
'aio/content/guide/reactive-forms.md',
|
||||
'aio/content/examples/reactive-forms/**/{*,.*}',
|
||||
'aio/content/images/guide/reactive-forms/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -291,6 +495,21 @@ groups:
|
||||
'packages/compiler/src/render3/view/i18n/**/{*,.*}',
|
||||
'packages/compiler-cli/src/extract_i18n.ts',
|
||||
'packages/localize/**/{*,.*}',
|
||||
'aio/content/guide/i18n-overview.md',
|
||||
'aio/content/guide/i18n-common-overview.md',
|
||||
'aio/content/guide/i18n-common-add-package.md',
|
||||
'aio/content/guide/i18n-common-locale-id.md',
|
||||
'aio/content/guide/i18n-common-format-data-locale.md',
|
||||
'aio/content/guide/i18n-common-prepare.md',
|
||||
'aio/content/guide/i18n-common-translation-files.md',
|
||||
'aio/content/guide/i18n-common-merge.md',
|
||||
'aio/content/guide/i18n-common-deploy.md',
|
||||
'aio/content/guide/i18n-example.md',
|
||||
'aio/content/guide/i18n-optional-overview.md',
|
||||
'aio/content/guide/i18n-optional-manual-runtime-locale.md',
|
||||
'aio/content/guide/i18n-optional-import-global-variants.md',
|
||||
'aio/content/guide/i18n-optional-manage-marked-text.md',
|
||||
'aio/content/examples/i18n/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -306,6 +525,9 @@ groups:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'packages/platform-server/**/{*,.*}',
|
||||
'aio/content/guide/prerendering.md',
|
||||
'aio/content/guide/ssr.md',
|
||||
'aio/content/examples/ssr/**/{*,.*}',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -327,6 +549,16 @@ groups:
|
||||
contains_any_globs(files, [
|
||||
'packages/router/**/{*,.*}',
|
||||
'packages/examples/router/**/{*,.*}',
|
||||
'aio/content/guide/router.md',
|
||||
'aio/content/guide/router-tutorial.md',
|
||||
'aio/content/guide/router-tutorial-toh.md',
|
||||
'aio/content/guide/routing-overview.md',
|
||||
'aio/content/guide/router-reference.md',
|
||||
'aio/content/examples/router-tutorial/**/{*,.*}',
|
||||
'aio/content/examples/router/**/{*,.*}',
|
||||
'aio/content/images/guide/router/**/{*,.*}',
|
||||
'aio/content/guide/routing-with-urlmatcher.md',
|
||||
'aio/content/examples/routing-with-urlmatcher/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -343,6 +575,15 @@ groups:
|
||||
contains_any_globs(files, [
|
||||
'packages/service-worker/**/{*,.*}',
|
||||
'packages/examples/service-worker/**/{*,.*}',
|
||||
'aio/content/guide/service-worker-getting-started.md',
|
||||
'aio/content/examples/service-worker-getting-started/**/{*,.*}',
|
||||
'aio/content/guide/app-shell.md',
|
||||
'aio/content/guide/service-worker-communications.md',
|
||||
'aio/content/guide/service-worker-config.md',
|
||||
'aio/content/guide/service-worker-devops.md',
|
||||
'aio/content/guide/service-worker-intro.md',
|
||||
'aio/content/guide/service-worker-notifications.md',
|
||||
'aio/content/images/guide/service-worker/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -359,6 +600,17 @@ groups:
|
||||
'packages/upgrade/**/{*,.*}',
|
||||
'packages/common/upgrade/**/{*,.*}',
|
||||
'packages/examples/upgrade/**/{*,.*}',
|
||||
'aio/content/guide/upgrade.md',
|
||||
'aio/content/examples/upgrade-lazy-load-ajs/**/{*,.*}',
|
||||
'aio/content/examples/upgrade-module/**/{*,.*}',
|
||||
'aio/content/images/guide/upgrade/**/{*,.*}',
|
||||
'aio/content/examples/upgrade-phonecat-1-typescript/**/{*,.*}',
|
||||
'aio/content/examples/upgrade-phonecat-2-hybrid/**/{*,.*}',
|
||||
'aio/content/examples/upgrade-phonecat-3-final/**/{*,.*}',
|
||||
'aio/content/guide/upgrade-performance.md',
|
||||
'aio/content/guide/upgrade-setup.md',
|
||||
'aio/content/guide/ajs-quick-reference.md',
|
||||
'aio/content/examples/ajs-quick-reference/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -374,6 +626,17 @@ groups:
|
||||
- >
|
||||
contains_any_globs(files.exclude('packages/compiler-cli/*').exclude('packages/language-service/*').exclude('packages/service-worker/*'), [
|
||||
'packages/**/testing/**/{*,.*}',
|
||||
'aio/content/guide/testing.md',
|
||||
'aio/content/guide/test-debugging.md',
|
||||
'aio/content/guide/testing-attribute-directives.md',
|
||||
'aio/content/guide/testing-code-coverage.md',
|
||||
'aio/content/guide/testing-components-basics.md',
|
||||
'aio/content/guide/testing-components-scenarios.md',
|
||||
'aio/content/guide/testing-pipes.md',
|
||||
'aio/content/guide/testing-services.md',
|
||||
'aio/content/guide/testing-utility-apis.md',
|
||||
'aio/content/examples/testing/**/{*,.*}',
|
||||
'aio/content/images/guide/testing/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -437,6 +700,9 @@ groups:
|
||||
'packages/tsconfig-tsec-base.json',
|
||||
'packages/tsec-exemption.json',
|
||||
'tools/tsec.bzl',
|
||||
'aio/content/guide/security.md',
|
||||
'aio/content/examples/security/**/{*,.*}',
|
||||
'aio/content/images/guide/security/**/{*,.*}',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -473,12 +739,13 @@ groups:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'packages/language-service/**/{*,.*}',
|
||||
'aio/content/guide/language-service.md',
|
||||
'aio/content/images/guide/language-service/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- alxhub
|
||||
- atscott
|
||||
- dylhunn
|
||||
|
||||
# =========================================================
|
||||
# zone.js
|
||||
@@ -489,6 +756,7 @@ groups:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'packages/zone.js/**/{*,.*}',
|
||||
'aio/content/guide/zone.md'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -547,6 +815,106 @@ groups:
|
||||
- dylhunn
|
||||
- thePunderWoman
|
||||
- josephperrott
|
||||
- pkozlowski-opensource
|
||||
|
||||
# =========================================================
|
||||
# Docs: Contributors
|
||||
# =========================================================
|
||||
docs-contributors:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/content/marketing/contributors.json',
|
||||
'aio/content/images/bios/**/{*,.*}',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- MarkTechson
|
||||
- mgechev
|
||||
- twerske
|
||||
|
||||
# =========================================================
|
||||
# Docs: Gettings Started & Tutorial
|
||||
# =========================================================
|
||||
docs-getting-started-and-tutorial:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/content/guide/setup-local.md',
|
||||
'aio/content/images/guide/setup-local/**/{*,.*}',
|
||||
'aio/content/tutorial/**/{*,.*}',
|
||||
'aio/content/images/guide/toh/**/{*,.*}',
|
||||
'aio/content/demos/first-app/**/{*,.*}',
|
||||
'aio/content/examples/first-app-*/**/{*,.*}',
|
||||
'aio/content/images/guide/faa/**/{*,.*}',
|
||||
'aio/content/examples/toh-pt0/**/{*,.*}',
|
||||
'aio/content/examples/toh-pt1/**/{*,.*}',
|
||||
'aio/content/examples/toh-pt2/**/{*,.*}',
|
||||
'aio/content/examples/toh-pt3/**/{*,.*}',
|
||||
'aio/content/examples/toh-pt4/**/{*,.*}',
|
||||
'aio/content/examples/toh-pt5/**/{*,.*}',
|
||||
'aio/content/examples/toh-pt6/**/{*,.*}',
|
||||
'aio/content/examples/getting-started-v0/**/{*,.*}',
|
||||
'aio/content/examples/getting-started/**/{*,.*}',
|
||||
'aio/content/start/**/{*,.*}',
|
||||
'aio/content/guide/quick-start.md',
|
||||
'aio/content/images/guide/start/**/{*,.*}',
|
||||
'aio/content/examples/what-is-angular/**/{*,.*}',
|
||||
'aio/content/guide/what-is-angular.md'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- AndrewKushnir
|
||||
- thePunderWoman
|
||||
|
||||
# =========================================================
|
||||
# Docs: Marketing
|
||||
# =========================================================
|
||||
docs-marketing:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files.exclude("aio/content/marketing/contributors.json"), [
|
||||
'aio/content/examples/marketing-first-app/**/{*,.*}',
|
||||
'aio/content/guide/roadmap.md',
|
||||
'aio/content/marketing/**/{*,.*}',
|
||||
'aio/content/images/marketing/**/{*,.*}',
|
||||
'aio/content/file-not-found.md',
|
||||
'aio/content/license.md',
|
||||
'aio/content/navigation.json'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- MarkTechson
|
||||
- mgechev
|
||||
- twerske
|
||||
|
||||
# =========================================================
|
||||
# Docs: Observables
|
||||
# =========================================================
|
||||
docs-observables:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/content/guide/observables.md',
|
||||
'aio/content/examples/observables/**/{*,.*}',
|
||||
'aio/content/guide/comparing-observables.md',
|
||||
'aio/content/examples/comparing-observables/**/{*,.*}',
|
||||
'aio/content/guide/observables-in-angular.md',
|
||||
'aio/content/examples/observables-in-angular/**/{*,.*}',
|
||||
'aio/content/guide/practical-observable-usage.md',
|
||||
'aio/content/examples/practical-observable-usage/**/{*,.*}',
|
||||
'aio/content/guide/rx-library.md',
|
||||
'aio/content/examples/rx-library/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- alxhub
|
||||
- atscott
|
||||
- dylhunn
|
||||
|
||||
# =========================================================
|
||||
# Docs: Packaging, Tooling, Releasing
|
||||
@@ -556,7 +924,22 @@ groups:
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'contributing-docs/public-api-surface.md',
|
||||
'docs/PUBLIC_API.md',
|
||||
'docs/RELEASE_SCHEDULE.md',
|
||||
'aio/content/guide/npm-packages.md',
|
||||
'aio/content/guide/browser-support.md',
|
||||
'aio/content/guide/releases.md',
|
||||
'aio/content/guide/updating.md',
|
||||
'aio/content/guide/deprecations.md',
|
||||
'aio/content/examples/deprecation-guide/**/{*,.*}',
|
||||
'aio/content/guide/migration-module-with-providers.md',
|
||||
'aio/content/guide/static-query-migration.md',
|
||||
'aio/content/guide/update-to-latest-version.md',
|
||||
'aio/content/guide/versions.md',
|
||||
'aio/content/guide/update-to-version-14.md',
|
||||
'aio/content/guide/update-to-version-15.md',
|
||||
'aio/content/guide/update-to-version-16.md',
|
||||
'aio/content/guide/update-to-version-17.md',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -566,6 +949,23 @@ groups:
|
||||
- thePunderWoman
|
||||
- jelbourn
|
||||
|
||||
# =========================================================
|
||||
# Docs: Angular DevTools
|
||||
# =========================================================
|
||||
docs-devtools:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/content/guide/devtools.md',
|
||||
'aio/content/images/guide/devtools/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- MarkTechson
|
||||
- mgechev
|
||||
- twerske
|
||||
|
||||
# =========================================================
|
||||
# Tooling: Compiler API shared with Angular CLI
|
||||
#
|
||||
@@ -589,6 +989,80 @@ groups:
|
||||
required: 2 # require at least 2 approvals
|
||||
reviewed_for: required
|
||||
|
||||
# =========================================================
|
||||
# Docs: CLI
|
||||
# =========================================================
|
||||
docs-cli:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/content/cli/**/{*,.*}',
|
||||
'aio/content/guide/typescript-configuration.md',
|
||||
'aio/content/examples/setup/**/{*,.*}',
|
||||
'aio/content/guide/build.md',
|
||||
'aio/content/images/guide/build/**/{*,.*}',
|
||||
'aio/content/images/guide/cli/**/{*,.*}',
|
||||
'aio/content/guide/cli-builder.md',
|
||||
'aio/content/examples/cli-builder/**/{*,.*}',
|
||||
'aio/content/guide/deployment.md',
|
||||
'aio/content/images/guide/deployment/**/{*,.*}',
|
||||
'aio/content/guide/file-structure.md',
|
||||
'aio/content/guide/ivy.md',
|
||||
'aio/content/guide/strict-mode.md',
|
||||
'aio/content/guide/web-worker.md',
|
||||
'aio/content/guide/workspace-config.md',
|
||||
'aio/content/guide/migration-solution-style-tsconfig.md',
|
||||
'aio/content/guide/migration-update-libraries-tslib.md',
|
||||
'aio/content/guide/esbuild.md',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- alan-agius4
|
||||
- clydin
|
||||
- dgp1130
|
||||
- mgechev
|
||||
|
||||
# =========================================================
|
||||
# Docs: CLI Libraries
|
||||
# =========================================================
|
||||
docs-libraries:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/content/examples/angular-linker-plugin/webpack.config.mjs',
|
||||
'aio/content/guide/creating-libraries.md',
|
||||
'aio/content/guide/libraries.md',
|
||||
'aio/content/guide/using-libraries.md',
|
||||
'aio/content/guide/angular-package-format.md'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- alan-agius4
|
||||
- alxhub
|
||||
- mgechev
|
||||
|
||||
# =========================================================
|
||||
# Docs: Schematics
|
||||
# =========================================================
|
||||
docs-schematics:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/content/guide/schematics.md',
|
||||
'aio/content/guide/schematics-authoring.md',
|
||||
'aio/content/guide/schematics-for-libraries.md',
|
||||
'aio/content/images/guide/schematics/**/{*,.*}',
|
||||
'aio/content/examples/schematics-for-libraries/**/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- alan-agius4
|
||||
- dylhunn
|
||||
- mgechev
|
||||
|
||||
# =========================================================
|
||||
# Docs: Angular Dev Site
|
||||
# =========================================================
|
||||
@@ -597,8 +1071,7 @@ groups:
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'adev/**/{.*,*}',
|
||||
'aio/**/{.*,*}'
|
||||
'adev/**/{.*,*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -615,6 +1088,65 @@ groups:
|
||||
- pkozlowski-opensource
|
||||
- ~JeanMeche
|
||||
|
||||
# =========================================================
|
||||
# Docs-infra
|
||||
# =========================================================
|
||||
docs-infra:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/{*,.*}',
|
||||
'aio/aio-builds-setup/**/{*,.*}',
|
||||
'aio/content/cli-src/**/{*,.*}',
|
||||
'aio/content/examples/{*,.*}',
|
||||
'aio/scripts/**/{*,.*}',
|
||||
'aio/src/**/{*,.*}',
|
||||
'aio/tests/**/{*,.*}',
|
||||
'aio/tools/**/{*,.*}',
|
||||
'aio/tools/examples/shared/boilerplate/cli/.vscode/**/{*,.*}',
|
||||
'aio/content/BUILD.bazel',
|
||||
'aio/content/images/guide/contributors-guide/**/{*,.*}',
|
||||
'aio/content/guide/contributors-guide-overview.md',
|
||||
'aio/content/guide/docs-style-guide.md',
|
||||
'aio/content/examples/docs-style-guide/**/{*,.*}',
|
||||
'aio/content/images/guide/docs-style-guide/**/{*,.*}',
|
||||
'aio/content/guide/docs-lint-errors.md',
|
||||
'aio/content/images/guide/docs-lint-errors/**/{*,.*}',
|
||||
'aio/content/guide/localized-documentation.md',
|
||||
'aio/content/guide/localizing-angular.md',
|
||||
'aio/content/guide/reviewing-content.md',
|
||||
'aio/content/guide/updating-content-github-ui.md',
|
||||
'aio/content/guide/updating-search-keywords.md',
|
||||
'aio/content/guide/doc-build-test.md',
|
||||
'aio/content/guide/doc-edit-finish.md',
|
||||
'aio/content/guide/doc-editing.md',
|
||||
'aio/content/guide/doc-github-tasks.md',
|
||||
'aio/content/guide/doc-pr-open.md',
|
||||
'aio/content/guide/doc-pr-prep.md',
|
||||
'aio/content/guide/doc-pr-update.md',
|
||||
'aio/content/guide/doc-prepare-to-edit.md',
|
||||
'aio/content/guide/doc-select-issue.md',
|
||||
'aio/content/guide/doc-tasks.md',
|
||||
'aio/content/guide/doc-update-overview.md',
|
||||
'aio/content/guide/doc-update-start.md',
|
||||
'aio/content/guide/docs-lint-errors.md',
|
||||
'aio/content/images/guide/preparing-to-edit-docs/**/{*,.*}',
|
||||
'aio/content/images/guide/github-for-docs/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-update-start/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-update-overview/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-pr-update/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-pr-prep/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-pr-open/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-github-tasks/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-prepare-to-edit/**/{*,.*}',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- AndrewKushnir
|
||||
- thePunderWoman
|
||||
- josephperrott
|
||||
|
||||
# =========================================================
|
||||
# Angular DevTools
|
||||
# =========================================================
|
||||
@@ -651,8 +1183,8 @@ groups:
|
||||
'.ng-dev/**/{*,.*}',
|
||||
'.vscode/**/{*,.*}',
|
||||
'.yarn/**/{*,.*}',
|
||||
'contributing-docs/*.md',
|
||||
'contributing-docs/images/**/{*,.*}',
|
||||
'docs/*.md',
|
||||
'docs/images/**/{*,.*}',
|
||||
'goldens/{*,.*}',
|
||||
'goldens/public-api/manage.js',
|
||||
'modules/{*,.*}',
|
||||
@@ -697,6 +1229,12 @@ groups:
|
||||
- >
|
||||
contains_any_globs(files.exclude("goldens/public-api/manage.js"), [
|
||||
'goldens/public-api/**/{*,.*}',
|
||||
'docs/NAMING.md',
|
||||
'aio/content/guide/angular-package-format.md',
|
||||
'aio/content/guide/glossary.md',
|
||||
'aio/content/guide/styleguide.md',
|
||||
'aio/content/examples/styleguide/**/{*,.*}',
|
||||
'aio/content/images/guide/styleguide/{*,.*}'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -707,9 +1245,6 @@ groups:
|
||||
- ~jelbourn
|
||||
- thePunderWoman
|
||||
- pkozlowski-opensource
|
||||
- ~iteriani
|
||||
- ~tbondwilkinson
|
||||
- ~rahatarmanahmed
|
||||
reviews:
|
||||
request: 3 # Request reviews from 3 people
|
||||
required: 2 # Require that 2 people approve
|
||||
@@ -807,6 +1342,9 @@ groups:
|
||||
- dylhunn # Dylan Hunn
|
||||
- AndrewKushnir # Andrew Kushnir
|
||||
- atscott # Andrew Scott
|
||||
reviews:
|
||||
required: 1
|
||||
reviewed_for: optional
|
||||
labels:
|
||||
pending: 'requires: TGP'
|
||||
approved: 'requires: TGP'
|
||||
@@ -831,9 +1369,14 @@ groups:
|
||||
- jesse-good # Jesse Costello-Good
|
||||
- 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'
|
||||
|
||||
Vendored
+2
@@ -12,12 +12,14 @@
|
||||
"**/node_modules/**": true,
|
||||
"**/bazel-out/**": true,
|
||||
"**/dist/**": true,
|
||||
"**/aio/src/generated/**": true,
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/bower_components": true,
|
||||
"**/bazel-out": true,
|
||||
"**/dist": true,
|
||||
"**/aio/src/generated": true,
|
||||
".history": true,
|
||||
},
|
||||
"git.ignoreLimitWarning": true,
|
||||
|
||||
@@ -67,6 +67,7 @@ nodejs_binary(
|
||||
data = [".yarn/releases/yarn-1.22.19.cjs"],
|
||||
entry_point = ".yarn/releases/yarn-1.22.19.cjs",
|
||||
visibility = [
|
||||
"//aio/tools/examples/shared:__pkg__",
|
||||
"//integration:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
+399
-504
@@ -1,519 +1,19 @@
|
||||
<a name="18.1.2"></a>
|
||||
# 18.1.2 (2024-07-24)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [463945003d](https://github.com/angular/angular/commit/463945003dcf253c64809ffdcddabedb87e78e06) | fix | limit the number of chained instructions ([#57069](https://github.com/angular/angular/pull/57069)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e904f34020](https://github.com/angular/angular/commit/e904f3402053ce9098854a31f2652020dd79e8f9) | fix | add warning for unused let declarations ([#57033](https://github.com/angular/angular/pull/57033)) |
|
||||
<a name="18.0.0-rc.0"></a>
|
||||
# 18.0.0-rc.0 (2024-05-01)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [9e52c1c840](https://github.com/angular/angular/commit/9e52c1c8402dd5a54cf73caafff4a5b81d73fabd) | fix | `afterNextRender` hooks return that callback value. ([#57031](https://github.com/angular/angular/pull/57031)) |
|
||||
| [b9fb98c67c](https://github.com/angular/angular/commit/b9fb98c67c29d8e5697b72788f09f1263e8130f4) | fix | tree shake dev mode error message ([#57035](https://github.com/angular/angular/pull/57035)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.1.1"></a>
|
||||
# 18.1.1 (2024-07-17)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a1cb9dfc0d](https://github.com/angular/angular/commit/a1cb9dfc0d3539d16020a53dd4c32311240a6265) | fix | Don't run preconnect assertion on the server. ([#56213](https://github.com/angular/angular/pull/56213)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [daf0317bdc](https://github.com/angular/angular/commit/daf0317bdcef79445eead4a3e0e1be75671f43fb) | fix | JIT mode incorrectly interpreting host directive configuration in partial compilation ([#57002](https://github.com/angular/angular/pull/57002)) |
|
||||
| [d7dca6dbb6](https://github.com/angular/angular/commit/d7dca6dbb6d8afc77a988de0b7471ac4e078762e) | fix | use strict equality for 'code' comparison ([#56944](https://github.com/angular/angular/pull/56944)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c94a897248](https://github.com/angular/angular/commit/c94a8972488f62656f5d0368b8763776e2cd39c6) | fix | avoid emitting references to typecheck files in TS 5.4 ([#56961](https://github.com/angular/angular/pull/56961)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [5682527d94](https://github.com/angular/angular/commit/5682527d949b078e92ff7588c7e25dad37fffc52) | fix | not all callbacks running when registered at the same time ([#56981](https://github.com/angular/angular/pull/56981)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [b666d2c20f](https://github.com/angular/angular/commit/b666d2c20f932f435fa6c51e1d74d7bca53381f2) | fix | fix common module removal ([#56968](https://github.com/angular/angular/pull/56968)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.1.0"></a>
|
||||
# 18.1.0 (2024-07-10)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [f25653e231](https://github.com/angular/angular/commit/f25653e2311152d30b14d25acb0dccb4e2b5ea56) | fix | typo in NgOptimizedImage warning ([#56756](https://github.com/angular/angular/pull/56756)) |
|
||||
| [9b35726e42](https://github.com/angular/angular/commit/9b35726e42ebdeed138a25581e0a7eefff466206) | fix | typo in warning for NgOptimizedDirective ([#56817](https://github.com/angular/angular/pull/56817)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [fd6cd0422d](https://github.com/angular/angular/commit/fd6cd0422d2d761d2c6cc0cd41838fbba8a3f010) | feat | Add extended diagnostic to warn when there are uncalled functions in event bindings ([#56295](https://github.com/angular/angular/pull/56295)) |
|
||||
| [341a116d61](https://github.com/angular/angular/commit/341a116d611c095ed414c82612adb529e7be310c) | fix | allow more characters in let declaration name ([#56764](https://github.com/angular/angular/pull/56764)) |
|
||||
| [2a1291e942](https://github.com/angular/angular/commit/2a1291e942a3cd645ee635e72e7d83722383d39b) | fix | give precedence to local let declarations over parent ones ([#56752](https://github.com/angular/angular/pull/56752)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [66e582551e](https://github.com/angular/angular/commit/66e582551eb081e422e0df41badce1821c46dc62) | fix | avoid duplicate diagnostics for let declarations read before definition ([#56843](https://github.com/angular/angular/pull/56843)) |
|
||||
| [4d18c5bfd5](https://github.com/angular/angular/commit/4d18c5bfd54c53655955c8cd90472081ade40b34) | fix | flag all conflicts between let declarations and local symbols ([#56752](https://github.com/angular/angular/pull/56752)) |
|
||||
| [9e21582456](https://github.com/angular/angular/commit/9e215824565f0d30da7edb20087c4460069a6660) | fix | Show template syntax errors in local compilation modified ([#55855](https://github.com/angular/angular/pull/55855)) |
|
||||
| [5996502921](https://github.com/angular/angular/commit/599650292107f8856c7cd41791bd0856f9d14eb1) | fix | type check let declarations nested inside nodes ([#56752](https://github.com/angular/angular/pull/56752)) |
|
||||
| [cdebf751e4](https://github.com/angular/angular/commit/cdebf751e4949048b01acc92de2517f46fcd5d37) | fix | used before declared diagnostic not firing for control flow blocks ([#56843](https://github.com/angular/angular/pull/56843)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ea3c802056](https://github.com/angular/angular/commit/ea3c80205653af109c688a4d4808143b34591d54) | feat | Add a schematic to migrate afterRender phase flag ([#55648](https://github.com/angular/angular/pull/55648)) |
|
||||
| [5df3e78c99](https://github.com/angular/angular/commit/5df3e78c9907f522f2f96c087b10ca12d57f7028) | feat | add equality function to rxjs-interop `toSignal` ([#56447](https://github.com/angular/angular/pull/56447)) |
|
||||
| [0a48d584f2](https://github.com/angular/angular/commit/0a48d584f2ffeebb9402032182d4fc13a260c5cf) | feat | add support for let syntax ([#56715](https://github.com/angular/angular/pull/56715)) |
|
||||
| [352e0782ec](https://github.com/angular/angular/commit/352e0782ec37d2adcc662cfc69c83d38058a34bf) | feat | expose signal input metadata in `ComponentMirror` ([#56402](https://github.com/angular/angular/pull/56402)) |
|
||||
| [a655e46447](https://github.com/angular/angular/commit/a655e46447962bf56bf0184e3104328b9f7c1531) | feat | Redesign the `afterRender` & `afterNextRender` phases API ([#55648](https://github.com/angular/angular/pull/55648)) |
|
||||
| [e5a6f91722](https://github.com/angular/angular/commit/e5a6f917225aafa7c5c860f280d2aafe3615727e) | feat | support TypeScript 5.5 ([#56096](https://github.com/angular/angular/pull/56096)) |
|
||||
| [38effcc63e](https://github.com/angular/angular/commit/38effcc63eea360e948dc22860add72d3aa02288) | fix | Add back phase flag option as a deprecated API ([#55648](https://github.com/angular/angular/pull/55648)) |
|
||||
| [86bcfd3e49](https://github.com/angular/angular/commit/86bcfd3e498b8ec1de1a2a1ad0847fe567f7e9d4) | fix | improve docs on afterRender hooks ([#56522](https://github.com/angular/angular/pull/56522)) |
|
||||
| [b2445a0953](https://github.com/angular/angular/commit/b2445a095314aa66da038d3093e6a1b18fe5768b) | fix | link errors to ADEV ([#55554](https://github.com/angular/angular/pull/55554)) ([#56038](https://github.com/angular/angular/pull/56038)) |
|
||||
| [03a2acd2a3](https://github.com/angular/angular/commit/03a2acd2a3bdc87aaeb6b835a7c1016f800b31cb) | fix | properly remove imports in the afterRender phase migration ([#56524](https://github.com/angular/angular/pull/56524)) |
|
||||
| [4d87b9e899](https://github.com/angular/angular/commit/4d87b9e899381894a1de90f251da58613a96eed0) | fix | rename the equality function option in toSignal ([#56769](https://github.com/angular/angular/pull/56769)) ([#56922](https://github.com/angular/angular/pull/56922)) |
|
||||
| [8bd4c074af](https://github.com/angular/angular/commit/8bd4c074afe85b739dff4d3c4dcc19384c42b85e) | fix | toSignal equal option should be passed to inner computed ([#56903](https://github.com/angular/angular/pull/56903)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [00bde8b1c2](https://github.com/angular/angular/commit/00bde8b1c2d1511da40526a374d4e94d31e0d575) | fix | Make `NgControlStatus` host bindings `OnPush` compatible ([#55720](https://github.com/angular/angular/pull/55720)) |
|
||||
### http
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [cc21989132](https://github.com/angular/angular/commit/cc21989132bc64b981df83cb6ff6e1506b42a1d0) | fix | Make `Content-Type` header case insensitive ([#56541](https://github.com/angular/angular/pull/56541)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [b400e2e4d4](https://github.com/angular/angular/commit/b400e2e4d4c27a9c8d8e91b52852ef7b64f7591a) | feat | autocompletion for the component not imported ([#55595](https://github.com/angular/angular/pull/55595)) |
|
||||
| [67b2c336bc](https://github.com/angular/angular/commit/67b2c336bc0bdce3f7ae054c094990a9831f5b20) | fix | import the default exported component correctly ([#56432](https://github.com/angular/angular/pull/56432)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a13f5da773](https://github.com/angular/angular/commit/a13f5da77303f4ab2f1543df1de1f416216b5a9c) | feat | Allow `UrlTree` as an input to `routerLink` ([#56265](https://github.com/angular/angular/pull/56265)) |
|
||||
| [1d3a7529b4](https://github.com/angular/angular/commit/1d3a7529b4fa3617a5d6a97e742cb13818253a14) | feat | Set a different browser URL from the one for route matching ([#53318](https://github.com/angular/angular/pull/53318)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.5"></a>
|
||||
# 18.0.5 (2024-06-26)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2f73281dfd](https://github.com/angular/angular/commit/2f73281dfd97fd254179770cbdbda5236f5f37fd) | fix | improve docs on afterRender hooks ([#56525](https://github.com/angular/angular/pull/56525)) |
|
||||
| [be9e4892f9](https://github.com/angular/angular/commit/be9e4892f9d2e3dbc772b732a130f97d67cba965) | fix | improve support for i18n hydration of projected content ([#56192](https://github.com/angular/angular/pull/56192)) |
|
||||
| [5f9bd5521e](https://github.com/angular/angular/commit/5f9bd5521eaadb4106c43eb2f8e7ac25777e9ea6) | fix | prevent calling devMode only function on `@defer` error. ([#56559](https://github.com/angular/angular/pull/56559)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.4"></a>
|
||||
# 18.0.4 (2024-06-20)
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ec0d1bf6f3](https://github.com/angular/angular/commit/ec0d1bf6f337fc4f2c29cacaa6ca5b915eb4e561) | fix | insert constant statements after the first group of imports ([#56431](https://github.com/angular/angular/pull/56431)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [83ffa94783](https://github.com/angular/angular/commit/83ffa9478372db3e5dd2d256d266a5612008da0a) | fix | do not activate event replay when no events are registered ([#56509](https://github.com/angular/angular/pull/56509)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [5578681da2](https://github.com/angular/angular/commit/5578681da27345b0c8260eb5d73e702d19581abd) | fix | Delay the view transition to ensure renders in microtasks complete ([#56494](https://github.com/angular/angular/pull/56494)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.3"></a>
|
||||
# 18.0.3 (2024-06-12)
|
||||
### benchpress
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ebf00aa0659](https://github.com/angular/angular/commit/ebf00aa06592a966b72c81ff4ca09c6ef1344a20) | fix | adjust supported browser names for headless chrome ([#56360](https://github.com/angular/angular/pull/56360)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dbd0fa00f8c](https://github.com/angular/angular/commit/dbd0fa00f8c742a9b804ce2a96a0add552a179dd) | fix | async EventEmitter should contribute to app stability ([#56308](https://github.com/angular/angular/pull/56308)) |
|
||||
| [625ca3e2b3f](https://github.com/angular/angular/commit/625ca3e2b3f04fb770ecbef03a9a4151c54e201b) | fix | signals should be tracked when embeddedViewRef.detectChanges is called ([#55719](https://github.com/angular/angular/pull/55719)) |
|
||||
### localize
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d6dd3dbdb09](https://github.com/angular/angular/commit/d6dd3dbdb09da956a7c7c95187ae29347568b2e9) | fix | add `@angular/localize/init` as polyfill in `angular.json` ([#56300](https://github.com/angular/angular/pull/56300)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c07e1b33569](https://github.com/angular/angular/commit/c07e1b335695ce8e5402e7d7ad7810ccd472b224) | fix | resolve error in standalone migration ([#56302](https://github.com/angular/angular/pull/56302)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.2"></a>
|
||||
# 18.0.2 (2024-06-05)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [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 |
|
||||
| -- | -- | -- |
|
||||
| [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="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 |
|
||||
| -- | -- | -- |
|
||||
| [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 |
|
||||
| -- | -- | -- |
|
||||
| [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 |
|
||||
| -- | -- | -- |
|
||||
| [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="17.3.10"></a>
|
||||
# 17.3.10 (2024-05-22)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<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.
|
||||
### 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.
|
||||
### 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
|
||||
`ApplicationRef`. `whenStable` of the fixture will now include unfinished
|
||||
router navigations and unfinished `HttpClient` requests. This will cause
|
||||
tests that `await` the `whenStable` promise to time out when there are
|
||||
incomplete requests. To fix this, remove the `whenStable`,
|
||||
instead wait for another condition, or ensure `HttpTestingController`
|
||||
mocks responses for all requests. Try adding `HttpTestingController.verify()`
|
||||
before your `await fixture.whenStable` to identify the open requests.
|
||||
Also, make sure your tests wait for the stability promise. We found many
|
||||
examples of tests that did not, meaning the expectations did not execute
|
||||
within the test body.
|
||||
|
||||
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)) |
|
||||
| [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 |
|
||||
| -- | -- | -- |
|
||||
| [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)) |
|
||||
| [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)) |
|
||||
| [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)) |
|
||||
| [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 |
|
||||
| -- | -- | -- |
|
||||
| [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 |
|
||||
| -- | -- | -- |
|
||||
| [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)) |
|
||||
| [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.9"></a>
|
||||
# 17.3.9 (2024-05-15)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.8"></a>
|
||||
# 17.3.8 (2024-05-08)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c21b459ba6](https://github.com/angular/angular/commit/c21b459ba6520fd5835e23800338ac9c997fee91) | fix | add math elements to schema ([#55631](https://github.com/angular/angular/pull/55631)) ([#55645](https://github.com/angular/angular/pull/55645)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [3818436ebc](https://github.com/angular/angular/commit/3818436ebc649267bb39b976b6b567b7f2b06a64) | fix | don't schedule timer triggers on the server ([#55605](https://github.com/angular/angular/pull/55605)) |
|
||||
| [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)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
@@ -534,6 +34,78 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-next.6"></a>
|
||||
# 18.0.0-next.6 (2024-04-25)
|
||||
## 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
|
||||
@@ -545,11 +117,83 @@
|
||||
|
||||
<!-- 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
|
||||
@@ -560,6 +204,135 @@
|
||||
|
||||
<!-- 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
|
||||
- `ComponentFixture.whenStable` now matches the
|
||||
`ApplicationRef.isStable` observable. Prior to this change, stability
|
||||
of the fixture did not include everything that was considered in
|
||||
`ApplicationRef`. `whenStable` of the fixture will now include unfinished
|
||||
router navigations and unfinished `HttpClient` requests. This will cause
|
||||
tests that `await` the `whenStable` promise to time out when there are
|
||||
incomplete requests. To fix this, remove the `whenStable`,
|
||||
instead wait for another condition, or ensure `HttpTestingController`
|
||||
mocks responses for all requests. Try adding `HttpTestingController.verify()`
|
||||
before your `await fixture.whenStable` to identify the open requests.
|
||||
Also, make sure your tests wait for the stability promise. We found many
|
||||
examples of tests that did not, meaning the expectations did not execute
|
||||
within the test body.
|
||||
|
||||
In addition, `ComponentFixture.isStable` would synchronously switch to
|
||||
true in some scenarios but will now always be asynchronous.
|
||||
### router
|
||||
- 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`.
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [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)) |
|
||||
| [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 |
|
||||
| -- | -- | -- |
|
||||
| [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)) |
|
||||
| [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)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [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)) |
|
||||
| [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)) |
|
||||
| [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)) |
|
||||
| [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)) |
|
||||
### 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)) |
|
||||
### 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)) |
|
||||
| [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)) |
|
||||
### 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)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [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)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.2"></a>
|
||||
# 17.3.2 (2024-03-28)
|
||||
### compiler
|
||||
@@ -590,6 +363,55 @@
|
||||
|
||||
<!-- 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
|
||||
@@ -603,6 +425,79 @@
|
||||
|
||||
<!-- 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
|
||||
|
||||
+7
-7
@@ -32,7 +32,7 @@ Stack Overflow is a much better place to ask questions since:
|
||||
|
||||
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
|
||||
|
||||
If you would like to chat about the question in real-time, you can reach out via [the Angular community Discord server][discord].
|
||||
If you would like to chat about the question in real-time, you can reach out via [our Discord server][discord].
|
||||
|
||||
|
||||
## <a name="issue"></a> Found a Bug?
|
||||
@@ -138,7 +138,7 @@ If we ask for changes via code reviews then:
|
||||
git push
|
||||
```
|
||||
|
||||
For more info on working with fixup commits see [here](./contributing-docs/using-fixup-commits.md).
|
||||
For more info on working with fixup commits see [here](docs/FIXUP_COMMITS.md).
|
||||
|
||||
That's it! Thank you for your contribution!
|
||||
|
||||
@@ -207,7 +207,7 @@ To ensure consistency throughout the source code, keep these rules in mind as yo
|
||||
* All public API methods **must be documented**.
|
||||
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
|
||||
|
||||
An automated formatter is available, see [DEVELOPER.md](contributing-docs/building-and-testing-angular#formatting-your-source-code).
|
||||
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#formatting-your-source-code).
|
||||
|
||||
|
||||
## <a name="commit"></a> Commit Message Format
|
||||
@@ -302,7 +302,7 @@ There are currently a few exceptions to the "use package name" rule:
|
||||
|
||||
* `dev-infra`: used for dev-infra related changes within the directories /scripts and /tools
|
||||
|
||||
* `docs-infra`: used for docs-app (angular.dev) related changes within the /adev directory of the repo
|
||||
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
|
||||
|
||||
* `migrations`: used for changes to the `ng update` migrations.
|
||||
|
||||
@@ -353,9 +353,9 @@ DEPRECATED: <what is deprecated>
|
||||
Closes #<pr number>
|
||||
```
|
||||
|
||||
Breaking Change section should start with the phrase `BREAKING CHANGE: ` followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
|
||||
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
|
||||
|
||||
Similarly, a Deprecation section should start with `DEPRECATED: ` followed by a short description of what is deprecated, a blank line, and a detailed description of the deprecation that also mentions the recommended update path.
|
||||
Similarly, a Deprecation section should start with "DEPRECATED: " followed by a short description of what is deprecated, a blank line, and a detailed description of the deprecation that also mentions the recommended update path.
|
||||
|
||||
|
||||
### Revert commits
|
||||
@@ -392,7 +392,7 @@ The following documents can help you sort out issues with GitHub accounts and mu
|
||||
[coc]: https://github.com/angular/code-of-conduct/blob/main/CODE_OF_CONDUCT.md
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
[corporate-cla]: https://cla.developers.google.com/about/google-corporate
|
||||
[dev-doc]: ./contributing-docs/building-and-testing-angular.md
|
||||
[dev-doc]: https://github.com/angular/angular/blob/main/docs/DEVELOPER.md
|
||||
[github]: https://github.com/angular/angular
|
||||
[discord]: https://discord.gg/angular
|
||||
[individual-cla]: https://cla.developers.google.com/about/google-individual
|
||||
|
||||
@@ -101,7 +101,7 @@ Angular is cross-platform, fast, scalable, has incredible tooling, and is loved
|
||||
## Ecosystem
|
||||
|
||||
<p>
|
||||
<img src="/contributing-docs/images/angular-ecosystem-logos.png" alt="angular ecosystem logos" width="500px" height="auto">
|
||||
<img src="/docs/images/angular-ecosystem-logos.png" alt="angular ecosystem logos" width="500px" height="auto">
|
||||
</p>
|
||||
|
||||
- [Angular Command Line (CLI)][cli]
|
||||
@@ -113,7 +113,7 @@ Angular is cross-platform, fast, scalable, has incredible tooling, and is loved
|
||||
|
||||
## Upgrading
|
||||
|
||||
Check out our [upgrade guide](https://angular.dev/update-guide/) to find out the best way to upgrade your project.
|
||||
Check out our [upgrade guide](https://update.angular.io/) to find out the best way to upgrade your project.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
Angular is part of Google [Open Source Software Vulnerability Reward Program](https://bughunters.google.com/about/rules/6521337925468160/google-open-source-software-vulnerability-reward-program-rules). For vulnerabilities in Angular, please submit your report [here](https://bughunters.google.com/report).
|
||||
|
||||
For more information, check out [Angular's security policy](https://angular.dev/best-practices/security).
|
||||
For more information, check out [Angular's security policy](https://angular.io/guide/security).
|
||||
|
||||
@@ -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-d30a56c19bafaac67cf44e605ed8c2c0e45b0a51.patch",
|
||||
"//tools/esm-interop:patches/npm/@angular+build-tooling+0.0.0-56d0b1f597b9e4b5d99f289f6904a220802164c1.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",
|
||||
@@ -94,6 +94,30 @@ yarn_install(
|
||||
yarn_lock = "//:yarn.lock",
|
||||
)
|
||||
|
||||
yarn_install(
|
||||
name = "aio_example_deps",
|
||||
# Rename the default js_library target from "node_modules" as this obscures the
|
||||
# the source directory stamped as a filegroup in the manual BUILD contents below.
|
||||
all_node_modules_target_name = "node_modules_all",
|
||||
data = [
|
||||
YARN_LABEL,
|
||||
"//:.yarnrc",
|
||||
],
|
||||
# Disabled because, when False, yarn_install preserves the node_modules folder
|
||||
# with bin symlinks in the external repository. This is needed to link the shared
|
||||
# set of deps for example e2es.
|
||||
exports_directories_only = False,
|
||||
manual_build_file_contents = """\
|
||||
filegroup(
|
||||
name = "node_modules_files",
|
||||
srcs = ["node_modules"],
|
||||
)
|
||||
""",
|
||||
package_json = "//aio/tools/examples/shared:package.json",
|
||||
yarn = YARN_LABEL,
|
||||
yarn_lock = "//aio/tools/examples/shared:yarn.lock",
|
||||
)
|
||||
|
||||
load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies")
|
||||
|
||||
aspect_bazel_lib_dependencies()
|
||||
@@ -143,10 +167,10 @@ cldr_xml_data_repository(
|
||||
# sass rules
|
||||
http_archive(
|
||||
name = "io_bazel_rules_sass",
|
||||
sha256 = "cd83736ea65d0df064283aea5922dbaf132dd2b3aa54e7151aae7edaa9572c3e",
|
||||
strip_prefix = "rules_sass-83022b98114c07e9588089c7fe8f76bc0262c7e7",
|
||||
sha256 = "845061fad5cb42a353ac394fe6450ec9f21d337acf5b98011ef29ddcb33e3671",
|
||||
strip_prefix = "rules_sass-9f8be59f5175d0dd3438d7da994b2782299e0c2c",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_sass/archive/83022b98114c07e9588089c7fe8f76bc0262c7e7.zip",
|
||||
"https://github.com/bazelbuild/rules_sass/archive/9f8be59f5175d0dd3438d7da994b2782299e0c2c.zip",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
+4
-4
@@ -26,7 +26,6 @@ APPLICATION_FILES = [
|
||||
|
||||
TEST_FILES = APPLICATION_FILES + [
|
||||
"karma.conf.js",
|
||||
"test-main.ts",
|
||||
"tsconfig.spec.json",
|
||||
] + glob(
|
||||
["**/*.spec.ts"],
|
||||
@@ -79,10 +78,10 @@ APPLICATION_DEPS = [
|
||||
"@npm//@lezer/highlight",
|
||||
"@npm//@lezer/javascript",
|
||||
"@npm//@lezer/common",
|
||||
"@npm//@stackblitz/sdk",
|
||||
"@npm//@xterm/xterm",
|
||||
"@npm//@xterm/addon-fit",
|
||||
"@npm//algoliasearch",
|
||||
"@npm//xterm",
|
||||
"@npm//xterm-addon-fit",
|
||||
"@npm//angular-split",
|
||||
"@npm//zone.js",
|
||||
]
|
||||
@@ -91,6 +90,7 @@ TEST_DEPS = APPLICATION_DEPS + [
|
||||
"@npm//@angular/platform-browser-dynamic",
|
||||
"@npm//@types/jasmine",
|
||||
"@npm//@types/node",
|
||||
"@npm//assert",
|
||||
"@npm//jasmine",
|
||||
"@npm//jasmine-core",
|
||||
"@npm//karma-chrome-launcher",
|
||||
@@ -177,7 +177,7 @@ architect_test(
|
||||
],
|
||||
chdir = package_name(),
|
||||
data = ensure_local_package_deps(TEST_DEPS) + TEST_FILES + APPLICATION_ASSETS + [
|
||||
"//adev/tools:windows-chromium-path",
|
||||
"//aio/tools:windows-chromium-path",
|
||||
"@npm//@angular/build-tooling/bazel/browsers/chromium",
|
||||
],
|
||||
env = {
|
||||
|
||||
+1
-17
@@ -24,30 +24,14 @@ yarn
|
||||
yarn docs
|
||||
```
|
||||
|
||||
If you are having issues with the docs building, see the [FAQs](#faqs) section.
|
||||
|
||||
## Contributing
|
||||
|
||||
Want to report a bug, contribute some code, or improve the documentation? Excellent!
|
||||
|
||||
Read through our [contributing guidelines](/CONTRIBUTING.md) to learn about our submission process, coding rules, and more.
|
||||
Read through our [contributing guidelines](CONTRIBUTING.md) to learn about our submission process, coding rules, and more.
|
||||
|
||||
And if you're new, check out one of our issues labeled as <kbd>[help wanted](https://github.com/angular/angular/labels/help%20wanted)</kbd> or <kbd>[good first issue](https://github.com/angular/angular/labels/good%20first%20issue)</kbd>.
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
## FAQs
|
||||
|
||||
### The build is failing and I'm seeing `bazel:bazel failed: missing input file` messages.
|
||||
|
||||
This is most likely due to a bazel dependency / caching issue. To resolve this, run the following command:
|
||||
|
||||
```
|
||||
# Try this first
|
||||
yarn bazel clean
|
||||
|
||||
# If that doesn't work, try it with the expunge flag
|
||||
yarn bazel clean --expunge
|
||||
```
|
||||
|
||||
+3
-9
@@ -20,21 +20,15 @@
|
||||
"builder": "@angular/build:application",
|
||||
"options": {
|
||||
"externalDependencies": ["path"],
|
||||
"define": {
|
||||
// We need this until xterm 5.6.0 is released
|
||||
// see https://github.com/xtermjs/xterm.js/pull/4940
|
||||
"self": "this"
|
||||
},
|
||||
"outputPath": "dist/angular-dev",
|
||||
"index": "src/index.html",
|
||||
"browser": "src/main.ts",
|
||||
"server": "src/main.server.ts",
|
||||
"ssr": true,
|
||||
"polyfills": [],
|
||||
"polyfills": ["src/polyfills.ts", "zone.js"],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": ["src/favicon.ico", "src/robots.txt", "src/assets"],
|
||||
"styles": ["@angular/docs/styles/global-styles.scss", "./src/local-styles.scss"],
|
||||
"styles": ["@angular/docs/styles/global-styles.scss"],
|
||||
"scripts": [],
|
||||
"webWorkerTsConfig": "tsconfig.worker.json",
|
||||
"optimization": {
|
||||
@@ -84,10 +78,10 @@
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"polyfills": ["zone.js", "zone.js/testing"],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"include": ["src/app"],
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"main": "test-main.ts",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": ["src/favicon.ico", "src/assets"],
|
||||
"styles": ["@angular/docs/styles/global-styles.scss"],
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"ignore": ["**/.*"],
|
||||
"headers": [
|
||||
{
|
||||
"source": "assets/images/tutorials/common/*.jpg",
|
||||
"source": "assets/tutorials/common/*.jpg",
|
||||
"headers": [
|
||||
{
|
||||
"key": "Cross-Origin-Resource-Policy",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
const {getAdjustedChromeBinPathForWindows} = require('../adev/tools/windows-chromium-path');
|
||||
const {getAdjustedChromeBinPathForWindows} = require('../aio/tools/windows-chromium-path');
|
||||
|
||||
process.env.CHROME_BIN = getAdjustedChromeBinPathForWindows();
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ function httpGet(url, options = {}) {
|
||||
] = `token ${process.env.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN}`;
|
||||
// User agent is required
|
||||
// https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#user-agent-required
|
||||
options.headers['User-Agent'] = `ADEV_Angular_CLI_Sources_Update`;
|
||||
options.headers['User-Agent'] = `AIO_Angular_CLI_Sources_Update`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
get(url, options, (res) => {
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import {ViewportScroller} from '@angular/common';
|
||||
import {
|
||||
Injectable,
|
||||
inject,
|
||||
ApplicationRef,
|
||||
afterNextRender,
|
||||
EnvironmentInjector,
|
||||
} from '@angular/core';
|
||||
import {Scroll, Router} from '@angular/router';
|
||||
import {filter, firstValueFrom, map, switchMap, tap} from 'rxjs';
|
||||
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class AppScroller {
|
||||
private readonly router = inject(Router);
|
||||
private readonly viewportScroller = inject(ViewportScroller);
|
||||
private readonly appRef = inject(ApplicationRef);
|
||||
private readonly injector = inject(EnvironmentInjector);
|
||||
disableScrolling = false;
|
||||
private _lastScrollEvent?: Scroll;
|
||||
private canScroll = false;
|
||||
private cancelScroll?: () => void;
|
||||
get lastScrollEvent(): Scroll | undefined {
|
||||
return this._lastScrollEvent;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.viewportScroller.setHistoryScrollRestoration('manual');
|
||||
this.router.events
|
||||
.pipe(
|
||||
filter((e): e is Scroll => e instanceof Scroll),
|
||||
tap((e) => {
|
||||
this.cancelScroll?.();
|
||||
this.canScroll = true;
|
||||
this._lastScrollEvent = e;
|
||||
}),
|
||||
filter(() => !this.disableScrolling),
|
||||
switchMap((e) => {
|
||||
return firstValueFrom(
|
||||
this.appRef.isStable.pipe(
|
||||
filter((stable) => stable),
|
||||
map(() => e),
|
||||
),
|
||||
);
|
||||
}),
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.scroll();
|
||||
});
|
||||
}
|
||||
|
||||
scroll() {
|
||||
if (!this._lastScrollEvent || !this.canScroll) {
|
||||
return;
|
||||
}
|
||||
// Prevent double scrolling on the same event
|
||||
this.canScroll = false;
|
||||
const {anchor, position} = this._lastScrollEvent;
|
||||
|
||||
// Don't scroll during rendering
|
||||
this.cancelScroll = afterNextRender(
|
||||
{
|
||||
write: () => {
|
||||
if (position) {
|
||||
this.viewportScroller.scrollToPosition(position);
|
||||
} else if (anchor) {
|
||||
this.viewportScroller.scrollToAnchor(anchor);
|
||||
} else {
|
||||
this.viewportScroller.scrollToPosition([0, 0]);
|
||||
}
|
||||
},
|
||||
},
|
||||
{injector: this.injector},
|
||||
).destroy;
|
||||
}
|
||||
}
|
||||
@@ -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,12 +11,10 @@ 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 = {location: {hostname: 'angular.dev'}};
|
||||
const fakeCurrentMajorVersion = 19;
|
||||
const fakeWindow = {};
|
||||
|
||||
it('should create the app', () => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -30,10 +28,6 @@ describe('AppComponent', () => {
|
||||
provide: Search,
|
||||
useValue: fakeSearch,
|
||||
},
|
||||
{
|
||||
provide: CURRENT_MAJOR_VERSION,
|
||||
useValue: fakeCurrentMajorVersion,
|
||||
},
|
||||
],
|
||||
});
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
|
||||
@@ -8,11 +8,9 @@
|
||||
|
||||
import {DOCUMENT, isPlatformBrowser} from '@angular/common';
|
||||
import {
|
||||
afterNextRender,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
inject,
|
||||
Injector,
|
||||
NgZone,
|
||||
OnInit,
|
||||
PLATFORM_ID,
|
||||
signal,
|
||||
@@ -25,18 +23,17 @@ import {
|
||||
getActivatedRouteSnapshotFromRouter,
|
||||
IS_SEARCH_DIALOG_OPEN,
|
||||
SearchDialog,
|
||||
WINDOW,
|
||||
} from '@angular/docs';
|
||||
import {Footer} from './core/layout/footer/footer.component';
|
||||
import {Navigation} from './core/layout/navigation/navigation.component';
|
||||
import {SecondaryNavigation} from './core/layout/secondary-navigation/secondary-navigation.component';
|
||||
import {ProgressBarComponent} from './core/layout/progress-bar/progress-bar.component';
|
||||
import {ESCAPE, SEARCH_TRIGGER_KEY} from './core/constants/keys';
|
||||
import {HeaderService} from './core/services/header.service';
|
||||
|
||||
@Component({
|
||||
selector: 'adev-root',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
selector: 'adev-root',
|
||||
imports: [
|
||||
CookiePopup,
|
||||
Navigation,
|
||||
@@ -49,14 +46,12 @@ import {HeaderService} from './core/services/header.service';
|
||||
],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
host: {
|
||||
'(window:keydown)': 'setSearchDialogVisibilityOnKeyPress($event)',
|
||||
},
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly ngZone = inject(NgZone);
|
||||
private readonly router = inject(Router);
|
||||
private readonly headerService = inject(HeaderService);
|
||||
private readonly window = inject(WINDOW);
|
||||
|
||||
currentUrl = signal('');
|
||||
displayFooter = signal(false);
|
||||
@@ -66,6 +61,7 @@ export class AppComponent implements OnInit {
|
||||
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
||||
|
||||
ngOnInit(): void {
|
||||
this.setSearchDialogVisibilityOnKeyPress();
|
||||
this.closeSearchDialogOnNavigationSkipped();
|
||||
this.router.events
|
||||
.pipe(
|
||||
@@ -76,8 +72,6 @@ export class AppComponent implements OnInit {
|
||||
this.currentUrl.set(url);
|
||||
this.setComponentsVisibility();
|
||||
this.displaySearchDialog.set(false);
|
||||
|
||||
this.updateCanonicalLink(url);
|
||||
});
|
||||
|
||||
this.focusFirstHeadingOnRouteChange();
|
||||
@@ -92,10 +86,6 @@ export class AppComponent implements OnInit {
|
||||
h1?.focus();
|
||||
}
|
||||
|
||||
private updateCanonicalLink(absoluteUrl: string) {
|
||||
this.headerService.setCanonical(absoluteUrl);
|
||||
}
|
||||
|
||||
private setComponentsVisibility(): void {
|
||||
const activatedRoute = getActivatedRouteSnapshotFromRouter(this.router as any);
|
||||
|
||||
@@ -115,16 +105,24 @@ export class AppComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
private setSearchDialogVisibilityOnKeyPress(event: KeyboardEvent): void {
|
||||
if (event.key === SEARCH_TRIGGER_KEY && (event.metaKey || event.ctrlKey)) {
|
||||
event.preventDefault();
|
||||
this.displaySearchDialog.update((display) => !display);
|
||||
}
|
||||
private setSearchDialogVisibilityOnKeyPress(): void {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.window.addEventListener('keydown', (event: KeyboardEvent) => {
|
||||
if (event.key === SEARCH_TRIGGER_KEY && (event.metaKey || event.ctrlKey)) {
|
||||
this.ngZone.run(() => {
|
||||
event.preventDefault();
|
||||
this.displaySearchDialog.update((display) => !display);
|
||||
});
|
||||
}
|
||||
|
||||
if (event.key === ESCAPE && this.displaySearchDialog()) {
|
||||
event.preventDefault();
|
||||
this.displaySearchDialog.set(false);
|
||||
}
|
||||
if (event.key === ESCAPE && this.displaySearchDialog()) {
|
||||
this.ngZone.run(() => {
|
||||
event.preventDefault();
|
||||
this.displaySearchDialog.set(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private closeSearchDialogOnNavigationSkipped(): void {
|
||||
|
||||
@@ -12,9 +12,8 @@ import {
|
||||
ApplicationConfig,
|
||||
ENVIRONMENT_INITIALIZER,
|
||||
ErrorHandler,
|
||||
VERSION,
|
||||
inject,
|
||||
provideExperimentalZonelessChangeDetection,
|
||||
provideZoneChangeDetection,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
DOCS_CONTENT_LOADER,
|
||||
@@ -32,7 +31,6 @@ import {
|
||||
TitleStrategy,
|
||||
createUrlTreeFromSnapshot,
|
||||
provideRouter,
|
||||
withComponentInputBinding,
|
||||
withInMemoryScrolling,
|
||||
withViewTransitions,
|
||||
} from '@angular/router';
|
||||
@@ -46,14 +44,12 @@ 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';
|
||||
import {AppScroller} from './app-scroller';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideRouter(
|
||||
routes,
|
||||
withInMemoryScrolling(),
|
||||
withInMemoryScrolling({anchorScrolling: 'enabled', scrollPositionRestoration: 'enabled'}),
|
||||
withViewTransitions({
|
||||
onViewTransitionCreated: ({transition, to}) => {
|
||||
const router = inject(Router);
|
||||
@@ -71,22 +67,11 @@ export const appConfig: ApplicationConfig = {
|
||||
}
|
||||
},
|
||||
}),
|
||||
withComponentInputBinding(),
|
||||
),
|
||||
provideExperimentalZonelessChangeDetection(),
|
||||
provideClientHydration(),
|
||||
provideHttpClient(withFetch()),
|
||||
provideAnimationsAsync(),
|
||||
{
|
||||
provide: CURRENT_MAJOR_VERSION,
|
||||
useValue: Number(VERSION.major),
|
||||
},
|
||||
{provide: ENVIRONMENT, useValue: environment},
|
||||
{
|
||||
provide: ENVIRONMENT_INITIALIZER,
|
||||
multi: true,
|
||||
useValue: () => inject(AppScroller),
|
||||
},
|
||||
{
|
||||
provide: ENVIRONMENT_INITIALIZER,
|
||||
multi: true,
|
||||
@@ -106,6 +91,7 @@ export const appConfig: ApplicationConfig = {
|
||||
deps: [DOCUMENT],
|
||||
},
|
||||
{provide: TitleStrategy, useClass: ADevTitleStrategy},
|
||||
provideZoneChangeDetection({eventCoalescing: true}),
|
||||
ReferenceScrollHandler,
|
||||
],
|
||||
};
|
||||
|
||||
@@ -8,6 +8,5 @@
|
||||
|
||||
export const GITHUB = 'https://github.com/angular/angular';
|
||||
export const X = 'https://x.com/angular';
|
||||
export const MEDIUM = 'https://blog.angular.dev';
|
||||
export const YOUTUBE = 'https://www.youtube.com/angular';
|
||||
export const DISCORD = 'https://discord.gg/angular';
|
||||
export const MEDIUM = 'https://blog.angular.io';
|
||||
export const YOUTUBE = 'https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw';
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
*/
|
||||
|
||||
export const VERSIONS_CONFIG = {
|
||||
aDevVersionsLinkPattern: 'https://{{prefix}}{{version}}angular.dev',
|
||||
aioVersions: [
|
||||
currentVersion: 'stable',
|
||||
historicalVersionsLinkPattern: 'https://v{{version}}.angular.dev',
|
||||
mainVersions: [
|
||||
{
|
||||
version: 'v17',
|
||||
url: 'https://v17.angular.io/docs',
|
||||
version: 'stable',
|
||||
url: 'https://angular.dev',
|
||||
},
|
||||
{
|
||||
version: 'v16',
|
||||
|
||||
@@ -17,7 +17,6 @@ export enum PagePrefix {
|
||||
PLAYGROUND = 'playground',
|
||||
REFERENCE = 'reference',
|
||||
TUTORIALS = 'tutorials',
|
||||
UPDATE = 'update-guide',
|
||||
}
|
||||
|
||||
// The enum with the default pages for each main tab
|
||||
@@ -26,5 +25,4 @@ export enum DefaultPage {
|
||||
REFERENCE = 'api',
|
||||
TUTORIALS = 'tutorials',
|
||||
PLAYGROUND = 'playground',
|
||||
UPDATE = 'update-guide',
|
||||
}
|
||||
|
||||
@@ -77,8 +77,6 @@
|
||||
}
|
||||
|
||||
.adev-version-picker {
|
||||
overflow-y: auto;
|
||||
max-height: 90vh;
|
||||
top: 30px;
|
||||
left: 10px;
|
||||
position: absolute;
|
||||
@@ -88,8 +86,8 @@
|
||||
padding-inline: 0;
|
||||
}
|
||||
|
||||
li a {
|
||||
line-height: 1em;
|
||||
li button {
|
||||
min-height: fit-content;
|
||||
}
|
||||
|
||||
@include mq.for-tablet {
|
||||
|
||||
@@ -82,8 +82,7 @@
|
||||
>
|
||||
<a aria-label="Angular homepage" routerLink="/">
|
||||
<!-- Logo Symbol -->
|
||||
@if(!isUwu) {
|
||||
<svg class="angular-logo" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
|
||||
<svg 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)"
|
||||
@@ -126,14 +125,6 @@
|
||||
</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+ -->
|
||||
@@ -165,14 +156,14 @@
|
||||
<ul class="adev-mini-menu adev-version-picker" cdkMenu>
|
||||
@for (item of versions(); track item) {
|
||||
<li>
|
||||
<a
|
||||
<button
|
||||
type="button"
|
||||
cdkMenuItem
|
||||
[href]="item.url"
|
||||
(click)="redirectToDocsVersion(item.url)"
|
||||
[attr.aria-label]="item.displayName"
|
||||
>
|
||||
<span>{{ item.displayName }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
@@ -380,24 +371,6 @@
|
||||
</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,7 +69,6 @@
|
||||
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(
|
||||
@@ -80,6 +79,11 @@
|
||||
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
|
||||
@@ -247,10 +251,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.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 {ActivatedRoute, NavigationEnd, Router, RouterLink} from '@angular/router';
|
||||
import {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, DISCORD} from '../../constants/links';
|
||||
import {GITHUB, MEDIUM, X, YOUTUBE} from '../../constants/links';
|
||||
import {PagePrefix} from '../../enums/pages';
|
||||
import {Theme, ThemeManager} from '../../services/theme-manager.service';
|
||||
import {VersionManager} from '../../services/version-manager.service';
|
||||
@@ -79,14 +79,10 @@ 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'},
|
||||
@@ -131,6 +127,10 @@ export class Navigation implements OnInit {
|
||||
this.closeMobileNavOnPrimaryRouteChange();
|
||||
}
|
||||
|
||||
redirectToDocsVersion(versionUrl: string): void {
|
||||
this.window.location.href = versionUrl;
|
||||
}
|
||||
|
||||
setTheme(theme: Theme): void {
|
||||
this.themeManager.setTheme(theme);
|
||||
}
|
||||
@@ -199,8 +199,7 @@ export class Navigation implements OnInit {
|
||||
this.activeRouteItem.set(PagePrefix.DOCS);
|
||||
} else if (
|
||||
urlAfterRedirects.startsWith(PagePrefix.REFERENCE) ||
|
||||
urlAfterRedirects.startsWith(PagePrefix.API) ||
|
||||
urlAfterRedirects.startsWith(PagePrefix.UPDATE)
|
||||
urlAfterRedirects.startsWith(PagePrefix.API)
|
||||
) {
|
||||
this.activeRouteItem.set(PagePrefix.REFERENCE);
|
||||
} else if (urlAfterRedirects === PagePrefix.PLAYGROUND) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
|
||||
|
||||
import {PROGRESS_BAR_DELAY, ProgressBarComponent} from './progress-bar.component';
|
||||
import {RouterTestingHarness, RouterTestingModule} from '@angular/router/testing';
|
||||
@@ -25,13 +25,13 @@ describe('ProgressBarComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should call progressBar.complete() on route change', async () => {
|
||||
it('should call progressBar.complete() on route change', fakeAsync(async () => {
|
||||
const progressBarCompleteSpy = spyOn(component.progressBar, 'complete');
|
||||
|
||||
const harness = await RouterTestingHarness.create();
|
||||
await harness.navigateByUrl('/');
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, PROGRESS_BAR_DELAY));
|
||||
tick(PROGRESS_BAR_DELAY);
|
||||
expect(progressBarCompleteSpy).toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
@use '@angular/docs/styles/media-queries' as mq;
|
||||
|
||||
:host {
|
||||
z-index: 100;
|
||||
|
||||
@include mq.for-tablet-landscape-up {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
// Render secondary nav below primary nav
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
@include mq.for-tablet-landscape-down {
|
||||
position: fixed;
|
||||
// Render secondary nav above mobile menu
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
@include mq.for-phone-only {
|
||||
transform: translateX(0);
|
||||
z-index: 99;
|
||||
transition: transform 0.3s ease;
|
||||
&:has(.docs-nav-secondary--open) {
|
||||
transform: translateX(82px);
|
||||
@@ -37,10 +40,7 @@
|
||||
transition: transform 0.45s ease;
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
transition:
|
||||
transform 0.45s ease,
|
||||
background-color 0.3s ease,
|
||||
border-color 0.3s ease;
|
||||
transition: transform 0.45s ease, background-color 0.3s ease, border-color 0.3s ease;
|
||||
}
|
||||
|
||||
@include mq.for-tablet-landscape-down {
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
PLATFORM_ID,
|
||||
computed,
|
||||
inject,
|
||||
signal,
|
||||
} from '@angular/core';
|
||||
import {takeUntilDestroyed, toObservable} from '@angular/core/rxjs-interop';
|
||||
import {
|
||||
@@ -65,19 +64,19 @@ export class SecondaryNavigation implements OnInit {
|
||||
private readonly router = inject(Router);
|
||||
private readonly window = inject(WINDOW);
|
||||
|
||||
readonly isSecondaryNavVisible = this.navigationState.isMobileNavVisible;
|
||||
readonly primaryActiveRouteItem = this.navigationState.primaryActiveRouteItem;
|
||||
readonly maxVisibleLevelsOnSecondaryNav = computed(() =>
|
||||
isSecondaryNavVisible = this.navigationState.isMobileNavVisible;
|
||||
primaryActiveRouteItem = this.navigationState.primaryActiveRouteItem;
|
||||
maxVisibleLevelsOnSecondaryNav = computed(() =>
|
||||
this.primaryActiveRouteItem() === PagePrefix.REFERENCE ? 1 : 2,
|
||||
);
|
||||
readonly navigationItemsSlides = this.navigationState.expandedItems;
|
||||
navigationItemsSlides = this.navigationState.expandedItems;
|
||||
navigationItems: NavigationItem[] | undefined;
|
||||
|
||||
translateX = computed(() => {
|
||||
const level = this.navigationState.expandedItems()?.length ?? 0;
|
||||
return `translateX(${-level * 100}%)`;
|
||||
});
|
||||
transition = signal('0ms');
|
||||
transition: string = '0ms';
|
||||
|
||||
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
|
||||
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
|
||||
@@ -183,7 +182,7 @@ export class SecondaryNavigation implements OnInit {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.transition.set(`${ANIMATION_DURATION}ms`);
|
||||
this.transition = `${ANIMATION_DURATION}ms`;
|
||||
}, ANIMATION_DURATION);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
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 {ChangeDetectionStrategy, Component, Inject, inject} from '@angular/core';
|
||||
import {Component, Inject} from '@angular/core';
|
||||
import {MAT_SNACK_BAR_DATA, MatSnackBarAction, MatSnackBarRef} from '@angular/material/snack-bar';
|
||||
|
||||
export interface ErrorSnackBarData {
|
||||
@@ -16,7 +16,6 @@ export interface ErrorSnackBarData {
|
||||
|
||||
@Component({
|
||||
selector: 'error-snack-bar',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: `
|
||||
{{ message }}
|
||||
<button
|
||||
@@ -29,16 +28,18 @@ export interface ErrorSnackBarData {
|
||||
{{ actionText }}
|
||||
</button>
|
||||
`,
|
||||
standalone: true,
|
||||
imports: [MatSnackBarAction],
|
||||
standalone: true,
|
||||
styles: `:host { display: flex; align-items: center; button { margin-left: 16px }}`,
|
||||
})
|
||||
export class ErrorSnackBar {
|
||||
protected message: string;
|
||||
protected actionText?: string;
|
||||
|
||||
constructor(protected snackBarRef: MatSnackBarRef<ErrorSnackBar>) {
|
||||
const data = inject(MAT_SNACK_BAR_DATA) as ErrorSnackBarData;
|
||||
constructor(
|
||||
protected snackBarRef: MatSnackBarRef<ErrorSnackBar>,
|
||||
@Inject(MAT_SNACK_BAR_DATA) public data: ErrorSnackBarData,
|
||||
) {
|
||||
this.message = data.message;
|
||||
this.actionText = data.actionText;
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
import {HeaderService} from './header.service';
|
||||
import {link} from 'fs';
|
||||
|
||||
describe('HeaderService', () => {
|
||||
let service: HeaderService;
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.inject(HeaderService);
|
||||
});
|
||||
|
||||
it('setCanonical', () => {
|
||||
// setCanonical assumes there is a preexisting element
|
||||
const linkEl = document.createElement('link');
|
||||
linkEl.setAttribute('rel', 'canonical');
|
||||
document.querySelector('head')?.appendChild(linkEl);
|
||||
|
||||
service.setCanonical('/some/link');
|
||||
expect(document.querySelector('link[rel=canonical]')!.getAttribute('href')).toBe(
|
||||
'https://angular.dev/some/link',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {Injectable, inject} from '@angular/core';
|
||||
|
||||
const ANGULAR_DEV = 'https://angular.dev';
|
||||
|
||||
/**
|
||||
* Information about the deployment of this application.
|
||||
*/
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class HeaderService {
|
||||
private readonly document = inject(DOCUMENT);
|
||||
|
||||
/**
|
||||
* Sets the canonical link in the header.
|
||||
* It supposes the header link is already present in the index.html
|
||||
*
|
||||
* The function behave invariably and will always point to angular.dev,
|
||||
* no matter if it's a specific version build
|
||||
*/
|
||||
setCanonical(absolutePath: string): void {
|
||||
const pathWithoutFragment = this.normalizePath(absolutePath).split('#')[0];
|
||||
const fullPath = `${ANGULAR_DEV}/${pathWithoutFragment}`;
|
||||
this.document.querySelector('link[rel=canonical]')?.setAttribute('href', fullPath);
|
||||
}
|
||||
|
||||
private normalizePath(path: string): string {
|
||||
if (path[0] === '/') {
|
||||
return path.substring(1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
@@ -8,52 +8,17 @@
|
||||
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
import {INITIAL_ADEV_DOCS_VERSION, VersionManager} from './version-manager.service';
|
||||
import {WINDOW} from '@angular/docs';
|
||||
import {CURRENT_MAJOR_VERSION} from '../providers/current-version';
|
||||
import {VersionManager} from './version-manager.service';
|
||||
|
||||
describe('VersionManager', () => {
|
||||
const fakeWindow = {location: {hostname: 'angular.dev'}};
|
||||
const fakeCurrentMajorVersion = 19;
|
||||
|
||||
let service: VersionManager;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: WINDOW,
|
||||
useValue: fakeWindow,
|
||||
},
|
||||
{
|
||||
provide: CURRENT_MAJOR_VERSION,
|
||||
useValue: fakeCurrentMajorVersion,
|
||||
},
|
||||
],
|
||||
});
|
||||
TestBed.configureTestingModule({});
|
||||
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,10 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {Injectable, computed, inject, signal} from '@angular/core';
|
||||
import {Injectable, VERSION, computed, 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;
|
||||
@@ -19,84 +17,39 @@ export interface Version {
|
||||
|
||||
export type VersionMode = 'stable' | 'deprecated' | 'rc' | 'next' | number;
|
||||
|
||||
export const INITIAL_ADEV_DOCS_VERSION = 18;
|
||||
export const VERSION_PLACEHOLDER = '{{version}}';
|
||||
export const MODE_PLACEHOLDER = '{{prefix}}';
|
||||
export const INITIAL_DOCS_VERSION = 17;
|
||||
export const VERSION_PATTERN_PLACEHOLDER = '{{version}}';
|
||||
|
||||
@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[]>([
|
||||
...this.getRecentVersions(),
|
||||
...this.getAdevVersions(),
|
||||
...this.getAioVersions(),
|
||||
...VERSIONS_CONFIG.mainVersions.map((item) =>
|
||||
this.mapToVersion(item as Pick<Version, 'url' | 'version'>),
|
||||
),
|
||||
...this.getHistoricalVersions(),
|
||||
]);
|
||||
|
||||
currentDocsVersion = computed(() => {
|
||||
return this.versions().find(
|
||||
(version) => version.version.toString() === this.currentVersionMode,
|
||||
(version) => version.version.toString() === VERSIONS_CONFIG.currentVersion,
|
||||
);
|
||||
});
|
||||
|
||||
// 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: 'https://angular.dev/',
|
||||
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),
|
||||
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(),
|
||||
),
|
||||
displayName: this.getVersion(version),
|
||||
version: 'deprecated',
|
||||
version,
|
||||
});
|
||||
}
|
||||
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'>),
|
||||
);
|
||||
return historicalVersions;
|
||||
}
|
||||
|
||||
private mapToVersion(value: Pick<Version, 'url' | 'version'>): Version {
|
||||
@@ -107,23 +60,14 @@ export class VersionManager {
|
||||
}
|
||||
|
||||
private getVersion(versionMode: VersionMode): string {
|
||||
if (versionMode === 'stable' || versionMode === 'deprecated') {
|
||||
return `v${this.currentMajorVersion}`;
|
||||
if (versionMode === 'stable') {
|
||||
return 'v17';
|
||||
// Temporarily commenting out till this works correctly
|
||||
// return `v${VERSION.major}`;
|
||||
}
|
||||
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()}.`}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,14 +65,6 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="adev-editor-download-button"
|
||||
type="button"
|
||||
(click)="openCurrentCodeInStackBlitz()"
|
||||
aria-label="Open current code in editor in StackBlitz"
|
||||
>
|
||||
<docs-icon>launch</docs-icon>
|
||||
</button>
|
||||
<button
|
||||
class="adev-editor-download-button"
|
||||
type="button"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {Location, NgFor, NgIf} from '@angular/common';
|
||||
import {NgFor, NgIf} from '@angular/common';
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
} from '@angular/core';
|
||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
import {MatTabGroup, MatTabsModule} from '@angular/material/tabs';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
import {debounceTime, map} from 'rxjs';
|
||||
|
||||
import {TerminalType} from '../terminal/terminal-handler.service';
|
||||
@@ -29,7 +28,6 @@ import {EmbeddedTutorialManager} from '../embedded-tutorial-manager.service';
|
||||
import {CodeMirrorEditor} from './code-mirror-editor.service';
|
||||
import {DiagnosticWithLocation, DiagnosticsState} from './services/diagnostics-state.service';
|
||||
import {DownloadManager} from '../download-manager.service';
|
||||
import {StackBlitzOpener} from '../stackblitz-opener.service';
|
||||
import {ClickOutside, IconComponent} from '@angular/docs';
|
||||
|
||||
export const REQUIRED_FILES = new Set([
|
||||
@@ -38,8 +36,6 @@ export const REQUIRED_FILES = new Set([
|
||||
'src/app/app.component.ts',
|
||||
]);
|
||||
|
||||
const ANGULAR_DEV = 'https://angular.dev';
|
||||
|
||||
@Component({
|
||||
selector: 'docs-tutorial-code-editor',
|
||||
standalone: true,
|
||||
@@ -77,9 +73,6 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
|
||||
private readonly codeMirrorEditor = inject(CodeMirrorEditor);
|
||||
private readonly diagnosticsState = inject(DiagnosticsState);
|
||||
private readonly downloadManager = inject(DownloadManager);
|
||||
private readonly stackblitzOpener = inject(StackBlitzOpener);
|
||||
private readonly title = inject(Title);
|
||||
private readonly location = inject(Location);
|
||||
private readonly embeddedTutorialManager = inject(EmbeddedTutorialManager);
|
||||
|
||||
private readonly errors$ = this.diagnosticsState.diagnostics$.pipe(
|
||||
@@ -117,16 +110,6 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
|
||||
this.codeMirrorEditor.disable();
|
||||
}
|
||||
|
||||
async openCurrentCodeInStackBlitz(): Promise<void> {
|
||||
const title = this.title.getTitle();
|
||||
|
||||
const path = this.location.path();
|
||||
const editorUrl = `${ANGULAR_DEV}${path}`;
|
||||
const description = `Angular.dev example generated from [${editorUrl}](${editorUrl})`;
|
||||
|
||||
await this.stackblitzOpener.openCurrentSolutionInStackBlitz({title, description});
|
||||
}
|
||||
|
||||
async downloadCurrentCodeEditorState(): Promise<void> {
|
||||
const name = this.embeddedTutorialManager.tutorialId();
|
||||
await this.downloadManager.downloadCurrentStateOfTheSolution(name);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {signal} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {TestBed, fakeAsync, tick} from '@angular/core/testing';
|
||||
import {BehaviorSubject, Subject} from 'rxjs';
|
||||
import {EditorState} from '@codemirror/state';
|
||||
import type {FileSystemTree} from '@webcontainer/api';
|
||||
@@ -142,19 +142,17 @@ describe('CodeMirrorEditor', () => {
|
||||
expect(service.currentFile().content).toBe(newContent);
|
||||
});
|
||||
|
||||
it('should write the changed file content to the sandbox filesystem', () => {
|
||||
jasmine.clock().install();
|
||||
jasmine.clock().mockDate();
|
||||
it('should write the changed file content to the sandbox filesystem', fakeAsync(() => {
|
||||
const newContent = 'new content';
|
||||
|
||||
const nodeRuntimeSandboxSpy = spyOn(fakeNodeRuntimeSandbox, 'writeFile');
|
||||
|
||||
dispatchDocumentChange(newContent);
|
||||
jasmine.clock().tick(EDITOR_CONTENT_CHANGE_DELAY_MILLIES);
|
||||
|
||||
tick(EDITOR_CONTENT_CHANGE_DELAY_MILLIES);
|
||||
|
||||
expect(nodeRuntimeSandboxSpy).toHaveBeenCalledWith(service.currentFile().filename, newContent);
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should add created file to code editor', async () => {
|
||||
const newFile = 'new-component.component.ts';
|
||||
|
||||
@@ -8,7 +8,6 @@ $width-breakpoint: 950px;
|
||||
container-name: embedded-editor;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
border: 1px solid var(--senary-contrast);
|
||||
}
|
||||
|
||||
// The entire thing - editor, terminal, console
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
import {NgIf, isPlatformBrowser} from '@angular/common';
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
@@ -45,12 +44,11 @@ export const LARGE_EDITOR_WIDTH_BREAKPOINT = 950;
|
||||
export const LARGE_EDITOR_HEIGHT_BREAKPOINT = 550;
|
||||
|
||||
@Component({
|
||||
selector: EMBEDDED_EDITOR_SELECTOR,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [AngularSplitModule, CodeEditor, Preview, Terminal, NgIf, MatTabsModule, IconComponent],
|
||||
selector: EMBEDDED_EDITOR_SELECTOR,
|
||||
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 {
|
||||
|
||||
@@ -107,10 +107,7 @@ export class NodeRuntimeSandbox {
|
||||
|
||||
console.timeEnd('Load time');
|
||||
} catch (error: any) {
|
||||
// If we're already in an error state, throw away the most recent error which may have happened because
|
||||
// we were in the error state already and tried to do more things after terminating.
|
||||
const message = this.nodeRuntimeState.error()?.message ?? error.message;
|
||||
this.setErrorState(message);
|
||||
this.setErrorState(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {TestBed, fakeAsync, tick} from '@angular/core/testing';
|
||||
import {DebugElement, signal} from '@angular/core';
|
||||
import {By} from '@angular/platform-browser';
|
||||
import {of} from 'rxjs';
|
||||
@@ -64,16 +64,16 @@ describe('Preview', () => {
|
||||
};
|
||||
};
|
||||
|
||||
it('should set iframe src on init', async () => {
|
||||
it('should set iframe src on init', fakeAsync(() => {
|
||||
const {component, PREVIEW_URL} = beforeEach();
|
||||
|
||||
component.ngAfterViewInit();
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
tick(100);
|
||||
|
||||
expect(component.previewIframe?.nativeElement).toBeTruthy();
|
||||
expect(component.previewIframe?.nativeElement?.src).toBe(PREVIEW_URL);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not render loading elements if the loadingStep is READY or ERROR', () => {
|
||||
const {fixture, fakeNodeRuntimeState, getLoadingElementsWrapper} = beforeEach();
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
import {StackBlitzOpener} from './stackblitz-opener.service';
|
||||
|
||||
describe('StackBlitzOpener', () => {
|
||||
let service: StackBlitzOpener;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(StackBlitzOpener);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,46 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {EnvironmentInjector, Injectable, inject} from '@angular/core';
|
||||
import sdk, {Project, ProjectFiles} from '@stackblitz/sdk';
|
||||
import {injectAsync} from '../core/services/inject-async';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class StackBlitzOpener {
|
||||
private readonly environmentInjector = inject(EnvironmentInjector);
|
||||
|
||||
/**
|
||||
* Generate a StackBlitz project from the current state of the solution in the EmbeddedEditor
|
||||
*/
|
||||
async openCurrentSolutionInStackBlitz(
|
||||
projectMetadata: Pick<Project, 'title' | 'description'>,
|
||||
): Promise<void> {
|
||||
const nodeRuntimeSandbox = await injectAsync(this.environmentInjector, () =>
|
||||
import('./node-runtime-sandbox.service').then((c) => c.NodeRuntimeSandbox),
|
||||
);
|
||||
|
||||
const runtimeFiles = await nodeRuntimeSandbox.getSolutionFiles();
|
||||
|
||||
const stackblitzProjectFiles: ProjectFiles = {};
|
||||
runtimeFiles.forEach((file) => {
|
||||
// Leading slashes are incompatible with StackBlitz SDK they are removed
|
||||
const path = file.path.replace(/^\//, '');
|
||||
|
||||
stackblitzProjectFiles[path] =
|
||||
typeof file.content !== 'string' ? new TextDecoder().decode(file.content) : file.content;
|
||||
});
|
||||
|
||||
sdk.openProject({
|
||||
...projectMetadata,
|
||||
template: 'node',
|
||||
files: stackblitzProjectFiles,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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/xterm/css/xterm.css';
|
||||
@import 'xterm/css/xterm.css';
|
||||
|
||||
.docs-tutorial-terminal {
|
||||
display: block;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
|
||||
import {By} from '@angular/platform-browser';
|
||||
|
||||
import {Terminal} from './terminal.component';
|
||||
@@ -61,12 +61,12 @@ describe('Terminal', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should call resizeToFitParent on window resize', async () => {
|
||||
it('should call resizeToFitParent on window resize', fakeAsync(() => {
|
||||
fakeWindow.dispatchEvent(new Event('resize'));
|
||||
|
||||
// debounce time
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
tick(50);
|
||||
|
||||
expect(terminalHandlerSpy.resizeToFitParent).toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -8,14 +8,13 @@
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {DocContent, DocViewer} from '@angular/docs';
|
||||
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
|
||||
import {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,7 +7,6 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
EnvironmentInjector,
|
||||
@@ -21,7 +20,6 @@ import {EmbeddedEditor, EmbeddedTutorialManager} from '../../../editor';
|
||||
|
||||
@Component({
|
||||
selector: 'adev-code-editor',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [EmbeddedEditor],
|
||||
template: `
|
||||
|
||||
@@ -2,70 +2,60 @@
|
||||
<div class="adev-top">
|
||||
<div class="adev-top-content">
|
||||
<!-- Banner(s) can be edited here! -->
|
||||
<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 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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="adev-canvas"></div>
|
||||
<div class="adev-logo">
|
||||
<div class="adev-logo-wordmark">
|
||||
@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;"
|
||||
/>
|
||||
}
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="adev-scale">
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
Component,
|
||||
ElementRef,
|
||||
Injector,
|
||||
NgZone,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
PLATFORM_ID,
|
||||
@@ -20,7 +21,7 @@ import {
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
import {WINDOW, shouldReduceMotion, isIos} from '@angular/docs';
|
||||
import {ActivatedRoute, RouterLink} from '@angular/router';
|
||||
import {RouterLink} from '@angular/router';
|
||||
|
||||
import {injectAsync} from '../../core/services/inject-async';
|
||||
|
||||
@@ -44,12 +45,11 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly injector = inject(Injector);
|
||||
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;
|
||||
@@ -63,7 +63,7 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
ngAfterViewInit(): void {
|
||||
this.element = this.home.nativeElement;
|
||||
|
||||
if (isPlatformBrowser(this.platformId)) {
|
||||
@@ -74,8 +74,10 @@ 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() && !this.isUwu) {
|
||||
this.loadHomeAnimation();
|
||||
if (this.isWebGLAvailable() && !shouldReduceMotion()) {
|
||||
this.ngZone.runOutsideAngular(async () => {
|
||||
await this.loadHomeAnimation();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
display: block;
|
||||
padding: var(--layout-padding);
|
||||
padding-block-end: 100px;
|
||||
height: 100vh;
|
||||
height: calc(98vh);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
+3
-2
@@ -70,6 +70,7 @@
|
||||
.docs-code {
|
||||
pre {
|
||||
margin-block: 0;
|
||||
padding-block: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,13 +120,13 @@
|
||||
transition: background-color 0.3s ease;
|
||||
font-family: monospace;
|
||||
|
||||
&.line {
|
||||
&.hljs-ln-line {
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
padding-block: 0.25rem;
|
||||
}
|
||||
|
||||
&.shiki-ln-line-highlighted {
|
||||
&.hljs-ln-line-highlighted {
|
||||
background-color: var(--senary-contrast);
|
||||
}
|
||||
&:hover {
|
||||
|
||||
+5
-5
@@ -8,7 +8,7 @@
|
||||
|
||||
import {HarnessLoader} from '@angular/cdk/testing';
|
||||
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {TestBed, waitForAsync} from '@angular/core/testing';
|
||||
import {MatTabGroupHarness} from '@angular/material/tabs/testing';
|
||||
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {ReferenceScrollHandler} from '../services/reference-scroll-handler.service';
|
||||
@@ -68,15 +68,15 @@ describe('ApiReferenceDetailsPage', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render tabs for all elements with tab attribute', async () => {
|
||||
it('should render tabs for all elements with tab attribute', waitForAsync(async () => {
|
||||
const matTabGroup = await loader.getHarness(MatTabGroupHarness);
|
||||
|
||||
const tabs = await matTabGroup.getTabs();
|
||||
|
||||
expect(tabs.length).toBe(4);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should display members cards when API tab is active', async () => {
|
||||
it('should display members cards when API tab is active', waitForAsync(async () => {
|
||||
const matTabGroup = await loader.getHarness(MatTabGroupHarness);
|
||||
const tabs = await matTabGroup.getTabs();
|
||||
|
||||
@@ -94,7 +94,7 @@ describe('ApiReferenceDetailsPage', () => {
|
||||
|
||||
membersCard = harness.fixture.debugElement.query(By.css('.docs-reference-members-container'));
|
||||
expect(membersCard).toBeTruthy();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should setup scroll listeners when API members are loaded', () => {
|
||||
const setupListenersSpy = spyOn(fakeApiReferenceScrollHandler, 'setupListeners');
|
||||
|
||||
+25
-16
@@ -11,19 +11,17 @@ import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
DestroyRef,
|
||||
EnvironmentInjector,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
afterNextRender,
|
||||
inject,
|
||||
signal,
|
||||
} from '@angular/core';
|
||||
import {DOCUMENT, NgFor, NgIf} from '@angular/common';
|
||||
import {DOCUMENT, NgFor, NgIf, ViewportScroller} from '@angular/common';
|
||||
import {MatTabGroup, MatTabsModule} from '@angular/material/tabs';
|
||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
import {distinctUntilChanged, map} from 'rxjs/operators';
|
||||
import {takeUntilDestroyed, toSignal} from '@angular/core/rxjs-interop';
|
||||
import {distinctUntilChanged, filter, map, take} from 'rxjs/operators';
|
||||
import {DocContent, DocViewer} from '@angular/docs';
|
||||
import {ActivatedRoute, Router, RouterLink} from '@angular/router';
|
||||
import {ActivatedRoute, Router, RouterLink, Scroll} from '@angular/router';
|
||||
import {ApiItemType} from './../interfaces/api-item-type';
|
||||
import {ReferenceScrollHandler} from '../services/reference-scroll-handler.service';
|
||||
import {
|
||||
@@ -36,7 +34,6 @@ import {
|
||||
API_REFERENCE_TAB_BODY_CLASS_NAME,
|
||||
API_REFERENCE_TAB_URL_ATTRIBUTE,
|
||||
} from '../constants/api-reference-prerender.constants';
|
||||
import {AppScroller} from '../../../app-scroller';
|
||||
|
||||
@Component({
|
||||
selector: 'adev-reference-page',
|
||||
@@ -54,7 +51,15 @@ export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly router = inject(Router);
|
||||
private readonly scrollHandler = inject(ReferenceScrollHandler);
|
||||
private readonly appScroller = inject(AppScroller);
|
||||
private readonly scroller = inject(ViewportScroller);
|
||||
private scrollEvent = toSignal(
|
||||
this.router.events.pipe(
|
||||
filter((e): e is Scroll => e instanceof Scroll),
|
||||
take(1),
|
||||
),
|
||||
{initialValue: null},
|
||||
);
|
||||
private cardsDisplayedOnInit = false;
|
||||
|
||||
ApiItemType = ApiItemType;
|
||||
|
||||
@@ -65,24 +70,28 @@ export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
|
||||
membersMarginTopInPx = this.scrollHandler.membersMarginTopInPx;
|
||||
selectedTabIndex = signal(0);
|
||||
|
||||
constructor() {
|
||||
this.appScroller.disableScrolling = true;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.setPageContent();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.appScroller.disableScrolling = false;
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.setActiveTab();
|
||||
if (this.canDisplayCards()) {
|
||||
this.cardsDisplayedOnInit = true;
|
||||
}
|
||||
this.listenToTabChange();
|
||||
}
|
||||
|
||||
membersCardsLoaded(): void {
|
||||
const event = this.scrollEvent();
|
||||
if (this.cardsDisplayedOnInit && event) {
|
||||
// Cards loaded after scroll event happened. We have to handle the scroll event manually
|
||||
if (event.position) {
|
||||
this.scroller.scrollToPosition(event.position);
|
||||
} else if (event.anchor) {
|
||||
this.scroller.scrollToAnchor(event.anchor);
|
||||
}
|
||||
}
|
||||
this.scrollHandler.setupListeners(API_TAB_CLASS_NAME);
|
||||
}
|
||||
|
||||
|
||||
+24
-21
@@ -1,13 +1,30 @@
|
||||
<div class="adev-reference-list-page">
|
||||
<header>
|
||||
<h6>Getting Started</h6>
|
||||
<h1>API Reference</h1>
|
||||
<h1 tabindex="-1">API Reference</h1>
|
||||
</header>
|
||||
|
||||
@if (featuredGroup().items.length) {
|
||||
<adev-api-items-section [group]="featuredGroup()" class="adev-featured-list" />
|
||||
<adev-api-items-section [group]="featuredGroup()" class="adev-featured-list" />
|
||||
}
|
||||
|
||||
<form class="adev-reference-list-form">
|
||||
<docs-text-field
|
||||
name="query"
|
||||
placeholder="Filter"
|
||||
[ngModel]="query()"
|
||||
(ngModelChange)="query.set($event)"
|
||||
/>
|
||||
|
||||
<div class="adev-reference-list-form-part-two">
|
||||
<docs-slide-toggle
|
||||
buttonId="includeDeprecated"
|
||||
label="Show @deprecated"
|
||||
name="includeDeprecated"
|
||||
[ngModel]="includeDeprecated()"
|
||||
(ngModelChange)="includeDeprecated.set($event)"
|
||||
/>
|
||||
</div>
|
||||
<ul class="adev-reference-list-legend">
|
||||
@for (itemType of itemTypes; track itemType) {
|
||||
<li
|
||||
@@ -20,24 +37,10 @@
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
<docs-text-field name="query" placeholder="Filter" [(ngModel)]="query" />
|
||||
|
||||
<div class="adev-reference-list-form-part-two">
|
||||
<docs-slide-toggle
|
||||
buttonId="includeDeprecated"
|
||||
label="Show @deprecated"
|
||||
name="includeDeprecated"
|
||||
[(ngModel)]="includeDeprecated"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@for (group of filteredGroups(); track group.id) {
|
||||
<adev-api-items-section [group]="group" />
|
||||
} @empty {
|
||||
<div class="adev-reference-list-empty">
|
||||
<p>No API items found.</p>
|
||||
</div>
|
||||
}
|
||||
</form>
|
||||
|
||||
@for (group of filteredGroups(); track group.id) {
|
||||
<adev-api-items-section [group]="group" />
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
+4
-13
@@ -25,6 +25,7 @@
|
||||
.adev-reference-list-legend {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
padding-block-end: 0.5rem;
|
||||
margin-block-start: 0;
|
||||
padding-inline: 0;
|
||||
cursor: pointer;
|
||||
@@ -56,10 +57,7 @@
|
||||
border-radius: 0.25rem;
|
||||
margin-inline-end: 0.5rem;
|
||||
margin-block-end: 0.5rem;
|
||||
transition:
|
||||
color 0.3s ease,
|
||||
background 0.3s ease,
|
||||
border 0.3s ease;
|
||||
transition: color 0.3s ease, background 0.3s ease, border 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
color: var(--primary-contrast);
|
||||
@@ -76,8 +74,8 @@
|
||||
|
||||
.adev-reference-list-form {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap-reverse;
|
||||
gap: 1.5rem;
|
||||
padding-block-start: 1.5rem;
|
||||
padding-block-end: 2rem;
|
||||
@@ -90,13 +88,6 @@
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.adev-reference-list-empty {
|
||||
text-align: center;
|
||||
p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.adev-featured-list {
|
||||
display: block;
|
||||
padding-block-end: 1rem;
|
||||
|
||||
+9
-15
@@ -9,11 +9,10 @@
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import ApiReferenceList, {ALL_STATUSES_KEY} from './api-reference-list.component';
|
||||
import {RouterTestingModule} from '@angular/router/testing';
|
||||
import {ApiReferenceManager} from './api-reference-manager.service';
|
||||
import {signal} from '@angular/core';
|
||||
import {ApiItemType} from '../interfaces/api-item-type';
|
||||
import {RouterTestingHarness} from '@angular/router/testing';
|
||||
import {provideRouter} from '@angular/router';
|
||||
|
||||
describe('ApiReferenceList', () => {
|
||||
let component: ApiReferenceList;
|
||||
@@ -53,11 +52,8 @@ describe('ApiReferenceList', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ApiReferenceList],
|
||||
providers: [
|
||||
{provide: ApiReferenceManager, useValue: fakeApiReferenceManager},
|
||||
provideRouter([{path: 'api', component: ApiReferenceList}]),
|
||||
],
|
||||
imports: [ApiReferenceList, RouterTestingModule],
|
||||
providers: [{provide: ApiReferenceManager, useValue: fakeApiReferenceManager}],
|
||||
});
|
||||
fixture = TestBed.createComponent(ApiReferenceList);
|
||||
component = fixture.componentInstance;
|
||||
@@ -94,27 +90,25 @@ describe('ApiReferenceList', () => {
|
||||
});
|
||||
|
||||
it('should display only class items when user selects Class in the Type select', () => {
|
||||
fixture.componentInstance.type.set(ApiItemType.CLASS);
|
||||
component.type.set(ApiItemType.CLASS);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.type()).toEqual(ApiItemType.CLASS);
|
||||
expect(component.filteredGroups()![0].items).toEqual([fakeItem2]);
|
||||
});
|
||||
|
||||
it('should set selected type when provided type is different than selected', async () => {
|
||||
expect(component.type()).toBe(ALL_STATUSES_KEY);
|
||||
it('should set selected type when provided type is different than selected', () => {
|
||||
component.filterByItemType(ApiItemType.BLOCK);
|
||||
await RouterTestingHarness.create(`/api?type=${ApiItemType.BLOCK}`);
|
||||
|
||||
expect(component.type()).toBe(ApiItemType.BLOCK);
|
||||
});
|
||||
|
||||
it('should reset selected type when provided type is equal to selected', async () => {
|
||||
it('should reset selected type when provided type is equal to selected', () => {
|
||||
component.filterByItemType(ApiItemType.BLOCK);
|
||||
const harness = await RouterTestingHarness.create(`/api?type=${ApiItemType.BLOCK}`);
|
||||
|
||||
expect(component.type()).toBe(ApiItemType.BLOCK);
|
||||
|
||||
component.filterByItemType(ApiItemType.BLOCK);
|
||||
harness.navigateByUrl(`/api`);
|
||||
|
||||
expect(component.type()).toBe(ALL_STATUSES_KEY);
|
||||
});
|
||||
});
|
||||
|
||||
+4
-26
@@ -6,17 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
effect,
|
||||
ElementRef,
|
||||
inject,
|
||||
model,
|
||||
signal,
|
||||
viewChild,
|
||||
} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, computed, inject, signal} from '@angular/core';
|
||||
import ApiItemsSection from '../api-items-section/api-items-section.component';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {SlideToggle, TextField} from '@angular/docs';
|
||||
@@ -48,22 +38,12 @@ export const ALL_STATUSES_KEY = 'All';
|
||||
})
|
||||
export default class ApiReferenceList {
|
||||
private readonly apiReferenceManager = inject(ApiReferenceManager);
|
||||
filterInput = viewChild.required(TextField, {read: ElementRef});
|
||||
|
||||
private readonly allGroups = this.apiReferenceManager.apiGroups;
|
||||
|
||||
private filterEffect = effect(() => {
|
||||
if (matchMedia('(hover: hover) and (pointer:fine)').matches) {
|
||||
// Lord forgive me for I have sinned
|
||||
// Use the CVA to focus when https://github.com/angular/angular/issues/31133 is implemented
|
||||
this.filterInput().nativeElement.querySelector('input').focus();
|
||||
}
|
||||
});
|
||||
|
||||
query = signal('');
|
||||
includeDeprecated = signal(false);
|
||||
|
||||
type = model<string | undefined>(ALL_STATUSES_KEY);
|
||||
type = signal(ALL_STATUSES_KEY);
|
||||
|
||||
featuredGroup = this.apiReferenceManager.featuredGroup;
|
||||
filteredGroups = computed((): ApiItemsGroup[] => {
|
||||
@@ -78,9 +58,7 @@ export default class ApiReferenceList {
|
||||
? apiItem.title.toLocaleLowerCase().includes(this.query().toLocaleLowerCase())
|
||||
: true) &&
|
||||
(this.includeDeprecated() ? true : apiItem.isDeprecated === this.includeDeprecated()) &&
|
||||
(this.type() === undefined ||
|
||||
this.type() === ALL_STATUSES_KEY ||
|
||||
apiItem.itemType === this.type())
|
||||
(this.type() === ALL_STATUSES_KEY || apiItem.itemType === this.type())
|
||||
);
|
||||
}),
|
||||
}))
|
||||
@@ -89,6 +67,6 @@ export default class ApiReferenceList {
|
||||
itemTypes = Object.values(ApiItemType);
|
||||
|
||||
filterByItemType(itemType: ApiItemType): void {
|
||||
this.type.update((currentType) => (currentType === itemType ? ALL_STATUSES_KEY : itemType));
|
||||
this.type.set(this.type() === itemType ? ALL_STATUSES_KEY : itemType);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -81,7 +81,7 @@
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&:has(.shiki-ln-line-highlighted) {
|
||||
&:has(.hljs-ln-line-highlighted) {
|
||||
&::before {
|
||||
background: var(--red-to-pink-to-purple-horizontal-gradient);
|
||||
}
|
||||
@@ -95,8 +95,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.shiki-ln-line-argument,
|
||||
.shiki-ln-line-option {
|
||||
.hljs-ln-line-argument,
|
||||
.hljs-ln-line-option {
|
||||
padding: 0.1rem 0.2rem 0.2rem;
|
||||
margin-inline: 0.1rem;
|
||||
color: var(--quaternary-contrast);
|
||||
@@ -110,12 +110,12 @@
|
||||
background: var(--septenary-contrast);
|
||||
}
|
||||
|
||||
&.shiki-ln-line-highlighted {
|
||||
&.hljs-ln-line-highlighted {
|
||||
color: var(--primary-contrast);
|
||||
background: var(--senary-contrast);
|
||||
}
|
||||
}
|
||||
.shiki-ln-line-argument {
|
||||
.hljs-ln-line-argument {
|
||||
margin-inline-start: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,6 @@ export const API_REFERENCE_TAB_API_LABEL = 'API';
|
||||
export const API_REFERENCE_TAB_QUERY_PARAM = 'tab';
|
||||
export const API_TAB_CLASS_NAME = '.docs-reference-api-tab';
|
||||
export const API_REFERENCE_MEMBER_CARD_CLASS_NAME = '.docs-reference-member-card';
|
||||
export const API_TAB_ACTIVE_CODE_LINE = 'shiki-ln-line-highlighted';
|
||||
export const HIGHLIGHT_JS_CODE_LINE_CLASS_NAME = 'shiki-ln-line';
|
||||
export const API_TAB_ACTIVE_CODE_LINE = 'hljs-ln-line-highlighted';
|
||||
export const HIGHLIGHT_JS_CODE_LINE_CLASS_NAME = 'hljs-ln-line';
|
||||
export const MEMBER_ID_ATTRIBUTE = 'member-id';
|
||||
|
||||
@@ -35,7 +35,6 @@ export function mapApiManifestToRoutes(): Route[] {
|
||||
),
|
||||
},
|
||||
data: {
|
||||
label: api.name,
|
||||
displaySecondaryNav: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
DestroyRef,
|
||||
EnvironmentInjector,
|
||||
Injectable,
|
||||
NgZone,
|
||||
OnDestroy,
|
||||
afterNextRender,
|
||||
inject,
|
||||
@@ -18,7 +19,7 @@ import {
|
||||
} from '@angular/core';
|
||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
import {fromEvent} from 'rxjs';
|
||||
import {auditTime, skipWhile} from 'rxjs/operators';
|
||||
import {auditTime} from 'rxjs/operators';
|
||||
import {
|
||||
API_REFERENCE_DETAILS_PAGE_MEMBERS_CLASS_NAME,
|
||||
API_REFERENCE_MEMBER_CARD_CLASS_NAME,
|
||||
@@ -26,8 +27,6 @@ import {
|
||||
MEMBER_ID_ATTRIBUTE,
|
||||
} from '../constants/api-reference-prerender.constants';
|
||||
import {WINDOW} from '@angular/docs';
|
||||
import {Router, Scroll} from '@angular/router';
|
||||
import {AppScroller} from '../../../app-scroller';
|
||||
|
||||
export const SCROLL_EVENT_DELAY = 20;
|
||||
export const SCROLL_THRESHOLD = 20;
|
||||
@@ -42,9 +41,8 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly injector = inject(EnvironmentInjector);
|
||||
private readonly ngZone = inject(NgZone);
|
||||
private readonly window = inject(WINDOW);
|
||||
private readonly router = inject(Router);
|
||||
private readonly appScroller = inject(AppScroller);
|
||||
|
||||
private readonly cardOffsetTop = new Map<string, number>();
|
||||
private resizeObserver: ResizeObserver | null = null;
|
||||
@@ -60,23 +58,6 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
|
||||
this.setupMemberCardListeners();
|
||||
this.setScrollEventHandlers();
|
||||
this.listenToResizeCardContainer();
|
||||
this.setupFragmentChangeListener();
|
||||
}
|
||||
|
||||
private setupFragmentChangeListener() {
|
||||
this.router.routerState.root.fragment
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((fragment) => {
|
||||
// If there is no fragment or the scroll event has a position (traversing through history),
|
||||
// allow the scroller to handler scrolling instead of going to the fragment
|
||||
if (!fragment || this.appScroller.lastScrollEvent?.position) {
|
||||
this.appScroller.scroll();
|
||||
return;
|
||||
}
|
||||
|
||||
const card = this.document.getElementById(fragment) as HTMLDivElement | null;
|
||||
this.scrollToCard(card);
|
||||
});
|
||||
}
|
||||
|
||||
updateMembersMarginTop(selectorOfTheElementToAlign: string): void {
|
||||
@@ -94,33 +75,35 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
|
||||
return;
|
||||
}
|
||||
|
||||
fromEvent(tocContainer, 'click')
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((event) => {
|
||||
// Get the card member ID from the attributes
|
||||
const target =
|
||||
event.target instanceof HTMLButtonElement
|
||||
? event.target
|
||||
: this.findButtonElement(event.target as HTMLElement);
|
||||
const memberId = this.getMemberId(target);
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
fromEvent(tocContainer, 'click')
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((event) => {
|
||||
// Get the card member ID from the attributes
|
||||
const target =
|
||||
event.target instanceof HTMLButtonElement
|
||||
? event.target
|
||||
: this.findButtonElement(event.target as HTMLElement);
|
||||
const memberId = this.getMemberId(target);
|
||||
|
||||
if (memberId) {
|
||||
this.router.navigate([], {fragment: memberId, replaceUrl: true});
|
||||
}
|
||||
});
|
||||
if (memberId) {
|
||||
const card = this.document.querySelector<HTMLDivElement>(`#${memberId}`);
|
||||
this.scrollToCard(card);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private setupMemberCardListeners(): void {
|
||||
this.getAllMemberCards().forEach((card) => {
|
||||
this.cardOffsetTop.set(card.id, card.offsetTop);
|
||||
fromEvent(card, 'click')
|
||||
.pipe(
|
||||
skipWhile((event) => event.target instanceof HTMLAnchorElement),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.router.navigate([], {fragment: card.id, replaceUrl: true});
|
||||
});
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.getAllMemberCards().forEach((card) => {
|
||||
this.cardOffsetTop.set(card.id, card.offsetTop);
|
||||
fromEvent(card, 'click')
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe(() => {
|
||||
this.scrollToCard(card);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -130,7 +113,9 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
);
|
||||
|
||||
scroll$.subscribe(() => this.setActiveCodeLine());
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
scroll$.subscribe(() => this.setActiveCodeLine());
|
||||
});
|
||||
}
|
||||
|
||||
private listenToResizeCardContainer(): void {
|
||||
@@ -224,10 +209,12 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
|
||||
this.resizeObserver?.disconnect();
|
||||
|
||||
this.resizeObserver = new ResizeObserver((_) => {
|
||||
const offsetTop = tabBody.getBoundingClientRect().top;
|
||||
if (offsetTop) {
|
||||
this.membersMarginTopInPx.set(offsetTop);
|
||||
}
|
||||
this.ngZone.run(() => {
|
||||
const offsetTop = tabBody.getBoundingClientRect().top;
|
||||
if (offsetTop) {
|
||||
this.membersMarginTopInPx.set(offsetTop);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.resizeObserver.observe(tabBody);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import {FocusMonitor} from '@angular/cdk/a11y';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {DestroyRef, ElementRef, Injectable, inject, signal} from '@angular/core';
|
||||
import {DestroyRef, ElementRef, Injectable, NgZone, inject, signal} from '@angular/core';
|
||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
import {fromEvent, combineLatest} from 'rxjs';
|
||||
import {map, filter} from 'rxjs/operators';
|
||||
@@ -33,6 +33,7 @@ export class SplitResizerHandler {
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly focusMonitor = inject(FocusMonitor);
|
||||
private readonly ngZone = inject(NgZone);
|
||||
|
||||
private container!: ElementRef<any>;
|
||||
private content!: ElementRef<HTMLDivElement>;
|
||||
@@ -150,11 +151,13 @@ export class SplitResizerHandler {
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
)
|
||||
.subscribe(([_, keyEvent]) => {
|
||||
const shift = keyEvent.key === 'ArrowLeft' ? -1 : 1;
|
||||
this.ngZone.run(() => {
|
||||
const shift = keyEvent.key === 'ArrowLeft' ? -1 : 1;
|
||||
|
||||
const contentWidth = this.getCurrentContainerWidth(this.content.nativeElement);
|
||||
const editorWidth = this.getCurrentContainerWidth(this.editor!.nativeElement);
|
||||
this.setWidthOfTheContainers(contentWidth + shift, editorWidth - shift);
|
||||
const contentWidth = this.getCurrentContainerWidth(this.content.nativeElement);
|
||||
const editorWidth = this.getCurrentContainerWidth(this.editor!.nativeElement);
|
||||
this.setWidthOfTheContainers(contentWidth + shift, editorWidth - shift);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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: 100vh;
|
||||
height: var(--fixed-content-height);
|
||||
|
||||
&::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: 100vh;
|
||||
height: var(--fixed-content-height);
|
||||
}
|
||||
|
||||
.adev-split-tutorial {
|
||||
|
||||
@@ -143,7 +143,7 @@ export default class Tutorial implements AfterViewInit {
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(this.embeddedTutorialManager.answerFiles()).map(([path, contents]) =>
|
||||
nodeRuntimeSandbox.writeFile(path, contents as string | Buffer),
|
||||
nodeRuntimeSandbox.writeFile(path, contents),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -161,7 +161,7 @@ export default class Tutorial implements AfterViewInit {
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(this.embeddedTutorialManager.tutorialFiles()).map(([path, contents]) =>
|
||||
nodeRuntimeSandbox.writeFile(path, contents as string | Buffer),
|
||||
nodeRuntimeSandbox.writeFile(path, contents),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,191 +0,0 @@
|
||||
<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) {
|
||||
<div>
|
||||
<mat-checkbox
|
||||
(change)="options[option.id] = $event.checked; showUpdatePath()"
|
||||
[checked]="options[option.id]"
|
||||
>I use {{option.name}} {{option.description}}</mat-checkbox
|
||||
>
|
||||
</div>
|
||||
}
|
||||
|
||||
@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>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user