Files
Artstr-Studio/src
thePR0M3TH3ANandClaude Opus 4.7 aaf044a946 Text layers: inline rich-text formatting toolbar
Replaces the previous whole-layer Link URL field with proper inline
rich-text editing. Users click into a text layer on the canvas,
select a range, and apply formatting to just that selection.

New side-panel toolbar buttons under the text-layer controls:

- B / I / U — bold / italic / underline on the selection.
- • / 1. — bulleted list / numbered list.
- 🔗 — insert link on the selection (prompts for URL; rejects
  anything that isn't http / https / mailto / tel / nostr via
  safeTextLinkHref).
- ⌧ — unlink the selection.

Wiring:

- Each button uses mousedown.preventDefault() so the contenteditable
  text layer keeps focus / selection when the user clicks the sidebar
  button.
- _runInlineFormat() locates the contenteditable via the
  .freeLayer[data-layer-id="..."] .textLayer selector, focuses it
  if needed, runs document.execCommand, reads innerHTML back into
  layer.html, and debounce-pushes one undo entry. No full render —
  that'd rebuild the editable and lose focus / selection.

Security: applyPreviewLayerTextStyle (the preview path) and the
in-editor render path both post-render-scrub every <a> tag —
unsafe hrefs get unwrapped (text kept, link dropped) and safe ones
get target="_blank" rel="noopener noreferrer" forced on.

End-to-end verified via headless Chrome + CDP. A test deck with
layer.html =

  Visit <a href="https://artstr.org">Artstr</a> for more or
  <a href="mailto:[email protected]">email us</a>.

  Try this <a href="javascript:alert(1)">bad link</a> too.
  Some <b>bold</b>, <i>italic</i>, and <u>underlined</u> bits.
  <ul><li>One</li><li>Two</li><li>Three</li></ul>

— PDF export:
  - pdftohtml -i extracts ONLY the legit URLs: https://artstr.org/
    and mailto:[email protected]. The javascript: link was stripped.
  - Visual render: "Artstr" and "email us" are underlined links;
    "bad link" is plain text; bold / italic / underline marks apply
    only to their selected sub-strings; <ul> renders with bullets.

The whole-layer Bold / Italic toggles in the existing text-tool row
remain — they set the default weight / style for the layer; inline
marks override per-span.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-26 22:25:28 -04:00
..
2026-05-26 16:13:06 -04:00
2026-05-20 22:06:50 -04:00
2026-05-26 16:13:06 -04:00