@vue/compiler-dom 3.1.1 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -45,11 +45,20 @@ const slotFlagsText = {
|
|
|
45
45
|
|
|
46
46
|
const range = 2;
|
|
47
47
|
function generateCodeFrame(source, start = 0, end = source.length) {
|
|
48
|
-
|
|
48
|
+
// Split the content into individual lines but capture the newline sequence
|
|
49
|
+
// that separated each line. This is important because the actual sequence is
|
|
50
|
+
// needed to properly take into account the full line length for offset
|
|
51
|
+
// comparison
|
|
52
|
+
let lines = source.split(/(\r?\n)/);
|
|
53
|
+
// Separate the lines and newline sequences into separate arrays for easier referencing
|
|
54
|
+
const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
|
|
55
|
+
lines = lines.filter((_, idx) => idx % 2 === 0);
|
|
49
56
|
let count = 0;
|
|
50
57
|
const res = [];
|
|
51
58
|
for (let i = 0; i < lines.length; i++) {
|
|
52
|
-
count +=
|
|
59
|
+
count +=
|
|
60
|
+
lines[i].length +
|
|
61
|
+
((newlineSequences[i] && newlineSequences[i].length) || 0);
|
|
53
62
|
if (count >= start) {
|
|
54
63
|
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
55
64
|
if (j < 0 || j >= lines.length)
|
|
@@ -57,9 +66,10 @@ function generateCodeFrame(source, start = 0, end = source.length) {
|
|
|
57
66
|
const line = j + 1;
|
|
58
67
|
res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
|
|
59
68
|
const lineLength = lines[j].length;
|
|
69
|
+
const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
|
|
60
70
|
if (j === i) {
|
|
61
71
|
// push underline
|
|
62
|
-
const pad = start - (count - lineLength
|
|
72
|
+
const pad = start - (count - (lineLength + newLineSeqLength));
|
|
63
73
|
const length = Math.max(1, end > count ? lineLength - pad : end - start);
|
|
64
74
|
res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
|
|
65
75
|
}
|
|
@@ -68,7 +78,7 @@ function generateCodeFrame(source, start = 0, end = source.length) {
|
|
|
68
78
|
const length = Math.max(Math.min(end - count, lineLength), 1);
|
|
69
79
|
res.push(` | ` + '^'.repeat(length));
|
|
70
80
|
}
|
|
71
|
-
count += lineLength +
|
|
81
|
+
count += lineLength + newLineSeqLength;
|
|
72
82
|
}
|
|
73
83
|
}
|
|
74
84
|
break;
|
|
@@ -515,18 +525,84 @@ function isCoreComponent(tag) {
|
|
|
515
525
|
}
|
|
516
526
|
const nonIdentifierRE = /^\d|[^\$\w]/;
|
|
517
527
|
const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
|
|
518
|
-
const
|
|
528
|
+
const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
|
|
529
|
+
const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
|
|
530
|
+
const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
|
|
531
|
+
/**
|
|
532
|
+
* Simple lexer to check if an expression is a member expression. This is
|
|
533
|
+
* lax and only checks validity at the root level (i.e. does not validate exps
|
|
534
|
+
* inside square brackets), but it's ok since these are only used on template
|
|
535
|
+
* expressions and false positives are invalid expressions in the first place.
|
|
536
|
+
*/
|
|
519
537
|
const isMemberExpression = (path) => {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
538
|
+
// remove whitespaces around . or [ first
|
|
539
|
+
path = path.trim().replace(whitespaceRE, s => s.trim());
|
|
540
|
+
let state = 0 /* inMemberExp */;
|
|
541
|
+
let stateStack = [];
|
|
542
|
+
let currentOpenBracketCount = 0;
|
|
543
|
+
let currentOpenParensCount = 0;
|
|
544
|
+
let currentStringType = null;
|
|
545
|
+
for (let i = 0; i < path.length; i++) {
|
|
546
|
+
const char = path.charAt(i);
|
|
547
|
+
switch (state) {
|
|
548
|
+
case 0 /* inMemberExp */:
|
|
549
|
+
if (char === '[') {
|
|
550
|
+
stateStack.push(state);
|
|
551
|
+
state = 1 /* inBrackets */;
|
|
552
|
+
currentOpenBracketCount++;
|
|
553
|
+
}
|
|
554
|
+
else if (char === '(') {
|
|
555
|
+
stateStack.push(state);
|
|
556
|
+
state = 2 /* inParens */;
|
|
557
|
+
currentOpenParensCount++;
|
|
558
|
+
}
|
|
559
|
+
else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
break;
|
|
563
|
+
case 1 /* inBrackets */:
|
|
564
|
+
if (char === `'` || char === `"` || char === '`') {
|
|
565
|
+
stateStack.push(state);
|
|
566
|
+
state = 3 /* inString */;
|
|
567
|
+
currentStringType = char;
|
|
568
|
+
}
|
|
569
|
+
else if (char === `[`) {
|
|
570
|
+
currentOpenBracketCount++;
|
|
571
|
+
}
|
|
572
|
+
else if (char === `]`) {
|
|
573
|
+
if (!--currentOpenBracketCount) {
|
|
574
|
+
state = stateStack.pop();
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
break;
|
|
578
|
+
case 2 /* inParens */:
|
|
579
|
+
if (char === `'` || char === `"` || char === '`') {
|
|
580
|
+
stateStack.push(state);
|
|
581
|
+
state = 3 /* inString */;
|
|
582
|
+
currentStringType = char;
|
|
583
|
+
}
|
|
584
|
+
else if (char === `(`) {
|
|
585
|
+
currentOpenParensCount++;
|
|
586
|
+
}
|
|
587
|
+
else if (char === `)`) {
|
|
588
|
+
// if the exp ends as a call then it should not be considered valid
|
|
589
|
+
if (i === path.length - 1) {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
if (!--currentOpenParensCount) {
|
|
593
|
+
state = stateStack.pop();
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
break;
|
|
597
|
+
case 3 /* inString */:
|
|
598
|
+
if (char === currentStringType) {
|
|
599
|
+
state = stateStack.pop();
|
|
600
|
+
currentStringType = null;
|
|
601
|
+
}
|
|
602
|
+
break;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return !currentOpenBracketCount && !currentOpenParensCount;
|
|
530
606
|
};
|
|
531
607
|
function getInnerRange(loc, offset, length) {
|
|
532
608
|
const source = loc.source.substr(offset, length);
|
|
@@ -1095,6 +1171,10 @@ function parseElement(context, ancestors) {
|
|
|
1095
1171
|
const isPreBoundary = context.inPre && !wasInPre;
|
|
1096
1172
|
const isVPreBoundary = context.inVPre && !wasInVPre;
|
|
1097
1173
|
if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
|
|
1174
|
+
// #4030 self-closing <pre> tag
|
|
1175
|
+
if (context.options.isPreTag(element.tag)) {
|
|
1176
|
+
context.inPre = false;
|
|
1177
|
+
}
|
|
1098
1178
|
return element;
|
|
1099
1179
|
}
|
|
1100
1180
|
// Children.
|
|
@@ -1150,12 +1230,13 @@ function parseTag(context, type, parent) {
|
|
|
1150
1230
|
// save current state in case we need to re-parse attributes with v-pre
|
|
1151
1231
|
const cursor = getCursor(context);
|
|
1152
1232
|
const currentSource = context.source;
|
|
1153
|
-
// Attributes.
|
|
1154
|
-
let props = parseAttributes(context, type);
|
|
1155
1233
|
// check <pre> tag
|
|
1156
|
-
|
|
1234
|
+
const isPreTag = context.options.isPreTag(tag);
|
|
1235
|
+
if (isPreTag) {
|
|
1157
1236
|
context.inPre = true;
|
|
1158
1237
|
}
|
|
1238
|
+
// Attributes.
|
|
1239
|
+
let props = parseAttributes(context, type);
|
|
1159
1240
|
// check v-pre
|
|
1160
1241
|
if (type === 0 /* Start */ &&
|
|
1161
1242
|
!context.inVPre &&
|
|
@@ -1202,41 +1283,17 @@ function parseTag(context, type, parent) {
|
|
|
1202
1283
|
}
|
|
1203
1284
|
}
|
|
1204
1285
|
let tagType = 0 /* ELEMENT */;
|
|
1205
|
-
|
|
1206
|
-
if (!context.inVPre && !options.isCustomElement(tag)) {
|
|
1207
|
-
const hasVIs = props.some(p => {
|
|
1208
|
-
if (p.name !== 'is')
|
|
1209
|
-
return;
|
|
1210
|
-
// v-is="xxx" (TODO: deprecate)
|
|
1211
|
-
if (p.type === 7 /* DIRECTIVE */) {
|
|
1212
|
-
return true;
|
|
1213
|
-
}
|
|
1214
|
-
// is="vue:xxx"
|
|
1215
|
-
if (p.value && p.value.content.startsWith('vue:')) {
|
|
1216
|
-
return true;
|
|
1217
|
-
}
|
|
1218
|
-
// in compat mode, any is usage is considered a component
|
|
1219
|
-
if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
|
|
1220
|
-
return true;
|
|
1221
|
-
}
|
|
1222
|
-
});
|
|
1223
|
-
if (options.isNativeTag && !hasVIs) {
|
|
1224
|
-
if (!options.isNativeTag(tag))
|
|
1225
|
-
tagType = 1 /* COMPONENT */;
|
|
1226
|
-
}
|
|
1227
|
-
else if (hasVIs ||
|
|
1228
|
-
isCoreComponent(tag) ||
|
|
1229
|
-
(options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
|
|
1230
|
-
/^[A-Z]/.test(tag) ||
|
|
1231
|
-
tag === 'component') {
|
|
1232
|
-
tagType = 1 /* COMPONENT */;
|
|
1233
|
-
}
|
|
1286
|
+
if (!context.inVPre) {
|
|
1234
1287
|
if (tag === 'slot') {
|
|
1235
1288
|
tagType = 2 /* SLOT */;
|
|
1236
1289
|
}
|
|
1237
|
-
else if (tag === 'template'
|
|
1238
|
-
props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
|
|
1239
|
-
|
|
1290
|
+
else if (tag === 'template') {
|
|
1291
|
+
if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
|
|
1292
|
+
tagType = 3 /* TEMPLATE */;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
else if (isComponent(tag, props, context)) {
|
|
1296
|
+
tagType = 1 /* COMPONENT */;
|
|
1240
1297
|
}
|
|
1241
1298
|
}
|
|
1242
1299
|
return {
|
|
@@ -1251,6 +1308,49 @@ function parseTag(context, type, parent) {
|
|
|
1251
1308
|
codegenNode: undefined // to be created during transform phase
|
|
1252
1309
|
};
|
|
1253
1310
|
}
|
|
1311
|
+
function isComponent(tag, props, context) {
|
|
1312
|
+
const options = context.options;
|
|
1313
|
+
if (options.isCustomElement(tag)) {
|
|
1314
|
+
return false;
|
|
1315
|
+
}
|
|
1316
|
+
if (tag === 'component' ||
|
|
1317
|
+
/^[A-Z]/.test(tag) ||
|
|
1318
|
+
isCoreComponent(tag) ||
|
|
1319
|
+
(options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
|
|
1320
|
+
(options.isNativeTag && !options.isNativeTag(tag))) {
|
|
1321
|
+
return true;
|
|
1322
|
+
}
|
|
1323
|
+
// at this point the tag should be a native tag, but check for potential "is"
|
|
1324
|
+
// casting
|
|
1325
|
+
for (let i = 0; i < props.length; i++) {
|
|
1326
|
+
const p = props[i];
|
|
1327
|
+
if (p.type === 6 /* ATTRIBUTE */) {
|
|
1328
|
+
if (p.name === 'is' && p.value) {
|
|
1329
|
+
if (p.value.content.startsWith('vue:')) {
|
|
1330
|
+
return true;
|
|
1331
|
+
}
|
|
1332
|
+
else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
|
|
1333
|
+
return true;
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
else {
|
|
1338
|
+
// directive
|
|
1339
|
+
// v-is (TODO Deprecate)
|
|
1340
|
+
if (p.name === 'is') {
|
|
1341
|
+
return true;
|
|
1342
|
+
}
|
|
1343
|
+
else if (
|
|
1344
|
+
// :is on plain element - only treat as component in compat mode
|
|
1345
|
+
p.name === 'bind' &&
|
|
1346
|
+
isBindKey(p.arg, 'is') &&
|
|
1347
|
+
true &&
|
|
1348
|
+
checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
|
|
1349
|
+
return true;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1254
1354
|
function parseAttributes(context, type) {
|
|
1255
1355
|
const props = [];
|
|
1256
1356
|
const attributeNames = new Set();
|
|
@@ -2113,7 +2213,7 @@ function createStructuralDirectiveTransform(name, fn) {
|
|
|
2113
2213
|
}
|
|
2114
2214
|
|
|
2115
2215
|
const PURE_ANNOTATION = `/*#__PURE__*/`;
|
|
2116
|
-
function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false }) {
|
|
2216
|
+
function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false, isTS = false }) {
|
|
2117
2217
|
const context = {
|
|
2118
2218
|
mode,
|
|
2119
2219
|
prefixIdentifiers,
|
|
@@ -2124,6 +2224,7 @@ function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode
|
|
|
2124
2224
|
runtimeGlobalName,
|
|
2125
2225
|
runtimeModuleName,
|
|
2126
2226
|
ssr,
|
|
2227
|
+
isTS,
|
|
2127
2228
|
source: ast.loc.source,
|
|
2128
2229
|
code: ``,
|
|
2129
2230
|
column: 1,
|
|
@@ -2279,7 +2380,7 @@ function genFunctionPreamble(ast, context) {
|
|
|
2279
2380
|
newline();
|
|
2280
2381
|
push(`return `);
|
|
2281
2382
|
}
|
|
2282
|
-
function genAssets(assets, type, { helper, push, newline }) {
|
|
2383
|
+
function genAssets(assets, type, { helper, push, newline, isTS }) {
|
|
2283
2384
|
const resolver = helper(type === 'filter'
|
|
2284
2385
|
? RESOLVE_FILTER
|
|
2285
2386
|
: type === 'component'
|
|
@@ -2292,7 +2393,7 @@ function genAssets(assets, type, { helper, push, newline }) {
|
|
|
2292
2393
|
if (maybeSelfReference) {
|
|
2293
2394
|
id = id.slice(0, -6);
|
|
2294
2395
|
}
|
|
2295
|
-
push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})`);
|
|
2396
|
+
push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
|
|
2296
2397
|
if (i < assets.length - 1) {
|
|
2297
2398
|
newline();
|
|
2298
2399
|
}
|
|
@@ -3400,7 +3501,8 @@ function hasForwardedSlots(children) {
|
|
|
3400
3501
|
switch (child.type) {
|
|
3401
3502
|
case 1 /* ELEMENT */:
|
|
3402
3503
|
if (child.tagType === 2 /* SLOT */ ||
|
|
3403
|
-
(child.tagType === 0 /* ELEMENT */
|
|
3504
|
+
((child.tagType === 0 /* ELEMENT */ ||
|
|
3505
|
+
child.tagType === 3 /* TEMPLATE */) &&
|
|
3404
3506
|
hasForwardedSlots(child.children))) {
|
|
3405
3507
|
return true;
|
|
3406
3508
|
}
|
|
@@ -3564,16 +3666,10 @@ function resolveComponentType(node, context, ssr = false) {
|
|
|
3564
3666
|
let { tag } = node;
|
|
3565
3667
|
// 1. dynamic component
|
|
3566
3668
|
const isExplicitDynamic = isComponentTag(tag);
|
|
3567
|
-
const isProp = findProp(node, 'is')
|
|
3669
|
+
const isProp = findProp(node, 'is');
|
|
3568
3670
|
if (isProp) {
|
|
3569
|
-
if (
|
|
3570
|
-
|
|
3571
|
-
// if not <component>, only is value that starts with "vue:" will be
|
|
3572
|
-
// treated as component by the parse phase and reach here, unless it's
|
|
3573
|
-
// compat mode where all is values are considered components
|
|
3574
|
-
tag = isProp.value.content.replace(/^vue:/, '');
|
|
3575
|
-
}
|
|
3576
|
-
else {
|
|
3671
|
+
if (isExplicitDynamic ||
|
|
3672
|
+
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {
|
|
3577
3673
|
const exp = isProp.type === 6 /* ATTRIBUTE */
|
|
3578
3674
|
? isProp.value && createSimpleExpression(isProp.value.content, true)
|
|
3579
3675
|
: isProp.exp;
|
|
@@ -3583,6 +3679,21 @@ function resolveComponentType(node, context, ssr = false) {
|
|
|
3583
3679
|
]);
|
|
3584
3680
|
}
|
|
3585
3681
|
}
|
|
3682
|
+
else if (isProp.type === 6 /* ATTRIBUTE */ &&
|
|
3683
|
+
isProp.value.content.startsWith('vue:')) {
|
|
3684
|
+
// <button is="vue:xxx">
|
|
3685
|
+
// if not <component>, only is value that starts with "vue:" will be
|
|
3686
|
+
// treated as component by the parse phase and reach here, unless it's
|
|
3687
|
+
// compat mode where all is values are considered components
|
|
3688
|
+
tag = isProp.value.content.slice(4);
|
|
3689
|
+
}
|
|
3690
|
+
}
|
|
3691
|
+
// 1.5 v-is (TODO: Deprecate)
|
|
3692
|
+
const isDir = !isExplicitDynamic && findDir(node, 'is');
|
|
3693
|
+
if (isDir && isDir.exp) {
|
|
3694
|
+
return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
|
|
3695
|
+
isDir.exp
|
|
3696
|
+
]);
|
|
3586
3697
|
}
|
|
3587
3698
|
// 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
|
|
3588
3699
|
const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
|
|
@@ -3666,7 +3777,9 @@ function buildProps(node, context, props = node.props, ssr = false) {
|
|
|
3666
3777
|
}
|
|
3667
3778
|
// skip is on <component>, or is="vue:xxx"
|
|
3668
3779
|
if (name === 'is' &&
|
|
3669
|
-
(isComponentTag(tag) ||
|
|
3780
|
+
(isComponentTag(tag) ||
|
|
3781
|
+
(value && value.content.startsWith('vue:')) ||
|
|
3782
|
+
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
|
|
3670
3783
|
continue;
|
|
3671
3784
|
}
|
|
3672
3785
|
properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
|
|
@@ -3689,7 +3802,10 @@ function buildProps(node, context, props = node.props, ssr = false) {
|
|
|
3689
3802
|
}
|
|
3690
3803
|
// skip v-is and :is on <component>
|
|
3691
3804
|
if (name === 'is' ||
|
|
3692
|
-
(isVBind &&
|
|
3805
|
+
(isVBind &&
|
|
3806
|
+
isBindKey(arg, 'is') &&
|
|
3807
|
+
(isComponentTag(tag) ||
|
|
3808
|
+
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
|
|
3693
3809
|
continue;
|
|
3694
3810
|
}
|
|
3695
3811
|
// skip v-on in SSR compilation
|
|
@@ -4214,7 +4330,7 @@ const transformModel = (dir, node, context) => {
|
|
|
4214
4330
|
// _unref(exp)
|
|
4215
4331
|
context.bindingMetadata[rawExp];
|
|
4216
4332
|
const maybeRef = !true /* SETUP_CONST */;
|
|
4217
|
-
if (!isMemberExpression(expString) && !maybeRef) {
|
|
4333
|
+
if (!expString.trim() || (!isMemberExpression(expString) && !maybeRef)) {
|
|
4218
4334
|
context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
|
|
4219
4335
|
return createTransformProps();
|
|
4220
4336
|
}
|