/*
* @name JSHTML
* @version 1.1
* ---
* @author James Padolsey http://james.padolsey.com
* @copyright James Padolsey
* ---
* @description
* JSHTML provides a simple way of introducing enhanced
* markup into your HTML documents. Markup found in HTML
* comments between the specified delmiters (+ preceeding flag)
* will be replaced with actual markup in the same position.
* ---
* @config
* ~ flag : A string used to signify JSHTML block.
* ~ delimiters : 2-part array containing delimiters, each one
* signifies the beginning and end of the block.
* ~ fragmentCallback : Function fires on each new fragment.
* ('this' refers to fragment)
* ~ template : By default an empty object. JSHTML can replace
* text wrapped in { and } within the JSHTML block.
* (a primative templating system)
* e.g. JSHTML.config.template.location = 'page.html';
* ...
*
* ---
* @example
* HTML:
*
*
*
* JavaScript:
* JSHTML.parse(); //< Only call once the DOM is fully loaded!
*/
var JSHTML = {
config : {
flag : 'JSHTML',
delimiters : ['{{','}}'],
fragmentCallback : function(){},
template : {}
},
parse : function() {
var config = this.config,
flagRegex = new RegExp(
'\\s*?' + config.flag + '\\s*?'
+ config.delimiters[0] + '(.+)'
+ config.delimiters[1] + ''
),
context = arguments[0] || document.documentElement,
nodes = context.childNodes,
nLen = nodes.length,
current, match,
makeFrag = function(str) {
var tempDiv = document.createElement('div'),
frag = document.createDocumentFragment(),
replacement = function($0, $1) {
return config.template[$1] || $0;
},
node;
tempDiv.innerHTML = str.replace(/^\s+|\s+$/g,'')
.replace(/\{(.+?)\}/g, replacement);
while (node = tempDiv.firstChild) {
frag.appendChild(node);
}
try { config.fragmentCallback.call(frag); }
catch(e) {
setTimeout(function(){ throw new Error(e); }, 0);
}
return frag;
};
while (nLen--) {
current = nodes[nLen];
if (current.nodeType !== 8) {
arguments.callee.call(this, current);
continue;
}
match = flagRegex.exec(current.data.replace(/[\n\r]/g,''));
if (!match) { continue; }
current.parentNode.replaceChild(makeFrag(match[1]), current);
}
}
};