save.js
Summary
Tools for saving content using Mozile.
WARNING: It is your responsibility to verify the safety of data that Mozile posts to your server! Failure to do so could lead to a cross site scripting vulnerability.
Project Homepage: http://mozile.mozdev.org
Version: 0.8
$Id: overview-summary-save.js.html,v 1.8 2008/02/20 18:47:09 jameso Exp $
Author: James A. Overton
mozile.require("mozile.dom");
mozile.require("mozile.xml");
mozile.provide("mozile.save.*");
mozile.save = new Object();
mozile.save.prototype = new mozile.Module;
mozile.save.method = null;
mozile.save.target = mozile.document;
mozile.save.format = null;
mozile.save.warn = true;
mozile.save.onbeforeunload = function(event) {
if(!mozile.save.warn) return undefined;
if(!event || !event.target) return undefined;
var win = event.target;
if(mozile.save.isSaved(win)) return undefined;
return "There are unsaved changes in this document. Changes will be lost if you navigate away from this page.";
}
mozile.save.isSaved = function(doc) {
if(!doc) doc = mozile.document;
if(!mozile.edit) return true;
var currentState = mozile.edit.getCurrentState(doc);
if(!currentState) return true;
if(currentState != this.getSavedState(doc)) return false;
return true;
}
mozile.save.getSavedState = function(doc) {
if(!doc) doc = mozile.document;
return doc.savedState;
}
mozile.save.save = function() {
if(!mozile.save.method) return false;
var content = mozile.save.getContent(mozile.save.target, mozile.save.format);
var result = mozile.save.method.save(content);
if(result && mozile.edit) mozile.document.savedState = mozile.edit.getCurrentState();
return result;
}
mozile.save.saveAs = function() {
if(!mozile.save.method) return false;
var content = mozile.save.getContent(mozile.save.target, mozile.save.format);
var result = mozile.save.method.saveAs(content);
if(result && mozile.edit) mozile.document.savedState = mozile.edit.getCurrentState();
return result;
}
mozile.save.getContent = function(target, format) {
var content = "";
if(!target) target = mozile.document;
if(target.nodeType == 9) {
target = target.documentElement;
content += mozile.save.getXMLDeclaration();
content += mozile.save.getDoctypeDeclaration();
content += mozile.save.getProcessingInstructions();
}
try {
target = target.cloneNode(true);
target = mozile.save.cleanDOM(target);
} catch(e) { }
content += mozile.xml.serialize(target);
if(format) {
if(format.toLowerCase() == "uppercase")
content = mozile.save.toUpperCase(content);
else if(format.toLowerCase() == "lowercase")
content = mozile.save.toLowerCase(content);
}
content = mozile.save.cleanContent(content);
return content;
}
mozile.save.getXMLDeclaration = function() {
var xmlDeclaration = "";
if(mozile.document.xmlVersion) {
xmlDeclaration = '<?xml version="'+ mozile.document.xmlVersion +'" encoding="'+ mozile.document.xmlEncoding +'"?>\n'
}
return xmlDeclaration;
}
mozile.save.getDoctypeDeclaration = function() {
var doctypeDeclaration = "";
if(mozile.document.doctype) {
doctypeDeclaration = mozile.xml.serialize(document.doctype) +"\n";
}
return doctypeDeclaration;
}
mozile.save.getProcessingInstructions = function() {
var PIString = "";
if(mozile.window.XPathEvaluator) {
var evaluator = new XPathEvaluator();
var PIList = evaluator.evaluate("/processing-instruction()", mozile.document, null, XPathResult.ANY_TYPE, null);
var PI = PIList.iterateNext();
while (PI) {
PIString += "<?"+ PI.target +" "+ PI.data + "?>\n";
PI = PIList.iterateNext();
}
}
return PIString;
}
mozile.save.cleanDOM = function(target) {
var root = target;
if(root.nodeType == mozile.dom.DOCUMENT_NODE)
root = root.documentElement;
if(root.nodeType == mozile.dom.ELEMENT_NODE &&
root.hasAttribute("mozileStatus")) {
root.removeAttribute("mozileStatus");
root.removeAttribute("mozileEnhancements");
root.removeAttribute("mozileClientRequest");
root.removeAttribute("mozileClientResponse");
root.removeAttribute("mozileServerRequest");
root.removeAttribute("mozileServerResponse");
for(var i=0; i < root.childNodes.length; i++) {
if(root.childNodes[i].nodeName.toLowerCase() == "body") {
root.childNodes[i].removeAttribute("contentEditable");
break;
}
}
}
if(document.createTreeWalker && mozile.dom.NodeFilter) {
var treeWalker = document.createTreeWalker(target, mozile.dom.NodeFilter.SHOW_ALL, null, false);
treeWalker.currentNode = target;
var current = treeWalker.currentNode;
var remove = new Array();
while(current) {
switch(mozile.dom.getClass(current)) {
case "mozileLink":
case "mozileGUI":
case "mozileScript":
case "mozileSchema":
remove.push(current);
break;
}
current = treeWalker.nextNode();
}
while(remove.length) {
if(remove[0].parentNode) remove[0].parentNode.removeChild(remove[0]);
remove.shift();
}
}
else mozile.debug.inform("mozile.save.cleanDOM", "Could not clean target because no TreeWalker is available.");
return target;
}
mozile.save.cleanContent = function(content) {
return content;
}
mozile.save.cleanMarkup = function(content) {
content = content.replace(/</g, "<");
content = content.replace(/>/g, ">");
return content;
}
mozile.save._tagPattern = /<(\;
mozile.save.toUpperCase = function(content) {
return content.replace(mozile.save._tagPattern, function(word) { return word.toUpperCase(); });
}
mozile.save.toLowerCase = function(content) {
return content.replace(mozile.save._tagPattern, function(word) { return word.toLowerCase(); });
}
mozile.save.Method = function(name) {
this.name = name;
}
mozile.save.Method.prototype.save = function(content) {
return false;
}
mozile.save.Method.prototype.saveAs = function(content) {
return this.save(content);
}
mozile.save.display = new mozile.save.Method("Display Source");
mozile.save.display.save = function(content) {
content = mozile.save.cleanMarkup(content);
if(mozile.gui) {
mozile.gui.display('<h3>Mozile Source</h3>\n<pre>'+ content +'</pre>');
}
else alert("Mozile Source\n\n"+ content);
return true;
}
mozile.save.method = mozile.save.display;
mozile.save.post = new mozile.save.Method("POST");
mozile.save.post.async = true;
mozile.save.post.showResponse = false;
mozile.save.post.uri = "";
mozile.save.post.user = null;
mozile.save.post.password = null;
mozile.save.post.contentType = "text/html";
if(mozile.document.contentType) mozile.save.post.contentType = mozile.document.contentType;
mozile.save.post.characterSet = "UTF-8";
if(mozile.document.characterSet) mozile.save.post.characterSet = mozile.document.characterSet;
mozile.save.post.save = function(content) {
if(!this.uri) {
if(mozile.debug) mozile.debug.inform("mozile.save.post.save", "No URI to save to.");
return false;
}
var CR = '\x0D';
var LF = '\x0A';
content = CR + LF + content + CR + LF;
if(this.XHR) this.XHR.abort();
this.XHR = null;
var XHR;
try{
if(mozile.window.XMLHttpRequest) {
XHR = new XMLHttpRequest();
}
else if(mozile.window.ActiveXObject) {
XHR = new ActiveXObject('Microsoft.XMLHTTP');
}
} catch(e) {
if(mozile.debug) mozile.debug.inform("mozile.save.post.save", "File save failed for '"+ this.uri +"' with error message:\n"+ e);
return false;
}
if(XHR) {
XHR.open("POST", this.uri, this.async, this.user, this.password);
XHR.setRequestHeader('Content-Type', this.contentType + "; " + this.characterSet);
if(mozile.browser.mozile && mozile.browser.mozileVersion < 1.8)
XHR.setRequestHeader('Content-Length', content.length);
XHR.setRequestHeader('Content-Location', this.uri);
XHR.onreadystatechange = this.onreadystatechange;
XHR.send(content);
this.XHR = XHR;
if(!this.async) {
this.onreadystatechange();
}
return true;
}
if(mozile.debug) mozile.debug.inform("mozile.save.post.save", "No XMLHttpRequest available when trying to save to '"+ this.uri +"'.");
return false;
}
mozile.save.post.onreadystatechange = function() {
var XHR = mozile.save.post.XHR;
if(!XHR) return;
if(XHR.readyState != 4) return;
if(XHR.status == 0 || XHR.status == 200) {
if(mozile.save.post.showResponse)
mozile.gui.display('<h3>Save Operation Response</h3>\n\n'+ XHR.responseText);
}
else {
if(mozile.save.post.showResponse)
mozile.gui.display('<h3>Save Operation Error</h3>\n\n'+ XHR.responseText);
else if(mozile.debug) mozile.debug.inform("mozile.save.post.save", "File save failed with status '"+ XHR.status +"' and message:\n"+ XHR.responseText);
}
}
mozile.save.post.saveAs = function(content) {
var uri = prompt("Save to what URI?", this.uri);
if(!uri) return false;
this.uri = uri;
return this.save(content);
}
Documentation generated by
JSDoc on Wed Feb 20 13:25:28 2008