Skip to content

feat(attributes): expose ccRegisterBlockElements#14

Merged
JohnMcLear merged 1 commit intomainfrom
fix/cc-register-block-elements
May 8, 2026
Merged

feat(attributes): expose ccRegisterBlockElements#14
JohnMcLear merged 1 commit intomainfrom
fix/cc-register-block-elements

Conversation

@JohnMcLear
Copy link
Copy Markdown
Member

Closes #13.

Problem

Etherpad core has two separate _blockElems-style sets:

  • the editor's ace runtime, registered via aceRegisterBlockElements,
  • the server-side content collector's, registered via ccRegisterBlockElements.

createLineAttribute and createTagAttribute currently return only the ace one. Plugins built on top — ep_headings2, ep_subscript_and_superscript, anything else using these factories — tell the editor that h1..h4 / code / sub / sup are block elements but never tell the importer. As a result the server-side content collector treats those tags as inline, and adjacent block-style elements coming in via any HTML import path (including the one mammoth produces from a DOCX) merge into a single pad line.

This just bit native DOCX import/export in ether/etherpad#7568: a pad with three <h1> / <h2> / <code> lines round-trips back as one merged line.

Fix

Have both factories also return ccRegisterBlockElements with the same tag set as aceRegisterBlockElements. A plugin re-exports it from ep.json under "ccRegisterBlockElements" (matching the existing pattern for "aceRegisterBlockElements").

exports.ccRegisterBlockElements = headings.ccRegisterBlockElements;
{
  "hooks": {
    "ccRegisterBlockElements": "ep_headings2/static/js/index"
  }
}

I'll send a follow-up PR against ep_headings2 to wire this up once this lands and is published. (And anyone downstream who consumes lineAttribute({tags: [...]}) gets the same hook for free.)

Tests

  • test/attributes.js: 3 new tests across both factories asserting the new function exists and returns the same tag set.
  • npm test locally: 91 passing.

Etherpad core's import-side content collector keeps its own
`_blockElems` set (`{div, p, pre, li}` by default), separate from
the editor's. `aceRegisterBlockElements` registers tags on the
editor side only -- so plugins built on `lineAttribute` /
`tagAttribute` (`ep_headings2`, `ep_subscript_and_superscript`,
etc.) tell the editor that `h1..h4` / `code` / `sub` / `sup` are
block elements but DON'T tell the importer.

Symptom: round-tripping a pad with `<h1>` / `<h2>` / `<code>` lines
through any HTML import path collapses adjacent heading-style
blocks into a single pad line. This just bit native DOCX export+
import in ether/etherpad#7568.

Fix: have `createLineAttribute` and `createTagAttribute` return a
`ccRegisterBlockElements` function with the same tag set as
`aceRegisterBlockElements`. Plugins re-export this from their
`ep.json` under `"ccRegisterBlockElements"` to register the same
tags on the import side.

Tests added for both factories.

Closes #13
@qodo-code-review
Copy link
Copy Markdown

ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one.

@JohnMcLear JohnMcLear merged commit 21fef4d into main May 8, 2026
4 checks passed
@JohnMcLear JohnMcLear deleted the fix/cc-register-block-elements branch May 8, 2026 15:56
JohnMcLear added a commit to ether/ep_headings2 that referenced this pull request May 8, 2026
ep_headings2 already registers h1-h4 + code as block elements in
the editor (aceRegisterBlockElements). It did NOT register them
on the server-side content collector (ccRegisterBlockElements),
so any HTML import path treated those tags as inline -- and
adjacent <h1>/<h2>/<code> blocks merged into a single pad line.

Fix: re-export the new ccRegisterBlockElements function from
ep_plugin_helpers' lineAttribute factory (added in
ether/ep_plugin_helpers#14) and wire it up via ep.json. This
treats h1-h4 + code as block elements on the import side too,
matching their editor behavior.

Bumps the ep_plugin_helpers minimum to ^0.5.2 (the version with
the new export).

Test added covers the regression: a pad with adjacent <h1> and
<h2> (no separator) survives a setHTML/getHTML round-trip with
each heading on its own line and no merged 'AlphaBeta' content.

Refs ether/etherpad#7568 -- this is the missing piece for the
DOCX/HTML round-trip story landing in core.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lineAttribute() should also expose ccRegisterBlockElements (server-side)

1 participant