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

Non è sempre stato facile per gli sviluppatori incorporare funzionalità di modifica avanzate nelle loro applicazioni web. La piattaforma web consente la modifica di documenti in testo normale e HTML tramite elementi come <input> e <textarea> o 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 finito di implementare la propria visualizzazione di editor personalizzata che implementa la funzionalità di cui gli utenti hanno bisogno. La visualizzazione dell'editor potrebbe essere creata con un DOM complesso o anche con un elemento <canvas>, ma poiché l'unico modo in cui lo sviluppatore riceve l'input di testo richiede un elemento modificabile attivo, dovrà comunque inserire un elemento contenteditable nascosto nella pagina.

Il risultato è che mentre l'utente sembra modificare direttamente i contenuti nella visualizzazione dell'editor personalizzata dell'app, lo sviluppatore riceve l'input con i gestori di eventi nell'elemento nascosto e poi lo esegue il mirroring nella visualizzazione editor visibile. Questo può causare problemi, in quanto lo sviluppatore combatte con il comportamento di modifica predefinito del browser nell'elemento contenteditable nascosto.

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

Un esempio reale

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

Problemi di collaborazione in Word Online durante la scrittura del testo

Per offrire una migliore esperienza agli sviluppatori e 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 testo e input di composizione direttamente tramite la piattaforma dell'API EditContext, invece che osservando le modifiche al DOM. Ciò consente di avere un controllo maggiore sulla modalità di gestione dell'input e di aggiungere possibilità di modifica all'elemento <canvas>.

Se associ un'istanza di EditContext a un elemento, quest'ultimo può essere modificato:

// 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 immissione avanzati, come finestre di composizione IME, selettori di emoji e altre superfici di input dei sistemi operativi. Per rendere possibile tutto ciò nel tuo elemento modificabile, l'API EditContext richiede alcune informazioni. Oltre al rendering del testo e della selezione, quando utilizzi l'API EditContext devi fare anche altre cose.

Gestire il lato di una regione modificabile o se la selezione dell'utente cambia

Richiama i metodi updateControlBounds() e updateSelectionBounds() per informare l'istanza EditContext ogni volta che la dimensione della regione modificabile o la selezione dell'utente cambia. In questo modo la piattaforma può 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() in risposta per aiutare la piattaforma a decidere dove mostrare le finestre IME e altre UI di modifica specifiche della piattaforma.

Applicazione della formattazione

Ascolta l'evento textformatupdate e applica la formattazione specificata dall'evento alla visualizzazione di editor. Queste decorazioni di testo vengono utilizzate dagli IME durante la scrittura di determinate lingue. Ad esempio, un IME per il giapponese userà una sottolineatura per mostrare la parte del testo in fase di scrittura attiva.

Uno screenshot di una finestra dell&#39;Editor del metodo di input utilizzata per l&#39;inserimento di caratteri giapponesi.

Gestione dei comportamenti di modifica nel formato RTF

Ascolta l'evento beforeinput per gestire eventuali comportamenti di modifica RTF che vuoi supportare, come i tasti di scelta rapida per applicare il grassetto o il corsivo al testo, o applicare una correzione del controllo ortografico.

Gestire le modifiche alle selezioni degli utenti

Quando la selezione dell'utente cambia a causa dell'input della tastiera o del mouse, devi informare l'istanza EditContext del cambiamento. Ciò è necessario a causa dell'applicabilità dell'API EditContext a un ampio numero di casi d'uso, tra cui editor sottoposti a rendering 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>, dovrai anche implementare i comportamenti di selezione e navigazione con cursore, ad esempio lo spostamento all'interno del testo con i tasti freccia. Inoltre, il controllo ortografico integrato del browser funziona solo in elementi non <canvas>.

Confronto tra contesto e contenteditable

EditContext è un'ottima scelta se stai implementando un editor con funzionalità complete e vuoi avere il controllo completo su come viene gestito l'input di testo o se stai aggiungendo funzionalità avanzate come la modifica condivisa con più utenti. Tuttavia, dati tutti i requisiti precedenti per l'utilizzo di EditContext, se hai solo bisogno di un semplice supporto della 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 sarà disponibile con la release 121 (gennaio 2024) sia di Chrome che di Edge. Per il momento è disponibile solo nei browser basati su Chromium, ma puoi leggere le posizioni di Mozilla e WebKit nell'API EditContext.

Vogliamo che gli sviluppatori web possano creare più facilmente esperienze di modifica personalizzate efficaci sul web e crediamo che l'API EditContext possa farlo affrontando le sfide esistenti e offrendo un modo più diretto per gestire l'input di testo.

Per saperne di più sull'API, consulta la documentazione di 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 una segnalazione all'indirizzo crbug.com.