Midas: Firefox und Rich Text Editing

Vor ein paar Jahren bin ich beim Schmökern der Referenz-Seiten des IE_DOMs über eine Property (Eigenschaft) namens isContentEditable gestolpert, die einem beliebigen Tag auf der HTML-Seite Editor-Fähigkeiten zuschusterte. Es gab auch einen Beispiel-Editor, den ich aber nicht mehr finde. Mittlerweile ist daraus ein ganzes Thema bei Microsoft geworden: How to Create an HTML Editor Application. Da ich dann auch noch andere auf Webseiten einbaubare Editoren, wie TinyMCE oder htmlArea gefunden habe, die Plattform übergreifend funktioniert haben, ist mein Interesse abgeklungen, sich damit weiter zu beschäftigen.

Per Zufall bin ich vor ein paar Tagen wieder mit dem Thema konfrontiert worden. Diesmal war die Frage, gibt es einen eingebauten Editor auch beim Firefox. Ja, gibts! Geht aber anders, siehe Midas Specification. Es gibt hier kein für alle Tags geltendes Attribut; man kann nur das ganze Dokument (DOM-Node: document) editierbar machen oder nicht und zwar mit document.designMode="on" und das gilt dann für alle Elemente in diesem Dokument. Da man fast immer außer dem Editieren noch was anderes im Dokument stehen hat (Benutzeroberfläche usw.), gibt es eigentlich nur einen praktischen Weg: Man integriert den zu editierenden Bereich in ein iframe und gibt dem iframe das designMode-Attribute auf on mit:

<iframe id="editor" src="about:blank"
onload="javascript:this.contentDocument.designMode='on';"
>/iframe>

Es gibt eine Reihe von Kommandos, die auf das Editor-Verhalten einwirken. Das funktioniert alles so leidlich, dass es fast schön ist. <div>-Elemente, die man mit dem style="position:absolute" in den Editor-Bereich einfügt, lassen sich sogar wie Objekte anklicken und verschieben/in der Größe verändern. Einige Kommandos sind auch durch Tasten zu aktivieren (Strg-Z, Strg-Shift-Z, Strg-A, Strg-C, Strg-X, Strg-V). Etwas lästig ist das Fehlen einer de-select-Funktionalität (Gegenstück zu selectAll), weil wenn man ein <div>-Objekt angeklickt hat, wird es eingerahmt und diese Einrahmung wird man nicht wieder los. Aber man den de-select nachbauen, indem man kurzzeitig den designMode deaktiviert und dann wieder aktiviert.

Da der Editor die Events deaktiviert bzw. auf sich umleitet, gehen die onclick, onmouseover usw. nicht mehr. Daher muss man per EventHandler Events wie Click, DblClick usw. abfangen:

function myEventHandler(mEvent) {
 alert(mEvent.clientX+','+mEvent.clientY); }

Den EventHandler muss man an geeignet Stelle aufrufen, z. B. im body-Tag per onload:

<body onload="document.getElementById('editor').contentWindow
.addEventListener('click', myEventHandler, true);">

Man kann den Midas zu einem einfachen Editor ausbauen; ist ja fast alles an Board. An den gesamten Inhalt (<body>) des <iframe> gelangt man über das weiter unten beschriebene outerHTML; über das Lesen und Speichern von lokalen Dateien hab ich ja auch bereits weiter unten was geschrieben. Das Abspeichern auf dem Web-Server kann man per AJAX erledigen.