Motivation: https://stackoverflow.com/questions/28120689/create-self-modifying-html-page-on-box
Bug: String escaping , formatting html
, js
generated by initial edited , saved html
, js
e.g.,
a) if open "saveFile.html" at local browser ;
b) type "abc" into textarea
;
c) click save file
button ;
d) click Save
at Save File
dialog ;
e) file-*[date according to universal time].html
saved to disk ;
f) open file-*[date according to universal time].html
in browser ;
g) type "def" into textarea
;
h) repeat d) , e) , f) ;
i) Bug: result at second file-*[date according to universal time].html
does display textarea
containing "abc def" text content ; button
not displayed at html
:
// at rendered `html` from second `file-*[date according to universal time].html`
// `textarea` containing "abc def" displayed here ,
// `button` _not_ displayed ; following string displayed following `textarea`:
');"console.log(clone);var file = new Blob([clone], {'type':'text/html'});a.href = URL.createObjectURL(file);a.download = 'file-' + new Date().getTime() + '.html';a.click();};
generated at line 26 , "saveFile.html"
+ "var clone = '<!doctype html>'+ document.documentElement.outerHTML.replace(/<textarea>.*<.+textarea>/, '<textarea>'+document.getElementsByTagName('textarea')[0].value+'<\/textarea>');"
"saveFile.html" v 1.0.0
html , js
<!doctype html>
<html>
<!-- saveFile.html 1.0.0 2015 guest271314 edit, save `html` document -->
<head>
</head>
<body>
<textarea>
</textarea>
<button>save file</button>
<script type="text/javascript">
var saveFile = document.getElementsByTagName("button")[0];
var input = document.getElementsByTagName("textarea")[0];
var a = document.createElement("a");
saveFile.onclick = function(e) {
var clone = ["<!doctype html><head></head><body><textarea>"
+ input.value
+ "</textarea>"
+ "<button>save file</button>"
+ "<script type='text/javascript'>"
+ "var saveFile = document.getElementsByTagName('button')[0];"
+ "var input = document.getElementsByTagName('textarea')[0];"
+ "var a = document.createElement('a');"
+ "saveFile.onclick = function(e) {"
+ "var clone = '<!doctype html>'+ document.documentElement.outerHTML.replace(/<textarea>.*<.+textarea>/, '<textarea>'+document.getElementsByTagName('textarea')[0].value+'<\/textarea>');"
+ "console.log(clone);"
+ "var file = new Blob([clone], {'type':'text/html'});"
+ "a.href = URL.createObjectURL(file);"
+ "a.download = 'file-' + new Date().getTime() + '.html';"
+ "a.click();"
+ "};"
+ "</scr"+"ipt>"
+ "</body>"
+ "</html>"];
var file = new Blob([clone], {"type":"text/html"});
a.href = URL.createObjectURL(file);
a.download = "file-" + new Date().getTime() + ".html";
a.click();
};
</script>
</body>
</html>
Your replace function replaces until the
/textarea>
that is in yourclone
variable. It doesn't do it from the first file because there's a newline character after textarea in the html. One way to fix it would be to add anewline
character in the generated html. Like this:I'm not sure what is breaking the third-generation clone so that it results in the js info being output to the page, but it would probably be better to use an actual document object to clone/manipulate the original and output its contents as string for the
Blob
object. For example, I tested using your base saveFile.html with the following changes:The only downsides I am seeing are:
This may be hard to expand into a more generic framework for generating a "live HTML file" of current state of loaded HTML page (though it shouldn't be more complicated than your example approach).
The string returned by
clone.documentElement.outerHTML
appears to drop the document type declaration to a simple element so that :is not in the output string. You could probably use something like:
as a workaround. Or, for something more robust: