Sortie de Wordgard 0.1
(marijnhaverbeke.nl)- Wordgard 0.1 est une nouvelle bibliothèque JavaScript d’édition de texte riche, conçue à partir de neuf ans d’expérience depuis la stabilisation de ProseMirror et en s’inspirant de la conception de CodeMirror 6
- Plutôt que de transformer ProseMirror en version 2.0 ou d’ajouter ces idées à la branche 1.x, le projet a été repensé avec un nouvel API sans contrainte de compatibilité et sous un nom distinct
- Sa conception centrale utilise un modèle fondé sur des sections de changement au lieu des steps, et combine des types de nœuds et de marques indépendants avec un système d’extension par facets à la CodeMirror
- La dépendance aux comportements de sélection du navigateur est réduite en gérant directement les sélections au pointeur et au clavier, mais la sélection tactile conserve l’implémentation native à cause des problèmes liés aux menus contextuels natifs
- Il peut être installé depuis npm avec
wordgard, et la documentation ainsi que le manuel de référence sont publiés, mais le projet devrait rester quelque temps en version 0.x pendant la collecte de retours et les corrections de bugs
Nature de Wordgard et état de la publication
- Wordgard est un nouveau projet qui réitère le système d’éditeur de texte riche dans le style de ProseMirror
- Il s’appuie sur ce qui a été appris pendant les neuf années écoulées depuis la stabilisation de ProseMirror, et a été fortement influencé par la refonte de CodeMirror en version 6
- C’est une bibliothèque JavaScript qui affiche l’interface de l’éditeur via le DOM du navigateur, sous licence MIT
- Le code est publié sur un serveur Forgejo
- Il peut être installé depuis le registre npm sous le nom
wordgard, et son utilisation est décrite sur le site web
Pourquoi créer un nouveau système plutôt que modifier ProseMirror
- ProseMirror continuera d’être maintenu, mais certains choix de conception restent des éléments qui auraient dû être faits différemment avec le recul actuel
- Publier un ProseMirror 2.0 avec des interfaces incompatibles risquerait de rendre ambigu ce que les gens entendent par « ProseMirror »
- Ajouter de nouvelles idées à ProseMirror 1.x de manière rétrocompatible pourrait conduire à une structure de compromis
- Wordgard reprend beaucoup d’idées de ProseMirror, mais son interface de programmation a été repensée depuis zéro sans tenir compte de la compatibilité
Représentation des changements : un modèle par sections au lieu des steps
- Les steps de ProseMirror découpent les changements en plusieurs opérations atomiques, chaque step s’appliquant au document produit par le step précédent
- Cette approche fonctionne, mais la correction des positions entre plusieurs steps et le suivi des plages modifiées deviennent complexes et peu agréables à manipuler
- Wordgard utilise un modèle plus simple, fondé sur la représentation des changements de CodeMirror et sur le format « delta » de ShareJS
- Si la longueur du document est 10 et que l’on insère
Là la position 4, cela se représente par[keep 4] [replace 0 with "L"] [keep 6] - La suppression des deux premiers caractères se représente par
[replace 2 with ""] [keep 8]
- Si la longueur du document est 10 et que l’on insère
- Pour gérer le texte riche, il ajoute des sections de changement, qui permettent d’ajouter ou de supprimer des marques comme l’emphase, les styles de liens ou le texte alternatif d’une image tout en conservant la structure
- Mettre en gras le mot entre 3 et 6 se représente par
[keep 3] [update 3 +bold] [keep 4]
- Mettre en gras le mot entre 3 et 6 se représente par
- Wordgard utilise, comme ProseMirror, un index par comptage de tokens pour traiter les positions du document comme une séquence plate de tokens d’ouverture et de fermeture de nœuds, et de tokens feuilles
- Une transaction unique possède toujours un seul changement, ce qui facilite la composition, l’inspection et l’inférence des changements
- Il prend en charge une forme limitée de transformation opérationnelle permettant de fusionner plusieurs changements exprimés à partir du même document initial
- Cela permet d’exprimer plus confortablement des transactions comportant plusieurs changements
- Cela peut servir à l’édition collaborative et à l’implémentation d’un historique d’annulation ne revenant que sur certains changements
Maintenir une structure de document valide
- Un document Wordgard ne doit pas être une simple séquence de tokens, mais une structure arborescente équilibrée
- Par exemple, supprimer un token de fermeture de nœud peut rompre l’équilibre des tokens et produire un changement impossible à appliquer
- Le code qui génère les ensembles de changements doit inspecter et ajuster les changements pour que le résultat reste une structure de document valide
- Dans la transformation opérationnelle aussi, le changement transformé ne doit pas invalider le document
- Le modèle de changements de Wordgard dérive, pendant la transformation, un fix-up change qui corrige le résultat combiné
- Les entrées sont utilisées avec soin afin de produire la même correction pour A-over-B et B-over-A
- Sans correction, les deux ordres peuvent produire un document identique, mais potentiellement invalide
- En composant la même correction, les deux ordres convergent vers le même document valide
- La plupart des changements n’ont pas besoin de correction, mais le système est conçu pour préserver la convergence même lorsqu’elle est nécessaire
Composition de schémas et généralisation des marques
- Le schéma de document de ProseMirror spécifie directement les relations entre nœuds et doit donc généralement être configuré à la main
- Les types de nœuds et de marques de ProseMirror n’existent qu’au sein d’un schéma donné, et il n’existe pas d’identité de nœud partageable entre schémas
- Dans Wordgard, les types de nœuds et de marques sont des objets indépendants pouvant être inclus dans plusieurs schémas de document
- Ces objets agissent comme des handles prenant en charge le typage et l’autocomplétion, ce qui facilite la création de schémas par composition des éléments nécessaires
- Un schéma peut surcharger les relations des éléments existants
- La définition d’un nœud ou d’une marque spécifie le contenu par défaut ou les types ciblés
- Lorsqu’on veut utiliser le même élément différemment, le schéma peut modifier ces relations
- Il devient possible de fournir un ensemble plus riche de nœuds intégrés par défaut, ce qui facilite l’attachement direct à ces nœuds d’intégrations système comme des extensions d’aide à l’édition ou des boutons de menu
- Les fonctionnalités auparavant associées à des attributs de nœuds spécifiques, comme l’alignement du texte ou le texte alternatif, peuvent être ajoutées de façon plus modulaire grâce à la généralisation des marques
- Le type de nœud lui-même n’a pas besoin de savoir quelles marques le ciblent
Pourquoi assouplir les contraintes sur le contenu
- La fonctionnalité emblématique de ProseMirror, la spécification du contenu autorisé par expressions régulières, n’est pas prise en charge dans Wordgard
- Dans Wordgard, la description du contenu d’un nœud limite uniquement les types d’enfants pris en charge, mais pas leur ordre
- Les contraintes fondées sur des expressions régulières rendent difficile l’écriture de code générique de manipulation de documents
- Un code qui n’est pas écrit pour un schéma précis peut faire très peu d’hypothèses sur la validité d’une transformation
- Chaque opération doit être confrontée aux contraintes de contenu, ce qui est subtil et lourd
- Des contraintes verrouillant fortement la forme du document peuvent bloquer les étapes intermédiaires d’édition permettant à l’utilisateur d’arriver à la forme voulue, au détriment de l’expérience utilisateur
- Wordgard encourage une approche plus souple de la forme du document
- Lorsqu’il faut des invariants dépassant les règles du schéma, il fournit une abstraction de correction
- Les formes de document que l’on ne souhaite pas autoriser sont corrigées par programme
- Cela permet des corrections plus intelligentes et plus contextuelles que l’application forcée d’expressions de contenu
- Cela peut aussi servir pour des conditions que les contraintes de ProseMirror ne permettaient pas d’exprimer, comme garantir des tableaux rectangulaires
Système d’extension : facets à la CodeMirror 6
- Le système d’extension de ProseMirror repose sur des plugins qui prennent en charge plusieurs responsabilités, avec un ordre dans le tableau qui influence les priorités
- Il peut arriver qu’un plugin ait besoin d’une priorité basse pour un hook et d’une priorité élevée pour un autre
- Le système fondé sur les facets de CodeMirror rend les extensions plus granulaires et permet à chaque valeur d’extension de définir sa propre catégorie de priorité
- Une facet est un point d’extension typé, qui peut être défini aussi bien par la bibliothèque elle-même que par n’importe quel code
- Sur ce point, Wordgard reprend presque tel quel le système de CodeMirror, y compris les mécanismes de mise à jour d’état et de reconfiguration
- La configuration n’est pas un tableau de plugins, mais un arbre d’extensions
- Définition de gestionnaires d’événements
- Configuration des propriétés de l’éditeur
- Ajout d’un nouvel état d’éditeur
- L’implémentation d’une fonctionnalité se compose généralement d’un ensemble d’extensions fonctionnant ensemble
- Les primitives sont conçues pour que la plupart des bundles d’extensions se composent correctement en étant simplement ajoutés à la configuration
Réduction de la dépendance au navigateur et gestion de la sélection
- Beaucoup de problèmes de ProseMirror sont liés à sa dépendance aux comportements natifs de sélection du navigateur
- L’approche existante consistait à laisser le navigateur gérer le déplacement du curseur dans les textes bidirectionnels ou les contenus au style particulier, puis à refléter le résultat dans son propre modèle de sélection
- En pratique, les navigateurs peuvent refuser de déplacer le curseur au-delà de certains contenus, ne pas l’afficher, le dessiner au mauvais endroit ou se comporter bizarrement lors d’une sélection à la souris par glisser-déposer
- Wordgard gère directement presque toutes les sélections au pointeur et au clavier
- Il implémente la gestion du texte bidirectionnel
- Il crée un modèle de disposition du contenu
- Il dessine lui-même le curseur
- La sélection tactile fait exception et utilise l’implémentation native
- La réimplémenter semble casser le menu contextuel natif
- Sur téléphones et tablettes, il est difficile de remplacer le menu contextuel
- La sélection tactile a tendance à se comporter moins bizarrement que la sélection au clavier
Traitement des événements de saisie et suppression de la surveillance des changements DOM
- Au cours des neuf dernières années, la prise en charge des événements d’édition par les navigateurs, en particulier de
beforeinput, est devenue plus cohérente - Des tests en conditions réelles restent nécessaires, mais Wordgard semble pouvoir fonctionner sans la surveillance des changements DOM ni les astuces de parsing du contenu modifié dont dépendait ProseMirror
- Wordgard traite les événements
beforeinputpour tout, à l’exception de la saisie de texte en composition - Cette approche évite toute une classe de problèmes nécessitant diverses solutions de contournement peu propres
Stabilité, plan de versionnage et licence
- Wordgard est dans un état un peu plus avancé que les projets précédents au moment de leur annonce
- Les interfaces principales prennent en charge presque toutes les fonctionnalités souhaitées, et plusieurs extensions ont été écrites pour vérifier que la conception est praticable
- La documentation reste encore assez brute, mais le manuel de référence est complet et utilisable
- De nombreux problèmes pourraient ne pas apparaître tant que des personnes ne l’utiliseront pas dans de vrais projets
- D’autres fonctionnalités sont envisagées, et l’auteur espère que d’autres personnes examineront le projet après sa publication
- Certaines parties de l’interface publique pourraient devoir être repensées à la lumière de nouveaux enseignements
- La première version est la 0.1, et le projet devrait rester en 0.x quelque temps afin de recueillir des retours, corriger des bugs et lisser les aspérités
- La durée prévue est d’au moins environ un an
- La licence est MIT, comme pour les projets précédents
- Une licence plus restrictive a été envisagée, mais l’objectif étant une large adoption, une licence permissive a été choisie
Modèles d’IA, génération de code et politique sur les pull requests
- Aucun modèle de langage n’a été utilisé pour créer ce logiciel
- Comme le code JavaScript est sur le web et que la documentation doit être publique, il n’existe probablement aucun moyen fiable d’empêcher que le code et les idées publiés soient intégrés à de grands modèles de langage
- Wordgard mène une expérience qui s’écarte des pratiques open source habituelles en n’acceptant pas les pull requests
- Relire de gros changements et les ajuster pour qu’ils correspondent aux attentes demande souvent plus de travail que de les implémenter directement
- Avec la forte baisse du coût de génération de code, le modèle où quelqu’un envoie du code et où le mainteneur doit le relire, le maintenir ou expliquer pourquoi il le refuse devient moins attractif
1 commentaires
Commentaires sur Lobste.rs
En tant qu’auteur, je passerai de temps en temps sur ce fil si vous avez des questions ou des retours
On pourrait sans doute générer du HTML avec un moteur de rendu Markdown et l’éditer dans Wordgard, mais comment extraire ensuite le Markdown du contenu de l’éditeur ?
Finiront-elles par passer à Wordgard ? Si quelqu’un envisage d’utiliser ProseMirror pour un nouveau projet, à quel moment devrait-il choisir Wordgard ?
Et il y a aussi de superbes illustrations réalisées par une vraie artiste humaine
J’aime bien
Un grand bravo à Marijn pour ce projet et cette annonce. Ça a l’air superbe, et j’aime aussi les illustrations de Kamila Stankiewicz
La page d’accueil principale du projet est https://wordgard.net/
Ce passage est vraiment intéressant, surtout tout le dernier paragraphe.
Je me demande si ce genre d’approche deviendra plus courant pendant un certain temps, jusqu’à ce que nous établissions une meilleure relation avec la génération de code par IA, ou que nous choisissions de ne pas en avoir du tout.
À noter que le code est sous licence MIT