feat: menu contextuel au highlight de texte — toolbar 4 lignes façon Notion (v7.62.0)
- Toolbar de sélection sous le surlignage : ligne de style (T + type de bloc dynamique → sous-menu Turn into), A/B/I/U/T barré/Tx, lien/surlignage/ code/équation/…, Comment + Ask AI, section grise Skills (4 actions) et pied « Edit with AI » (Alt+⇧+E) ; positionnée sous la sélection (au-dessus si manque de place), fermée au clic hors sélection - « … » → menu contextuel de bloc existant (recherche « Search actions… », groupe Text, 10 actions + raccourcis, pied auteur/heure/taille) - Info-bulle claire à droite des éléments du menu : data-tooltip-html + classe .tooltip-light dans le tooltip global (app.js) - Persistance du formatage inline : sérialiseur gtMd() (DOM formaté → source markdown) branché sur sync() ; mdEsc() rend __…__ (u), ==…== (mark) et $$…$$ (équation inline KaTeX, data-tex conservé) - Fixes racine : askAI(idx) écrasé par askAI() → askAIBlock(idx) (menu de bloc, Ctrl+J, Alt+⇧+E) ; ed.__x (Alpine v2) inexistant sous v3 → _xed() via _x_dataStack[0] (showFmt/hideCommentBtn/mentions ne s'exécutaient jamais) ; ancre de sélection nœud élément gérée ; checkMd() appelé avec un id au lieu de l'index (exception à chaque barre d'espace) - Tests : tests/test_v762_selection_toolbar.py (roundtrip gtMd/mdEsc sous node) + e2e/v762_selection_toolbar.spec.js (structure, sous-menus, géométrie, persistance bold/highlight après reload) ; suite complète 1368 passed / 0 failed, ruff OK, OpenAPI régénérée 7.62.0 (525 chemins)
This commit is contained in:
@@ -1,5 +1,68 @@
|
||||
# Changelog - FlowDeck
|
||||
|
||||
## v7.62.0 (2026-10-08) — Menu contextuel au highlight de texte (toolbar façon Notion)
|
||||
|
||||
### Added
|
||||
|
||||
- **Toolbar de sélection** — dès qu'un texte est surligné dans l'éditeur, un menu
|
||||
flottant apparaît **sous la sélection** (au-dessus si manque de place), centré et
|
||||
clampé au viewport, en 4 lignes comme dans Notion :
|
||||
1. **Style de texte** — `T` + libellé **dynamique** du type de bloc (Normal Text,
|
||||
Heading 1… ; le type courant) + `›` → ouvre le sous-menu **Turn into** existant
|
||||
(coche sur le type actuel, fermeture au survol sortant).
|
||||
2. **A** (sous-menu Color : texte/fond + dernière couleur), **B** gras, *I* italique,
|
||||
**U** souligné, **T** barré, **Tx** code inline.
|
||||
3. 🔗 lien, **S** surlignage (`<mark>`), `</>` bloc code, **√x** équation inline
|
||||
(prompt LaTeX → KaTeX), **…** → menu contextuel de bloc (recherche + 10 actions +
|
||||
pied « Last edited by … / N words, M characters »).
|
||||
4. 💬 Comment (`Ctrl+⇧+M`), ✨ Ask AI (`Ctrl+J`).
|
||||
puis la section grise **Skills** (Improve writing, Proofread, Explain, Reformat →
|
||||
`runSkill` sur le bloc) et le pied **Edit with AI** `Alt+⇧+E`.
|
||||
- **Info-bulle claire à droite** des éléments du menu — extension du système de
|
||||
tooltip existant (`app.js`) : `data-tooltip-html` (ex. en italique + description
|
||||
pour la ligne 1) + classe `.tooltip-light`, position à droite de l'élément (débord
|
||||
→ à gauche), sous l'élément hors toolbar.
|
||||
- **Persistance du formatage inline** : nouveau sérialiseur **`gtMd()`** (DOM formaté
|
||||
→ source markdown) appelé par `sync()` (blocs + enfants toggle/columns) — le
|
||||
formatage posé ressort en `**gras**`, `*ital*`, `__souligné__`, `~~barré~~`,
|
||||
`` `code` ``, `==surlignage==`, `[texte](url)` ; les chips wiki gardent leur token.
|
||||
`mdEsc()` rend en plus `__…__` (`<u>`), `==…==` (`<mark>`) et `$$…$$`
|
||||
(équation inline KaTeX, `data-tex` conservé pour l'aller-retour).
|
||||
- **Fermeture propre** : clic hors sélection → le menu se referme ; clic **dans** la
|
||||
toolbar → sélection et menu intacts (`@mousedown.prevent` + garde `mouseup`).
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`askAI(idx)` était écrasé par `askAI()`** (même clé dans l'objet éditeur, définie
|
||||
plus bas) : « Ask AI » du menu de bloc et `Ctrl+J` ouvraient l'IA de **page** au
|
||||
lieu du composeur du bloc → renommé **`askAIBlock(idx)`** (appels : menu de bloc,
|
||||
`Ctrl+J`, `Alt+⇧+E`).
|
||||
- **`ed.__x` introuvable sous Alpine v3** — le data de `.page-editor-wrapper` était
|
||||
lu via `ed.__x` (API Alpine v2, plus exposée depuis le bundle CSP) : `showFmt`,
|
||||
`hideCommentBtn` et les handlers de mentions ne s'exécutaient **jamais** → la
|
||||
toolbar de sélection n'apparaissait pas. Accès unifié via `_xed()`
|
||||
(`_x_dataStack[0]`, repli `__x`), 4 sites éditeur.
|
||||
- **Ancre de sélection** — `closest('[data-bid]')` partait du parent de l'ancre :
|
||||
quand l'ancre est un nœud **élément** (sélection programmée, double-clic), le bloc
|
||||
n'était jamais trouvé → `showFmt` pas appelé. Gestion des 2 types de nœud.
|
||||
- **Barre d'espace = exception** — `checkMd()` recevait l'**id** du bloc au lieu de
|
||||
l'index : chaque espace levait `Cannot read properties of undefined (reading 'id')`
|
||||
et les raccourcis markdown (`# `, `- `) ne se déclenchaient jamais.
|
||||
|
||||
### Tests
|
||||
|
||||
- `tests/test_v762_selection_toolbar.py` : ordre des 4 lignes + Skills + pied,
|
||||
câblage réel des actions, persistance `gtMd`/`mdEsc` (**roundtrip réel sous node**),
|
||||
placement/fermeture, styles ; `tests/test_v761_block_menu.py` adapté
|
||||
(`askAIBlock`).
|
||||
- **e2e Playwright** `e2e/v762_selection_toolbar.spec.js` (instance 8081) : structure
|
||||
des 4 lignes, sous-menu Turn into (coche du type courant), menu « … » (recherche +
|
||||
pied), géométrie (sous la sélection, dans le viewport), **persistance du gras et du
|
||||
surlignage après reload**, fermeture hors sélection → 1 passed (captures dans
|
||||
`e2e/shots/` — répertoire gitignoré).
|
||||
- **Suite complète** : `pytest tests/ -q -n auto` → **1368 passed / 0 failed**,
|
||||
`ruff check app tests` → All checks passed.
|
||||
|
||||
## v7.61.0 (2026-10-08) — Menu contextuel de bloc refondu façon Notion
|
||||
|
||||
### Added
|
||||
|
||||
Reference in New Issue
Block a user