Dieser Artikel befasst sich mit einem Problem aus den Randbezirken der täglichen Praxisrelevanz, aber da ich daran ganz schön herumtüfteln musste, kann die Nachwelt sich vielleicht nach der Lektüre der nächsten paar Zeilen ein wenig Arbeit ersparen. Das Problem tauchte auf, als ich einen Bug in meiner kleinen Web Component namens html-import bemerkte. Die Komponente verwende ich, um in meinen HTML-basierten Präsentationen eine clientseitige Importfunktion umzusetzen, ohne dass ich JavaScript zu schreiben brauche. In einer gegebenen Präsentation A möchte ich buchstäblich <html-import src="praesentationB.html#SlideIdFoo"> schreiben können, statt Copy & Paste zu betreiben. Die Komponente funktioniert wie folgt:

  1. Die im src-Attribut angegebene URL wird mit fetch() geladen
  2. Der HTML-Content wird in ein neues Dokument geparsed
  3. Entweder der komplette Inhalt des Dokuments oder ein bestimmtes Element werden in das importierende Dokument importiert (document.importNode())
  4. Der importierte Inhalt wird im Dokument nach dem importierenden <html-import>-Element eingehängt

Dazu kommt allerlei Hexerei für ein Promise auf dem <html-import>-Element und rekursive Imports. Und alles funktionierte ganz hervorragend, bis mir auffiel, dass importierte <script>-Elemente im Firefox nicht ausgeführt wurden, während sie in Chrome funktionierten …

Nach längerer Recherche kann ich nur vermuten, dass Firefox ganz einfach aus Sicherheitsgründen streikt. Ich habe beim Durchforsten der HTML5- und DOM-Spezifikationen nicht herausgefunden, ob das vorgeschrieben oder zulässig ist, aber es scheint einfach so zu sein, dass der Firefox das aus einem fremden Dokument importierte Script nicht vertrauenswürdig findet. Was also tun?

Firefox hat ein Problem mit dem importierten Script-Element, aber nicht mit dem Script-Inhalt. Die Lösung besteht also darin, ein neues Script-Element im importierenden Dokument zu erstellen, den Script-Inhalt (mit der text-Property, nicht mit innerHTML) und/oder das src-Attribut vom Original im Fremd-Dokument zu übernehmen und das neue Script nach dem Original im Original-Dokument einzufügen. Dann funktioniert das Script im Firefox, läuft aber in Chrome zweimal (denn dort funktionieren Original und Klon gleichermaßen). Hier gibt es nun zwei Möglichkeiten:

  1. In meinem Fall, in dem ich Inhalt aus einem Fremd-Dokument übernehme, kann ich ganz einfach das Original-Script aus dem Dokument heraushalten. Nach dem Anlegen des Klons wird das Original einfach verworfen statt ins Dokument eingehängt.
  2. Falls das mal nicht so einfach möglich sein sollte, kann man das Original-Script auch deaktivieren. Hierzu einfach als type-Attribut etwas angeben, das nicht auf der HTML5-Liste der Script-MIME-Types steht.

Das neue Script-Element wird asynchron ausgeführt, aber das wäre beim direkten Import des Originals nicht anders.

Wie sich die ganze Angelegenheit in IE und Safari o.Ä. darstellt, habe ich noch nicht getestet. Auffällig fand ich, dass das für mich das erste Mal seit langem war, dass ich eine Frage nicht durch irgendeine Spezifikation zumindest teilweise beantwortet bekommen habe. Normalerweise kann man sich heutzutage darauf verlassen, dass man in HTML5 u.Ä. zumindest so etwas wie einen klar definierten Soll-Zustand vorfindet. Empirische Browser-Forschung ist jedenfalls bei mir zum Ausnahmefall geworden. Das war früher mal gaaanz anders …