tidy.js
Summary
Tools for serializing the DOM in a tidy way. Formatting follows the example of the HTML Tidy project and should match Tidy with indenting enabled and wrapping set to 0.
Version: 0.8
$Id: overview-summary-tidy.js.html,v 1.1 2008/02/20 18:47:09 jameso Exp $
Author: James A. Overton
mozile.require("mozile.dom");
mozile.require("mozile.xml");
mozile.require("mozile.edit");
mozile.require("mozile.save");
mozile.provide("mozile.save.tidy.*");
mozile.save.tidy = new Object();
mozile.save.tidy.prototype = new mozile.Module;
mozile.save.tidy.spaces = true;
mozile.save.tidy.newline = "\n";
mozile.save.tidy.tab = " ";
mozile.save.tidy.isXML = function(node) {
if(node.namespaceURI && node.namespaceURI != mozile.xml.ns.xhtml)
return true;
else return false;
}
mozile.save.tidy.countAncestors = function(node) {
var i = -1;
while(node && node != document) {
i++;
node = node.parentNode;
}
return i;
}
mozile.save.tidy.spaceBefore = function(node) {
var output = "";
if(!this.spaces) return output;
switch(node.nodeName.toLowerCase()) {
case "html": return "";
case "head":
case "body":
return this.newline;
case "textarea":
output = this.newline;
for(var i=1; i < this.countAncestors(node); i++) output += this.tab;
break;
}
if(node.parentNode && node.parentNode.nodeName.toLowerCase() == "head") {
return this.newline + this.tab;
}
if(mozile.edit.isBlock(node) || mozile.save.tidy.isXML(node)) {
output = this.newline;
for(var i=1; i < this.countAncestors(node); i++) output += this.tab;
}
return output;
}
mozile.save.tidy.spaceBetween = function(node) {
var output = "";
if(!this.spaces) return output;
if(mozile.edit.isBlock(node) || mozile.save.tidy.isXML(node))
return this.newline;
switch(node.nodeName.toLowerCase()) {
case "textarea":
output = this.newline;
break;
}
return output;
}
mozile.save.tidy.spaceAfter = function(node) {
var output = "";
if(!this.spaces) return output;
switch(node.nodeName.toLowerCase()) {
case "head":
case "body":
case "script":
case "style":
case "ul":
case "ol":
case "dl":
output = this.spaceBefore(node);
break;
case "html":
output = this.newline + output;
}
if(mozile.save.tidy.isXML(node) && mozile.dom.getFirstChildElement(node))
output = this.spaceBefore(node);
return output;
}
mozile.save.tidy.formatNode = function(node) {
var output = "";
var indent = "";
switch(node.nodeType) {
case mozile.dom.ELEMENT_NODE:
var name = this.formatName(node.nodeName);
if(node.nodeName.toLowerCase() == "script") return "";
output = this.spaceBefore(node);
output += "<"+ name;
var i;
if(node.attributes.length) {
var attr = new Array();
for(i=node.attributes.length-1; i>=0; i--) {
var a = node.attributes[i];
if(!a.nodeValue) continue;
if(!a.specified) continue;
if(a.nodeName.toLowerCase() == "contenteditable" &&
a.nodeValue == "inherit") continue;
attr.push(this.formatNode(a));
}
if(attr.length) output += " "+ attr.join(" ");
}
if(node.childNodes.length) {
output += ">";
var children = new Array();
for(i=0; i < node.childNodes.length; i++) {
children.push(this.formatNode(node.childNodes[i]));
}
output += children.join("");
output += this.spaceAfter(node);
output += "</"+ name +">";
}
else output += "/>";
break;
case mozile.dom.ATTRIBUTE_NODE:
output = node.nodeName +'="'+ node.nodeValue +'"';
break;
case mozile.dom.TEXT_NODE:
if(node.data.match(/\w/)) output = mozile.save.cleanMarkup(node.data);
else {
if(node != node.parentNode.firstChild &&
node != node.parentNode.lastChild) {
output = this.spaceBetween(node.nextSibling);
}
}
break;
case mozile.dom.CDATA_SECTION_NODE:
if(node.parentNode && node.parentNode.nodeName.toLowerCase() == "style")
output = "/*<![CDATA[*/"+ node.data +"/*]]>*/";
else if(node.parentNode && node.parentNode.nodeName.toLowerCase() == "script")
output = "//<![CDATA[\n"+ node.data +"\n//]]>";
else output = "<![CDATA["+ node.data +"]]>";
break;
case mozile.dom.ENTITY_REFERENCE_NODE:
output = "UNHANDLED";
break;
case mozile.dom.ENTITY_NODE:
output = "UNHANDLED";
break;
case mozile.dom.PROCESSING_INSTRUCTION_NODE:
output = "<?"+ node.target +" "+ node.data +"?>";
break;
case mozile.dom.COMMENT_NODE:
output = "<!--"+ node.data +"-->";
break;
case mozile.dom.DOCUMENT_NODE:
output = this.formatNode(node.documentElement);
break;
case mozile.dom.DOCUMENT_TYPE_NODE:
output = mozile.xml.serialize(node);
break;
case mozile.dom.DOCUMENT_FRAGMENT_NODE:
output = "";
break;
case mozile.dom.NOTATION_NODE:
output = "UNHANDLED";
break;
default:
output = "UNHANDLED";
}
return output;
}
mozile.save.tidy.formatName = function(name) {
if(!mozile.save || !mozile.save.format) return name;
if(typeof(mozile.save.format) != "string") return name;
if(mozile.save.format.toLowerCase() == "lowercase") return name.toLowerCase();
if(mozile.save.format.toLowerCase() == "uppercase") return name.toUpperCase();
return name;
}
Documentation generated by
JSDoc on Wed Feb 20 13:25:28 2008