mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
285 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a8a35343bc | |||
| 41ef1cbd80 | |||
| 567d48f2a1 | |||
| adf4987185 | |||
| 4f38429cea | |||
| 33769c234f | |||
| 4c9d09c643 | |||
| 1fbaeab37d | |||
| 69b6d6547e | |||
| 94117f1cfc | |||
| d0c5fe9886 | |||
| 790bdbfc48 | |||
| d36dbce309 | |||
| 7a88ce5ef3 | |||
| c611c8d212 | |||
| 3b0b4936c6 | |||
| 5ecceda5cb | |||
| 3edc494ea2 | |||
| 91149b5cdb | |||
| 51caec89ed | |||
| 20f806a658 | |||
| 1dc5c39086 | |||
| f0990c67e6 | |||
| da25071c11 | |||
| c2102c545b | |||
| 5a66f6072d | |||
| 164facb6ba | |||
| e16394a1c9 | |||
| b323e2db2b | |||
| 354b1fa22f | |||
| 236a623294 | |||
| 066c52e0a3 | |||
| 538895b5f5 | |||
| 265739544e | |||
| 4ec0e66cc1 | |||
| ec1e4c3d94 | |||
| da1426b3fe | |||
| a29c2e0f25 | |||
| fa260a9862 | |||
| a1b45799eb | |||
| d359650273 | |||
| e7834767f6 | |||
| 798752b423 | |||
| 951178233d | |||
| b8d1b070b2 | |||
| 6d8c2e2162 | |||
| e9f10eb4c9 | |||
| 26c64a8554 | |||
| 28551a82b4 | |||
| 8d40876900 | |||
| d46dd77742 | |||
| 387eb043a7 | |||
| e141893836 | |||
| 82eba1d44b | |||
| 37d4fa883b | |||
| f76adcc33c | |||
| 6b2685de65 | |||
| 1b4fc8e20b | |||
| 3fd69d7ab4 | |||
| 419e67faf4 | |||
| defe672084 | |||
| 16fc074689 | |||
| 04851c748b | |||
| 6d1ebc52a2 | |||
| adbf013cea | |||
| 0131c703ab | |||
| f01d827a05 | |||
| df03cfd731 | |||
| 22c2dfa756 | |||
| 20df2cd108 | |||
| 01f669a274 | |||
| b41a263508 | |||
| bc6e11160e | |||
| 710759ddcc | |||
| 46f36a58bf | |||
| 9366e842b2 | |||
| f9e59007ce | |||
| 544fb89709 | |||
| ce216723a5 | |||
| dcfb9f1959 | |||
| cab7a9b69c | |||
| 6e999300a7 | |||
| 27c39f5a8a | |||
| 6217e45cc5 | |||
| 87588ecd2b | |||
| dbbd0d3536 | |||
| d09bb7e8b0 | |||
| d2c6d0c443 | |||
| 2137f80702 | |||
| 802397d997 | |||
| 724885bbc6 | |||
| ad01b6a788 | |||
| 2115cca958 | |||
| 09e309da6f | |||
| d7b5c597ff | |||
| 53a4668b58 | |||
| 976125e0b4 | |||
| 8eef6b7d1f | |||
| 2a0731f9c7 | |||
| 419634c391 | |||
| cde83e99bc | |||
| 3f6ccfc173 | |||
| 29a2924d5a | |||
| 29d412d31a | |||
| 0558b38283 | |||
| e77391f51c | |||
| 1ca8491b46 | |||
| 6efcbe8f7a | |||
| 5d89ffc959 | |||
| 67db7f7147 | |||
| f179dc5cef | |||
| 4418064599 | |||
| 79f0736089 | |||
| 1828a84062 | |||
| 544b9ee7ca | |||
| 68dbaf5548 | |||
| c3f1c7aecc | |||
| f6029bc126 | |||
| 1a06eb2e46 | |||
| fb909446e4 | |||
| 07e5136b61 | |||
| 70a71187f2 | |||
| 522acbf3d7 | |||
| 0fdc4cd795 | |||
| f3d6c49b1e | |||
| 3c28301085 | |||
| cb1cb0cf9a | |||
| 873870f60f | |||
| 82528492eb | |||
| d0dc8f76a5 | |||
| 2c770a251a | |||
| e7d0ca1bd5 | |||
| 068cf2966d | |||
| 557ca8dd9d | |||
| caaa7ca6b8 | |||
| 0a9c03c7b1 | |||
| 1c84cbca30 | |||
| 1225657462 | |||
| 3f4d5f636a | |||
| 093ba4b5c7 | |||
| 7613bb46cd | |||
| f668440eca | |||
| 6338257202 | |||
| 170c052141 | |||
| 7a328ba13e | |||
| b4b36ed9e3 | |||
| d6e78c072d | |||
| 15cc74fe82 | |||
| 6a92b80ae6 | |||
| b7b8da5b5a | |||
| f8b8a3e7c0 | |||
| 4574ece590 | |||
| 9ea6337653 | |||
| 4867b64050 | |||
| cdb439b809 | |||
| 8070353d22 | |||
| 455ae44393 | |||
| 9ee4e42283 | |||
| 60094d3853 | |||
| e3da35ec74 | |||
| 1de822c561 | |||
| c2436702df | |||
| 7dc5116f62 | |||
| 597a33c482 | |||
| cb6272199b | |||
| 66d07e7baf | |||
| 38c8868223 | |||
| a62c84bc18 | |||
| 89b391c245 | |||
| 0de5049daa | |||
| 78af7a5059 | |||
| 39690969af | |||
| 26f6d4c485 | |||
| 53160e504d | |||
| b2b3816cb1 | |||
| 408af24ff3 | |||
| d7575c201c | |||
| 67fe0b94c7 | |||
| ecfb74d287 | |||
| 64836215c6 | |||
| 2ec826dfdc | |||
| 266a8f2f2e | |||
| 8dcd889987 | |||
| 95a05bb202 | |||
| 6f7716268a | |||
| 70c4b83509 | |||
| 5497102769 | |||
| b88f81da19 | |||
| 2e72ec7e1c | |||
| 55837de2a9 | |||
| 4eb541837c | |||
| 4507109ac7 | |||
| a4eb74c79c | |||
| 612f11616b | |||
| 8b08a25f6b | |||
| 81f8fe63bd | |||
| 906413aba3 | |||
| d12a186d53 | |||
| 797800ce0a | |||
| 126c80c39b | |||
| 5c9d739a05 | |||
| 357795cb96 | |||
| eb0b1851f4 | |||
| 326248ce85 | |||
| 74daef1ca2 | |||
| 0d019e9e2b | |||
| 810ed6aad5 | |||
| e36e812fd0 | |||
| e2b7359498 | |||
| 95c0e51b6e | |||
| f8e1f8508c | |||
| cfdf5ee0f5 | |||
| d0fc0d2da1 | |||
| 1fba8d1e51 | |||
| 6a0dd9639a | |||
| b44c0203c5 | |||
| 0130298328 | |||
| 3e7ba3d014 | |||
| 99c542a19b | |||
| 51a4839e86 | |||
| 3913893ef4 | |||
| f6e7516747 | |||
| a7f824a7ec | |||
| 2b85ddc916 | |||
| a0756e45c0 | |||
| 4efb1918ee | |||
| e33e673ff9 | |||
| 69cd6f0884 | |||
| 53c3f8538c | |||
| 2a8a8f02f2 | |||
| d78de38f4c | |||
| 983b21bcd2 | |||
| 3a9d084b3d | |||
| f73f39cb96 | |||
| c67af8b66d | |||
| f68e9cd2e8 | |||
| f1aba5320f | |||
| f5e8693701 | |||
| a1cbfa377a | |||
| 411b4f54bb | |||
| de12b524e9 | |||
| 03339d5f94 | |||
| 6fc5f182cd | |||
| ff386718f7 | |||
| 8091a4afe0 | |||
| c0ffd81efa | |||
| b745d8ddf9 | |||
| 9146c68733 | |||
| ee63b0bafa | |||
| e4efc67222 | |||
| c2b77b52fe | |||
| f90dc4ca27 | |||
| 574cfaf530 | |||
| c8bbade542 | |||
| 59a1d68ce7 | |||
| ca1d392210 | |||
| 7debf0f74c | |||
| ce28bffcb7 | |||
| dec8f91a90 | |||
| 14fb8ce4c0 | |||
| 53c8dc6d70 | |||
| 3b1fbceed9 | |||
| aed49ddaaa | |||
| 4d9bfab807 | |||
| 2ec76641f5 | |||
| 679d4d1ae8 | |||
| 213d1b3a82 | |||
| bfaeefe302 | |||
| 988a6b2aaf | |||
| fedee14090 | |||
| 4491b5bf24 | |||
| 3502039bff | |||
| c281807e92 | |||
| c6b66e5aba | |||
| d7cce1c78b | |||
| 8ca298dc9c | |||
| ac0a655ad5 | |||
| 5ec4997ac8 | |||
| 86a3260ba7 | |||
| 621a5d1f59 | |||
| 5906bb07ac | |||
| 1223324b26 | |||
| a6a43477bb | |||
| 13a51b6b05 | |||
| 77b24cd575 |
File diff suppressed because it is too large
Load Diff
@@ -5,9 +5,9 @@ runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/saucelabs@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Starting Saucelabs tunnel service
|
||||
shell: bash
|
||||
run: ./tools/saucelabs/sauce-service.sh run &
|
||||
|
||||
@@ -4,7 +4,7 @@ description: 'Installs the dependencies using Yarn'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4
|
||||
- uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4
|
||||
with:
|
||||
path: |
|
||||
./node_modules/
|
||||
|
||||
@@ -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@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build //adev:build --full_build_adev --config=release
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
pull-number: '${{github.event.pull_request.number}}'
|
||||
|
||||
@@ -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@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
github-token: '${{secrets.GITHUB_TOKEN}}'
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
|
||||
@@ -16,6 +16,6 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/yarn-install
|
||||
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
bazelrc: ./.bazelrc.user
|
||||
|
||||
|
||||
+24
-22
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
@@ -41,13 +41,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Run unit tests
|
||||
@@ -59,13 +59,13 @@ jobs:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
@@ -76,30 +76,32 @@ jobs:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- 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 --config=release
|
||||
- name: Run tests
|
||||
run: yarn bazel test //adev/...
|
||||
# TODO: re-enable tests once the next release is shipped
|
||||
# Tests are broken because of https://github.com/angular/angular/issues/54858
|
||||
# - name: Run tests
|
||||
# run: yarn bazel test //adev/...
|
||||
|
||||
publish-snapshots:
|
||||
runs-on:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
|
||||
@@ -111,7 +113,7 @@ jobs:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
@@ -119,9 +121,9 @@ jobs:
|
||||
./packages/zone.js/node_modules
|
||||
./packages/zone.js/test/typings/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: |
|
||||
@@ -158,7 +160,7 @@ jobs:
|
||||
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
@@ -171,11 +173,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
|
||||
@@ -13,13 +13,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
post_approval_changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
run-tests-guide-url: http://go/angular-g3sync-start
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -13,17 +13,17 @@ jobs:
|
||||
JOBS: 2
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
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@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/saucelabs@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Set up Sauce Tunnel Daemon
|
||||
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
|
||||
env:
|
||||
|
||||
@@ -9,6 +9,6 @@ jobs:
|
||||
status:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
workflows: ${{ steps.workflows.outputs.workflows }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn -s install --frozen-lockfile
|
||||
- id: workflows
|
||||
@@ -36,9 +36,9 @@ jobs:
|
||||
workflow: ${{ fromJSON(needs.list.outputs.workflows) }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn -s install --frozen-lockfile
|
||||
# We utilize the google-github-actions/auth action to allow us to get an active credential using workflow
|
||||
|
||||
+23
-21
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
- 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@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/linting/licenses@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
allow-dependencies-licenses: 'pkg:npm/google-protobuf@'
|
||||
|
||||
@@ -47,13 +47,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Run unit tests
|
||||
@@ -65,13 +65,13 @@ jobs:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
@@ -83,19 +83,19 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- 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@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
with:
|
||||
name: pr-artifacts-${{ github.event.number }}
|
||||
path: dist/packages-dist/
|
||||
@@ -105,24 +105,26 @@ jobs:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- 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 --config=release
|
||||
- name: Run tests
|
||||
run: yarn bazel test //adev/...
|
||||
# TODO: re-enable tests once the next release is shipped
|
||||
# Tests are broken because of https://github.com/angular/angular/issues/54858
|
||||
# - name: Run tests
|
||||
# run: yarn bazel test //adev/...
|
||||
|
||||
zone-js:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
@@ -130,9 +132,9 @@ jobs:
|
||||
./packages/zone.js/node_modules
|
||||
./packages/zone.js/test/typings/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: |
|
||||
@@ -169,7 +171,7 @@ jobs:
|
||||
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: 'Run analysis'
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.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@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
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@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
|
||||
uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -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@289aa644e65a557bcb21adcf75ad60605a9c9859
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@2670abf637fa155971cdd1f7e570a7f234922a65
|
||||
with:
|
||||
branch-prefix: update-cli-help
|
||||
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
|
||||
|
||||
@@ -32,7 +32,6 @@ export const commitMessage: CommitMessageConfig = {
|
||||
'router',
|
||||
'service-worker',
|
||||
'upgrade',
|
||||
've',
|
||||
'zone.js',
|
||||
],
|
||||
};
|
||||
|
||||
@@ -22,4 +22,12 @@ export const pullRequest: PullRequestConfig = {
|
||||
assertEnforceTested: true,
|
||||
assertIsolatedSeparateFiles: true,
|
||||
},
|
||||
|
||||
requiredStatuses: [
|
||||
{type: 'check', name: 'test'},
|
||||
{type: 'check', name: 'lint'},
|
||||
{type: 'check', name: 'adev'},
|
||||
{type: 'check', name: 'zone-js'},
|
||||
{type: 'status', name: 'google-internal-tests'},
|
||||
],
|
||||
};
|
||||
|
||||
+10
-4
@@ -56,8 +56,8 @@
|
||||
|
||||
version: 3
|
||||
|
||||
availability:
|
||||
users_unavailable: ['atscott']
|
||||
# availability:
|
||||
# users_unavailable: ['atscott']
|
||||
|
||||
# Meta field that goes unused by PullApprove to allow for defining aliases to be
|
||||
# used throughout the config.
|
||||
@@ -133,6 +133,7 @@ groups:
|
||||
- devversion
|
||||
- kirjs
|
||||
- JoostK
|
||||
- mmalerba
|
||||
|
||||
# =========================================================
|
||||
# Framework: General (most code in our packages)
|
||||
@@ -175,6 +176,7 @@ groups:
|
||||
- ~jelbourn
|
||||
- thePunderWoman
|
||||
- pkozlowski-opensource
|
||||
- mmalerba
|
||||
|
||||
# =========================================================
|
||||
# Framework: Security-sensitive files which require extra review
|
||||
@@ -227,9 +229,9 @@ groups:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
contains_any_globs(files.exclude('yarn.lock'), [
|
||||
'packages/zone.js/**/{*,.*}',
|
||||
])
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- JiaLiPassion
|
||||
@@ -285,6 +287,7 @@ groups:
|
||||
- mgechev
|
||||
- MarkTechson
|
||||
- kirjs
|
||||
- mmalerba
|
||||
|
||||
# =========================================================
|
||||
# Angular DevTools
|
||||
@@ -391,6 +394,7 @@ groups:
|
||||
- thePunderWoman
|
||||
- pkozlowski-opensource
|
||||
- kirjs
|
||||
- mmalerba
|
||||
- ~iteriani
|
||||
- ~tbondwilkinson
|
||||
- ~rahatarmanahmed
|
||||
@@ -420,6 +424,7 @@ groups:
|
||||
- ~jelbourn
|
||||
- thePunderWoman
|
||||
- pkozlowski-opensource
|
||||
- mmalerba
|
||||
reviews:
|
||||
request: 2 # Request reviews from 2 people
|
||||
required: 1 # Require that 1 person approve
|
||||
@@ -516,6 +521,7 @@ groups:
|
||||
- iteriani # Thomas Nguyen
|
||||
- tbondwilkinson # Tom Wilkinson
|
||||
- rahatarmanahmed # Rahat Ahmed
|
||||
- ENAML # Ethan Cline
|
||||
labels:
|
||||
pending: 'requires: TGP'
|
||||
approved: 'requires: TGP'
|
||||
|
||||
+207
-81
@@ -1,3 +1,210 @@
|
||||
<a name="19.1.8"></a>
|
||||
# 19.1.8 (2025-02-26)
|
||||
### benchpress
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [f0990c67e6](https://github.com/angular/angular/commit/f0990c67e660c61109fa910885da6aa4beaf576a) | fix | Ensure future-proof correct initialization order ([#60025](https://github.com/angular/angular/pull/60025)) |
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [1fbaeab37d](https://github.com/angular/angular/commit/1fbaeab37d5c65436938b6e14e21bc4d57bb517b) | fix | make types for HttpClient more readable ([#59901](https://github.com/angular/angular/pull/59901)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c611c8d212](https://github.com/angular/angular/commit/c611c8d212b0134365954726c2fd6c98c28e5424) | fix | capture stack for HMR errors ([#60067](https://github.com/angular/angular/pull/60067)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [4c9d09c643](https://github.com/angular/angular/commit/4c9d09c643cf1232d1f502ff7d6bd25709ba1c6a) | fix | provide correct rename info for elements ([#60088](https://github.com/angular/angular/pull/60088)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.7"></a>
|
||||
# 19.1.7 (2025-02-19)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e9f10eb4c9](https://github.com/angular/angular/commit/e9f10eb4c950692992098619b9628ecefd1b36ce) | fix | clean up `urlChanges` subscribers when root scope is destroyed ([#59703](https://github.com/angular/angular/pull/59703)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [16fc074689](https://github.com/angular/angular/commit/16fc074689d31ef6886c49525b020bc6c1529d0e) | fix | avoid crash in isolated transform operations ([#59869](https://github.com/angular/angular/pull/59869)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ec1e4c3d94](https://github.com/angular/angular/commit/ec1e4c3d9430f5ea4380252098d2b4b71d8a950f) | fix | Fix typing on `FormRecord`. ([#59993](https://github.com/angular/angular/pull/59993)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.6"></a>
|
||||
# 19.1.6 (2025-02-12)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [01f669a274](https://github.com/angular/angular/commit/01f669a27425c5034a04274763cc60801f961aa2) | fix | handle tracking expressions requiring temporary variables ([#58520](https://github.com/angular/angular/pull/58520)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dcfb9f1959](https://github.com/angular/angular/commit/dcfb9f1959164baf45f5f954b4bf681d650d8a2d) | fix | handle deferred blocks with shared dependencies correctly ([#59926](https://github.com/angular/angular/pull/59926)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [cab7a9b69c](https://github.com/angular/angular/commit/cab7a9b69c3a5d789432a87a554e8489c78a0f15) | fix | invalidate HMR component if replacement throws an error ([#59854](https://github.com/angular/angular/pull/59854)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [710759ddcc](https://github.com/angular/angular/commit/710759ddcc0ecbad68deb20821b535fd5deb69c6) | fix | account for let declarations in control flow migration ([#59861](https://github.com/angular/angular/pull/59861)) |
|
||||
| [46f36a58bf](https://github.com/angular/angular/commit/46f36a58bf3a7b9131b6330e84d4adb3e73f3601) | fix | count used dependencies inside existing control flow ([#59861](https://github.com/angular/angular/pull/59861)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.5"></a>
|
||||
# 19.1.5 (2025-02-06)
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d7b5c597ffc](https://github.com/angular/angular/commit/d7b5c597ffcb6469ae3f08a97e7790599d569cc4) | fix | gracefully fall back if const enum cannot be passed through ([#59815](https://github.com/angular/angular/pull/59815)) |
|
||||
| [53a4668b58b](https://github.com/angular/angular/commit/53a4668b58b645e41baddc5b67d52ede21c8e945) | fix | handle const enums used inside HMR data ([#59815](https://github.com/angular/angular/pull/59815)) |
|
||||
| [976125e0b4c](https://github.com/angular/angular/commit/976125e0b4cf4e7fb4621a7203e3f43b009885f0) | fix | handle enum members without initializers in partial evaluator ([#59815](https://github.com/angular/angular/pull/59815)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.4"></a>
|
||||
# 19.1.4 (2025-01-29)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [544b9ee7ca0](https://github.com/angular/angular/commit/544b9ee7ca00925e62b7c74cf7930777a10aaf76) | fix | check whether application is destroyed before printing hydration stats ([#59716](https://github.com/angular/angular/pull/59716)) |
|
||||
| [d6e78c072dc](https://github.com/angular/angular/commit/d6e78c072dcb5b0b6efc2b098fdb911ccddf6e81) | fix | ensure type is preserved during HMR ([#59700](https://github.com/angular/angular/pull/59700)) |
|
||||
| [c2436702df9](https://github.com/angular/angular/commit/c2436702df980bbf2db0fe3bee4c72860edb4e63) | fix | fixes test timer-based test flakiness in CI ([#59674](https://github.com/angular/angular/pull/59674)) |
|
||||
### elements
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [44180645992](https://github.com/angular/angular/commit/44180645992f7d9018ccb2d7663530b3cffde36b) | fix | not setting initial value on signal-based input ([#59773](https://github.com/angular/angular/pull/59773)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [1828a840620](https://github.com/angular/angular/commit/1828a8406201827e52549c8afa487bf6364a70c3) | fix | prepend `baseHref` to `sourceMappingURL` in CSS content ([#59730](https://github.com/angular/angular/pull/59730)) |
|
||||
| [1c84cbca30e](https://github.com/angular/angular/commit/1c84cbca30e6606e6df3f40346989d9434d89bc6) | fix | Update pseudoevent created by createMouseSpecialEvent to populate `_originalEvent` property ([#59690](https://github.com/angular/angular/pull/59690)) |
|
||||
| [12256574626](https://github.com/angular/angular/commit/12256574626f04f5fe2b41e805f7bdc93d62df0a) | fix | Update pseudoevent created by createMouseSpecialEvent to populate `_originalEvent` property ([#59690](https://github.com/angular/angular/pull/59690)) |
|
||||
| [3f4d5f636aa](https://github.com/angular/angular/commit/3f4d5f636aac90cabe32ff6c4d75180ced99eb97) | fix | Update pseudoevent created by createMouseSpecialEvent to populate `_originalEvent` property ([#59690](https://github.com/angular/angular/pull/59690)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e3da35ec749](https://github.com/angular/angular/commit/e3da35ec749395239731158f89e29d47e7a9ef36) | fix | prevent error handling when injector is destroyed ([#59457](https://github.com/angular/angular/pull/59457)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [522acbf3d7e](https://github.com/angular/angular/commit/522acbf3d7ed502e7802117776acda3529a9a2b4) | fix | add missing `rxjs` peer dependency ([#59747](https://github.com/angular/angular/pull/59747)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.3"></a>
|
||||
# 19.1.3 (2025-01-22)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ecfb74d287](https://github.com/angular/angular/commit/ecfb74d287bec7bec37d0b476b321b047bef2c43) | fix | handle :host-context with comma-separated child selector ([#59276](https://github.com/angular/angular/pull/59276)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [53160e504d](https://github.com/angular/angular/commit/53160e504df44b05f59cacd9afeb40a0e627b744) | fix | extract parenthesized dependencies during HMR ([#59644](https://github.com/angular/angular/pull/59644)) |
|
||||
| [39690969af](https://github.com/angular/angular/commit/39690969af14914df0c9b5a009b2df920f5c03e7) | fix | handle conditional expressions when extracting dependencies ([#59637](https://github.com/angular/angular/pull/59637)) |
|
||||
| [78af7a5059](https://github.com/angular/angular/commit/78af7a5059cc3e03704ba63f8512351a40470557) | fix | handle new expressions when extracting dependencies ([#59637](https://github.com/angular/angular/pull/59637)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [408af24ff3](https://github.com/angular/angular/commit/408af24ff3490926e9992cb4f1f71914d71ad6ad) | fix | capture self-referencing component during HMR ([#59644](https://github.com/angular/angular/pull/59644)) |
|
||||
| [d7575c201c](https://github.com/angular/angular/commit/d7575c201cfd61010952b3a633eec03e32f58220) | fix | replace metadata in place during HMR ([#59644](https://github.com/angular/angular/pull/59644)) |
|
||||
| [26f6d4c485](https://github.com/angular/angular/commit/26f6d4c485b566d7bc127c78cc163c376d0fe6b5) | fix | skip component ID collision warning during SSR ([#59625](https://github.com/angular/angular/pull/59625)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a62c84bc18](https://github.com/angular/angular/commit/a62c84bc188d41ea24cf0eca14ac18c4b917ccd0) | fix | avoid applying the same replacements twice when cleaning up unused imports ([#59656](https://github.com/angular/angular/pull/59656)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [b2b3816cb1](https://github.com/angular/angular/commit/b2b3816cb1c5c573dc9368f05fd2971671d7159f) | fix | clear renderer cache during HMR when using async animations ([#59644](https://github.com/angular/angular/pull/59644)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.2"></a>
|
||||
# 19.1.2 (2025-01-20)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [8dcd889987](https://github.com/angular/angular/commit/8dcd88998700a94115a542462e6ae6beedbfbd9d) | fix | update `@ng/component` URL to be relative ([#59620](https://github.com/angular/angular/pull/59620)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [95a05bb202](https://github.com/angular/angular/commit/95a05bb2021acab02df3468212adf023d331a688) | fix | disable tree shaking during HMR ([#59595](https://github.com/angular/angular/pull/59595)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a4eb74c79c](https://github.com/angular/angular/commit/a4eb74c79cca802d8179118cf4d53c73285baadb) | fix | animation sometimes renderer not being destroyed during HMR ([#59574](https://github.com/angular/angular/pull/59574)) |
|
||||
| [906413aba3](https://github.com/angular/angular/commit/906413aba31459e6499420ed14519d1280e182ad) | fix | change `Resource` to use explicit `undefined` in its typings ([#59024](https://github.com/angular/angular/pull/59024)) |
|
||||
| [4eb541837c](https://github.com/angular/angular/commit/4eb541837cf28ce1950d782213291165a2436410) | fix | cleanup `_ejsa` when app is destroyed ([#59492](https://github.com/angular/angular/pull/59492)) |
|
||||
| [5497102769](https://github.com/angular/angular/commit/549710276969ec4cf8c1e3d2f19d1fe9f755976e) | fix | cleanup stash listener when app is destroyed ([#59598](https://github.com/angular/angular/pull/59598)) |
|
||||
| [266a8f2f2e](https://github.com/angular/angular/commit/266a8f2f2ebf9f5e310ba5de695be5072790e1e5) | fix | handle shadow DOM encapsulated component with HMR ([#59597](https://github.com/angular/angular/pull/59597)) |
|
||||
| [6f7716268a](https://github.com/angular/angular/commit/6f7716268afa5146f2b2d0dbbea146defa9acfef) | fix | HMR not matching component that injects ViewContainerRef ([#59596](https://github.com/angular/angular/pull/59596)) |
|
||||
| [d12a186d53](https://github.com/angular/angular/commit/d12a186d531b41e6a16f84446a1d54eaed010fc4) | fix | treat exceptions in `equal` as part of computation ([#55818](https://github.com/angular/angular/pull/55818)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.1"></a>
|
||||
# 19.1.1 (2025-01-16)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [357795cb96](https://github.com/angular/angular/commit/357795cb96a1cd138ec263c468c9de8ca8b2af9c) | fix | run HMR replacement in the zone ([#59562](https://github.com/angular/angular/pull/59562)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [eb0b1851f4](https://github.com/angular/angular/commit/eb0b1851f494adfe72f583763a44bd2528a5956c) | fix | roll back HMR fix ([#59557](https://github.com/angular/angular/pull/59557)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.0"></a>
|
||||
# 19.1.0 (2025-01-15)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e4c50b3bea](https://github.com/angular/angular/commit/e4c50b3bea22ca2afba74465893c36730952f4b9) | feat | expose component instance in NgComponentOutlet ([#58698](https://github.com/angular/angular/pull/58698)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ceadd28ea1](https://github.com/angular/angular/commit/ceadd28ea12140e8e78cdb706aff0487f5a87a3c) | fix | allow $any in two-way bindings ([#59362](https://github.com/angular/angular/pull/59362)) |
|
||||
| [aed49ddaaa](https://github.com/angular/angular/commit/aed49ddaaa40d6e6816198b47ceada4e98cd636c) | fix | use chunk origin in template HMR request URL ([#59459](https://github.com/angular/angular/pull/59459)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c5c20e9d86](https://github.com/angular/angular/commit/c5c20e9d86d72b33840dcf0adea02876437a589f) | fix | check event side of two-way bindings ([#59002](https://github.com/angular/angular/pull/59002)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d010e11b73](https://github.com/angular/angular/commit/d010e11b735562ded439989ddb84cc83c6c00e81) | feat | add event listener options to renderer ([#59092](https://github.com/angular/angular/pull/59092)) |
|
||||
| [57f3550219](https://github.com/angular/angular/commit/57f3550219f2a57c7c26c9183e48ee66845e0439) | feat | add utility for resolving defer block information to ng global ([#59184](https://github.com/angular/angular/pull/59184)) |
|
||||
| [22f191f763](https://github.com/angular/angular/commit/22f191f76339a08bb8f0f2dfbc60dde0f2e38e73) | feat | extend the set of profiler events ([#59183](https://github.com/angular/angular/pull/59183)) |
|
||||
| [e894a5daea](https://github.com/angular/angular/commit/e894a5daea401b4e1173b0e66557ae40140eb9a0) | feat | set kind field on template and effect nodes ([#58865](https://github.com/angular/angular/pull/58865)) |
|
||||
| [bd1f1294ae](https://github.com/angular/angular/commit/bd1f1294aeb0d47b24421b7b7a608988689a459f) | feat | support TypeScript 5.7 ([#58609](https://github.com/angular/angular/pull/58609)) |
|
||||
| [9870b643bf](https://github.com/angular/angular/commit/9870b643bff46f089a3f0a30514fb7e062a66d56) | fix | Defer afterRender until after first CD ([#58250](https://github.com/angular/angular/pull/58250)) |
|
||||
| [a5fc962094](https://github.com/angular/angular/commit/a5fc9620948c59da2146d46d27de388839b93254) | fix | Don't run effects in check no changes pass ([#58250](https://github.com/angular/angular/pull/58250)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d298d25426](https://github.com/angular/angular/commit/d298d254269ff759111fbdef7736bc8b713638bc) | feat | add schematic to clean up unused imports ([#59353](https://github.com/angular/angular/pull/59353)) |
|
||||
| [14fb8ce4c0](https://github.com/angular/angular/commit/14fb8ce4c00fc458cfbe1d7f2c85638c6165b636) | fix | resolve text replacement issue ([#59452](https://github.com/angular/angular/pull/59452)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [8c5db3cfb7](https://github.com/angular/angular/commit/8c5db3cfb75700dd64f4c8c073554c7086835950) | fix | avoid circular DI error in async renderer ([#59256](https://github.com/angular/angular/pull/59256)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [52a6710f54](https://github.com/angular/angular/commit/52a6710f54bcec81f4cde23a78b9f78d038156c5) | fix | complete router `events` on dispose ([#59327](https://github.com/angular/angular/pull/59327)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.0.6"></a>
|
||||
# 19.0.6 (2025-01-08)
|
||||
### compiler-cli
|
||||
@@ -21,22 +228,6 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.0-next.4"></a>
|
||||
# 19.1.0-next.4 (2024-12-18)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [57f3550219](https://github.com/angular/angular/commit/57f3550219f2a57c7c26c9183e48ee66845e0439) | feat | add utility for resolving defer block information to ng global ([#59184](https://github.com/angular/angular/pull/59184)) |
|
||||
| [22f191f763](https://github.com/angular/angular/commit/22f191f76339a08bb8f0f2dfbc60dde0f2e38e73) | feat | extend the set of profiler events ([#59183](https://github.com/angular/angular/pull/59183)) |
|
||||
| [1f4ff2fa36](https://github.com/angular/angular/commit/1f4ff2fa36f5d6240cbc4a40839d3d89501519d8) | fix | avoid triggering `on timer` and `on idle` on the server ([#59177](https://github.com/angular/angular/pull/59177)) |
|
||||
| [cf89f14766](https://github.com/angular/angular/commit/cf89f14766b0ed0204f7012d44a4732fccb35398) | fix | Fix nested timer serialization ([#59173](https://github.com/angular/angular/pull/59173)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [300b141cc8](https://github.com/angular/angular/commit/300b141cc8652fd714b02f05c943cb79167ea844) | fix | Warn user when transfer state happens more than once ([#58935](https://github.com/angular/angular/pull/58935)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.0.5"></a>
|
||||
# 19.0.5 (2024-12-18)
|
||||
### core
|
||||
@@ -51,26 +242,6 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.0-next.3"></a>
|
||||
# 19.1.0-next.3 (2024-12-12)
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c5c20e9d86](https://github.com/angular/angular/commit/c5c20e9d86d72b33840dcf0adea02876437a589f) | fix | check event side of two-way bindings ([#59002](https://github.com/angular/angular/pull/59002)) |
|
||||
| [0dee2681f7](https://github.com/angular/angular/commit/0dee2681f782106fdb0fdcf9bc6ad1bca562751d) | fix | consider pre-release versions when detecting feature support ([#59061](https://github.com/angular/angular/pull/59061)) |
|
||||
| [1b9492edf8](https://github.com/angular/angular/commit/1b9492edf88f8a217c0fd1a8203df489d91b623b) | fix | error in unused standalone imports diagnostic ([#59064](https://github.com/angular/angular/pull/59064)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d010e11b73](https://github.com/angular/angular/commit/d010e11b735562ded439989ddb84cc83c6c00e81) | feat | add event listener options to renderer ([#59092](https://github.com/angular/angular/pull/59092)) |
|
||||
| [30e676098d](https://github.com/angular/angular/commit/30e676098d72e9e11a6628b9716668df08f18c62) | fix | Fix a bug where snapshotted functions are being run twice if they return a nullish/falsey value. ([#59073](https://github.com/angular/angular/pull/59073)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [52be35118f](https://github.com/angular/angular/commit/52be35118feee587d2efe5a6c55502c171caaa97) | fix | collect external component styles from server rendering ([#59031](https://github.com/angular/angular/pull/59031)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.0.4"></a>
|
||||
# 19.0.4 (2024-12-12)
|
||||
### compiler-cli
|
||||
@@ -89,43 +260,11 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.0-next.2"></a>
|
||||
# 19.1.0-next.2 (2024-12-04)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.0.3"></a>
|
||||
# 19.0.3 (2024-12-04)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.0-next.1"></a>
|
||||
# 19.1.0-next.1 (2024-12-04)
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [f280467398](https://github.com/angular/angular/commit/f280467398c6980878b5e755a78606251814447b) | fix | account for multiple generated namespace imports in HMR ([#58924](https://github.com/angular/angular/pull/58924)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e894a5daea](https://github.com/angular/angular/commit/e894a5daea401b4e1173b0e66557ae40140eb9a0) | feat | set kind field on template and effect nodes ([#58865](https://github.com/angular/angular/pull/58865)) |
|
||||
| [3b765367f3](https://github.com/angular/angular/commit/3b765367f31b6d1bb32406505f18151acdf1f2b2) | fix | Explicitly manage TracingSnapshot lifecycle and dispose of it once it's been used. ([#58929](https://github.com/angular/angular/pull/58929)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e31e52e177](https://github.com/angular/angular/commit/e31e52e1771ea565a6869b4ed252d6ff7097d4ad) | fix | class content being deleted in some edge cases ([#58959](https://github.com/angular/angular/pull/58959)) |
|
||||
| [508d3a1b3b](https://github.com/angular/angular/commit/508d3a1b3bc5770f18e3e46e2105bf0ba6178a87) | fix | correctly strip away parameters surrounded by comments in inject migration ([#58959](https://github.com/angular/angular/pull/58959)) |
|
||||
| [7191aa6e09](https://github.com/angular/angular/commit/7191aa6e09ca3b85efd3fd14a18944eac4384763) | fix | don't migrate classes with parameters that can't be injected ([#58959](https://github.com/angular/angular/pull/58959)) |
|
||||
| [a4924af6d5](https://github.com/angular/angular/commit/a4924af6d580c5bdaa185c4c97277c4effb55af9) | fix | inject migration aggressively removing imports ([#58959](https://github.com/angular/angular/pull/58959)) |
|
||||
| [35165d152d](https://github.com/angular/angular/commit/35165d152d7f9c3c8789ebdf792037aafdc1cc66) | fix | inject migration dropping code if everything except super is removed ([#58959](https://github.com/angular/angular/pull/58959)) |
|
||||
| [68e5ba7a3a](https://github.com/angular/angular/commit/68e5ba7a3a44c2f1647c4c6cc7ed66b010f85d15) | fix | preserve type literals and tuples in inject migrations ([#58959](https://github.com/angular/angular/pull/58959)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [1cfbfc66d3](https://github.com/angular/angular/commit/1cfbfc66d3a24b6c41abf13550e7c2911e20b550) | fix | remove peer dependency on animations ([#58997](https://github.com/angular/angular/pull/58997)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.0.2"></a>
|
||||
# 19.0.2 (2024-12-04)
|
||||
### compiler-cli
|
||||
@@ -161,19 +300,6 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.1.0-next.0"></a>
|
||||
# 19.1.0-next.0 (2024-11-26)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e4c50b3bea](https://github.com/angular/angular/commit/e4c50b3bea22ca2afba74465893c36730952f4b9) | feat | expose component instance in NgComponentOutlet ([#58698](https://github.com/angular/angular/pull/58698)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [bd1f1294ae](https://github.com/angular/angular/commit/bd1f1294aeb0d47b24421b7b7a608988689a459f) | feat | support TypeScript 5.7 ([#58609](https://github.com/angular/angular/pull/58609)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="19.0.1"></a>
|
||||
# 19.0.1 (2024-11-26)
|
||||
### compiler-cli
|
||||
|
||||
@@ -125,6 +125,7 @@ Help us keep Angular open and inclusive. Please read and follow our [Code of Con
|
||||
Join the conversation and help the community.
|
||||
|
||||
- [X (formerly Twitter)][X (formerly Twitter)]
|
||||
- [Bluesky][bluesky]
|
||||
- [Discord][discord]
|
||||
- [Gitter][gitter]
|
||||
- [YouTube][youtube]
|
||||
@@ -154,6 +155,7 @@ Join the conversation and help the community.
|
||||
[npm]: https://www.npmjs.com/get-npm
|
||||
[codeofconduct]: CODE_OF_CONDUCT.md
|
||||
[X (formerly Twitter)]: https://www.twitter.com/angular
|
||||
[bluesky]: https://bsky.app/profile/angular.dev
|
||||
[discord]: https://discord.gg/angular
|
||||
[gitter]: https://gitter.im/angular/angular
|
||||
[stackoverflow]: https://stackoverflow.com/questions/tagged/angular
|
||||
|
||||
@@ -50,16 +50,16 @@ load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
|
||||
nodejs_register_toolchains(
|
||||
name = "nodejs",
|
||||
node_repositories = {
|
||||
"18.20.0-darwin_arm64": ("node-v18.20.0-darwin-arm64.tar.gz", "node-v18.20.0-darwin-arm64", "10066ad4dd9e03ea5c4c45ef8775420ff37b860de09bbdf87b97e0c07b1ea036"),
|
||||
"18.20.0-darwin_amd64": ("node-v18.20.0-darwin-x64.tar.gz", "node-v18.20.0-darwin-x64", "062ba71618e88e06321de5caa038843c350aababa2d315f3ca7b8551f8e66c1c"),
|
||||
"18.20.0-linux_arm64": ("node-v18.20.0-linux-arm64.tar.xz", "node-v18.20.0-linux-arm64", "afe51da9ffb38ac1e3a20d9a06efd403ced4bf8831ab554a02a088dd8392fd79"),
|
||||
"18.20.0-linux_ppc64le": ("node-v18.20.0-linux-ppc64le.tar.xz", "node-v18.20.0-linux-ppc64le", "9e652bbf53a3e37285b11dfb9d6a9bb8b02010c3b50e5c8229d4cc10e72681da"),
|
||||
"18.20.0-linux_s390x": ("node-v18.20.0-linux-s390x.tar.xz", "node-v18.20.0-linux-s390x", "a6c2a5796b9d9e9bf21da62ec89ff30b41a8108880b9eaa3c912f1ce795a7743"),
|
||||
"18.20.0-linux_amd64": ("node-v18.20.0-linux-x64.tar.xz", "node-v18.20.0-linux-x64", "03eea148e56785babb27930b05ed6bf311aaa3bc573c0399dd63cad2fe5713c7"),
|
||||
"18.20.0-windows_amd64": ("node-v18.20.0-win-x64.zip", "node-v18.20.0-win-x64", "1c0aab05cc6836a8f5148cca345b92ebc948a4a2013f18d117b7ade6ff05aca6"),
|
||||
"18.20.5-darwin_arm64": ("node-v18.20.5-darwin-arm64.tar.gz", "node-v18.20.5-darwin-arm64", "bdfeaf59dbf29aec08c0c66130edf0a8a17014b4f2997727641dfd0b58b51f48"),
|
||||
"18.20.5-darwin_amd64": ("node-v18.20.5-darwin-x64.tar.gz", "node-v18.20.5-darwin-x64", "dff01068da7d3fe7b515f72a3903dca96a34dc377f6f426b6a813901274b6441"),
|
||||
"18.20.5-linux_arm64": ("node-v18.20.5-linux-arm64.tar.xz", "node-v18.20.5-linux-arm64", "a77db6ab34267f3bc80e02ed68abf51b7065eb5c82fcd69adc4b40e390d9b116"),
|
||||
"18.20.5-linux_ppc64le": ("node-v18.20.5-linux-ppc64le.tar.xz", "node-v18.20.5-linux-ppc64le", "63b4c6801c96fb452e3bd8125e8b5b195ecacc4fa2505e47a128e94587999aeb"),
|
||||
"18.20.5-linux_s390x": ("node-v18.20.5-linux-s390x.tar.xz", "node-v18.20.5-linux-s390x", "617d7456e16534a4b4e03f5285cc8d13581f39cdad9196efff2516d6588de319"),
|
||||
"18.20.5-linux_amd64": ("node-v18.20.5-linux-x64.tar.xz", "node-v18.20.5-linux-x64", "e4a3a21e5ac7e074ed50d2533dd0087d8460647ab567464867141a2b643f3fb3"),
|
||||
"18.20.5-windows_amd64": ("node-v18.20.5-win-x64.zip", "node-v18.20.5-win-x64", "910237449895b4de61026568dc076fa6c3ffcd667563ed03112a4a77e1f1556b"),
|
||||
},
|
||||
# We need at least Node 18.17 due to some transitive dependencies.
|
||||
node_version = "18.20.0",
|
||||
# We need at least Node 18.20.5 due to some transitive dependencies.
|
||||
node_version = "18.20.5",
|
||||
)
|
||||
|
||||
# Download npm dependencies.
|
||||
@@ -143,10 +143,10 @@ cldr_xml_data_repository(
|
||||
# sass rules
|
||||
http_archive(
|
||||
name = "io_bazel_rules_sass",
|
||||
sha256 = "0eae9a0c840e1e0d0b9ace056f8bde06384315315c4e2ebdb5cec722d1d4134b",
|
||||
strip_prefix = "rules_sass-aff53ca13ff2af82d323adb02a83c45a301e9ae8",
|
||||
sha256 = "e8b863f6be5609c6ed15664d12512ee36d93e8bcb2c1a331f85d9e8758a82ee7",
|
||||
strip_prefix = "rules_sass-3b3667fd5861b06a03bea1f1946b55ac7100d4ea",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_sass/archive/aff53ca13ff2af82d323adb02a83c45a301e9ae8.zip",
|
||||
"https://github.com/bazelbuild/rules_sass/archive/3b3667fd5861b06a03bea1f1946b55ac7100d4ea.zip",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ The content is written primarily in Markdown format located in `src/content`. Fo
|
||||
|
||||
## Local Development
|
||||
|
||||
For local development, [yarn](https://yarnpkg.com/) is the preferred package manager. You can setup a local environment with the following commands
|
||||
For local development, [yarn](https://yarnpkg.com/) is the preferred package manager. You can set up a local environment with the following commands
|
||||
:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
transition: background-color 0.3s ease;
|
||||
background-color: var(--septenary-contrast);
|
||||
|
||||
@include mq.for-tablet-landscape-down {
|
||||
background-color: var(--quinary-contrast);
|
||||
}
|
||||
|
||||
border-radius: 10px;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
|
||||
@@ -2,6 +2,8 @@ dialog {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding-block-end: 3rem;
|
||||
margin: 0 auto;
|
||||
top: 15vh;
|
||||
|
||||
&::backdrop {
|
||||
backdrop-filter: blur(5px);
|
||||
|
||||
@@ -6,26 +6,26 @@
|
||||
<ul class="docs-faceted-list">
|
||||
<!-- TODO: Hide li elements with class docs-toc-item-h3 for laptop, table and phone screen resolutions -->
|
||||
@for (item of tableOfContentItems(); track item.id) {
|
||||
<li
|
||||
class="docs-faceted-list-item"
|
||||
[class.docs-toc-item-h2]="item.level === TableOfContentsLevel.H2"
|
||||
[class.docs-toc-item-h3]="item.level === TableOfContentsLevel.H3"
|
||||
>
|
||||
<a
|
||||
routerLink="."
|
||||
[fragment]="item.id"
|
||||
[class.docs-faceted-list-item-active]="item.id === activeItemId()"
|
||||
<li
|
||||
class="docs-faceted-list-item"
|
||||
[class.docs-toc-item-h2]="item.level === TableOfContentsLevel.H2"
|
||||
[class.docs-toc-item-h3]="item.level === TableOfContentsLevel.H3"
|
||||
>
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
<!-- Not using routerLink + fragment because of: https://github.com/angular/angular/issues/30139 -->
|
||||
<a
|
||||
[href]="location.path() + '#' + item.id"
|
||||
[class.docs-faceted-list-item-active]="item.id === activeItemId()"
|
||||
>
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</nav>
|
||||
@if (shouldDisplayScrollToTop()) {
|
||||
<button type="button" (click)="scrollToTop()">
|
||||
<docs-icon role="presentation">arrow_upward_alt</docs-icon>
|
||||
Back to the top
|
||||
</button>
|
||||
<button type="button" (click)="scrollToTop()">
|
||||
<docs-icon role="presentation">arrow_upward_alt</docs-icon>
|
||||
Back to the top
|
||||
</button>
|
||||
}
|
||||
</aside>
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
computed,
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {Location} from '@angular/common';
|
||||
import {TableOfContentsLevel} from '../../interfaces/index';
|
||||
import {TableOfContentsLoader} from '../../services/table-of-contents-loader.service';
|
||||
import {TableOfContentsScrollSpy} from '../../services/table-of-contents-scroll-spy.service';
|
||||
@@ -25,11 +25,12 @@ import {IconComponent} from '../icon/icon.component';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
templateUrl: './table-of-contents.component.html',
|
||||
styleUrls: ['./table-of-contents.component.scss'],
|
||||
imports: [RouterLink, IconComponent],
|
||||
imports: [IconComponent],
|
||||
})
|
||||
export class TableOfContents {
|
||||
// Element that contains the content from which the Table of Contents is built
|
||||
readonly contentSourceElement = input.required<HTMLElement>();
|
||||
readonly location = inject(Location);
|
||||
|
||||
private readonly scrollSpy = inject(TableOfContentsScrollSpy);
|
||||
private readonly tableOfContentsLoader = inject(TableOfContentsLoader);
|
||||
|
||||
@@ -112,6 +112,13 @@ describe('DocViewer', () => {
|
||||
|
||||
expect(exampleViewer).not.toBeNull();
|
||||
expect(exampleViewer.componentInstance.view()).toBe(CodeExampleViewMode.SNIPPET);
|
||||
|
||||
const checkIcon = fixture.debugElement.query(By.directive(IconComponent));
|
||||
expect((checkIcon.nativeElement as HTMLElement).classList).toContain(
|
||||
`material-symbols-outlined`,
|
||||
);
|
||||
expect((checkIcon.nativeElement as HTMLElement).classList).toContain(`docs-check`);
|
||||
expect(checkIcon.nativeElement.innerHTML).toBe('check');
|
||||
});
|
||||
|
||||
it('should display example viewer in multi file mode when user clicks expand', async () => {
|
||||
|
||||
@@ -265,9 +265,12 @@ export class DocViewer implements OnChanges {
|
||||
}
|
||||
|
||||
private loadIcons(element: HTMLElement): void {
|
||||
element.querySelectorAll('docs-icon').forEach((iconsPlaceholder) => {
|
||||
this.renderComponent(IconComponent, iconsPlaceholder as HTMLElement);
|
||||
});
|
||||
// We need to make sure that we don't reload the icons in loadCopySourceCodeButtons
|
||||
element
|
||||
.querySelectorAll('docs-icon:not([docs-copy-source-code] docs-icon)')
|
||||
.forEach((iconsPlaceholder) => {
|
||||
this.renderComponent(IconComponent, iconsPlaceholder as HTMLElement);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,9 +293,6 @@ export class DocViewer implements OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger change detection after setting inputs.
|
||||
componentRef.changeDetectorRef.detectChanges();
|
||||
|
||||
// Attach a view to the ApplicationRef for change detection
|
||||
// purposes and for hydration serialization to pick it up
|
||||
// during SSG.
|
||||
@@ -340,7 +340,12 @@ export class DocViewer implements OnChanges {
|
||||
relativeUrl = hrefAttr;
|
||||
}
|
||||
|
||||
handleHrefClickEventWithRouter(e, this.router, relativeUrl);
|
||||
// Unless this is a link to an element within the same page, use the Angular router.
|
||||
// https://github.com/angular/angular/issues/30139
|
||||
const scrollToElementExists = relativeUrl.startsWith(this.location.path() + '#');
|
||||
if (!scrollToElementExists) {
|
||||
handleHrefClickEventWithRouter(e, this.router, relativeUrl);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -103,8 +103,6 @@ export class ExampleViewer {
|
||||
|
||||
this.snippetCode.set(this.exampleMetadata()?.files[0]);
|
||||
|
||||
this.changeDetector.detectChanges();
|
||||
|
||||
this.setCodeLinesVisibility();
|
||||
|
||||
this.elementRef.nativeElement.setAttribute(
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
load("//adev/shared-docs/pipeline:_guides.bzl", _generate_guides = "generate_guides")
|
||||
load("//adev/shared-docs/pipeline:_stackblitz.bzl", _generate_stackblitz = "generate_stackblitz")
|
||||
load("//adev/shared-docs/pipeline:_navigation.bzl", _generate_nav_items = "generate_nav_items")
|
||||
load("//adev/shared-docs/pipeline:_playground.bzl", _generate_playground = "generate_playground")
|
||||
load("//adev/shared-docs/pipeline:_stackblitz.bzl", _generate_stackblitz = "generate_stackblitz")
|
||||
load("//adev/shared-docs/pipeline:_tutorial.bzl", _generate_tutorial = "generate_tutorial")
|
||||
|
||||
generate_guides = _generate_guides
|
||||
generate_stackblitz = _generate_stackblitz
|
||||
generate_playground = _generate_playground
|
||||
generate_tutorial = _generate_tutorial
|
||||
generate_nav_items = _generate_nav_items
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
"name": "@angular/docs",
|
||||
"version": "0.0.0-PLACEHOLDER",
|
||||
"peerDependencies": {
|
||||
"@angular/cdk": "^19.1.0-next",
|
||||
"@angular/common": "^19.1.0-next",
|
||||
"@angular/core": "^19.1.0-next",
|
||||
"@angular/forms": "^19.1.0-next",
|
||||
"@angular/material": "^19.1.0-next",
|
||||
"@angular/platform-browser": "^19.1.0-next",
|
||||
"@angular/router": "^19.1.0-next",
|
||||
"@angular/ssr": "^19.1.0-next",
|
||||
"@angular/cdk": "^19.2.0-next",
|
||||
"@angular/common": "^19.2.0-next",
|
||||
"@angular/core": "^19.2.0-next",
|
||||
"@angular/forms": "^19.2.0-next",
|
||||
"@angular/material": "^19.2.0-next",
|
||||
"@angular/platform-browser": "^19.2.0-next",
|
||||
"@angular/router": "^19.2.0-next",
|
||||
"@angular/ssr": "^19.2.0-next",
|
||||
"algoliasearch": "^5.0.0",
|
||||
"rxjs": "^7.8.1"
|
||||
},
|
||||
@@ -20,10 +20,10 @@
|
||||
"fast-glob": "~3.3.2",
|
||||
"fflate": "^0.8.2",
|
||||
"html-entities": "~2.5.2",
|
||||
"jsdom": "~25.0.0",
|
||||
"jsdom": "~26.0.0",
|
||||
"marked": "~15.0.0",
|
||||
"mermaid": "^11.0.0",
|
||||
"shiki": "^1.10.3"
|
||||
"shiki": "^2.0.0"
|
||||
},
|
||||
"exports": {
|
||||
"./styles/*": {
|
||||
|
||||
@@ -97,11 +97,24 @@ esbuild_esm_bundle(
|
||||
],
|
||||
)
|
||||
|
||||
esbuild_esm_bundle(
|
||||
name = "navigation-bundle",
|
||||
entry_point = "//adev/shared-docs/pipeline/navigation:index.ts",
|
||||
output = "navigation.mjs",
|
||||
platform = "node",
|
||||
target = "es2022",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//adev/shared-docs/pipeline/navigation",
|
||||
],
|
||||
)
|
||||
|
||||
exports_files([
|
||||
"_guides.bzl",
|
||||
"_stackblitz.bzl",
|
||||
"_playground.bzl",
|
||||
"_tutorial.bzl",
|
||||
"_navigation.bzl",
|
||||
"BUILD.bazel",
|
||||
])
|
||||
|
||||
@@ -160,3 +173,9 @@ nodejs_binary(
|
||||
entry_point = "//adev/shared-docs/pipeline:tutorial.mjs",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
nodejs_binary(
|
||||
name = "navigation",
|
||||
entry_point = "//adev/shared-docs/pipeline:navigation.mjs",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
load("@build_bazel_rules_nodejs//:providers.bzl", "run_node")
|
||||
|
||||
def _generate_nav_items(ctx):
|
||||
"""Implementation of the navigation items data generator rule"""
|
||||
|
||||
# Set the arguments for the actions inputs and output location.
|
||||
args = ctx.actions.args()
|
||||
|
||||
# Use a param file because we may have a large number of inputs.
|
||||
args.set_param_file_format("multiline")
|
||||
args.use_param_file("%s", use_always = True)
|
||||
|
||||
# Pass the set of source files.
|
||||
args.add_joined(ctx.files.srcs, join_with = ",")
|
||||
|
||||
# Add BUILD file path to the arguments.
|
||||
args.add(ctx.label.package)
|
||||
|
||||
# Add the nav item generation strategy to thte arguments.
|
||||
args.add(ctx.attr.strategy)
|
||||
|
||||
# File declaration of the generated JSON file.
|
||||
json_output = ctx.actions.declare_file("routes.json")
|
||||
|
||||
# Add the path to the output file to the arguments.
|
||||
args.add(json_output.path)
|
||||
|
||||
run_node(
|
||||
ctx = ctx,
|
||||
inputs = depset(ctx.files.srcs),
|
||||
executable = "_generate_nav_items",
|
||||
outputs = [json_output],
|
||||
arguments = [args],
|
||||
)
|
||||
|
||||
# The return value describes what the rule is producing. In this case we need to specify
|
||||
# the "DefaultInfo" with the output json file.
|
||||
return [DefaultInfo(files = depset([json_output]))]
|
||||
|
||||
generate_nav_items = rule(
|
||||
# Point to the starlark function that will execute for this rule.
|
||||
implementation = _generate_nav_items,
|
||||
doc = """Rule that generates navigation items data.""",
|
||||
|
||||
# The attributes that can be set to this rule.
|
||||
attrs = {
|
||||
"srcs": attr.label_list(
|
||||
doc = """Markdown files that represent the page contents.""",
|
||||
allow_empty = False,
|
||||
allow_files = True,
|
||||
),
|
||||
"strategy": attr.string(
|
||||
doc = """Represents the navigation items generation strategy.""",
|
||||
),
|
||||
"_generate_nav_items": attr.label(
|
||||
default = Label("//adev/shared-docs/pipeline:navigation"),
|
||||
executable = True,
|
||||
cfg = "exec",
|
||||
),
|
||||
},
|
||||
)
|
||||
@@ -43,6 +43,7 @@ const MD_CTYPE_MAP: {[key in FileType]: string} = {
|
||||
export function interpolateCodeExamples(entries: DocEntry[]): void {
|
||||
for (const entry of entries) {
|
||||
entry.rawComment = replaceExample(entry.rawComment);
|
||||
entry.description = replaceExample(entry.description);
|
||||
|
||||
for (const jsdocTag of entry.jsdocTags) {
|
||||
jsdocTag.comment = replaceExample(jsdocTag.comment);
|
||||
|
||||
@@ -15,7 +15,7 @@ const tsMdBlock = (code: string) => '```angular-ts\n' + code + '\n```';
|
||||
const htmlMdBlock = (code: string) => '```angular-html\n' + code + '\n```';
|
||||
|
||||
const entriesBuilder = (comment: string): DocEntry[] => [
|
||||
{jsdocTags: [], rawComment: comment} as unknown as DocEntry,
|
||||
{jsdocTags: [], rawComment: comment, description: ''} as unknown as DocEntry,
|
||||
];
|
||||
|
||||
const getComment = (entries: DocEntry[]) => entries[0].rawComment;
|
||||
@@ -35,6 +35,7 @@ describe('interpolate_code_examples', () => {
|
||||
},
|
||||
],
|
||||
rawComment: `{@example dummy/jsdocs_raw.ts region='function'}`,
|
||||
description: `{@example dummy/jsdocs_raw.ts region='function'}`,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
// TODO(jelbourn): all of these CSS classes should use the `docs-` prefix.
|
||||
|
||||
export const API_REFERENCE_CONTAINER = 'docs-api';
|
||||
|
||||
export const PARAM_KEYWORD_CLASS_NAME = 'docs-param-keyword';
|
||||
export const PARAM_GROUP_CLASS_NAME = 'docs-param-group';
|
||||
|
||||
export const REFERENCE_HEADER = 'docs-reference-header';
|
||||
export const REFERENCE_MEMBERS = 'docs-reference-members';
|
||||
export const REFERENCE_DEPRECATED = 'docs-reference-deprecated';
|
||||
export const REFERENCE_MEMBERS_CONTAINER = 'docs-reference-members-container';
|
||||
export const REFERENCE_MEMBER_CARD = 'docs-reference-member-card';
|
||||
export const REFERENCE_MEMBER_CARD_HEADER = 'docs-reference-card-header';
|
||||
export const REFERENCE_MEMBER_CARD_BODY = 'docs-reference-card-body';
|
||||
@@ -24,3 +24,6 @@ export const HEADER_CLASS_NAME = 'docs-reference-header';
|
||||
export const HEADER_ENTRY_CATEGORY = 'docs-reference-category';
|
||||
export const HEADER_ENTRY_TITLE = 'docs-reference-title';
|
||||
export const HEADER_ENTRY_LABEL = 'docs-api-item-label';
|
||||
|
||||
export const SECTION_CONTAINER = 'docs-reference-section';
|
||||
export const SECTION_HEADING = 'docs-reference-section-heading';
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
isPropertyEntry,
|
||||
isSetterEntry,
|
||||
} from '../entities/categorization';
|
||||
import {MemberEntryRenderable} from '../entities/renderables';
|
||||
import {MemberEntryRenderable, MethodEntryRenderable} from '../entities/renderables';
|
||||
import {
|
||||
REFERENCE_MEMBER_CARD,
|
||||
REFERENCE_MEMBER_CARD_BODY,
|
||||
@@ -27,20 +27,24 @@ import {getFunctionMetadataRenderable} from '../transforms/function-transforms';
|
||||
import {CodeSymbol} from './code-symbols';
|
||||
|
||||
export function ClassMember(props: {member: MemberEntryRenderable}) {
|
||||
const member = props.member;
|
||||
|
||||
const renderMethod = (method: MethodEntryRenderable) => {
|
||||
const signature = method.signatures.length ? method.signatures : [method.implementation];
|
||||
return signature.map((sig) => {
|
||||
const renderableMember = getFunctionMetadataRenderable(sig);
|
||||
return <ClassMethodInfo entry={renderableMember} options={{showUsageNotes: true}} />;
|
||||
});
|
||||
};
|
||||
|
||||
const body = (
|
||||
<div className={REFERENCE_MEMBER_CARD_BODY}>
|
||||
{isClassMethodEntry(props.member) ? (
|
||||
(props.member.signatures.length
|
||||
? props.member.signatures
|
||||
: [props.member.implementation]
|
||||
).map((sig) => {
|
||||
const renderableMember = getFunctionMetadataRenderable(sig);
|
||||
return <ClassMethodInfo entry={renderableMember} options={{showUsageNotes: true}} />;
|
||||
})
|
||||
) : props.member.htmlDescription || props.member.deprecationMessage ? (
|
||||
{isClassMethodEntry(member) ? (
|
||||
renderMethod(member)
|
||||
) : member.htmlDescription || member.deprecationMessage ? (
|
||||
<div className={REFERENCE_MEMBER_CARD_ITEM}>
|
||||
<DeprecatedLabel entry={props.member} />
|
||||
<RawHtml value={props.member.htmlDescription} />
|
||||
<DeprecatedLabel entry={member} />
|
||||
<RawHtml value={member.htmlDescription} />
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
@@ -48,23 +52,19 @@ export function ClassMember(props: {member: MemberEntryRenderable}) {
|
||||
</div>
|
||||
);
|
||||
|
||||
const memberName = props.member.name;
|
||||
const returnType = getMemberType(props.member);
|
||||
const memberName = member.name;
|
||||
const returnType = getMemberType(member);
|
||||
return (
|
||||
<div id={memberName} className={REFERENCE_MEMBER_CARD} tabIndex={-1}>
|
||||
<header>
|
||||
<div className={REFERENCE_MEMBER_CARD_HEADER}>
|
||||
<h3>{memberName}</h3>
|
||||
<div>
|
||||
{isClassMethodEntry(props.member) && props.member.signatures.length > 1 ? (
|
||||
<span>{props.member.signatures.length} overloads</span>
|
||||
) : returnType ? (
|
||||
<CodeSymbol code={returnType} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div id={memberName} className={REFERENCE_MEMBER_CARD}>
|
||||
<header className={REFERENCE_MEMBER_CARD_HEADER}>
|
||||
<h3>{memberName}</h3>
|
||||
{isClassMethodEntry(member) && member.signatures.length > 1 ? (
|
||||
<span>{member.signatures.length} overloads</span>
|
||||
) : returnType ? (
|
||||
<CodeSymbol code={returnType} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</header>
|
||||
{body}
|
||||
</div>
|
||||
|
||||
@@ -10,26 +10,26 @@ import {Fragment, h} from 'preact';
|
||||
import {ClassEntryRenderable, DecoratorEntryRenderable} from '../entities/renderables';
|
||||
import {ClassMemberList} from './class-member-list';
|
||||
import {HeaderApi} from './header-api';
|
||||
import {REFERENCE_MEMBERS_CONTAINER} from '../styling/css-classes';
|
||||
import {TabDescription} from './tab-description';
|
||||
import {TabUsageNotes} from './tab-usage-notes';
|
||||
import {TabApi} from './tab-api';
|
||||
import {API_REFERENCE_CONTAINER, REFERENCE_MEMBERS} from '../styling/css-classes';
|
||||
import {SectionDescription} from './section-description';
|
||||
import {SectionUsageNotes} from './section-usage-notes';
|
||||
import {SectionApi} from './section-api';
|
||||
|
||||
/** Component to render a class API reference document. */
|
||||
export function ClassReference(entry: ClassEntryRenderable | DecoratorEntryRenderable) {
|
||||
return (
|
||||
<div class="api">
|
||||
<div className={API_REFERENCE_CONTAINER}>
|
||||
<HeaderApi entry={entry} />
|
||||
<TabApi entry={entry} />
|
||||
<TabDescription entry={entry} />
|
||||
<TabUsageNotes entry={entry} />
|
||||
<SectionApi entry={entry} />
|
||||
{entry.members.length > 0 ? (
|
||||
<div class={REFERENCE_MEMBERS_CONTAINER}>
|
||||
<div class={REFERENCE_MEMBERS}>
|
||||
<ClassMemberList members={entry.members} />
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<SectionDescription entry={entry} />
|
||||
<SectionUsageNotes entry={entry} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,17 +9,12 @@
|
||||
import {Fragment, h} from 'preact';
|
||||
import {CliCardRenderable} from '../entities/renderables';
|
||||
import {DeprecatedLabel} from './deprecated-label';
|
||||
import { REFERENCE_MEMBER_CARD, REFERENCE_MEMBER_CARD_HEADER } from '../styling/css-classes';
|
||||
import {REFERENCE_MEMBER_CARD, REFERENCE_MEMBER_CARD_BODY} from '../styling/css-classes';
|
||||
|
||||
export function CliCard(props: {card: CliCardRenderable}) {
|
||||
return (
|
||||
<div id={props.card.type} class={REFERENCE_MEMBER_CARD} tabIndex={-1}>
|
||||
<header>
|
||||
<div class={REFERENCE_MEMBER_CARD_HEADER}>
|
||||
<h3>{props.card.type}</h3>
|
||||
</div>
|
||||
</header>
|
||||
<div class="docs-reference-card-body">
|
||||
<div class={REFERENCE_MEMBER_CARD}>
|
||||
<div className={REFERENCE_MEMBER_CARD_BODY}>
|
||||
{props.card.items.map((item) => (
|
||||
<div class="docs-ref-content">
|
||||
{item.deprecated ? <DeprecatedLabel entry={item} /> : <></>}
|
||||
|
||||
@@ -6,55 +6,74 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import { Fragment, h } from 'preact';
|
||||
import { CliCommandRenderable } from '../entities/renderables';
|
||||
import { REFERENCE_MEMBERS, REFERENCE_MEMBERS_CONTAINER } from '../styling/css-classes';
|
||||
import { CliCard } from './cli-card';
|
||||
import { HeaderCli } from './header-cli';
|
||||
import { RawHtml } from './raw-html';
|
||||
import {Fragment, h} from 'preact';
|
||||
import {CliCommandRenderable} from '../entities/renderables';
|
||||
import {REFERENCE_MEMBERS} from '../styling/css-classes';
|
||||
import {CliCard} from './cli-card';
|
||||
import {HeaderCli} from './header-cli';
|
||||
import {RawHtml} from './raw-html';
|
||||
import {SectionHeading} from './section-heading';
|
||||
|
||||
/** Component to render a CLI command reference document. */
|
||||
export function CliCommandReference(entry: CliCommandRenderable) {
|
||||
return (
|
||||
<div className="cli">
|
||||
<div className="docs-cli">
|
||||
<div className="docs-reference-cli-content">
|
||||
<HeaderCli command={entry} />
|
||||
{[entry.name, ...entry.aliases].map((command) =>
|
||||
{[entry.name, ...entry.aliases].map((command) => (
|
||||
<div class="docs-code docs-reference-cli-toc">
|
||||
<pre class="docs-mini-scroll-track">
|
||||
<code>
|
||||
<div className={'shiki line cli'}>
|
||||
ng {commandName(entry, command)}
|
||||
{entry.argumentsLabel ? <button member-id={'Arguments'} className="shiki-ln-line-argument">{entry.argumentsLabel}</button> : <></>}
|
||||
{entry.hasOptions ? <button member-id={'Options'} className="shiki-ln-line-option">[options]</button> : <></>}
|
||||
{entry.argumentsLabel ? (
|
||||
<button member-id={'Arguments'} className="shiki-ln-line-argument">
|
||||
{entry.argumentsLabel}
|
||||
</button>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{entry.hasOptions ? (
|
||||
<button member-id={'Options'} className="shiki-ln-line-option">
|
||||
[options]
|
||||
</button>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
))}
|
||||
<RawHtml value={entry.htmlDescription} />
|
||||
{entry.subcommands && entry.subcommands?.length > 0 ? (
|
||||
<>
|
||||
<h3>Sub-commands</h3>
|
||||
<p>This command has the following sub-commands</p>
|
||||
<ul>
|
||||
{entry.subcommands.map((subcommand) => (
|
||||
<li>
|
||||
<a href={`cli/${entry.name}/${subcommand.name}`}>{subcommand.name}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<RawHtml value={entry.htmlDescription}/>
|
||||
{entry.subcommands && entry.subcommands?.length > 0 ? <>
|
||||
<h3>Sub-commands</h3>
|
||||
<p>This command has the following sub-commands</p>
|
||||
<ul>
|
||||
{entry.subcommands.map((subcommand) =>
|
||||
<li>
|
||||
<a href={`cli/${entry.name}/${subcommand.name}`}>{subcommand.name}</a>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</> : <></>}
|
||||
</div>
|
||||
<div className={REFERENCE_MEMBERS_CONTAINER}>
|
||||
<div className={REFERENCE_MEMBERS}>
|
||||
{entry.cards.map((card) => <CliCard card={card} />)}
|
||||
</div>
|
||||
<div className={REFERENCE_MEMBERS}>
|
||||
{entry.cards.map((card) => (
|
||||
<>
|
||||
<SectionHeading name={card.type} />
|
||||
<CliCard card={card} />
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function commandName(entry: CliCommandRenderable, command: string) {
|
||||
if (entry.parentCommand?.name) {
|
||||
return `${entry.parentCommand?.name} ${command}`;
|
||||
|
||||
@@ -9,18 +9,19 @@
|
||||
import {h} from 'preact';
|
||||
import {ConstantEntryRenderable} from '../entities/renderables';
|
||||
import {HeaderApi} from './header-api';
|
||||
import {TabDescription} from './tab-description';
|
||||
import {TabUsageNotes} from './tab-usage-notes';
|
||||
import {TabApi} from './tab-api';
|
||||
import {SectionDescription} from './section-description';
|
||||
import {SectionUsageNotes} from './section-usage-notes';
|
||||
import {SectionApi} from './section-api';
|
||||
import {API_REFERENCE_CONTAINER} from '../styling/css-classes';
|
||||
|
||||
/** Component to render a constant API reference document. */
|
||||
export function ConstantReference(entry: ConstantEntryRenderable) {
|
||||
return (
|
||||
<div class="api">
|
||||
<div className={API_REFERENCE_CONTAINER}>
|
||||
<HeaderApi entry={entry} />
|
||||
<TabApi entry={entry} />
|
||||
<TabDescription entry={entry} />
|
||||
<TabUsageNotes entry={entry} />
|
||||
<SectionApi entry={entry} />
|
||||
<SectionDescription entry={entry} />
|
||||
<SectionUsageNotes entry={entry} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
import {h} from 'preact';
|
||||
import {DocEntryRenderable} from '../entities/renderables';
|
||||
import {HeaderApi} from './header-api';
|
||||
import {TabDescription} from './tab-description';
|
||||
import {SectionDescription} from './section-description';
|
||||
import {API_REFERENCE_CONTAINER} from '../styling/css-classes';
|
||||
|
||||
/** Component to render a block or element API reference document. */
|
||||
export function DocsReference(entry: DocEntryRenderable) {
|
||||
return (
|
||||
<div class="api">
|
||||
<div className={API_REFERENCE_CONTAINER}>
|
||||
<HeaderApi entry={entry} />
|
||||
<TabDescription entry={entry} />
|
||||
<SectionDescription entry={entry} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,29 +9,27 @@
|
||||
import {h, Fragment} from 'preact';
|
||||
import {EnumEntryRenderable, MemberEntryRenderable} from '../entities/renderables';
|
||||
import {HeaderApi} from './header-api';
|
||||
import {TabDescription} from './tab-description';
|
||||
import {TabApi} from './tab-api';
|
||||
import {REFERENCE_MEMBERS, REFERENCE_MEMBERS_CONTAINER} from '../styling/css-classes';
|
||||
import {SectionDescription} from './section-description';
|
||||
import {SectionApi} from './section-api';
|
||||
import {API_REFERENCE_CONTAINER, REFERENCE_MEMBERS} from '../styling/css-classes';
|
||||
import {ClassMember} from './class-member';
|
||||
|
||||
/** Component to render a enum API reference document. */
|
||||
export function EnumReference(entry: EnumEntryRenderable) {
|
||||
return (
|
||||
<div class="api">
|
||||
<div className={API_REFERENCE_CONTAINER}>
|
||||
<HeaderApi entry={entry} />
|
||||
<TabApi entry={entry} />
|
||||
<TabDescription entry={entry} />
|
||||
{
|
||||
entry.members.length > 0
|
||||
? (
|
||||
<div class={REFERENCE_MEMBERS_CONTAINER}>
|
||||
<div class={REFERENCE_MEMBERS}>
|
||||
{entry.members.map((member: MemberEntryRenderable) => (<ClassMember member={member}/>))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
: (<></>)
|
||||
}
|
||||
<SectionApi entry={entry} />
|
||||
{entry.members.length > 0 ? (
|
||||
<div class={REFERENCE_MEMBERS}>
|
||||
{entry.members.map((member: MemberEntryRenderable) => (
|
||||
<ClassMember member={member} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<SectionDescription entry={entry} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,20 +6,23 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {h} from 'preact';
|
||||
import {FunctionEntryRenderable, FunctionSignatureMetadataRenderable} from '../entities/renderables';
|
||||
import {h, Fragment} from 'preact';
|
||||
import {
|
||||
FunctionEntryRenderable,
|
||||
FunctionSignatureMetadataRenderable,
|
||||
} from '../entities/renderables';
|
||||
import {
|
||||
API_REFERENCE_CONTAINER,
|
||||
REFERENCE_MEMBERS,
|
||||
REFERENCE_MEMBERS_CONTAINER,
|
||||
REFERENCE_MEMBER_CARD,
|
||||
REFERENCE_MEMBER_CARD_BODY,
|
||||
REFERENCE_MEMBER_CARD_HEADER,
|
||||
} from '../styling/css-classes';
|
||||
import {ClassMethodInfo} from './class-method-info';
|
||||
import {HeaderApi} from './header-api';
|
||||
import {TabApi} from './tab-api';
|
||||
import {TabDescription} from './tab-description';
|
||||
import {TabUsageNotes} from './tab-usage-notes';
|
||||
import {SectionApi} from './section-api';
|
||||
import {SectionDescription} from './section-description';
|
||||
import {SectionUsageNotes} from './section-usage-notes';
|
||||
import {HighlightTypeScript} from './highlight-ts';
|
||||
import {printInitializerFunctionSignatureLine} from '../transforms/code-transforms';
|
||||
import {getFunctionMetadataRenderable} from '../transforms/function-transforms';
|
||||
@@ -32,8 +35,8 @@ export const signatureCard = (
|
||||
printSignaturesAsHeader: boolean,
|
||||
) => {
|
||||
return (
|
||||
<div class={REFERENCE_MEMBER_CARD} id={opts.id} tabIndex={-1}>
|
||||
<header>
|
||||
<div id={opts.id} class={REFERENCE_MEMBER_CARD}>
|
||||
<header class={REFERENCE_MEMBER_CARD_HEADER}>
|
||||
{printSignaturesAsHeader ? (
|
||||
<code>
|
||||
<HighlightTypeScript
|
||||
@@ -46,12 +49,12 @@ export const signatureCard = (
|
||||
/>
|
||||
</code>
|
||||
) : (
|
||||
<div className={REFERENCE_MEMBER_CARD_HEADER}>
|
||||
<>
|
||||
<h3>{name}</h3>
|
||||
<div>
|
||||
<CodeSymbol code={signature.returnType} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</header>
|
||||
<div class={REFERENCE_MEMBER_CARD_BODY}>
|
||||
@@ -67,25 +70,24 @@ export function FunctionReference(entry: FunctionEntryRenderable) {
|
||||
const printSignaturesAsHeader = entry.signatures.length > 1;
|
||||
|
||||
return (
|
||||
<div class="api">
|
||||
<div className={API_REFERENCE_CONTAINER}>
|
||||
<HeaderApi entry={entry} />
|
||||
<TabApi entry={entry} />
|
||||
<TabDescription entry={entry} />
|
||||
<TabUsageNotes entry={entry} />
|
||||
<div className={REFERENCE_MEMBERS_CONTAINER}>
|
||||
<div className={REFERENCE_MEMBERS}>
|
||||
{entry.signatures.map((s, i) =>
|
||||
signatureCard(
|
||||
s.name,
|
||||
getFunctionMetadataRenderable(s, entry.moduleName),
|
||||
{
|
||||
id: `${s.name}_${i}`,
|
||||
},
|
||||
printSignaturesAsHeader,
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
<SectionApi entry={entry} />
|
||||
<div className={REFERENCE_MEMBERS}>
|
||||
{entry.signatures.map((s, i) =>
|
||||
signatureCard(
|
||||
s.name,
|
||||
getFunctionMetadataRenderable(s, entry.moduleName),
|
||||
{
|
||||
id: `${s.name}_${i}`,
|
||||
},
|
||||
printSignaturesAsHeader,
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
|
||||
<SectionDescription entry={entry} />
|
||||
<SectionUsageNotes entry={entry} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
+33
-34
@@ -9,9 +9,9 @@
|
||||
import {h, JSX} from 'preact';
|
||||
import {InitializerApiFunctionRenderable} from '../entities/renderables';
|
||||
import {HeaderApi} from './header-api';
|
||||
import {TabApi} from './tab-api';
|
||||
import {TabUsageNotes} from './tab-usage-notes';
|
||||
import {REFERENCE_MEMBERS, REFERENCE_MEMBERS_CONTAINER} from '../styling/css-classes';
|
||||
import {SectionApi} from './section-api';
|
||||
import {SectionUsageNotes} from './section-usage-notes';
|
||||
import {API_REFERENCE_CONTAINER, REFERENCE_MEMBERS} from '../styling/css-classes';
|
||||
import {getFunctionMetadataRenderable} from '../transforms/function-transforms';
|
||||
import {signatureCard} from './function-reference';
|
||||
|
||||
@@ -34,42 +34,41 @@ export function InitializerApiFunction(entry: InitializerApiFunctionRenderable)
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="api">
|
||||
<div className={API_REFERENCE_CONTAINER}>
|
||||
<HeaderApi entry={entry} showFullDescription={true} />
|
||||
<TabApi entry={entry} />
|
||||
<TabUsageNotes entry={entry} />
|
||||
<SectionApi entry={entry} />
|
||||
|
||||
<div class={REFERENCE_MEMBERS_CONTAINER}>
|
||||
<div class={REFERENCE_MEMBERS}>
|
||||
{entry.callFunction.signatures.map((s, i) =>
|
||||
signatureCard(
|
||||
s.name,
|
||||
getFunctionMetadataRenderable(s, entry.moduleName),
|
||||
{
|
||||
id: `${s.name}_${i}`,
|
||||
},
|
||||
printSignaturesAsHeader,
|
||||
),
|
||||
)}
|
||||
<div class={REFERENCE_MEMBERS}>
|
||||
{entry.callFunction.signatures.map((s, i) =>
|
||||
signatureCard(
|
||||
s.name,
|
||||
getFunctionMetadataRenderable(s, entry.moduleName),
|
||||
{
|
||||
id: `${s.name}_${i}`,
|
||||
},
|
||||
printSignaturesAsHeader,
|
||||
),
|
||||
)}
|
||||
|
||||
{entry.subFunctions.reduce(
|
||||
(elements, subFunction) => [
|
||||
...elements,
|
||||
...subFunction.signatures.map((s, i) =>
|
||||
signatureCard(
|
||||
`${entry.name}.${s.name}`,
|
||||
getFunctionMetadataRenderable(s, entry.moduleName),
|
||||
{
|
||||
id: `${entry.name}_${s.name}_${i}`,
|
||||
},
|
||||
printSignaturesAsHeader,
|
||||
),
|
||||
{entry.subFunctions.reduce(
|
||||
(elements, subFunction) => [
|
||||
...elements,
|
||||
...subFunction.signatures.map((s, i) =>
|
||||
signatureCard(
|
||||
`${entry.name}.${s.name}`,
|
||||
getFunctionMetadataRenderable(s, entry.moduleName),
|
||||
{
|
||||
id: `${entry.name}_${s.name}_${i}`,
|
||||
},
|
||||
printSignaturesAsHeader,
|
||||
),
|
||||
],
|
||||
[] as JSX.Element[],
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
],
|
||||
[] as JSX.Element[],
|
||||
)}
|
||||
</div>
|
||||
|
||||
<SectionUsageNotes entry={entry} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*!
|
||||
* @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 {h} from 'preact';
|
||||
import {DocEntryRenderable} from '../entities/renderables';
|
||||
import {HasRenderableToc} from '../entities/traits';
|
||||
import {CodeTableOfContents} from './code-table-of-contents';
|
||||
import {SECTION_CONTAINER} from '../styling/css-classes';
|
||||
import {SectionHeading} from './section-heading';
|
||||
|
||||
const API_SECTION_NAME = 'API';
|
||||
|
||||
/** Component to render the API section. */
|
||||
export function SectionApi(props: {entry: DocEntryRenderable & HasRenderableToc}) {
|
||||
return (
|
||||
<div className={SECTION_CONTAINER + ' docs-reference-api-section'}>
|
||||
<SectionHeading name={API_SECTION_NAME} />
|
||||
<CodeTableOfContents entry={props.entry} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+7
-5
@@ -8,14 +8,15 @@
|
||||
|
||||
import {Fragment, h} from 'preact';
|
||||
import {DocEntryRenderable} from '../entities/renderables';
|
||||
import {normalizeTabUrl} from '../transforms/url-transforms';
|
||||
import {RawHtml} from './raw-html';
|
||||
import {CodeSymbol} from './code-symbols';
|
||||
import {SECTION_CONTAINER} from '../styling/css-classes';
|
||||
import {SectionHeading} from './section-heading';
|
||||
|
||||
const DESCRIPTION_TAB_NAME = 'Description';
|
||||
const DESCRIPTION_SECTION_NAME = 'Description';
|
||||
|
||||
/** Component to render the description tab. */
|
||||
export function TabDescription(props: {entry: DocEntryRenderable}) {
|
||||
/** Component to render the description section. */
|
||||
export function SectionDescription(props: {entry: DocEntryRenderable}) {
|
||||
const exportedBy = props.entry.jsdocTags.filter((t) => t.name === 'ngModule');
|
||||
if (
|
||||
(!props.entry.htmlDescription ||
|
||||
@@ -26,7 +27,8 @@ export function TabDescription(props: {entry: DocEntryRenderable}) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div data-tab={DESCRIPTION_TAB_NAME} data-tab-url={normalizeTabUrl(DESCRIPTION_TAB_NAME)}>
|
||||
<div className={SECTION_CONTAINER}>
|
||||
<SectionHeading name={DESCRIPTION_SECTION_NAME} />
|
||||
<RawHtml value={props.entry.htmlDescription} />
|
||||
|
||||
{exportedBy.length ? (
|
||||
@@ -0,0 +1,25 @@
|
||||
/*!
|
||||
* @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 {h} from 'preact';
|
||||
import {convertSectionNameToId} from '../transforms/reference-section-id';
|
||||
import {SECTION_HEADING} from '../styling/css-classes';
|
||||
|
||||
/** Component to render the API section. */
|
||||
export function SectionHeading(props: {name: string}) {
|
||||
const id = convertSectionNameToId(props.name);
|
||||
const label = 'Link to ' + props.name + ' section';
|
||||
|
||||
return (
|
||||
<h2 id={id} class={SECTION_HEADING}>
|
||||
<a href={'#' + id} aria-label={label} tabIndex={-1}>
|
||||
{props.name}
|
||||
</a>
|
||||
</h2>
|
||||
);
|
||||
}
|
||||
+8
-6
@@ -8,19 +8,21 @@
|
||||
|
||||
import {Fragment, h} from 'preact';
|
||||
import {DocEntryRenderable} from '../entities/renderables';
|
||||
import {normalizeTabUrl} from '../transforms/url-transforms';
|
||||
import {RawHtml} from './raw-html';
|
||||
import {SECTION_CONTAINER} from '../styling/css-classes';
|
||||
import {SectionHeading} from './section-heading';
|
||||
|
||||
const USAGE_NOTES_TAB_NAME = 'Usage Notes';
|
||||
const USAGE_NOTES_SECTION_NAME = 'Usage Notes';
|
||||
|
||||
/** Component to render the usage notes tab. */
|
||||
export function TabUsageNotes(props: {entry: DocEntryRenderable}) {
|
||||
/** Component to render the usage notes section. */
|
||||
export function SectionUsageNotes(props: {entry: DocEntryRenderable}) {
|
||||
if (!props.entry.htmlUsageNotes) {
|
||||
return (<></>);
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div data-tab={USAGE_NOTES_TAB_NAME} data-tab-url={normalizeTabUrl(USAGE_NOTES_TAB_NAME)}>
|
||||
<div className={SECTION_CONTAINER}>
|
||||
<SectionHeading name={USAGE_NOTES_SECTION_NAME} />
|
||||
<RawHtml value={props.entry.htmlUsageNotes} />
|
||||
</div>
|
||||
);
|
||||
@@ -1,26 +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 {h} from 'preact';
|
||||
import {DocEntryRenderable} from '../entities/renderables';
|
||||
import {HasRenderableToc} from '../entities/traits';
|
||||
import {normalizeTabUrl} from '../transforms/url-transforms';
|
||||
import {CodeTableOfContents} from './code-table-of-contents';
|
||||
|
||||
const API_TAB_NAME = 'API';
|
||||
|
||||
/** Component to render the API tab. */
|
||||
export function TabApi(props: {entry: DocEntryRenderable & HasRenderableToc}) {
|
||||
return (
|
||||
<div data-tab={API_TAB_NAME} data-tab-url={normalizeTabUrl(API_TAB_NAME)}>
|
||||
<div class={'docs-reference-api-tab'}>
|
||||
<CodeTableOfContents entry={props.entry} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -9,18 +9,19 @@
|
||||
import {h} from 'preact';
|
||||
import {TypeAliasEntryRenderable} from '../entities/renderables';
|
||||
import {HeaderApi} from './header-api';
|
||||
import {TabDescription} from './tab-description';
|
||||
import {TabUsageNotes} from './tab-usage-notes';
|
||||
import {TabApi} from './tab-api';
|
||||
import {SectionDescription} from './section-description';
|
||||
import {SectionUsageNotes} from './section-usage-notes';
|
||||
import {SectionApi} from './section-api';
|
||||
import {API_REFERENCE_CONTAINER} from '../styling/css-classes';
|
||||
|
||||
/** Component to render a type alias API reference document. */
|
||||
export function TypeAliasReference(entry: TypeAliasEntryRenderable) {
|
||||
return (
|
||||
<div class="api">
|
||||
<div className={API_REFERENCE_CONTAINER}>
|
||||
<HeaderApi entry={entry} />
|
||||
<TabApi entry={entry} />
|
||||
<TabDescription entry={entry} />
|
||||
<TabUsageNotes entry={entry} />
|
||||
<SectionApi entry={entry} />
|
||||
<SectionDescription entry={entry} />
|
||||
<SectionUsageNotes entry={entry} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*!
|
||||
* @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
|
||||
*/
|
||||
|
||||
export const convertSectionNameToId = (sectionName: string): string => {
|
||||
return sectionName
|
||||
.toLowerCase()
|
||||
.replace(/\s|\//g, '-') // remove spaces and slashes
|
||||
.replace(/[^0-9a-z\-]/g, ''); // only keep letters, digits & dashes
|
||||
};
|
||||
@@ -19,15 +19,3 @@ export const normalizePath = (path: string): string => {
|
||||
}
|
||||
return path;
|
||||
};
|
||||
|
||||
export const normalizeTabUrl = (tabName: string): string => {
|
||||
return tabName
|
||||
.toLowerCase()
|
||||
.replace(/<code>(.*?)<\/code>/g, '$1') // remove <code>
|
||||
.replace(/<strong>(.*?)<\/strong>/g, '$1') // remove <strong>
|
||||
.replace(/<em>(.*?)<\/em>/g, '$1') // remove <em>
|
||||
.replace(/\s|\//g, '-') // remove spaces and slashes
|
||||
.replace(/gt;|lt;/g, '') // remove escaped < and >
|
||||
.replace(/&#\d+;/g, '') // remove HTML entities
|
||||
.replace(/[^0-9a-zA-Z\-]/g, ''); // only keep letters, digits & dashes
|
||||
};
|
||||
|
||||
@@ -21,14 +21,13 @@
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"builder": "@angular-devkit/build-angular:application",
|
||||
"options": {
|
||||
"outputPath": "dist/example-app",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"browser": "src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "css",
|
||||
"assets": ["src/assets"],
|
||||
"styles": ["src/styles.css"],
|
||||
"stylePreprocessorOptions": {
|
||||
@@ -59,12 +58,9 @@
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
"sourceMap": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {Token, Tokens, RendererThis, TokenizerThis} from 'marked';
|
||||
import {formatHeading, headingRender} from '../../tranformations/heading';
|
||||
import {formatHeading} from '../../tranformations/heading';
|
||||
|
||||
interface DocsStepToken extends Tokens.Generic {
|
||||
type: 'docs-step';
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
```mermaid
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
```
|
||||
|
||||
```mermaid
|
||||
pie title Pets adopted by volunteers
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
```
|
||||
@@ -20,9 +20,24 @@ describe('markdown to html', () => {
|
||||
// Extend the timeout interval tyo 15 seconds because we were seeing issues with not being able to run marked
|
||||
// within the default timeframe.
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000;
|
||||
const markdownContent = await readFile(runfiles.resolvePackageRelative('./mermaid.md'), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
|
||||
// This test was flaky, 1st attemp to fix it is by inlining the markdown content
|
||||
const markdownContent = `
|
||||
\`\`\`mermaid
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
\`\`\`
|
||||
|
||||
\`\`\`mermaid
|
||||
pie title Pets adopted by volunteers
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
\`\`\`
|
||||
`;
|
||||
|
||||
marked.use({
|
||||
async: true,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
ts_library(
|
||||
name = "lib",
|
||||
srcs = glob(
|
||||
[
|
||||
"*.ts",
|
||||
],
|
||||
exclude = [
|
||||
"index.ts",
|
||||
],
|
||||
),
|
||||
deps = [
|
||||
"//adev/shared-docs/interfaces",
|
||||
"@npm//@types/node",
|
||||
"@npm//@webcontainer/api",
|
||||
"@npm//fast-glob",
|
||||
],
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "navigation",
|
||||
srcs = [
|
||||
"index.ts",
|
||||
],
|
||||
visibility = [
|
||||
"//adev/shared-docs:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":lib",
|
||||
"//adev/shared-docs/interfaces",
|
||||
"@npm//@types/node",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
/*!
|
||||
* @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 {readFileSync, writeFileSync} from 'fs';
|
||||
import {generateNavItems} from './nav-items-gen';
|
||||
import {getNavItemGenStrategy} from './strategies';
|
||||
|
||||
async function main() {
|
||||
const [paramFilePath] = process.argv.slice(2);
|
||||
const rawParamLines = readFileSync(paramFilePath, {encoding: 'utf8'}).split('\n');
|
||||
const [joinedSrcs, packageDir, strategy, outputFilePath] = rawParamLines;
|
||||
|
||||
const srcs = joinedSrcs.split(',');
|
||||
|
||||
// Generate navigation data
|
||||
const navData = await generateNavItems(srcs, getNavItemGenStrategy(strategy, packageDir));
|
||||
|
||||
writeFileSync(outputFilePath, JSON.stringify(navData));
|
||||
}
|
||||
|
||||
await main();
|
||||
@@ -0,0 +1,59 @@
|
||||
/*!
|
||||
* @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 fs from 'fs';
|
||||
import readline from 'readline';
|
||||
import {basename, dirname, resolve} from 'path';
|
||||
|
||||
import {NavigationItem} from '../../interfaces';
|
||||
import {NavigationItemGenerationStrategy} from './types';
|
||||
|
||||
/**
|
||||
* Generate navigations items by a provided strategy.
|
||||
*
|
||||
* @param mdFilesPaths Paths to the Markdown files that represent the page contents
|
||||
* @param strategy Strategy
|
||||
* @returns An array with navigation items
|
||||
*/
|
||||
export async function generateNavItems(
|
||||
mdFilesPaths: string[],
|
||||
strategy: NavigationItemGenerationStrategy,
|
||||
): Promise<NavigationItem[]> {
|
||||
const navItems: NavigationItem[] = [];
|
||||
const {labelGeneratorFn, pathPrefix, contentPath} = strategy;
|
||||
|
||||
for (const path of mdFilesPaths) {
|
||||
const fullPath = resolve(dirname(path), basename(path));
|
||||
const name = path.split('/').pop()?.replace('.md', '')!;
|
||||
const firstLine = await getMdFileHeading(fullPath);
|
||||
|
||||
navItems.push({
|
||||
label: labelGeneratorFn(name, firstLine),
|
||||
path: `${pathPrefix}/${name}`,
|
||||
contentPath: `${contentPath}/${name}`,
|
||||
});
|
||||
}
|
||||
|
||||
return navItems;
|
||||
}
|
||||
|
||||
/** Extract the first heading from a Markdown file. */
|
||||
async function getMdFileHeading(filePath: string): Promise<string> {
|
||||
const readStream = fs.createReadStream(filePath);
|
||||
const rl = readline.createInterface({input: readStream});
|
||||
|
||||
for await (const line of rl) {
|
||||
if (line.trim().startsWith('#')) {
|
||||
rl.close();
|
||||
readStream.destroy();
|
||||
return line.replace(/^#+[ \t]+/, '');
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*!
|
||||
* @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 {NavigationItemGenerationStrategy, Strategy} from './types';
|
||||
|
||||
// Should point to the website content.
|
||||
// Update, if the location is updated or shared-docs is extracted from `adev/`.
|
||||
const CONTENT_FOLDER_PATH = 'adev/src/content/';
|
||||
|
||||
// Ensure that all Strategy-ies are part of SUPPORTED_STRATEGIES by using a key-typed object.
|
||||
const strategiesObj: {[key in Strategy]: null} = {errors: null, 'extended-diagnostics': null};
|
||||
const SUPPORTED_STRATEGIES = Object.keys(strategiesObj);
|
||||
|
||||
/** Get navigation item generation strategy by a provided strategy string. */
|
||||
export function getNavItemGenStrategy(
|
||||
strategy: string,
|
||||
packageDir: string,
|
||||
): NavigationItemGenerationStrategy {
|
||||
if (SUPPORTED_STRATEGIES.indexOf(strategy) === -1) {
|
||||
throw new Error(
|
||||
`Unsupported NavigationItem generation strategy "${strategy}". Supported: ${SUPPORTED_STRATEGIES.join(', ')}`,
|
||||
);
|
||||
}
|
||||
|
||||
switch (strategy as Strategy) {
|
||||
case 'errors':
|
||||
return errorsStrategy(packageDir);
|
||||
case 'extended-diagnostics':
|
||||
return extendedDiagnosticsStrategy(packageDir);
|
||||
}
|
||||
}
|
||||
|
||||
// "Errors" navigation items generation strategy
|
||||
function errorsStrategy(packageDir: string): NavigationItemGenerationStrategy {
|
||||
return {
|
||||
pathPrefix: 'errors',
|
||||
contentPath: packageDir.replace(CONTENT_FOLDER_PATH, ''),
|
||||
labelGeneratorFn: (fileName, firstLine) => fileName + ': ' + firstLine,
|
||||
};
|
||||
}
|
||||
|
||||
// "Extended diagnostics" items generation strategy
|
||||
function extendedDiagnosticsStrategy(packageDir: string): NavigationItemGenerationStrategy {
|
||||
return {
|
||||
pathPrefix: 'extended-diagnostics',
|
||||
contentPath: packageDir.replace(CONTENT_FOLDER_PATH, ''),
|
||||
labelGeneratorFn: (fileName, firstLine) => fileName + ': ' + firstLine,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
load("//tools:defaults.bzl", "jasmine_node_test", "ts_library")
|
||||
|
||||
package(default_visibility = ["//adev/shared-docs/pipeline/navigation:__subpackages__"])
|
||||
|
||||
ts_library(
|
||||
name = "unit_test_lib",
|
||||
testonly = True,
|
||||
srcs = glob(["*.spec.ts"]),
|
||||
deps = [
|
||||
"//adev/shared-docs/pipeline/navigation:lib",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "unit_tests",
|
||||
deps = [":unit_test_lib"],
|
||||
)
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @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 {generateNavItems} from '../nav-items-gen';
|
||||
import {NavigationItemGenerationStrategy} from '../types';
|
||||
import fs from 'fs';
|
||||
import readline from 'readline';
|
||||
|
||||
const readlineInterfaceMock = {
|
||||
close: () => {},
|
||||
async *[Symbol.asyncIterator]() {
|
||||
yield '<!-- Comment -->';
|
||||
yield 'Some random text';
|
||||
yield '## Heading';
|
||||
yield 'Some text';
|
||||
},
|
||||
};
|
||||
|
||||
describe('generateNavItems', () => {
|
||||
it('should test the default case', async () => {
|
||||
spyOn(fs, 'createReadStream').and.returnValue({destroy: () => null} as any);
|
||||
spyOn(readline, 'createInterface').and.returnValue(readlineInterfaceMock as any);
|
||||
|
||||
const strategy: NavigationItemGenerationStrategy = {
|
||||
pathPrefix: 'page',
|
||||
contentPath: 'content/directory',
|
||||
labelGeneratorFn: (fileName, firstLine) => fileName + ' // ' + firstLine,
|
||||
};
|
||||
|
||||
const navItems = await generateNavItems(['directory/home.md', 'directory/about.md'], strategy);
|
||||
|
||||
expect(navItems).toEqual([
|
||||
{
|
||||
label: 'home // Heading',
|
||||
path: 'page/home',
|
||||
contentPath: 'content/directory/home',
|
||||
},
|
||||
{
|
||||
label: 'about // Heading',
|
||||
path: 'page/about',
|
||||
contentPath: 'content/directory/about',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
/*!
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* `NavigationItem` generation strategy
|
||||
*/
|
||||
export type NavigationItemGenerationStrategy = {
|
||||
/** App route path prefix. */
|
||||
pathPrefix: string;
|
||||
/** Content path where the source files are kept. */
|
||||
contentPath: string;
|
||||
/** Page/route label generator function. */
|
||||
labelGeneratorFn: (fileName: string, firstLine: string) => string;
|
||||
};
|
||||
|
||||
/** Strategy for navigation item generation. */
|
||||
export type Strategy = 'errors' | 'extended-diagnostics';
|
||||
@@ -33,7 +33,6 @@ ts_library(
|
||||
":editor",
|
||||
"//adev/shared-docs/interfaces",
|
||||
"@npm//@types/node",
|
||||
"@npm//fast-glob",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -49,9 +49,7 @@ export class TableOfContentsLoader {
|
||||
const updatedTopValues = new Map<string, number>();
|
||||
|
||||
for (const heading of headings) {
|
||||
const parentTop = heading.parentElement?.offsetTop ?? 0;
|
||||
const top = Math.floor(parentTop + heading.offsetTop - this.toleranceThreshold);
|
||||
updatedTopValues.set(heading.id, top);
|
||||
updatedTopValues.set(heading.id, this.calculateTop(heading));
|
||||
}
|
||||
|
||||
this.tableOfContentItems.update((oldItems) => {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
&:not(.full) {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
flex: 0 0 22px;
|
||||
}
|
||||
|
||||
&.full {
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
@use './anchor' as anchor;
|
||||
|
||||
/* Common styles for the API & CLI references */
|
||||
@mixin reference-common() {
|
||||
.docs-code {
|
||||
pre {
|
||||
margin-block: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.docs-reference-header {
|
||||
// deprecated markers beside header
|
||||
& ~ .docs-deprecated {
|
||||
margin-block-start: 0.5rem;
|
||||
}
|
||||
|
||||
& > p {
|
||||
color: var(--secondary-contrast);
|
||||
margin-block-start: 0;
|
||||
margin-block-end: 1.5rem;
|
||||
}
|
||||
|
||||
.docs-reference-title {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-block-end: 0;
|
||||
gap: 0.5rem;
|
||||
|
||||
> div {
|
||||
margin-block: 0.67em;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
h1 {
|
||||
margin-block: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
fill: var(--quinary-contrast);
|
||||
transition: fill 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
fill: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.docs-reference-category {
|
||||
color: var(--gray-400);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.4rem;
|
||||
letter-spacing: -0.00875rem;
|
||||
}
|
||||
|
||||
.docs-code {
|
||||
margin-block-end: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.docs-reference-section-heading {
|
||||
padding-block-start: 3rem;
|
||||
|
||||
a {
|
||||
@include anchor.docs-anchor();
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.docs-reference-members {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.docs-reference-member-card {
|
||||
border: 1px solid var(--senary-contrast);
|
||||
border-radius: 0.25rem;
|
||||
position: relative;
|
||||
transition: border 0.3s ease;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
inset: -1px;
|
||||
position: absolute;
|
||||
background: transparent;
|
||||
border-radius: 0.35rem;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&.highlighted {
|
||||
box-shadow: 10px 4px 40px 0 rgba(0, 0, 0, 0.01);
|
||||
|
||||
&::before {
|
||||
background: var(--red-to-pink-to-purple-horizontal-gradient);
|
||||
}
|
||||
}
|
||||
|
||||
> p {
|
||||
padding-inline: 1.25rem;
|
||||
margin-block-end: 0;
|
||||
}
|
||||
|
||||
.docs-reference-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-radius: 0.25rem 0.25rem 0 0;
|
||||
background-color: var(--octonary-contrast);
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
padding: 0.7rem 1rem;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
transition:
|
||||
background-color 0.3s ease,
|
||||
border 0.3s ease;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:has(+ .docs-reference-card-body:empty) {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875rem;
|
||||
|
||||
&:has(pre) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&:not(pre *) {
|
||||
padding: 0 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0;
|
||||
|
||||
/* Do we have a better alternative ? */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
h3 {
|
||||
display: inline-block;
|
||||
font-family: var(--code-font);
|
||||
font-size: 1rem;
|
||||
letter-spacing: -0.025rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
.docs-reference-card-body {
|
||||
padding: 0.25rem 1.25rem;
|
||||
background: var(--septenary-contrast);
|
||||
transition: background-color 0.3s ease;
|
||||
color: var(--quaternary-contrast);
|
||||
border-radius: 0 0 0.25rem 0.25rem;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-block: 2rem;
|
||||
}
|
||||
|
||||
.docs-code {
|
||||
margin-block-end: 1rem;
|
||||
}
|
||||
|
||||
.docs-deprecation-message {
|
||||
border-block-end: 1px solid var(--senary-contrast);
|
||||
|
||||
.docs-deprecated {
|
||||
color: var(--page-background);
|
||||
background-color: var(--quaternary-contrast);
|
||||
width: max-content;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.1rem 0.25rem;
|
||||
margin-block-start: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* API reference styles */
|
||||
@mixin api-reference {
|
||||
// API section styles
|
||||
.docs-reference-api-section {
|
||||
.docs-code {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
|
||||
button {
|
||||
transition: background-color 0.3s ease;
|
||||
|
||||
&.shiki-ln-line-highlighted {
|
||||
background-color: var(--senary-contrast);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--septenary-contrast);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: var(--senary-contrast);
|
||||
|
||||
span {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hide copy source code button
|
||||
button[docs-copy-source-code] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
margin-block: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre;
|
||||
overflow-x: auto;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// "API member card"-specific styles
|
||||
.docs-reference-member-card {
|
||||
.docs-reference-card-item {
|
||||
// When it's not the only card ...
|
||||
&:has(~ .docs-reference-card-item) {
|
||||
border: 1px solid var(--senary-contrast);
|
||||
margin-block: 1rem;
|
||||
border-radius: 0.25rem;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
// & the last card
|
||||
&:last-child:not(:first-of-type) {
|
||||
border: 1px solid var(--senary-contrast);
|
||||
margin-block: 1rem;
|
||||
border-radius: 0.25rem;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.docs-function-definition:has(*) {
|
||||
border-block-end: 1px solid var(--senary-contrast);
|
||||
}
|
||||
|
||||
.docs-param-group {
|
||||
margin-block-start: 1rem;
|
||||
|
||||
// If it's the only param group...
|
||||
&:not(:has(~ .docs-param-group)) {
|
||||
margin-block: 1rem;
|
||||
}
|
||||
|
||||
.docs-param-name {
|
||||
color: var(--vivid-pink);
|
||||
font-family: var(--code-font);
|
||||
margin-inline-end: 0.25rem;
|
||||
|
||||
&::after {
|
||||
content: ':';
|
||||
}
|
||||
}
|
||||
|
||||
.docs-parameter-description {
|
||||
p:first-child {
|
||||
margin-block-start: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.docs-param-keyword {
|
||||
color: var(--primary-contrast);
|
||||
font-family: var(--code-font);
|
||||
margin-inline-end: 0.5rem;
|
||||
}
|
||||
|
||||
.docs-return-type {
|
||||
padding-block: 1rem;
|
||||
|
||||
// & does not follow a function definition
|
||||
&:not(.docs-function-definition + .docs-return-type) {
|
||||
border-block-start: 1px solid var(--senary-contrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* CLI reference styles */
|
||||
@mixin cli-reference {
|
||||
// CLI TOC
|
||||
.docs-reference-cli-toc {
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.shiki-ln-line-argument,
|
||||
.shiki-ln-line-option {
|
||||
padding: 0.1rem 0.2rem 0.2rem;
|
||||
margin-inline: 0.1rem;
|
||||
color: var(--quaternary-contrast);
|
||||
background: transparent;
|
||||
border-radius: 0.25rem;
|
||||
position: relative;
|
||||
transition:
|
||||
color 0.3s ease,
|
||||
background 0.3s ease,
|
||||
border 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
color: var(--primary-contrast);
|
||||
background: var(--septenary-contrast);
|
||||
}
|
||||
|
||||
&.shiki-ln-line-highlighted {
|
||||
color: var(--primary-contrast);
|
||||
background: var(--senary-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
.shiki-ln-line-argument {
|
||||
margin-inline-start: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.docs-reference-members {
|
||||
.docs-reference-section-heading {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// "CLI member card"-specific styles
|
||||
.docs-reference-member-card {
|
||||
.docs-ref-content {
|
||||
padding: 1rem 0;
|
||||
|
||||
&:not(:first-child) {
|
||||
border-block-start: 1px solid var(--senary-contrast);
|
||||
}
|
||||
|
||||
.docs-reference-type-and-default {
|
||||
width: 4.375rem;
|
||||
flex-shrink: 0;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
font-size: 0.875rem;
|
||||
margin-block-end: 0.2rem;
|
||||
white-space: nowrap;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-block-start: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.775rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,9 @@
|
||||
border: 1px solid var(--senary-contrast);
|
||||
border-radius: 0.25rem;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.3s ease, background-color 0.3s ease;
|
||||
transition:
|
||||
border-color 0.3s ease,
|
||||
background-color 0.3s ease;
|
||||
|
||||
p:first-of-type {
|
||||
margin-block-start: 1.5rem;
|
||||
@@ -54,6 +56,7 @@
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
border-block-start: 1px solid var(--senary-contrast);
|
||||
|
||||
h3 {
|
||||
margin-bottom: 0;
|
||||
margin-block-start: 1rem;
|
||||
@@ -79,7 +82,6 @@
|
||||
color: transparent;
|
||||
font-size: 0.875rem;
|
||||
margin-block: 0;
|
||||
|
||||
transition: background-position 1.8s ease-out;
|
||||
background-size: 200% 100%;
|
||||
background-position: 100% 0%;
|
||||
@@ -87,10 +89,11 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--subtle-purple);
|
||||
|
||||
span {
|
||||
background-position: 0% 0%;
|
||||
}
|
||||
background: var(--subtle-purple);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,12 +144,16 @@ class FakeFileSystemAPI implements FileSystemAPI {
|
||||
): Promise<DirEnt<string>[]>;
|
||||
readdir(
|
||||
path: unknown,
|
||||
options?: unknown,
|
||||
options?: {encoding?: string | null | undefined; withFileTypes?: boolean} | string | null,
|
||||
):
|
||||
| Promise<Uint8Array[]>
|
||||
| Promise<string[]>
|
||||
| Promise<DirEnt<Uint8Array>[]>
|
||||
| Promise<DirEnt<string>[]> {
|
||||
if (typeof options === 'object' && options?.withFileTypes === true) {
|
||||
return Promise.resolve([{name: 'fake-file', isFile: () => true, isDirectory: () => false}]);
|
||||
}
|
||||
|
||||
return Promise.resolve(['/fake-dirname']);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@ ts_library(
|
||||
"//adev/shared-docs/providers",
|
||||
"//packages/core",
|
||||
"//packages/router",
|
||||
"@npm//@types/node",
|
||||
"@npm//@webcontainer/api",
|
||||
"@npm//fflate",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -41,7 +41,7 @@ interface FileSystemAPI {
|
||||
export const checkFilesInDirectory = async (
|
||||
dir: string,
|
||||
fs: FileSystemAPI,
|
||||
filterFoldersPredicate: (path?: string) => boolean = () => true,
|
||||
filterFromRootPredicate: ((path: string) => boolean) | null,
|
||||
files: FileAndContent[] = [],
|
||||
) => {
|
||||
const entries = (await fs.readdir(dir, {withFileTypes: true})) ?? [];
|
||||
@@ -49,11 +49,15 @@ export const checkFilesInDirectory = async (
|
||||
for (const entry of entries) {
|
||||
const fullPath = normalizePath(`${dir}/${entry.name}`);
|
||||
|
||||
if (filterFromRootPredicate && !filterFromRootPredicate?.(entry.name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.isFile()) {
|
||||
const content = await fs.readFile(fullPath, 'utf-8');
|
||||
files.push({content, path: fullPath});
|
||||
} else if (entry.isDirectory() && filterFoldersPredicate(entry.name)) {
|
||||
await checkFilesInDirectory(fullPath, fs, filterFoldersPredicate, files);
|
||||
} else if (entry.isDirectory()) {
|
||||
await checkFilesInDirectory(fullPath, fs, null, files);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,11 @@ export class AppScroller {
|
||||
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;
|
||||
}
|
||||
@@ -41,7 +42,6 @@ export class AppScroller {
|
||||
this.canScroll = true;
|
||||
this._lastScrollEvent = e;
|
||||
}),
|
||||
filter(() => !this.disableScrolling),
|
||||
filter(() => {
|
||||
const info = this.router.lastSuccessfulNavigation?.extras.info as Record<
|
||||
'disableScrolling',
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
import {mergeApplicationConfig, ApplicationConfig} from '@angular/core';
|
||||
import {provideServerRendering} from '@angular/platform-server';
|
||||
import {provideServerRoutesConfig, RenderMode} from '@angular/ssr';
|
||||
import {provideServerRouting, RenderMode} from '@angular/ssr';
|
||||
import {appConfig} from './app.config';
|
||||
|
||||
const serverConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideServerRendering(),
|
||||
provideServerRoutesConfig([{path: '**', renderMode: RenderMode.Prerender}]),
|
||||
provideServerRouting([{path: '**', renderMode: RenderMode.Prerender}]),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -11,3 +11,4 @@ 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 BLUESKY = 'https://bsky.app/profile/angular.dev';
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
export const VERSIONS_CONFIG = {
|
||||
aDevVersionsLinkPattern: 'https://{{prefix}}{{version}}angular.dev',
|
||||
aioVersions: [
|
||||
{
|
||||
version: 'v18',
|
||||
url: 'https://v18.angular.dev/overview',
|
||||
},
|
||||
{
|
||||
version: 'v17',
|
||||
url: 'https://v17.angular.io/docs',
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
<li>
|
||||
<a [href]="X" title="X (formerly Twitter)">X (formerly Twitter)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [href]="BLUESKY" title="Bluesky">Bluesky</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [href]="YOUTUBE" title="YouTube">YouTube</a>
|
||||
</li>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import {ChangeDetectionStrategy, Component} from '@angular/core';
|
||||
import {ExternalLink} from '@angular/docs';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {GITHUB, X, MEDIUM, YOUTUBE} from './../../constants/links';
|
||||
import {GITHUB, X, MEDIUM, YOUTUBE, BLUESKY} from './../../constants/links';
|
||||
|
||||
@Component({
|
||||
selector: 'footer[adev-footer]',
|
||||
@@ -23,4 +23,5 @@ export class Footer {
|
||||
readonly X = X;
|
||||
readonly YOUTUBE = YOUTUBE;
|
||||
readonly MEDIUM = MEDIUM;
|
||||
readonly BLUESKY = BLUESKY;
|
||||
}
|
||||
|
||||
@@ -346,6 +346,27 @@
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
[href]="BLUESKY"
|
||||
cdkMenuItem
|
||||
title="Angular Bluesky profile"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<!-- Bluesky Icon -->
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3.468 1.948C5.303 3.325 7.276 6.118 8 7.616c.725-1.498 2.697-4.29 4.532-5.668C13.855.955 16 .186 16 2.632c0 .489-.28 4.105-.444 4.692-.572 2.04-2.653 2.561-4.504 2.246 3.236.551 4.06 2.375 2.281 4.2-3.376 3.464-4.852-.87-5.23-1.98-.07-.204-.103-.3-.103-.218 0-.081-.033.014-.102.218-.379 1.11-1.855 5.444-5.231 1.98-1.778-1.825-.955-3.65 2.28-4.2-1.85.315-3.932-.205-4.503-2.246C.28 6.737 0 3.12 0 2.632 0 .186 2.145.955 3.468 1.948Z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
[href]="MEDIUM"
|
||||
|
||||
@@ -64,7 +64,9 @@
|
||||
// render primary nav / mini menu above tablet secondary bar
|
||||
z-index: 250;
|
||||
position: relative;
|
||||
transition: background-color 0.3s ease, border-color 0.3s ease;
|
||||
transition:
|
||||
background-color 0.3s ease,
|
||||
border-color 0.3s ease;
|
||||
height: 100dvh;
|
||||
padding-block-start: 1rem;
|
||||
padding-block-end: 2rem;
|
||||
@@ -96,8 +98,8 @@
|
||||
color-mix(in srgb, var(--orange-red), transparent 60%) 0%,
|
||||
color-mix(in srgb, var(--vivid-pink), transparent 40%) 15%,
|
||||
color-mix(in srgb, var(--electric-violet), transparent 70%) 25%,
|
||||
color-mix(in srgb, var(--bright-blue), transparent 60%) 90%,
|
||||
);
|
||||
color-mix(in srgb, var(--bright-blue), transparent 60%) 90%
|
||||
);
|
||||
}
|
||||
|
||||
&.adev-nav-primary--deprecated {
|
||||
@@ -195,7 +197,7 @@
|
||||
}
|
||||
|
||||
li {
|
||||
padding-inline: 1rem;
|
||||
padding-inline: 0.875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,8 +211,9 @@
|
||||
gap: 1rem;
|
||||
|
||||
@include mq.for-tablet {
|
||||
flex-direction: row;
|
||||
flex-direction: row !important;
|
||||
margin-inline-end: 1.25rem;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.adev-nav-item--active {
|
||||
@@ -249,8 +252,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
.adev-nav-item--logo a {
|
||||
height: 34px;
|
||||
.adev-nav-item--logo {
|
||||
a {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
@include mq.for-tablet {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.adev-close-nav {
|
||||
@@ -281,7 +290,9 @@
|
||||
border-block-end: 1px solid var(--septenary-contrast);
|
||||
padding-block: 1rem;
|
||||
padding-inline: var(--layout-padding);
|
||||
transition: background-color 0.3s ease, border-color 0.3s ease;
|
||||
transition:
|
||||
background-color 0.3s ease,
|
||||
border-color 0.3s ease;
|
||||
button {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
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, DISCORD, BLUESKY} from '../../constants/links';
|
||||
import {PagePrefix} from '../../enums/pages';
|
||||
import {Theme, ThemeManager} from '../../services/theme-manager.service';
|
||||
import {VersionManager} from '../../services/version-manager.service';
|
||||
@@ -67,6 +67,7 @@ export class Navigation implements OnInit {
|
||||
readonly MEDIUM = MEDIUM;
|
||||
readonly YOUTUBE = YOUTUBE;
|
||||
readonly DISCORD = DISCORD;
|
||||
readonly BLUESKY = BLUESKY;
|
||||
|
||||
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
|
||||
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
|
||||
|
||||
@@ -39,8 +39,8 @@ describe('VersionManager', () => {
|
||||
});
|
||||
|
||||
it('should contain correct number of Angular Docs versions', () => {
|
||||
// Note: From v2 to v17 (inclusive), there were no v3
|
||||
const expectedAioDocsVersionsCount = 15;
|
||||
// Note: From v2 to v18 (inclusive), there were no v3
|
||||
const expectedAioDocsVersionsCount = 16;
|
||||
|
||||
// Last stable version and next
|
||||
const expectedRecentDocsVersionCount = 2;
|
||||
|
||||
@@ -44,7 +44,8 @@ class FakeCodeMirrorEditor implements Partial<CodeMirrorEditor> {
|
||||
const codeMirrorEditorService = new FakeCodeMirrorEditor();
|
||||
const fakeChangeDetectorRef = new FakeChangeDetectorRef();
|
||||
|
||||
describe('CodeEditor', () => {
|
||||
// Disabled because broken (like because of package mismatch)
|
||||
xdescribe('CodeEditor', () => {
|
||||
let component: CodeEditor;
|
||||
let fixture: ComponentFixture<CodeEditor>;
|
||||
let loader: HarnessLoader;
|
||||
@@ -148,6 +149,9 @@ describe('CodeEditor', () => {
|
||||
});
|
||||
|
||||
it('should focused on a new tab when adding a new file', async () => {
|
||||
// Wait until the asynchronous injection stuff is done.
|
||||
await fixture.whenStable();
|
||||
|
||||
const button = fixture.debugElement.query(By.css('button.adev-add-file')).nativeElement;
|
||||
button.click();
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
Component,
|
||||
DestroyRef,
|
||||
ElementRef,
|
||||
EnvironmentInjector,
|
||||
OnDestroy,
|
||||
ViewChild,
|
||||
inject,
|
||||
@@ -21,10 +22,9 @@ import {
|
||||
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 {debounceTime, from, map, switchMap} from 'rxjs';
|
||||
|
||||
import {TerminalType} from '../terminal/terminal-handler.service';
|
||||
import {EmbeddedTutorialManager} from '../embedded-tutorial-manager.service';
|
||||
|
||||
import {CodeMirrorEditor} from './code-mirror-editor.service';
|
||||
import {DiagnosticWithLocation, DiagnosticsState} from './services/diagnostics-state.service';
|
||||
@@ -34,6 +34,7 @@ import {ClickOutside, IconComponent} from '@angular/docs';
|
||||
import {CdkMenu, CdkMenuItem, CdkMenuTrigger} from '@angular/cdk/menu';
|
||||
import {IDXLauncher} from '../idx-launcher.service';
|
||||
import {MatTooltip} from '@angular/material/tooltip';
|
||||
import {injectEmbeddedTutorialManager} from '../inject-embedded-tutorial-manager';
|
||||
|
||||
export const REQUIRED_FILES = new Set([
|
||||
'src/main.ts',
|
||||
@@ -91,7 +92,7 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
|
||||
private readonly idxLauncher = inject(IDXLauncher);
|
||||
private readonly title = inject(Title);
|
||||
private readonly location = inject(Location);
|
||||
private readonly embeddedTutorialManager = inject(EmbeddedTutorialManager);
|
||||
private readonly environmentInjector = inject(EnvironmentInjector);
|
||||
|
||||
private readonly errors$ = this.diagnosticsState.diagnostics$.pipe(
|
||||
// Display errors one second after code update
|
||||
@@ -142,7 +143,8 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
async downloadCurrentCodeEditorState(): Promise<void> {
|
||||
const name = this.embeddedTutorialManager.tutorialId();
|
||||
const embeddedTutorialManager = await injectEmbeddedTutorialManager(this.environmentInjector);
|
||||
const name = embeddedTutorialManager.tutorialId();
|
||||
await this.downloadManager.downloadCurrentStateOfTheSolution(name);
|
||||
}
|
||||
|
||||
@@ -236,8 +238,14 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
private setSelectedTabOnTutorialChange() {
|
||||
this.embeddedTutorialManager.tutorialChanged$
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
// Using `from` to prevent injecting the embedded tutorial manager once the
|
||||
// injector is destroyed (this may happen in unit tests when the test ends
|
||||
// before `injectAsync` runs, causing an error).
|
||||
from(injectEmbeddedTutorialManager(this.environmentInjector))
|
||||
.pipe(
|
||||
switchMap((embeddedTutorialManager) => embeddedTutorialManager.tutorialChanged$),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
)
|
||||
.subscribe(() => {
|
||||
// selected file on project change is always the first
|
||||
this.matTabGroup.selectedIndex = 0;
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
import {DOCUMENT, isPlatformBrowser} from '@angular/common';
|
||||
import {EnvironmentInjector, Injectable, PLATFORM_ID, inject} from '@angular/core';
|
||||
import {generateZip} from '@angular/docs';
|
||||
import {injectAsync} from '../core/services/inject-async';
|
||||
|
||||
import {injectNodeRuntimeSandbox} from './inject-node-runtime-sandbox';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -23,9 +24,7 @@ export class DownloadManager {
|
||||
* Generate ZIP with the current state of the solution in the EmbeddedEditor
|
||||
*/
|
||||
async downloadCurrentStateOfTheSolution(name: string) {
|
||||
const nodeRuntimeSandbox = await injectAsync(this.environmentInjector, () =>
|
||||
import('./node-runtime-sandbox.service').then((c) => c.NodeRuntimeSandbox),
|
||||
);
|
||||
const nodeRuntimeSandbox = await injectNodeRuntimeSandbox(this.environmentInjector);
|
||||
|
||||
const files = await nodeRuntimeSandbox.getSolutionFiles();
|
||||
const content = await generateZip(files);
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {DestroyRef, inject, Injectable, signal} from '@angular/core';
|
||||
import {EnvironmentInjector, inject, Injectable, signal} from '@angular/core';
|
||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
import {filter, map, Subject} from 'rxjs';
|
||||
import {filter, from, map, Subject, switchMap} from 'rxjs';
|
||||
|
||||
import {TutorialMetadata, TutorialType} from '@angular/docs';
|
||||
|
||||
import {EmbeddedTutorialManager} from './embedded-tutorial-manager.service';
|
||||
import {injectEmbeddedTutorialManager} from './inject-embedded-tutorial-manager';
|
||||
|
||||
export interface EditorUiStateConfig {
|
||||
displayOnlyInteractiveTerminal: boolean;
|
||||
@@ -23,8 +23,7 @@ export const DEFAULT_EDITOR_UI_STATE: EditorUiStateConfig = {
|
||||
|
||||
@Injectable()
|
||||
export class EditorUiState {
|
||||
private readonly embeddedTutorialManager = inject(EmbeddedTutorialManager);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly environmentInjector = inject(EnvironmentInjector);
|
||||
|
||||
private readonly stateChanged = new Subject<void>();
|
||||
|
||||
@@ -41,11 +40,13 @@ export class EditorUiState {
|
||||
}
|
||||
|
||||
private handleTutorialChange() {
|
||||
this.embeddedTutorialManager.tutorialChanged$
|
||||
from(injectEmbeddedTutorialManager(this.environmentInjector))
|
||||
.pipe(
|
||||
map(() => this.embeddedTutorialManager.type()),
|
||||
switchMap((embeddedTutorialManager) =>
|
||||
embeddedTutorialManager.tutorialChanged$.pipe(map(() => embeddedTutorialManager.type())),
|
||||
),
|
||||
filter((tutorialType): tutorialType is TutorialMetadata['type'] => Boolean(tutorialType)),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
takeUntilDestroyed(),
|
||||
)
|
||||
.subscribe((tutorialType) => {
|
||||
if (tutorialType === TutorialType.CLI) {
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
*/
|
||||
|
||||
import {EnvironmentInjector, Injectable, inject} from '@angular/core';
|
||||
import {injectAsync} from '../core/services/inject-async';
|
||||
import * as IDX from 'open-in-idx';
|
||||
|
||||
import {injectNodeRuntimeSandbox} from './inject-node-runtime-sandbox';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
@@ -17,9 +18,7 @@ export class IDXLauncher {
|
||||
private readonly environmentInjector = inject(EnvironmentInjector);
|
||||
|
||||
async openCurrentSolutionInIDX(): Promise<void> {
|
||||
const nodeRuntimeSandbox = await injectAsync(this.environmentInjector, () =>
|
||||
import('./node-runtime-sandbox.service').then((c) => c.NodeRuntimeSandbox),
|
||||
);
|
||||
const nodeRuntimeSandbox = await injectNodeRuntimeSandbox(this.environmentInjector);
|
||||
|
||||
const runtimeFiles = await nodeRuntimeSandbox.getSolutionFiles();
|
||||
const workspaceFiles: Record<string, string> = {};
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
export {EmbeddedTutorialManager} from './embedded-tutorial-manager.service';
|
||||
export {LoadingStep} from './enums/loading-steps';
|
||||
export {NodeRuntimeState} from './node-runtime-state.service';
|
||||
|
||||
export {NodeRuntimeSandbox} from './node-runtime-sandbox.service';
|
||||
export {injectNodeRuntimeSandbox} from './inject-node-runtime-sandbox';
|
||||
|
||||
export {EmbeddedEditor, EMBEDDED_EDITOR_SELECTOR} from './embedded-editor.component';
|
||||
|
||||
export {injectEmbeddedTutorialManager} from './inject-embedded-tutorial-manager';
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*!
|
||||
* @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} from '@angular/core';
|
||||
|
||||
import {injectAsync} from '../core/services/inject-async';
|
||||
|
||||
export function injectEmbeddedTutorialManager(injector: EnvironmentInjector) {
|
||||
return injectAsync(injector, () =>
|
||||
import('./embedded-tutorial-manager.service').then((c) => c.EmbeddedTutorialManager),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*!
|
||||
* @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} from '@angular/core';
|
||||
|
||||
import {injectAsync} from '../core/services/inject-async';
|
||||
|
||||
export function injectNodeRuntimeSandbox(injector: EnvironmentInjector) {
|
||||
return injectAsync(injector, () =>
|
||||
import('./node-runtime-sandbox.service').then((c) => c.NodeRuntimeSandbox),
|
||||
);
|
||||
}
|
||||
@@ -300,4 +300,18 @@ describe('NodeRuntimeSandbox', () => {
|
||||
expect(deleteFileSpy).toHaveBeenCalledWith(fileToDelete);
|
||||
}
|
||||
});
|
||||
|
||||
it('should not have any filePath starting with "/" in solutions files', async () => {
|
||||
service['webContainerPromise'] = Promise.resolve(
|
||||
new FakeWebContainer() as unknown as WebContainer,
|
||||
);
|
||||
setValuesToInitializeProject();
|
||||
|
||||
await service.init();
|
||||
|
||||
const files = await service.getSolutionFiles();
|
||||
|
||||
expect(files.length).toBe(1);
|
||||
expect(files[0].path).toBe('fake-file');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -143,12 +143,20 @@ export class NodeRuntimeSandbox {
|
||||
async getSolutionFiles(): Promise<FileAndContent[]> {
|
||||
const webContainer = await this.webContainerPromise!;
|
||||
|
||||
const excludeFolders = ['node_modules', '.angular', 'dist'];
|
||||
const excludeFromRoot = [
|
||||
'node_modules',
|
||||
'.angular',
|
||||
'dist',
|
||||
'BUILD.bazel',
|
||||
'idx',
|
||||
'package.json.template',
|
||||
'config.json',
|
||||
];
|
||||
|
||||
return await checkFilesInDirectory(
|
||||
'/',
|
||||
'',
|
||||
webContainer.fs,
|
||||
(path?: string) => !!path && !excludeFolders.includes(path),
|
||||
(path: string) => !excludeFromRoot.includes(path),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
inject,
|
||||
computed,
|
||||
} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, inject, computed} from '@angular/core';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
import {toSignal} from '@angular/core/rxjs-interop';
|
||||
|
||||
@@ -30,7 +24,6 @@ import {PreviewError} from './preview-error.component';
|
||||
imports: [PreviewError],
|
||||
})
|
||||
export class Preview {
|
||||
private readonly changeDetectorRef = inject(ChangeDetectorRef);
|
||||
private readonly domSanitizer = inject(DomSanitizer);
|
||||
private readonly nodeRuntimeSandbox = inject(NodeRuntimeSandbox);
|
||||
private readonly nodeRuntimeState = inject(NodeRuntimeState);
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
import {EnvironmentInjector, Injectable, inject} from '@angular/core';
|
||||
import sdk, {Project, ProjectFiles} from '@stackblitz/sdk';
|
||||
import {injectAsync} from '../core/services/inject-async';
|
||||
|
||||
import {injectNodeRuntimeSandbox} from './inject-node-runtime-sandbox';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -22,9 +23,7 @@ export class StackBlitzOpener {
|
||||
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 nodeRuntimeSandbox = await injectNodeRuntimeSandbox(this.environmentInjector);
|
||||
|
||||
const runtimeFiles = await nodeRuntimeSandbox.getSolutionFiles();
|
||||
|
||||
|
||||
@@ -17,10 +17,13 @@ import {
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
import {forkJoin} from 'rxjs';
|
||||
import {forkJoin, switchMap} from 'rxjs';
|
||||
|
||||
import {injectAsync} from '../../../core/services/inject-async';
|
||||
import {EmbeddedEditor, EmbeddedTutorialManager} from '../../../editor';
|
||||
import {
|
||||
EmbeddedEditor,
|
||||
injectEmbeddedTutorialManager,
|
||||
injectNodeRuntimeSandbox,
|
||||
} from '../../../editor';
|
||||
|
||||
@Component({
|
||||
selector: 'adev-code-editor',
|
||||
@@ -32,7 +35,6 @@ import {EmbeddedEditor, EmbeddedTutorialManager} from '../../../editor';
|
||||
})
|
||||
export class CodeEditorComponent implements OnInit {
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
private readonly embeddedTutorialManager = inject(EmbeddedTutorialManager);
|
||||
private readonly environmentInjector = inject(EnvironmentInjector);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
@@ -47,13 +49,18 @@ export class CodeEditorComponent implements OnInit {
|
||||
// and completed, which can lead to a memory leak if the user navigates away from
|
||||
// this component to another page.
|
||||
forkJoin([
|
||||
injectAsync(this.environmentInjector, () =>
|
||||
import('../../../editor/index').then((c) => c.NodeRuntimeSandbox),
|
||||
),
|
||||
this.embeddedTutorialManager.fetchAndSetTutorialFiles(this.tutorialFiles),
|
||||
injectNodeRuntimeSandbox(this.environmentInjector),
|
||||
injectEmbeddedTutorialManager(this.environmentInjector),
|
||||
])
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe(([nodeRuntimeSandbox]) => {
|
||||
.pipe(
|
||||
switchMap(([nodeRuntimeSandbox, embeddedTutorialManager]) =>
|
||||
embeddedTutorialManager
|
||||
.fetchAndSetTutorialFiles(this.tutorialFiles)
|
||||
.then(() => nodeRuntimeSandbox),
|
||||
),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
)
|
||||
.subscribe((nodeRuntimeSandbox) => {
|
||||
this.cdRef.markForCheck();
|
||||
nodeRuntimeSandbox.init();
|
||||
});
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {DOCUMENT, isPlatformBrowser} from '@angular/common';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
DestroyRef,
|
||||
ElementRef,
|
||||
Injector,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
PLATFORM_ID,
|
||||
ViewChild,
|
||||
afterNextRender,
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
import {WINDOW, shouldReduceMotion, isIos} from '@angular/docs';
|
||||
import {ActivatedRoute, RouterLink} from '@angular/router';
|
||||
import {from} from 'rxjs';
|
||||
|
||||
import {injectAsync} from '../../core/services/inject-async';
|
||||
|
||||
@@ -38,14 +38,14 @@ export const TUTORIALS_HOMEPAGE_DIRECTORY = 'homepage';
|
||||
styleUrls: ['./home.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
export default class Home {
|
||||
@ViewChild('home') home!: ElementRef<HTMLDivElement>;
|
||||
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly injector = inject(Injector);
|
||||
private readonly platformId = inject(PLATFORM_ID);
|
||||
private readonly window = inject(WINDOW);
|
||||
private readonly activatedRoute = inject(ActivatedRoute);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
protected readonly tutorialFiles = TUTORIALS_HOMEPAGE_DIRECTORY;
|
||||
protected readonly isUwu = 'uwu' in this.activatedRoute.snapshot.queryParams;
|
||||
@@ -53,19 +53,12 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
private homeAnimation?: HomeAnimation;
|
||||
private intersectionObserver: IntersectionObserver | undefined;
|
||||
|
||||
ctaLink = 'tutorials/learn-angular';
|
||||
ctaIosLink = 'overview';
|
||||
readonly ctaLink = isIos ? 'overview' : 'tutorials/learn-angular';
|
||||
|
||||
ngOnInit(): void {
|
||||
if (isIos) {
|
||||
this.ctaLink = this.ctaIosLink;
|
||||
}
|
||||
}
|
||||
constructor() {
|
||||
afterNextRender(() => {
|
||||
this.element = this.home.nativeElement;
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.element = this.home.nativeElement;
|
||||
|
||||
if (isPlatformBrowser(this.platformId)) {
|
||||
// Always scroll to top on home page (even for navigating back)
|
||||
this.window.scrollTo({top: 0, left: 0, behavior: 'instant'});
|
||||
|
||||
@@ -76,18 +69,13 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
if (this.isWebGLAvailable() && !shouldReduceMotion() && !this.isUwu) {
|
||||
this.loadHomeAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (isPlatformBrowser(this.platformId)) {
|
||||
this.destroyRef.onDestroy(() => {
|
||||
// Stop observing and disconnect
|
||||
this.intersectionObserver?.disconnect();
|
||||
|
||||
if (this.homeAnimation) {
|
||||
this.homeAnimation.destroy();
|
||||
}
|
||||
}
|
||||
this.homeAnimation?.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
private initIntersectionObserver(): void {
|
||||
@@ -102,9 +90,7 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.headerTop(headerEntry);
|
||||
|
||||
// Disable animation at end of page
|
||||
if (this.homeAnimation) {
|
||||
this.homeAnimation.disableEnd(footerEntry);
|
||||
}
|
||||
this.homeAnimation?.disableEnd(footerEntry);
|
||||
});
|
||||
|
||||
// Start observing
|
||||
@@ -124,12 +110,17 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
private async loadHomeAnimation() {
|
||||
this.homeAnimation = await injectAsync(this.injector, () =>
|
||||
import('./services/home-animation.service').then((c) => c.HomeAnimation),
|
||||
);
|
||||
|
||||
await this.homeAnimation.init(this.element);
|
||||
private loadHomeAnimation() {
|
||||
from(
|
||||
injectAsync(this.injector, () =>
|
||||
import('./services/home-animation.service').then((c) => c.HomeAnimation),
|
||||
),
|
||||
)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((homeAnimation) => {
|
||||
this.homeAnimation = homeAnimation;
|
||||
this.homeAnimation.init(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
private isWebGLAvailable() {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
import {RESIZE_EVENT_DELAY, WEBGL_LOADED_DELAY, WINDOW} from '@angular/docs';
|
||||
import {gsap} from 'gsap';
|
||||
import {ScrollTrigger} from 'gsap/ScrollTrigger';
|
||||
import {fromEvent} from 'rxjs';
|
||||
import {from, fromEvent} from 'rxjs';
|
||||
import {debounceTime} from 'rxjs/operators';
|
||||
import {ThemeManager} from '../../../core/services/theme-manager.service';
|
||||
import {Canvas} from '../components/canvas';
|
||||
@@ -80,7 +80,7 @@ export class HomeAnimation {
|
||||
/**
|
||||
* Initialize CSS styles, GSAP, the WebGL canvas and animations.
|
||||
*/
|
||||
async init(element: HTMLDivElement): Promise<void> {
|
||||
init(element: HTMLDivElement): void {
|
||||
this.element = element;
|
||||
|
||||
// CSS styles needed for the animation
|
||||
@@ -93,32 +93,40 @@ export class HomeAnimation {
|
||||
ignoreMobileResize: true,
|
||||
});
|
||||
|
||||
await this.initCanvas();
|
||||
this.getViews();
|
||||
// Wrap `initCanvas` in an observable to prevent executing any code,
|
||||
// such as `getViews()`, if the view is destroyed before the canvas becomes ready.
|
||||
from(this.initCanvas())
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe(() => {
|
||||
this.getViews();
|
||||
|
||||
// Call theme and resize handlers once before setting the animations
|
||||
this.onTheme();
|
||||
this.onResize();
|
||||
this.setAnimations();
|
||||
// Call theme and resize handlers once before setting the animations
|
||||
this.onTheme();
|
||||
this.onResize();
|
||||
this.setAnimations();
|
||||
|
||||
// Call update handler once before starting the animation
|
||||
this.onUpdate(0, 0, 0, 0);
|
||||
this.enable();
|
||||
// Call update handler once before starting the animation
|
||||
this.onUpdate(0, 0, 0, 0);
|
||||
this.enable();
|
||||
|
||||
// Workaround for the flash of white before the programs are ready
|
||||
setTimeout(() => {
|
||||
// Show the canvas
|
||||
this.element.classList.add(LOADED_CLASS_NAME);
|
||||
}, WEBGL_LOADED_DELAY);
|
||||
// Workaround for the flash of white before the programs are ready
|
||||
const timeoutId = setTimeout(() => {
|
||||
// Show the canvas
|
||||
this.element.classList.add(LOADED_CLASS_NAME);
|
||||
}, WEBGL_LOADED_DELAY);
|
||||
|
||||
// If the view is destroyed before the timer fires, we clean up the handle.
|
||||
// This will be a no-op if the timer has already fired.
|
||||
this.destroyRef.onDestroy(() => clearTimeout(timeoutId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the canvas controller.
|
||||
*/
|
||||
private async initCanvas(): Promise<void> {
|
||||
private initCanvas(): Promise<void[]> {
|
||||
this.canvas = new Canvas(this.document.querySelector(CANVAS)!, this.document, this.window);
|
||||
|
||||
await this.canvas.ready();
|
||||
return this.canvas.ready();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import {WINDOW} from '@angular/docs';
|
||||
|
||||
import {NodeRuntimeSandbox, EmbeddedTutorialManager} from '../../editor';
|
||||
import {EmbeddedTutorialManager} from '../../editor';
|
||||
import {NodeRuntimeSandbox} from '../../editor/node-runtime-sandbox.service';
|
||||
|
||||
import TutorialPlayground from './playground.component';
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user