fix(clipboard): use ProseMirror selection state for Shadow DOM compatibility (#2677)
OpenProject embeds BlockNote inside a Shadow DOM (attachShadow({ mode: 'open' }))
to isolate it from the host Angular application. In this setup,
window.getSelection() returns null or a collapsed selection even when text is
selected (Firefox all versions, Safari ≤16.3, Chromium edge cases), causing
checkIfSelectionInNonEditableBlock to always return true and skip the
clipboard write entirely. The browser's default copy then fires, which uses
ProseMirror's DOMSerializer without semantic wrappers — so list formatting,
headings, and bold/italic are lost on paste into external apps.
Fix: use view.state.selection.empty as the primary empty-selection guard.
ProseMirror's internal state is always accurate regardless of DOM mode. The
DOM-level non-editable-island check is kept as a secondary guard, but only
when window.getSelection() actually returns a non-collapsed selection.
Fixes copy/cut for editors mounted inside attachShadow({ mode: 'open' }). W
Wieland Lindenthal committed
130a91698114457bbe6635fc397b2c2df8be4675
Parent: 38c5515
Committed by GitHub <noreply@github.com>
on 4/29/2026, 3:56:14 PM