Ei kuvausta

codehtml.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. $.define(["jQuery", "doc", "body", "util"], "code", function($, doc, $body, util) {
  2. /**
  3. * env={ ce:current Element; cd:current Data; ci:current index in
  4. * ListElement array[ci=index] or object[ci=key] es:Element stack; Array
  5. * ds:Data stack; Array is:index stack;Array sh:value handler
  6. * function(env,key){return [String]} dir:directive handler
  7. * Aarray(function(env){}.call(elementObj={},env) }
  8. */
  9. var ch_val_buider = {
  10. /*{{111-222-333-444}}=={k:111,h:222,p:[333,444]} */
  11. /*{{111}}=={k:111,h:s} */
  12. /*{{111-222}}=={k:111,h:222,p:undefined} */
  13. "c": function( /* env */ ) {
  14. return this.k;
  15. },
  16. "s": function(env) {
  17. var v = env.cd;
  18. if(v) v = this.k ? v[this.k] : v;
  19. if(v) return v;
  20. return 0===v?"0":"";
  21. },
  22. "cp":function(env){
  23. var v = env.cd;
  24. if(v) return v;
  25. return 0===v?"0":"";
  26. },
  27. "_index": function(env) {
  28. return env.ci+1;
  29. },
  30. "bool":function(env){
  31. return env.cd[this.k]?"是":"否";
  32. },
  33. "date":function(env){
  34. var v = env.cd[this.k];
  35. return v?(v.substring(0,4)+"年"+v.substring(4,6)+"月"+v.substring(6,8)+"日"):((this.p && this.p[0])||"");
  36. }
  37. },
  38. simpleAttrHandler = function(env) {
  39. env.ce.setAttribute(this.n, this.v);
  40. },
  41. AttrHandler = function(env) {
  42. var ret = [],
  43. va = this.v;
  44. for(var i = 0; i < va.length; ++i) {
  45. var item = va[i];
  46. ret.push[env.sh[item.h].call(this, env)];
  47. }
  48. env.ce.setAttribute(this.n, ret.join(""));
  49. },
  50. /**
  51. * r:array s:text value f:lslast value in array Is * Text
  52. */
  53. strSplit_s = function(r, s, f) {
  54. if(f) {
  55. var tmp = r[r.length - 1];
  56. tmp.k = tmp.k + s;
  57. } else {
  58. r.push({ k: s, h: "c" });
  59. }
  60. },
  61. strSplit_o = function(r /* array */ , shell /* trim value like {{shell}} */ ) {
  62. var tmp = shell.split("-");
  63. var obj = { k: tmp.shift(), h: "s" };
  64. if(tmp.length) { obj.h = tmp.shift(); }
  65. if(tmp.length) { obj.p = tmp; }
  66. r.push(obj);
  67. },
  68. strSplit = function(s) { // s.length>4
  69. var r = [],
  70. len = s.length,
  71. si = 0,
  72. /* parse start index */
  73. ei, /* end shell ei = s.indexOf("}}",bi+2) */
  74. shell, /* {{shell}} */
  75. tmp, /* last shell */
  76. f /* prev is not shell */ ,
  77. bi = s.indexOf("{{"); /* begin shell bi = s.indexOf("{{",si) */
  78. if(bi >= 0) {
  79. ei = s.indexOf("}}", bi);
  80. if(ei>0){
  81. while(true) {
  82. if(bi > si) {
  83. r.push({ k: s.substring(si, bi), h: "c" });
  84. f = true;
  85. }
  86. shell = s.substring(bi + 2, ei).trim();
  87. si = ei + 2;
  88. if(shell.length) {
  89. f = false;
  90. strSplit_o(r, shell);
  91. } else {
  92. strSplit_s(r, s.substring(bi, si), f);
  93. f = true;
  94. }
  95. if(si >= len) return r;
  96. bi = s.indexOf("{{", si);
  97. if(bi < 0) { strSplit_s(r, s.substring(si), f); return r; }
  98. ei = s.indexOf("}}", bi);
  99. if(ei < 0) { strSplit_s(r, s.substring(si), f); return r; }
  100. }}
  101. }
  102. return s;
  103. },
  104. strCompile = function(s) {
  105. var r = strSplit(s);
  106. if(typeof r != "string") {
  107. return r.length > 1 ? r : r[0];
  108. /*
  109. * [{k:"",h:"",p:[]},...] :
  110. * {k:"",h:"",p:[]}
  111. */
  112. }
  113. return s; // String;
  114. },
  115. simpleAttrHand = function(env) {
  116. env.ce.setAttribute(this.n, this.v);
  117. },
  118. singleAttrHand = function(env) {
  119. env.ce.setAttribute(this.n, env.sh[this.v.h].call(this.v, env));
  120. },
  121. arrayAttrHand = function(env) {
  122. var item, ret = [],
  123. vs = this.v,
  124. len = vs.length;
  125. for(var i = 0; i < len; ++i) {
  126. item = vs[i];
  127. ret.push(env.sh[item.h].call(item, env));
  128. }
  129. env.ce.setAttribute(this.n, ret.join(""));
  130. },
  131. /* ret.h(env); attribute compiler */
  132. attrCompile = function(attr) {
  133. var s = attr.value || "",
  134. ret = { n: attr.name, v: s, h: simpleAttrHand };
  135. if(s.length > 4) {
  136. s = strCompile(s);
  137. if(typeof s != "string") {
  138. ret.v = s;
  139. // is Array
  140. ret.h = s.length ? arrayAttrHand : singleAttrHand;
  141. }
  142. }
  143. return ret;
  144. },
  145. /* ret.h(env); textNode compiler */
  146. textCompile = function(s /* s = textNode.nodeValue */ ) {
  147. var len = s.length,
  148. ret = { v: s, h: "_t" };
  149. if(len > 4) {
  150. s = strCompile(s);
  151. if(typeof s != "string") {
  152. ret.v = s;
  153. // is Array
  154. ret.h = s.length ? "_at" : "_st";
  155. }
  156. }
  157. return ret;
  158. },
  159. ch_dir_container = {
  160. /* simpleTextHand= */
  161. "_t": function(env) { env.ce.appendChild(doc.createTextNode(this.v)); },
  162. /* singleTextHand= */
  163. "_st": function(env) { env.ce.appendChild(doc.createTextNode(env.sh[this.v.h].call(this.v, env))); },
  164. /* arrayTextHand= */
  165. "_at": function(env) {
  166. var item, ret = [],
  167. vs = this.v,
  168. len = vs.length;
  169. for(var i = 0; i < len; ++i) {
  170. item = vs[i];
  171. ret.push(env.sh[item.h].call(item, env));
  172. }
  173. env.ce.appendChild(doc.createTextNode(ret.join("")));
  174. },
  175. "_": function(env) {
  176. var ele = doc.createElement(this.n),
  177. as = this.as,
  178. es = this.es,
  179. item;
  180. env.ce.appendChild(ele);
  181. env.es.push(env.ce);
  182. env.ce = ele;
  183. for(var i = 0; i < as.length; ++i) {
  184. as[i].h(env);
  185. }
  186. for(var i = 0; i < es.length; ++i) {
  187. item = es[i];
  188. env.dir[item.h].call(item, env);
  189. }
  190. env.ce = env.es.pop();
  191. },
  192. "list": function(env) {
  193. var hand = env.dir["_"],
  194. as = this.as,
  195. es = this.es,
  196. item, data = env.cd,
  197. p = this.p;
  198. if(data && p && p.length && p[0]) {
  199. env.ds.push(data);
  200. data = env.cd = data[p[0]] || [];
  201. env.is.push(env.ci);
  202. for(var i = 0; i < data.length; ++i) {
  203. env.ci = i;
  204. env.cd = data[i];
  205. hand.call(this, env);
  206. }
  207. env.ci = env.is.pop();
  208. env.cd = env.ds.pop();
  209. } else if(data && data.length) {
  210. env.is.push(env.ci);
  211. env.ds.push(data);
  212. for(var i = 0; i < data.length; ++i) {
  213. env.ci = i;
  214. env.cd = data[i];
  215. hand.call(this, env);
  216. }
  217. env.cd=env.ds.pop();
  218. env.ci = env.is.pop();
  219. }
  220. },
  221. "array.empty":function(env){
  222. if((!env.cd) || (!env.cd.length)){
  223. env.dir["_"].call(this,env);
  224. }
  225. },
  226. "each": function(env) {
  227. var hand = env.dir["_"],
  228. as = this.as,
  229. es = this.es,
  230. item, data = env.cd,
  231. p = this.p;
  232. if(data && p && p.length && p[0]) {
  233. env.ds.push(data);
  234. env.is.push(env.ci);
  235. for(var i = 0; i < p.length; ++i) {
  236. env.ci = p[i];
  237. env.cd = data[env.ci];
  238. hand.call(this, env);
  239. }
  240. env.ci = env.is.pop();
  241. env.cd = env.ds.pop();
  242. } else if(data) {
  243. env.is.push(env.ci);
  244. env.ds.push(data);
  245. for(var key in data) {
  246. env.ci = k;
  247. env.cd = data[key];
  248. hand.call(this, env);
  249. }
  250. env.cd = env.ds.pop();
  251. env.ci = env.is.pop();
  252. }
  253. },
  254. "val": function(env) {
  255. var hand = env.dir["_"],
  256. items, item, data = env.cd,
  257. p = this.p;
  258. if(p && p.length && p[0]) {
  259. items = p[0].split("\\.");
  260. env.ds.push(data);
  261. while(items.length && data) {
  262. data = data[items.shift()];
  263. }
  264. if(items.length === 0) {
  265. env.cd = data;
  266. hand.call(this,env);
  267. }
  268. env.cd = env.ds.pop();
  269. }
  270. },
  271. "valTag": function(env) {
  272. var items, item, data = env.cd,
  273. p = this.p,es = this.es;
  274. if(p && p.length && p[0]) {
  275. items = p[0].split("\\.");
  276. env.ds.push(data);
  277. while(items.length && data) {
  278. data = data[items.shift()];
  279. }
  280. if(items.length === 0) {
  281. env.cd = data;
  282. for(var i = 0; i < es.length; ++i) {
  283. item = es[i];
  284. env.dir(item.h).call(item, env);
  285. }
  286. }
  287. env.cd = env.ds.pop();
  288. }
  289. }
  290. },
  291. childCompile = function(chs) {
  292. var ret = [],stack = [],ev, as, es, attrs, ch, ele;
  293. hObj = { r: ret, i: 0, c: chs, t: false, s: "", l: chs.length };
  294. while(hObj) {
  295. while(hObj.i < hObj.l) {
  296. ele = hObj.c[hObj.i++];
  297. if(ele.nodeType == 1) {
  298. if(hObj.t) {
  299. hObj.r.push(textCompile(hObj.s));
  300. }
  301. hObj.t = false;
  302. attrs = ele.attributes;
  303. ch = (ele.getAttribute("ch-dir") || "_").split("-");
  304. ev = { n: ele.nodeName, h: (ch.shift()||"_"), p: ch };
  305. as = ev.as = [];
  306. es = ev.es = [];
  307. hObj.r.push(ev);
  308. for(var i = 0; i < attrs.length; ++i) {
  309. as.push(attrCompile(attrs[i]));
  310. }
  311. as = ele.childNodes.length;
  312. if(as) {
  313. stack.push(hObj);
  314. hObj = { r: es, i: 0, c: ele.childNodes, t: false, s: "", l: as };
  315. stack.push(hObj);
  316. break;
  317. }
  318. } else if(ele.nodeType == 3) {
  319. hObj.s = hObj.t ? (hObj.s + ele.nodeValue) : ele.nodeValue;
  320. if(hObj.i>=hObj.l){
  321. hObj.r.push(textCompile(hObj.s));
  322. }else{
  323. hObj.t = true;
  324. }
  325. }
  326. }
  327. hObj = stack.pop();
  328. }
  329. return ret;
  330. },
  331. // /* ret.h(env) Element compiler */
  332. // eleCompile = function(ele) {
  333. // var attrs = ele.attributes,
  334. // cdir = ele.getAttribute("ch-dir") || "_",
  335. // ret = { n: ele.nodeName },
  336. // as = ret.as = [],
  337. // es = ret.es = [],
  338. // lisT, s, ch;
  339. // ch = cdir.split("-");
  340. // ret.h = ch.shift();
  341. // if(ch.length) ret.p = ch;
  342. // for(var i = 0; i < attrs.length; ++i) {
  343. // as.push(attrCompile(attrs[i]));
  344. // }
  345. // childCompile(ele.childNodes, ret.es);
  346. // return ret;
  347. // },
  348. parseElement = function(ele) {
  349. var env = { sh: {}, dir: {} },
  350. chs = childCompile(ele.childNodes);
  351. $.extend(env.sh, ch_val_buider);
  352. $.extend(env.dir, ch_dir_container);
  353. return {
  354. "shell": function(name, hand) {
  355. if(hand) {
  356. env.sh[name] = hand;
  357. return this;
  358. } else return env.sh[name];
  359. },
  360. "dir": function(name, hand) {
  361. if(hand) {
  362. env.dir[name] = hand;
  363. return this;
  364. } else return env.dir[name];
  365. },
  366. "fill": function(pe, data) {
  367. env.es = [];
  368. env.ds = [];
  369. env.is = [];
  370. env.ce = pe, env.cd = data;
  371. for(var i = 0; i < chs.length; ++i) {
  372. var ch = chs[i];
  373. env.dir[ch.h].call(ch, env);
  374. }
  375. return this;
  376. }
  377. };
  378. },
  379. parseCode = function(ele) {
  380. var ele=ele.jquery?ele[0]:ele, hand = parseElement(ele),
  381. $ele = $(ele),
  382. bh = util.nochange,
  383. lses = [];
  384. return $.extend(hand, {
  385. "val": function(data) {
  386. data = bh(data);
  387. if(false === data) return this;
  388. $ele.empty();
  389. var docf = doc.createDocumentFragment();
  390. this.fill(docf, data);
  391. ele.appendChild(docf);
  392. for(var i = 0; i < lses.length; ++i) {
  393. lses[i]();
  394. }
  395. return this;
  396. },
  397. "empty": function() {
  398. $(ele).empty();
  399. return this;
  400. },
  401. "listen": function(h) {
  402. if(h) lses.push(h);
  403. return this;
  404. },
  405. "before": function(h) {
  406. if(h) {
  407. bh = h;
  408. }
  409. }
  410. });
  411. },
  412. parseHtmlTemplate = function(c) {
  413. var $div = $("<div style='display:none;'></div>");
  414. $div.appendTo($body).html(c);
  415. var h = parseCode($div[0]);
  416. $div.remove();
  417. return $.extend(h, {
  418. "appendTo": function(pe, data) {
  419. var docf = doc.createDocumentFragment();
  420. this.fill(docf, data);
  421. pe.appendChild(docf);
  422. }
  423. });
  424. };
  425. return {
  426. "parse": parseElement,
  427. "parseCode": parseCode,
  428. "template": parseHtmlTemplate
  429. };
  430. });