feat(BlockEditor): add rich paste support with html-to-blocks parsing
- add clipboard.js with htmlToBlocks, blocksToHtml, and blocksToPlainText helpers - handle single-paragraph html paste as inline splice preserving block type - handle multi-block html paste by splitting current block and merging head/tail paragraphs - add onPasteInline and onPasteBlocks props to Block component - implement handlePasteInline and handlePasteBlocks in BlockEditor - fallback to plain text insertion when html is absent or yields no blocks - update README to document clipboard behaviour and new paste handlers
This commit is contained in:
@@ -78,6 +78,7 @@ import {
|
||||
sliceInline, concatInline, applyMark, toggleMark, removeAllMarks,
|
||||
marksAtOffset, marksInRange, INLINE_COLORS,
|
||||
isHexColor, collectUsedColors,
|
||||
blocksToHtml, blocksToPlainText, htmlToBlocks,
|
||||
} from '@zen/core/shared/components/BlockEditor';
|
||||
```
|
||||
|
||||
@@ -142,7 +143,8 @@ En mode sélection multi-blocs :
|
||||
- `Backspace` / `Delete` → supprime tous les blocs sélectionnés
|
||||
- `Escape` → quitte la sélection
|
||||
- `Ctrl/Cmd + A` → étend à tous les blocs (no-op si déjà tous sélectionnés)
|
||||
- `Ctrl/Cmd + C` / `Ctrl/Cmd + X` → copie/coupe le texte concaténé (texte plat)
|
||||
- `Ctrl/Cmd + C` / `Ctrl/Cmd + X` → copie/coupe les blocs sélectionnés au format **HTML structuré** (titres, gras, listes, citations, …) + fallback `text/plain`. Collable dans Word, Google Docs, Slack, ou un autre `BlockEditor`.
|
||||
- `Ctrl/Cmd + V` → remplace les blocs sélectionnés par le contenu HTML du presse-papier (parsé par `htmlToBlocks`).
|
||||
- frappe d'un caractère imprimable → remplace les blocs sélectionnés par un nouveau paragraphe contenant ce caractère
|
||||
- clic dans l'éditeur → quitte la sélection
|
||||
|
||||
@@ -201,11 +203,40 @@ utils/ids.js UUID pour les blocs
|
||||
utils/caret.js gestion du caret (multi-Text-nodes)
|
||||
```
|
||||
|
||||
## Copier-coller avec formatage
|
||||
|
||||
Le presse-papier transporte deux MIME en parallèle : `text/html` (structure
|
||||
+ formatage) et `text/plain` (fallback). Côté éditeur :
|
||||
|
||||
- **Copy / Cut** : `blocksToHtml(selected)` produit un HTML standard
|
||||
(`<h1>…<h6>`, `<p>`, `<ul>/<ol><li>`, `<blockquote>`, `<pre><code>`,
|
||||
`<hr>`, `<figure><img>`). Pour les sélections multi-blocs (focus
|
||||
défocus), on passe par l'API async `navigator.clipboard.write` avec un
|
||||
`ClipboardItem` qui inclut les deux MIME.
|
||||
- **Paste dans un bloc** : `Block.handlePaste` lit `text/html` en
|
||||
priorité et appelle `htmlToBlocks`. Si un seul paragraphe est produit,
|
||||
son contenu inline est splicé au caret. Sinon le bloc courant est
|
||||
coupé en deux et les blocs collés sont insérés entre les deux moitiés
|
||||
(avec fusion tête/queue si extrémités = paragraphe).
|
||||
- **Paste en sélection multi-blocs** : `navigator.clipboard.read()` lit
|
||||
le HTML du presse-papier, le convertit, et remplace les blocs
|
||||
sélectionnés.
|
||||
|
||||
Tags HTML reconnus en entrée : `<h1>`–`<h6>`, `<p>`, `<ul>/<ol><li>`,
|
||||
`<ul data-checklist>` ou `<li>` contenant `<input type="checkbox">`,
|
||||
`<blockquote>`, `<pre>`, `<code>`, `<hr>`, `<figure>`, `<img>`, plus
|
||||
toutes les marks de `domToInline` (`<strong>/<b>`, `<em>/<i>`, `<u>`,
|
||||
`<s>/<strike>/<del>`, `<code>`, `<a href>`, `<span data-color>` /
|
||||
`<span data-highlight>`).
|
||||
|
||||
Les wrappers de Word / Google Docs (`<b id=...>`, `<div>` de mise en
|
||||
page) sont traversés pour atteindre les éléments block-level
|
||||
descendants. Les styles CSS inline (`font-weight`, `font-style`,
|
||||
`text-decoration`) sont également lus en plus des tags sémantiques.
|
||||
|
||||
## Limitations connues
|
||||
|
||||
- Pas d'imbrication de listes.
|
||||
- Paste : seul le texte brut est conservé (sanitize HTML). Le formatage
|
||||
inline copié depuis l'extérieur n'est pas préservé.
|
||||
- Image : URL uniquement, pas d'upload de fichier (Phase 2). La caption est
|
||||
une string plate (pas de formatage inline pour l'instant).
|
||||
- Tables : Phase 3.
|
||||
|
||||
Reference in New Issue
Block a user