dom, vdom, hyperjson, and an api which provides a matrix of conversions
parent
4cf2a8a0bd
commit
b958caebdd
@ -0,0 +1,57 @@
|
|||||||
|
define([
|
||||||
|
'/common/virtual-dom.js',
|
||||||
|
'/common/hyperjson.js',
|
||||||
|
'/common/hyperscript.js'
|
||||||
|
], function (vdom, hyperjson, hyperscript) {
|
||||||
|
// complain if you don't find the required APIs
|
||||||
|
if (!(vdom && hyperjson && hyperscript)) { throw new Error(); }
|
||||||
|
|
||||||
|
// Generate a matrix of conversions
|
||||||
|
/*
|
||||||
|
convert.dom.to.hjson, convert.hjson.to.dom,
|
||||||
|
convert.dom.to.vdom, convert.vdom.to.dom,
|
||||||
|
convert.vdom.to.hjson, convert.hjson.to.vdom
|
||||||
|
|
||||||
|
and of course, identify functions in case you try to
|
||||||
|
convert a datatype to itself
|
||||||
|
*/
|
||||||
|
var convert = (function () {
|
||||||
|
var Self = function (x) {
|
||||||
|
return x;
|
||||||
|
},
|
||||||
|
methods = {
|
||||||
|
dom:{
|
||||||
|
dom: Self,
|
||||||
|
hjson: hyperjson.fromDOM,
|
||||||
|
vdom: function (D) {
|
||||||
|
return hyperjson.callOn(hyperjson.fromDOM(D), vdom.h);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hjson:{
|
||||||
|
hjson: Self,
|
||||||
|
dom: function (H) {
|
||||||
|
// hyperjson.fromDOM,
|
||||||
|
return hyperjson.callOn(H, hyperscript);
|
||||||
|
},
|
||||||
|
vdom: function (H) {
|
||||||
|
return hyperjson.callOn(H, vdom.h);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
vdom:{
|
||||||
|
vdom: Self,
|
||||||
|
dom: function (V) {
|
||||||
|
return vdom.create(V);
|
||||||
|
},
|
||||||
|
hjson: function (V) {
|
||||||
|
return hyperjson.fromDOM(vdom.create(V));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
convert = {};
|
||||||
|
Object.keys(methods).forEach(function (method) {
|
||||||
|
convert[method] = { to: methods[method] };
|
||||||
|
});
|
||||||
|
return convert;
|
||||||
|
}());
|
||||||
|
return convert;
|
||||||
|
});
|
@ -0,0 +1,96 @@
|
|||||||
|
define([], function () {
|
||||||
|
|
||||||
|
// this makes recursing a lot simpler
|
||||||
|
var isArray = function (A) {
|
||||||
|
return Object.prototype.toString.call(A)==='[object Array]';
|
||||||
|
};
|
||||||
|
|
||||||
|
var parseStyle = function(el){
|
||||||
|
var style = el.style;
|
||||||
|
var output = {};
|
||||||
|
for (var i = 0; i < style.length; ++i) {
|
||||||
|
var item = style.item(i);
|
||||||
|
output[item] = style[item];
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
};
|
||||||
|
|
||||||
|
var callOnHyperJSON = function (hj, cb) {
|
||||||
|
var children;
|
||||||
|
|
||||||
|
if (hj && hj[2]) {
|
||||||
|
children = hj[2].map(function (child) {
|
||||||
|
if (isArray(child)) {
|
||||||
|
// if the child is an array, recurse
|
||||||
|
return callOnHyperJSON(child, cb);
|
||||||
|
} else if (typeof (child) === 'string') {
|
||||||
|
// string nodes have leading and trailing quotes
|
||||||
|
return child.replace(/(^"|"$)/g,"");
|
||||||
|
} else {
|
||||||
|
// the above branches should cover all methods
|
||||||
|
// if we hit this, there is a problem
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
children = [];
|
||||||
|
}
|
||||||
|
// this should return the top level element of your new DOM
|
||||||
|
return cb(hj[0], hj[1], children);
|
||||||
|
};
|
||||||
|
|
||||||
|
var DOM2HyperJSON = function(el){
|
||||||
|
if(!el.tagName && el.nodeType === Node.TEXT_NODE){
|
||||||
|
return el.textContent;
|
||||||
|
}
|
||||||
|
if(!el.attributes){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attributes = {};
|
||||||
|
for(var i = 0; i < el.attributes.length; i++){
|
||||||
|
var attr = el.attributes[i];
|
||||||
|
if(attr.name && attr.value){
|
||||||
|
if(attr.name == "style"){
|
||||||
|
attributes.style = parseStyle(el);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
attributes[attr.name] = attr.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this should never be longer than three elements
|
||||||
|
var result = [];
|
||||||
|
|
||||||
|
// get the element type, id, and classes of the element
|
||||||
|
// and push them to the result array
|
||||||
|
var sel = el.tagName;
|
||||||
|
|
||||||
|
if(attributes.id){
|
||||||
|
sel = sel +'#'+ attributes.id;
|
||||||
|
delete attributes.id;
|
||||||
|
}
|
||||||
|
if(attributes.class){
|
||||||
|
sel = sel +'.'+ attributes.class.replace(/ /g,".");
|
||||||
|
delete attributes.class;
|
||||||
|
}
|
||||||
|
result.push(sel);
|
||||||
|
|
||||||
|
// second element of the array is the element attributes
|
||||||
|
result.push(attributes);
|
||||||
|
|
||||||
|
// third element of the array is an array of child nodes
|
||||||
|
var children = [];
|
||||||
|
for(var i = 0; i < el.childNodes.length; i++){
|
||||||
|
children.push(DOM2HyperJSON(el.childNodes[i]));
|
||||||
|
}
|
||||||
|
result.push(children);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
fromDOM: DOM2HyperJSON,
|
||||||
|
callOn: callOnHyperJSON
|
||||||
|
};
|
||||||
|
});
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue