`buildHeaderElement` interpolated the header into a string that is then parsed
as HTML, so markup in a header became an element instead of text. The ten
captions on https://angular.dev/guide/i18n/translation-files read
`messages.fr.xlf ()`, having turned `(<trans-unit>)` into an empty element.
These are the only two headers in the guides containing markup.
(cherry picked from commit 9073469416)
#65848 renamed `messages.fr.xlf.html` to `messages.fr.xlf` and, in the same
lines, reverted `region=` back to `visibleRegion=`, undoing #65530 from two
weeks earlier. `visibleRegion` is not read by the tokenizer, and `xlf` is not
in `REGION_MATCHERS`, so both halves of the snippet handling broke at once.
Since then https://angular.dev/guide/i18n/translation-files has shown the same
78 line file ten times where the prose describes single `<trans-unit>`
elements, and https://angular.dev/guide/i18n/manage-marked-text three times,
each carrying the `#docregion` scaffolding into the rendered code.
Mapping `xlf` to the html matcher also cleans up
https://angular.dev/guide/i18n/example, which renders the whole file on purpose
but leaked 27 marker lines into it.
`docs-code.spec.mts` already loads this fixture but only asserted the block
existed, so it stayed green throughout. It now also asserts no marker survives.
(cherry picked from commit 61b353ebee)
`docs-alert` was the only marked extension in the pipeline without a `start`
hook, so marked never cut `inlineText` short at an alert and swallowed any
directive that was not at the start of the inline source. Writing the alert on
its own line without a blank line before it left the literal text in the body.
On https://angular.dev/guide/http/testing two alerts render as boxes and a
third shows as `IMPORTANT:` in the paragraph text. Also affects
https://angular.dev/errors/NG3003 and the first step of the first app tutorial.
The same renderer handles JSDoc, so one API page changes too:
https://angular.dev/api/upgrade/static/downgradeModule has three `NOTE:`
continuation lines inside bullets that now render as alerts.
`docs-video` and `docs-pill` already declare `start` the same way.
(cherry picked from commit 4043800ef2)
`isKnownRoute` exempted both families behind TODOs waiting on route extraction
for those packages. That extraction had already landed when the TODOs were
written in #66254: cdk pages since #60853 and aria pages since the cross-repo
workflow. `defined-routes.json` carries 70 `api/cdk` and 39 `api/aria` routes
today, and all 45 such link targets in the guides resolve, so the build stays
green without the exemptions.
The gap was not theoretical. `guide/aria/select.md` and
`guide/aria/multiselect.md` linked `api/cdk/overlay/CdkConnectedOverlay`, which
has never been a route, and it shipped as a 404 for six months. Link validation
landed four months into that and said nothing, because of this exemption. It
took a user filing #68914 and an outside contributor fixing it in #68915.
Pointing an existing `api/cdk` link at a symbol that does not exist passes the
build today and fails it with this change.
(cherry picked from commit b0cda277da)
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)
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)
Two headings on the same page can generate the same anchor id, and every
link to it then resolves to whichever comes first. Nothing caught this
because the route manifest keeps anchors in a `Set`, so a repeat collapses
into one entry before any check runs, and the existing link validation only
asks whether an anchor exists, which a duplicate satisfies.
The generator now inspects each page's headings while they are still an
ordered list and fails with the offending pages and anchors. The scanning
and the duplicate check move to `heading.mts` so they are covered by tests
next to `getIdFromHeading`, which should keep this from coming back.
(cherry picked from commit 5e8a70a010)
Consolidates deindentation logic into formatCode so both docs-code and
docs-code-block are covered by a single fix. The original deindent
function incorrectly iterated over blank lines instead of non-blank
lines when computing minimum indentation, causing code blocks to render
with excessive leading whitespace. Also fixes region extraction which
had the same trim-before-deindent ordering issue.
(cherry picked from commit 7febf40e0d)
When an inline code symbol is used as the text of an explicit markdown
link (e.g. [`httpResource`](/guide/http/http-resource)), the codespan
renderer recognized it as an API symbol and wrapped it in a second
anchor pointing at the API reference. This produced nested <a> tags, so
the explicit link was effectively replaced by the API symbol link.
Disable auto-linking while rendering a link's inner tokens so the
explicit href is preserved, matching the pattern already used by the
heading and docs-card renderers.
Fixes#69549
Update the `headerRule` regex to capture the complete quoted header value. The previous pattern excluded quote characters from the content and failed to parse headers such as:
```angular-ts {avoid, header: "Can't inject interface"}
```
The new pattern matches everything between the opening and closing quote delimiters.
Follow-up to #69205. After switching adev's COEP to `credentialless`, the
cross-origin YouTube iframe in `<docs-video>` loads in Chromium and Safari but
not Firefox, whose `credentialless` policy does not extend to nested frames. The
result was a COEP error screen instead of the player.
Render `<docs-video>` as a lightweight thumbnail facade instead of embedding the
iframe directly. The thumbnail is a cross-origin subresource, so it loads under
`credentialless` in every browser. `DocViewer` then upgrades the facade to the
inline player on hydration in browsers that can load the embed (Chromium,
Safari), preserving the previous behavior there. On Firefox the facade stays a
plain link that opens the video on YouTube (with autoplay), which replaces the
error screen.
The thumbnail uses `maxresdefault` and falls back to `hqdefault` when a video
has no max-resolution image.
Add required, pattern, min, max, minLength and maxLength to LINK_EXEMPT
so FieldState property names stop auto-linking to the validator
functions of the same name.
Updates the Playground card copy and adds a `titleInline` attribute on
<docs-card> so the icon and title sit on the same row. Existing cards
are unaffected.
This commit extracts the heading ID generation logic into a shared utility
and updates both the route generation script and the markdown pipeline to use it.
This ensures consistency between the generated routes and the rendered
documentation, and fixes an issue where custom heading IDs (`{#id}`)
were ignored during route generation.
Fixes#67200
The tokenizer regex pattern `[^<]*` was consuming all non-`<` content
before custom HTML tags, causing lost content.
Changed to `\s*` which only allows leading whitespace, letting marked
properly tokenize preceding content.
Previously our system only found the first matching symboling to link to within a code block on each line, now we set up a link for all of the discovered symbols on each line
Fixes#65403
The list of valid links is generated from navigation data configuration in the ADEV app.
Redirections are knowingly exclude so we stop referencing them.
Adds the ability to hide the copy button on code snippets.
Updates documentation to use the new `hideCopy` option with the new
markdown code fence syntax.
Previously we extracted the regions and only made the visible region visible on the page, but since there is not a need for the
non-visible code to be presented, we don't need to include it in the generated code snippets.
Move the header id tracking into the renderer context rather than a global state. Since the RendererContext is
initialized for each execution of the marked parser, we can store the context of which header ids have been seen within
a single page there which allows us to run these parse interactions in parallel.
Rather than manually calling the transformer we use for headings from within a render function, we now properly call into the Renderer to do them
via the tokens they are require instead. This is being done to allow us to have a per Renderer instance of state instead of a global state, which will
allow us to run marked async and hopefully speed up the pipeline
Improves the symbol linking logic to handle Angular component selectors (e.g., ngCombobox). It attempts to convert Angular selector patterns to their corresponding class names, improving navigation to Angular API documentation.
Migrate docs-alert to be inline instead of block, this ensures that the content is placed within a <p> tag as expected. This is important
for ensuring that the iconography is placed correctly within the wrapper div generated for the alert. Additionally, we refactor the matcher
code to be more efficient, running with fewer loops.