Guten Morgen,
ich habe eine SVG mithilfe von Javascript verändert und würde das Resultat gerne vom Benutzer speichern lassen.
Dabei war meine Idee das vorhandene DOM zu serialisieren und dann als neuen Stream zu speichern.
Die erste Frage die dabei auftaucht: Gibt es das Serialisieren (also quasi DOM2text) als fertige Methode (oder Funktion) oder muss ich mir das noch basteln?
So und wenn ich dann diesen String hätte, der das Dokument enthält, wie biete ich es dem Benutzer an, damit er es speichern kann. Meine Ansätze waren diese:
Ich öffne ein neues Fenster und schreib den Kram da rein:
var Fenster = window.open(null,"SVG_saveme");
Fenster.document.write(DOM_string);
(ich hab echt überhaupt keine Erfahrung mit .write()
, ich benutze sonst nur DOM-Methoden)
Wenn ich Popups erlaube funktioniert das auch, es wird ein SVG (als Testdaten dann statisch) in einem neuen Fenster erstellt. Aber dann wird's schwierig.
Wenn ich das mit FireFox (4) mache, dann erscheint ein neuer Tab, der aber endlos auf "laden" bleibt, also dieser kleine Kringel, der eben dies anzeigt dreht sich ewig.
Wenn ich in diesem Fenster einfach Strg+S drücke und das dann als SVG speichere speichert er das Ursprungs-Dokument, welches das PopUp erstellt hat... nicht mein Wunsch.
Möglich ist allerdings, dass ich das Kontextmenü des SVG öffne, dort auf "Auswahl-Quelltext anzeigen" klicke und eben jenen Quelltext speichere. Das funktioniert ist aber ein blödes Workaround für den Benutzer.
In Chrome (Iron 8) muss ich ebenfalls PopUps erlauben, dann wird auch dort das SVG in einem neuen Fenster geöffnet. Mit diesem PopUp kann ich gar nichts machen, ein Menü (also das Schraubenschlüssel-Icon) wird nicht angezeigt, im Kontextmenü ist nichts nützliches zu finden und wenn ich Strg+S drücke passiert gar nichts.
Mit Chrome habe ich noch ein Nebenproblem, welches ich unten anspreche (oder in einem zweiten Beitrag, mal gucken), Opera und Safari hab ich noch nicht getestet.
Zweiter Ansatz: Einmal Server und zurück:
<?php
header('Content-type: image/svg+xml');
echo ($_POST['svg_string']);
?>
Da wäre meine erste Frage: Sieht da jemand ein Sicherheitsproblem? Muss ich was maskieren oder demaskieren?
Und die andere: Wie kriege ich denn eigentlich so einen POST-Request, aus Javascript an den Server abgesetzt, so dass ich eben als Antwort ein neues Fenster mit der Antwort erhalte. Mit AJAX bekäme ich das wahrscheinlich irgendwie hin, aber dann sind wir wieder bei dem Problem von oben, ich habe einen JS-String und muss den irgendwie in ein speicherbares Dokument kriegen. Also will ich die Antwort direkt verarbeiten ohne JS.
Also kann ich irgendwie einen POST-Request erzeugen, dessen Antwort in einem neuen Fenster landet? Muss ich vielleicht den XHTML-Namensraum einbinden, dann ein Formular erstellen, dort meinen DOM-String reinkippen um dieses Formular dann abzuschicken? Erscheint mir sehr aufwendig, aber wenn es sein muss... was muss ich da beim Escaping beachten?
Und nun noch das "Nebenproblem" mit Chrome: Wenn ich mein SVG drucken will, dann druckt Chrome die Hintergrundbilder nicht mit. Das ist aber quasi der Kern des JS-Programms, dass man die Flächen neu texturiert eben um sie auszudrucken. Mit Suchmaschinen habe ich herausgefunden, dass Chrome entsprechende Drucker-Einstellungen (alá "Hintergrund-Grafik mit drucken") noch fehlen. Stattdessen druckt Chrome alle Flächen schwarz (default bei SVG), sehr Toner-sparsam -.-
Oh und noch was: Opera (11) führt mein Script zwar aus, zeigt aber keines meiner Steuer-Elemente (dynamisch erstelltes SVG). Es legt sie alle an (kann ich in DragonFly sehen) aber rendert sie nicht.
Und abschließend noch ne Demo des Scripts... ja es ist nicht sooo sauber programmiert, viele globale Variablen wenig bis kein OOP aber... naja ich muss ja nicht stolz drauf sein, vielleicht schreibe ich später eine OOP-Variante.
Demo
sh:( fo:| ch:? rl:( br:& n4:& ie:{ mo:} va:) de:µ_de:] zu:) fl:( ss:| ls:[ js:(