Repository navigation
feat(core/dfn-panel): show linking terms in panel - #5251
marcoscaceres wants to merge 12 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds visibility into a definition’s alternate “linking terms” (from data-lt) by rendering them in the DFN panel, addressing the usability request in #3741.
Changes:
- Render a “Linking terms:” line in the DFN panel when
data-ltis present and contains aliases beyond the DFN’s own text. - Normalize/dedupe
data-ltvalues for display and omit the term matching the DFN’s text content. - Add a spec test covering presence/absence and whitespace normalization behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/core/dfn-panel.js |
Adds linkingTermsToHTML() and injects linking-term display into the panel markup. |
tests/spec/core/dfn-panel-spec.js |
Adds coverage ensuring linking terms appear only when appropriate and handle trimming/deduping. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
13771de to
6cf689e
Compare
marcoscaceres
left a comment
There was a problem hiding this comment.
I'm pretty happy with where this ended up.
| if ((dfnType === "element-attr" || dfnType === "attr-value") && dfnFor) { | ||
| return `[^${dfnFor}/${term}^]`; | ||
| } |
There was a problem hiding this comment.
If we've dfnFor with other case (element), that should be a warning then? Do we need to special case it here?
There was a problem hiding this comment.
Fair question. I tried [^blink^] and [^html/blink^] for an element definition with a data-dfn-for, and neither links. The panel now lists nothing for an element with a for, and the special case is gone. A warning for authors belongs in the definition code, not in this pull request.
| const btn = | ||
| target instanceof HTMLElement && target.closest(".dfn-panel-copy-btn"); | ||
| if (!(btn instanceof HTMLElement)) return; | ||
| const text = btn.dataset.copyText; |
There was a problem hiding this comment.
Should we grab the textContent (of previous sibling) instead of duplicating text to button?
There was a problem hiding this comment.
Done. The button no longer carries data-copy-text, and the runtime copies the text of the code element before the button. The doc comment on createSyntaxCopyButton says the button has to follow the code element.
| setupCopyButtons(); | ||
| } | ||
|
|
||
| function setupCopyButtons() { |
There was a problem hiding this comment.
How about using core/clipboard.js? It has a SVG icon for copy as well.
There was a problem hiding this comment.
The copy icon now comes from core/clipboard.js, which exports COPY_SVG. I did not reuse createCopyButton. That function builds the code-block button: 40 by 28 pixels, absolutely positioned, tied to a header selector. The exporter also strips that button from exported specs. The panel's buttons must stay in exported specs and copy a string. The runtime keeps its own click handler, because the handler ships inside the exported page.
| )} | ||
| </ul>`; | ||
| ></button>`; | ||
| button.innerHTML = COPY_SVG; |
There was a problem hiding this comment.
Optimization: Add the COPY_SVG once to page as a <symbol>; then reuse it with <use>, so we don't bloat generated HTML. Was less important before with few code blocks, now there's manifold increase.
There was a problem hiding this comment.
Done. The page now holds one <symbol> in a hidden SVG, and every button points at the symbol with <use>. The sprite appears only when some panel lists syntaxes. On my test page of 93 definitions, the exported file went from 175,475 bytes (an SVG in every button) to 143,307 bytes.
| aria-label="Copy ${text} to clipboard" | ||
| title="Copy to clipboard" |
There was a problem hiding this comment.
Some screen readers will announce both aria-label and title when they differ. Either make them same, or remove title (safer).
There was a problem hiding this comment.
Removed both title and aria-label. The button name now comes from the text inside the button: "Copy" plus the syntax.
|
|
||
| const COPY_SVG = | ||
| export const COPY_SVG = | ||
| '<svg height="16" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3 3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H3c-.55 0-1 .45-1 1z"/></svg>'; |
There was a problem hiding this comment.
Please mark this SVG as aria-hidden, otherwise it can show like: button [copy to clipboard] > image
There was a problem hiding this comment.
Added aria-hidden="true" to COPY_SVG, so the code-block buttons get the attribute too. The icons in the panel have the attribute as well.
| if (!btn) return; | ||
| const text = btn.previousElementSibling?.textContent; | ||
| if (!text) return; | ||
| navigator.clipboard?.writeText(text).catch(() => {}); |
There was a problem hiding this comment.
Let's add btn.ariaNotify("Copied") as well. Ideally, we should update icon, but let's do this as well.
There was a problem hiding this comment.
Added. After a successful copy, the button calls ariaNotify("Copied"). Browsers without ariaNotify skip the call, and a failed copy announces nothing. Chrome has the method. I did not check Safari or Firefox.
| html`<li> | ||
| <code>${syntax}</code> ${createSyntaxCopyButton(syntax)} | ||
| </li>` |
There was a problem hiding this comment.
Have you considered this markup?
<li>
<button type="button">
<span class="visually-hidden">Copy </span><code>${term}</code>
<svg aria-hidden="true" …></svg>
</button>
</li>There was a problem hiding this comment.
I took the markup from your comment. Each row is now one button holding the hidden "Copy ", the code and the icon. The runtime copies the text of the code inside the clicked button. ReSpec had no visually-hidden class, so I added one scoped to the panel. In Chrome, keyboard focus shows the browser's focus ring around the whole row.
Adds a "Possible linking syntaxes:" section to each dfn popup panel,
showing the correct ReSpec inline shorthand for linking to the definition.
Handles all dfn types: [= =] for concepts, {{ }} for IDL, [^ ^] for
elements/attributes, {^ ^} for CDDL. Includes data-lt aliases and per-item
copy-to-clipboard buttons. Fixes selectors in dfn-index-spec.js.
Closes #3741
- Add "interface mixin" and "callback interface" to IDL_TYPES - Add removeOnSave to copy buttons so they're stripped from exports - Include buttons in trapFocus selector (a11y: keyboard users can reach copy buttons)
…fault
Split comma-separated data-dfn-for values so each produces a separate
linking syntax (e.g. {{Foo/method()}} and {{Bar/method()}} instead of
the invalid {{Foo, Bar/method()}}). Also skip primaryTerm when
data-lt-noDefault is set, matching getDfnTitles behavior.
828a81c to
fbc61bb
Compare
|
I've decided we should only show the linking syntaxes if the definition is exported. Otherwise it might be confusing. |
Closes #3741
Screenshot:
Written with AI: this change was generated by Claude. Per AI_POLICY.md.