Przedstawiamy nowy sposób tworzenia niestandardowych funkcji do edytowania stron internetowych za pomocą interfejsu EditContext API

Wprowadzanie zaawansowanych funkcji edycji w aplikacji internetowej nie zawsze było proste. Platforma internetowa umożliwia edytowanie zarówno dokumentów tekstowych, jak i dokumentów HTML za pomocą elementów takich jak <input><textarea> lub przez zastosowanie atrybutu contenteditable do elementów. Jednak podstawowe możliwości tych typów elementów często nie wystarczają do tego, co deweloperzy chcą osiągnąć w swoich aplikacjach.

Deweloperzy często implementowali własne widoki niestandardowego edytora, które zapewniały funkcje potrzebne użytkownikom. Widok edytora może być utworzony za pomocą złożonego DOM-u lub nawet elementu <canvas>, ale ponieważ jedynym sposobem, w jaki deweloper może otrzymywać tekst, jest skupiony element edytowalny, musi on gdzieś na stronie umieścić ukryty element contenteditable.

W efekcie, gdy użytkownik wydaje się bezpośrednio edytować zawartość w widoku niestandardowego edytora aplikacji, deweloper faktycznie otrzymuje dane wejściowe za pomocą elementów obsługujących zdarzenia w ukrytym elemencie, a potem odzwierciedla je w widocznym widoku edytora. Może to powodować problemy, ponieważ deweloper musi walczyć z domyślnym zachowaniem przeglądarki w ukrytym elemencie contenteditable.

Aby rozwiązać tę klasę, zespół Microsoft Edge wprowadził ustandaryzowanie EditContext, nowego interfejsu API platformy internetowej, który umożliwia programistom bezpośrednie otrzymywanie tekstu bez konieczności łączenia się z domyślnymi ustawieniami edycji w przeglądarce.

Przykład praktycznego zastosowania

Na przykład, gdy użytkownicy współpracują w Word Online. Użytkownicy mogą wspólnie edytować pliki i widzieć zmiany oraz pozycje kursorów innych użytkowników. Jeśli jednak jeden z współpracowników używa okna edytora metody wprowadzania (IME), aby tworzyć tekst w języku japońskim, jego edytor nie będzie aktualizowany, aby uwzględniać zmiany wprowadzane przez innych użytkowników, dopóki użytkownik IME nie zakończy tworzenia tekstu. Dzieje się tak, ponieważ wprowadzanie zmian w obszarze DOM podczas aktywnej kompozycji IME może spowodować przedwczesne anulowanie kompozycji. Aplikacja musi poczekać, aż okno IME zostanie zamknięte, aby zaktualizować widok. Może to powodować opóźnienia i utrudniać współpracę.

Problemy z współpracą w Word Online podczas tworzenia tekstu

Aby zapewnić lepsze wrażenia zarówno deweloperom, jak i użytkownikom, deweloperzy muszą mieć możliwość rozdzielenia danych wejściowych tekstu od widoku DOM HTML. Rozwiązaniem tego problemu jest interfejs EditContext API.

Podstawy funkcji EditContext

Dzięki EditContext możesz otrzymywać dane wejściowe dotyczące tekstu i kompozycji bezpośrednio przez interfejs EditContext API, a nie przez obserwowanie zmian w interfejsie DOM. Zapewnia to ściślejszą kontrolę nad sposobem obsługi danych wejściowych, a nawet umożliwia dodanie możliwości edycji elementu <canvas>.

Powiązanie instancji EditContext z elementem umożliwia jej edycję:

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

Obowiązki autora

Użycie interfejsu EditContext API ułatwia obsługę zaawansowanych metod wprowadzania, takich jak okna kompozycji IME, selektory emotikonów i inne platformy do wprowadzania danych w systemie operacyjnym. Aby umożliwić edycję elementu, interfejs EditContext API wymaga podania pewnych informacji. Oprócz renderowania tekstu i wyboru musisz wykonać jeszcze kilka innych czynności podczas korzystania z interfejsu EditContext API.

