@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.
|
@@ -48,11 +48,20 @@ var VueCompilerDOM = (function (exports) {
|
|
|
48
48
|
|
|
49
49
|
const range = 2;
|
|
50
50
|
function generateCodeFrame(source, start = 0, end = source.length) {
|
|
51
|
-
|
|
51
|
+
// Split the content into individual lines but capture the newline sequence
|
|
52
|
+
// that separated each line. This is important because the actual sequence is
|
|
53
|
+
// needed to properly take into account the full line length for offset
|
|
54
|
+
// comparison
|
|
55
|
+
let lines = source.split(/(\r?\n)/);
|
|
56
|
+
// Separate the lines and newline sequences into separate arrays for easier referencing
|
|
57
|
+
const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
|
|
58
|
+
lines = lines.filter((_, idx) => idx % 2 === 0);
|
|
52
59
|
let count = 0;
|
|
53
60
|
const res = [];
|
|
54
61
|
for (let i = 0; i < lines.length; i++) {
|
|
55
|
-
count +=
|
|
62
|
+
count +=
|
|
63
|
+
lines[i].length +
|
|
64
|
+
((newlineSequences[i] && newlineSequences[i].length) || 0);
|
|
56
65
|
if (count >= start) {
|
|
57
66
|
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
58
67
|
if (j < 0 || j >= lines.length)
|
|
@@ -60,9 +69,10 @@ var VueCompilerDOM = (function (exports) {
|
|
|
60
69
|
const line = j + 1;
|
|
61
70
|
res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
|
|
62
71
|
const lineLength = lines[j].length;
|
|
72
|
+
const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
|
|
63
73
|
if (j === i) {
|
|
64
74
|
// push underline
|
|
65
|
-
const pad = start - (count - lineLength
|
|
75
|
+
const pad = start - (count - (lineLength + newLineSeqLength));
|
|
66
76
|
const length = Math.max(1, end > count ? lineLength - pad : end - start);
|
|
67
77
|
res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
|
|
68
78
|
}
|
|
@@ -71,7 +81,7 @@ var VueCompilerDOM = (function (exports) {
|
|
|
71
81
|
const length = Math.max(Math.min(end - count, lineLength), 1);
|
|
72
82
|
res.push(` | ` + '^'.repeat(length));
|
|
73
83
|
}
|
|
74
|
-
count += lineLength +
|
|
84
|
+
count += lineLength + newLineSeqLength;
|
|
75
85
|
}
|
|
76
86
|
}
|
|
77
87
|
break;
|
|
@@ -518,18 +528,84 @@ var VueCompilerDOM = (function (exports) {
|
|
|
518
528
|
}
|
|
519
529
|
const nonIdentifierRE = /^\d|[^\$\w]/;
|
|
520
530
|
const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
|
|
521
|
-
const
|
|
531
|
+
const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
|
|
532
|
+
const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
|
|
533
|
+
const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
|
|
534
|
+
/**
|
|
535
|
+
* Simple lexer to check if an expression is a member expression. This is
|
|
536
|
+
* lax and only checks validity at the root level (i.e. does not validate exps
|
|
537
|
+
* inside square brackets), but it's ok since these are only used on template
|
|
538
|
+
* expressions and false positives are invalid expressions in the first place.
|
|
539
|
+
*/
|
|
522
540
|
const isMemberExpression = (path) => {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
541
|
+
// remove whitespaces around . or [ first
|
|
542
|
+
path = path.trim().replace(whitespaceRE, s => s.trim());
|
|
543
|
+
let state = 0 /* inMemberExp */;
|
|
544
|
+
let stateStack = [];
|
|
545
|
+
let currentOpenBracketCount = 0;
|
|
546
|
+
let currentOpenParensCount = 0;
|
|
547
|
+
let currentStringType = null;
|
|
548
|
+
for (let i = 0; i < path.length; i++) {
|
|
549
|
+
const char = path.charAt(i);
|
|
550
|
+
switch (state) {
|
|
551
|
+
case 0 /* inMemberExp */:
|
|
552
|
+
if (char === '[') {
|
|
553
|
+
stateStack.push(state);
|
|
554
|
+
state = 1 /* inBrackets */;
|
|
555
|
+
currentOpenBracketCount++;
|
|
556
|
+
}
|
|
557
|
+
else if (char === '(') {
|
|
558
|
+
stateStack.push(state);
|
|
559
|
+
state = 2 /* inParens */;
|
|
560
|
+
currentOpenParensCount++;
|
|
561
|
+
}
|
|
562
|
+
else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
|
|
563
|
+
return false;
|
|
564
|
+
}
|
|
565
|
+
break;
|
|
566
|
+
case 1 /* inBrackets */:
|
|
567
|
+
if (char === `'` || char === `"` || char === '`') {
|
|
568
|
+
stateStack.push(state);
|
|
569
|
+
state = 3 /* inString */;
|
|
570
|
+
currentStringType = char;
|
|
571
|
+
}
|
|
572
|
+
else if (char === `[`) {
|
|
573
|
+
currentOpenBracketCount++;
|
|
574
|
+
}
|
|
575
|
+
else if (char === `]`) {
|
|
576
|
+
if (!--currentOpenBracketCount) {
|
|
577
|
+
state = stateStack.pop();
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
break;
|
|
581
|
+
case 2 /* inParens */:
|
|
582
|
+
if (char === `'` || char === `"` || char === '`') {
|
|
583
|
+
stateStack.push(state);
|
|
584
|
+
state = 3 /* inString */;
|
|
585
|
+
currentStringType = char;
|
|
586
|
+
}
|
|
587
|
+
else if (char === `(`) {
|
|
588
|
+
currentOpenParensCount++;
|
|
589
|
+
}
|
|
590
|
+
else if (char === `)`) {
|
|
591
|
+
// if the exp ends as a call then it should not be considered valid
|
|
592
|
+
if (i === path.length - 1) {
|
|
593
|
+
return false;
|
|
594
|
+
}
|
|
595
|
+
if (!--currentOpenParensCount) {
|
|
596
|
+
state = stateStack.pop();
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
break;
|
|
600
|
+
case 3 /* inString */:
|
|
601
|
+
if (char === currentStringType) {
|
|
602
|
+
state = stateStack.pop();
|
|
603
|
+
currentStringType = null;
|
|
604
|
+
}
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
return !currentOpenBracketCount && !currentOpenParensCount;
|
|
533
609
|
};
|
|
534
610
|
function getInnerRange(loc, offset, length) {
|
|
535
611
|
const source = loc.source.substr(offset, length);
|
|
@@ -1098,6 +1174,10 @@ var VueCompilerDOM = (function (exports) {
|
|
|
1098
1174
|
const isPreBoundary = context.inPre && !wasInPre;
|
|
1099
1175
|
const isVPreBoundary = context.inVPre && !wasInVPre;
|
|
1100
1176
|
if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
|
|
1177
|
+
// #4030 self-closing <pre> tag
|
|
1178
|
+
if (context.options.isPreTag(element.tag)) {
|
|
1179
|
+
context.inPre = false;
|
|
1180
|
+
}
|
|
1101
1181
|
return element;
|
|
1102
1182
|
}
|
|
1103
1183
|
// Children.
|
|
@@ -1153,12 +1233,13 @@ var VueCompilerDOM = (function (exports) {
|
|
|
1153
1233
|
// save current state in case we need to re-parse attributes with v-pre
|
|
1154
1234
|
const cursor = getCursor(context);
|
|
1155
1235
|
const currentSource = context.source;
|
|
1156
|
-
// Attributes.
|
|
1157
|
-
let props = parseAttributes(context, type);
|
|
1158
1236
|
// check <pre> tag
|
|
1159
|
-
|
|
1237
|
+
const isPreTag = context.options.isPreTag(tag);
|
|
1238
|
+
if (isPreTag) {
|
|
1160
1239
|
context.inPre = true;
|
|
1161
1240
|
}
|
|
1241
|
+
// Attributes.
|
|
1242
|
+
let props = parseAttributes(context, type);
|
|
1162
1243
|
// check v-pre
|
|
1163
1244
|
if (type === 0 /* Start */ &&
|
|
1164
1245
|
!context.inVPre &&
|
|
@@ -1205,41 +1286,17 @@ var VueCompilerDOM = (function (exports) {
|
|
|
1205
1286
|
}
|
|
1206
1287
|
}
|
|
1207
1288
|
let tagType = 0 /* ELEMENT */;
|
|
1208
|
-
|
|
1209
|
-
if (!context.inVPre && !options.isCustomElement(tag)) {
|
|
1210
|
-
const hasVIs = props.some(p => {
|
|
1211
|
-
if (p.name !== 'is')
|
|
1212
|
-
return;
|
|
1213
|
-
// v-is="xxx" (TODO: deprecate)
|
|
1214
|
-
if (p.type === 7 /* DIRECTIVE */) {
|
|
1215
|
-
return true;
|
|
1216
|
-
}
|
|
1217
|
-
// is="vue:xxx"
|
|
1218
|
-
if (p.value && p.value.content.startsWith('vue:')) {
|
|
1219
|
-
return true;
|
|
1220
|
-
}
|
|
1221
|
-
// in compat mode, any is usage is considered a component
|
|
1222
|
-
if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
|
|
1223
|
-
return true;
|
|
1224
|
-
}
|
|
1225
|
-
});
|
|
1226
|
-
if (options.isNativeTag && !hasVIs) {
|
|
1227
|
-
if (!options.isNativeTag(tag))
|
|
1228
|
-
tagType = 1 /* COMPONENT */;
|
|
1229
|
-
}
|
|
1230
|
-
else if (hasVIs ||
|
|
1231
|
-
isCoreComponent(tag) ||
|
|
1232
|
-
(options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
|
|
1233
|
-
/^[A-Z]/.test(tag) ||
|
|
1234
|
-
tag === 'component') {
|
|
1235
|
-
tagType = 1 /* COMPONENT */;
|
|
1236
|
-
}
|
|
1289
|
+
if (!context.inVPre) {
|
|
1237
1290
|
if (tag === 'slot') {
|
|
1238
1291
|
tagType = 2 /* SLOT */;
|
|
1239
1292
|
}
|
|
1240
|
-
else if (tag === 'template'
|
|
1241
|
-
props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
|
|
1242
|
-
|
|
1293
|
+
else if (tag === 'template') {
|
|
1294
|
+
if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
|
|
1295
|
+
tagType = 3 /* TEMPLATE */;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
else if (isComponent(tag, props, context)) {
|
|
1299
|
+
tagType = 1 /* COMPONENT */;
|
|
1243
1300
|
}
|
|
1244
1301
|
}
|
|
1245
1302
|
return {
|
|
@@ -1254,6 +1311,49 @@ var VueCompilerDOM = (function (exports) {
|
|
|
1254
1311
|
codegenNode: undefined // to be created during transform phase
|
|
1255
1312
|
};
|
|
1256
1313
|
}
|
|
1314
|
+
function isComponent(tag, props, context) {
|
|
1315
|
+
const options = context.options;
|
|
1316
|
+
if (options.isCustomElement(tag)) {
|
|
1317
|
+
return false;
|
|
1318
|
+
}
|
|
1319
|
+
if (tag === 'component' ||
|
|
1320
|
+
/^[A-Z]/.test(tag) ||
|
|
1321
|
+
isCoreComponent(tag) ||
|
|
1322
|
+
(options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
|
|
1323
|
+
(options.isNativeTag && !options.isNativeTag(tag))) {
|
|
1324
|
+
return true;
|
|
1325
|
+
}
|
|
1326
|
+
// at this point the tag should be a native tag, but check for potential "is"
|
|
1327
|
+
// casting
|
|
1328
|
+
for (let i = 0; i < props.length; i++) {
|
|
1329
|
+
const p = props[i];
|
|
1330
|
+
if (p.type === 6 /* ATTRIBUTE */) {
|
|
1331
|
+
if (p.name === 'is' && p.value) {
|
|
1332
|
+
if (p.value.content.startsWith('vue:')) {
|
|
1333
|
+
return true;
|
|
1334
|
+
}
|
|
1335
|
+
else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
|
|
1336
|
+
return true;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
else {
|
|
1341
|
+
// directive
|
|
1342
|
+
// v-is (TODO Deprecate)
|
|
1343
|
+
if (p.name === 'is') {
|
|
1344
|
+
return true;
|
|
1345
|
+
}
|
|
1346
|
+
else if (
|
|
1347
|
+
// :is on plain element - only treat as component in compat mode
|
|
1348
|
+
p.name === 'bind' &&
|
|
1349
|
+
isBindKey(p.arg, 'is') &&
|
|
1350
|
+
true &&
|
|
1351
|
+
checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
|
|
1352
|
+
return true;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1257
1357
|
function parseAttributes(context, type) {
|
|
1258
1358
|
const props = [];
|
|
1259
1359
|
const attributeNames = new Set();
|
|
@@ -2116,7 +2216,7 @@ var VueCompilerDOM = (function (exports) {
|
|
|
2116
2216
|
}
|
|
2117
2217
|
|
|
2118
2218
|
const PURE_ANNOTATION = `/*#__PURE__*/`;
|
|
2119
|
-
function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false }) {
|
|
2219
|
+
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 }) {
|
|
2120
2220
|
const context = {
|
|
2121
2221
|
mode,
|
|
2122
2222
|
prefixIdentifiers,
|
|
@@ -2127,6 +2227,7 @@ var VueCompilerDOM = (function (exports) {
|
|
|
2127
2227
|
runtimeGlobalName,
|
|
2128
2228
|
runtimeModuleName,
|
|
2129
2229
|
ssr,
|
|
2230
|
+
isTS,
|
|
2130
2231
|
source: ast.loc.source,
|
|
2131
2232
|
code: ``,
|
|
2132
2233
|
column: 1,
|
|
@@ -2282,7 +2383,7 @@ var VueCompilerDOM = (function (exports) {
|
|
|
2282
2383
|
newline();
|
|
2283
2384
|
push(`return `);
|
|
2284
2385
|
}
|
|
2285
|
-
function genAssets(assets, type, { helper, push, newline }) {
|
|
2386
|
+
function genAssets(assets, type, { helper, push, newline, isTS }) {
|
|
2286
2387
|
const resolver = helper(type === 'filter'
|
|
2287
2388
|
? RESOLVE_FILTER
|
|
2288
2389
|
: type === 'component'
|
|
@@ -2295,7 +2396,7 @@ var VueCompilerDOM = (function (exports) {
|
|
|
2295
2396
|
if (maybeSelfReference) {
|
|
2296
2397
|
id = id.slice(0, -6);
|
|
2297
2398
|
}
|
|
2298
|
-
push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})`);
|
|
2399
|
+
push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
|
|
2299
2400
|
if (i < assets.length - 1) {
|
|
2300
2401
|
newline();
|
|
2301
2402
|
}
|
|
@@ -3403,7 +3504,8 @@ var VueCompilerDOM = (function (exports) {
|
|
|
3403
3504
|
switch (child.type) {
|
|
3404
3505
|
case 1 /* ELEMENT */:
|
|
3405
3506
|
if (child.tagType === 2 /* SLOT */ ||
|
|
3406
|
-
(child.tagType === 0 /* ELEMENT */
|
|
3507
|
+
((child.tagType === 0 /* ELEMENT */ ||
|
|
3508
|
+
child.tagType === 3 /* TEMPLATE */) &&
|
|
3407
3509
|
hasForwardedSlots(child.children))) {
|
|
3408
3510
|
return true;
|
|
3409
3511
|
}
|
|
@@ -3567,16 +3669,10 @@ var VueCompilerDOM = (function (exports) {
|
|
|
3567
3669
|
let { tag } = node;
|
|
3568
3670
|
// 1. dynamic component
|
|
3569
3671
|
const isExplicitDynamic = isComponentTag(tag);
|
|
3570
|
-
const isProp = findProp(node, 'is')
|
|
3672
|
+
const isProp = findProp(node, 'is');
|
|
3571
3673
|
if (isProp) {
|
|
3572
|
-
if (
|
|
3573
|
-
|
|
3574
|
-
// if not <component>, only is value that starts with "vue:" will be
|
|
3575
|
-
// treated as component by the parse phase and reach here, unless it's
|
|
3576
|
-
// compat mode where all is values are considered components
|
|
3577
|
-
tag = isProp.value.content.replace(/^vue:/, '');
|
|
3578
|
-
}
|
|
3579
|
-
else {
|
|
3674
|
+
if (isExplicitDynamic ||
|
|
3675
|
+
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {
|
|
3580
3676
|
const exp = isProp.type === 6 /* ATTRIBUTE */
|
|
3581
3677
|
? isProp.value && createSimpleExpression(isProp.value.content, true)
|
|
3582
3678
|
: isProp.exp;
|
|
@@ -3586,6 +3682,21 @@ var VueCompilerDOM = (function (exports) {
|
|
|
3586
3682
|
]);
|
|
3587
3683
|
}
|
|
3588
3684
|
}
|
|
3685
|
+
else if (isProp.type === 6 /* ATTRIBUTE */ &&
|
|
3686
|
+
isProp.value.content.startsWith('vue:')) {
|
|
3687
|
+
// <button is="vue:xxx">
|
|
3688
|
+
// if not <component>, only is value that starts with "vue:" will be
|
|
3689
|
+
// treated as component by the parse phase and reach here, unless it's
|
|
3690
|
+
// compat mode where all is values are considered components
|
|
3691
|
+
tag = isProp.value.content.slice(4);
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
// 1.5 v-is (TODO: Deprecate)
|
|
3695
|
+
const isDir = !isExplicitDynamic && findDir(node, 'is');
|
|
3696
|
+
if (isDir && isDir.exp) {
|
|
3697
|
+
return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
|
|
3698
|
+
isDir.exp
|
|
3699
|
+
]);
|
|
3589
3700
|
}
|
|
3590
3701
|
// 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
|
|
3591
3702
|
const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
|
|
@@ -3669,7 +3780,9 @@ var VueCompilerDOM = (function (exports) {
|
|
|
3669
3780
|
}
|
|
3670
3781
|
// skip is on <component>, or is="vue:xxx"
|
|
3671
3782
|
if (name === 'is' &&
|
|
3672
|
-
(isComponentTag(tag) ||
|
|
3783
|
+
(isComponentTag(tag) ||
|
|
3784
|
+
(value && value.content.startsWith('vue:')) ||
|
|
3785
|
+
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
|
|
3673
3786
|
continue;
|
|
3674
3787
|
}
|
|
3675
3788
|
properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
|
|
@@ -3692,7 +3805,10 @@ var VueCompilerDOM = (function (exports) {
|
|
|
3692
3805
|
}
|
|
3693
3806
|
// skip v-is and :is on <component>
|
|
3694
3807
|
if (name === 'is' ||
|
|
3695
|
-
(isVBind &&
|
|
3808
|
+
(isVBind &&
|
|
3809
|
+
isBindKey(arg, 'is') &&
|
|
3810
|
+
(isComponentTag(tag) ||
|
|
3811
|
+
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
|
|
3696
3812
|
continue;
|
|
3697
3813
|
}
|
|
3698
3814
|
// skip v-on in SSR compilation
|
|
@@ -4217,7 +4333,7 @@ var VueCompilerDOM = (function (exports) {
|
|
|
4217
4333
|
// _unref(exp)
|
|
4218
4334
|
context.bindingMetadata[rawExp];
|
|
4219
4335
|
const maybeRef = !true /* SETUP_CONST */;
|
|
4220
|
-
if (!isMemberExpression(expString) && !maybeRef) {
|
|
4336
|
+
if (!expString.trim() || (!isMemberExpression(expString) && !maybeRef)) {
|
|
4221
4337
|
context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
|
|
4222
4338
|
return createTransformProps();
|
|
4223
4339
|
}
|