EditContext API'yi kullanarak özel web düzenleme deneyimleri oluşturmanın yeni bir yolu

Geliştiricilerin web uygulamalarına gelişmiş düzenleme özellikleri eklemesi her zaman kolay olmamıştır. Web platformu, <input> ve <textarea> gibi öğeleri kullanarak veya öğelere contenteditable özelliğini uygulayarak hem düz metin hem de HTML dokümanları için düzenlenebilirlik sağlar. Ancak bu öğe türlerinin temel özellikleri, geliştiricilerin uygulamalarında ulaşmak istedikleri hedefler için genellikle yeterli değildir.

Geliştiriciler genellikle kullanıcılarının ihtiyaç duyduğu işlevleri uygulayan kendi özel düzenleyici görünümlerini uygulamaya koymuştur. Düzenleyici görünümü karmaşık bir DOM ile veya hatta bir <canvas> öğesiyle oluşturulabilir ancak geliştiricinin metin girişi almasının tek yolu odaklanmış bir düzenlenebilir öğe gerektirdiğinden, sayfalarına bir yere gizli bir contenteditable öğesi yerleştirmeleri gerekir.

Sonuç olarak, kullanıcı uygulamanın özel düzenleyici görünümünde içeriği doğrudan düzenlerken geliştirici aslında girişi gizli öğedeki etkinlik işleyicileriyle alır ve görünür düzenleyici görünümüne yansıtır. Geliştirici, gizli contenteditable öğesindeki tarayıcı varsayılan düzenleme davranışıyla mücadele etmeye başladığından bu durum sorunlara yol açabilir.

Microsoft Edge ekibi, bu tür sorunları gidermek için geliştiricilerin tarayıcı varsayılan düzenleme davranışlarına bağlı kalmadan doğrudan metin girişi almasına olanak tanıyan yeni bir web platformu API'si olan EditContext'in standartlaştırılmasını sağladı.

Gerçek hayattan örnek

Örneğin, kullanıcılar Word Online'da ortak çalışma yaparken. Kullanıcılar birlikte düzenleme yapabilir ve birbirlerinin değişikliklerini ve imleç konumlarını görebilir. Ancak, ortak çalışanlardan biri Japonca metin oluşturmak için Giriş Yöntemi Düzenleyicisi (IME) penceresi kullanıyorsa IME kullanıcısı metin oluşturmayı tamamlayana kadar düzenleyicisi, diğer kullanıcıların yaptığı değişiklikleri gösterecek şekilde güncellenmez. Bunun nedeni, etkin bir IME bileşimi varken düzenlenen DOM alanında değişiklik yapılmasının bileşimin erken iptal edilmesine neden olabilmesidir. Uygulama, görünümü güncellemek için IME penceresinin kapanmasını beklemelidir. Bu durum gecikmeye neden olabilir ve ortak çalışmayı engelleyebilir.

Metin yazarken Word Online'da ortak çalışmayla ilgili sorun

Geliştiricilerin hem geliştiricilere hem de kullanıcılara daha iyi bir deneyim sunmak için metin girişini HTML DOM görünümünden ayırmanın bir yoluna ihtiyacı vardır. EditContext API, bu sorunun çözümüdür.

EditContext ile ilgili temel bilgiler

EditContext ile, DOM'daki değişiklikleri gözlemlemek yerine metin ve kompozisyon girişini doğrudan EditContext API yüzeyi üzerinden alabilirsiniz. Bu, girişin nasıl işlendiği konusunda daha sıkı kontrol sağlar ve hatta <canvas> öğesine düzenlenebilirlik özelliği eklemenize olanak tanır.

EditContext örneğini bir öğeyle ilişkilendirmek, öğeyi düzenlenebilir hale getirir:

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

Yazarın sorumlulukları

EditContext API'yi kullanmak, IME kompozisyon pencereleri, emoji seçicileri ve diğer işletim sistemi giriş yüzeyleri gibi gelişmiş giriş yöntemlerini desteklemeyi kolaylaştırır. Düzenlenebilir öğenizde tüm bunların mümkün olabilmesi için EditContext API'nin bazı bilgilere ihtiyacı vardır. EditContext API'yi kullanırken metni ve seçimi oluşturmanın yanı sıra yapmanız gereken başka şeyler de vardır.

