1. /*
  2.  * @name JSHTML
  3.  * @version 1.1
  4.  * ---
  5.  * @author James Padolsey http://james.padolsey.com
  6.  * @copyright James Padolsey
  7.  * ---
  8.  * @description
  9.  * JSHTML provides a simple way of introducing enhanced
  10.  * markup into your HTML documents. Markup found in HTML
  11.  * comments between the specified delmiters (+ preceeding flag)
  12.  * will be replaced with actual markup in the same position.
  13.  * ---
  14.  * @config
  15.  * ~ flag : A string used to signify JSHTML block.
  16.  * ~ delimiters : 2-part array containing delimiters, each one
  17.  * signifies the beginning and end of the block.
  18.  * ~ fragmentCallback : Function fires on each new fragment.
  19.  * ('this' refers to fragment)
  20.  * ~ template : By default an empty object. JSHTML can replace
  21.  * text wrapped in { and } within the JSHTML block.
  22.  * (a primative templating system)
  23.  * e.g. JSHTML.config.template.location = 'page.html';
  24.  * ...
  25.  * <!-- JSHTML {{ <a href="{location}">Blah!</a> }} -->
  26.  * ---
  27.  * @example
  28.  * HTML:
  29.  * <div id="normal">
  30.  * <!-- JSHTML {
  31.  * <span id="control">
  32.  * This span only appears when JS is enabled
  33.  * </span>
  34.  * } -->
  35.  * </div>
  36.  * JavaScript:
  37.  * JSHTML.parse(); //< Only call once the DOM is fully loaded!
  38.  */
  39.  
  40. var JSHTML = {
  41. config : {
  42. flag : 'JSHTML',
  43. delimiters : ['{{','}}'],
  44. fragmentCallback : function(){},
  45. template : {}
  46. },
  47. parse : function() {
  48. var config = this.config,
  49. flagRegex = new RegExp(
  50. '\\s*?' + config.flag + '\\s*?'
  51. + config.delimiters[0] + '(.+)'
  52. + config.delimiters[1] + ''
  53. ),
  54. context = arguments[0] || document.documentElement,
  55. nodes = context.childNodes,
  56. nLen = nodes.length,
  57. current, match,
  58. makeFrag = function(str) {
  59. var tempDiv = document.createElement('div'),
  60. frag = document.createDocumentFragment(),
  61. replacement = function($0, $1) {
  62. return config.template[$1] || $0;
  63. },
  64. node;
  65. tempDiv.innerHTML = str.replace(/^\s+|\s+$/g,'')
  66. .replace(/\{(.+?)\}/g, replacement);
  67. while (node = tempDiv.firstChild) {
  68. frag.appendChild(node);
  69. }
  70. try { config.fragmentCallback.call(frag); }
  71. catch(e) {
  72. setTimeout(function(){ throw new Error(e); }, 0);
  73. }
  74. return frag;
  75. };
  76. while (nLen--) {
  77. current = nodes[nLen];
  78. if (current.nodeType !== 8) {
  79. arguments.callee.call(this, current);
  80. continue;
  81. }
  82. match = flagRegex.exec(current.data.replace(/[\n\r]/g,''));
  83. if (!match) { continue; }
  84. current.parentNode.replaceChild(makeFrag(match[1]), current);
  85. }
  86. }
  87. };
  88.  

ALL COPYRIGHT © James Padolsey unless otherwise specified
Go back to the top