Comparing version 0.0.3 to 0.0.4
{ | ||
"name": "xsalt", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "Salty templates", | ||
@@ -5,0 +5,0 @@ "main": "xsalt.js", |
220
xsalt.js
@@ -0,87 +1,195 @@ | ||
(function() { | ||
function xsalt(tmpl) { | ||
var jsdom = require('jsdom'); | ||
var document = jsdom.jsdom(tmpl); | ||
if( typeof module !== 'undefined' && module.exports ) { | ||
var jsdom = require('jsdom').jsdom; | ||
var document = jsdom(tmpl); | ||
this.doc = document; | ||
} | ||
var temp = document.createElement('div'); | ||
else { | ||
this.doc = window.document; | ||
} | ||
// creating a sandbox for moving elements around | ||
var temp = this.doc.createElement('div'); | ||
temp.innerHTML = tmpl; | ||
this.template = temp; | ||
this.doc = document; | ||
}; | ||
/** | ||
* Factory | ||
*/ | ||
function xs(tmpl) { | ||
return new xsalt(tmpl); | ||
} | ||
/** | ||
* Maps an array of "keys" to a JSON object and returns the set | ||
*/ | ||
xsalt.prototype.map = function( keys, data ) { | ||
return keys.reduce(function (data, key) { | ||
return data[key]; | ||
}, data); | ||
}, data); | ||
}; | ||
/*/ Changes XML to JSON | ||
xsalt.prototype.json = function(xml) { | ||
// Create the return object | ||
var obj = {}; | ||
/** | ||
* Attribute parsers | ||
*/ | ||
if (xml.nodeType == 1) { // element | ||
// do attributes | ||
if (xml.attributes.length > 0) { | ||
obj["@attributes"] = {}; | ||
for (var j = 0; j < xml.attributes.length; j++) { | ||
var attribute = xml.attributes.item(j); | ||
obj["@attributes"][attribute.nodeName] = attribute.nodeValue; | ||
} | ||
} | ||
} else if (xml.nodeType == 3) { // text | ||
obj = xml.nodeValue; | ||
} | ||
xsalt.prototype.parse = { | ||
'each': function( node, data, callback ) { | ||
var that = this, | ||
html = this.doc.createElement('div'); | ||
// do children | ||
if (xml.hasChildNodes()) { | ||
for(var i = 0; i < xml.childNodes.length; i++) { | ||
var item = xml.childNodes.item(i); | ||
var nodeName = item.nodeName; | ||
if (typeof(obj[nodeName]) == "undefined") { | ||
obj[nodeName] = xmlToJson(item); | ||
} else { | ||
if (typeof(obj[nodeName].push) == "undefined") { | ||
var old = obj[nodeName]; | ||
obj[nodeName] = []; | ||
obj[nodeName].push(old); | ||
node.removeAttribute('each'); | ||
data.forEach(function(i) { | ||
var n = that.clone(node); | ||
// wish there was a cleaner way to do this but cloneNode won't let | ||
// the tagName be changed | ||
Array.prototype.forEach.call(node.attributes, function(v) { | ||
if( typeof that.parse[v.nodeName] === "function" ) { | ||
that.parse[v.nodeName].call(that, n, v.value, i); | ||
if( typeof callback === "function" ) { | ||
callback.call(that, n, i); | ||
} | ||
} | ||
obj[nodeName].push(xmlToJson(item)); | ||
} | ||
} | ||
}); | ||
node.parentNode.insertBefore(n, node); | ||
}); | ||
node.parentNode.removeChild(node); | ||
}, | ||
'html': function( node, key, data ) { | ||
node.innerHTML = data[key]; | ||
node.removeAttribute('html'); | ||
}, | ||
'val': function( node, key, data ) { | ||
node.setAttribute('value', data[key]); | ||
node.removeAttribute('val'); | ||
} | ||
return obj; | ||
};*/ | ||
}; | ||
xsalt.prototype.loop = function( node, data ) { | ||
/** | ||
* Clones a node and it's attributes, trimming "xs:" from the tag name | ||
*/ | ||
xsalt.prototype.clone = function(node) { | ||
var tag = node.tagName.toLowerCase().replace('xs:', ''); | ||
var n = this.doc.createElement(tag); | ||
n.innerHTML = node.innerHTML; | ||
Array.prototype.forEach.call(node.attributes, function(v) { | ||
n.setAttribute(v.nodeName, v.value); | ||
}); | ||
return n; | ||
}; | ||
/** | ||
* Replaces one node with another | ||
*/ | ||
xsalt.prototype.replace = function(node, n) { | ||
node.parentNode.insertBefore(n, node); | ||
node.parentNode.removeChild(node); | ||
}; | ||
/** | ||
* Compiles template and data together and returns a HTML string | ||
*/ | ||
xsalt.prototype.compile = function( data, node, callback ) { | ||
var that = this; | ||
if( typeof node === "function" ) { | ||
callback = node; | ||
node = this.template.children; | ||
} | ||
else { | ||
node = node || this.template.children; | ||
} | ||
for( var ii = 0, l = node.length; ii < l; ++ii ) { | ||
var tag = node[ii].tagName.toLowerCase(); | ||
if( /xs:/g.test(tag) ) { | ||
var keys = node[ii].getAttribute('value').split('.'); | ||
var t = this.doc.createElement(tag.replace('xs:', '')); | ||
if( /^xs:/g.test( tag ) ) { | ||
// collections have to be handled a little differently | ||
// the template node does not get replaced here since it has to be | ||
// "cloned" multiple times | ||
// iterative functions must handle this internally | ||
if( node[ii].hasAttribute('each') ) { | ||
var attr = node[ii].getAttribute('each'); | ||
t.innerHTML = this.map(keys, data); | ||
// not necessary to separate the last key | ||
// each data set will be available in the callback individually | ||
var set = ( attr === '.' | ||
? data | ||
: this.map( attr.split('.'), data ) ); | ||
Array.prototype.forEach.call(node[ii].attributes, function(v) { | ||
t.setAttribute(v.nodeName, v.nodeValue); | ||
}); | ||
this.parse.each.call(that, node[ii], set, callback); | ||
} | ||
node[ii].parentNode.replaceChild(t, node[ii]); | ||
else { | ||
// hot swap the node to replace the "xs:" tag with the real one | ||
this.replace(node[ii], this.clone(node[ii])); | ||
// it is probably quicker (and easier to check) to iterate over | ||
// the available parsers than to iterate a nodes attributes | ||
for( var p in this.parse ) { | ||
if( node[ii].hasAttribute( p ) ) { | ||
var path = node[ii].getAttribute(p).split('.'); | ||
// the final part of they key is separated from the map | ||
// so the entire data set can be passed around for use | ||
// in the callback | ||
var key = path.pop(); | ||
// make nested var selection possible by splitting the | ||
// var path and mapping it to the data object | ||
var set = this.map(path, data); | ||
this.parse[p].call(that, node[ii], key, set); | ||
if( typeof callback === "function" ) { | ||
callback.call(this, node[ii], set); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
if( node[ii].children ) { | ||
this.loop(node[ii].children, data); | ||
if( node[ii] && node[ii].children ) { | ||
this.compile(data, node[ii].children, callback); | ||
} | ||
} | ||
}; | ||
xsalt.prototype.compile = function( data ) { | ||
this.loop(this.template.children, data); | ||
return this.template.innerHTML; | ||
}; | ||
module.exports = function(tmpl) { | ||
return new xsalt(tmpl); | ||
}; | ||
if( typeof module !== 'undefined' && module.exports ) { | ||
module.exports = xs; | ||
} | ||
else { | ||
window.xsalt = xs; | ||
} | ||
})(); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
6291
5
192
1