When navigation items contain external URLs (e.g. https:// links for documentation or third-party resources), mapNavigationItemsToRoutes previously registered them as Angular Router route definitions. In recent versions of @angular/build, the static prerender worker asserts that discovered routes do not return empty content during SSG prerendering, causing production builds and CI adev-deploy to fail on these routes.
This change filters out external links in mapNavigationItemsToRoutes so only valid internal application paths are registered as Angular routes.
(cherry picked from commit 502fa130aa)
When an abstract base class has something like a lifecycle hook, Angular
compiles it as a directive with no selector. If a pipe extends that base
class, the pipe picks up the base class's directive definition through
normal class inheritance.
The NgModule dev-mode checks then got confused by that inherited
definition and reported the pipe as a broken directive:
- "Directive SomePipe has no selector, please add it!"
- or, if the base class was a default (standalone) abstract directive,
"SomePipe is marked as standalone and can't be declared..."
Both only happened in tests (TestBed), not when running the app.
Now the selector check and the standalone check both look at the pipe's
own definition and ignore a directive definition that only came from a
base class.
Fixes#36427
(cherry picked from commit 58d536bc83)
Make the SVG animation security context depend on the tag name instead of the namespace the element was created in. An animation element declared outside an `<svg>` is created in the HTML namespace, but still animates once it ends up inside an SVG subtree, so to and `attributeName` bindings were reaching the DOM unvalidated.
Fixes #70490
(cherry picked from commit 7168bed663)
Preserve hasUAVisualTransition through Location and the Router navigation pipeline. This prevents withViewTransitions from starting an author transition after the browser has already performed one, including across redirects and when using experimental platform navigation.
(cherry picked from commit af26a8c521)
In recent conventional-changelog version updates, the underlying
@conventional-changelog/git-client dropped support for the raw `grep` and
`extendedRegexp` options, causing all monorepo commits to be included in the
zone.js changelog. Additionally, without `tagPrefix: 'zone.js-'`, conventional-changelog
treated monorepo release tags as release boundaries, generating changelog sections
for every intermediate monorepo release.
This change:
- Configures `tagPrefix: 'zone.js-'` and filters commits by `scope === 'zone.js'`
via `writerOpts.transform` in the gulp changelog task.
- Fixes the PR creation link in the release script to use the cross-fork
compare URL format on GitHub.
- Fixes the release commit SHA lookup in `cutReleaseWorkflow`.
- Updates zone.js release documentation.
(cherry picked from commit cd771174b9)
Two tutorial steps list a file in `openFiles` that does not exist, and a
missing entry is dropped without complaint. `first-app/05-inputs` asks for
`housinglocations.ts` when the file is `housinglocation.ts`; since
`hiddenFiles` is everything not in `openFiles`, the interface that step
teaches was marked hidden rather than opened.
`signals/5-component-communication-with-signals` asks for
`quantity-selector.ts`, which exists in neither `src` nor `answer`. Every
openFiles entry in the tutorials now resolves.
(cherry picked from commit 45148dae44)
The code block lives inside `@if (showCode())`, so hiding it destroys the DOM and
showing it builds a fresh copy with no hidden lines. Nothing reapplied
`setCodeLinesVisibility()`, so a collapsed block came back showing the whole file.
Reapply it once the block is rendered again. It already branches on `expanded()`,
so a block that was expanded stays expanded.
(cherry picked from commit 90b9e081f5)
`reactive-forms` and `form-validation` were excluded from `embeddable` in
full, with a TODO to fix them. The examples are fine; four partial snapshots
quoted by the guides are not, since each shares the final template of the
component it precedes, which references members it does not have yet.
Excluding those four files clears all 30 errors and puts 23 app files back in
the preview pool, so both guides' final components can be previewed for the
first time.
(cherry picked from commit 431b170fd5)
The block quotes a `.ts` file but declares `language="html"`, and shiki's
HTML grammar does not know Angular control flow, so the whole `@for` line
renders unstyled. Use `angular-ts`, matching the other blocks in the
tutorial.
(cherry picked from commit c03e872ed9)
The TextMate grammars for inline templates and inline styles ended the
string at the first occurrence of the delimiter, so an escaped delimiter
(e.g. \`) terminated the highlighting prematurely and the rest of the
template was no longer highlighted as HTML.
Escape sequences are now consumed before delegating to the HTML/CSS
grammars, so escaped delimiters no longer end the string. Also removes
the stray pipes from the string delimiter character class, which
unintentionally matched a literal '|'.
Fixes#65493
(cherry picked from commit 1d9e445d1a)
Extended template diagnostic interpolated_signal_not_invoked previously
only checked symbols with kind === SymbolKind.Expression. When a signal
is aliased via @let (or a template variable), getSymbolOfNode returns
a LetDeclarationSymbol (or VariableSymbol), causing the diagnostic to
skip checking uninvoked usages of signal aliases in interpolations and
bindings.
This commit updates interpolated_signal_not_invoked to also check
LetDeclarationSymbol and VariableSymbol, using the usage site's AST
name span for reporting the diagnostic.
Closes#70476
(cherry picked from commit faafd18a4c)
Three ways a callout could be misparsed:
- A title quoted with `'` or a backtick was dropped, leaving an empty
heading. Two callouts lose their title on angular.dev today, on
guide/forms/template-driven-forms and guide/i18n/prepare. The first has
to use single quotes because its title contains `"pristine"`.
- A title containing `>` was dropped, because the attribute capture
stopped at the first `>` even inside a quoted value.
- The severity was matched anywhere in the tag, so a title such as
"Why this is important" silently rendered an important callout.
Scan attributes with quoting in mind, accept all three quote characters
as #69268 did for docs-code-block, and match the severity flags against
the tag with attribute values removed. The i18n callout also spelled the
attribute `header`, which the extension has never read.
(cherry picked from commit b70edd2768)
`input.svg` and `output.svg` are leftovers that #70335 missed. Their
last reference was deleted by #54829 when the AIO guides were removed,
and nothing in the repo mentions them or their directory. Removing both
empties `adev/src/assets/images/guide/inputs-outputs`.
(cherry picked from commit a92f6057d3)
Replaces the temporary `promiseWithResolvers` polyfill with the
native `Promise.withResolvers()` API in test files and Updates the TypeScript configuration to include the `es2024.promise`.
(cherry picked from commit b5ce15c659)
RESOURCE_COMPLETED_BEFORE_PRODUCING_VALUE had no guide, no JSDoc on
RxResourceOptions.stream, and — since the code was positive rather
than negative — could never get an auto-linked docs page even if one
existed. Flip it to -991, add the NG0991 reference page, and document
the "stream must emit a value or an error before completing"
requirement on stream's JSDoc and in the RxJS interop guide.
Also documents and tests that an unguarded template read of an
errored resource's .value() propagates to the global ErrorHandler,
and recommends guarding with .hasValue() as defense in depth.
httpResource can throw the same error, but for a different reason:
its internal request Observable isn't something app code writes
directly, so an empty completion there is almost always an
HttpInterceptor swallowing the response (catchError(() => EMPTY))
rather than a stream authored in the resource() call itself. The page
covers both APIs with guidance matched to what's actually going on
for each.
(cherry picked from commit 8975b4346d)
There's a short window where Angular can't send errors to ErrorHandler
yet: while it's still building the root module or root component. It
needs that root instance to look up the ErrorHandler you provided, so
an error thrown before it exists just becomes a normal uncaught error
instead.
This mostly bites people using Angular elements, where a custom element
tag already sitting in the page gets upgraded (and its component built)
the moment you call customElements.define, which can happen very early.
Added a short section to the error handling guide explaining why this
happens and the usual ways around it: setTimeout, APP_BOOTSTRAP_LISTENER,
or moving element registration to ngDoBootstrap.
Fixes#29211
(cherry picked from commit ca38305976)
Associate each recommendation with its checkbox so assistive technology has a descriptive label and non-interactive text toggles the control. Keep embedded links independently operable.
(cherry picked from commit d8e74e7d39)
Only touch tsconfig files for targets that use an Angular builder, including community ones like Nx, so non-Angular projects in mixed workspaces are left alone.
Fixes#69837
(cherry picked from commit f72600eadd)
`copyEventListenerOptions` copied the caller's options with `{...options}`
before forwarding to the native `addEventListener`. Object spread only
copies own enumerable data properties, whereas the native call reads
each dictionary member via WebIDL — a plain `[[Get]]` per member, which
invokes accessors and ignores enumerability. The copy was therefore
lossy in a way the native call is not:
- `Object.defineProperty(opts, 'passive', { get })` (the shape used by
MDN's passive-listener feature test) — the getter was never invoked,
so libraries that use the feature test fall back to the legacy boolean
and register every listener as non-passive.
- `Object.defineProperty(opts, 'capture', { get: () => true })` — the
listener was silently registered on the bubbling phase.
- `Object.defineProperty(opts, 'once', { get: () => true })` — the
listener fired on every dispatch.
`signal` was already special-cased for `AbortController.prototype.signal`
after #54142; that patch generalises the workaround to every recognised
member.
The copy itself was the correct fix for #54142 (frozen/readonly options)
and is preserved. The fix reads each recognised member from the source
via `[[Get]]` when the spread did not, which recovers accessors and
non-enumerable properties without double-invoking any getter. The list
of recognised members is hoisted to module scope so it isn't allocated
on every `patchEventTarget` invocation.
The call site is reordered to `buildEventListenerOptions(
copyEventListenerOptions(...))` so the passive-events code path also
spreads a normalised data object rather than the caller's raw input.
Fixes#70431
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
(cherry picked from commit 4c4a705ce3)
The debounce() utility scheduled a setTimeout when using a numeric wait value, but the scheduled timer was never cleared when a new value arrived, the observable threw, or the injector was destroyed. This caused pending timers to fire after invalidation and leak beyond the owner's lifecycle.
Refactor timer cancellation into a dedicated helper and track the pending timer id so any stale timer is cleared on new values or teardown. Adds tests covering cancellation on new values, errors, and injector destruction.
(cherry picked from commit 0904f90b13)
Under the WHATWG URL standard, HTTP and HTTPS URLs lacking an authority
(e.g., `http:/path` or `http:path`) resolve as relative paths when resolved
against an origin of the same scheme. Previously, `relativeUrlsTransformerInterceptorFn`
treated any URL with a scheme as an absolute URL, bypassing base resolution in SSR
and allowing Node fetch to parse the path as a cross-origin host.
This commit updates SSR URL resolution and the HTTP interceptor to ensure
HTTP(S) URLs without an authority are resolved against the current origin,
preventing unexpected origin changes and aligning SSR with browser behavior.
Fixes#70447
(cherry picked from commit b3bb36ad87)
Fixes that signal forms were overridding the `name` input of the CVA with an auto-generated one. This can break directives like `mat-radio` that assign their own `name`.
Fixes#69677.
(cherry picked from commit 38861ac41b)
The 34 pages using `<docs-decorative-header>` render their title
through `getPageTitle()` without passing the markdown file path, so
the "Edit this page" link is silently dropped. Every other page keeps
it. Compare https://v19.angular.dev/guide/components, which still has
the pencil, against https://angular.dev/guide/components, which does
not.
`filePath` was required until #63536 made it optional, so API
descriptions with no editable source could render a title without a
link. That removed the compile error forcing the decorative header to
supply it, and the argument was lost with nothing to catch it.
Pass the path again and cover both header variants with tests, since
the edit link had no coverage at all.
(cherry picked from commit acdac1cb89)
An unclosed `<docs-step>` or `<docs-card>` produces no error, just wrong
output, so the two cases fixed in the previous commit went unnoticed for
years.
Validate that the paired custom elements balance before parsing. A
mismatch now names the file and the counts instead of silently
swallowing a section.
(cherry picked from commit d9afca095b)
`reactive-forms.md` and `app-shell.md` each open a `<docs-step>` that is
never closed. The tokenizers match up to the *next* closing tag instead
of failing, so the unclosed tag pulls in the content that follows and
leaves the block after it unparsed in the output.
On https://angular.dev/guide/forms/reactive-forms the "Creating nested
form groups" section shows raw source: "To create a nested group in
`profileForm`, add a nested `address` element", backticks and all. Its
heading is swallowed into the unclosed step instead of being an h3, and
the page renders 20 of its 21 steps. On
https://angular.dev/ecosystem/service-workers/app-shell the third step
is missing entirely.
`reactive-forms.md` has been broken since #52536, `app-shell.md` since
#55550.
(cherry picked from commit 0752282c8f)
The tutorial's example files shifted without the README line references
following, so several steps point at the wrong code. In two cases every
requested line is past the end of the file; on the inputs step this renders
as a code block with no lines visible at all.
(cherry picked from commit 46b02cc181)
Both indices point past the end of their block, so the intended lines are
never highlighted. The reactive forms block renders with no highlight at all,
and the first example in output-interop.md highlights nothing while its
sibling block is unaffected.
(cherry picked from commit cd3c8cdd3a)
bluebirdjs.com no longer resolves. npm lists the GitHub repo as the package's
homepage, so the link now goes there.
(cherry picked from commit 731c838dbb)
The fork guide link 404s since GitHub retired help.github.com, and the
rules_nodejs debugging docs moved to the bazel-contrib org. Also points the
git setup link straight at its current home rather than through a redirect.
(cherry picked from commit 519c52eea0)
jsperf.com now returns 410 for every benchmark. Two of them still exist on the
successor site and are repointed at jsperf.app; the other five are gone, so the
links are removed and the performance claims they backed are kept.
(cherry picked from commit 2a4903fec1)
help.github.com/ignore-files/ 404s since GitHub retired that domain. Five of the
files still linked to it over plain http as well.
(cherry picked from commit 1e8dd80458)
Foreign components imported via foreignImports and created by the
ɵɵforeignComponent instruction were previously rendered eagerly in the
creation phase (rf & 1) of the template. This restricted which
properties could be passed to foreign component props, as parent-bound
inputs (@Input(), input(), input.required()), properties initialized in
ngOnInit(), and pull-based view queries (viewChild()) were not yet
initialized at creation time.
This change defers foreign component rendering to run as a view effect
during the update pass:
- Update ɵɵforeignComponent in core to schedule component rendering via
createViewEffect (executed in runEffectsInView during refreshView),
executed with setActiveConsumer(null) to prevent reactive context
leakage and destroyed immediately upon first execution.
- Update ɵɵforeignComponent to strictly accept props as a factory function
(() => props) or null.
- Update the compiler template pipeline to wrap foreign component props
in an arrow function closure (() => ({ ... })).
- Hoist creation-time foreign content projection instructions
(ɵɵforeignContent, ɵɵforeignContentFn) into creation-phase variable
declarations before ɵɵforeignComponent so creation-time context is
captured safely.
(cherry picked from commit 34817da735)
The common tutorial scaffold's .gitignore opens with a link to
help.github.com/ignore-files/, which 404s. That directory is copied into every
tutorial and playground, so the dead link ships to anyone who opens one.
(cherry picked from commit 843a65cba0)