Une nouvelle façon de créer des expériences d'édition Web personnalisées à l'aide de l'API EditContext

Il n'a pas toujours été simple pour les développeurs d'intégrer des fonctionnalités d'édition avancées à 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. Toutefois, les fonctionnalités de base de ces types d'éléments ne suffisent souvent pas à répondre aux attentes des développeurs.

Souvent, les développeurs implémentent leur propre vue d'éditeur personnalisée qui implémente la fonctionnalité dont leurs utilisateurs ont besoin. La vue de l'éditeur peut être créée avec un DOM complexe, ou même avec un élément <canvas>, mais comme le seul moyen pour le développeur de recevoir du texte nécessite un élément modifiable sélectionné, il doit tout de même placer un élément contenteditable masqué sur sa page.

Alors que l'utilisateur semble modifier directement le contenu dans la vue de l'éditeur personnalisé de l'application, le développeur reçoit 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 confronté au 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 piloté la standardisation de EditContext, une nouvelle API de plate-forme Web qui permet aux développeurs de recevoir des entrées de texte directement, sans dépendre des comportements d'édition par défaut du navigateur.

Exemple concret

Par exemple, lorsque des utilisateurs collaborent dans Word Online. Les utilisateurs peuvent modifier plusieurs éléments simultanément, et voir les modifications et les positions de curseur des autres utilisateurs. Toutefois, si un collaborateur utilise une fenêtre Éditeur du mode de saisie (IME) pour rédiger du texte en japonais, par exemple, son éditeur ne sera pas mis à jour pour afficher les modifications des autres utilisateurs tant que l'éditeur IME n'aura pas terminé sa rédaction. En effet, apporter des modifications à la zone du DOM en cours de modification alors qu'il existe une composition IME 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.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> Problème de collaboration dans Word Online lors de la rédaction de texte
.

Afin d'améliorer l'expérience utilisateur et celle des développeurs, les développeurs doivent pouvoir dissocier les entrées textuelles de l'affichage HTML DOM. L'API EditContext est la solution à ce problème.

Principes de base d'EditContext

Avec EditContext, vous pouvez recevoir des entrées de texte et de composition directement via la surface de l'API EditContext, plutôt qu'en observant les modifications apportées au DOM. Cela permet de contrôler plus précisément la façon dont l'entrée est traitée et d'ajouter de la modification à 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'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 modifiable, l'API EditContext a besoin de certaines informations. Outre l'affichage du texte et de 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 aide la plate-forme à décider où afficher les fenêtres IME et d'autres UI d'édition 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 d'édition spécifiques à la plate-forme.

Application de la mise en forme...

Écoutez l'événement textformatupdate et appliquez la mise en forme spécifiée par celui-ci à 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.

Capture d&#39;écran d&#39;une fenêtre de l&#39;éditeur de mode de saisie utilisée pour la saisie de caractères japonais.

Gérer les comportements d'édition de texte enrichi

Écoutez l'événement beforeinput pour gérer les comportements de modification de texte enrichi que vous souhaitez activer, comme l'utilisation de touches d'accès rapide pour mettre du texte en gras ou en italique, ou pour appliquer une correction 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. Cette opération 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>, lorsque le navigateur ne peut pas détecter automatiquement les changements 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>.

Comparaison entre EditContext et contenteditable

EditContext est un excellent choix si vous mettez en œuvre un éditeur complet et souhaitez contrôler totalement la saisie de texte, ou si vous ajoutez des fonctionnalités avancées telles que l'édition collaborative avec plusieurs utilisateurs. Toutefois, compte tenu de toutes les conditions requises précédentes pour utiliser EditContext, si vous n'avez besoin que d'une assistance pour l'édition de texte, vous aurez probablement besoin d'utiliser <input>, les éléments <textarea> ou l'attribut contenteditable.

Et demain ?

L'équipe Microsoft Edge a implémenté EditContext dans Chromium en collaboration avec les ingénieurs Chrome, et lance 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 nous faire part de vos commentaires sur la conception de l'API, signalez 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, rendez-vous sur crbug.com.