Created
September 12, 2012 12:17
-
-
Save teramako/3706243 to your computer and use it in GitHub Desktop.
ObjectをDOM変換する
This file contains hidden or 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
/* | |
* @example | |
* var tree = { | |
* body: [ | |
* {$: "p", | |
* attrs: { "liberator:highlight": "Hint", }, | |
* child: "hoge", | |
* }, | |
* "text node", | |
* {$: "p", | |
* attrs: { class: "foo" }, | |
* child: { | |
* b: "foo" | |
* } | |
* } | |
* ] | |
* }; | |
* document.appendChild( | |
* JSXML.toDOM(tree, document, { liberator: "http://vimperator.org/namespaces/liberator" }) | |
* ); | |
*/ | |
const EXPORTED_SYMBOLS = ["JSXML"]; | |
const JSXML = (function(){ | |
function getNS (name, aNS) { | |
var pos = name.indexOf(":"); | |
if (pos === -1) | |
return null; | |
var prefix = name.substr(0, pos); | |
return aNS[prefix] || null; | |
} | |
function toObject (aElement) { | |
var container; | |
if (aElement.nodeType === Node.ELEMENT_NODE) { | |
container = { | |
$: (aElement.prefix ? aElement.prefix + ":" : "") + aElement.localName | |
}; | |
if (aElement.attributes.length > 0) { | |
container.attrs = {}; | |
for (let i = 0, len = aElement.attributes.length; i < len; ++i) { | |
let attr = aElement.attributes[i]; | |
let attrName = (attr.prefix ? attr.prefix + ":" : "") + attr.localName; | |
container.attrs[attrName] = attr.value; | |
} | |
} | |
if (aElement.hasChildNodes()) { | |
container.child = []; | |
for (let i = 0, len = aElement.childNodes.length; i < len; ++i) { | |
let node = aElement.childNodes[i]; | |
container.child.push(node.nodeType === Node.TEXT_NODE ? node.data : toObject(node)); | |
} | |
} | |
} else if (aElement.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | |
container = []; | |
for (let i = 0, len = aElement.childNodes.length; i < len; ++i) { | |
let node = aElement.childNodes[i]; | |
container.push(node.nodeType === Node.TEXT_NODE ? node.data : toObject(node)); | |
} | |
} | |
return container; | |
} | |
/** toDOM {{{2 | |
* @param {Object} aObj | |
* @param {Element|DocumentFragment} aParent | |
* @param {Document} aDoc | |
* @param {Object} aNS | |
* @return {Element|DocumentFragment} return aParent | |
*/ | |
function toDOM (aObj, aParent, aDoc, aNS) { | |
if (aObj == null) | |
aObj = String(aObj); | |
switch (typeof aObj) { | |
case "string": | |
case "number": | |
case "boolean": | |
aParent.appendChild(aDoc.createTextNode(aObj.toString())); | |
break; | |
case "object": | |
if (Array.isArray(aObj)) { | |
for (let i = 0, len = aObj.length; i < len; ++i) { | |
toDOM(aObj[i], aParent, aDoc, aNS); | |
} | |
} else if ("$" in aObj) { | |
let ns = getNS(aObj.$, aNS); | |
let child = ns ? aDoc.createElementNS(ns, aObj.$) : aDoc.createElement(aObj.$); | |
if ("attrs" in aObj) { | |
for (let attr in aObj.attrs) { | |
child.setAttributeNS(getNS(attr, aNS), attr, aObj.attrs[attr]); | |
} | |
} | |
if ("child" in aObj) | |
toDOM(aObj.child, child, aDoc, aNS); | |
aParent.appendChild(child); | |
} else { | |
for (let key in aObj) { | |
if (key.charAt(0) === "@") { | |
let attrName = key.substr(1); | |
aParent.setAttributeNS(getNS(attrName, aNS), attrName, aObj[key]); | |
} else if (key === "text") { | |
aParent.appendChild(aDoc.createTextNode(aObj.text)); | |
} else { | |
let ns = getNS(key, aNS); | |
let child = ns ? aDoc.createElementNS(ns, key) : aDoc.createElement(key); | |
aParent.appendChild(toDOM(aObj[key], child, aDoc, aNS)); | |
} | |
} | |
} | |
} | |
return aParent; | |
} // 2}}} | |
return { | |
toDOM: function JSXML_toDOM (aTree, aDoc, aNS) { | |
if (!aNS) | |
aNS = {}; | |
return toDOM(aTree, aDoc.createDocumentFragment(), aDoc, aNS); | |
}, | |
toObject: function JSXML_toObject (aElement) { | |
return toObject(aElement); | |
} | |
}; | |
}()); | |
//vim :set fdm=marker sw=2 ts=2: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment