| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 | 
							- module.exports = serializeNode
 
- var voidElements = ["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"];
 
- function serializeNode(node) {
 
-     switch (node.nodeType) {
 
-         case 3:
 
-             return escapeText(node.data)
 
-         case 8:
 
-             return "<!--" + node.data + "-->"
 
-         default:
 
-             return serializeElement(node)
 
-     }
 
- }
 
- function serializeElement(elem) {
 
-     var strings = []
 
-     var tagname = elem.tagName
 
-     if (elem.namespaceURI === "http://www.w3.org/1999/xhtml") {
 
-         tagname = tagname.toLowerCase()
 
-     }
 
-     strings.push("<" + tagname + properties(elem) + datasetify(elem))
 
-     if (voidElements.indexOf(tagname) > -1) {
 
-         strings.push(" />")
 
-     } else {
 
-         strings.push(">")
 
-         if (elem.childNodes.length) {
 
-             strings.push.apply(strings, elem.childNodes.map(serializeNode))
 
-         } else if (elem.textContent || elem.innerText) {
 
-             strings.push(escapeText(elem.textContent || elem.innerText))
 
-         } else if (elem.innerHTML) {
 
-             strings.push(elem.innerHTML)
 
-         }
 
-         strings.push("</" + tagname + ">")
 
-     }
 
-     return strings.join("")
 
- }
 
- function isProperty(elem, key) {
 
-     var type = typeof elem[key]
 
-     if (key === "style" && Object.keys(elem.style).length > 0) {
 
-       return true
 
-     }
 
-     return elem.hasOwnProperty(key) &&
 
-         (type === "string" || type === "boolean" || type === "number") &&
 
-         key !== "nodeName" && key !== "className" && key !== "tagName" &&
 
-         key !== "textContent" && key !== "innerText" && key !== "namespaceURI" &&  key !== "innerHTML"
 
- }
 
- function stylify(styles) {
 
-     if (typeof styles === 'string') return styles
 
-     var attr = ""
 
-     Object.keys(styles).forEach(function (key) {
 
-         var value = styles[key]
 
-         key = key.replace(/[A-Z]/g, function(c) {
 
-             return "-" + c.toLowerCase();
 
-         })
 
-         attr += key + ":" + value + ";"
 
-     })
 
-     return attr
 
- }
 
- function datasetify(elem) {
 
-     var ds = elem.dataset
 
-     var props = []
 
-     for (var key in ds) {
 
-         props.push({ name: "data-" + key, value: ds[key] })
 
-     }
 
-     return props.length ? stringify(props) : ""
 
- }
 
- function stringify(list) {
 
-     var attributes = []
 
-     list.forEach(function (tuple) {
 
-         var name = tuple.name
 
-         var value = tuple.value
 
-         if (name === "style") {
 
-             value = stylify(value)
 
-         }
 
-         attributes.push(name + "=" + "\"" + escapeAttributeValue(value) + "\"")
 
-     })
 
-     return attributes.length ? " " + attributes.join(" ") : ""
 
- }
 
- function properties(elem) {
 
-     var props = []
 
-     for (var key in elem) {
 
-         if (isProperty(elem, key)) {
 
-             props.push({ name: key, value: elem[key] })
 
-         }
 
-     }
 
-     for (var ns in elem._attributes) {
 
-       for (var attribute in elem._attributes[ns]) {
 
-         var prop = elem._attributes[ns][attribute]
 
-         var name = (prop.prefix ? prop.prefix + ":" : "") + attribute
 
-         props.push({ name: name, value: prop.value })
 
-       }
 
-     }
 
-     if (elem.className) {
 
-         props.push({ name: "class", value: elem.className })
 
-     }
 
-     return props.length ? stringify(props) : ""
 
- }
 
- function escapeText(s) {
 
-     var str = '';
 
-     if (typeof(s) === 'string') { 
 
-         str = s; 
 
-     } else if (s) {
 
-         str = s.toString();
 
-     }
 
-     return str
 
-         .replace(/&/g, "&")
 
-         .replace(/</g, "<")
 
-         .replace(/>/g, ">")
 
- }
 
- function escapeAttributeValue(str) {
 
-     return escapeText(str).replace(/"/g, """)
 
- }
 
 
  |