Un nuovo modo per creare esperienze di modifica web personalizzate utilizzando l'API EditContext

Non è sempre stato un'attività semplice per gli sviluppatori incorporare funzionalità di modifica avanzate nelle proprie applicazioni web. La piattaforma web consente di modificare i documenti in testo normale e HTML utilizzando elementi come <input> e <textarea> oppure applicando l'attributo contenteditable agli elementi. Tuttavia, le funzionalità di base di questi tipi di elementi spesso non sono sufficienti per ciò che gli sviluppatori vogliono ottenere nelle loro app.

Spesso gli sviluppatori hanno implementato una propria visualizzazione dell'editor personalizzata che implementa le funzionalità necessarie per i propri utenti. La visualizzazione dell'editor potrebbe essere creata con un DOM complesso o anche con un elemento <canvas>, ma poiché l'unico modo per lo sviluppatore di ricevere input di testo richiede un elemento modificabile attivo, dovrà comunque inserire un elemento contenteditable nascosto da qualche parte nella pagina.

Il risultato è che, anche se l'utente sembra modificare direttamente i contenuti nella visualizzazione dell'editor personalizzato dell'app, lo sviluppatore riceve effettivamente l'input con i gestori degli eventi nell'elemento nascosto e poi lo esegue il mirroring nella visualizzazione dell'editor visibile. Ciò può causare problemi perché lo sviluppatore finisce per dover fare i conti con il comportamento di modifica predefinito del browser nell'elemento contenteditable nascosto.

Per risolvere questo tipo di problemi, il team di Microsoft Edge ha promosso la standardizzazione di EditContext, una nuova API della piattaforma web che consente agli sviluppatori di ricevere direttamente l'input di testo senza essere vincolati ai comportamenti di modifica predefiniti del browser.

Un esempio reale

ad esempio quando gli utenti collaborano in Word Online. Gli utenti possono apportare modifiche in collaborazione e vedere le modifiche e le posizioni del cursore degli altri. Tuttavia, se un collaboratore utilizza una finestra Input Method Editor (IME) per scrivere testo in giapponese, ad esempio, l'editor non verrà aggiornato per mostrare le modifiche di altri utenti finché l'utente IME non avrà terminato la composizione. Questo perché apportare modifiche all'area del DOM in fase di modifica quando è attiva una composizione IME può causare l'annullamento prematuro della composizione. L'applicazione deve attendere che la finestra dell'IME venga chiusa per aggiornare la visualizzazione, il che può causare ritardi e ostacolare la collaborazione.

Problemi di collaborazione in Word Online durante la composizione del testo

Per offrire un'esperienza migliore sia agli sviluppatori che agli utenti, gli sviluppatori hanno bisogno di un modo per disaccoppiare l'input di testo dalla visualizzazione DOM HTML. L'API EditContext è la soluzione a questo problema.

Nozioni di base su EditContext

Con EditContext, puoi ricevere input di testo e composizione direttamente tramite la piattaforma dell'API EditContext, anziché osservando le modifiche al DOM. Ciò consente un controllo più rigoroso sulla modalità di gestione dell'input e consente persino di aggiungere la modificabilità all'elemento <canvas>.

L'associazione di un'istanza EditContext a un elemento rende quest'ultimo modificabile:

// 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à dell'autore

L'utilizzo dell'API EditContext semplifica il supporto di metodi di inserimento avanzati come finestre di composizione IME, selettori di emoji e altre interfacce di input del sistema operativo. Per rendere tutto ciò possibile nell'elemento modificabile, l'API EditContext richiede alcune informazioni. Oltre a eseguire il rendering del testo e la selezione, ci sono altre cose che devi fare quando utilizzi l'API EditContext.

Gestione del lato di una regione modificabile o se la selezione dell'utente cambia

Chiama i metodi updateControlBounds() e updateSelectionBounds() per informare l'istanza EditContext ogni volta che le dimensioni della regione modificabile o la selezione dell'utente cambiano. Ciò consente alla piattaforma di decidere dove mostrare le finestre IME e altre UI di modifica specifiche della piattaforma.

// 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);

Gestione della posizione dell'interfaccia utente dell'editor

Ascolta l'evento characterboundsupdate e chiama updateCharacterBounds() per aiutare la piattaforma a decidere dove mostrare le finestre IME e altre UI di modifica specifiche della piattaforma.

Applicazione della formattazione in corso...

Ascolta l'evento textformatupdate e applica la formattazione specificata dall'evento alla visualizzazione dell'editor. Queste decorazioni di testo vengono utilizzate dagli IME durante la composizione di determinate lingue. Ad esempio, un IME giapponese utilizzerà un'evidenziazione per mostrare la parte di testo in fase di composizione.

Uno screenshot di una finestra di Input Method Editor utilizzata per l&#39;inserimento di caratteri giapponesi.

Gestione dei comportamenti di modifica del testo avanzato

Ascolta l'evento beforeinput per gestire eventuali comportamenti di modifica del testo avanzato che vuoi supportare, ad esempio le scorciatoie da tastiera per applicare il grassetto o il corsivo al testo o per applicare una correzione ortografica.

Gestione delle modifiche alle selezioni degli utenti

Quando la selezione dell'utente cambia a causa dell'input della tastiera o del mouse, devi informare l'istanza di EditContext della modifica. Questo è necessario a causa dell'applicabilità dell'API EditContext a un numero elevato di casi d'uso, inclusi gli editor visualizzati con l'elemento <canvas> in cui il browser non è in grado di rilevare automaticamente le modifiche alla selezione.

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);
});

Se l'elemento che utilizzi con EditContext è un elemento <canvas>, devi anche implementare i comportamenti di selezione e navigazione con il cursore, ad esempio la navigazione nel testo con i tasti Freccia. Inoltre, il controllo ortografico integrato del browser funziona solo negli elementi diversi da <canvas>.

Confronto tra EditContext e contenteditable

EditContext è un'ottima scelta se stai implementando un editor completo e vuoi avere il controllo completo sulla modalità di gestione dell'input di testo oppure se stai aggiungendo funzionalità avanzate come la modifica collaborativa con più utenti. Tuttavia, dati tutti i requisiti precedenti per l'utilizzo di EditContext, se hai bisogno solo di un semplice supporto per la modifica del testo, probabilmente vorrai comunque utilizzare gli elementi <input>, <textarea> o l'attributo contenteditable.

Prospettive future

Il team di Microsoft Edge ha implementato EditContext in Chromium in collaborazione con gli ingegneri di Chrome e lo ha reso disponibile nella release 121 (gennaio 2024) di Chrome ed Edge. Per il momento, è disponibile solo nei browser basati su Chromium, ma puoi leggere le posizioni di Mozilla e WebKit nell'API EditContext.

Vogliamo semplificare la creazione di potenti esperienze di modifica personalizzate sul web per gli sviluppatori web e riteniamo che l'API EditContext lo ottenga affrontando le sfide esistenti e offrendo un modo più diretto per gestire l'input di testo.

Per scoprire di più sull'API, consulta la documentazione MDN. Per inviare un feedback sulla progettazione dell'API, apri un problema nel repository GitHub dell'API EditContext. Per segnalare bug relativi all'implementazione dell'API, invia un bug all'indirizzo crbug.com.