Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

aui-template-debug.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. AUI.add('aui-template', function(A) {
  2. var Lang = A.Lang,
  3. UA = A.UA,
  4. LString = Lang.String,
  5. isArray = Lang.isArray,
  6. isDate = Lang.isDate,
  7. isString = Lang.isString,
  8. isObject = Lang.isObject,
  9. isValue = Lang.isValue,
  10. isUndefined = Lang.isUndefined,
  11. REGEX_TPL = /<tpl\b[^>]*?((for|if|exec)="([^"]+)")*?>((?:(?=([^<]+))\5|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
  12. REGEX_NEWLINE = /\r\n|\n/g,
  13. REGEX_QUOTE = /'/g,
  14. REGEX_QUOTE_ESCAPED = /\\'/g,
  15. REGEX_PREFIX_GLOBAL_REPLACE = /^(?!\$)/,
  16. REGEX_TPL_VAR = /\{([\w-.#$]+)(?:\:([\w.]*)(?:\((.*?)?\))?)?(\s?[+\-*\/]\s?[\d.+\-*\/()]+)?\}/g,
  17. REGEX_TPL_SCRIPTLET = /\{\[((?:\\\]|.|\n)*?)\]\}/g,
  18. STR_BLANK = '',
  19. STR_COLON = ':',
  20. STR_COMMA = ',',
  21. STR_DOT = '.',
  22. STR_FOR = 'for',
  23. STR_EXEC = 'exec',
  24. STR_IF = 'if',
  25. STR_QUOTE = '\'',
  26. STR_BRACE_OPEN = '{',
  27. STR_BRACE_CLOSE = '}',
  28. STR_PAREN_OPEN = '(',
  29. STR_PAREN_CLOSE = ')',
  30. STR_GLOBAL_SYMBOL = '$',
  31. STR_JOIN_OPEN = STR_QUOTE + STR_COMMA,
  32. STR_JOIN_CLOSE = STR_COMMA + STR_QUOTE,
  33. STR_JOIN_GROUP_OPEN = STR_JOIN_OPEN + STR_PAREN_OPEN,
  34. STR_JOIN_GROUP_CLOSE = STR_PAREN_CLOSE + STR_JOIN_CLOSE,
  35. STR_COMPILE_TPL_ARGS = 'values, parent, $index, $i, $count, $last, $ns, $ans, $yns',
  36. BUFFER_HTML = ['<tpl>', null, '</tpl>'],
  37. BUFFER_STR_COMPILE_SUB_TPL = [
  38. STR_JOIN_OPEN + 'this._compileSubTpl(',
  39. null,
  40. STR_COMMA + STR_COMPILE_TPL_ARGS + STR_PAREN_CLOSE + STR_JOIN_CLOSE
  41. ],
  42. BUFFER_COMPILED_TPL_FN = [
  43. 'compiledTplFn = function(' + STR_COMPILE_TPL_ARGS + ') { return [' + STR_QUOTE,
  44. null,
  45. STR_QUOTE + '].join("");};'
  46. ],
  47. BUFFER_GLOBAL_PROP = ['MAP_GLOBALS["', null, '"]'],
  48. BUFFER_VALUES_LOOKUP = [
  49. 'values["',
  50. null,
  51. '"]'
  52. ],
  53. STR_INVOKE_METHOD_NAME_OPEN = 'this._invokeMethod("',
  54. STR_INVOKE_METHOD_NAME_CLOSE = '"' + STR_COMMA,
  55. STR_UNDEFINED_OUT = ' === undefined ? "" : ',
  56. STR_REPLACE_NEWLINE = '\\n',
  57. STR_REPLACE_QUOTE = "\\'",
  58. STR_VALUES = 'values',
  59. STR_PARENT = 'parent',
  60. STR_SPECIAL_I = '$i',
  61. STR_SPECIAL_INDEX = '$index',
  62. STR_SPECIAL_COUNT = '$count',
  63. STR_SPECIAL_LAST = '$last',
  64. STR_SPECIAL_ANS = '$ans',
  65. STR_SPECIAL_NS = '$ns',
  66. STR_SPECIAL_YNS = '$yns',
  67. STR_RETURN = 'return ',
  68. STR_WITHVALUES = 'with(values){ ',
  69. STR_WITHCLOSE = '; }',
  70. STR_LANGSTRING_VAR = 'LString.',
  71. TOKEN_TPL = 'AUITPL',
  72. TOKEN_TPL_LENGTH = TOKEN_TPL.length,
  73. TOKEN_PARENT_PROP = STR_PARENT + STR_DOT,
  74. TOKEN_THIS_PROP = 'this.',
  75. TOKEN_THIS_PROP_LENGTH = TOKEN_THIS_PROP.length,
  76. TOKEN_VALUES_PROP = STR_VALUES + STR_DOT,
  77. MAP_TPL_FN = {
  78. '.': new Function(
  79. STR_VALUES,
  80. STR_PARENT,
  81. STR_WITHVALUES + STR_RETURN + STR_VALUES + STR_WITHCLOSE
  82. ),
  83. '..': new Function(
  84. STR_VALUES,
  85. STR_PARENT,
  86. STR_WITHVALUES + STR_RETURN + STR_PARENT + STR_WITHCLOSE
  87. )
  88. },
  89. MAP_TPL_FILTERED_TYPES = {
  90. 'boolean': true,
  91. 'number': true,
  92. 'string': true
  93. },
  94. MAP_TPL_VALUES = {
  95. '.': 'this._getValidValues(values)',
  96. '#': STR_SPECIAL_INDEX,
  97. '$index': STR_SPECIAL_INDEX,
  98. '$i': STR_SPECIAL_I,
  99. '$count': STR_SPECIAL_COUNT,
  100. '$last': STR_SPECIAL_LAST,
  101. '$ans': STR_SPECIAL_ANS,
  102. '$ns': STR_SPECIAL_NS,
  103. '$yns': STR_SPECIAL_YNS
  104. },
  105. MAP_GLOBALS = {},
  106. SRC_CREATE = {},
  107. AUI_NS = A.getClassName(STR_BLANK),
  108. YUI_NS = A.ClassNameManager.getClassName(STR_BLANK),
  109. _INSTANCES = {};
  110. var Template = function(html, src) {
  111. var instance = this;
  112. var tpl;
  113. var fromStaticCall = (src === SRC_CREATE);
  114. if (fromStaticCall || A.instanceOf(instance, Template)) {
  115. if (!fromStaticCall) {
  116. html = instance._parseArgs(arguments);
  117. }
  118. tpl = instance._parse(html);
  119. }
  120. else {
  121. html = Template.prototype._parseArgs(arguments);
  122. tpl = new Template(html, SRC_CREATE);
  123. }
  124. return tpl;
  125. };
  126. Template.prototype = {
  127. html: function(tpl) {
  128. var instance = this;
  129. var retVal = instance;
  130. if (isValue(tpl)) {
  131. instance._parse(instance._parseArgs(arguments));
  132. }
  133. else {
  134. retVal = instance._html;
  135. }
  136. return retVal;
  137. },
  138. parse: function(values) {
  139. var instance = this;
  140. return instance._parentTpl.compiled.call(instance, values, {}, 1, 1, 1);
  141. },
  142. render: function(values, node) {
  143. var instance = this;
  144. var rendered = A.Node.create(instance.parse(values));
  145. node = node && A.one(node);
  146. if (node) {
  147. node.setContent(rendered);
  148. }
  149. return rendered;
  150. },
  151. _compile: function(tpl) {
  152. var instance = this;
  153. var compiledTplFn;
  154. var fnBody = tpl.tplBody;
  155. fnBody = fnBody.replace(REGEX_NEWLINE, STR_REPLACE_NEWLINE);
  156. fnBody = fnBody.replace(REGEX_QUOTE, STR_REPLACE_QUOTE);
  157. fnBody = fnBody.replace(REGEX_TPL_VAR, instance._compileTpl);
  158. fnBody = fnBody.replace(REGEX_TPL_SCRIPTLET, instance._compileCode);
  159. BUFFER_COMPILED_TPL_FN[1] = fnBody;
  160. var body = BUFFER_COMPILED_TPL_FN.join(STR_BLANK);
  161. var $yns = instance.$yns;
  162. var $ans = instance.$ans;
  163. var $ns = instance.$ns;
  164. eval(body);
  165. tpl.compiled = function(values, parent, $index, $i, $count, $last) {
  166. var buffer = [];
  167. var subTpl = STR_BLANK;
  168. var testFn = tpl.testFn;
  169. if (!testFn || testFn.call(instance, values, parent, $index, $i, $count, $last, $ns, $ans, $yns)) {
  170. var subValues = values;
  171. var tplFn = tpl.tplFn;
  172. if (tplFn) {
  173. subValues = tplFn.call(instance, values, parent);
  174. parent = values;
  175. }
  176. if (tplFn && isArray(subValues)) {
  177. var length = subValues.length;
  178. var execFn = tpl.execFn;
  179. for (var i = 0; i < length; i++) {
  180. var index = i + 1;
  181. var last = (index == length);
  182. var subValue = subValues[i];
  183. buffer[buffer.length] = compiledTplFn.call(instance, subValue, parent, index, i, length, last, $ns, $ans, $yns);
  184. if (execFn) {
  185. execFn.call(instance, subValues[i]);
  186. }
  187. }
  188. subTpl = buffer.join(STR_BLANK);
  189. }
  190. else {
  191. subTpl = compiledTplFn.call(instance, subValues, parent, $index, $i, $count, $last, $ns, $ans, $yns);
  192. }
  193. }
  194. return subTpl;
  195. };
  196. return instance;
  197. },
  198. _compileCode: function(match, code) {
  199. return STR_JOIN_GROUP_OPEN + code.replace(REGEX_QUOTE_ESCAPED, STR_QUOTE) + STR_JOIN_GROUP_CLOSE;
  200. },
  201. _compileSubTpl: function(id, values, parent, $index, $i, $count, $last, $ns, $ans, $yns) {
  202. var instance = this;
  203. var length;
  204. var tpl = instance.tpls[id];
  205. return tpl.compiled.call(instance, values, parent, $index, $i, $count, $last, $ns, $ans, $yns);
  206. },
  207. _compileTpl: function(match, name, methodName, args, math, offset, str) {
  208. var compiled;
  209. if (name.indexOf(TOKEN_TPL) === 0) {
  210. BUFFER_STR_COMPILE_SUB_TPL[1] = name.substr(TOKEN_TPL_LENGTH);
  211. compiled = BUFFER_STR_COMPILE_SUB_TPL.join(STR_BLANK);
  212. }
  213. else {
  214. var value = MAP_TPL_VALUES[name];
  215. if (!value) {
  216. if (name.indexOf(TOKEN_PARENT_PROP) === 0) {
  217. value = name;
  218. }
  219. else if (name.indexOf(STR_DOT) > -1) {
  220. value = TOKEN_VALUES_PROP + name;
  221. }
  222. else if (name.indexOf(STR_GLOBAL_SYMBOL) === 0 && (name in MAP_GLOBALS)) {
  223. BUFFER_GLOBAL_PROP[1] = name;
  224. value = BUFFER_GLOBAL_PROP.join(STR_BLANK);
  225. }
  226. else {
  227. BUFFER_VALUES_LOOKUP[1] = name;
  228. value = BUFFER_VALUES_LOOKUP.join(STR_BLANK);
  229. }
  230. }
  231. if (math) {
  232. value = STR_PAREN_OPEN + value + math + STR_PAREN_CLOSE;
  233. }
  234. if (methodName) {
  235. args = args ? STR_COMMA + args : STR_BLANK;
  236. if (methodName.indexOf(TOKEN_THIS_PROP) !== 0) {
  237. methodName = STR_LANGSTRING_VAR + methodName + STR_PAREN_OPEN;
  238. }
  239. else {
  240. methodName = STR_INVOKE_METHOD_NAME_OPEN + methodName.substr(TOKEN_THIS_PROP_LENGTH) + STR_INVOKE_METHOD_NAME_CLOSE;
  241. args = STR_COMMA + STR_VALUES;
  242. }
  243. }
  244. else {
  245. args = STR_BLANK;
  246. methodName = STR_PAREN_OPEN + value + STR_UNDEFINED_OUT;
  247. }
  248. compiled = STR_JOIN_OPEN + methodName + value + args + STR_JOIN_GROUP_CLOSE;
  249. }
  250. return compiled;
  251. },
  252. _getValidValues: function(values) {
  253. var instance = this;
  254. var val = STR_BLANK;
  255. if (MAP_TPL_FILTERED_TYPES[typeof values] || isDate(values)) {
  256. val = values;
  257. }
  258. return val;
  259. },
  260. _invokeMethod: function(methodName, value, allValues) {
  261. var instance = this;
  262. return instance[methodName](value, allValues);
  263. },
  264. _parse: function(html) {
  265. var instance = this;
  266. instance._html = html;
  267. var match;
  268. var id = 0;
  269. var tpls = [];
  270. BUFFER_HTML[1] = html;
  271. html = BUFFER_HTML.join(STR_BLANK);
  272. while (match = html.match(REGEX_TPL)) {
  273. var testFn = null;
  274. var execFn = null;
  275. var tplFn = null;
  276. var expression = match[2];
  277. var expressionValue = match[3];
  278. if (expressionValue) {
  279. if (expression == STR_FOR) {
  280. tplFn = MAP_TPL_FN[expressionValue] || new Function(
  281. STR_VALUES,
  282. STR_PARENT,
  283. STR_WITHVALUES + STR_RETURN + expressionValue + STR_WITHCLOSE
  284. );
  285. }
  286. else {
  287. expressionValue = LString.unescapeEntities(expressionValue);
  288. if (expression == STR_IF) {
  289. testFn = new Function(
  290. STR_VALUES,
  291. STR_PARENT,
  292. STR_SPECIAL_INDEX,
  293. STR_SPECIAL_I,
  294. STR_SPECIAL_COUNT,
  295. STR_SPECIAL_LAST,
  296. STR_SPECIAL_NS,
  297. STR_SPECIAL_ANS,
  298. STR_SPECIAL_YNS,
  299. STR_WITHVALUES + STR_RETURN + expressionValue + STR_WITHCLOSE
  300. );
  301. }
  302. else if (expression == STR_EXEC) {
  303. execFn = new Function(
  304. STR_VALUES,
  305. STR_PARENT,
  306. STR_SPECIAL_INDEX,
  307. STR_SPECIAL_I,
  308. STR_SPECIAL_COUNT,
  309. STR_SPECIAL_LAST,
  310. STR_SPECIAL_NS,
  311. STR_SPECIAL_ANS,
  312. STR_SPECIAL_YNS,
  313. STR_WITHVALUES + expressionValue + STR_WITHCLOSE
  314. );
  315. }
  316. }
  317. }
  318. var tplBody = match[4] || STR_BLANK;
  319. html = html.replace(match[0], STR_BRACE_OPEN + TOKEN_TPL + id + STR_BRACE_CLOSE);
  320. id = tpls.push(
  321. {
  322. execFn: execFn,
  323. id: id,
  324. testFn: testFn,
  325. tplBody: tplBody,
  326. tplFn: tplFn
  327. }
  328. );
  329. }
  330. var lastIndex = id - 1;
  331. while (id--) {
  332. instance._compile(tpls[id]);
  333. }
  334. instance._parentTpl = tpls[lastIndex];
  335. instance.tpls = tpls;
  336. return instance;
  337. },
  338. _parseArgs: function(args) {
  339. var instance = this;
  340. var config;
  341. var tpl = args[0];
  342. if (isArray(tpl)) {
  343. if (isObject(tpl[tpl.length - 1])) {
  344. config = tpl.pop();
  345. }
  346. else if (isObject(args[1])) {
  347. config = args[1];
  348. }
  349. tpl = tpl.join(STR_BLANK);
  350. }
  351. else if (args.length > 1) {
  352. var buffer = [];
  353. args = A.Array(args, 0, true);
  354. var length = args.length;
  355. var item;
  356. var lastItem = args[length - 1];
  357. if (isObject(lastItem)) {
  358. config = args.pop();
  359. }
  360. for (var i = 0; i < length; i++) {
  361. item = args[i];
  362. buffer.push(item);
  363. }
  364. tpl = buffer.join(STR_BLANK);
  365. }
  366. if (config) {
  367. A.mix(instance, config, true);
  368. }
  369. return tpl;
  370. },
  371. $ans: AUI_NS,
  372. $yns: YUI_NS
  373. };
  374. var TEMPLATE_PROTO = Template.prototype;
  375. TEMPLATE_PROTO.$ns = AUI_NS;
  376. var globalVar = function(key, value) {
  377. var retVal = null;
  378. if (isUndefined(value) && key) {
  379. retVal = MAP_GLOBALS[key];
  380. }
  381. else {
  382. if (key) {
  383. key = String(key).replace(REGEX_PREFIX_GLOBAL_REPLACE, STR_GLOBAL_SYMBOL);
  384. if (value !== null) {
  385. MAP_GLOBALS[key] = value;
  386. retVal = value;
  387. }
  388. else {
  389. delete MAP_GLOBALS[key];
  390. }
  391. }
  392. }
  393. return retVal;
  394. };
  395. Template.globalVar = TEMPLATE_PROTO.globalVar = globalVar;
  396. Template._GLOBALS = MAP_GLOBALS;
  397. var NODE_PROTO = A.Node.prototype;
  398. NODE_PROTO.toTPL = function() {
  399. return Template.from(this);
  400. };
  401. NODE_PROTO.renderTPL = function(tpl, data) {
  402. var instance = this;
  403. if (isString(tpl) || isArray(tpl)) {
  404. tpl = new Template(tpl);
  405. }
  406. if (tpl && data) {
  407. tpl.render(instance, data);
  408. }
  409. return instance;
  410. };
  411. A.NodeList.importMethod(
  412. NODE_PROTO,
  413. [
  414. 'renderTPL'
  415. ]
  416. );
  417. A.mix(
  418. Template,
  419. {
  420. from: function(node) {
  421. node = A.one(node);
  422. var content = STR_BLANK;
  423. if (node) {
  424. node = node.getDOM();
  425. var nodeName = String(node && node.nodeName).toLowerCase();
  426. if (nodeName != 'script') {
  427. content = node.value || node.innerHTML;
  428. }
  429. else {
  430. content = node.text || node.textContent || node.innerHTML;
  431. }
  432. }
  433. return new Template(content);
  434. },
  435. get: function(key) {
  436. var template = _INSTANCES[key];
  437. if (template && !A.instanceOf(template, Template)) {
  438. template = new Template(template);
  439. _INSTANCES[key] = template;
  440. }
  441. return template;
  442. },
  443. parse: function(key, data) {
  444. var template = Template.get(key);
  445. return template && template.parse(data);
  446. },
  447. register: function(key, value) {
  448. var instance = this;
  449. var tpl = value;
  450. if (!(key in _INSTANCES) &&
  451. (Lang.isArray(value) || A.instanceOf(value, Template))) {
  452. _INSTANCES[key] = value;
  453. }
  454. return value;
  455. },
  456. render: function(key, data, node) {
  457. var template = Template.get(key);
  458. return template && template.render(data, node);
  459. },
  460. _INSTANCES: _INSTANCES
  461. }
  462. );
  463. A.Template = Template;
  464. }, '@VERSION@' ,{requires:['aui-base'], skinnable:false});