-
-
Save jonschlinkert/4026013 to your computer and use it in GitHub Desktop.
DOM tree to Pre converter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* See https://github.com/sellside/pre | |
*/ | |
/** | |
* References/todos: | |
* http://www.lemoda.net/javascript/dump-dom/dump-dom.html | |
* http://www.howtocreate.co.uk/tutorials/javascript/dombasics | |
* Use treewalker or nodefilter?? | |
* https://developer.mozilla.org/en-US/docs/DOM/NodeFilter | |
* https://developer.mozilla.org/en-US/docs/DOM/treeWalker | |
*/ | |
function toPre(el) { | |
"use strict"; | |
var s = '', | |
tagName, | |
classes, | |
id, | |
tabChar = ' ', | |
tabWidth = 2, | |
attrs, | |
attrName, | |
wsRe = /^\s+$/, | |
selector, | |
slice = Array.prototype.slice; | |
(function traverse(el, depth) { | |
depth = depth || 0; | |
var childNodes, | |
indent = Array(depth * tabWidth + 1).join(tabChar), | |
nextIndent = indent + Array(tabWidth + 1).join(tabChar), | |
nodeValue, | |
isEmpty = true; | |
switch(el.nodeType) { | |
case 1: // ELEMENT_NODE | |
classes = slice.call(el.classList).join('.'); | |
id = el.id; | |
tagName = el.tagName.toLowerCase(); | |
// omit 'div' tag name is classes and/or id present | |
if(tagName === 'div' && (classes || id)) { | |
tagName = ''; | |
} | |
selector = tagName | |
+ (id ? ('#' + id) : '') | |
+ (classes ? ('.' + classes) : ''); | |
break; | |
case 3: // TEXT_NODE | |
nodeValue = el.nodeValue; | |
if(wsRe.test(nodeValue)) { // filter whitespace-only text nodes | |
return; | |
} | |
selector = 'text'; | |
break; | |
case 8: // COMMENT_NODE | |
nodeValue = el.nodeValue; | |
selector = 'comment'; | |
break; | |
default: | |
// skip other kinds of nodes... | |
return; | |
} | |
// selector + opening brace | |
s += indent + selector +' {'; | |
if(el.nodeType === 1) { // ELEMENT_NODE | |
// output attributes | |
if(el.hasAttributes()) { | |
isEmpty = false; // body not empty | |
attrs = el.attributes; | |
s += '\n'; | |
for(var i = 0, len = attrs.length; i < len; i++) { | |
// normalize attr name | |
attrName = attrs[i].name.replace(/:/g, '-').toLowerCase(); | |
// skip 'id' and 'class' attributes (they are present in the selector) | |
if(attrName !== 'id' && attrName !== 'class') { | |
s += nextIndent + attrName + ': "' + attrs[i].nodeValue + '";\n'; | |
} | |
} | |
} | |
// output child nodes | |
if(el.hasChildNodes()) { | |
isEmpty = false; | |
s += '\n'; | |
childNodes = el.childNodes; | |
for(var i = 0, len = childNodes.length; i < len; i++) { | |
traverse(childNodes[i], depth + 1); | |
} | |
} | |
if(!isEmpty) { | |
s += indent; // add indentation before the closing bracket if it's on new line | |
} | |
} else { // Comment or text nodes... | |
// just put the value directly inside the body | |
if(nodeValue.indexOf('\n') > -1) { // multiline - surround value with newlines | |
nodeValue = '\n' + nodeValue + '\n' + indent; | |
} | |
s += nodeValue; | |
} | |
// closing brace | |
s += '}\n'; | |
})(el); | |
return s; | |
} | |
//console.log(toPre(document.documentElement)); | |
// For executing directly from the console: | |
copy(toPre(document.documentElement)); | |
console.log('Markup copied to clipboard'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment