PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/bower_components/CanJS/amd-dev/can/view/parser.js

https://gitlab.com/alekhya484/example-project
JavaScript | 304 lines | 295 code | 1 blank | 8 comment | 8 complexity | 9a78d5a5a7289617536e52e53518e55d MD5 | raw file
  1. /*!
  2. * CanJS - 2.3.23
  3. * http://canjs.com/
  4. * Copyright (c) 2016 Bitovi
  5. * Fri, 08 Apr 2016 17:58:15 GMT
  6. * Licensed MIT
  7. */
  8. /*can@2.3.23#view/parser/parser*/
  9. define([], function () {
  10. function each(items, callback) {
  11. for (var i = 0; i < items.length; i++) {
  12. callback(items[i], i);
  13. }
  14. }
  15. function makeMap(str) {
  16. var obj = {}, items = str.split(',');
  17. each(items, function (name) {
  18. obj[name] = true;
  19. });
  20. return obj;
  21. }
  22. function handleIntermediate(intermediate, handler) {
  23. for (var i = 0, len = intermediate.length; i < len; i++) {
  24. var item = intermediate[i];
  25. handler[item.tokenType].apply(handler, item.args);
  26. }
  27. return intermediate;
  28. }
  29. var alphaNumeric = 'A-Za-z0-9', alphaNumericHU = '-:_' + alphaNumeric, attributeNames = '[^=>\\s\\/]+', spaceEQspace = '\\s*=\\s*', singleCurly = '\\{[^\\}\\{]\\}', doubleCurly = '\\{\\{[^\\}]\\}\\}\\}?', attributeEqAndValue = '(?:' + spaceEQspace + '(?:' + '(?:' + doubleCurly + ')|(?:' + singleCurly + ')|(?:"[^"]*")|(?:\'[^\']*\')|[^>\\s]+))?', matchStash = '\\{\\{[^\\}]*\\}\\}\\}?', stash = '\\{\\{([^\\}]*)\\}\\}\\}?', startTag = new RegExp('^<([' + alphaNumeric + '][' + alphaNumericHU + ']*)' + '(' + '(?:\\s*' + '(?:(?:' + '(?:' + attributeNames + ')?' + attributeEqAndValue + ')|' + '(?:' + matchStash + ')+)' + ')*' + ')\\s*(\\/?)>'), endTag = new RegExp('^<\\/([' + alphaNumericHU + ']+)[^>]*>'), mustache = new RegExp(stash, 'g'), txtBreak = /<|\{\{/, space = /\s/;
  30. var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed');
  31. var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');
  32. var inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');
  33. var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
  34. var special = makeMap('script');
  35. var tokenTypes = 'start,end,close,attrStart,attrEnd,attrValue,chars,comment,special,done'.split(',');
  36. var fn = function () {
  37. };
  38. var HTMLParser = function (html, handler, returnIntermediate) {
  39. if (typeof html === 'object') {
  40. return handleIntermediate(html, handler);
  41. }
  42. var intermediate = [];
  43. handler = handler || {};
  44. if (returnIntermediate) {
  45. each(tokenTypes, function (name) {
  46. var callback = handler[name] || fn;
  47. handler[name] = function () {
  48. if (callback.apply(this, arguments) !== false) {
  49. intermediate.push({
  50. tokenType: name,
  51. args: [].slice.call(arguments, 0)
  52. });
  53. }
  54. };
  55. });
  56. }
  57. function parseStartTag(tag, tagName, rest, unary) {
  58. tagName = tagName.toLowerCase();
  59. if (block[tagName] && !inline[tagName]) {
  60. var last = stack.last();
  61. while (last && inline[last] && !block[last]) {
  62. parseEndTag('', last);
  63. last = stack.last();
  64. }
  65. }
  66. if (closeSelf[tagName] && stack.last() === tagName) {
  67. parseEndTag('', tagName);
  68. }
  69. unary = empty[tagName] || !!unary;
  70. handler.start(tagName, unary);
  71. if (!unary) {
  72. stack.push(tagName);
  73. }
  74. HTMLParser.parseAttrs(rest, handler);
  75. handler.end(tagName, unary);
  76. }
  77. function parseEndTag(tag, tagName) {
  78. var pos;
  79. if (!tagName) {
  80. pos = 0;
  81. } else {
  82. tagName = tagName.toLowerCase();
  83. for (pos = stack.length - 1; pos >= 0; pos--) {
  84. if (stack[pos] === tagName) {
  85. break;
  86. }
  87. }
  88. }
  89. if (pos >= 0) {
  90. for (var i = stack.length - 1; i >= pos; i--) {
  91. if (handler.close) {
  92. handler.close(stack[i]);
  93. }
  94. }
  95. stack.length = pos;
  96. }
  97. }
  98. function parseMustache(mustache, inside) {
  99. if (handler.special) {
  100. handler.special(inside);
  101. }
  102. }
  103. var callChars = function () {
  104. if (charsText) {
  105. if (handler.chars) {
  106. handler.chars(charsText);
  107. }
  108. }
  109. charsText = '';
  110. };
  111. var index, chars, match, stack = [], last = html, charsText = '';
  112. stack.last = function () {
  113. return this[this.length - 1];
  114. };
  115. while (html) {
  116. chars = true;
  117. if (!stack.last() || !special[stack.last()]) {
  118. if (html.indexOf('<!--') === 0) {
  119. index = html.indexOf('-->');
  120. if (index >= 0) {
  121. callChars();
  122. if (handler.comment) {
  123. handler.comment(html.substring(4, index));
  124. }
  125. html = html.substring(index + 3);
  126. chars = false;
  127. }
  128. } else if (html.indexOf('</') === 0) {
  129. match = html.match(endTag);
  130. if (match) {
  131. callChars();
  132. html = html.substring(match[0].length);
  133. match[0].replace(endTag, parseEndTag);
  134. chars = false;
  135. }
  136. } else if (html.indexOf('<') === 0) {
  137. match = html.match(startTag);
  138. if (match) {
  139. callChars();
  140. html = html.substring(match[0].length);
  141. match[0].replace(startTag, parseStartTag);
  142. chars = false;
  143. }
  144. } else if (html.indexOf('{{') === 0) {
  145. match = html.match(mustache);
  146. if (match) {
  147. callChars();
  148. html = html.substring(match[0].length);
  149. match[0].replace(mustache, parseMustache);
  150. }
  151. }
  152. if (chars) {
  153. index = html.search(txtBreak);
  154. if (index === 0 && html === last) {
  155. charsText += html.charAt(0);
  156. html = html.substr(1);
  157. index = html.search(txtBreak);
  158. }
  159. var text = index < 0 ? html : html.substring(0, index);
  160. html = index < 0 ? '' : html.substring(index);
  161. if (text) {
  162. charsText += text;
  163. }
  164. }
  165. } else {
  166. html = html.replace(new RegExp('([\\s\\S]*?)</' + stack.last() + '[^>]*>'), function (all, text) {
  167. text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
  168. if (handler.chars) {
  169. handler.chars(text);
  170. }
  171. return '';
  172. });
  173. parseEndTag('', stack.last());
  174. }
  175. if (html === last) {
  176. throw new Error('Parse Error: ' + html);
  177. }
  178. last = html;
  179. }
  180. callChars();
  181. parseEndTag();
  182. handler.done();
  183. return intermediate;
  184. };
  185. var callAttrStart = function (state, curIndex, handler, rest) {
  186. state.attrStart = rest.substring(typeof state.nameStart === 'number' ? state.nameStart : curIndex, curIndex);
  187. handler.attrStart(state.attrStart);
  188. state.inName = false;
  189. };
  190. var callAttrEnd = function (state, curIndex, handler, rest) {
  191. if (state.valueStart !== undefined && state.valueStart < curIndex) {
  192. handler.attrValue(rest.substring(state.valueStart, curIndex));
  193. } else if (!state.inValue) {
  194. }
  195. handler.attrEnd(state.attrStart);
  196. state.attrStart = undefined;
  197. state.valueStart = undefined;
  198. state.inValue = false;
  199. state.inName = false;
  200. state.lookingForEq = false;
  201. state.inQuote = false;
  202. state.lookingForName = true;
  203. };
  204. HTMLParser.parseAttrs = function (rest, handler) {
  205. if (!rest) {
  206. return;
  207. }
  208. var i = 0;
  209. var curIndex;
  210. var state = {
  211. inDoubleCurly: false,
  212. inName: false,
  213. nameStart: undefined,
  214. inValue: false,
  215. valueStart: undefined,
  216. inQuote: false,
  217. attrStart: undefined,
  218. lookingForName: true,
  219. lookingForValue: false,
  220. lookingForEq: false
  221. };
  222. while (i < rest.length) {
  223. curIndex = i;
  224. var cur = rest.charAt(i);
  225. var next = rest.charAt(i + 1);
  226. var nextNext = rest.charAt(i + 2);
  227. i++;
  228. if (cur === '{' && next === '{') {
  229. if (state.inValue && curIndex > state.valueStart) {
  230. handler.attrValue(rest.substring(state.valueStart, curIndex));
  231. } else if (state.inName && state.nameStart < curIndex) {
  232. callAttrStart(state, curIndex, handler, rest);
  233. callAttrEnd(state, curIndex, handler, rest);
  234. } else if (state.lookingForValue) {
  235. state.inValue = true;
  236. } else if (state.lookingForEq && state.attrStart) {
  237. callAttrEnd(state, curIndex, handler, rest);
  238. }
  239. state.inDoubleCurly = true;
  240. state.doubleCurlyStart = curIndex + 2;
  241. i++;
  242. } else if (state.inDoubleCurly) {
  243. if (cur === '}' && next === '}') {
  244. var isTriple = nextNext === '}' ? 1 : 0;
  245. handler.special(rest.substring(state.doubleCurlyStart, curIndex));
  246. state.inDoubleCurly = false;
  247. if (state.inValue) {
  248. state.valueStart = curIndex + 2 + isTriple;
  249. }
  250. i += 1 + isTriple;
  251. }
  252. } else if (state.inValue) {
  253. if (state.inQuote) {
  254. if (cur === state.inQuote) {
  255. callAttrEnd(state, curIndex, handler, rest);
  256. }
  257. } else if (space.test(cur)) {
  258. callAttrEnd(state, curIndex, handler, rest);
  259. }
  260. } else if (cur === '=' && (state.lookingForEq || state.lookingForName || state.inName)) {
  261. if (!state.attrStart) {
  262. callAttrStart(state, curIndex, handler, rest);
  263. }
  264. state.lookingForValue = true;
  265. state.lookingForEq = false;
  266. state.lookingForName = false;
  267. } else if (state.inName) {
  268. if (space.test(cur)) {
  269. callAttrStart(state, curIndex, handler, rest);
  270. state.lookingForEq = true;
  271. }
  272. } else if (state.lookingForName) {
  273. if (!space.test(cur)) {
  274. if (state.attrStart) {
  275. callAttrEnd(state, curIndex, handler, rest);
  276. }
  277. state.nameStart = curIndex;
  278. state.inName = true;
  279. }
  280. } else if (state.lookingForValue) {
  281. if (!space.test(cur)) {
  282. state.lookingForValue = false;
  283. state.inValue = true;
  284. if (cur === '\'' || cur === '"') {
  285. state.inQuote = cur;
  286. state.valueStart = curIndex + 1;
  287. } else {
  288. state.valueStart = curIndex;
  289. }
  290. }
  291. }
  292. }
  293. if (state.inName) {
  294. callAttrStart(state, curIndex + 1, handler, rest);
  295. callAttrEnd(state, curIndex + 1, handler, rest);
  296. } else if (state.lookingForEq) {
  297. callAttrEnd(state, curIndex + 1, handler, rest);
  298. } else if (state.inValue) {
  299. callAttrEnd(state, curIndex + 1, handler, rest);
  300. }
  301. };
  302. return HTMLParser;
  303. });