Skip to content

Instantly share code, notes, and snippets.

@Noitidart
Last active March 27, 2017 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Noitidart/9504180 to your computer and use it in GitHub Desktop.
Save Noitidart/9504180 to your computer and use it in GitHub Desktop.
_js-snippet-MDNBuildingDomTrees - how to use the jsonToDom function the way I like. This code is a JavaScript snippet but compatabile with privelaged Firefox addon scope. Is not compataible with Google Chrome, I haven't tested other browsers. I do need to work on making it compatabile with other browsers.
function example() {
var hotkeyLabelJson =
['ul', {class: 'apple cf',id:'apple-qwerty'},
['li', {class:'apple'},
['a',{class:'nthotkey-apple-key apple-key'},
[span, {},
1
]
]
],
['th', {},
'VALUE'
]
];
document.documentElement.appendChild(jsonToDOM(hotkeyLabelJson, document, {}));
}
/*dom insertion library function from MDN - https://developer.mozilla.org/en-US/docs/XUL_School/DOM_Building_and_HTML_Insertion*/
jsonToDOM.namespaces = {
html: 'http://www.w3.org/1999/xhtml',
xul: 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'
};
jsonToDOM.defaultNamespace = jsonToDOM.namespaces.html;
function jsonToDOM(xml, doc, nodes) {
function namespace(name) {
var m = /^(?:(.*):)?(.*)$/.exec(name);
return [jsonToDOM.namespaces[m[1]], m[2]];
}
function tag(name, attr) {
if (Array.isArray(name)) {
var frag = doc.createDocumentFragment();
Array.forEach(arguments, function (arg) {
if (!Array.isArray(arg[0]))
frag.appendChild(tag.apply(null, arg));
else
arg.forEach(function (arg) {
frag.appendChild(tag.apply(null, arg));
});
});
return frag;
}
var args = Array.slice(arguments, 2);
var vals = namespace(name);
var elem = doc.createElementNS(vals[0] || jsonToDOM.defaultNamespace, vals[1]);
for (var key in attr) {
var val = attr[key];
if (nodes && key == 'key')
nodes[val] = elem;
vals = namespace(key);
if (typeof val == 'function')
elem.addEventListener(key.replace(/^on/, ''), val, false);
else
elem.setAttributeNS(vals[0] || '', vals[1], val);
}
args.forEach(function(e) {
try {
elem.appendChild(
Object.prototype.toString.call(e) == '[object Array]'
?
tag.apply(null, e)
:
e instanceof doc.defaultView.Node
?
e
:
doc.createTextNode(e)
);
} catch (ex) {
elem.appendChild(doc.createTextNode(ex));
}
});
return elem;
}
return tag.apply(null, xml);
}
/*end - dom insertion library function from MDN*/
@Noitidart
Copy link
Author

README

Rev1

  • Initial
  • Originally taken from MDN - DOM Building and HTML Insertion
    • But modified so can paste into privileged scope and use from there
    • Also fixed something, I now use Object.prototype.toString.call(e) == '[object Array]' instead of typeof e == "object", I think this is a fix but I don't remember what exactly it fixes, I think the person who made it was confused but he did use Array.isArray so I'm not sure, but so far it works well for me.
    • Not compatible with other browsers that don't support Array. functions, I should probably change this to Array.prototype :todo:
  • More Examples

Rev2

  • Description update
  • File name update

Rev3

  • Neatened the library function code
  • Added how to appendChild in example

Rev4

  • Some more neatening

Rev5

  • File type was .js fixed that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment