Guest User

Untitled

a guest
Jun 18th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.57 KB | None | 0 0
  1. /**
  2. * 将字符串编译为 DOM 结构
  3. * @deprecated 请注意,不要用该函数,因为 compile('<div></div><p></p>') 会编译成嵌套结构:<p><div></div></p>
  4. * @public
  5. * @param {String} domString
  6. * @return {HTMLElement}
  7. * @throws {Error} 如果输入不是合法的 DOM 字符串
  8. *
  9. * @example
  10. * compile('<div><p><a><em></em></a></p></div>')
  11. * // =>
  12. * <div>
  13. * <p>
  14. * <a>
  15. * <em></em>
  16. * </a>
  17. * </p>
  18. * </div>
  19. *
  20. * @example
  21. * compile('<div></p>')
  22. * // => Uncaught Error: DOM string invalid
  23. */
  24. function compile(domString) {
  25. var validated = validate(domString);
  26. if (!validated) {
  27. throw new Error('DOM string invalid');
  28. }
  29.  
  30. const compiled = assemble(validated);
  31.  
  32. return compiled;
  33. }
  34.  
  35. /**
  36. * 检测是否是合法的 DOM 字符串
  37. * @private
  38. *
  39. * @param {String} domString
  40. * @return {String[]|false} 若合法则返回标签名数组,否则返回 false
  41. *
  42. * @example
  43. * validate('<div></div>')
  44. * // => ['div']
  45. *
  46. * @example
  47. * validate('<div></p>')
  48. * // => false
  49. *
  50. * @example
  51. * validate('<div><p><a><em></em></a></p></div>')
  52. * // => ['div', 'p', 'a', 'em']
  53. */
  54. function validate(domString) {
  55. const beginTagPattern = /^<(\w+)>/;
  56. const closeTagPattern = /^<\/(\w+)>/;
  57. const stack = [];
  58. const tags = [];
  59.  
  60. let testString = domString;
  61. let delta = 1;
  62.  
  63. while (testString.length > 0) {
  64. const beginTagMatches = testString.match(beginTagPattern);
  65. const closeTagMatches = testString.match(closeTagPattern);
  66. let matches;
  67.  
  68. if (beginTagMatches) {
  69. matches = beginTagMatches;
  70. stack.push(matches[1]);
  71. // console.log('after push stack:', stack);
  72. } else if (closeTagMatches) {
  73. matches = closeTagMatches;
  74.  
  75. if (stack[stack.length - 1] === matches[1]) {
  76. const tag = stack.pop();
  77.  
  78. tags.push(tag);
  79.  
  80. // console.log('after pop stack:', stack);
  81. }
  82. } else {
  83. break;
  84. }
  85.  
  86. delta = matches[0].length + matches.index;
  87. testString = testString.slice(delta);
  88. }
  89.  
  90. // console.log('final stack:', stack);
  91.  
  92. return stack.length === 0 ? tags.reverse() : false;
  93. }
  94.  
  95. /**
  96. * 将标签组装为嵌套的 DOM 结构
  97. * @private
  98. * @param {String[]} tags
  99. * @return {HTMLElement}
  100. *
  101. * @example
  102. * assemble(['div', 'p', 'a', 'em'])
  103. * // => <div><p><a><em></em></a></p></div>
  104. */
  105. function assemble(tags) {
  106. const elements = tags.map((tag) => document.createElement(tag));
  107.  
  108. elements.forEach((element, index, elements) => {
  109. // console.log('element:', element);
  110. if (index !== elements.length - 1) {
  111. element.appendChild(elements[index + 1]);
  112. }
  113. });
  114.  
  115. return elements[0];
  116. }
Add Comment
Please, Sign In to add comment