Düzenlenebilir bir bölgenin tarafını yönetme veya kullanıcının seçiminin değişmesi

Düzenlenebilir bölgenin boyutu veya kullanıcının seçimi değiştiğinde EditContext örneğini bilgilendirmek için updateControlBounds() ve updateSelectionBounds() yöntemlerini çağırın. Bu, platformun IME pencerelerini ve platforma özgü diğer düzenleme kullanıcı arayüzlerini nerede göstereceğine karar vermesine yardımcı olur.

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

Düzenleyici kullanıcı arayüzünün konumunu yönetme

Platformun IME pencerelerini ve platforma özgü diğer düzenleme kullanıcı arayüzlerini nerede göstereceğine karar vermesine yardımcı olmak için characterboundsupdate etkinliğini dinleyin ve updateCharacterBounds() çağrısı yapın.

Biçimlendirmeyi uygulama

textformatupdate etkinliğini dinleyin ve etkinlik tarafından belirtilen biçimlendirmeyi düzenleyici görünümünüze uygulayın. Bu metin süslemeleri, IME'ler tarafından belirli diller yazılırken kullanılır. Örneğin, Japonca IME, metnin hangi kısmının etkin olarak yazıldığını göstermek için alt çizgi kullanır.

Japonca karakter girişi için kullanılan Giriş Yöntemi Düzenleyici penceresinin ekran görüntüsü.

Zengin metin düzenleme davranışlarını işleme

Metni kalın veya italik yazmak ya da yazım denetimi düzeltmesi uygulamak için kullanılan kısayol tuşları gibi desteklemek istediğiniz zengin metin düzenleme davranışlarını işlemek üzere beforeinput etkinliğini dinleyin.

Kullanıcı seçimlerinde yapılan değişiklikleri yönetme

Kullanıcının seçimi klavye veya fare girişi nedeniyle değiştiğinde, EditContext örneğini değişikliği hakkında bilgilendirmeniz gerekir. EditContext API'nin, tarayıcının seçim değişikliklerini otomatik olarak algılayamadığı <canvas> öğesiyle oluşturulan düzenleyiciler de dahil olmak üzere çok sayıda kullanım alanına uygulanabilir olması nedeniyle bu gereklidir.

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

EditContext ile kullandığınız öğe bir <canvas> öğesiyse ok tuşlarıyla metinde gezinme gibi seçim ve imleç gezinme davranışlarını da uygulamanız gerekir. Ayrıca, tarayıcının yerleşik yazım denetimi yalnızca <canvas> olmayan öğelerde çalışır.

EditContext ve contenteditable

Tam özellikli bir düzenleyici uyguluyorsanız ve metin girişinin nasıl işlendiği üzerinde tam kontrol sahibi olmak istiyorsanız ya da birden fazla kullanıcıyla birlikte düzenleme gibi gelişmiş özellikler ekliyorsanız EditContext mükemmel bir seçimdir. Ancak EditContext'i kullanmayla ilgili önceki tüm koşullar göz önüne alındığında, tek ihtiyacınız basit metin düzenleme desteğiyse yine de <input>, <textarea> öğelerini veya contenteditable özelliğini kullanmak isteyebilirsiniz.

Gelecek için sabırsızlanıyoruz

Microsoft Edge ekibi, Chrome mühendisleriyle birlikte çalışarak EditContext'i Chromium'a uyguladı ve bu özelliği hem Chrome hem de Edge'in 121 numaralı sürümünde (Ocak 2024) kullanıma sundu. Şu anda yalnızca Chromium tabanlı tarayıcılarda kullanılabilir ancak EditContext API ile ilgili Mozilla'nın ve WebKit'in görüşlerini okuyabilirsiniz.

Web geliştiricilerin web'de güçlü özel düzenleme deneyimleri oluşturmasını kolaylaştırmak istiyoruz. EditContext API'nin, mevcut zorlukları gidererek ve metin girişini işlemek için daha doğrudan bir yol sunarak bunu başaracağına inanıyoruz.

API hakkında daha fazla bilgi edinmek istiyorsanız MDN belgelerine göz atın. API'nin tasarımıyla ilgili geri bildirim göndermek için EditContext API'nin GitHub deposunda bir sorun açın. API'nin uygulanmasıyla ilgili hataları bildirmek için crbug.com adresinden hata gönderin.