New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More

xsalt

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xsalt - npm Package Compare versions

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",

@@ -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;
}
})();