Class RteHtmlCodec

java.lang.Object
vaadinx.swing.text.RteHtmlCodec

public final class RteHtmlCodec extends Object
Codec between a Swing StyledDocument and Vaadin RichTextEditor's HTML value, behind vaadinx.swing.JTextPane (D_jtextpane). One format both ways: the emulator pushes the document to the peer as RTE-subset HTML (toHtml(StyledDocument), via the main setValue channel) and reads browser edits back from the same HTML value (fromHtml(String, StyledDocument)). Reading the property the change event fired on — rather than asDelta() — removes the cross-property staleness of the old mixed push-HTML/read-Delta split (D_jtextpane).
String html = RteHtmlCodec.toHtml(styledDoc);   // push:  doc  -> "<h2>..</h2><p>..</p>"
RteHtmlCodec.fromHtml(html, styledDoc);         // read:  HTML -> doc (clear + re-insert)

Mapping (empirically pinned against the live component — D_jtextpane)

Swing StyleConstants / opaque-carry attribute ⇄ RTE HTML
Bold/Italic/Underline/StrikeThrough<strong>/<em>/<u>/<s>
Foreground/Backgroundstyle="color:…"/"background-color:…"
Superscript/Subscript<sup>/<sub>
Alignment (paragraph) inline style="text-align:…" on <p>/<h1..3>/<blockquote> (left omitted); dropped + WARNed on <pre>/<li> — RTE can't persist it there
IconAttribute (ImageIcon)<img src="data:…"> (base64)
FontSize (uniform per paragraph) <h1..3> by band (≥22→h1, 18..21→h2, 14..17→h3); read fabricates the band's representative size (24/20/16) back onto the runs. Sub-threshold sizes drop + WARN.
HEADER/LIST/BLOCKQUOTE/CODE_BLOCK/LINK <h1..3>/<ol>|<ul>+<li>/<blockquote>/<pre>/<a href> — no StyleConstants home, carried opaquely so a browser edit round-trips

Headings have two carriers: the opaque HEADER key (authoritative, browser-origin) and a Swing-authored uniform FontSize band. HEADER wins when present; the band is the set-from-Swing entry point (RTE has no font-size control, so <hN> is the only lever that renders bigger). A read <hN> sets HEADER and fabricates the representative FontSize, so introspection sees the size and the round-trip is idempotent from the first cycle.

fromHtml(String, StyledDocument) absorbs Quill's read-back normalizations (verified in a real browser): inline attributes accumulate regardless of tag nesting order (<s><u> ≡ <u><s>); colour is read from a <span style="color"> or a style="color" on an inline element (Quill moves it onto the format tag); rel/target/spellcheck are ignored; a trailing "\n" inside <pre> is stripped.

Attributes with no RTE counterpart (font family, indents, line spacing, insertComponent, a non-ImageIcon icon, and a sub-band FontSize) WARN via EHelper.onUnimplemented(String, String, Object...) and are dropped.

Not migrator API — internal to the JTextPane emulator.

  • Field Details

    • LIST

      public static final Object LIST
    • BLOCKQUOTE

      public static final Object BLOCKQUOTE
    • CODE_BLOCK

      public static final Object CODE_BLOCK
  • Method Details

    • toHtml

      public static String toHtml(StyledDocument doc)
      Serializes doc to RTE-subset HTML — the format pushed to the peer via the main setValue channel. Pushing HTML (not asDelta().setValue, whose async executeJs("return this.htmlValue") reconcile races Quill's render to empty during construction — D_jtextpane) keeps the value consistent and never self-clobbers; Karibu can't reproduce that browser race, so this note is the only guard against a "just use asDelta().setValue" simplification.
    • fromHtml

      public static void fromHtml(String html, StyledDocument doc)
      Replaces doc's content with the RTE-subset HTML parsed from a browser edit (clear + re-insert) — the inverse of toHtml(StyledDocument). One block element becomes one paragraph; inline tags accumulate into run attributes regardless of nesting order (<s><u> ≡ <u><s>), and colour is read from either a <span style="color:…"> or a style="color:…" on the inline element itself — Quill attaches it to the format element, e.g. <strong style="color: rgb(…)">x</strong> (empirically pinned against the live component). rel/target/spellcheck and unknown tags are ignored (text preserved). Malformed input is swallowed + WARNed (D_never_fail_on_gaps: reads never fail).

      The caller guards the peer-echo with preventPeerEvents.