Tune & Inline menu
Les composants d'interaction — Tune, Inline_menu, dom.js, utils.js
Tune — contrôleur du bloc
Tune est un composant autonome injecté dans chaque bloc. Il génère deux éléments DOM :
les boutons + et ⋮ (rdac-tools), et le dropdown de contrôle
(rdac-tune-dd).
Tune ne fait rien par lui-même. Il expose des callbacks que
Redac._mount_tune() définit après la création du bloc. Cette séparation
permet à Tune d'être complètement découplé de Redac.
Callbacks
| Callback | Déclenché par | Ce que Redac fait |
|---|---|---|
on_add | Clic + | _add_block(block.id) — crée un bloc après |
on_up | Clic ↑ Monter | Déplace le DOM + blocks.up() + _refresh_states() |
on_down | Clic ↓ Descendre | Déplace le DOM + blocks.down() + _refresh_states() |
on_delete | Clic ✕ Supprimer | Retire du DOM + blocks.rm() + _refresh_states() |
on_apply_attrs | Clic Appliquer | Applique data-custom-id et classes sur le wrapper |
on_open | Ouverture du dropdown | Retourne { id, classes } pour pré-remplir les inputs |
Méthodes
| Méthode | Description |
|---|---|
render() | Construit les deux éléments DOM. Retourne { tools, dropdown } |
update_state(is_first, is_last, is_only) | Désactive les boutons ↑/↓/✕ selon la position du bloc dans la liste |
close() | Ferme le dropdown |
get is_open() | État actuel du dropdown |
Pourquoi deux éléments séparés ?
render() retourne
{ tools, dropdown } et non un seul wrapper. Cela permet à Paragraph
d'insérer les deux au bon endroit dans sa structure flex (tools en flex item gauche,
dropdown en position:absolute). Un seul wrapper rendrait le layout plus
complexe.
Inline_menu — formatage de sélection
Barre d'outils flottante qui apparaît quand l'utilisateur sélectionne du texte dans une zone
.rdac-content. Se positionne au-dessus de la sélection.
Fonctionnement
- Le wrapper est inséré une seule fois dans
document.bodyau constructor. - Au
mouseup,Redacvérifie si la sélection est dans un.rdac-content. - Si oui,
inline_menu.render(selection, selected_txt)positionne le menu et construit les boutons. - Au clic en dehors ou à
selectstart,close()masque le menu.
Positionnement
const rect = selection.getRangeAt(0).getBoundingClientRect()
left = scrollX + rect.left + rect.width / 2 // centré sur la sélection
top = scrollY + rect.top // bord haut de la sélection
transform = translate(-50%, calc(-100% - 6px)) // au-dessus
Contrat des inline tools
Chaque outil (gras, italique, lien…) doit implémenter ce contrat :
| Méthode | Description |
|---|---|
get name() | Identifiant unique : 'bold', 'italic', 'link'… |
render(selection, selected_txt) |
Retourne le bouton DOM. Appelé à chaque ouverture du menu. L'outil stocke
la sélection ici pour la relire dans action().
Le bouton doit avoir dataset.redacItName = this.name.
|
action(event) |
Applique le formatage sur la sélection stockée dans render().
Délégation : un seul listener sur le wrapper lit btn.dataset.redacItName
pour trouver le bon outil.
|
Limitation connue : la sélection est stockée dans
render() (mouseup)
et relue dans action() (click). Certains navigateurs effacent la sélection entre
les deux événements. Si bold/italic ne s'applique pas, c'est cette raison.
Solution future : sauvegarder le Range et le restaurer avant d'appliquer.
dom.js — helpers DOM
Deux méthodes statiques utilisées partout dans le code.
| Méthode | Exemple | Retourne |
|---|---|---|
Dom.makel(tag, classes) |
Dom.makel('div', ['rdac-block', 'mt-2']) |
<div class="rdac-block mt-2"> |
Dom.make_icon(class_names) |
Dom.make_icon(['bi-type-bold']) |
<i class="bi bi-type-bold"> |
make_icon prend un tableau et ajoute automatiquement bi comme première
classe. Ne pas passer de strings séparées — c'est une erreur qui a déjà causé un bug
('bi','bi-trash3' au lieu de ['bi-trash3']).
utils.js — utilitaires
| Méthode | Description |
|---|---|
Utils.rdm_id(length = 10) |
Génère un identifiant aléatoire de la longueur spécifiée.
Caractères : a-z, 0-9, -.
Utilisé par Block pour créer l'id de chaque bloc.
Exemple : "k7x2mq4pnb"
|