Introductie van een nieuwe manier om aangepaste webbewerkingservaringen te bouwen met behulp van de EditContext API

Het is voor ontwikkelaars niet altijd eenvoudig geweest om geavanceerde bewerkingsmogelijkheden in hun webapplicaties op te nemen. Het webplatform biedt bewerkbaarheid voor zowel platte tekst als HTML-documenten met behulp van elementen als <input> en <textarea> , of door het contenteditable attribuut op elementen toe te passen. De basismogelijkheden van deze elementtypen zijn echter vaak niet voldoende voor wat ontwikkelaars met hun apps willen bereiken.

Ontwikkelaars hebben vaak hun eigen aangepaste editorweergave geïmplementeerd die de functionaliteit implementeert die hun gebruikers nodig hebben. De editorweergave kan zijn gebouwd met een complexe DOM (of zelfs met een <canvas> -element), maar aangezien de enige manier waarop de ontwikkelaar tekstinvoer kan ontvangen een gericht bewerkbaar element vereist, zullen ze nog steeds een verborgen contenteditable element op de tekst moeten plaatsen. hun pagina ergens.

Het resultaat is dat terwijl het lijkt alsof de gebruiker de inhoud rechtstreeks bewerkt in de aangepaste editorweergave van de app, de ontwikkelaar feitelijk de invoer ontvangt met gebeurtenishandlers in het verborgen element en deze vervolgens spiegelt in de zichtbare editorweergave. Dit kan tot problemen leiden omdat de ontwikkelaar uiteindelijk in gevecht komt met het browserstandaard bewerkingsgedrag in het verborgen contenteditable element.

Om deze categorie problemen aan te pakken heeft het Microsoft Edge-team de standaardisatie van EditContext gestimuleerd, een nieuwe webplatform-API waarmee ontwikkelaars tekstinvoer rechtstreeks kunnen ontvangen zonder gebonden te zijn aan het standaard bewerkingsgedrag van de browser.

Een voorbeeld uit de praktijk

Bijvoorbeeld wanneer gebruikers samenwerken in Word Online. Gebruikers kunnen samen bewerken en elkaars wijzigingen en cursorposities bekijken. Als een bijdrager echter een IME-venster (Input Method Editor) gebruikt om bijvoorbeeld Japanse tekst op te stellen, wordt zijn editor pas bijgewerkt om wijzigingen van andere gebruikers weer te geven totdat de IME-gebruiker zijn compositie heeft voltooid. Dit komt omdat het aanbrengen van wijzigingen in het gebied van de DOM dat wordt bewerkt terwijl er een actieve IME-compositie is, ertoe kan leiden dat de compositie voortijdig wordt geannuleerd. De applicatie moet wachten tot het IME-venster wordt gesloten voordat de weergave wordt bijgewerkt, wat vertragingen kan veroorzaken en de samenwerking kan belemmeren.

Problemen met samenwerken in Word Online tijdens het opstellen van tekst

Om zowel een betere ontwikkelaars- als gebruikerservaring te bieden, hebben ontwikkelaars een manier nodig om tekstinvoer te ontkoppelen van de HTML DOM-weergave. De EditContext API is de oplossing voor dit probleem.

De basisprincipes van EditContext

Met EditContext kunt u tekst- en compositie-invoer rechtstreeks ontvangen via het EditContext API-oppervlak, in plaats van via het observeren van wijzigingen in de DOM. Dit zorgt voor een strakkere controle over de manier waarop de invoer wordt afgehandeld, en maakt het zelfs mogelijk om bewerkbaarheid aan het <canvas> -element toe te voegen.

Door een EditContext-instantie aan een element te koppelen, wordt deze bewerkbaar:

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

Verantwoordelijkheden van de auteur

Het gebruik van de EditContext API maakt het eenvoudiger om geavanceerde invoermethoden te ondersteunen, zoals IME-compositievensters, emoji-kiezers en andere invoeroppervlakken van het besturingssysteem. Om dit allemaal mogelijk te maken in uw bewerkbare element, heeft de EditContext API wat informatie nodig. Naast het weergeven van de tekst en selectie zijn er nog enkele andere dingen die u moet doen als u de EditContext API gebruikt.

