Mit der EditContext API benutzerdefinierte Bearbeitungsmöglichkeiten für Websites erstellen

Es war nicht immer eine einfache Aufgabe für Entwickler, erweiterte Bearbeitungsfunktionen in ihre Webanwendungen zu integrieren. Die Webplattform bietet Bearbeitungsmöglichkeiten sowohl für Nur-Text- als auch für HTML-Dokumente mithilfe von Elementen wie <input> und <textarea> oder durch Anwenden des contenteditable-Attributs auf Elemente. Die grundlegenden Funktionen dieser Elementtypen sind jedoch häufig nicht ausreichend für das, was Entwickler mit ihren Apps erreichen möchten.

Entwickler haben oft ihre eigene benutzerdefinierte Editoransicht implementiert, mit der die von den Nutzern benötigten Funktionen implementiert werden. Die Editoransicht kann mit einem komplexen DOM oder sogar mit einem <canvas>-Element erstellt werden. Da der Entwickler jedoch nur die Möglichkeit hat, Texteingaben zu erhalten, wenn ein hervorgehobenes bearbeitbares Element erforderlich ist, muss er trotzdem ein ausgeblendetes contenteditable-Element auf seiner Seite platzieren.

Das Ergebnis: Während der Nutzer den Inhalt in der benutzerdefinierten Editoransicht der App direkt bearbeitet, erhält der Entwickler die Eingabe mit Event-Handlern im ausgeblendeten Element und spiegelt sie dann in der sichtbaren Editoransicht. Dies kann zu Problemen führen, da der Entwickler letztendlich gegen das standardmäßige Bearbeitungsverhalten des Browsers für das ausgeblendete contenteditable-Element zu kämpfen hat.

Um diese Probleme anzugehen, hat das Microsoft Edge-Team die Standardisierung von EditContext vorangetrieben, einer neuen Webplattform-API, mit der Entwickler direkt Texteingaben empfangen können, ohne an das Standardverhalten des Browsers gebunden zu sein.

Ein Beispiel aus der Praxis

Zum Beispiel, wenn Nutzer in Word Online zusammenarbeiten. Die Nutzer können das Dokument gemeinsam bearbeiten und die Änderungen und Cursorpositionen der anderen sehen. Wenn ein Mitbearbeiter jedoch zum Schreiben von japanischem Text das Fenster Input Method Editor (IME) verwendet, wird der Editor erst aktualisiert, um Änderungen von anderen Nutzern anzuzeigen, bis der IME-Nutzer die Komposition abgeschlossen hat. Das liegt daran, dass Änderungen am Bereich des DOM, der bearbeitet wird, während eine aktive IME-Zusammensetzung vorhanden ist, dazu führen können, dass die Komposition vorzeitig abgebrochen wird. Die Anwendung muss warten, bis das IME-Fenster geschlossen wird, um die Ansicht zu aktualisieren. Dies kann zu Verzögerungen führen und die Zusammenarbeit behindern.

Probleme bei der Zusammenarbeit in Word Online beim Schreiben von Text

Um sowohl eine bessere Entwickler- als auch eine bessere Nutzererfahrung zu bieten, müssen Entwickler eine Möglichkeit haben, die Texteingabe von der HTML-DOM-Ansicht zu entkoppeln. Die EditContext API ist die Lösung für dieses Problem.

Grundlagen von EditContext

Mit EditContext können Sie Text- und Kompositionseingaben direkt über die EditContext API-Oberfläche empfangen, anstatt Änderungen am DOM zu beobachten. So lässt sich genauer steuern, wie die Eingabe verarbeitet wird, und das <canvas>-Element kann sogar bearbeitet werden.

Wenn Sie eine EditContext-Instanz mit einem Element verknüpfen, kann es bearbeitet werden:

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

Pflichten des Autors

Mit der EditContext API können erweiterte Eingabemethoden wie IME-Kombinationsfenster, Emoji-Auswahl und andere Eingabeoberflächen für Betriebssysteme einfacher unterstützt werden. Damit dies in Ihrem bearbeitbaren Element möglich ist, benötigt die EditContext API einige Informationen. Neben dem Rendern des Textes und der Auswahl müssen Sie bei der Verwendung der EditContext API noch einige andere Dinge tun.

