Signatur
Beschreibung
Die Schnittstelle TextFormat gehört zur EditContext API. Mit dieser API lassen sich eigene Texteditoren bauen, etwa auf Basis von <canvas> oder eigenen DOM-Strukturen, die trotzdem vollständig mit dem Eingabesystem des Betriebssystems zusammenarbeiten. Dazu gehören IMEs für Chinesisch, Japanisch oder Koreanisch, Bildschirmtastaturen und Diktierfunktionen.
Während einer Texteingabe mit Komposition (Composition) will die IME bestimmte Abschnitte des noch nicht bestätigten Textes hervorheben, meist durch eine Unterstreichung. Der Browser löst dann auf dem EditContext das Ereignis textformatupdate aus. Über event.getTextFormats() bekommt man ein Array von TextFormat-Objekten. Jedes Objekt gibt einen Bereich an (rangeStart bis rangeEnd, als Zeichenpositionen im Text des EditContext) und legt fest, wie dieser Bereich dargestellt werden soll.
Die Instanzeigenschaften sind alle schreibgeschützt:
rangeStart(number): Anfangsposition des Bereichs, inklusive.rangeEnd(number): Endposition des Bereichs, exklusive.underlineStyle(string):"none","solid","dotted","dashed"oder"wavy".underlineThickness(string):"none","thin"oder"thick".
Der Browser zeichnet diese Formate nicht selbst. Die Anwendung muss sie selbst darstellen, zum Beispiel über die CSS Custom Highlight API oder durch Zeichnen auf einem Canvas. Mit dem Konstruktor new TextFormat(options) lassen sich außerdem eigene Instanzen erzeugen, etwa für Tests.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | Object | {} | Optionales Objekt für den Konstruktor new TextFormat(options). |
| $options.rangeStart | number | 0 | Anfangsposition des formatierten Bereichs, inklusive. |
| $options.rangeEnd | number | 0 | Endposition des formatierten Bereichs, exklusive. |
| $options.underlineStyle | "none" | "solid" | "dotted" | "dashed" | "wavy" | "none" | Stil der Unterstreichung. |
| $options.underlineThickness | "none" | "thin" | "thick" | "none" | Stärke der Unterstreichung. |
Rückgabewert
TextFormat-Instanz. Im normalen Einsatz bekommt man die Objekte jedoch über TextFormatUpdateEvent.getTextFormats() als Array.Beispiele
Formate beim textformatupdate-Ereignis auslesen
// <div id="editor"></div> im HTML
const editor = document.getElementById('editor');
if ('EditContext' in window) {
const editContext = new EditContext();
editor.editContext = editContext;
editContext.addEventListener('textformatupdate', (event) => {
const formats = event.getTextFormats();
for (const format of formats) {
console.log(
`Bereich ${format.rangeStart}–${format.rangeEnd}:`,
format.underlineStyle,
format.underlineThickness
);
}
});
} else {
console.warn('EditContext API wird nicht unterstützt.');
}
IME-Formate mit der CSS Custom Highlight API darstellen
/* CSS:
::highlight(ime-thin) { text-decoration: underline 1px; }
::highlight(ime-thick) { text-decoration: underline 3px; }
::highlight(ime-wavy) { text-decoration: underline wavy; }
*/
const editor = document.getElementById('editor');
const editContext = new EditContext();
editor.editContext = editContext;
// Text selbst rendern (vereinfacht: ein einziger Textknoten)
editContext.addEventListener('textupdate', () => {
editor.textContent = editContext.text;
});
editContext.addEventListener('textformatupdate', (event) => {
const textNode = editor.firstChild;
const groups = { 'ime-thin': new Highlight(), 'ime-thick': new Highlight(), 'ime-wavy': new Highlight() };
if (textNode) {
for (const f of event.getTextFormats()) {
if (f.underlineStyle === 'none') continue;
const range = new Range();
range.setStart(textNode, f.rangeStart);
range.setEnd(textNode, f.rangeEnd);
const key = f.underlineStyle === 'wavy'
? 'ime-wavy'
: f.underlineThickness === 'thick' ? 'ime-thick' : 'ime-thin';
groups[key].add(range);
}
}
for (const [name, highlight] of Object.entries(groups)) {
CSS.highlights.set(name, highlight);
}
});
// Nach Ende der Komposition Hervorhebungen entfernen
editContext.addEventListener('compositionend', () => {
['ime-thin', 'ime-thick', 'ime-wavy'].forEach((n) => CSS.highlights.delete(n));
});
Eigene TextFormat-Instanz erzeugen (z. B. für Tests)
const format = new TextFormat({
rangeStart: 2,
rangeEnd: 5,
underlineStyle: 'dashed',
underlineThickness: 'thin'
});
console.log(format.rangeStart, format.rangeEnd);
console.log(format.underlineStyle, format.underlineThickness);
// Wichtig · Fallstricke
- Experimentell: Die EditContext API und damit
TextFormatgibt es bisher nur in Chromium-Browsern (Chrome/Edge ab 121). Prüfe die Unterstützung vorher mit'EditContext' in windowund sieh eine Ausweichlösung vor, etwacontenteditableoder<textarea>. - Keine automatische Darstellung: Der Browser liefert die Formate nur als Daten. Wenn deine Anwendung sie nicht selbst zeichnet, sieht der Nutzer während der IME-Komposition keine Hervorhebung.
- Positionen beziehen sich auf
editContext.text, nicht auf DOM-Knoten. Sie zählen in UTF-16-Codeeinheiten. Wenn du den Text auf mehrere Knoten verteilst, musst du die Positionen selbst in DOM-Bereiche umrechnen. - Die Werte können sich unterscheiden: Frühe Entwürfe der Spezifikation hatten zusätzlich Eigenschaften wie
textColor,backgroundColorundunderlineColor. Diese wurden wieder entfernt. Einige frühe Chromium-Versionen lieferten die Werte außerdem großgeschrieben (z. B."Solid"). Vergleiche zur Sicherheit ohne Beachtung der Groß-/Kleinschreibung, etwa mitvalue.toLowerCase(). - Die Formate gelten nur für die laufende Komposition. Entferne deine Hervorhebungen bei
compositionendoder beim nächstentextformatupdate.