jquery-jtemplates_uncompressed.js 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399
  1. /**
  2. * jTemplates 0.8.4 (http://jtemplates.tpython.com)
  3. * Copyright (c) 2007-2013 Tomasz Gloc (http://www.tpython.com)
  4. *
  5. * Dual licensed under the MIT (MIT-LICENSE.txt)
  6. * and/or GPL (GPL-LICENSE.txt) licenses.
  7. *
  8. * Id: $Id: jquery-jtemplates_uncompressed.js 203 2013-02-03 13:28:34Z tom $
  9. */
  10. /**
  11. * @fileOverview Template engine in JavaScript.
  12. * @name jTemplates
  13. * @author Tomasz Gloc
  14. * @date $Date: 2013-02-03 14:28:34 +0100 (N, 03 lut 2013) $
  15. */
  16. if (window.jQuery && !window.jQuery.createTemplate) {
  17. (function (jQuery) {
  18. /**
  19. * [abstract]
  20. * @name BaseNode
  21. * @class Abstract node. [abstract]
  22. */
  23. /**
  24. * Process node and get the html string. [abstract]
  25. * @name get
  26. * @function
  27. * @param {object} d data
  28. * @param {object} param parameters
  29. * @param {Element} element a HTML element
  30. * @param {Number} deep
  31. * @return {String}
  32. * @memberOf BaseNode
  33. */
  34. /**
  35. * [abstract]
  36. * @name BaseArray
  37. * @augments BaseNode
  38. * @class Abstract array/collection. [abstract]
  39. */
  40. /**
  41. * Add node 'e' to array.
  42. * @name push
  43. * @function
  44. * @param {BaseNode} e a node
  45. * @memberOf BaseArray
  46. */
  47. /**
  48. * See (http://jquery.com/).
  49. * @name jQuery
  50. * @class jQuery Library (http://jquery.com/)
  51. */
  52. /**
  53. * See (http://jquery.com/)
  54. * @name fn
  55. * @class jQuery Library (http://jquery.com/)
  56. * @memberOf jQuery
  57. */
  58. /**
  59. * Create new template from string s.
  60. * @name Template
  61. * @class A template or multitemplate.
  62. * @param {string} s A template string (like: "Text: {$T.txt}.").
  63. * @param {array} [includes] Array of included templates.
  64. * @param {object} [settings] Settings.
  65. * @config {boolean} [disallow_functions] Do not allow use function in data (default: true).
  66. * @config {boolean} [filter_data] Enable filter data using escapeHTML (default: true).
  67. * @config {boolean} [filter_params] Enable filter parameters using escapeHTML (default: false).
  68. * @config {boolean} [runnable_functions] Automatically run function (from data) inside {} [default: false].
  69. * @config {boolean} [clone_data] Clone input data [default: true]
  70. * @config {boolean} [clone_params] Clone input parameters [default: true]
  71. * @config {Function} [f_cloneData] Function used to data cloning
  72. * @config {Function} [f_escapeString] Function used to escape strings
  73. * @config {Function} [f_parseJSON] Function used to parse JSON
  74. * @augments BaseNode
  75. */
  76. var Template = function (s, includes, settings) {
  77. this._tree = [];
  78. this._param = {};
  79. this._includes = null;
  80. this._templates = {};
  81. this._templates_code = {};
  82. //default parameters
  83. this.settings = jQuery.extend({
  84. disallow_functions: false,
  85. filter_data: true,
  86. filter_params: false,
  87. runnable_functions: false,
  88. clone_data: true,
  89. clone_params: true
  90. }, settings);
  91. //set handlers
  92. this.f_cloneData = (this.settings.f_cloneData !== undefined) ? (this.settings.f_cloneData) : (TemplateUtils.cloneData);
  93. this.f_escapeString = (this.settings.f_escapeString !== undefined) ? (this.settings.f_escapeString) : (TemplateUtils.escapeHTML);
  94. this.f_parseJSON = (this.settings.f_parseJSON !== undefined) ? (this.settings.f_parseJSON) : ((this.settings.disallow_functions) ? (jQuery.parseJSON) : (TemplateUtils.parseJSON));
  95. if (s == null) {
  96. return;
  97. }
  98. //split multiteplate
  99. this.splitTemplates(s, includes);
  100. if (s) {
  101. //set main template
  102. this.setTemplate(this._templates_code['MAIN'], includes, this.settings);
  103. }
  104. this._templates_code = null;
  105. };
  106. /**
  107. * jTemplates version
  108. * @type string
  109. */
  110. Template.version = '0.8.4';
  111. /**
  112. * Debug mode (all errors are on), default: off
  113. * @type Boolean
  114. */
  115. Template.DEBUG_MODE = false;
  116. /**
  117. * Foreach loop limit (enable only when DEBUG_MODE = true)
  118. * @type integer
  119. */
  120. Template.FOREACH_LOOP_LIMIT = 10000;
  121. /**
  122. * Global guid
  123. * @type integer
  124. */
  125. Template.guid = 0;
  126. /**
  127. * Split multitemplate into multiple templates.
  128. * @param {string} s A template string (like: "Text: {$T.txt}.").
  129. * @param {array} includes Array of included templates.
  130. */
  131. Template.prototype.splitTemplates = function (s, includes) {
  132. var reg = /\{#template *(\w+) *(.*?) *\}/g, //split multitemplate into subtemplates
  133. iter, tname, se, lastIndex = null, _template_settings = [], i;
  134. //while find new subtemplate
  135. while ((iter = reg.exec(s)) !== null) {
  136. lastIndex = reg.lastIndex;
  137. tname = iter[1];
  138. se = s.indexOf('{#/template ' + tname + '}', lastIndex);
  139. if (se === -1) {
  140. throw new Error('jTemplates: Template "' + tname + '" is not closed.');
  141. }
  142. //save a subtemplate and parse options
  143. this._templates_code[tname] = s.substring(lastIndex, se);
  144. _template_settings[tname] = TemplateUtils.optionToObject(iter[2]);
  145. }
  146. //when no subtemplates, use all as main template
  147. if (lastIndex === null) {
  148. this._templates_code['MAIN'] = s;
  149. return;
  150. }
  151. //create a new object for every subtemplates
  152. for (i in this._templates_code) {
  153. if (i !== 'MAIN') {
  154. this._templates[i] = new Template();
  155. }
  156. }
  157. for (i in this._templates_code) {
  158. if (i !== 'MAIN') {
  159. this._templates[i].setTemplate(this._templates_code[i],
  160. jQuery.extend({}, includes || {}, this._templates || {}),
  161. jQuery.extend({}, this.settings, _template_settings[i]));
  162. this._templates_code[i] = null;
  163. }
  164. }
  165. };
  166. /**
  167. * Parse template. (should be template, not multitemplate).
  168. * @param {string} s A template string (like: "Text: {$T.txt}.").
  169. * @param {array} includes Array of included templates.
  170. * @param {object} [settings] Settings.
  171. */
  172. Template.prototype.setTemplate = function (s, includes, settings) {
  173. if (s == undefined) {
  174. this._tree.push(new TextNode('', 1, this));
  175. return;
  176. }
  177. s = s.replace(/[\n\r]/g, ''); //remove endlines
  178. s = s.replace(/\{\*.*?\*\}/g, ''); //remove comments
  179. this._includes = jQuery.extend({}, this._templates || {}, includes || {});
  180. this.settings = new Object(settings);
  181. var node = this._tree,
  182. op = s.match(/\{#.*?\}/g), //find operators
  183. ss = 0, se = 0, e, literalMode = 0, i, l;
  184. //loop operators
  185. for (i = 0, l = (op) ? (op.length) : (0); i < l; ++i) {
  186. var this_op = op[i];
  187. //when literal mode is on, treat operator like a text
  188. if (literalMode) {
  189. se = s.indexOf('{#/literal}', ss); //find end of block
  190. if (se === -1) {
  191. throw new Error("jTemplates: No end of literal.");
  192. }
  193. if (se > ss) {
  194. node.push(new TextNode(s.substring(ss, se), 1, this));
  195. }
  196. ss = se + 11; //strlen '{#/literal}'
  197. literalMode = 0;
  198. while (i < l && op[i] !== '{#/literal}') { //skip all operators until literal end
  199. i++;
  200. }
  201. continue;
  202. }
  203. se = s.indexOf(this_op, ss);
  204. if (se > ss) {
  205. node.push(new TextNode(s.substring(ss, se), literalMode, this));
  206. }
  207. this_op.match(/\{#([\w\/]+).*?\}/); //find operator name
  208. var op_ = RegExp.$1;
  209. switch (op_) {
  210. case 'elseif':
  211. node.addCond(this_op);
  212. break;
  213. case 'if':
  214. e = new opIF(node, this);
  215. e.addCond(this_op);
  216. node.push(e);
  217. node = e;
  218. break;
  219. case 'else':
  220. node.switchToElse();
  221. break;
  222. case '/if':
  223. case '/for':
  224. case '/foreach':
  225. node = node.getParent();
  226. break;
  227. case 'foreach':
  228. e = new opFOREACH(this_op, node, this);
  229. node.push(e);
  230. node = e;
  231. break;
  232. case 'for':
  233. e = opFORFactory(this_op, node, this);
  234. node.push(e);
  235. node = e;
  236. break;
  237. case 'continue':
  238. case 'break':
  239. node.push(new JTException(op_));
  240. break;
  241. case 'include':
  242. node.push(new Include(this_op, this._includes, this));
  243. break;
  244. case 'param':
  245. node.push(new UserParam(this_op, this));
  246. break;
  247. case 'var':
  248. node.push(new UserVariable(this_op, this));
  249. break;
  250. case 'cycle':
  251. node.push(new Cycle(this_op));
  252. break;
  253. case 'ldelim':
  254. node.push(new TextNode('{', 1, this));
  255. break;
  256. case 'rdelim':
  257. node.push(new TextNode('}', 1, this));
  258. break;
  259. case 'literal':
  260. literalMode = 1;
  261. break;
  262. case '/literal':
  263. if (Template.DEBUG_MODE) {
  264. throw new Error("jTemplates: Missing begin of literal.");
  265. }
  266. break;
  267. default:
  268. if (Template.DEBUG_MODE) {
  269. throw new Error('jTemplates: unknown tag: ' + op_ + '.');
  270. }
  271. }
  272. ss = se + this_op.length;
  273. }
  274. if (s.length > ss) {
  275. node.push(new TextNode(s.substr(ss), literalMode, this));
  276. }
  277. };
  278. /**
  279. * Process template and get the html string.
  280. * @param {object} d data
  281. * @param {object} param parameters
  282. * @param {Element} element a HTML element
  283. * @param {Number} deep
  284. * @return {String}
  285. */
  286. Template.prototype.get = function (d, param, element, deep) {
  287. ++deep;
  288. if (deep == 1 && element != undefined) {
  289. jQuery.removeData(element, "jTemplatesRef");
  290. }
  291. var $T = d, $P, ret = '';
  292. //create clone of data
  293. if (this.settings.clone_data) {
  294. $T = this.f_cloneData(d, { escapeData: (this.settings.filter_data && deep == 1), noFunc: this.settings.disallow_functions }, this.f_escapeString);
  295. }
  296. //create clone of parameters
  297. if (!this.settings.clone_params) {
  298. $P = jQuery.extend({}, this._param, param);
  299. } else {
  300. $P = jQuery.extend({},
  301. this.f_cloneData(this._param, { escapeData: (this.settings.filter_params), noFunc: false }, this.f_escapeString),
  302. this.f_cloneData(param, { escapeData: (this.settings.filter_params && deep == 1), noFunc: false }, this.f_escapeString));
  303. }
  304. for (var i = 0, l = this._tree.length; i < l; ++i) {
  305. ret += this._tree[i].get($T, $P, element, deep);
  306. }
  307. this.EvalObj = null;
  308. --deep;
  309. return ret;
  310. };
  311. /**
  312. * Create and return EvalClass object
  313. * @return {EvalClass}
  314. */
  315. Template.prototype.getBin = function () {
  316. if (this.EvalObj == null) {
  317. this.EvalObj = new EvalClass(this);
  318. }
  319. return this.EvalObj;
  320. };
  321. /**
  322. * Set to parameter 'name' value 'value'.
  323. * @param {string} name
  324. * @param {object} value
  325. */
  326. Template.prototype.setParam = function (name, value) {
  327. this._param[name] = value;
  328. };
  329. /**
  330. * Template utilities.
  331. * @namespace Template utilities.
  332. */
  333. TemplateUtils = function () {
  334. };
  335. /**
  336. * Replace chars &, >, <, ", ' with html entities.
  337. * To disable function set settings: filter_data=false, filter_params=false
  338. * @param {string} string
  339. * @return {string}
  340. * @static
  341. * @memberOf TemplateUtils
  342. */
  343. TemplateUtils.escapeHTML = function (txt) {
  344. return txt.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
  345. };
  346. /**
  347. * Make a copy od data 'd'. It also filters data (depend on 'filter').
  348. * @param {object} d input data
  349. * @param {object} filter a filters
  350. * @config {boolean} [escapeData] Use escapeHTML on every string.
  351. * @config {boolean} [noFunc] Do not allow to use function (throws exception).
  352. * @param {Function} f_escapeString function using to filter string (usually: TemplateUtils.escapeHTML)
  353. * @return {object} output data (filtered)
  354. * @static
  355. * @memberOf TemplateUtils
  356. */
  357. TemplateUtils.cloneData = function (d, filter, f_escapeString) {
  358. if (d == null) {
  359. return d;
  360. }
  361. switch (d.constructor) {
  362. case Object:
  363. var o = {};
  364. for (var i in d) {
  365. o[i] = TemplateUtils.cloneData(d[i], filter, f_escapeString);
  366. }
  367. if (!filter.noFunc) {
  368. if (d.hasOwnProperty("toString")) {
  369. o.toString = d.toString;
  370. }
  371. }
  372. return o;
  373. case Array:
  374. var a = [];
  375. for (var i = 0, l = d.length; i < l; ++i) {
  376. a[i] = TemplateUtils.cloneData(d[i], filter, f_escapeString);
  377. }
  378. return a;
  379. case String:
  380. return (filter.escapeData) ? (f_escapeString(d)) : (d);
  381. case Function:
  382. if (filter.noFunc) {
  383. if (Template.DEBUG_MODE) {
  384. throw new Error("jTemplates: Functions are not allowed.");
  385. }
  386. else {
  387. return undefined;
  388. }
  389. }
  390. }
  391. return d;
  392. };
  393. /**
  394. * Convert text-based option string to Object
  395. * @param {string} optionText text-based option string
  396. * @return {Object}
  397. * @static
  398. * @memberOf TemplateUtils
  399. */
  400. TemplateUtils.optionToObject = function (optionText) {
  401. if (optionText === null || optionText === undefined) {
  402. return {};
  403. }
  404. var o = optionText.split(/[= ]/);
  405. if (o[0] === '') {
  406. o.shift();
  407. }
  408. var obj = {};
  409. for (var i = 0, l = o.length; i < l; i += 2) {
  410. obj[o[i]] = o[i + 1];
  411. }
  412. return obj;
  413. };
  414. /**
  415. * Parse JSON string into object
  416. * @param {string} data Text JSON
  417. * @return {Object}
  418. * @static
  419. */
  420. TemplateUtils.parseJSON = function (data) {
  421. if (typeof data !== "string" || !data) {
  422. return null;
  423. }
  424. try {
  425. return (new Function("return " + jQuery.trim(data)))();
  426. } catch (e) {
  427. if (Template.DEBUG_MODE) {
  428. throw new Error("jTemplates: Invalid JSON");
  429. }
  430. return {};
  431. }
  432. };
  433. /**
  434. * Find parents nodes for a reference value and return it
  435. * @param {Element} el html element
  436. * @param {int} guid template process unique identificator
  437. * @param {int} id index
  438. * @return {object}
  439. * @static
  440. */
  441. TemplateUtils.ReturnRefValue = function (el, guid, id) {
  442. //search element with stored data
  443. while (el != null) {
  444. var d = jQuery.data(el, 'jTemplatesRef');
  445. if (d != undefined && d.guid == guid && d.d[id] != undefined) {
  446. return d.d[id];
  447. }
  448. el = el.parentNode;
  449. }
  450. return null;
  451. };
  452. /**
  453. * Create a new text node.
  454. * @name TextNode
  455. * @class All text (block {..}) between control's block "{#..}".
  456. * @param {string} val text string
  457. * @param {boolean} literalMode When enable (true) template does not process blocks {..}.
  458. * @param {Template} Template object
  459. * @augments BaseNode
  460. */
  461. var TextNode = function (val, literalMode, template) {
  462. this._value = val;
  463. this._literalMode = literalMode;
  464. this._template = template;
  465. };
  466. /**
  467. * Get the html string for a text node.
  468. * @param {object} d data
  469. * @param {object} param parameters
  470. * @param {Element} element a HTML element
  471. * @param {Number} deep
  472. * @return {String}
  473. */
  474. TextNode.prototype.get = function (d, param, element, deep) {
  475. if (this._literalMode) {
  476. return this._value;
  477. }
  478. var s = this._value;
  479. var result = "";
  480. var i = -1;
  481. var nested = 0;
  482. var sText = -1;
  483. var sExpr = 0;
  484. while (true) {
  485. var lm = s.indexOf("{", i + 1);
  486. var rm = s.indexOf("}", i + 1);
  487. if (lm < 0 && rm < 0) {
  488. break;
  489. }
  490. if ((lm != -1 && lm < rm) || (rm == -1)) {
  491. i = lm;
  492. if (++nested == 1) {
  493. sText = lm;
  494. result += s.substring(sExpr, i);
  495. sExpr = -1;
  496. }
  497. } else {
  498. i = rm;
  499. if (--nested === 0) {
  500. if (sText >= 0) {
  501. result += this._template.getBin().evaluateContent(d, param, element, s.substring(sText, rm + 1));
  502. sText = -1;
  503. sExpr = i + 1;
  504. }
  505. } else if (nested < 0) {
  506. nested = 0;
  507. }
  508. }
  509. }
  510. if (sExpr > -1) {
  511. result += s.substr(sExpr);
  512. }
  513. return result;
  514. };
  515. /**
  516. * Virtual context for eval() (internal class)
  517. * @name EvalClass
  518. * @class Virtual bin for eval() evaluation
  519. * @param {Template} t template
  520. * @private
  521. */
  522. EvalClass = function (t) {
  523. this.__templ = t;
  524. };
  525. /**
  526. * Evaluate expression (template content)
  527. * @param {object} $T data
  528. * @param {object} $P parameters
  529. * @param {object} $Q element
  530. * @param {String} __value Template content
  531. * @return {String}
  532. */
  533. EvalClass.prototype.evaluateContent = function ($T, $P, $Q, __value) {
  534. try {
  535. var result = eval(__value);
  536. if (jQuery.isFunction(result)) {
  537. if (this.__templ.settings.disallow_functions || !this.__templ.settings.runnable_functions) {
  538. return '';
  539. }
  540. result = result($T, $P, $Q);
  541. }
  542. return (result === undefined) ? ("") : (String(result));
  543. } catch (e) {
  544. if (Template.DEBUG_MODE) {
  545. if (e instanceof JTException) {
  546. e.type = "subtemplate";
  547. }
  548. throw e;
  549. }
  550. return "";
  551. }
  552. };
  553. /**
  554. * Evaluate expression (simple eval)
  555. * @param {object} $T data
  556. * @param {object} $P parameters
  557. * @param {object} $Q element
  558. * @param {String} __value content to evaluate
  559. * @return {String}
  560. */
  561. EvalClass.prototype.evaluate = function ($T, $P, $Q, __value) {
  562. return eval(__value);
  563. };
  564. /**
  565. * Create a new conditional node.
  566. * @name opIF
  567. * @class A class represent: {#if}.
  568. * @param {object} par parent node
  569. * @param {Template} templ template
  570. * @augments BaseArray
  571. */
  572. var opIF = function (par, templ) {
  573. this._parent = par;
  574. this._templ = templ;
  575. this._cond = []; //conditions
  576. this._tree = []; //conditions subtree
  577. this._curr = null; //current subtree
  578. };
  579. /**
  580. * Add node 'e' to array.
  581. * @param {BaseNode} e a node
  582. */
  583. opIF.prototype.push = function (e) {
  584. this._curr.push(e);
  585. };
  586. /**
  587. * Get a parent node.
  588. * @return {BaseNode}
  589. */
  590. opIF.prototype.getParent = function () {
  591. return this._parent;
  592. };
  593. /**
  594. * Add condition
  595. * @param {string} oper content of operator {#..}
  596. */
  597. opIF.prototype.addCond = function (oper) {
  598. oper.match(/\{#(?:else)*if (.*?)\}/);
  599. this._cond.push(RegExp.$1);
  600. this._curr = [];
  601. this._tree.push(this._curr);
  602. };
  603. /**
  604. * Switch to else
  605. */
  606. opIF.prototype.switchToElse = function () {
  607. this._cond.push(true); //else is the last condition and its always true
  608. this._curr = [];
  609. this._tree.push(this._curr);
  610. };
  611. /**
  612. * Process node depend on conditional and get the html string.
  613. * @param {object} d data
  614. * @param {object} param parameters
  615. * @param {Element} element a HTML element
  616. * @param {Number} deep
  617. * @return {String}
  618. */
  619. opIF.prototype.get = function (d, param, element, deep) {
  620. var ret = ''; //result
  621. try {
  622. //foreach condition
  623. for (var ci = 0, cl = this._cond.length; ci < cl; ++ci) {
  624. //if condition is true
  625. if (this._templ.getBin().evaluate(d, param, element, this._cond[ci])) {
  626. //execute and exit
  627. var t = this._tree[ci];
  628. for (var i = 0, l = t.length; i < l; ++i) {
  629. ret += t[i].get(d, param, element, deep);
  630. }
  631. return ret;
  632. }
  633. }
  634. } catch (e) {
  635. if (Template.DEBUG_MODE || (e instanceof JTException)) {
  636. throw e;
  637. }
  638. }
  639. return ret;
  640. };
  641. /**
  642. * Handler for a tag 'FOR'. Create new and return relative opFOREACH object.
  643. * @name opFORFactory
  644. * @class Handler for a tag 'FOR'. Create new and return relative opFOREACH object.
  645. * @param {string} oper content of operator {#..}
  646. * @param {object} par parent node
  647. * @param {Template} template a pointer to Template object
  648. * @return {opFOREACH}
  649. */
  650. opFORFactory = function (oper, par, template) {
  651. //create operator FOREACH with function as iterator
  652. if (oper.match(/\{#for (\w+?) *= *(\S+?) +to +(\S+?) *(?:step=(\S+?))*\}/)) {
  653. var f = new opFOREACH(null, par, template);
  654. f._name = RegExp.$1;
  655. f._option = { 'begin': (RegExp.$2 || 0), 'end': (RegExp.$3 || -1), 'step': (RegExp.$4 || 1), 'extData': '$T' };
  656. f._runFunc = (function (i) { return i; });
  657. return f;
  658. } else {
  659. throw new Error('jTemplates: Operator failed "find": ' + oper);
  660. }
  661. };
  662. /**
  663. * Create a new loop node.
  664. * @name opFOREACH
  665. * @class A class represent: {#foreach}.
  666. * @param {string} oper content of operator {#..}
  667. * @param {object} par parent node
  668. * @param {Template} template a pointer to Template object
  669. * @augments BaseArray
  670. */
  671. var opFOREACH = function (oper, par, template) {
  672. this._parent = par;
  673. this._template = template;
  674. if (oper != null) {
  675. oper.match(/\{#foreach +(.+?) +as +(\w+?)( .+)*\}/);
  676. this._arg = RegExp.$1;
  677. this._name = RegExp.$2;
  678. this._option = RegExp.$3 || null;
  679. this._option = TemplateUtils.optionToObject(this._option);
  680. }
  681. this._onTrue = [];
  682. this._onFalse = [];
  683. this._currentState = this._onTrue;
  684. //this._runFunc = null;
  685. };
  686. /**
  687. * Add node 'e' to array.
  688. * @param {BaseNode} e
  689. */
  690. opFOREACH.prototype.push = function (e) {
  691. this._currentState.push(e);
  692. };
  693. /**
  694. * Get a parent node.
  695. * @return {BaseNode}
  696. */
  697. opFOREACH.prototype.getParent = function () {
  698. return this._parent;
  699. };
  700. /**
  701. * Switch from collection onTrue to onFalse.
  702. */
  703. opFOREACH.prototype.switchToElse = function () {
  704. this._currentState = this._onFalse;
  705. };
  706. /**
  707. * Process loop and get the html string.
  708. * @param {object} d data
  709. * @param {object} param parameters
  710. * @param {Element} element a HTML element
  711. * @param {Number} deep
  712. * @return {String}
  713. */
  714. opFOREACH.prototype.get = function (d, param, element, deep) {
  715. try {
  716. //array of elements in foreach (or function)
  717. var fcount = (this._runFunc === undefined) ? (this._template.getBin().evaluate(d, param, element, this._arg)) : (this._runFunc);
  718. if (fcount === $) {
  719. throw new Error("jTemplate: Variable '$' cannot be used as loop-function");
  720. }
  721. var key = []; //only for objects
  722. var mode = typeof fcount;
  723. if (mode == 'object') {
  724. //transform object to array
  725. var arr = [];
  726. jQuery.each(fcount, function (k, v) {
  727. key.push(k);
  728. arr.push(v);
  729. });
  730. fcount = arr;
  731. }
  732. //setup primary iterator, iterator can get data from options (using by operator FOR) or from data "$T"
  733. var extData = (this._option.extData !== undefined) ? (this._template.getBin().evaluate(d, param, element, this._option.extData)) : ((d != null) ? (d) : ({}));
  734. if (extData == null) {
  735. extData = {};
  736. }
  737. //start, end and step
  738. var s = Number(this._template.getBin().evaluate(d, param, element, this._option.begin) || 0), e; //start, end
  739. var step = Number(this._template.getBin().evaluate(d, param, element, this._option.step) || 1);
  740. if (mode != 'function') {
  741. e = fcount.length;
  742. } else {
  743. if (this._option.end === undefined || this._option.end === null) {
  744. e = Number.MAX_VALUE;
  745. } else {
  746. e = Number(this._template.getBin().evaluate(d, param, element, this._option.end)) + ((step > 0) ? (1) : (-1));
  747. }
  748. }
  749. var ret = ''; //result string
  750. var i, l; //local iterators
  751. if (this._option.count) {
  752. //limit number of loops
  753. var tmp = s + Number(this._template.getBin().evaluate(d, param, element, this._option.count));
  754. e = (tmp > e) ? (e) : (tmp);
  755. }
  756. if ((e > s && step > 0) || (e < s && step < 0)) {
  757. var iteration = 0;
  758. var _total = (mode != 'function') ? (Math.ceil((e - s) / step)) : undefined;
  759. var ckey, cval; //current key, current value
  760. var loopCounter = 0;
  761. for (; ((step > 0) ? (s < e) : (s > e)); s += step, ++iteration, ++loopCounter) {
  762. if (Template.DEBUG_MODE && loopCounter > Template.FOREACH_LOOP_LIMIT) {
  763. throw new Error("jTemplate: Foreach loop limit was exceed");
  764. }
  765. ckey = key[s];
  766. if (mode != 'function') {
  767. cval = fcount[s]; //get value from array
  768. } else {
  769. cval = fcount(s); //calc function
  770. //if no result from function then stop foreach
  771. if (cval === undefined || cval === null) {
  772. break;
  773. }
  774. }
  775. if ((typeof cval == 'function') && (this._template.settings.disallow_functions || !this._template.settings.runnable_functions)) {
  776. continue;
  777. }
  778. if ((mode == 'object') && (ckey in Object) && (cval === Object[ckey])) {
  779. continue;
  780. }
  781. //backup on value
  782. var prevValue = extData[this._name];
  783. //set iterator properties
  784. extData[this._name] = cval;
  785. extData[this._name + '$index'] = s;
  786. extData[this._name + '$iteration'] = iteration;
  787. extData[this._name + '$first'] = (iteration === 0);
  788. extData[this._name + '$last'] = (s + step >= e);
  789. extData[this._name + '$total'] = _total;
  790. extData[this._name + '$key'] = (ckey !== undefined && ckey.constructor == String) ? (this._template.f_escapeString(ckey)) : (ckey);
  791. extData[this._name + '$typeof'] = typeof cval;
  792. for (i = 0, l = this._onTrue.length; i < l; ++i) {
  793. try {
  794. ret += this._onTrue[i].get(extData, param, element, deep);
  795. } catch (ex) {
  796. if (ex instanceof JTException) {
  797. switch (ex.type) {
  798. case 'continue':
  799. i = l; //force skip to next node
  800. break;
  801. case 'break':
  802. i = l; //force skip to next node
  803. s = e; //force skip outsite foreach
  804. break;
  805. default:
  806. throw ex;
  807. }
  808. } else {
  809. throw ex;
  810. }
  811. }
  812. }
  813. //restore values
  814. delete extData[this._name + '$index'];
  815. delete extData[this._name + '$iteration'];
  816. delete extData[this._name + '$first'];
  817. delete extData[this._name + '$last'];
  818. delete extData[this._name + '$total'];
  819. delete extData[this._name + '$key'];
  820. delete extData[this._name + '$typeof'];
  821. delete extData[this._name];
  822. extData[this._name] = prevValue;
  823. }
  824. } else {
  825. //no items to loop ("foreach->else")
  826. for (i = 0, l = this._onFalse.length; i < l; ++i) {
  827. ret += this._onFalse[i].get(d, param, element, deep);
  828. }
  829. }
  830. return ret;
  831. } catch (e) {
  832. if (Template.DEBUG_MODE || (e instanceof JTException)) {
  833. throw e;
  834. }
  835. return "";
  836. }
  837. };
  838. /**
  839. * Template-control exceptions
  840. * @name JTException
  841. * @class A class used internals for a template-control exceptions
  842. * @param type {string} Type of exception
  843. * @augments Error
  844. * @augments BaseNode
  845. */
  846. var JTException = function (type) {
  847. this.type = type;
  848. };
  849. JTException.prototype = Error;
  850. /**
  851. * Throw a template-control exception
  852. * @throws It throws itself
  853. */
  854. JTException.prototype.get = function (d) {
  855. throw this;
  856. };
  857. /**
  858. * Create a new entry for included template.
  859. * @name Include
  860. * @class A class represent: {#include}.
  861. * @param {string} oper content of operator {#..}
  862. * @param {array} includes
  863. * @param {Template} templ template
  864. * @augments BaseNode
  865. */
  866. var Include = function (oper, includes, templ) {
  867. oper.match(/\{#include (.*?)(?: root=(.*?))?\}/);
  868. this._template = includes[RegExp.$1];
  869. if (this._template == undefined) {
  870. if (Template.DEBUG_MODE) {
  871. throw new Error('jTemplates: Cannot find include: ' + RegExp.$1);
  872. }
  873. }
  874. this._root = RegExp.$2;
  875. this._mainTempl = templ;
  876. };
  877. /**
  878. * Run method get on included template.
  879. * @param {object} d data
  880. * @param {object} param parameters
  881. * @param {Element} element a HTML element
  882. * @param {Number} deep
  883. * @return {String}
  884. */
  885. Include.prototype.get = function (d, param, element, deep) {
  886. try {
  887. //run a subtemplates with a new root node
  888. return this._template.get(this._mainTempl.getBin().evaluate(d, param, element, this._root), param, element, deep);
  889. } catch (e) {
  890. if (Template.DEBUG_MODE || (e instanceof JTException)) {
  891. throw e;
  892. }
  893. }
  894. return '';
  895. };
  896. /**
  897. * Create new node for {#param}.
  898. * @name UserParam
  899. * @class A class represent: {#param}.
  900. * @param {string} oper content of operator {#..}
  901. * @param {Template} templ template
  902. * @augments BaseNode
  903. */
  904. var UserParam = function (oper, templ) {
  905. oper.match(/\{#param name=(\w*?) value=(.*?)\}/);
  906. this._name = RegExp.$1;
  907. this._value = RegExp.$2;
  908. this._templ = templ;
  909. };
  910. /**
  911. * Return value of selected parameter.
  912. * @param {object} d data
  913. * @param {object} param parameters
  914. * @param {Element} element a HTML element
  915. * @param {Number} deep
  916. * @return {String} empty string
  917. */
  918. UserParam.prototype.get = function (d, param, element, deep) {
  919. try {
  920. param[this._name] = this._templ.getBin().evaluate(d, param, element, this._value);
  921. } catch (e) {
  922. if (Template.DEBUG_MODE || (e instanceof JTException)) {
  923. throw e;
  924. }
  925. param[this._name] = undefined;
  926. }
  927. return '';
  928. };
  929. /**
  930. * Create new node for {#var}.
  931. * @name UserVariable
  932. * @class A class represent: {#var}.
  933. * @param {string} oper content of operator {#..}
  934. * @param {Template} templ template
  935. * @augments BaseNode
  936. */
  937. var UserVariable = function (oper, templ) {
  938. oper.match(/\{#var (.*?)\}/);
  939. this._id = RegExp.$1;
  940. this._templ = templ;
  941. };
  942. /**
  943. * Return value of selected variable.
  944. * @param {object} d data
  945. * @param {object} param parameters
  946. * @param {Element} element a HTML element
  947. * @param {Number} deep
  948. * @return {String} calling of function ReturnRefValue (as text string)
  949. */
  950. UserVariable.prototype.get = function (d, param, element, deep) {
  951. try {
  952. if (element == undefined) {
  953. return "";
  954. }
  955. var obj = this._templ.getBin().evaluate(d, param, element, this._id);
  956. var refobj = jQuery.data(element, "jTemplatesRef");
  957. if (refobj == undefined) {
  958. refobj = { guid: (++Template.guid), d: [] };
  959. }
  960. var i = refobj.d.push(obj);
  961. jQuery.data(element, "jTemplatesRef", refobj);
  962. return "(TemplateUtils.ReturnRefValue(this," + refobj.guid + "," + (i - 1) + "))";
  963. } catch (e) {
  964. if (Template.DEBUG_MODE || (e instanceof JTException)) {
  965. throw e;
  966. }
  967. return '';
  968. }
  969. };
  970. /**
  971. * Create a new cycle node.
  972. * @name Cycle
  973. * @class A class represent: {#cycle}.
  974. * @param {string} oper content of operator {#..}
  975. * @augments BaseNode
  976. */
  977. var Cycle = function (oper) {
  978. oper.match(/\{#cycle values=(.*?)\}/);
  979. this._values = eval(RegExp.$1);
  980. this._length = this._values.length;
  981. if (this._length <= 0) {
  982. throw new Error('jTemplates: no elements for cycle');
  983. }
  984. this._index = 0;
  985. this._lastSessionID = -1;
  986. };
  987. /**
  988. * Do a step on cycle and return value.
  989. * @param {object} d data
  990. * @param {object} param parameters
  991. * @param {Element} element a HTML element
  992. * @param {Number} deep
  993. * @return {String}
  994. */
  995. Cycle.prototype.get = function (d, param, element, deep) {
  996. var sid = jQuery.data(element, 'jTemplateSID');
  997. if (sid != this._lastSessionID) {
  998. this._lastSessionID = sid;
  999. this._index = 0;
  1000. }
  1001. var i = this._index++ % this._length;
  1002. return this._values[i];
  1003. };
  1004. /**
  1005. * Add a Template to HTML Elements.
  1006. * @param {Template/string} s a Template or a template string
  1007. * @param {array} [includes] Array of included templates.
  1008. * @param {object} [settings] Settings (see Template)
  1009. * @return {jQuery} chainable jQuery class
  1010. * @memberOf jQuery.fn
  1011. */
  1012. jQuery.fn.setTemplate = function (s, includes, settings) {
  1013. return jQuery(this).each(function () {
  1014. var t = (s && s.constructor == Template) ? s : new Template(s, includes, settings);
  1015. jQuery.data(this, 'jTemplate', t);
  1016. jQuery.data(this, 'jTemplateSID', 0);
  1017. });
  1018. };
  1019. /**
  1020. * Add a Template (from URL) to HTML Elements.
  1021. * @param {string} url_ URL to template
  1022. * @param {array} [includes] Array of included templates.
  1023. * @param {object} [settings] Settings (see Template)
  1024. * @return {jQuery} chainable jQuery class
  1025. * @memberOf jQuery.fn
  1026. */
  1027. jQuery.fn.setTemplateURL = function (url_, includes, settings) {
  1028. var s = jQuery.ajax({
  1029. url: url_,
  1030. dataType: 'text',
  1031. async: false,
  1032. type: 'GET'
  1033. }).responseText;
  1034. return jQuery(this).setTemplate(s, includes, settings);
  1035. };
  1036. /**
  1037. * Create a Template from element's content.
  1038. * @param {string} elementName an ID of element
  1039. * @param {array} [includes] Array of included templates.
  1040. * @param {object} [settings] Settings (see Template)
  1041. * @return {jQuery} chainable jQuery class
  1042. * @memberOf jQuery.fn
  1043. */
  1044. jQuery.fn.setTemplateElement = function (elementName, includes, settings) {
  1045. var s = jQuery('#' + elementName).val();
  1046. if (s == null) {
  1047. s = jQuery('#' + elementName).html();
  1048. s = s.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
  1049. }
  1050. s = jQuery.trim(s);
  1051. s = s.replace(/^<\!\[CDATA\[([\s\S]*)\]\]>$/im, '$1');
  1052. s = s.replace(/^<\!--([\s\S]*)-->$/im, '$1');
  1053. return jQuery(this).setTemplate(s, includes, settings);
  1054. };
  1055. /**
  1056. * Check it HTML Elements have a template. Return count of templates.
  1057. * @return {number} Number of templates.
  1058. * @memberOf jQuery.fn
  1059. */
  1060. jQuery.fn.hasTemplate = function () {
  1061. var count = 0;
  1062. jQuery(this).each(function () {
  1063. if (jQuery.getTemplate(this)) {
  1064. ++count;
  1065. }
  1066. });
  1067. return count;
  1068. };
  1069. /**
  1070. * Remote Template from HTML Element(s)
  1071. * @return {jQuery} chainable jQuery class
  1072. */
  1073. jQuery.fn.removeTemplate = function () {
  1074. jQuery(this).processTemplateStop();
  1075. return jQuery(this).each(function () {
  1076. jQuery.removeData(this, 'jTemplate');
  1077. });
  1078. };
  1079. /**
  1080. * Set to parameter 'name' value 'value'.
  1081. * @param {string} name
  1082. * @param {object} value
  1083. * @return {jQuery} chainable jQuery class
  1084. * @memberOf jQuery.fn
  1085. */
  1086. jQuery.fn.setParam = function (name, value) {
  1087. return jQuery(this).each(function () {
  1088. var t = jQuery.getTemplate(this);
  1089. if (t != null) {
  1090. t.setParam(name, value);
  1091. } else if (Template.DEBUG_MODE) {
  1092. throw new Error('jTemplates: Template is not defined.');
  1093. }
  1094. });
  1095. };
  1096. /**
  1097. * Process template using data 'd' and parameters 'param'. Update HTML code.
  1098. * @param {object} d data
  1099. * @param {object} [param] parameters
  1100. * @option {object} [options] internal use only
  1101. * @return {jQuery} chainable jQuery class
  1102. * @memberOf jQuery.fn
  1103. */
  1104. jQuery.fn.processTemplate = function (d, param, options) {
  1105. return jQuery(this).each(function () {
  1106. var t = jQuery.getTemplate(this);
  1107. if (t != null) {
  1108. if (options != undefined && options.StrToJSON) {
  1109. d = t.f_parseJSON(d);
  1110. }
  1111. jQuery.data(this, 'jTemplateSID', jQuery.data(this, 'jTemplateSID') + 1);
  1112. jQuery(this).html(t.get(d, param, this, 0));
  1113. } else if (Template.DEBUG_MODE) {
  1114. throw new Error('jTemplates: Template is not defined.');
  1115. }
  1116. });
  1117. };
  1118. /**
  1119. * Process template using data from URL 'url_' (only format JSON) and parameters 'param'. Update HTML code.
  1120. * @param {string} url_ URL to data (in JSON)
  1121. * @param {object} [param] parameters
  1122. * @param {object} options options (over ajaxSettings) and callbacks
  1123. * @return {jQuery} chainable jQuery class
  1124. * @memberOf jQuery.fn
  1125. */
  1126. jQuery.fn.processTemplateURL = function (url_, param, options) {
  1127. var that = this;
  1128. var o = jQuery.extend({ cache: false }, jQuery.ajaxSettings);
  1129. o = jQuery.extend(o, options);
  1130. jQuery.ajax({
  1131. url: url_,
  1132. type: o.type,
  1133. data: o.data,
  1134. dataFilter: o.dataFilter,
  1135. async: o.async,
  1136. headers: o.headers,
  1137. cache: o.cache,
  1138. timeout: o.timeout,
  1139. dataType: 'text',
  1140. success: function (d) {
  1141. var r = jQuery(that).processTemplate(d, param, { StrToJSON: true });
  1142. if (o.on_success) {
  1143. o.on_success(r);
  1144. }
  1145. },
  1146. error: o.on_error,
  1147. complete: o.on_complete
  1148. });
  1149. return this;
  1150. };
  1151. /**
  1152. * Create new Updater.
  1153. * @name Updater
  1154. * @class This class is used for 'Live Refresh!'.
  1155. * @param {string} url A destination URL
  1156. * @param {object} param Parameters (for template)
  1157. * @param {number} interval Time refresh interval
  1158. * @param {object} args Additional URL parameters (in URL alter ?) as assoc array.
  1159. * @param {array} objs An array of HTMLElement which will be modified by Updater.
  1160. * @param {object} options options and callbacks
  1161. */
  1162. var Updater = function (url, param, interval, args, objs, options) {
  1163. this._url = url;
  1164. this._param = param;
  1165. this._interval = interval;
  1166. this._args = args;
  1167. this.objs = objs;
  1168. this.timer = null;
  1169. this._options = options || {};
  1170. var that = this;
  1171. jQuery(objs).each(function () {
  1172. jQuery.data(this, 'jTemplateUpdater', that);
  1173. });
  1174. this.run();
  1175. };
  1176. /**
  1177. * Create new HTTP request to server, get data (as JSON) and send it to templates. Also check does HTMLElements still exists in Document.
  1178. */
  1179. Updater.prototype.run = function () {
  1180. //remove deleted node
  1181. this.objs = jQuery.grep(this.objs, function (elem) {
  1182. return (jQuery.contains(document.body, elem.jquery ? elem[0] : elem));
  1183. });
  1184. //if no node then do nothing
  1185. if (this.objs.length === 0) {
  1186. return;
  1187. }
  1188. //ajax call
  1189. var that = this;
  1190. jQuery.ajax({
  1191. url: this._url,
  1192. dataType: 'text',
  1193. data: this._args,
  1194. cache: false,
  1195. headers: that._options.headers,
  1196. success: function (d) {
  1197. try {
  1198. var r = jQuery(that.objs).processTemplate(d, that._param, { StrToJSON: true });
  1199. if (that._options.on_success) {
  1200. that._options.on_success(r); //callback
  1201. }
  1202. } catch (ex) { }
  1203. }
  1204. });
  1205. //schedule next run
  1206. this.timer = setTimeout(function () { that.run(); }, this._interval);
  1207. };
  1208. /**
  1209. * Start 'Live Refresh!'.
  1210. * @param {string} url A destination URL
  1211. * @param {object} param Parameters (for template)
  1212. * @param {number} interval Time refresh interval
  1213. * @param {object} args Additional URL parameters (in URL alter ?) as assoc array.
  1214. * @param {object} options options and callbacks
  1215. * @return {Updater} an Updater object
  1216. * @memberOf jQuery.fn
  1217. */
  1218. jQuery.fn.processTemplateStart = function (url, param, interval, args, options) {
  1219. return new Updater(url, param, interval, args, this, options);
  1220. };
  1221. /**
  1222. * Stop 'Live Refresh!'.
  1223. * @return {jQuery} chainable jQuery class
  1224. * @memberOf jQuery.fn
  1225. */
  1226. jQuery.fn.processTemplateStop = function () {
  1227. return jQuery(this).each(function () {
  1228. var updater = jQuery.data(this, 'jTemplateUpdater');
  1229. if (updater == null) {
  1230. return;
  1231. }
  1232. var that = this;
  1233. updater.objs = jQuery.grep(updater.objs, function (o) {
  1234. return o != that;
  1235. });
  1236. jQuery.removeData(this, 'jTemplateUpdater');
  1237. });
  1238. };
  1239. jQuery.extend(/** @scope jQuery.prototype */{
  1240. /**
  1241. * Create new Template.
  1242. * @param {string} s A template string (like: "Text: {$T.txt}.").
  1243. * @param {array} includes Array of included templates.
  1244. * @param {object} settings Settings. (see Template)
  1245. * @return {Template}
  1246. */
  1247. createTemplate: function (s, includes, settings) {
  1248. return new Template(s, includes, settings);
  1249. },
  1250. /**
  1251. * Create new Template from URL.
  1252. * @param {string} url_ URL to template
  1253. * @param {array} includes Array of included templates.
  1254. * @param {object} settings Settings. (see Template)
  1255. * @return {Template}
  1256. */
  1257. createTemplateURL: function (url_, includes, settings) {
  1258. var s = jQuery.ajax({
  1259. url: url_,
  1260. dataType: 'text',
  1261. async: false,
  1262. type: 'GET'
  1263. }).responseText;
  1264. return new Template(s, includes, settings);
  1265. },
  1266. /**
  1267. * Get a Template for HTML node
  1268. * @param {Element} HTML node
  1269. * @return {Template} a Template or "undefined"
  1270. */
  1271. getTemplate: function (element) {
  1272. return jQuery.data(element, 'jTemplate');
  1273. },
  1274. /**
  1275. * Process template and return text content.
  1276. * @param {Template} template A Template
  1277. * @param {object} data data
  1278. * @param {object} param parameters
  1279. * @return {string} Content of template
  1280. */
  1281. processTemplateToText: function (template, data, parameter) {
  1282. return template.get(data, parameter, undefined, 0);
  1283. },
  1284. /**
  1285. * Set Debug Mode
  1286. * @param {Boolean} value
  1287. */
  1288. jTemplatesDebugMode: function (value) {
  1289. Template.DEBUG_MODE = value;
  1290. }
  1291. });
  1292. })(jQuery);
  1293. };