Verwalten der Seite einer bearbeitbaren Region oder wenn sich die Auswahl des Nutzers ändert

Rufen Sie die Methoden updateControlBounds() und updateSelectionBounds() auf, um die EditContext-Instanz immer dann zu informieren, wenn sich die Größe der bearbeitbaren Region oder die Auswahl des Nutzers ändert. So kann die Plattform besser entscheiden, wo IME-Fenster und andere plattformspezifische Bearbeitungsoberflächen angezeigt werden.

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

Position der Benutzeroberfläche des Editors verwalten

Warten Sie auf das characterboundsupdate-Ereignis und rufen Sie updateCharacterBounds() als Reaktion auf, um der Plattform zu helfen, zu entscheiden, wo IME-Fenster und andere plattformspezifische Bearbeitungs-UIs angezeigt werden.

Formatierung wird angewendet

Warten Sie auf das Ereignis textformatupdate und wenden Sie die vom Ereignis angegebene Formatierung in Ihrer Editoransicht an. Diese Textdekorationen werden von IMEs beim Erstellen bestimmter Sprachen verwendet. Ein japanischer IME verwendet beispielsweise eine Unterstreichung, um zu zeigen, welcher Teil des Texts aktiv komponiert ist.

Screenshot eines Fensters für den Eingabemethoden-Editor, in dem japanische Zeichen eingegeben werden.

Umgang mit Rich-Text-Bearbeitungsverhalten

Prüfen Sie das beforeinput-Ereignis, um alle gewünschten Bearbeitungsfunktionen für Rich-Text zu verarbeiten, z. B. Hotkeys zum fett oder kursiv formatierten Text oder Anwenden einer Rechtschreibkorrektur.

Änderungen an der Nutzerauswahl verwalten

Wenn sich die Auswahl des Nutzers aufgrund einer Tastatur- oder Mauseingabe ändert, müssen Sie die EditContext-Instanz über diese Änderung informieren. Das ist notwendig, da die EditContext API für eine Vielzahl von Anwendungsfällen geeignet ist. Dazu gehören auch Editoren, die mit dem <canvas>-Element gerendert werden und bei denen der Browser Auswahländerungen nicht automatisch erkennen kann.

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

Wenn das Element, das Sie mit EditContext verwenden, ein <canvas>-Element ist, müssen Sie auch Auswahl- und Caret-Navigationsverhalten implementieren, z. B. das Navigieren durch Text mit Pfeiltasten. Außerdem funktioniert die integrierte Rechtschreibprüfung des Browsers nur bei Nicht-<canvas>-Elementen.

EditContext im Vergleich zu contenteditable

„EditContext“ ist eine gute Wahl, wenn Sie einen Editor mit allen Funktionen implementieren und die vollständige Kontrolle darüber haben möchten, wie die Texteingabe verarbeitet wird, oder wenn Sie erweiterte Funktionen wie die gemeinsame Bearbeitung mit mehreren Nutzern hinzufügen möchten. Angesichts der oben genannten Anforderungen für die Verwendung von „EditContext“ werden Sie wahrscheinlich trotzdem die Elemente <input>, <textarea> oder das Attribut contenteditable verwenden, wenn Sie lediglich die Unterstützung für die einfache Textbearbeitung benötigen.

Aussichten

Das Microsoft Edge-Team hat EditContext in Chromium in Zusammenarbeit mit Chrome-Entwicklern implementiert und veröffentlicht mit Version 121 (Januar 2024) sowohl Chrome als auch Edge. Derzeit ist die Funktion nur in Chromium-basierten Browsern verfügbar. Sie können sich jedoch die Positionen von Mozilla und WebKit in der EditContext API ansehen.

Wir möchten es Webentwicklern einfacher machen, leistungsstarke benutzerdefinierte Bearbeitungsfunktionen im Web zu erstellen. Wir sind der Meinung, dass die EditContext API dieses Ziel erreicht, indem sie bestehende Herausforderungen angeht und eine direktere Möglichkeit zur Verarbeitung von Texteingaben bietet.

Weitere Informationen zur API finden Sie in der MDN-Dokumentation. Wenn Sie Feedback zum Design der API geben möchten, können Sie ein Problem im GitHub-Repository der EditContext API erstellen. Wenn Sie Fehler bei der Implementierung der API melden möchten, können Sie diese unter crbug.com einreichen.