Zarządzanie bokiem obszaru do edycji lub po zmianie wyboru użytkownika

Wywołuj metody updateControlBounds()updateSelectionBounds(), aby poinformować instancję EditContext, gdy rozmiar edytowalnego regionu lub zaznaczenie użytkownika ulegnie zmianie. Ułatwia to platformie podjęcie decyzji, gdzie mają wyświetlić się okna IME i inny interfejs użytkownika do edycji dostosowany do platformy.

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

zarządzanie pozycją interfejsu edytora.

Nasłuchuj zdarzenia characterboundsupdate i w odpowiedzi na nie wywołuj metody updateCharacterBounds(), aby pomóc platformie zdecydować, gdzie wyświetlać okna IME i inne interfejsy edycji specyficzne dla platformy.

Stosowanie formatowania

Nasłuchuj zdarzenie textformatupdate i zastosuj formatowanie określone przez to zdarzenie w widoku edytora. Dekoracje tekstu są używane przez edytory IME podczas tworzenia wiadomości w określonych językach. Na przykład japoński edytor IME użyje podkreślenia, by pokazać, która część tekstu jest aktywnie tworzona.

Zrzut ekranu okna Edytora metody wprowadzania służącego do wpisywania znaków japońskich.

Obsługa zachowań edycji tekstu sformatowanego

Słuchaj zdarzenia beforeinput, aby obsługiwać dowolne zachowania edycji tekstu sformatowanego, które chcesz obsługiwać, takie jak skróty klawiszowe do pogrubienia lub pochylenia tekstu czy stosowanie korekty pisowni.

Zarządzanie zmianami w wyborach użytkownika

Gdy wybór użytkownika zmieni się z powodu danych wejściowych z klawiatury lub myszy, musisz poinformować o tej zmianie instancję EditContext. Jest to konieczne, ponieważ interfejs EditContext API jest przydatny w wielu przypadkach użycia, w tym w przypadku edytorów renderowanych za pomocą elementu <canvas>, w których przeglądarka nie może automatycznie wykryć zmian w wybranym obszarze.

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

Jeśli element, którego używasz w EditContext, jest elementem <canvas>, musisz też zaimplementować zachowania nawigacyjne zaznaczania i nawigacji przy użyciu kursora, np. nawigowanie po tekście za pomocą klawiszy strzałek. Ponadto wbudowana funkcja sprawdzania pisowni w przeglądarce działa tylko w elementach innych niż <canvas>.

EditContext a contenteditable

EditContext to świetny wybór, jeśli wdrażasz w pełni funkcjonalny edytor i chcesz mieć pełną kontrolę nad sposobem obsługi wprowadzania tekstu lub jeśli dodajesz zaawansowane funkcje, takie jak współedytowanie przez wielu użytkowników. Jeśli jednak wystarczy Ci proste edytowanie tekstu, nadal użyjesz elementów <input>, <textarea> lub atrybutu contenteditable.

Pozdrawiam

Zespół Microsoft Edge wdrożył rozszerzenie EditContext w Chromium przy pomocy inżynierów Chrome. Udostępniane są wersje 121 (styczeń 2024 r.) Chrome i Edge. W tej chwili jest on dostępny tylko w przeglądarkach opartych na Chromium, ale informacje o pozycji Mozilli i WebKit znajdziesz w interfejsie EditContext API.

Chcemy ułatwić programistom stron internetowych tworzenie zaawansowanych, niestandardowych funkcji edycji w internecie. Wierzymy, że interfejs EditContext API pozwala to osiągnąć, rozwiązując istniejące problemy i oferując bardziej bezpośredni sposób wprowadzania tekstu.

Więcej informacji o interfejsie API znajdziesz w dokumentacji MDN. Aby przesłać opinię na temat interfejsu API, otwórz zgłoszenie w repozytorium GitHub interfejsu EditContext API. Aby zgłosić błędy implementacji interfejsu API, prześlij raport o błędach na stronie crbug.com.