parseSfc.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.parse = void 0;
  4. const compiler = require("@vue/compiler-dom");
  5. function parse(source) {
  6. const errors = [];
  7. const ast = compiler.parse(source, {
  8. // there are no components at SFC parsing level
  9. isNativeTag: () => true,
  10. // preserve all whitespaces
  11. isPreTag: () => true,
  12. getTextMode: ({ tag, props }, parent) => {
  13. if ((!parent && tag !== 'template')
  14. || (tag === 'template'
  15. && props.some(p => p.type === 6 /* compiler.NodeTypes.ATTRIBUTE */ &&
  16. p.name === 'lang' &&
  17. p.value &&
  18. p.value.content &&
  19. p.value.content !== 'html'))) {
  20. return 2 /* compiler.TextModes.RAWTEXT */;
  21. }
  22. else {
  23. return 0 /* compiler.TextModes.DATA */;
  24. }
  25. },
  26. onError: e => {
  27. errors.push(e);
  28. },
  29. comments: true,
  30. });
  31. const descriptor = {
  32. filename: 'anonymous.vue',
  33. source,
  34. template: null,
  35. script: null,
  36. scriptSetup: null,
  37. styles: [],
  38. customBlocks: [],
  39. cssVars: [],
  40. slotted: false,
  41. shouldForceReload: () => false,
  42. };
  43. ast.children.forEach(node => {
  44. if (node.type !== 1 /* compiler.NodeTypes.ELEMENT */) {
  45. return;
  46. }
  47. switch (node.tag) {
  48. case 'template':
  49. const templateBlock = (descriptor.template = createBlock(node, source));
  50. templateBlock.ast = node;
  51. break;
  52. case 'script':
  53. const scriptBlock = createBlock(node, source);
  54. const isSetup = !!scriptBlock.attrs.setup;
  55. if (isSetup && !descriptor.scriptSetup) {
  56. descriptor.scriptSetup = scriptBlock;
  57. break;
  58. }
  59. if (!isSetup && !descriptor.script) {
  60. descriptor.script = scriptBlock;
  61. break;
  62. }
  63. break;
  64. case 'style':
  65. const styleBlock = createBlock(node, source);
  66. descriptor.styles.push(styleBlock);
  67. break;
  68. default:
  69. descriptor.customBlocks.push(createBlock(node, source));
  70. break;
  71. }
  72. });
  73. return {
  74. descriptor,
  75. errors,
  76. };
  77. }
  78. exports.parse = parse;
  79. function createBlock(node, source) {
  80. const type = node.tag;
  81. let { start, end } = node.loc;
  82. let content = '';
  83. if (node.children.length) {
  84. start = node.children[0].loc.start;
  85. end = node.children[node.children.length - 1].loc.end;
  86. content = source.slice(start.offset, end.offset);
  87. }
  88. else {
  89. const offset = node.loc.source.indexOf(`</`);
  90. if (offset > -1) {
  91. start = {
  92. line: start.line,
  93. column: start.column + offset,
  94. offset: start.offset + offset
  95. };
  96. }
  97. end = Object.assign({}, start);
  98. }
  99. const loc = {
  100. source: content,
  101. start,
  102. end
  103. };
  104. const attrs = {};
  105. const block = {
  106. type,
  107. content,
  108. loc,
  109. attrs
  110. };
  111. node.props.forEach(p => {
  112. if (p.type === 6 /* compiler.NodeTypes.ATTRIBUTE */) {
  113. attrs[p.name] = p.value ? p.value.content || true : true;
  114. if (p.name === 'lang') {
  115. block.lang = p.value && p.value.content;
  116. }
  117. else if (p.name === 'src') {
  118. block.src = p.value && p.value.content;
  119. }
  120. else if (type === 'style') {
  121. if (p.name === 'scoped') {
  122. block.scoped = true;
  123. }
  124. else if (p.name === 'module') {
  125. block.module = attrs[p.name];
  126. }
  127. }
  128. else if (type === 'script' && p.name === 'setup') {
  129. block.setup = attrs.setup;
  130. }
  131. }
  132. });
  133. return block;
  134. }
  135. //# sourceMappingURL=parseSfc.js.map