feat(inlines): support [[[SPEC#id]]] for cross-spec section links#5146
feat(inlines): support [[[SPEC#id]]] for cross-spec section links#5146marcoscaceres wants to merge 5 commits intomainfrom
Conversation
02aca58 to
ca4f622
Compare
There was a problem hiding this comment.
Pull request overview
Extends ReSpec’s [[[...]]] inline expansion parsing so authors can cite a spec and link directly to a section using a fragment (e.g., [[[fetch#data-fetch]]]), leveraging existing data-cite fragment handling.
Changes:
- Updated the
[[[...]]]inline-expansion regex to allow an optional#fragmentsuffix. - Added a unit test asserting that
[[[fetch#data-fetch]]]resolves to the spec URL with the fragment and uses the spec title as link text.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/core/inlines.js |
Broadens inlineExpansion matching to include SPEC#fragment forms. |
tests/spec/core/inlines-spec.js |
Adds coverage for cross-spec section linking via [[[SPEC#id]]]. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@sidvishnoi Good point. The spec title alone isn't useful for section-level links. The intended behavior for The data for this is available in w3c/webref's headings data. I've opened speced/respec-web-services#469 to add a Holding this PR until the headings API is available and the inlines.js expansion can use real heading text. Will also add alias support ( |
Extends the inline expansion regex to allow [[[SPEC#fragment-id]]], e.g. [[[fetch#data-fetch]]]. The result is a link to that spec's specific section (href resolved via the existing data-cite machinery), with the spec title as the link text. Existing [[[SPEC]]] and [[[#local-id]]] syntax is unchanged.
Tighten the inlineExpansion regex to use explicit alternation: - [[[#id]]] — in-doc fragment (starts with #, no second #) - [[[SPEC]]] or [[[SPEC#id]]] — cross-spec (no leading #) Previously, #?[\w-.]+(?:#[\w-.]+)? allowed [[[#foo#bar]]] to match, which would produce an invalid URL fragment. Adds a test for this case.
[[[SPEC#id]]] now displays the actual section heading text (e.g., '§ 3.1.1 Cookie header') instead of just the spec title. Heading text is fetched from POST /xref/headings/ (speced/respec-web-services#469). Also adds alias support: [[[SPEC#id|custom text]]] uses the custom text as link text, skipping the heading lookup. Fallback chain: alias → heading text → spec title → raw ref. Changes: - inlines.js: regex updated for pipe alias, inlineRefMatches stores alias as data-lt - data-cite.js: batch-fetches headings for cross-spec links, formats as '§ NUMBER TITLE' with spec title in a cite element
2de2f1e to
da52313
Compare
…al var instead of dataset Self-review fixes: - Remove unused headingElements map - Cache toCiteDetails results to avoid calling twice per element - Use local headingSpecTitle var instead of dataset for temp storage - Guard heading lookup with frag check to avoid undefined key
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const citeDetailsMap = new Map(); | ||
| const headingQueries = []; | ||
| for (const elem of elems) { |
There was a problem hiding this comment.
headingElements is declared but never used. Please remove it (and the corresponding .set(...)) or use it for its intended purpose (e.g., deduping queries / mapping results back to elements) to avoid dead code and potential lint failures.
| // Collect elements that need heading text (triple-bracket cross-spec links) | ||
| if ( | ||
| elem.localName === "a" && | ||
| elem.textContent === "" && | ||
| !elem.dataset.lt && |
There was a problem hiding this comment.
This heading-fetching branch triggers for any empty <a data-cite> with a fragment (not just [[[...]]] expansions). That changes the output semantics of existing markup like <a data-cite="fetch#foo"></a> by attempting to replace link text based on a remote headings API. Consider scoping this to the new triple-bracket feature (e.g., require data-matched-text to be present / start with [[[), or gating it behind an explicit config option.
| // Use heading text for cross-spec section links | ||
| let headingSpecTitle = null; | ||
| if (citeDetails.frag && elem.textContent === "") { | ||
| const spec = citeDetails.key.replace(/^[!?]/, "").toLowerCase(); | ||
| const id = citeDetails.frag.replace("#", ""); | ||
| const heading = headings.get(`${spec}#${id}`); | ||
| if (heading) { | ||
| const secNum = heading.number ? `§\u00A0${heading.number} ` : "§ "; | ||
| elem.textContent = `${secNum}${heading.title}`; | ||
| headingSpecTitle = heading.specTitle; | ||
| } | ||
| } | ||
| linkElem(elem, linkProps, citeDetails); | ||
| // Add spec title cite element for heading links | ||
| if (headingSpecTitle) { | ||
| const cite = document.createElement("cite"); | ||
| cite.textContent = headingSpecTitle; | ||
| elem.before(cite); | ||
| cite.after(" "); | ||
| } |
There was a problem hiding this comment.
When a heading is found, this overwrites the anchor’s text (e.g., to § …) instead of the spec title. That conflicts with the PR description and the new test in tests/spec/core/inlines-spec.js which expects [[[fetch#data-fetch]]] to have link text Fetch Standard. Either adjust the behavior to keep spec-title link text (and just append #fragment), or update tests/docs and ensure the output is stable (doesn’t depend on network/API availability).
| // Use heading text for cross-spec section links | |
| let headingSpecTitle = null; | |
| if (citeDetails.frag && elem.textContent === "") { | |
| const spec = citeDetails.key.replace(/^[!?]/, "").toLowerCase(); | |
| const id = citeDetails.frag.replace("#", ""); | |
| const heading = headings.get(`${spec}#${id}`); | |
| if (heading) { | |
| const secNum = heading.number ? `§\u00A0${heading.number} ` : "§ "; | |
| elem.textContent = `${secNum}${heading.title}`; | |
| headingSpecTitle = heading.specTitle; | |
| } | |
| } | |
| linkElem(elem, linkProps, citeDetails); | |
| // Add spec title cite element for heading links | |
| if (headingSpecTitle) { | |
| const cite = document.createElement("cite"); | |
| cite.textContent = headingSpecTitle; | |
| elem.before(cite); | |
| cite.after(" "); | |
| } | |
| linkElem(elem, linkProps, citeDetails); |
| cite.textContent = headingSpecTitle; | ||
| elem.before(cite); | ||
| cite.after(" "); | ||
| } | ||
| } else { |
There was a problem hiding this comment.
Inserting a separate <cite> node as a sibling before the anchor changes the DOM shape of inline expansions (from a single link to two nodes). If the intended output is just a link to SPEC#fragment (per PR description), this should be removed; otherwise, the expected structure should be documented and covered by tests since it can affect styling/screen-reader output.
| it("links to specific section of another spec using [[[SPEC#id]]] syntax", async () => { | ||
| const config = { | ||
| localBiblio: { | ||
| fetch: { |
There was a problem hiding this comment.
New parsing supports [[[...|text]]] (including [[[SPEC#id|text]]]), but there’s no test coverage confirming that the custom link text is preserved for these triple-bracket expansions. Add at least one assertion for [[[fetch#data-fetch|Custom]]] (and/or [[[fetch|Custom]]]) so regressions in data-lt handling are caught.
…syntax Tests for: - Cross-spec alias: [[[fetch#data-fetch|fetching data]]] uses custom text - Cross-spec without alias: falls back to spec title (headings API not deployed) - In-document alias: [[[#section|see this]]] uses custom text
Summary
[[[...]]]inline expansion syntax to allow[[[SPEC#fragment]]]#fragmentappended[[[fetch#data-fetch]]]→ link to the Fetch spec's#data-fetchsection, with link text taken from the spec titleTest plan
pnpm test:unit[[[fetch#data-fetch]]]produces a link tohttps://fetch.spec.whatwg.org/#data-fetch