Store the trigger kind before each switch and assign the value to `never` in the fallback branch.
This removes the `any` casts and makes the switches exhaustive. Adding a new `DeferTriggerKind` without handling it in either phase now produces a TypeScript compilation error.
Runtime behavior and error messages remain unchanged.
The angle-guessing minigame's result popup personifies your score with a
hand-drawn stick-figure that changes expression by accuracy. Now that Angie
appears across adev — the 404 page, docs search, the embedded editor, the
tutorial intros and completions — give the minigame the same treatment so
its result feels consistent with the rest of the docs.
Replace the result reactor's stick-figure illustration with an Angie pose
keyed to accuracy (seven tiers, superhero down to angry). She is revealed
once the accuracy counter finishes counting up, popping in beside a speech
bubble that carries the round's existing quote. The result popup is widened
so Angie and the bubble sit side by side, and the share link is moved from
twitter.com to x.com.
This removes the previous hand-drawn stick-figure result art. NG the Angle,
the interactive character in the play area, is unchanged.
Previously, the `pending()` status on a field's `ValidationState` only checked if the field itself or its immediate children had a pending asynchronous validator by directly inspecting `asyncErrors()`. This meant that a pending asynchronous validator deep within a nested form (e.g. on a grand-child) would not correctly bubble the `pending` state up to the root form.
fixes#69840
Adds a compliance case pinning the instruction-set selection for a
directive-free standalone component:
- full compile: the compiler can prove the template has no directive
dependencies, so it takes the DOM-only fast path
(`ɵɵdomElementStart`/`ɵɵdomElementEnd`).
- local compile: the compiler cannot inspect dependencies, so
`hasDirectiveDependencies` is forced true and the full instruction
set is emitted (`ɵɵelementStart`/`ɵɵelementEnd`).
This mode-dependent switch was previously only exercised incidentally by
the `foreign_component` case, which couples it with foreign-component
compilation. The new case isolates it.
Currently, the SVG sanitizer checks a static set of candidate attribute
names (`attributeName` and `attributename`). This approach misses other case
variations (such as `attributenAme` or others), which could potentially
bypass sanitization when binding sensitive attributes like `href` on
`<set>` or `<animate>` elements.
This change retrieves all attribute names of the SVG element, performs a
case-insensitive comparison with `'attributename'`, and sanitizes the value
if a match is found.
The tutorial intro and "next steps" pages were plain headings with no
send-off. Bookend each tutorial with Angie: a greeting pose welcoming
learners on the intro page, and a superhero pose congratulating them on
the completion page, each beside a speech bubble.
The bubble treatment from the 404 page lived inside the not-found
component, so it's extracted into a reusable docs-content style
(docs-tutorial-mascot) usable from tutorial markdown, and applied to the
intro and completion pages of the Learn Angular, Signals, and Signal
Forms tutorials.
When only some NgClass usages are migrated (partial migration),
the NgClass import should be preserved in the module/component
imports if it is still used elsewhere.
The "Page Not Found" page always rendered the sentence "We have
initiated a search for the term extracted from the URL", but the
NotFound component only runs a search when a term can be extracted,
and only renders results when there is at least one hit. On a 404
with no extractable term or no matching results, the page asserted
a search it never backed up.
Gate the sentence behind the same searchResults() check that guards
the results list, so the empty state simply reads "We couldn't find
what you were looking for."
`makeCacheKey` joined the request fields with `|` before hashing. The url
and the serialized body can contain `|` themselves, so a shifted field
boundary (url `/items/a` + body `b|c` vs url `/items/a|b` + body `c`)
produced the same joined string and the same key, letting two distinct
requests share a transfer cache slot.
Join with `\0` instead, which cannot occur in a valid url or in encoded
params, so the field boundaries cannot be forged by field content.
The Angie illustrations on the DevTools empty-state screens (added in
#69786) shipped with an empty `alt` and `aria-hidden="true"`. Give them
descriptive alt text and drop `aria-hidden` to improve accessibility.
The MCP server setup guide linked to /ai/skills, which 404s. The
page lives at /ai/agent-skills. Update the link to point to the
correct route.
Fixes#69838
The Transfer State and signal-graph tabs render bare-text placeholders
when there's nothing to show. Add the Angie mascot to both, matching the
pattern already shipped on the top-level DevTools screens (#69786):
- Transfer State "isn't using Transfer State" card: replace the
swap_horiz icon with the teaching pose.
- Signal graph "No signals in this component": add the orthos-back pose
above the message.
The `inlineStyleLanguage` build option has existed since v12 but was
never listed in the workspace configuration reference. Add it to the
"Extra build and test options" table alongside the other style options,
documenting its accepted values (css, less, sass, scss) and default.
Fixes#69801
Interpolating GitHub context values directly into `run:` steps creates
an expression-injection vector. Move the affected values into an `env:`
block and reference them as environment variables in the shell script
instead. This prevents shell metacharacters in context values from
altering step behaviour.
Signed-off-by: El Mehdi Abenhazou <mehdiananas007@gmail.com>
Bind spyOn explicitly to Window so Jasmine uses the DOM setTimeout signature that returns a number instead of the Node.js Timeout type. Remove the unsafe any cast and the obsolete TODO.
The DevTools state screens (Angular not detected, unsupported version,
production build) showed a plain Material icon above the message. Show
the Angie mascot instead, matching the treatment already used across
angular.dev (the 404 page, empty search, the preview error state).
Each screen uses a pose that fits its message: the dizzy `error` pose for
"application not detected", `coding-01` for the version-upgrade prompt,
and `sad` for the production build notice.
If a directive has an input declared as `dismissible = input<boolean>(true, {transform: booleanAttribute});` then the following templates were not compiling:
```
<div directiveName dismissible="true"></div>
<div directiveName dismissible></div>
```
This commit fixes the issue, without breaking contravariant consumers.
The NAMED_FORMATS and DATE_FORMATS caches were plain objects read with a
truthy check keyed by a token from the format string, so a token matching
an inherited Object member (e.g. `__proto__`) resolved to a prototype
value. Create both caches with a null prototype so only real entries are
returned.
Native text `<input type="text">` controls do not support `null` values.
When a Signal Forms model bound to a text input is set to `null`, the value
is silently coerced to an empty string.
Updates the template parser to detect and ignore processing instruction syntax (e.g. `<? foo ?>` or `<? foo >`). Currently it is being printed out as text.
Fixes#34371.
The cookie consent popup showed only text and two buttons. Add the
Angie greeting pose to it so the first thing a new visitor sees carries
the same mascot treatment already used across the docs (the 404 page,
empty search results, the preview error state).
The message and mascot sit in a flex header row; the two action buttons
now share the row equally so they fill the card instead of leaving a
trailing gap. Layout only, the consent behaviour is unchanged.
Move the DebugSignalGraph, DebugSignalGraphEdge, and DebugSignalGraphNode interfaces from packages/core/src/render3/util/signal_debug.ts into the packages/core/primitives/devtools/src package. This decouples the signal graph debug types from runtime render3 utilities and allows devtools and internal core tooling to import them directly from primitives as type-only exports.
Replace the lazy quantifier (.+?) with a negated character class
([^\s*]+) that excludes whitespace and asterisks. Source map URLs
never contain these characters, so the fix is semantically
equivalent while eliminating the O(n²) backtracking path triggered
by unclosed /*# sourceMappingURL= fragments.
Fixes: polynomial ReDoS in addBaseHrefToCssSourceMap
When `HttpClient` is called from within an `effect()` or other reactive
context, any signal reads performed inside HTTP interceptors were
inadvertently tracked by that context. This caused the effect to
re-execute whenever those signals changed, regardless of whether the
signal was semantically related to the HTTP call.
The fix wraps the interceptor chain invocation in `untracked()` so that
signal reads inside interceptors — both functional (`withInterceptors`)
and class-based (`withInterceptorsFromDi`) — are invisible to the
calling reactive context. This matches the precedent set by the resource
API, which also wraps its loader in `untracked()` for the same reason.
Fixes#58682