var HTML5 = require('../html5'); var events = require('events'); function keys(o) { var r = []; for(var k in o) { r.push(k); } return r; } function hescape(s) { return s.replace(/&/g, "&").replace(//g, ">") } var default_opts = { lowercase: true, minimize_boolean_attributes: true, quote_attr_values: true, use_best_quote_char: true, use_trailing_solidus: true, escape_lt_in_attrs: true, space_before_trailing_solidus: true } HTML5.serialize = function(src, target, override) { var options; if(!override) { options = default_opts } else { options = {} var k; for(k in default_opts) options[k] = default_opts[k] for(k in override) options[k] = override[k] } var dest; if(target instanceof Function) { dest = new events.EventEmitter(); dest.addListener('data', target); } else if(!target) { dest = new events.EventEmitter(); var ret = ''; dest.addListener('data', function(d) { ret += d; }); } else { dest = target; } var strict = false; var errors = []; function serialize_error(data) { errors.push(data); if(strict) throw(data); } var in_cdata = false; //TODO: Filters var doctype; var escape_rcdata = false; var w = new HTML5.TreeWalker(src, function(tok) { if(tok.type == "Doctype") { doctype = ""; dest.emit('data', doctype); } else if(tok.type == 'Characters' || tok.type == 'SpaceCharacters') { if(in_cdata || tok.type == 'SpaceCharacters') { if(in_cdata && tok.data.indexOf("'\"" + "]").test(v) } v = v.replace(/&/g, '&'); if(options.escape_lt_in_attrs) v = v.replace(/"); } else if(tok.type == 'EndTag') { if(HTML5.RCDATA_ELEMENTS.indexOf(tok.name.toLowerCase()) != -1) { in_cdata = false; } else if(in_cdata) { serialize_error("Unexpected child element of a CDATA element"); } if(options.lowercase) tok.name = tok.name.toLowerCase() dest.emit('data', ''); } else if(tok.type == 'Comment') { if(tok.data.match(/--/)) serialize_error("Comment contains --"); dest.emit('data', ''); } else { serialize_error(tok.data); } }); dest.emit('end') if(ret) return ret; }