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 eklemek her zaman kolay bir iş değildir. Web platformu, <input> ve <textarea> gibi öğeleri kullanarak veya contenteditable özelliğini öğelere 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 olmaz.

Geliştiriciler genellikle, kullanıcılarının ihtiyaç duyduğu işlevleri uygulayan kendi özel düzenleyici görünümlerini uygulamak durumundadır. Düzenleyici görünümü karmaşık bir DOM (veya bir <canvas> öğesiyle) ile oluşturulmuş olabilir. Ancak geliştiricinin metin girişi almasının tek yolu, odaklanmış bir düzenlenebilir öğe gerektirdiğinden, yine de sayfasında bir yere gizli contenteditable öğesi yerleştirmesi gerekir.

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

Bu türden sorunları çözmek için Microsoft Edge ekibi, geliştiricilerin tarayıcının varsayılan düzenleme davranışlarına bağlanmadan doğrudan metin girişi almasına olanak tanıyan yeni bir web platformu API'si olan EditContext'in standartlaştırılmasına öncülük etti.

Gerçek hayattan bir örnek

Örneğin, kullanıcılar Word Online'da ortak çalışırken. Kullanıcılar birlikte düzenleme yapabilir ve birbirlerinin değişikliklerini ve imleç konumlarını görebilir. Bununla birlikte, ortak çalışanlardan biri Japonca metin oluşturmak için Giriş Yöntemi Düzenleyici (IME) penceresi kullanıyorsa örneğin, IME kullanıcısı besteyi tamamlayana kadar kullanıcının düzenleyicisi diğer kullanıcıların yaptığı değişiklikleri gösterecek şekilde güncellenmez. Bunun nedeni, etkin bir IME bestesi varken düzenlenen DOM alanında yapılan değişikliklerin, bestenin zamanında iptal edilmesine neden olabilmesidir. Uygulamanın, görünümü güncellemek için IME penceresi kapatılana kadar beklemesi gerekir. Bu, gecikmelere neden olabilir ve ortak çalışmayı engelleyebilir.

Metin oluştururken Word Online'da ortak çalışma sorunu

Hem daha iyi bir geliştirici hem de kullanıcı deneyimi sağlamak için geliştiricilerin metin girişlerini HTML DOM görünümünden ayırabilecekleri bir yönteme ihtiyacı vardır. EditContext API, bu sorunun çözümüdür.

EditContext ile ilgili temel bilgiler

EditContext sayesinde, DOM'daki değişiklikleri gözlemlemek yerine, doğrudan EditContext API yüzeyi üzerinden metin ve beste girişi alabilirsiniz. Bu, girişin işlenme şekli üzerinde daha sıkı bir kontrole ve hatta <canvas> öğesine düzenlenebilirlik eklenmesine olanak tanır.

EditContext örneğinin bir öğeyle ilişkilendirilmesi, örneği 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'nin kullanılması, IME oluşturma pencereleri, emoji seçiciler ve diğer işletim sistemi giriş yüzeyleri gibi gelişmiş giriş yöntemlerinin desteklenmesini kolaylaştırır. Bunların tümünü düzenlenebilir öğenizde mümkün hale getirmek için EditContext API'sı bazı bilgilere ihtiyaç duyar. EditContext API'sini kullanırken metni ve seçimi oluşturmanın yanı sıra yapmanız gereken bazı başka işlemler de vardır.

Düzenlenebilir bir bölgenin tarafını yönetmek veya kullanıcının seçimi değişirse

Düzenlenebilir bölgenin boyutu veya kullanıcı seçimi her değiştiğinde EditContext örneğini bilgilendirmek için updateControlBounds() ve updateSelectionBounds() yöntemlerini çağırın. Bu, platformun IME pencerelerinin ve platforma özgü diğer düzenleme kullanıcı arayüzünün nerede gösterileceğ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

characterboundsupdate etkinliğini dinleyin ve 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 updateCharacterBounds() yöntemini çağırın.

Biçimlendirme uygulanıyor

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 oluşturulurken kullanılır. Örneğin, Japonca IME'de metnin hangi bölümünün etkin olarak oluşturulduğunu göstermek için alt çizgi kullanılır.

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

Zengin metin düzenleme davranışlarını yönetme

Metni kalın veya italik hale getirmek için kullanabileceğiniz kısayol tuşları ya da yazım denetimi düzeltmesi uygulama gibi, desteklemek istediğiniz zengin metin düzenleme davranışlarını gerçekleştirmek için beforeinput etkinliğini dinleyin.

Kullanıcı seçimlerindeki 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 bildirmeniz gerekir. Bu, EditContext API'sinin, 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ında uygulanabilirliği nedeniyle 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.

Bağlamı düzenleme ile contenteditable karşılaştırması

Tüm özelliklere sahip bir düzenleyici kullanıyorsanız ve metin girişinin işlenme şekli üzerinde tam denetime sahip olmak istiyorsanız ya da birden fazla kullanıcıyla birlikte düzenleme gibi gelişmiş özellikler ekliyorsanız EditContext harika bir seçenektir. Ancak, EditContext kullanımı için önceki tüm koşullar göz önünde bulundurulduğunda, ihtiyacınız olan tek şey basit metin düzenleme desteği ise yine de <input>, <textarea> öğelerini veya contenteditable özelliğini kullanmak istersiniz.

Beklenenler

Microsoft Edge ekibi, Chrome mühendisleriyle birlikte çalışarak Chromium'da EditContext özelliğini uyguladı ve hem Chrome hem de Edge'in 121 (Ocak 2024) sürümünü yayınladı. Şimdilik yalnızca Chromium tabanlı tarayıcılarda kullanılabilmektedir, ancak EditContext API'sinde Mozilla'nın ve WebKit'in konumlarını okuyabilirsiniz.

Web geliştiricilerin web'de güçlü özel düzenleme deneyimleri oluşturmasının daha kolay olmasını istiyoruz. EditContext API'nin, mevcut zorlukları ele alarak ve metin girişlerini işlemek için daha doğrudan bir yol sunarak bunu başardığına inanıyoruz.

API hakkında daha fazla bilgi edinmek istiyorsanız MDN belgelerini inceleyin. API'nin tasarımı hakkında geri bildirim göndermek için EditContext API'nin GitHub deposunda bir sorunu açın. API'nin uygulanmasındaki hataları bildirmek için crbug.com adresinden hata bildiriminde bulunun.