vue-template-html.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const plugin = ({ modules }) => {
  4. return {
  5. version: 1,
  6. compileSFCTemplate(lang, template, options) {
  7. if (lang === 'html') {
  8. const compiler = modules['@vue/compiler-dom'];
  9. return compiler.compile(template, {
  10. ...options,
  11. comments: true,
  12. });
  13. }
  14. },
  15. updateSFCTemplate(oldResult, change) {
  16. const CompilerDOM = modules['@vue/compiler-dom'];
  17. const lengthDiff = change.newText.length - (change.end - change.start);
  18. let hitNodes = [];
  19. if (tryUpdateNode(oldResult.ast) && hitNodes.length) {
  20. hitNodes = hitNodes.sort((a, b) => a.loc.source.length - b.loc.source.length);
  21. const hitNode = hitNodes[0];
  22. if (hitNode.type === 4 /* CompilerDOM.NodeTypes.SIMPLE_EXPRESSION */) {
  23. return oldResult;
  24. }
  25. }
  26. function tryUpdateNode(node) {
  27. if (withinChangeRange(node.loc)) {
  28. hitNodes.push(node);
  29. }
  30. if (tryUpdateNodeLoc(node.loc)) {
  31. if (node.type === 0 /* CompilerDOM.NodeTypes.ROOT */) {
  32. for (const child of node.children) {
  33. if (!tryUpdateNode(child)) {
  34. return false;
  35. }
  36. }
  37. }
  38. else if (node.type === 1 /* CompilerDOM.NodeTypes.ELEMENT */) {
  39. if (withinChangeRange(node.loc)) {
  40. // if not self closing, should not hit tag name
  41. const start = node.loc.start.offset + 2;
  42. const end = node.loc.start.offset + node.loc.source.lastIndexOf('</');
  43. if (!withinChangeRange({ start: { offset: start }, end: { offset: end }, source: '' })) {
  44. return false;
  45. }
  46. }
  47. for (const prop of node.props) {
  48. if (!tryUpdateNode(prop)) {
  49. return false;
  50. }
  51. }
  52. for (const child of node.children) {
  53. if (!tryUpdateNode(child)) {
  54. return false;
  55. }
  56. }
  57. }
  58. else if (node.type === 6 /* CompilerDOM.NodeTypes.ATTRIBUTE */) {
  59. if (node.value && !tryUpdateNode(node.value)) {
  60. return false;
  61. }
  62. }
  63. else if (node.type === 7 /* CompilerDOM.NodeTypes.DIRECTIVE */) {
  64. if (node.arg && withinChangeRange(node.arg.loc) && node.name === 'slot') {
  65. return false;
  66. }
  67. if (node.exp && withinChangeRange(node.exp.loc) && node.name === 'for') { // #2266
  68. return false;
  69. }
  70. if (node.arg && !tryUpdateNode(node.arg)) {
  71. return false;
  72. }
  73. if (node.exp && !tryUpdateNode(node.exp)) {
  74. return false;
  75. }
  76. }
  77. else if (node.type === 12 /* CompilerDOM.NodeTypes.TEXT_CALL */) {
  78. if (!tryUpdateNode(node.content)) {
  79. return false;
  80. }
  81. }
  82. else if (node.type === 8 /* CompilerDOM.NodeTypes.COMPOUND_EXPRESSION */) {
  83. for (const childNode of node.children) {
  84. if (typeof childNode === 'object') {
  85. if (!tryUpdateNode(childNode)) {
  86. return false;
  87. }
  88. }
  89. }
  90. }
  91. else if (node.type === 9 /* CompilerDOM.NodeTypes.IF */) {
  92. for (const branch of node.branches) {
  93. if (branch.condition && !tryUpdateNode(branch.condition)) {
  94. return false;
  95. }
  96. for (const child of branch.children) {
  97. if (!tryUpdateNode(child)) {
  98. return false;
  99. }
  100. }
  101. }
  102. }
  103. else if (node.type === 11 /* CompilerDOM.NodeTypes.FOR */) {
  104. for (const child of [
  105. node.parseResult.source,
  106. node.parseResult.value,
  107. node.parseResult.key,
  108. node.parseResult.index,
  109. ]) {
  110. if (child && !tryUpdateNode(child)) {
  111. return false;
  112. }
  113. }
  114. for (const child of node.children) {
  115. if (!tryUpdateNode(child)) {
  116. return false;
  117. }
  118. }
  119. }
  120. else if (node.type === 5 /* CompilerDOM.NodeTypes.INTERPOLATION */) {
  121. if (!tryUpdateNode(node.content)) {
  122. return false;
  123. }
  124. }
  125. else if (node.type === 4 /* CompilerDOM.NodeTypes.SIMPLE_EXPRESSION */) {
  126. if (withinChangeRange(node.loc)) { // TODO: review this (slot name?)
  127. if (node.isStatic) {
  128. return false;
  129. }
  130. else {
  131. node.content = node.loc.source;
  132. }
  133. }
  134. }
  135. return true;
  136. }
  137. return false;
  138. }
  139. function tryUpdateNodeLoc(loc) {
  140. delete loc.__endOffset;
  141. if (withinChangeRange(loc)) {
  142. loc.source =
  143. loc.source.substring(0, change.start - loc.start.offset)
  144. + change.newText
  145. + loc.source.substring(change.end - loc.start.offset);
  146. loc.__endOffset = loc.end.offset;
  147. loc.end.offset += lengthDiff;
  148. return true;
  149. }
  150. else if (change.end <= loc.start.offset) {
  151. loc.__endOffset = loc.end.offset;
  152. loc.start.offset += lengthDiff;
  153. loc.end.offset += lengthDiff;
  154. return true;
  155. }
  156. else if (change.start >= loc.end.offset) {
  157. return true; // no need update
  158. }
  159. return false;
  160. }
  161. function withinChangeRange(loc) {
  162. const originalLocEnd = loc.__endOffset ?? loc.end.offset;
  163. return change.start >= loc.start.offset && change.end <= originalLocEnd;
  164. }
  165. },
  166. };
  167. };
  168. exports.default = plugin;
  169. //# sourceMappingURL=vue-template-html.js.map