Het beheren van de zijkant van een bewerkbaar gebied, of als de selectie van de gebruiker verandert

Roep de methoden updateControlBounds() en updateSelectionBounds() aan om de EditContext-instantie te informeren wanneer de grootte van het bewerkbare gebied of de selectie van de gebruiker verandert. Dit helpt het platform te beslissen waar IME-vensters en andere platformspecifieke bewerkingsinterfaces moeten worden weergegeven.

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

Beheer van de positie van de gebruikersinterface van de editor

Luister naar de characterboundsupdate gebeurtenis en roep updateCharacterBounds() aan om het platform te helpen beslissen waar IME-vensters en andere platformspecifieke bewerkingsinterfaces moeten worden weergegeven.

Opmaak toepassen

Luister naar de gebeurtenis textformatupdate en pas de door de gebeurtenis gespecificeerde opmaak toe op uw editorweergave. Deze tekstversieringen worden door IME's gebruikt bij het samenstellen van bepaalde talen. Een Japanse IME gebruikt bijvoorbeeld een onderstreping om aan te geven welk deel van de tekst actief wordt samengesteld.

Een screenshot van een Input Method Editor-venster dat wordt gebruikt voor de invoer van Japanse karakters.

Omgaan met rich-text-bewerkingsgedrag

Luister naar de beforeinput gebeurtenis om eventuele rich-text-bewerkingsgedragingen af ​​te handelen die u wilt ondersteunen, zoals sneltoetsen voor het vetgedrukt of cursief maken van tekst, of het toepassen van een spellingcontrolecorrectie.

Wijzigingen in gebruikersselecties beheren

Wanneer de selectie van de gebruiker verandert als gevolg van toetsenbord- of muisinvoer, moet u de EditContext-instantie op de hoogte stellen van de wijziging. Dit is nodig vanwege de toepasbaarheid van de EditContext API op een groot aantal gebruiksscenario's, inclusief editors die worden weergegeven met het <canvas> -element waarbij de browser selectiewijzigingen niet automatisch kan detecteren.

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

Als het element dat u gebruikt met EditContext een <canvas> -element is, moet u ook selectie- en cursornavigatiegedrag implementeren, zoals het navigeren door tekst met de pijltjestoetsen. Bovendien werkt de ingebouwde spellingcontrole van de browser alleen in niet- <canvas> -elementen.

EditContext versus contenteditable

EditContext is een uitstekende keuze als u een volledig uitgeruste editor implementeert en volledige controle wilt hebben over hoe tekstinvoer wordt afgehandeld, of als u geavanceerde functies toevoegt, zoals gezamenlijk bewerken met meerdere gebruikers. Gezien alle voorgaande vereisten voor het gebruik van EditContext, zul je echter, als je alleen ondersteuning voor eenvoudige tekstbewerking nodig hebt, waarschijnlijk nog steeds <input> , <textarea> elementen of het contenteditable attribuut willen gebruiken.

Ergens naar uitkijken

Het Microsoft Edge-team heeft EditContext in Chromium geïmplementeerd via een samenwerking met Chrome-technici en wordt geleverd met release 121 (januari 2024) van zowel Chrome als Edge. Voorlopig is het alleen beschikbaar in Chromium-gebaseerde browsers, maar je kunt de standpunten van Mozilla en WebKit over de EditContext API lezen.

We willen dat het voor webontwikkelaars gemakkelijker wordt om krachtige aangepaste bewerkingservaringen op internet te bouwen, en we geloven dat de EditContext API dit bereikt door bestaande uitdagingen aan te pakken en een directere manier te bieden om met tekstinvoer om te gaan.

Als je meer wilt weten over de API, raadpleeg dan de MDN-documentatie . Als u feedback wilt geven over het ontwerp van de API, opent u een issue in de Github-repository van de EditContext API . Om bugs bij de implementatie van de API te melden, dient u een bug in op crbug.com .