Il n'a pas toujours été simple pour les développeurs d'intégrer des fonctionnalités de retouche avancées dans leurs applications Web. La plate-forme Web permet de modifier les documents en texte brut et HTML à l'aide d'éléments tels que <input>
et <textarea>
, ou en appliquant l'attribut contenteditable
aux éléments. Cependant, les fonctionnalités de base de ces types d'éléments ne sont souvent pas suffisantes pour ce que les développeurs souhaitent accomplir dans leurs applications.
Les développeurs ont souvent fini par implémenter leur propre vue d'éditeur personnalisée qui implémente les fonctionnalités dont leurs utilisateurs ont besoin. La vue de l'éditeur peut être créée avec un DOM complexe, voire avec un élément <canvas>
. Toutefois, comme le seul moyen pour le développeur de recevoir une entrée de texte nécessite un élément éditable en mode focus, il doit toujours placer un élément contenteditable
masqué quelque part sur sa page.
Par conséquent, bien que l'utilisateur semble modifier directement le contenu dans la vue de l'éditeur personnalisé de l'application, le développeur reçoit en réalité l'entrée avec des gestionnaires d'événements dans l'élément masqué, puis la duplique dans la vue de l'éditeur visible. Cela peut entraîner des problèmes, car le développeur se retrouve à lutter contre le comportement de modification par défaut du navigateur dans l'élément contenteditable
masqué.
Pour résoudre ce type de problèmes, l'équipe Microsoft Edge a conduit à la standardisation de EditContext, une nouvelle API de plate-forme Web qui permet aux développeurs de recevoir directement la saisie de texte sans être liés aux comportements de modification par défaut du navigateur.
Exemple concret
Par exemple, lorsque les utilisateurs collaborent dans Word Online. Les utilisateurs peuvent coéditer et voir les modifications et les positions du curseur de chacun. Toutefois, si un collaborateur utilise une fenêtre d'éditeur de mode de saisie (IME) pour composer du texte en japonais, par exemple, son éditeur ne sera pas mis à jour pour afficher les modifications apportées par d'autres utilisateurs tant que l'utilisateur de l'IME n'aura pas terminé sa composition. En effet, modifier la zone du DOM en cours de modification alors qu'une composition IME est active peut entraîner l'annulation prématurée de la composition. L'application doit attendre que la fenêtre IME soit fermée pour mettre à jour l'affichage, ce qui peut entraîner des retards et entraver la collaboration.
Pour offrir une meilleure expérience aux développeurs et aux utilisateurs, les développeurs doivent pouvoir dissocier la saisie de texte de la vue DOM HTML. L'API EditContext est la solution à ce problème.
Principes de base d'EditContext
Avec EditContext, vous pouvez recevoir du texte et des entrées de composition directement via la surface de l'API EditContext, plutôt que d'observer les modifications apportées au DOM. Cela permet de mieux contrôler la manière dont la saisie est gérée et même d'ajouter la possibilité de modifier l'élément <canvas>
.
Associer une instance EditContext à un élément le rend modifiable:
// This will be our editable element.
const element = document.querySelector('#editor-element');
// Creating the EditContext object.
const editContext = new EditContext();
// Associating the EditContext object with our DOM element.
// The element is now focusable and can receive text input.
element.editContext = editContext;
// In order to render the text typed by the user onto the
// page, as well as the user's selection, you'll need to
// receive the input in a textupdate event callback.
editContext.addEventListener('textupdate', event => {
element.textContent = editContext.text;
// For brevity, the code to render the selection
// isn't shown here.
renderSelection(event.selectionStart, event.selectionEnd);
});
Responsabilités de l'auteur
L'utilisation de l'API EditContext facilite la prise en charge des méthodes de saisie avancées telles que les fenêtres de composition IME, les sélecteurs d'emoji et d'autres surfaces de saisie du système d'exploitation. Pour que tout cela soit possible dans votre élément éditable, l'API EditContext nécessite certaines informations. En plus d'afficher le texte et la sélection, vous devez effectuer d'autres opérations lorsque vous utilisez l'API EditContext.
Gérer le côté d'une région modifiable, ou si la sélection de l'utilisateur change
Appelez les méthodes updateControlBounds()
et updateSelectionBounds()
pour informer l'instance EditContext chaque fois que la taille de la région modifiable ou la sélection de l'utilisateur change. Cela permet à la plate-forme de décider où afficher les fenêtres de l'IME et d'autres interfaces utilisateur de modification spécifiques à la plate-forme.
// It's necessary to provide bounds information because EditContext
// is generic enough to work with any type of web editor, even
// <canvas>-based editors. The API doesn't make any assumptions as
// to how the editor is implemented or how the selection is rendered.
// Bounds are given in the client coordinate space.
const controlBound = editorElement.getBoundingClientRect();
const selection = document.getSelection();
const selectionBound = selection.getRangeAt(0).getBoundingClientRect();
editContext.updateControlBounds(controlBound);
editContext.updateSelectionBounds(selectionBound);
Gérer la position de l'UI de l'éditeur
Écoutez l'événement characterboundsupdate
et appelez updateCharacterBounds()
en réponse pour aider la plate-forme à décider où afficher les fenêtres IME et d'autres UI de modification spécifiques à la plate-forme.
Appliquer la mise en forme
Écoutez l'événement textformatupdate
et appliquez la mise en forme spécifiée par l'événement à la vue de l'éditeur. Ces décorations sont utilisées par les IME lors de la rédaction de certaines langues. Par exemple, dans l'éditeur de mode de saisie japonais, le texte est souligné pour indiquer la partie du texte qui est en cours de rédaction.
Gérer les comportements d'édition de texte enrichi
Écoutez l'événement beforeinput
pour gérer les comportements de modification du texte enrichi que vous souhaitez prendre en charge, comme les touches de raccourci pour mettre en gras ou en italique le texte, ou appliquer une correction de la vérification orthographique.
Gérer les modifications apportées aux sélections d'utilisateurs
Lorsque la sélection de l'utilisateur change en raison de la saisie au clavier ou à la souris, vous devez en informer l'instance EditContext. Cela est nécessaire, car l'API EditContext s'applique à un grand nombre de cas d'utilisation, y compris aux éditeurs affichés avec l'élément <canvas>
, où le navigateur ne peut pas détecter automatiquement les modifications de sélection.
document.addEventListener('selectionchange', () => {
const selection = document.getSelection();
// EditContext doesn't handle caret navigation, so all the caret navigation/selection that happens
// in DOM space needs to be mapped to plain text space by the author and passed to EditContext.
// This example code assumes the editable area only contains text under a single node.
editContext.updateSelection(selection.anchorOffset, selection.focusOffset);
});
Si l'élément que vous utilisez avec EditContext est un élément <canvas>
, vous devez également implémenter les comportements de sélection et de navigation au curseur de saisie, comme la navigation dans le texte à l'aide des touches fléchées. De plus, le correcteur orthographique intégré au navigateur ne fonctionne que dans les éléments non-<canvas>
.
EditContext par rapport à contenteditable
EditContext est un excellent choix si vous implémentez un éditeur complet et que vous souhaitez contrôler complètement la gestion de la saisie de texte, ou si vous ajoutez des fonctionnalités avancées telles que la coédition avec plusieurs utilisateurs. Toutefois, compte tenu de toutes les exigences précédentes concernant l'utilisation d'EditContext, si tout ce dont vous avez besoin est une prise en charge simple de la modification de texte, vous devrez probablement utiliser les éléments <input>
, <textarea>
ou l'attribut contenteditable
.
Et demain ?
L'équipe Microsoft Edge a implémenté EditContext dans Chromium en collaboration avec les ingénieurs Chrome. Elle est disponible dans la version 121 (janvier 2024) de Chrome et d'Edge. Pour le moment, cette fonctionnalité n'est disponible que dans les navigateurs basés sur Chromium, mais vous pouvez lire les positions de Mozilla et de WebKit sur l'API EditContext.
Nous souhaitons qu'il soit plus facile pour les développeurs Web de créer des expériences d'édition personnalisées et performantes sur le Web. Nous sommes convaincus que l'API EditContext y parvient en relevant les défis existants et en offrant un moyen plus direct de gérer la saisie de texte.
Pour en savoir plus sur l'API, consultez la documentation MDN. Pour envoyer des commentaires sur la conception de l'API, ouvrez un problème dans le dépôt GitHub de l'API EditContext. Pour signaler des bugs liés à l'implémentation de l'API, envoyez-les sur crbug.com.