Best JavaScript code snippet using playwright-internal
vendor-node_modules_r.js
Source:vendor-node_modules_r.js
...803 // in v3 mode, only enable if explicitly set to true804 // otherwise enable for any non-false value805 return mode === 3 ? value === true : value !== false;806}807function checkCompatEnabled(key, context, loc, ...args) {808 const enabled = isCompatEnabled(key, context);809 if (( true) && enabled) {810 warnDeprecation(key, context, loc, ...args);811 }812 return enabled;813}814function warnDeprecation(key, context, loc, ...args) {815 const val = getCompatValue(key, context);816 if (val === 'suppress-warning') {817 return;818 }819 const { message, link } = deprecationData[key];820 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;821 const err = new SyntaxError(msg);822 err.code = key;823 if (loc)824 err.loc = loc;825 context.onWarn(err);826}827// The default decoder only provides escapes for characters reserved as part of828// the template syntax, and is only used if the custom renderer did not provide829// a platform-specific decoder.830const decodeRE = /&(gt|lt|amp|apos|quot);/g;831const decodeMap = {832 gt: '>',833 lt: '<',834 amp: '&',835 apos: "'",836 quot: '"'837};838const defaultParserOptions = {839 delimiters: [`{{`, `}}`],840 getNamespace: () => 0 /* HTML */,841 getTextMode: () => 0 /* DATA */,842 isVoidTag: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,843 isPreTag: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,844 isCustomElement: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,845 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),846 onError: defaultOnError,847 onWarn: defaultOnWarn,848 comments: false849};850function baseParse(content, options = {}) {851 const context = createParserContext(content, options);852 const start = getCursor(context);853 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));854}855function createParserContext(content, rawOptions) {856 const options = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, defaultParserOptions);857 for (const key in rawOptions) {858 // @ts-ignore859 options[key] = rawOptions[key] || defaultParserOptions[key];860 }861 return {862 options,863 column: 1,864 line: 1,865 offset: 0,866 originalSource: content,867 source: content,868 inPre: false,869 inVPre: false,870 onWarn: options.onWarn871 };872}873function parseChildren(context, mode, ancestors) {874 const parent = last(ancestors);875 const ns = parent ? parent.ns : 0 /* HTML */;876 const nodes = [];877 while (!isEnd(context, mode, ancestors)) {878 const s = context.source;879 let node = undefined;880 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {881 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {882 // '{{'883 node = parseInterpolation(context, mode);884 }885 else if (mode === 0 /* DATA */ && s[0] === '<') {886 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state887 if (s.length === 1) {888 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);889 }890 else if (s[1] === '!') {891 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state892 if (startsWith(s, '<!--')) {893 node = parseComment(context);894 }895 else if (startsWith(s, '<!DOCTYPE')) {896 // Ignore DOCTYPE by a limitation.897 node = parseBogusComment(context);898 }899 else if (startsWith(s, '<![CDATA[')) {900 if (ns !== 0 /* HTML */) {901 node = parseCDATA(context, ancestors);902 }903 else {904 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);905 node = parseBogusComment(context);906 }907 }908 else {909 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);910 node = parseBogusComment(context);911 }912 }913 else if (s[1] === '/') {914 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state915 if (s.length === 2) {916 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);917 }918 else if (s[2] === '>') {919 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);920 advanceBy(context, 3);921 continue;922 }923 else if (/[a-z]/i.test(s[2])) {924 emitError(context, 23 /* X_INVALID_END_TAG */);925 parseTag(context, 1 /* End */, parent);926 continue;927 }928 else {929 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);930 node = parseBogusComment(context);931 }932 }933 else if (/[a-z]/i.test(s[1])) {934 node = parseElement(context, ancestors);935 // 2.x <template> with no directive compat936 if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&937 node &&938 node.tag === 'template' &&939 !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&940 isSpecialTemplateDirective(p.name))) {941 ( true) &&942 warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);943 node = node.children;944 }945 }946 else if (s[1] === '?') {947 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);948 node = parseBogusComment(context);949 }950 else {951 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);952 }953 }954 }955 if (!node) {956 node = parseText(context, mode);957 }958 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(node)) {959 for (let i = 0; i < node.length; i++) {960 pushNode(nodes, node[i]);961 }962 }963 else {964 pushNode(nodes, node);965 }966 }967 // Whitespace handling strategy like v2968 let removedWhitespace = false;969 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {970 const preserve = context.options.whitespace === 'preserve';971 for (let i = 0; i < nodes.length; i++) {972 const node = nodes[i];973 if (!context.inPre && node.type === 2 /* TEXT */) {974 if (!/[^\t\r\n\f ]/.test(node.content)) {975 const prev = nodes[i - 1];976 const next = nodes[i + 1];977 // Remove if:978 // - the whitespace is the first or last node, or:979 // - (condense mode) the whitespace is adjacent to a comment, or:980 // - (condense mode) the whitespace is between two elements AND contains newline981 if (!prev ||982 !next ||983 (!preserve &&984 (prev.type === 3 /* COMMENT */ ||985 next.type === 3 /* COMMENT */ ||986 (prev.type === 1 /* ELEMENT */ &&987 next.type === 1 /* ELEMENT */ &&988 /[\r\n]/.test(node.content))))) {989 removedWhitespace = true;990 nodes[i] = null;991 }992 else {993 // Otherwise, the whitespace is condensed into a single space994 node.content = ' ';995 }996 }997 else if (!preserve) {998 // in condense mode, consecutive whitespaces in text are condensed999 // down to a single space.1000 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1001 }1002 }1003 // also remove comment nodes in prod by default1004 if (false) {}1005 }1006 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1007 // remove leading newline per html spec1008 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1009 const first = nodes[0];1010 if (first && first.type === 2 /* TEXT */) {1011 first.content = first.content.replace(/^\r?\n/, '');1012 }1013 }1014 }1015 return removedWhitespace ? nodes.filter(Boolean) : nodes;1016}1017function pushNode(nodes, node) {1018 if (node.type === 2 /* TEXT */) {1019 const prev = last(nodes);1020 // Merge if both this and the previous node are text and those are1021 // consecutive. This happens for cases like "a < b".1022 if (prev &&1023 prev.type === 2 /* TEXT */ &&1024 prev.loc.end.offset === node.loc.start.offset) {1025 prev.content += node.content;1026 prev.loc.end = node.loc.end;1027 prev.loc.source += node.loc.source;1028 return;1029 }1030 }1031 nodes.push(node);1032}1033function parseCDATA(context, ancestors) {1034 advanceBy(context, 9);1035 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1036 if (context.source.length === 0) {1037 emitError(context, 6 /* EOF_IN_CDATA */);1038 }1039 else {1040 advanceBy(context, 3);1041 }1042 return nodes;1043}1044function parseComment(context) {1045 const start = getCursor(context);1046 let content;1047 // Regular comment.1048 const match = /--(\!)?>/.exec(context.source);1049 if (!match) {1050 content = context.source.slice(4);1051 advanceBy(context, context.source.length);1052 emitError(context, 7 /* EOF_IN_COMMENT */);1053 }1054 else {1055 if (match.index <= 3) {1056 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1057 }1058 if (match[1]) {1059 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1060 }1061 content = context.source.slice(4, match.index);1062 // Advancing with reporting nested comments.1063 const s = context.source.slice(0, match.index);1064 let prevIndex = 1, nestedIndex = 0;1065 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1066 advanceBy(context, nestedIndex - prevIndex + 1);1067 if (nestedIndex + 4 < s.length) {1068 emitError(context, 16 /* NESTED_COMMENT */);1069 }1070 prevIndex = nestedIndex + 1;1071 }1072 advanceBy(context, match.index + match[0].length - prevIndex + 1);1073 }1074 return {1075 type: 3 /* COMMENT */,1076 content,1077 loc: getSelection(context, start)1078 };1079}1080function parseBogusComment(context) {1081 const start = getCursor(context);1082 const contentStart = context.source[1] === '?' ? 1 : 2;1083 let content;1084 const closeIndex = context.source.indexOf('>');1085 if (closeIndex === -1) {1086 content = context.source.slice(contentStart);1087 advanceBy(context, context.source.length);1088 }1089 else {1090 content = context.source.slice(contentStart, closeIndex);1091 advanceBy(context, closeIndex + 1);1092 }1093 return {1094 type: 3 /* COMMENT */,1095 content,1096 loc: getSelection(context, start)1097 };1098}1099function parseElement(context, ancestors) {1100 // Start tag.1101 const wasInPre = context.inPre;1102 const wasInVPre = context.inVPre;1103 const parent = last(ancestors);1104 const element = parseTag(context, 0 /* Start */, parent);1105 const isPreBoundary = context.inPre && !wasInPre;1106 const isVPreBoundary = context.inVPre && !wasInVPre;1107 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1108 // #4030 self-closing <pre> tag1109 if (context.options.isPreTag(element.tag)) {1110 context.inPre = false;1111 }1112 return element;1113 }1114 // Children.1115 ancestors.push(element);1116 const mode = context.options.getTextMode(element, parent);1117 const children = parseChildren(context, mode, ancestors);1118 ancestors.pop();1119 // 2.x inline-template compat1120 {1121 const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1122 if (inlineTemplateProp &&1123 checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1124 const loc = getSelection(context, element.loc.end);1125 inlineTemplateProp.value = {1126 type: 2 /* TEXT */,1127 content: loc.source,1128 loc1129 };1130 }1131 }1132 element.children = children;1133 // End tag.1134 if (startsWithEndTagOpen(context.source, element.tag)) {1135 parseTag(context, 1 /* End */, parent);1136 }1137 else {1138 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1139 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1140 const first = children[0];1141 if (first && startsWith(first.loc.source, '<!--')) {1142 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1143 }1144 }1145 }1146 element.loc = getSelection(context, element.loc.start);1147 if (isPreBoundary) {1148 context.inPre = false;1149 }1150 if (isVPreBoundary) {1151 context.inVPre = false;1152 }1153 return element;1154}1155const isSpecialTemplateDirective = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.makeMap)(`if,else,else-if,for,slot`);1156function parseTag(context, type, parent) {1157 // Tag open.1158 const start = getCursor(context);1159 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1160 const tag = match[1];1161 const ns = context.options.getNamespace(tag, parent);1162 advanceBy(context, match[0].length);1163 advanceSpaces(context);1164 // save current state in case we need to re-parse attributes with v-pre1165 const cursor = getCursor(context);1166 const currentSource = context.source;1167 // check <pre> tag1168 const isPreTag = context.options.isPreTag(tag);1169 if (isPreTag) {1170 context.inPre = true;1171 }1172 // Attributes.1173 let props = parseAttributes(context, type);1174 // check v-pre1175 if (type === 0 /* Start */ &&1176 !context.inVPre &&1177 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1178 context.inVPre = true;1179 // reset context1180 (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)(context, cursor);1181 context.source = currentSource;1182 // re-parse attrs and filter out v-pre itself1183 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1184 }1185 // Tag close.1186 let isSelfClosing = false;1187 if (context.source.length === 0) {1188 emitError(context, 9 /* EOF_IN_TAG */);1189 }1190 else {1191 isSelfClosing = startsWith(context.source, '/>');1192 if (type === 1 /* End */ && isSelfClosing) {1193 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1194 }1195 advanceBy(context, isSelfClosing ? 2 : 1);1196 }1197 if (type === 1 /* End */) {1198 return;1199 }1200 // 2.x deprecation checks1201 if (( true) &&1202 isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1203 let hasIf = false;1204 let hasFor = false;1205 for (let i = 0; i < props.length; i++) {1206 const p = props[i];1207 if (p.type === 7 /* DIRECTIVE */) {1208 if (p.name === 'if') {1209 hasIf = true;1210 }1211 else if (p.name === 'for') {1212 hasFor = true;1213 }1214 }1215 if (hasIf && hasFor) {1216 warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1217 }1218 }1219 }1220 let tagType = 0 /* ELEMENT */;1221 if (!context.inVPre) {1222 if (tag === 'slot') {1223 tagType = 2 /* SLOT */;1224 }1225 else if (tag === 'template') {1226 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1227 tagType = 3 /* TEMPLATE */;1228 }1229 }1230 else if (isComponent(tag, props, context)) {1231 tagType = 1 /* COMPONENT */;1232 }1233 }1234 return {1235 type: 1 /* ELEMENT */,1236 ns,1237 tag,1238 tagType,1239 props,1240 isSelfClosing,1241 children: [],1242 loc: getSelection(context, start),1243 codegenNode: undefined // to be created during transform phase1244 };1245}1246function isComponent(tag, props, context) {1247 const options = context.options;1248 if (options.isCustomElement(tag)) {1249 return false;1250 }1251 if (tag === 'component' ||1252 /^[A-Z]/.test(tag) ||1253 isCoreComponent(tag) ||1254 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1255 (options.isNativeTag && !options.isNativeTag(tag))) {1256 return true;1257 }1258 // at this point the tag should be a native tag, but check for potential "is"1259 // casting1260 for (let i = 0; i < props.length; i++) {1261 const p = props[i];1262 if (p.type === 6 /* ATTRIBUTE */) {1263 if (p.name === 'is' && p.value) {1264 if (p.value.content.startsWith('vue:')) {1265 return true;1266 }1267 else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1268 return true;1269 }1270 }1271 }1272 else {1273 // directive1274 // v-is (TODO Deprecate)1275 if (p.name === 'is') {1276 return true;1277 }1278 else if (1279 // :is on plain element - only treat as component in compat mode1280 p.name === 'bind' &&1281 isBindKey(p.arg, 'is') &&1282 true &&1283 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1284 return true;1285 }1286 }1287 }1288}1289function parseAttributes(context, type) {1290 const props = [];1291 const attributeNames = new Set();1292 while (context.source.length > 0 &&1293 !startsWith(context.source, '>') &&1294 !startsWith(context.source, '/>')) {1295 if (startsWith(context.source, '/')) {1296 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1297 advanceBy(context, 1);1298 advanceSpaces(context);1299 continue;1300 }1301 if (type === 1 /* End */) {1302 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1303 }1304 const attr = parseAttribute(context, attributeNames);1305 if (type === 0 /* Start */) {1306 props.push(attr);1307 }1308 if (/^[^\t\r\n\f />]/.test(context.source)) {1309 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1310 }1311 advanceSpaces(context);1312 }1313 return props;1314}1315function parseAttribute(context, nameSet) {1316 // Name.1317 const start = getCursor(context);1318 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1319 const name = match[0];1320 if (nameSet.has(name)) {1321 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1322 }1323 nameSet.add(name);1324 if (name[0] === '=') {1325 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1326 }1327 {1328 const pattern = /["'<]/g;1329 let m;1330 while ((m = pattern.exec(name))) {1331 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1332 }1333 }1334 advanceBy(context, name.length);1335 // Value1336 let value = undefined;1337 if (/^[\t\r\n\f ]*=/.test(context.source)) {1338 advanceSpaces(context);1339 advanceBy(context, 1);1340 advanceSpaces(context);1341 value = parseAttributeValue(context);1342 if (!value) {1343 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1344 }1345 }1346 const loc = getSelection(context, start);1347 if (!context.inVPre && /^(v-|:|@|#)/.test(name)) {1348 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1349 let dirName = match[1] ||1350 (startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot');1351 let arg;1352 if (match[2]) {1353 const isSlot = dirName === 'slot';1354 const startOffset = name.lastIndexOf(match[2]);1355 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1356 let content = match[2];1357 let isStatic = true;1358 if (content.startsWith('[')) {1359 isStatic = false;1360 if (!content.endsWith(']')) {1361 emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1362 }1363 content = content.substr(1, content.length - 2);1364 }1365 else if (isSlot) {1366 // #1241 special case for v-slot: vuetify relies extensively on slot1367 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1368 // supports such usage so we are keeping it consistent with 2.x.1369 content += match[3] || '';1370 }1371 arg = {1372 type: 4 /* SIMPLE_EXPRESSION */,1373 content,1374 isStatic,1375 constType: isStatic1376 ? 3 /* CAN_STRINGIFY */1377 : 0 /* NOT_CONSTANT */,1378 loc1379 };1380 }1381 if (value && value.isQuoted) {1382 const valueLoc = value.loc;1383 valueLoc.start.offset++;1384 valueLoc.start.column++;1385 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1386 valueLoc.source = valueLoc.source.slice(1, -1);1387 }1388 const modifiers = match[3] ? match[3].substr(1).split('.') : [];1389 // 2.x compat v-bind:foo.sync -> v-model:foo1390 if (dirName === 'bind' && arg) {1391 if (modifiers.includes('sync') &&1392 checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1393 dirName = 'model';1394 modifiers.splice(modifiers.indexOf('sync'), 1);1395 }1396 if (( true) && modifiers.includes('prop')) {1397 checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1398 }1399 }1400 return {1401 type: 7 /* DIRECTIVE */,1402 name: dirName,1403 exp: value && {1404 type: 4 /* SIMPLE_EXPRESSION */,1405 content: value.content,1406 isStatic: false,1407 // Treat as non-constant by default. This can be potentially set to1408 // other values by `transformExpression` to make it eligible for hoisting.1409 constType: 0 /* NOT_CONSTANT */,1410 loc: value.loc1411 },1412 arg,1413 modifiers,1414 loc1415 };1416 }1417 return {1418 type: 6 /* ATTRIBUTE */,1419 name,1420 value: value && {1421 type: 2 /* TEXT */,1422 content: value.content,1423 loc: value.loc1424 },1425 loc1426 };1427}1428function parseAttributeValue(context) {1429 const start = getCursor(context);1430 let content;1431 const quote = context.source[0];1432 const isQuoted = quote === `"` || quote === `'`;1433 if (isQuoted) {1434 // Quoted value.1435 advanceBy(context, 1);1436 const endIndex = context.source.indexOf(quote);1437 if (endIndex === -1) {1438 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1439 }1440 else {1441 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1442 advanceBy(context, 1);1443 }1444 }1445 else {1446 // Unquoted1447 const match = /^[^\t\r\n\f >]+/.exec(context.source);1448 if (!match) {1449 return undefined;1450 }1451 const unexpectedChars = /["'<=`]/g;1452 let m;1453 while ((m = unexpectedChars.exec(match[0]))) {1454 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1455 }1456 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1457 }1458 return { content, isQuoted, loc: getSelection(context, start) };1459}1460function parseInterpolation(context, mode) {1461 const [open, close] = context.options.delimiters;1462 const closeIndex = context.source.indexOf(close, open.length);1463 if (closeIndex === -1) {1464 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1465 return undefined;1466 }1467 const start = getCursor(context);1468 advanceBy(context, open.length);1469 const innerStart = getCursor(context);1470 const innerEnd = getCursor(context);1471 const rawContentLength = closeIndex - open.length;1472 const rawContent = context.source.slice(0, rawContentLength);1473 const preTrimContent = parseTextData(context, rawContentLength, mode);1474 const content = preTrimContent.trim();1475 const startOffset = preTrimContent.indexOf(content);1476 if (startOffset > 0) {1477 advancePositionWithMutation(innerStart, rawContent, startOffset);1478 }1479 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1480 advancePositionWithMutation(innerEnd, rawContent, endOffset);1481 advanceBy(context, close.length);1482 return {1483 type: 5 /* INTERPOLATION */,1484 content: {1485 type: 4 /* SIMPLE_EXPRESSION */,1486 isStatic: false,1487 // Set `isConstant` to false by default and will decide in transformExpression1488 constType: 0 /* NOT_CONSTANT */,1489 content,1490 loc: getSelection(context, innerStart, innerEnd)1491 },1492 loc: getSelection(context, start)1493 };1494}1495function parseText(context, mode) {1496 const endTokens = ['<', context.options.delimiters[0]];1497 if (mode === 3 /* CDATA */) {1498 endTokens.push(']]>');1499 }1500 let endIndex = context.source.length;1501 for (let i = 0; i < endTokens.length; i++) {1502 const index = context.source.indexOf(endTokens[i], 1);1503 if (index !== -1 && endIndex > index) {1504 endIndex = index;1505 }1506 }1507 const start = getCursor(context);1508 const content = parseTextData(context, endIndex, mode);1509 return {1510 type: 2 /* TEXT */,1511 content,1512 loc: getSelection(context, start)1513 };1514}1515/**1516 * Get text data with a given length from the current location.1517 * This translates HTML entities in the text data.1518 */1519function parseTextData(context, length, mode) {1520 const rawText = context.source.slice(0, length);1521 advanceBy(context, length);1522 if (mode === 2 /* RAWTEXT */ ||1523 mode === 3 /* CDATA */ ||1524 rawText.indexOf('&') === -1) {1525 return rawText;1526 }1527 else {1528 // DATA or RCDATA containing "&"". Entity decoding required.1529 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1530 }1531}1532function getCursor(context) {1533 const { column, line, offset } = context;1534 return { column, line, offset };1535}1536function getSelection(context, start, end) {1537 end = end || getCursor(context);1538 return {1539 start,1540 end,1541 source: context.originalSource.slice(start.offset, end.offset)1542 };1543}1544function last(xs) {1545 return xs[xs.length - 1];1546}1547function startsWith(source, searchString) {1548 return source.startsWith(searchString);1549}1550function advanceBy(context, numberOfCharacters) {1551 const { source } = context;1552 advancePositionWithMutation(context, source, numberOfCharacters);1553 context.source = source.slice(numberOfCharacters);1554}1555function advanceSpaces(context) {1556 const match = /^[\t\r\n\f ]+/.exec(context.source);1557 if (match) {1558 advanceBy(context, match[0].length);1559 }1560}1561function getNewPosition(context, start, numberOfCharacters) {1562 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1563}1564function emitError(context, code, offset, loc = getCursor(context)) {1565 if (offset) {1566 loc.offset += offset;1567 loc.column += offset;1568 }1569 context.options.onError(createCompilerError(code, {1570 start: loc,1571 end: loc,1572 source: ''1573 }));1574}1575function isEnd(context, mode, ancestors) {1576 const s = context.source;1577 switch (mode) {1578 case 0 /* DATA */:1579 if (startsWith(s, '</')) {1580 // TODO: probably bad performance1581 for (let i = ancestors.length - 1; i >= 0; --i) {1582 if (startsWithEndTagOpen(s, ancestors[i].tag)) {1583 return true;1584 }1585 }1586 }1587 break;1588 case 1 /* RCDATA */:1589 case 2 /* RAWTEXT */: {1590 const parent = last(ancestors);1591 if (parent && startsWithEndTagOpen(s, parent.tag)) {1592 return true;1593 }1594 break;1595 }1596 case 3 /* CDATA */:1597 if (startsWith(s, ']]>')) {1598 return true;1599 }1600 break;1601 }1602 return !s;1603}1604function startsWithEndTagOpen(source, tag) {1605 return (startsWith(source, '</') &&1606 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&1607 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1608}1609function hoistStatic(root, context) {1610 walk(root, context, 1611 // Root node is unfortunately non-hoistable due to potential parent1612 // fallthrough attributes.1613 isSingleElementRoot(root, root.children[0]));1614}1615function isSingleElementRoot(root, child) {1616 const { children } = root;1617 return (children.length === 1 &&1618 child.type === 1 /* ELEMENT */ &&1619 !isSlotOutlet(child));1620}1621function walk(node, context, doNotHoistNode = false) {1622 let hasHoistedNode = false;1623 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces1624 // static bindings with expressions. These expressions are guaranteed to be1625 // constant so they are still eligible for hoisting, but they are only1626 // available at runtime and therefore cannot be evaluated ahead of time.1627 // This is only a concern for pre-stringification (via transformHoist by1628 // @vue/compiler-dom), but doing it here allows us to perform only one full1629 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its1630 // stringficiation threshold is met.1631 let canStringify = true;1632 const { children } = node;1633 for (let i = 0; i < children.length; i++) {1634 const child = children[i];1635 // only plain elements & text calls are eligible for hoisting.1636 if (child.type === 1 /* ELEMENT */ &&1637 child.tagType === 0 /* ELEMENT */) {1638 const constantType = doNotHoistNode1639 ? 0 /* NOT_CONSTANT */1640 : getConstantType(child, context);1641 if (constantType > 0 /* NOT_CONSTANT */) {1642 if (constantType < 3 /* CAN_STRINGIFY */) {1643 canStringify = false;1644 }1645 if (constantType >= 2 /* CAN_HOIST */) {1646 child.codegenNode.patchFlag =1647 -1 /* HOISTED */ + (( true) ? ` /* HOISTED */` : 0);1648 child.codegenNode = context.hoist(child.codegenNode);1649 hasHoistedNode = true;1650 continue;1651 }1652 }1653 else {1654 // node may contain dynamic children, but its props may be eligible for1655 // hoisting.1656 const codegenNode = child.codegenNode;1657 if (codegenNode.type === 13 /* VNODE_CALL */) {1658 const flag = getPatchFlag(codegenNode);1659 if ((!flag ||1660 flag === 512 /* NEED_PATCH */ ||1661 flag === 1 /* TEXT */) &&1662 getGeneratedPropsConstantType(child, context) >=1663 2 /* CAN_HOIST */) {1664 const props = getNodeProps(child);1665 if (props) {1666 codegenNode.props = context.hoist(props);1667 }1668 }1669 }1670 }1671 }1672 else if (child.type === 12 /* TEXT_CALL */) {1673 const contentType = getConstantType(child.content, context);1674 if (contentType > 0) {1675 if (contentType < 3 /* CAN_STRINGIFY */) {1676 canStringify = false;1677 }1678 if (contentType >= 2 /* CAN_HOIST */) {1679 child.codegenNode = context.hoist(child.codegenNode);1680 hasHoistedNode = true;1681 }1682 }1683 }1684 // walk further1685 if (child.type === 1 /* ELEMENT */) {1686 const isComponent = child.tagType === 1 /* COMPONENT */;1687 if (isComponent) {1688 context.scopes.vSlot++;1689 }1690 walk(child, context);1691 if (isComponent) {1692 context.scopes.vSlot--;1693 }1694 }1695 else if (child.type === 11 /* FOR */) {1696 // Do not hoist v-for single child because it has to be a block1697 walk(child, context, child.children.length === 1);1698 }1699 else if (child.type === 9 /* IF */) {1700 for (let i = 0; i < child.branches.length; i++) {1701 // Do not hoist v-if single child because it has to be a block1702 walk(child.branches[i], context, child.branches[i].children.length === 1);1703 }1704 }1705 }1706 if (canStringify && hasHoistedNode && context.transformHoist) {1707 context.transformHoist(children, context, node);1708 }1709}1710function getConstantType(node, context) {1711 const { constantCache } = context;1712 switch (node.type) {1713 case 1 /* ELEMENT */:1714 if (node.tagType !== 0 /* ELEMENT */) {1715 return 0 /* NOT_CONSTANT */;1716 }1717 const cached = constantCache.get(node);1718 if (cached !== undefined) {1719 return cached;1720 }1721 const codegenNode = node.codegenNode;1722 if (codegenNode.type !== 13 /* VNODE_CALL */) {1723 return 0 /* NOT_CONSTANT */;1724 }1725 const flag = getPatchFlag(codegenNode);1726 if (!flag) {1727 let returnType = 3 /* CAN_STRINGIFY */;1728 // Element itself has no patch flag. However we still need to check:1729 // 1. Even for a node with no patch flag, it is possible for it to contain1730 // non-hoistable expressions that refers to scope variables, e.g. compiler1731 // injected keys or cached event handlers. Therefore we need to always1732 // check the codegenNode's props to be sure.1733 const generatedPropsType = getGeneratedPropsConstantType(node, context);1734 if (generatedPropsType === 0 /* NOT_CONSTANT */) {1735 constantCache.set(node, 0 /* NOT_CONSTANT */);1736 return 0 /* NOT_CONSTANT */;1737 }1738 if (generatedPropsType < returnType) {1739 returnType = generatedPropsType;1740 }1741 // 2. its children.1742 for (let i = 0; i < node.children.length; i++) {1743 const childType = getConstantType(node.children[i], context);1744 if (childType === 0 /* NOT_CONSTANT */) {1745 constantCache.set(node, 0 /* NOT_CONSTANT */);1746 return 0 /* NOT_CONSTANT */;1747 }1748 if (childType < returnType) {1749 returnType = childType;1750 }1751 }1752 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01753 // type, check if any of the props can cause the type to be lowered1754 // we can skip can_patch because it's guaranteed by the absence of a1755 // patchFlag.1756 if (returnType > 1 /* CAN_SKIP_PATCH */) {1757 for (let i = 0; i < node.props.length; i++) {1758 const p = node.props[i];1759 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1760 const expType = getConstantType(p.exp, context);1761 if (expType === 0 /* NOT_CONSTANT */) {1762 constantCache.set(node, 0 /* NOT_CONSTANT */);1763 return 0 /* NOT_CONSTANT */;1764 }1765 if (expType < returnType) {1766 returnType = expType;1767 }1768 }1769 }1770 }1771 // only svg/foreignObject could be block here, however if they are1772 // static then they don't need to be blocks since there will be no1773 // nested updates.1774 if (codegenNode.isBlock) {1775 context.removeHelper(OPEN_BLOCK);1776 context.removeHelper(CREATE_BLOCK);1777 codegenNode.isBlock = false;1778 context.helper(CREATE_VNODE);1779 }1780 constantCache.set(node, returnType);1781 return returnType;1782 }1783 else {1784 constantCache.set(node, 0 /* NOT_CONSTANT */);1785 return 0 /* NOT_CONSTANT */;1786 }1787 case 2 /* TEXT */:1788 case 3 /* COMMENT */:1789 return 3 /* CAN_STRINGIFY */;1790 case 9 /* IF */:1791 case 11 /* FOR */:1792 case 10 /* IF_BRANCH */:1793 return 0 /* NOT_CONSTANT */;1794 case 5 /* INTERPOLATION */:1795 case 12 /* TEXT_CALL */:1796 return getConstantType(node.content, context);1797 case 4 /* SIMPLE_EXPRESSION */:1798 return node.constType;1799 case 8 /* COMPOUND_EXPRESSION */:1800 let returnType = 3 /* CAN_STRINGIFY */;1801 for (let i = 0; i < node.children.length; i++) {1802 const child = node.children[i];1803 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(child)) {1804 continue;1805 }1806 const childType = getConstantType(child, context);1807 if (childType === 0 /* NOT_CONSTANT */) {1808 return 0 /* NOT_CONSTANT */;1809 }1810 else if (childType < returnType) {1811 returnType = childType;1812 }1813 }1814 return returnType;1815 default:1816 if ((true)) ;1817 return 0 /* NOT_CONSTANT */;1818 }1819}1820function getGeneratedPropsConstantType(node, context) {1821 let returnType = 3 /* CAN_STRINGIFY */;1822 const props = getNodeProps(node);1823 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {1824 const { properties } = props;1825 for (let i = 0; i < properties.length; i++) {1826 const { key, value } = properties[i];1827 const keyType = getConstantType(key, context);1828 if (keyType === 0 /* NOT_CONSTANT */) {1829 return keyType;1830 }1831 if (keyType < returnType) {1832 returnType = keyType;1833 }1834 if (value.type !== 4 /* SIMPLE_EXPRESSION */) {1835 return 0 /* NOT_CONSTANT */;1836 }1837 const valueType = getConstantType(value, context);1838 if (valueType === 0 /* NOT_CONSTANT */) {1839 return valueType;1840 }1841 if (valueType < returnType) {1842 returnType = valueType;1843 }1844 }1845 }1846 return returnType;1847}1848function getNodeProps(node) {1849 const codegenNode = node.codegenNode;1850 if (codegenNode.type === 13 /* VNODE_CALL */) {1851 return codegenNode.props;1852 }1853}1854function getPatchFlag(node) {1855 const flag = node.patchFlag;1856 return flag ? parseInt(flag, 10) : undefined;1857}1858function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NOOP, isCustomElement = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, ssrCssVars = ``, bindingMetadata = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {1859 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);1860 const context = {1861 // options1862 selfName: nameMatch && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.capitalize)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.camelize)(nameMatch[1])),1863 prefixIdentifiers,1864 hoistStatic,1865 cacheHandlers,1866 nodeTransforms,1867 directiveTransforms,1868 transformHoist,1869 isBuiltInComponent,1870 isCustomElement,1871 expressionPlugins,1872 scopeId,1873 slotted,1874 ssr,1875 ssrCssVars,1876 bindingMetadata,1877 inline,1878 isTS,1879 onError,1880 onWarn,1881 compatConfig,1882 // state1883 root,1884 helpers: new Map(),1885 components: new Set(),1886 directives: new Set(),1887 hoists: [],1888 imports: [],1889 constantCache: new Map(),1890 temps: 0,1891 cached: 0,1892 identifiers: Object.create(null),1893 scopes: {1894 vFor: 0,1895 vSlot: 0,1896 vPre: 0,1897 vOnce: 01898 },1899 parent: null,1900 currentNode: root,1901 childIndex: 0,1902 // methods1903 helper(name) {1904 const count = context.helpers.get(name) || 0;1905 context.helpers.set(name, count + 1);1906 return name;1907 },1908 removeHelper(name) {1909 const count = context.helpers.get(name);1910 if (count) {1911 const currentCount = count - 1;1912 if (!currentCount) {1913 context.helpers.delete(name);1914 }1915 else {1916 context.helpers.set(name, currentCount);1917 }1918 }1919 },1920 helperString(name) {1921 return `_${helperNameMap[context.helper(name)]}`;1922 },1923 replaceNode(node) {1924 /* istanbul ignore if */1925 if ((true)) {1926 if (!context.currentNode) {1927 throw new Error(`Node being replaced is already removed.`);1928 }1929 if (!context.parent) {1930 throw new Error(`Cannot replace root node.`);1931 }1932 }1933 context.parent.children[context.childIndex] = context.currentNode = node;1934 },1935 removeNode(node) {1936 if (( true) && !context.parent) {1937 throw new Error(`Cannot remove root node.`);1938 }1939 const list = context.parent.children;1940 const removalIndex = node1941 ? list.indexOf(node)1942 : context.currentNode1943 ? context.childIndex1944 : -1;1945 /* istanbul ignore if */1946 if (( true) && removalIndex < 0) {1947 throw new Error(`node being removed is not a child of current parent`);1948 }1949 if (!node || node === context.currentNode) {1950 // current node removed1951 context.currentNode = null;1952 context.onNodeRemoved();1953 }1954 else {1955 // sibling node removed1956 if (context.childIndex > removalIndex) {1957 context.childIndex--;1958 context.onNodeRemoved();1959 }1960 }1961 context.parent.children.splice(removalIndex, 1);1962 },1963 onNodeRemoved: () => { },1964 addIdentifiers(exp) {1965 },1966 removeIdentifiers(exp) {1967 },1968 hoist(exp) {1969 context.hoists.push(exp);1970 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);1971 identifier.hoisted = exp;1972 return identifier;1973 },1974 cache(exp, isVNode = false) {1975 return createCacheExpression(++context.cached, exp, isVNode);1976 }1977 };1978 {1979 context.filters = new Set();1980 }1981 return context;1982}1983function transform(root, options) {1984 const context = createTransformContext(root, options);1985 traverseNode(root, context);1986 if (options.hoistStatic) {1987 hoistStatic(root, context);1988 }1989 if (!options.ssr) {1990 createRootCodegen(root, context);1991 }1992 // finalize meta information1993 root.helpers = [...context.helpers.keys()];1994 root.components = [...context.components];1995 root.directives = [...context.directives];1996 root.imports = context.imports;1997 root.hoists = context.hoists;1998 root.temps = context.temps;1999 root.cached = context.cached;2000 {2001 root.filters = [...context.filters];2002 }2003}2004function createRootCodegen(root, context) {2005 const { helper, removeHelper } = context;2006 const { children } = root;2007 if (children.length === 1) {2008 const child = children[0];2009 // if the single child is an element, turn it into a block.2010 if (isSingleElementRoot(root, child) && child.codegenNode) {2011 // single element root is never hoisted so codegenNode will never be2012 // SimpleExpressionNode2013 const codegenNode = child.codegenNode;2014 if (codegenNode.type === 13 /* VNODE_CALL */) {2015 if (!codegenNode.isBlock) {2016 removeHelper(CREATE_VNODE);2017 codegenNode.isBlock = true;2018 helper(OPEN_BLOCK);2019 helper(CREATE_BLOCK);2020 }2021 }2022 root.codegenNode = codegenNode;2023 }2024 else {2025 // - single <slot/>, IfNode, ForNode: already blocks.2026 // - single text node: always patched.2027 // root codegen falls through via genNode()2028 root.codegenNode = child;2029 }2030 }2031 else if (children.length > 1) {2032 // root has multiple nodes - return a fragment block.2033 let patchFlag = 64 /* STABLE_FRAGMENT */;2034 let patchFlagText = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64];2035 // check if the fragment actually contains a single valid child with2036 // the rest being comments2037 if (( true) &&2038 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2039 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2040 patchFlagText += `, ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[2048]}`;2041 }2042 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (( true) ? ` /* ${patchFlagText} */` : 0), undefined, undefined, true);2043 }2044 else ;2045}2046function traverseChildren(parent, context) {2047 let i = 0;2048 const nodeRemoved = () => {2049 i--;2050 };2051 for (; i < parent.children.length; i++) {2052 const child = parent.children[i];2053 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child))2054 continue;2055 context.parent = parent;2056 context.childIndex = i;2057 context.onNodeRemoved = nodeRemoved;2058 traverseNode(child, context);2059 }2060}2061function traverseNode(node, context) {2062 context.currentNode = node;2063 // apply transform plugins2064 const { nodeTransforms } = context;2065 const exitFns = [];2066 for (let i = 0; i < nodeTransforms.length; i++) {2067 const onExit = nodeTransforms[i](node, context);2068 if (onExit) {2069 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(onExit)) {2070 exitFns.push(...onExit);2071 }2072 else {2073 exitFns.push(onExit);2074 }2075 }2076 if (!context.currentNode) {2077 // node was removed2078 return;2079 }2080 else {2081 // node may have been replaced2082 node = context.currentNode;2083 }2084 }2085 switch (node.type) {2086 case 3 /* COMMENT */:2087 if (!context.ssr) {2088 // inject import for the Comment symbol, which is needed for creating2089 // comment nodes with `createVNode`2090 context.helper(CREATE_COMMENT);2091 }2092 break;2093 case 5 /* INTERPOLATION */:2094 // no need to traverse, but we need to inject toString helper2095 if (!context.ssr) {2096 context.helper(TO_DISPLAY_STRING);2097 }2098 break;2099 // for container types, further traverse downwards2100 case 9 /* IF */:2101 for (let i = 0; i < node.branches.length; i++) {2102 traverseNode(node.branches[i], context);2103 }2104 break;2105 case 10 /* IF_BRANCH */:2106 case 11 /* FOR */:2107 case 1 /* ELEMENT */:2108 case 0 /* ROOT */:2109 traverseChildren(node, context);2110 break;2111 }2112 // exit transforms2113 context.currentNode = node;2114 let i = exitFns.length;2115 while (i--) {2116 exitFns[i]();2117 }2118}2119function createStructuralDirectiveTransform(name, fn) {2120 const matches = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(name)2121 ? (n) => n === name2122 : (n) => name.test(n);2123 return (node, context) => {2124 if (node.type === 1 /* ELEMENT */) {2125 const { props } = node;2126 // structural directive transforms are not concerned with slots2127 // as they are handled separately in vSlot.ts2128 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2129 return;2130 }2131 const exitFns = [];2132 for (let i = 0; i < props.length; i++) {2133 const prop = props[i];2134 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2135 // structural directives are removed to avoid infinite recursion2136 // also we remove them *before* applying so that it can further2137 // traverse itself in case it moves the node around2138 props.splice(i, 1);2139 i--;2140 const onExit = fn(node, prop, context);2141 if (onExit)2142 exitFns.push(onExit);2143 }2144 }2145 return exitFns;2146 }2147 };2148}2149const PURE_ANNOTATION = `/*#__PURE__*/`;2150function 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 }) {2151 const context = {2152 mode,2153 prefixIdentifiers,2154 sourceMap,2155 filename,2156 scopeId,2157 optimizeImports,2158 runtimeGlobalName,2159 runtimeModuleName,2160 ssr,2161 isTS,2162 source: ast.loc.source,2163 code: ``,2164 column: 1,2165 line: 1,2166 offset: 0,2167 indentLevel: 0,2168 pure: false,2169 map: undefined,2170 helper(key) {2171 return `_${helperNameMap[key]}`;2172 },2173 push(code, node) {2174 context.code += code;2175 },2176 indent() {2177 newline(++context.indentLevel);2178 },2179 deindent(withoutNewLine = false) {2180 if (withoutNewLine) {2181 --context.indentLevel;2182 }2183 else {2184 newline(--context.indentLevel);2185 }2186 },2187 newline() {2188 newline(context.indentLevel);2189 }2190 };2191 function newline(n) {2192 context.push('\n' + ` `.repeat(n));2193 }2194 return context;2195}2196function generate(ast, options = {}) {2197 const context = createCodegenContext(ast, options);2198 if (options.onContextCreated)2199 options.onContextCreated(context);2200 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2201 const hasHelpers = ast.helpers.length > 0;2202 const useWithBlock = !prefixIdentifiers && mode !== 'module';2203 // preambles2204 // in setup() inline mode, the preamble is generated in a sub context2205 // and returned separately.2206 const preambleContext = context;2207 {2208 genFunctionPreamble(ast, preambleContext);2209 }2210 // enter render function2211 const functionName = ssr ? `ssrRender` : `render`;2212 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2213 const signature = args.join(', ');2214 {2215 push(`function ${functionName}(${signature}) {`);2216 }2217 indent();2218 if (useWithBlock) {2219 push(`with (_ctx) {`);2220 indent();2221 // function mode const declarations should be inside with block2222 // also they should be renamed to avoid collision with user properties2223 if (hasHelpers) {2224 push(`const { ${ast.helpers2225 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2226 .join(', ')} } = _Vue`);2227 push(`\n`);2228 newline();2229 }2230 }2231 // generate asset resolution statements2232 if (ast.components.length) {2233 genAssets(ast.components, 'component', context);2234 if (ast.directives.length || ast.temps > 0) {2235 newline();2236 }2237 }2238 if (ast.directives.length) {2239 genAssets(ast.directives, 'directive', context);2240 if (ast.temps > 0) {2241 newline();2242 }2243 }2244 if (ast.filters && ast.filters.length) {2245 newline();2246 genAssets(ast.filters, 'filter', context);2247 newline();2248 }2249 if (ast.temps > 0) {2250 push(`let `);2251 for (let i = 0; i < ast.temps; i++) {2252 push(`${i > 0 ? `, ` : ``}_temp${i}`);2253 }2254 }2255 if (ast.components.length || ast.directives.length || ast.temps) {2256 push(`\n`);2257 newline();2258 }2259 // generate the VNode tree expression2260 if (!ssr) {2261 push(`return `);2262 }2263 if (ast.codegenNode) {2264 genNode(ast.codegenNode, context);2265 }2266 else {2267 push(`null`);2268 }2269 if (useWithBlock) {2270 deindent();2271 push(`}`);2272 }2273 deindent();2274 push(`}`);2275 return {2276 ast,2277 code: context.code,2278 preamble: ``,2279 // SourceMapGenerator does have toJSON() method but it's not in the types2280 map: context.map ? context.map.toJSON() : undefined2281 };2282}2283function genFunctionPreamble(ast, context) {2284 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName } = context;2285 const VueBinding = runtimeGlobalName;2286 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2287 // Generate const declaration for helpers2288 // In prefix mode, we place the const declaration at top so it's done2289 // only once; But if we not prefixing, we place the declaration inside the2290 // with block so it doesn't incur the `in` check cost for every helper access.2291 if (ast.helpers.length > 0) {2292 {2293 // "with" mode.2294 // save Vue in a separate variable to avoid collision2295 push(`const _Vue = ${VueBinding}\n`);2296 // in "with" mode, helpers are declared inside the with block to avoid2297 // has check cost, but hoists are lifted out of the function - we need2298 // to provide the helper here.2299 if (ast.hoists.length) {2300 const staticHelpers = [2301 CREATE_VNODE,2302 CREATE_COMMENT,2303 CREATE_TEXT,2304 CREATE_STATIC2305 ]2306 .filter(helper => ast.helpers.includes(helper))2307 .map(aliasHelper)2308 .join(', ');2309 push(`const { ${staticHelpers} } = _Vue\n`);2310 }2311 }2312 }2313 genHoists(ast.hoists, context);2314 newline();2315 push(`return `);2316}2317function genAssets(assets, type, { helper, push, newline, isTS }) {2318 const resolver = helper(type === 'filter'2319 ? RESOLVE_FILTER2320 : type === 'component'2321 ? RESOLVE_COMPONENT2322 : RESOLVE_DIRECTIVE);2323 for (let i = 0; i < assets.length; i++) {2324 let id = assets[i];2325 // potential component implicit self-reference inferred from SFC filename2326 const maybeSelfReference = id.endsWith('__self');2327 if (maybeSelfReference) {2328 id = id.slice(0, -6);2329 }2330 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2331 if (i < assets.length - 1) {2332 newline();2333 }2334 }2335}2336function genHoists(hoists, context) {2337 if (!hoists.length) {2338 return;2339 }2340 context.pure = true;2341 const { push, newline, helper, scopeId, mode } = context;2342 newline();2343 hoists.forEach((exp, i) => {2344 if (exp) {2345 push(`const _hoisted_${i + 1} = `);2346 genNode(exp, context);2347 newline();2348 }2349 });2350 context.pure = false;2351}2352function isText$1(n) {2353 return ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(n) ||2354 n.type === 4 /* SIMPLE_EXPRESSION */ ||2355 n.type === 2 /* TEXT */ ||2356 n.type === 5 /* INTERPOLATION */ ||2357 n.type === 8 /* COMPOUND_EXPRESSION */);2358}2359function genNodeListAsArray(nodes, context) {2360 const multilines = nodes.length > 3 ||2361 ((( true)) && nodes.some(n => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(n) || !isText$1(n)));2362 context.push(`[`);2363 multilines && context.indent();2364 genNodeList(nodes, context, multilines);2365 multilines && context.deindent();2366 context.push(`]`);2367}2368function genNodeList(nodes, context, multilines = false, comma = true) {2369 const { push, newline } = context;2370 for (let i = 0; i < nodes.length; i++) {2371 const node = nodes[i];2372 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node)) {2373 push(node);2374 }2375 else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(node)) {2376 genNodeListAsArray(node, context);2377 }2378 else {2379 genNode(node, context);2380 }2381 if (i < nodes.length - 1) {2382 if (multilines) {2383 comma && push(',');2384 newline();2385 }2386 else {2387 comma && push(', ');2388 }2389 }2390 }2391}2392function genNode(node, context) {2393 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node)) {2394 context.push(node);2395 return;2396 }2397 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(node)) {2398 context.push(context.helper(node));2399 return;2400 }2401 switch (node.type) {2402 case 1 /* ELEMENT */:2403 case 9 /* IF */:2404 case 11 /* FOR */:2405 ( true) &&2406 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2407 `Apply appropriate transforms first.`);2408 genNode(node.codegenNode, context);2409 break;2410 case 2 /* TEXT */:2411 genText(node, context);2412 break;2413 case 4 /* SIMPLE_EXPRESSION */:2414 genExpression(node, context);2415 break;2416 case 5 /* INTERPOLATION */:2417 genInterpolation(node, context);2418 break;2419 case 12 /* TEXT_CALL */:2420 genNode(node.codegenNode, context);2421 break;2422 case 8 /* COMPOUND_EXPRESSION */:2423 genCompoundExpression(node, context);2424 break;2425 case 3 /* COMMENT */:2426 genComment(node, context);2427 break;2428 case 13 /* VNODE_CALL */:2429 genVNodeCall(node, context);2430 break;2431 case 14 /* JS_CALL_EXPRESSION */:2432 genCallExpression(node, context);2433 break;2434 case 15 /* JS_OBJECT_EXPRESSION */:2435 genObjectExpression(node, context);2436 break;2437 case 17 /* JS_ARRAY_EXPRESSION */:2438 genArrayExpression(node, context);2439 break;2440 case 18 /* JS_FUNCTION_EXPRESSION */:2441 genFunctionExpression(node, context);2442 break;2443 case 19 /* JS_CONDITIONAL_EXPRESSION */:2444 genConditionalExpression(node, context);2445 break;2446 case 20 /* JS_CACHE_EXPRESSION */:2447 genCacheExpression(node, context);2448 break;2449 // SSR only types2450 case 21 /* JS_BLOCK_STATEMENT */:2451 break;2452 case 22 /* JS_TEMPLATE_LITERAL */:2453 break;2454 case 23 /* JS_IF_STATEMENT */:2455 break;2456 case 24 /* JS_ASSIGNMENT_EXPRESSION */:2457 break;2458 case 25 /* JS_SEQUENCE_EXPRESSION */:2459 break;2460 case 26 /* JS_RETURN_STATEMENT */:2461 break;2462 /* istanbul ignore next */2463 case 10 /* IF_BRANCH */:2464 // noop2465 break;2466 default:2467 if ((true)) {2468 assert(false, `unhandled codegen node type: ${node.type}`);2469 // make sure we exhaust all possible types2470 const exhaustiveCheck = node;2471 return exhaustiveCheck;2472 }2473 }2474}2475function genText(node, context) {2476 context.push(JSON.stringify(node.content), node);2477}2478function genExpression(node, context) {2479 const { content, isStatic } = node;2480 context.push(isStatic ? JSON.stringify(content) : content, node);2481}2482function genInterpolation(node, context) {2483 const { push, helper, pure } = context;2484 if (pure)2485 push(PURE_ANNOTATION);2486 push(`${helper(TO_DISPLAY_STRING)}(`);2487 genNode(node.content, context);2488 push(`)`);2489}2490function genCompoundExpression(node, context) {2491 for (let i = 0; i < node.children.length; i++) {2492 const child = node.children[i];2493 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child)) {2494 context.push(child);2495 }2496 else {2497 genNode(child, context);2498 }2499 }2500}2501function genExpressionAsPropertyKey(node, context) {2502 const { push } = context;2503 if (node.type === 8 /* COMPOUND_EXPRESSION */) {2504 push(`[`);2505 genCompoundExpression(node, context);2506 push(`]`);2507 }2508 else if (node.isStatic) {2509 // only quote keys if necessary2510 const text = isSimpleIdentifier(node.content)2511 ? node.content2512 : JSON.stringify(node.content);2513 push(text, node);2514 }2515 else {2516 push(`[${node.content}]`, node);2517 }2518}2519function genComment(node, context) {2520 const { push, helper, pure } = context;2521 if (pure) {2522 push(PURE_ANNOTATION);2523 }2524 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2525}2526function genVNodeCall(node, context) {2527 const { push, helper, pure } = context;2528 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking } = node;2529 if (directives) {2530 push(helper(WITH_DIRECTIVES) + `(`);2531 }2532 if (isBlock) {2533 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2534 }2535 if (pure) {2536 push(PURE_ANNOTATION);2537 }2538 push(helper(isBlock ? CREATE_BLOCK : CREATE_VNODE) + `(`, node);2539 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2540 push(`)`);2541 if (isBlock) {2542 push(`)`);2543 }2544 if (directives) {2545 push(`, `);2546 genNode(directives, context);2547 push(`)`);2548 }2549}2550function genNullableArgs(args) {2551 let i = args.length;2552 while (i--) {2553 if (args[i] != null)2554 break;2555 }2556 return args.slice(0, i + 1).map(arg => arg || `null`);2557}2558// JavaScript2559function genCallExpression(node, context) {2560 const { push, helper, pure } = context;2561 const callee = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node.callee) ? node.callee : helper(node.callee);2562 if (pure) {2563 push(PURE_ANNOTATION);2564 }2565 push(callee + `(`, node);2566 genNodeList(node.arguments, context);2567 push(`)`);2568}2569function genObjectExpression(node, context) {2570 const { push, indent, deindent, newline } = context;2571 const { properties } = node;2572 if (!properties.length) {2573 push(`{}`, node);2574 return;2575 }2576 const multilines = properties.length > 1 ||2577 ((( true)) &&2578 properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2579 push(multilines ? `{` : `{ `);2580 multilines && indent();2581 for (let i = 0; i < properties.length; i++) {2582 const { key, value } = properties[i];2583 // key2584 genExpressionAsPropertyKey(key, context);2585 push(`: `);2586 // value2587 genNode(value, context);2588 if (i < properties.length - 1) {2589 // will only reach this if it's multilines2590 push(`,`);2591 newline();2592 }2593 }2594 multilines && deindent();2595 push(multilines ? `}` : ` }`);2596}2597function genArrayExpression(node, context) {2598 genNodeListAsArray(node.elements, context);2599}2600function genFunctionExpression(node, context) {2601 const { push, indent, deindent, scopeId, mode } = context;2602 const { params, returns, body, newline, isSlot } = node;2603 if (isSlot) {2604 // wrap slot functions with owner context2605 push(`_${helperNameMap[WITH_CTX]}(`);2606 }2607 push(`(`, node);2608 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(params)) {2609 genNodeList(params, context);2610 }2611 else if (params) {2612 genNode(params, context);2613 }2614 push(`) => `);2615 if (newline || body) {2616 push(`{`);2617 indent();2618 }2619 if (returns) {2620 if (newline) {2621 push(`return `);2622 }2623 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(returns)) {2624 genNodeListAsArray(returns, context);2625 }2626 else {2627 genNode(returns, context);2628 }2629 }2630 else if (body) {2631 genNode(body, context);2632 }2633 if (newline || body) {2634 deindent();2635 push(`}`);2636 }2637 if (isSlot) {2638 if (node.isNonScopedSlot) {2639 push(`, undefined, true`);2640 }2641 push(`)`);2642 }2643}2644function genConditionalExpression(node, context) {2645 const { test, consequent, alternate, newline: needNewline } = node;2646 const { push, indent, deindent, newline } = context;2647 if (test.type === 4 /* SIMPLE_EXPRESSION */) {2648 const needsParens = !isSimpleIdentifier(test.content);2649 needsParens && push(`(`);2650 genExpression(test, context);2651 needsParens && push(`)`);2652 }2653 else {2654 push(`(`);2655 genNode(test, context);2656 push(`)`);2657 }2658 needNewline && indent();2659 context.indentLevel++;2660 needNewline || push(` `);2661 push(`? `);2662 genNode(consequent, context);2663 context.indentLevel--;2664 needNewline && newline();2665 needNewline || push(` `);2666 push(`: `);2667 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2668 if (!isNested) {2669 context.indentLevel++;2670 }2671 genNode(alternate, context);2672 if (!isNested) {2673 context.indentLevel--;2674 }2675 needNewline && deindent(true /* without newline */);2676}2677function genCacheExpression(node, context) {2678 const { push, helper, indent, deindent, newline } = context;2679 push(`_cache[${node.index}] || (`);2680 if (node.isVNode) {2681 indent();2682 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2683 newline();2684 }2685 push(`_cache[${node.index}] = `);2686 genNode(node.value, context);2687 if (node.isVNode) {2688 push(`,`);2689 newline();2690 push(`${helper(SET_BLOCK_TRACKING)}(1),`);2691 newline();2692 push(`_cache[${node.index}]`);2693 deindent();2694 }2695 push(`)`);2696}2697// these keywords should not appear inside expressions, but operators like2698// typeof, instanceof and in are allowed2699const prohibitedKeywordRE = new RegExp('\\b' +2700 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +2701 'super,throw,while,yield,delete,export,import,return,switch,default,' +2702 'extends,finally,continue,debugger,function,arguments,typeof,void')2703 .split(',')2704 .join('\\b|\\b') +2705 '\\b');2706// strip strings in expressions2707const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;2708/**2709 * Validate a non-prefixed expression.2710 * This is only called when using the in-browser runtime compiler since it2711 * doesn't prefix expressions.2712 */2713function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {2714 const exp = node.content;2715 // empty expressions are validated per-directive since some directives2716 // do allow empty expressions.2717 if (!exp.trim()) {2718 return;2719 }2720 try {2721 new Function(asRawStatements2722 ? ` ${exp} `2723 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);2724 }2725 catch (e) {2726 let message = e.message;2727 const keywordMatch = exp2728 .replace(stripStringRE, '')2729 .match(prohibitedKeywordRE);2730 if (keywordMatch) {2731 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;2732 }2733 context.onError(createCompilerError(43 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));2734 }2735}2736const transformExpression = (node, context) => {2737 if (node.type === 5 /* INTERPOLATION */) {2738 node.content = processExpression(node.content, context);2739 }2740 else if (node.type === 1 /* ELEMENT */) {2741 // handle directives on element2742 for (let i = 0; i < node.props.length; i++) {2743 const dir = node.props[i];2744 // do not process for v-on & v-for since they are special handled2745 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {2746 const exp = dir.exp;2747 const arg = dir.arg;2748 // do not process exp if this is v-on:arg - we need special handling2749 // for wrapping inline statements.2750 if (exp &&2751 exp.type === 4 /* SIMPLE_EXPRESSION */ &&2752 !(dir.name === 'on' && arg)) {2753 dir.exp = processExpression(exp, context, 2754 // slot args must be processed as function params2755 dir.name === 'slot');2756 }2757 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {2758 dir.arg = processExpression(arg, context);2759 }2760 }2761 }2762 }2763};2764// Important: since this function uses Node.js only dependencies, it should2765// always be used with a leading !true check so that it can be2766// tree-shaken from the browser build.2767function processExpression(node, context, 2768// some expressions like v-slot props & v-for aliases should be parsed as2769// function params2770asParams = false, 2771// v-on handler values may contain multiple statements2772asRawStatements = false) {2773 {2774 if ((true)) {2775 // simple in-browser validation (same logic in 2.x)2776 validateBrowserExpression(node, context, asParams, asRawStatements);2777 }2778 return node;2779 }2780}2781const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {2782 return processIf(node, dir, context, (ifNode, branch, isRoot) => {2783 // #1587: We need to dynamically increment the key based on the current2784 // node's sibling nodes, since chained v-if/else branches are2785 // rendered at the same depth2786 const siblings = context.parent.children;2787 let i = siblings.indexOf(ifNode);2788 let key = 0;2789 while (i-- >= 0) {2790 const sibling = siblings[i];2791 if (sibling && sibling.type === 9 /* IF */) {2792 key += sibling.branches.length;2793 }2794 }2795 // Exit callback. Complete the codegenNode when all children have been2796 // transformed.2797 return () => {2798 if (isRoot) {2799 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);2800 }2801 else {2802 // attach this branch's codegen node to the v-if root.2803 const parentCondition = getParentCondition(ifNode.codegenNode);2804 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);2805 }2806 };2807 });2808});2809// target-agnostic transform used for both Client and SSR2810function processIf(node, dir, context, processCodegen) {2811 if (dir.name !== 'else' &&2812 (!dir.exp || !dir.exp.content.trim())) {2813 const loc = dir.exp ? dir.exp.loc : node.loc;2814 context.onError(createCompilerError(27 /* X_V_IF_NO_EXPRESSION */, dir.loc));2815 dir.exp = createSimpleExpression(`true`, false, loc);2816 }2817 if ( true && dir.exp) {2818 validateBrowserExpression(dir.exp, context);2819 }2820 if (dir.name === 'if') {2821 const branch = createIfBranch(node, dir);2822 const ifNode = {2823 type: 9 /* IF */,2824 loc: node.loc,2825 branches: [branch]2826 };2827 context.replaceNode(ifNode);2828 if (processCodegen) {2829 return processCodegen(ifNode, branch, true);2830 }2831 }2832 else {2833 // locate the adjacent v-if2834 const siblings = context.parent.children;2835 const comments = [];2836 let i = siblings.indexOf(node);2837 while (i-- >= -1) {2838 const sibling = siblings[i];2839 if (( true) && sibling && sibling.type === 3 /* COMMENT */) {2840 context.removeNode(sibling);2841 comments.unshift(sibling);2842 continue;2843 }2844 if (sibling &&2845 sibling.type === 2 /* TEXT */ &&2846 !sibling.content.trim().length) {2847 context.removeNode(sibling);2848 continue;2849 }2850 if (sibling && sibling.type === 9 /* IF */) {2851 // move the node to the if node's branches2852 context.removeNode();2853 const branch = createIfBranch(node, dir);2854 if (( true) &&2855 comments.length &&2856 // #3619 ignore comments if the v-if is direct child of <transition>2857 !(context.parent &&2858 context.parent.type === 1 /* ELEMENT */ &&2859 isBuiltInType(context.parent.tag, 'transition'))) {2860 branch.children = [...comments, ...branch.children];2861 }2862 // check if user is forcing same key on different branches2863 if (true) {2864 const key = branch.userKey;2865 if (key) {2866 sibling.branches.forEach(({ userKey }) => {2867 if (isSameKey(userKey, key)) {2868 context.onError(createCompilerError(28 /* X_V_IF_SAME_KEY */, branch.userKey.loc));2869 }2870 });2871 }2872 }2873 sibling.branches.push(branch);2874 const onExit = processCodegen && processCodegen(sibling, branch, false);2875 // since the branch was removed, it will not be traversed.2876 // make sure to traverse here.2877 traverseNode(branch, context);2878 // call on exit2879 if (onExit)2880 onExit();2881 // make sure to reset currentNode after traversal to indicate this2882 // node has been removed.2883 context.currentNode = null;2884 }2885 else {2886 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));2887 }2888 break;2889 }2890 }2891}2892function createIfBranch(node, dir) {2893 return {2894 type: 10 /* IF_BRANCH */,2895 loc: node.loc,2896 condition: dir.name === 'else' ? undefined : dir.exp,2897 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')2898 ? node.children2899 : [node],2900 userKey: findProp(node, `key`)2901 };2902}2903function createCodegenNodeForBranch(branch, keyIndex, context) {2904 if (branch.condition) {2905 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 2906 // make sure to pass in asBlock: true so that the comment node call2907 // closes the current block.2908 createCallExpression(context.helper(CREATE_COMMENT), [2909 ( true) ? '"v-if"' : 0,2910 'true'2911 ]));2912 }2913 else {2914 return createChildrenCodegenNode(branch, keyIndex, context);2915 }2916}2917function createChildrenCodegenNode(branch, keyIndex, context) {2918 const { helper, removeHelper } = context;2919 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));2920 const { children } = branch;2921 const firstChild = children[0];2922 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;2923 if (needFragmentWrapper) {2924 if (children.length === 1 && firstChild.type === 11 /* FOR */) {2925 // optimize away nested fragments when child is a ForNode2926 const vnodeCall = firstChild.codegenNode;2927 injectProp(vnodeCall, keyProperty, context);2928 return vnodeCall;2929 }2930 else {2931 let patchFlag = 64 /* STABLE_FRAGMENT */;2932 let patchFlagText = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64];2933 // check if the fragment actually contains a single valid child with2934 // the rest being comments2935 if (( true) &&2936 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2937 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2938 patchFlagText += `, ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[2048]}`;2939 }2940 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (( true) ? ` /* ${patchFlagText} */` : 0), undefined, undefined, true, false, branch.loc);2941 }2942 }2943 else {2944 const vnodeCall = firstChild2945 .codegenNode;2946 // Change createVNode to createBlock.2947 if (vnodeCall.type === 13 /* VNODE_CALL */ && !vnodeCall.isBlock) {2948 removeHelper(CREATE_VNODE);2949 vnodeCall.isBlock = true;2950 helper(OPEN_BLOCK);2951 helper(CREATE_BLOCK);2952 }2953 // inject branch key2954 injectProp(vnodeCall, keyProperty, context);2955 return vnodeCall;2956 }2957}2958function isSameKey(a, b) {2959 if (!a || a.type !== b.type) {2960 return false;2961 }2962 if (a.type === 6 /* ATTRIBUTE */) {2963 if (a.value.content !== b.value.content) {2964 return false;2965 }2966 }2967 else {2968 // directive2969 const exp = a.exp;2970 const branchExp = b.exp;2971 if (exp.type !== branchExp.type) {2972 return false;2973 }2974 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||2975 (exp.isStatic !== branchExp.isStatic ||2976 exp.content !== branchExp.content)) {2977 return false;2978 }2979 }2980 return true;2981}2982function getParentCondition(node) {2983 while (true) {2984 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {2985 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {2986 node = node.alternate;2987 }2988 else {2989 return node;2990 }2991 }2992 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {2993 node = node.value;2994 }2995 }2996}2997const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {2998 const { helper, removeHelper } = context;2999 return processFor(node, dir, context, forNode => {3000 // create the loop render function expression now, and add the3001 // iterator on exit after all children have been traversed3002 const renderExp = createCallExpression(helper(RENDER_LIST), [3003 forNode.source3004 ]);3005 const keyProp = findProp(node, `key`);3006 const keyProperty = keyProp3007 ? createObjectProperty(`key`, keyProp.type === 6 /* ATTRIBUTE */3008 ? createSimpleExpression(keyProp.value.content, true)3009 : keyProp.exp)3010 : null;3011 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3012 forNode.source.constType > 0 /* NOT_CONSTANT */;3013 const fragmentFlag = isStableFragment3014 ? 64 /* STABLE_FRAGMENT */3015 : keyProp3016 ? 128 /* KEYED_FRAGMENT */3017 : 256 /* UNKEYED_FRAGMENT */;3018 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3019 (( true) ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[fragmentFlag]} */` : 0), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, node.loc);3020 return () => {3021 // finish the codegen now that all children have been traversed3022 let childBlock;3023 const isTemplate = isTemplateNode(node);3024 const { children } = forNode;3025 // check <template v-for> key placement3026 if (( true) && isTemplate) {3027 node.children.some(c => {3028 if (c.type === 1 /* ELEMENT */) {3029 const key = findProp(c, 'key');3030 if (key) {3031 context.onError(createCompilerError(32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3032 return true;3033 }3034 }3035 });3036 }3037 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3038 const slotOutlet = isSlotOutlet(node)3039 ? node3040 : isTemplate &&3041 node.children.length === 1 &&3042 isSlotOutlet(node.children[0])3043 ? node.children[0] // api-extractor somehow fails to infer this3044 : null;3045 if (slotOutlet) {3046 // <slot v-for="..."> or <template v-for="..."><slot/></template>3047 childBlock = slotOutlet.codegenNode;3048 if (isTemplate && keyProperty) {3049 // <template v-for="..." :key="..."><slot/></template>3050 // we need to inject the key to the renderSlot() call.3051 // the props for renderSlot is passed as the 3rd argument.3052 injectProp(childBlock, keyProperty, context);3053 }3054 }3055 else if (needFragmentWrapper) {3056 // <template v-for="..."> with text or multi-elements3057 // should generate a fragment block for each loop3058 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3059 (( true)3060 ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64]} */`3061 : 0), undefined, undefined, true);3062 }3063 else {3064 // Normal element v-for. Directly use the child's codegenNode3065 // but mark it as a block.3066 childBlock = children[0]3067 .codegenNode;3068 if (isTemplate && keyProperty) {3069 injectProp(childBlock, keyProperty, context);3070 }3071 if (childBlock.isBlock !== !isStableFragment) {3072 if (childBlock.isBlock) {3073 // switch from block to vnode3074 removeHelper(OPEN_BLOCK);3075 removeHelper(CREATE_BLOCK);3076 }3077 else {3078 // switch from vnode to block3079 removeHelper(CREATE_VNODE);3080 }3081 }3082 childBlock.isBlock = !isStableFragment;3083 if (childBlock.isBlock) {3084 helper(OPEN_BLOCK);3085 helper(CREATE_BLOCK);3086 }3087 else {3088 helper(CREATE_VNODE);3089 }3090 }3091 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3092 };3093 });3094});3095// target-agnostic transform used for both Client and SSR3096function processFor(node, dir, context, processCodegen) {3097 if (!dir.exp) {3098 context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3099 return;3100 }3101 const parseResult = parseForExpression(3102 // can only be simple expression because vFor transform is applied3103 // before expression transform.3104 dir.exp, context);3105 if (!parseResult) {3106 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3107 return;3108 }3109 const { addIdentifiers, removeIdentifiers, scopes } = context;3110 const { source, value, key, index } = parseResult;3111 const forNode = {3112 type: 11 /* FOR */,3113 loc: dir.loc,3114 source,3115 valueAlias: value,3116 keyAlias: key,3117 objectIndexAlias: index,3118 parseResult,3119 children: isTemplateNode(node) ? node.children : [node]3120 };3121 context.replaceNode(forNode);3122 // bookkeeping3123 scopes.vFor++;3124 const onExit = processCodegen && processCodegen(forNode);3125 return () => {3126 scopes.vFor--;3127 if (onExit)3128 onExit();3129 };3130}3131const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3132// This regex doesn't cover the case if key or index aliases have destructuring,3133// but those do not make sense in the first place, so this works in practice.3134const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3135const stripParensRE = /^\(|\)$/g;3136function parseForExpression(input, context) {3137 const loc = input.loc;3138 const exp = input.content;3139 const inMatch = exp.match(forAliasRE);3140 if (!inMatch)3141 return;3142 const [, LHS, RHS] = inMatch;3143 const result = {3144 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3145 value: undefined,3146 key: undefined,3147 index: undefined3148 };3149 if (true) {3150 validateBrowserExpression(result.source, context);3151 }3152 let valueContent = LHS.trim()3153 .replace(stripParensRE, '')3154 .trim();3155 const trimmedOffset = LHS.indexOf(valueContent);3156 const iteratorMatch = valueContent.match(forIteratorRE);3157 if (iteratorMatch) {3158 valueContent = valueContent.replace(forIteratorRE, '').trim();3159 const keyContent = iteratorMatch[1].trim();3160 let keyOffset;3161 if (keyContent) {3162 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3163 result.key = createAliasExpression(loc, keyContent, keyOffset);3164 if (true) {3165 validateBrowserExpression(result.key, context, true);3166 }3167 }3168 if (iteratorMatch[2]) {3169 const indexContent = iteratorMatch[2].trim();3170 if (indexContent) {3171 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3172 ? keyOffset + keyContent.length3173 : trimmedOffset + valueContent.length));3174 if (true) {3175 validateBrowserExpression(result.index, context, true);3176 }3177 }3178 }3179 }3180 if (valueContent) {3181 result.value = createAliasExpression(loc, valueContent, trimmedOffset);3182 if (true) {3183 validateBrowserExpression(result.value, context, true);3184 }3185 }3186 return result;3187}3188function createAliasExpression(range, content, offset) {3189 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3190}3191function createForLoopParams({ value, key, index }) {3192 const params = [];3193 if (value) {3194 params.push(value);3195 }3196 if (key) {3197 if (!value) {3198 params.push(createSimpleExpression(`_`, false));3199 }3200 params.push(key);3201 }3202 if (index) {3203 if (!key) {3204 if (!value) {3205 params.push(createSimpleExpression(`_`, false));3206 }3207 params.push(createSimpleExpression(`__`, false));3208 }3209 params.push(index);3210 }3211 return params;3212}3213const defaultFallback = createSimpleExpression(`undefined`, false);3214// A NodeTransform that:3215// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3216// by transformExpression. This is only applied in non-browser builds with3217// { prefixIdentifiers: true }.3218// 2. Track v-slot depths so that we know a slot is inside another slot.3219// Note the exit callback is executed before buildSlots() on the same node,3220// so only nested slots see positive numbers.3221const trackSlotScopes = (node, context) => {3222 if (node.type === 1 /* ELEMENT */ &&3223 (node.tagType === 1 /* COMPONENT */ ||3224 node.tagType === 3 /* TEMPLATE */)) {3225 // We are only checking non-empty v-slot here3226 // since we only care about slots that introduce scope variables.3227 const vSlot = findDir(node, 'slot');3228 if (vSlot) {3229 vSlot.exp;3230 context.scopes.vSlot++;3231 return () => {3232 context.scopes.vSlot--;3233 };3234 }3235 }3236};3237// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3238// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3239const trackVForSlotScopes = (node, context) => {3240 let vFor;3241 if (isTemplateNode(node) &&3242 node.props.some(isVSlot) &&3243 (vFor = findDir(node, 'for'))) {3244 const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3245 if (result) {3246 const { value, key, index } = result;3247 const { addIdentifiers, removeIdentifiers } = context;3248 value && addIdentifiers(value);3249 key && addIdentifiers(key);3250 index && addIdentifiers(index);3251 return () => {3252 value && removeIdentifiers(value);3253 key && removeIdentifiers(key);3254 index && removeIdentifiers(index);3255 };3256 }3257 }3258};3259const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3260// Instead of being a DirectiveTransform, v-slot processing is called during3261// transformElement to build the slots object for a component.3262function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3263 context.helper(WITH_CTX);3264 const { children, loc } = node;3265 const slotsProperties = [];3266 const dynamicSlots = [];3267 // If the slot is inside a v-for or another v-slot, force it to be dynamic3268 // since it likely uses a scope variable.3269 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3270 // 1. Check for slot with slotProps on component itself.3271 // <Comp v-slot="{ prop }"/>3272 const onComponentSlot = findDir(node, 'slot', true);3273 if (onComponentSlot) {3274 const { arg, exp } = onComponentSlot;3275 if (arg && !isStaticExp(arg)) {3276 hasDynamicSlots = true;3277 }3278 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));3279 }3280 // 2. Iterate through children and check for template slots3281 // <template v-slot:foo="{ prop }">3282 let hasTemplateSlots = false;3283 let hasNamedDefaultSlot = false;3284 const implicitDefaultChildren = [];3285 const seenSlotNames = new Set();3286 for (let i = 0; i < children.length; i++) {3287 const slotElement = children[i];3288 let slotDir;3289 if (!isTemplateNode(slotElement) ||3290 !(slotDir = findDir(slotElement, 'slot', true))) {3291 // not a <template v-slot>, skip.3292 if (slotElement.type !== 3 /* COMMENT */) {3293 implicitDefaultChildren.push(slotElement);3294 }3295 continue;3296 }3297 if (onComponentSlot) {3298 // already has on-component slot - this is incorrect usage.3299 context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3300 break;3301 }3302 hasTemplateSlots = true;3303 const { children: slotChildren, loc: slotLoc } = slotElement;3304 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3305 // check if name is dynamic.3306 let staticSlotName;3307 if (isStaticExp(slotName)) {3308 staticSlotName = slotName ? slotName.content : `default`;3309 }3310 else {3311 hasDynamicSlots = true;3312 }3313 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3314 // check if this slot is conditional (v-if/v-for)3315 let vIf;3316 let vElse;3317 let vFor;3318 if ((vIf = findDir(slotElement, 'if'))) {3319 hasDynamicSlots = true;3320 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3321 }3322 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3323 // find adjacent v-if3324 let j = i;3325 let prev;3326 while (j--) {3327 prev = children[j];3328 if (prev.type !== 3 /* COMMENT */) {3329 break;3330 }3331 }3332 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3333 // remove node3334 children.splice(i, 1);3335 i--;3336 // attach this slot to previous conditional3337 let conditional = dynamicSlots[dynamicSlots.length - 1];3338 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3339 conditional = conditional.alternate;3340 }3341 conditional.alternate = vElse.exp3342 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3343 : buildDynamicSlot(slotName, slotFunction);3344 }3345 else {3346 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3347 }3348 }3349 else if ((vFor = findDir(slotElement, 'for'))) {3350 hasDynamicSlots = true;3351 const parseResult = vFor.parseResult ||3352 parseForExpression(vFor.exp, context);3353 if (parseResult) {3354 // Render the dynamic slots as an array and add it to the createSlot()3355 // args. The runtime knows how to handle it appropriately.3356 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3357 parseResult.source,3358 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3359 ]));3360 }3361 else {3362 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3363 }3364 }3365 else {3366 // check duplicate static names3367 if (staticSlotName) {3368 if (seenSlotNames.has(staticSlotName)) {3369 context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3370 continue;3371 }3372 seenSlotNames.add(staticSlotName);3373 if (staticSlotName === 'default') {3374 hasNamedDefaultSlot = true;3375 }3376 }3377 slotsProperties.push(createObjectProperty(slotName, slotFunction));3378 }3379 }3380 if (!onComponentSlot) {3381 const buildDefaultSlotProperty = (props, children) => {3382 const fn = buildSlotFn(props, children, loc);3383 if (context.compatConfig) {3384 fn.isNonScopedSlot = true;3385 }3386 return createObjectProperty(`default`, fn);3387 };3388 if (!hasTemplateSlots) {3389 // implicit default slot (on component)3390 slotsProperties.push(buildDefaultSlotProperty(undefined, children));3391 }3392 else if (implicitDefaultChildren.length &&3393 // #37663394 // with whitespace: 'preserve', whitespaces between slots will end up in3395 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.3396 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {3397 // implicit default slot (mixed with named slots)3398 if (hasNamedDefaultSlot) {3399 context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));3400 }3401 else {3402 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));3403 }3404 }3405 }3406 const slotFlag = hasDynamicSlots3407 ? 2 /* DYNAMIC */3408 : hasForwardedSlots(node.children)3409 ? 3 /* FORWARDED */3410 : 1 /* STABLE */;3411 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 3412 // 2 = compiled but dynamic = can skip normalization, but must run diff3413 // 1 = compiled and static = can skip normalization AND diff as optimized3414 createSimpleExpression(slotFlag + (( true) ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.slotFlagsText[slotFlag]} */` : 0), false))), loc);3415 if (dynamicSlots.length) {3416 slots = createCallExpression(context.helper(CREATE_SLOTS), [3417 slots,3418 createArrayExpression(dynamicSlots)3419 ]);3420 }3421 return {3422 slots,3423 hasDynamicSlots3424 };3425}3426function buildDynamicSlot(name, fn) {3427 return createObjectExpression([3428 createObjectProperty(`name`, name),3429 createObjectProperty(`fn`, fn)3430 ]);3431}3432function hasForwardedSlots(children) {3433 for (let i = 0; i < children.length; i++) {3434 const child = children[i];3435 switch (child.type) {3436 case 1 /* ELEMENT */:3437 if (child.tagType === 2 /* SLOT */ ||3438 ((child.tagType === 0 /* ELEMENT */ ||3439 child.tagType === 3 /* TEMPLATE */) &&3440 hasForwardedSlots(child.children))) {3441 return true;3442 }3443 break;3444 case 9 /* IF */:3445 if (hasForwardedSlots(child.branches))3446 return true;3447 break;3448 case 10 /* IF_BRANCH */:3449 case 11 /* FOR */:3450 if (hasForwardedSlots(child.children))3451 return true;3452 break;3453 }3454 }3455 return false;3456}3457function isNonWhitespaceContent(node) {3458 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)3459 return true;3460 return node.type === 2 /* TEXT */3461 ? !!node.content.trim()3462 : isNonWhitespaceContent(node.content);3463}3464// some directive transforms (e.g. v-model) may return a symbol for runtime3465// import, which should be used instead of a resolveDirective call.3466const directiveImportMap = new WeakMap();3467// generate a JavaScript AST for this element's codegen3468const transformElement = (node, context) => {3469 // perform the work on exit, after all child expressions have been3470 // processed and merged.3471 return function postTransformElement() {3472 node = context.currentNode;3473 if (!(node.type === 1 /* ELEMENT */ &&3474 (node.tagType === 0 /* ELEMENT */ ||3475 node.tagType === 1 /* COMPONENT */))) {3476 return;3477 }3478 const { tag, props } = node;3479 const isComponent = node.tagType === 1 /* COMPONENT */;3480 // The goal of the transform is to create a codegenNode implementing the3481 // VNodeCall interface.3482 let vnodeTag = isComponent3483 ? resolveComponentType(node, context)3484 : `"${tag}"`;3485 const isDynamicComponent = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;3486 let vnodeProps;3487 let vnodeChildren;3488 let vnodePatchFlag;3489 let patchFlag = 0;3490 let vnodeDynamicProps;3491 let dynamicPropNames;3492 let vnodeDirectives;3493 let shouldUseBlock = 3494 // dynamic component may resolve to plain elements3495 isDynamicComponent ||3496 vnodeTag === TELEPORT ||3497 vnodeTag === SUSPENSE ||3498 (!isComponent &&3499 // <svg> and <foreignObject> must be forced into blocks so that block3500 // updates inside get proper isSVG flag at runtime. (#639, #643)3501 // This is technically web-specific, but splitting the logic out of core3502 // leads to too much unnecessary complexity.3503 (tag === 'svg' ||3504 tag === 'foreignObject' ||3505 // #938: elements with dynamic keys should be forced into blocks3506 findProp(node, 'key', true)));3507 // props3508 if (props.length > 0) {3509 const propsBuildResult = buildProps(node, context);3510 vnodeProps = propsBuildResult.props;3511 patchFlag = propsBuildResult.patchFlag;3512 dynamicPropNames = propsBuildResult.dynamicPropNames;3513 const directives = propsBuildResult.directives;3514 vnodeDirectives =3515 directives && directives.length3516 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))3517 : undefined;3518 }3519 // children3520 if (node.children.length > 0) {3521 if (vnodeTag === KEEP_ALIVE) {3522 // Although a built-in component, we compile KeepAlive with raw children3523 // instead of slot functions so that it can be used inside Transition3524 // or other Transition-wrapping HOCs.3525 // To ensure correct updates with block optimizations, we need to:3526 // 1. Force keep-alive into a block. This avoids its children being3527 // collected by a parent block.3528 shouldUseBlock = true;3529 // 2. Force keep-alive to always be updated, since it uses raw children.3530 patchFlag |= 1024 /* DYNAMIC_SLOTS */;3531 if (( true) && node.children.length > 1) {3532 context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {3533 start: node.children[0].loc.start,3534 end: node.children[node.children.length - 1].loc.end,3535 source: ''3536 }));3537 }3538 }3539 const shouldBuildAsSlots = isComponent &&3540 // Teleport is not a real component and has dedicated runtime handling3541 vnodeTag !== TELEPORT &&3542 // explained above.3543 vnodeTag !== KEEP_ALIVE;3544 if (shouldBuildAsSlots) {3545 const { slots, hasDynamicSlots } = buildSlots(node, context);3546 vnodeChildren = slots;3547 if (hasDynamicSlots) {3548 patchFlag |= 1024 /* DYNAMIC_SLOTS */;3549 }3550 }3551 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {3552 const child = node.children[0];3553 const type = child.type;3554 // check for dynamic text children3555 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||3556 type === 8 /* COMPOUND_EXPRESSION */;3557 if (hasDynamicTextChild &&3558 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {3559 patchFlag |= 1 /* TEXT */;3560 }3561 // pass directly if the only child is a text node3562 // (plain / interpolation / expression)3563 if (hasDynamicTextChild || type === 2 /* TEXT */) {3564 vnodeChildren = child;3565 }3566 else {3567 vnodeChildren = node.children;3568 }3569 }3570 else {3571 vnodeChildren = node.children;3572 }3573 }3574 // patchFlag & dynamicPropNames3575 if (patchFlag !== 0) {3576 if ((true)) {3577 if (patchFlag < 0) {3578 // special flags (negative and mutually exclusive)3579 vnodePatchFlag = patchFlag + ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[patchFlag]} */`;3580 }3581 else {3582 // bitwise flags3583 const flagNames = Object.keys(_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames)3584 .map(Number)3585 .filter(n => n > 0 && patchFlag & n)3586 .map(n => _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[n])3587 .join(`, `);3588 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;3589 }3590 }3591 else {}3592 if (dynamicPropNames && dynamicPropNames.length) {3593 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);3594 }3595 }3596 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, node.loc);3597 };3598};3599function resolveComponentType(node, context, ssr = false) {3600 let { tag } = node;3601 // 1. dynamic component3602 const isExplicitDynamic = isComponentTag(tag);3603 const isProp = findProp(node, 'is');3604 if (isProp) {3605 if (isExplicitDynamic ||3606 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {3607 const exp = isProp.type === 6 /* ATTRIBUTE */3608 ? isProp.value && createSimpleExpression(isProp.value.content, true)3609 : isProp.exp;3610 if (exp) {3611 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3612 exp3613 ]);3614 }3615 }3616 else if (isProp.type === 6 /* ATTRIBUTE */ &&3617 isProp.value.content.startsWith('vue:')) {3618 // <button is="vue:xxx">3619 // if not <component>, only is value that starts with "vue:" will be3620 // treated as component by the parse phase and reach here, unless it's3621 // compat mode where all is values are considered components3622 tag = isProp.value.content.slice(4);3623 }3624 }3625 // 1.5 v-is (TODO: Deprecate)3626 const isDir = !isExplicitDynamic && findDir(node, 'is');3627 if (isDir && isDir.exp) {3628 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3629 isDir.exp3630 ]);3631 }3632 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)3633 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);3634 if (builtIn) {3635 // built-ins are simply fallthroughs / have special handling during ssr3636 // so we don't need to import their runtime equivalents3637 if (!ssr)3638 context.helper(builtIn);3639 return builtIn;3640 }3641 // 5. user component (resolve)3642 context.helper(RESOLVE_COMPONENT);3643 context.components.add(tag);3644 return toValidAssetId(tag, `component`);3645}3646function buildProps(node, context, props = node.props, ssr = false) {3647 const { tag, loc: elementLoc } = node;3648 const isComponent = node.tagType === 1 /* COMPONENT */;3649 let properties = [];3650 const mergeArgs = [];3651 const runtimeDirectives = [];3652 // patchFlag analysis3653 let patchFlag = 0;3654 let hasRef = false;3655 let hasClassBinding = false;3656 let hasStyleBinding = false;3657 let hasHydrationEventBinding = false;3658 let hasDynamicKeys = false;3659 let hasVnodeHook = false;3660 const dynamicPropNames = [];3661 const analyzePatchFlag = ({ key, value }) => {3662 if (isStaticExp(key)) {3663 const name = key.content;3664 const isEventHandler = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isOn)(name);3665 if (!isComponent &&3666 isEventHandler &&3667 // omit the flag for click handlers because hydration gives click3668 // dedicated fast path.3669 name.toLowerCase() !== 'onclick' &&3670 // omit v-model handlers3671 name !== 'onUpdate:modelValue' &&3672 // omit onVnodeXXX hooks3673 !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isReservedProp)(name)) {3674 hasHydrationEventBinding = true;3675 }3676 if (isEventHandler && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isReservedProp)(name)) {3677 hasVnodeHook = true;3678 }3679 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||3680 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||3681 value.type === 8 /* COMPOUND_EXPRESSION */) &&3682 getConstantType(value, context) > 0)) {3683 // skip if the prop is a cached handler or has constant value3684 return;3685 }3686 if (name === 'ref') {3687 hasRef = true;3688 }3689 else if (name === 'class' && !isComponent) {3690 hasClassBinding = true;3691 }3692 else if (name === 'style' && !isComponent) {3693 hasStyleBinding = true;3694 }3695 else if (name !== 'key' && !dynamicPropNames.includes(name)) {3696 dynamicPropNames.push(name);3697 }3698 }3699 else {3700 hasDynamicKeys = true;3701 }3702 };3703 for (let i = 0; i < props.length; i++) {3704 // static attribute3705 const prop = props[i];3706 if (prop.type === 6 /* ATTRIBUTE */) {3707 const { loc, name, value } = prop;3708 let isStatic = true;3709 if (name === 'ref') {3710 hasRef = true;3711 }3712 // skip is on <component>, or is="vue:xxx"3713 if (name === 'is' &&3714 (isComponentTag(tag) ||3715 (value && value.content.startsWith('vue:')) ||3716 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {3717 continue;3718 }3719 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));3720 }3721 else {3722 // directives3723 const { name, arg, exp, loc } = prop;3724 const isVBind = name === 'bind';3725 const isVOn = name === 'on';3726 // skip v-slot - it is handled by its dedicated transform.3727 if (name === 'slot') {3728 if (!isComponent) {3729 context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));3730 }3731 continue;3732 }3733 // skip v-once - it is handled by its dedicated transform.3734 if (name === 'once') {3735 continue;3736 }3737 // skip v-is and :is on <component>3738 if (name === 'is' ||3739 (isVBind &&3740 isBindKey(arg, 'is') &&3741 (isComponentTag(tag) ||3742 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {3743 continue;3744 }3745 // skip v-on in SSR compilation3746 if (isVOn && ssr) {3747 continue;3748 }3749 // special case for v-bind and v-on with no argument3750 if (!arg && (isVBind || isVOn)) {3751 hasDynamicKeys = true;3752 if (exp) {3753 if (properties.length) {3754 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));3755 properties = [];3756 }3757 if (isVBind) {3758 {3759 // 2.x v-bind object order compat3760 if ((true)) {3761 const hasOverridableKeys = mergeArgs.some(arg => {3762 if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {3763 return arg.properties.some(({ key }) => {3764 if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||3765 !key.isStatic) {3766 return true;3767 }3768 return (key.content !== 'class' &&3769 key.content !== 'style' &&3770 !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isOn)(key.content));3771 });3772 }3773 else {3774 // dynamic expression3775 return true;3776 }3777 });3778 if (hasOverridableKeys) {3779 checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);3780 }3781 }3782 if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {3783 mergeArgs.unshift(exp);3784 continue;3785 }3786 }3787 mergeArgs.push(exp);3788 }3789 else {3790 // v-on="obj" -> toHandlers(obj)3791 mergeArgs.push({3792 type: 14 /* JS_CALL_EXPRESSION */,3793 loc,3794 callee: context.helper(TO_HANDLERS),3795 arguments: [exp]3796 });3797 }3798 }3799 else {3800 context.onError(createCompilerError(isVBind3801 ? 33 /* X_V_BIND_NO_EXPRESSION */3802 : 34 /* X_V_ON_NO_EXPRESSION */, loc));3803 }3804 continue;3805 }3806 const directiveTransform = context.directiveTransforms[name];3807 if (directiveTransform) {3808 // has built-in directive transform.3809 const { props, needRuntime } = directiveTransform(prop, node, context);3810 !ssr && props.forEach(analyzePatchFlag);3811 properties.push(...props);3812 if (needRuntime) {3813 runtimeDirectives.push(prop);3814 if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(needRuntime)) {3815 directiveImportMap.set(prop, needRuntime);3816 }3817 }3818 }3819 else {3820 // no built-in transform, this is a user custom directive.3821 runtimeDirectives.push(prop);3822 }3823 }3824 if (prop.type === 6 /* ATTRIBUTE */ &&3825 prop.name === 'ref' &&3826 context.scopes.vFor > 0 &&3827 checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {3828 properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));3829 }3830 }3831 let propsExpression = undefined;3832 // has v-bind="object" or v-on="object", wrap with mergeProps3833 if (mergeArgs.length) {3834 if (properties.length) {3835 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));3836 }3837 if (mergeArgs.length > 1) {3838 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);3839 }3840 else {3841 // single v-bind with nothing else - no need for a mergeProps call...
dep-56143c31.js
Source:dep-56143c31.js
...1426 // in v3 mode, only enable if explicitly set to true1427 // otherwise enable for any non-false value1428 return mode === 3 ? value === true : value !== false;1429}1430function checkCompatEnabled(key, context, loc, ...args) {1431 const enabled = isCompatEnabled(key, context);1432 if ((process.env.NODE_ENV !== 'production') && enabled) {1433 warnDeprecation(key, context, loc, ...args);1434 }1435 return enabled;1436}1437function warnDeprecation(key, context, loc, ...args) {1438 const val = getCompatValue(key, context);1439 if (val === 'suppress-warning') {1440 return;1441 }1442 const { message, link } = deprecationData[key];1443 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;1444 const err = new SyntaxError(msg);1445 err.code = key;1446 if (loc)1447 err.loc = loc;1448 context.onWarn(err);1449}1450// The default decoder only provides escapes for characters reserved as part of1451// the template syntax, and is only used if the custom renderer did not provide1452// a platform-specific decoder.1453const decodeRE = /&(gt|lt|amp|apos|quot);/g;1454const decodeMap = {1455 gt: '>',1456 lt: '<',1457 amp: '&',1458 apos: "'",1459 quot: '"'1460};1461const defaultParserOptions = {1462 delimiters: [`{{`, `}}`],1463 getNamespace: () => 0 /* HTML */,1464 getTextMode: () => 0 /* DATA */,1465 isVoidTag: NO,1466 isPreTag: NO,1467 isCustomElement: NO,1468 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),1469 onError: defaultOnError,1470 onWarn: defaultOnWarn,1471 comments: (process.env.NODE_ENV !== 'production')1472};1473function baseParse(content, options = {}) {1474 const context = createParserContext(content, options);1475 const start = getCursor(context);1476 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));1477}1478function createParserContext(content, rawOptions) {1479 const options = extend({}, defaultParserOptions);1480 let key;1481 for (key in rawOptions) {1482 // @ts-ignore1483 options[key] =1484 rawOptions[key] === undefined1485 ? defaultParserOptions[key]1486 : rawOptions[key];1487 }1488 return {1489 options,1490 column: 1,1491 line: 1,1492 offset: 0,1493 originalSource: content,1494 source: content,1495 inPre: false,1496 inVPre: false,1497 onWarn: options.onWarn1498 };1499}1500function parseChildren(context, mode, ancestors) {1501 const parent = last(ancestors);1502 const ns = parent ? parent.ns : 0 /* HTML */;1503 const nodes = [];1504 while (!isEnd(context, mode, ancestors)) {1505 const s = context.source;1506 let node = undefined;1507 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {1508 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {1509 // '{{'1510 node = parseInterpolation(context, mode);1511 }1512 else if (mode === 0 /* DATA */ && s[0] === '<') {1513 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state1514 if (s.length === 1) {1515 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);1516 }1517 else if (s[1] === '!') {1518 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state1519 if (startsWith(s, '<!--')) {1520 node = parseComment(context);1521 }1522 else if (startsWith(s, '<!DOCTYPE')) {1523 // Ignore DOCTYPE by a limitation.1524 node = parseBogusComment(context);1525 }1526 else if (startsWith(s, '<![CDATA[')) {1527 if (ns !== 0 /* HTML */) {1528 node = parseCDATA(context, ancestors);1529 }1530 else {1531 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);1532 node = parseBogusComment(context);1533 }1534 }1535 else {1536 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);1537 node = parseBogusComment(context);1538 }1539 }1540 else if (s[1] === '/') {1541 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state1542 if (s.length === 2) {1543 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);1544 }1545 else if (s[2] === '>') {1546 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);1547 advanceBy(context, 3);1548 continue;1549 }1550 else if (/[a-z]/i.test(s[2])) {1551 emitError(context, 23 /* X_INVALID_END_TAG */);1552 parseTag(context, 1 /* End */, parent);1553 continue;1554 }1555 else {1556 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);1557 node = parseBogusComment(context);1558 }1559 }1560 else if (/[a-z]/i.test(s[1])) {1561 node = parseElement(context, ancestors);1562 // 2.x <template> with no directive compat1563 if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&1564 node &&1565 node.tag === 'template' &&1566 !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&1567 isSpecialTemplateDirective(p.name))) {1568 (process.env.NODE_ENV !== 'production') &&1569 warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);1570 node = node.children;1571 }1572 }1573 else if (s[1] === '?') {1574 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);1575 node = parseBogusComment(context);1576 }1577 else {1578 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);1579 }1580 }1581 }1582 if (!node) {1583 node = parseText(context, mode);1584 }1585 if (isArray(node)) {1586 for (let i = 0; i < node.length; i++) {1587 pushNode(nodes, node[i]);1588 }1589 }1590 else {1591 pushNode(nodes, node);1592 }1593 }1594 // Whitespace handling strategy like v21595 let removedWhitespace = false;1596 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {1597 const shouldCondense = context.options.whitespace !== 'preserve';1598 for (let i = 0; i < nodes.length; i++) {1599 const node = nodes[i];1600 if (!context.inPre && node.type === 2 /* TEXT */) {1601 if (!/[^\t\r\n\f ]/.test(node.content)) {1602 const prev = nodes[i - 1];1603 const next = nodes[i + 1];1604 // Remove if:1605 // - the whitespace is the first or last node, or:1606 // - (condense mode) the whitespace is adjacent to a comment, or:1607 // - (condense mode) the whitespace is between two elements AND contains newline1608 if (!prev ||1609 !next ||1610 (shouldCondense &&1611 (prev.type === 3 /* COMMENT */ ||1612 next.type === 3 /* COMMENT */ ||1613 (prev.type === 1 /* ELEMENT */ &&1614 next.type === 1 /* ELEMENT */ &&1615 /[\r\n]/.test(node.content))))) {1616 removedWhitespace = true;1617 nodes[i] = null;1618 }1619 else {1620 // Otherwise, the whitespace is condensed into a single space1621 node.content = ' ';1622 }1623 }1624 else if (shouldCondense) {1625 // in condense mode, consecutive whitespaces in text are condensed1626 // down to a single space.1627 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1628 }1629 }1630 // Remove comment nodes if desired by configuration.1631 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {1632 removedWhitespace = true;1633 nodes[i] = null;1634 }1635 }1636 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1637 // remove leading newline per html spec1638 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1639 const first = nodes[0];1640 if (first && first.type === 2 /* TEXT */) {1641 first.content = first.content.replace(/^\r?\n/, '');1642 }1643 }1644 }1645 return removedWhitespace ? nodes.filter(Boolean) : nodes;1646}1647function pushNode(nodes, node) {1648 if (node.type === 2 /* TEXT */) {1649 const prev = last(nodes);1650 // Merge if both this and the previous node are text and those are1651 // consecutive. This happens for cases like "a < b".1652 if (prev &&1653 prev.type === 2 /* TEXT */ &&1654 prev.loc.end.offset === node.loc.start.offset) {1655 prev.content += node.content;1656 prev.loc.end = node.loc.end;1657 prev.loc.source += node.loc.source;1658 return;1659 }1660 }1661 nodes.push(node);1662}1663function parseCDATA(context, ancestors) {1664 advanceBy(context, 9);1665 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1666 if (context.source.length === 0) {1667 emitError(context, 6 /* EOF_IN_CDATA */);1668 }1669 else {1670 advanceBy(context, 3);1671 }1672 return nodes;1673}1674function parseComment(context) {1675 const start = getCursor(context);1676 let content;1677 // Regular comment.1678 const match = /--(\!)?>/.exec(context.source);1679 if (!match) {1680 content = context.source.slice(4);1681 advanceBy(context, context.source.length);1682 emitError(context, 7 /* EOF_IN_COMMENT */);1683 }1684 else {1685 if (match.index <= 3) {1686 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1687 }1688 if (match[1]) {1689 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1690 }1691 content = context.source.slice(4, match.index);1692 // Advancing with reporting nested comments.1693 const s = context.source.slice(0, match.index);1694 let prevIndex = 1, nestedIndex = 0;1695 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1696 advanceBy(context, nestedIndex - prevIndex + 1);1697 if (nestedIndex + 4 < s.length) {1698 emitError(context, 16 /* NESTED_COMMENT */);1699 }1700 prevIndex = nestedIndex + 1;1701 }1702 advanceBy(context, match.index + match[0].length - prevIndex + 1);1703 }1704 return {1705 type: 3 /* COMMENT */,1706 content,1707 loc: getSelection(context, start)1708 };1709}1710function parseBogusComment(context) {1711 const start = getCursor(context);1712 const contentStart = context.source[1] === '?' ? 1 : 2;1713 let content;1714 const closeIndex = context.source.indexOf('>');1715 if (closeIndex === -1) {1716 content = context.source.slice(contentStart);1717 advanceBy(context, context.source.length);1718 }1719 else {1720 content = context.source.slice(contentStart, closeIndex);1721 advanceBy(context, closeIndex + 1);1722 }1723 return {1724 type: 3 /* COMMENT */,1725 content,1726 loc: getSelection(context, start)1727 };1728}1729function parseElement(context, ancestors) {1730 // Start tag.1731 const wasInPre = context.inPre;1732 const wasInVPre = context.inVPre;1733 const parent = last(ancestors);1734 const element = parseTag(context, 0 /* Start */, parent);1735 const isPreBoundary = context.inPre && !wasInPre;1736 const isVPreBoundary = context.inVPre && !wasInVPre;1737 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1738 // #4030 self-closing <pre> tag1739 if (isPreBoundary) {1740 context.inPre = false;1741 }1742 if (isVPreBoundary) {1743 context.inVPre = false;1744 }1745 return element;1746 }1747 // Children.1748 ancestors.push(element);1749 const mode = context.options.getTextMode(element, parent);1750 const children = parseChildren(context, mode, ancestors);1751 ancestors.pop();1752 // 2.x inline-template compat1753 {1754 const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1755 if (inlineTemplateProp &&1756 checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1757 const loc = getSelection(context, element.loc.end);1758 inlineTemplateProp.value = {1759 type: 2 /* TEXT */,1760 content: loc.source,1761 loc1762 };1763 }1764 }1765 element.children = children;1766 // End tag.1767 if (startsWithEndTagOpen(context.source, element.tag)) {1768 parseTag(context, 1 /* End */, parent);1769 }1770 else {1771 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1772 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1773 const first = children[0];1774 if (first && startsWith(first.loc.source, '<!--')) {1775 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1776 }1777 }1778 }1779 element.loc = getSelection(context, element.loc.start);1780 if (isPreBoundary) {1781 context.inPre = false;1782 }1783 if (isVPreBoundary) {1784 context.inVPre = false;1785 }1786 return element;1787}1788const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);1789function parseTag(context, type, parent) {1790 // Tag open.1791 const start = getCursor(context);1792 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1793 const tag = match[1];1794 const ns = context.options.getNamespace(tag, parent);1795 advanceBy(context, match[0].length);1796 advanceSpaces(context);1797 // save current state in case we need to re-parse attributes with v-pre1798 const cursor = getCursor(context);1799 const currentSource = context.source;1800 // check <pre> tag1801 if (context.options.isPreTag(tag)) {1802 context.inPre = true;1803 }1804 // Attributes.1805 let props = parseAttributes(context, type);1806 // check v-pre1807 if (type === 0 /* Start */ &&1808 !context.inVPre &&1809 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1810 context.inVPre = true;1811 // reset context1812 extend(context, cursor);1813 context.source = currentSource;1814 // re-parse attrs and filter out v-pre itself1815 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1816 }1817 // Tag close.1818 let isSelfClosing = false;1819 if (context.source.length === 0) {1820 emitError(context, 9 /* EOF_IN_TAG */);1821 }1822 else {1823 isSelfClosing = startsWith(context.source, '/>');1824 if (type === 1 /* End */ && isSelfClosing) {1825 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1826 }1827 advanceBy(context, isSelfClosing ? 2 : 1);1828 }1829 if (type === 1 /* End */) {1830 return;1831 }1832 // 2.x deprecation checks1833 if ((process.env.NODE_ENV !== 'production') &&1834 isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1835 let hasIf = false;1836 let hasFor = false;1837 for (let i = 0; i < props.length; i++) {1838 const p = props[i];1839 if (p.type === 7 /* DIRECTIVE */) {1840 if (p.name === 'if') {1841 hasIf = true;1842 }1843 else if (p.name === 'for') {1844 hasFor = true;1845 }1846 }1847 if (hasIf && hasFor) {1848 warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1849 break;1850 }1851 }1852 }1853 let tagType = 0 /* ELEMENT */;1854 if (!context.inVPre) {1855 if (tag === 'slot') {1856 tagType = 2 /* SLOT */;1857 }1858 else if (tag === 'template') {1859 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1860 tagType = 3 /* TEMPLATE */;1861 }1862 }1863 else if (isComponent(tag, props, context)) {1864 tagType = 1 /* COMPONENT */;1865 }1866 }1867 return {1868 type: 1 /* ELEMENT */,1869 ns,1870 tag,1871 tagType,1872 props,1873 isSelfClosing,1874 children: [],1875 loc: getSelection(context, start),1876 codegenNode: undefined // to be created during transform phase1877 };1878}1879function isComponent(tag, props, context) {1880 const options = context.options;1881 if (options.isCustomElement(tag)) {1882 return false;1883 }1884 if (tag === 'component' ||1885 /^[A-Z]/.test(tag) ||1886 isCoreComponent(tag) ||1887 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1888 (options.isNativeTag && !options.isNativeTag(tag))) {1889 return true;1890 }1891 // at this point the tag should be a native tag, but check for potential "is"1892 // casting1893 for (let i = 0; i < props.length; i++) {1894 const p = props[i];1895 if (p.type === 6 /* ATTRIBUTE */) {1896 if (p.name === 'is' && p.value) {1897 if (p.value.content.startsWith('vue:')) {1898 return true;1899 }1900 else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1901 return true;1902 }1903 }1904 }1905 else {1906 // directive1907 // v-is (TODO Deprecate)1908 if (p.name === 'is') {1909 return true;1910 }1911 else if (1912 // :is on plain element - only treat as component in compat mode1913 p.name === 'bind' &&1914 isStaticArgOf(p.arg, 'is') &&1915 true &&1916 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1917 return true;1918 }1919 }1920 }1921}1922function parseAttributes(context, type) {1923 const props = [];1924 const attributeNames = new Set();1925 while (context.source.length > 0 &&1926 !startsWith(context.source, '>') &&1927 !startsWith(context.source, '/>')) {1928 if (startsWith(context.source, '/')) {1929 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1930 advanceBy(context, 1);1931 advanceSpaces(context);1932 continue;1933 }1934 if (type === 1 /* End */) {1935 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1936 }1937 const attr = parseAttribute(context, attributeNames);1938 // Trim whitespace between class1939 // https://github.com/vuejs/core/issues/42511940 if (attr.type === 6 /* ATTRIBUTE */ &&1941 attr.value &&1942 attr.name === 'class') {1943 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1944 }1945 if (type === 0 /* Start */) {1946 props.push(attr);1947 }1948 if (/^[^\t\r\n\f />]/.test(context.source)) {1949 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1950 }1951 advanceSpaces(context);1952 }1953 return props;1954}1955function parseAttribute(context, nameSet) {1956 // Name.1957 const start = getCursor(context);1958 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1959 const name = match[0];1960 if (nameSet.has(name)) {1961 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1962 }1963 nameSet.add(name);1964 if (name[0] === '=') {1965 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1966 }1967 {1968 const pattern = /["'<]/g;1969 let m;1970 while ((m = pattern.exec(name))) {1971 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1972 }1973 }1974 advanceBy(context, name.length);1975 // Value1976 let value = undefined;1977 if (/^[\t\r\n\f ]*=/.test(context.source)) {1978 advanceSpaces(context);1979 advanceBy(context, 1);1980 advanceSpaces(context);1981 value = parseAttributeValue(context);1982 if (!value) {1983 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1984 }1985 }1986 const loc = getSelection(context, start);1987 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1988 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1989 let isPropShorthand = startsWith(name, '.');1990 let dirName = match[1] ||1991 (isPropShorthand || startsWith(name, ':')1992 ? 'bind'1993 : startsWith(name, '@')1994 ? 'on'1995 : 'slot');1996 let arg;1997 if (match[2]) {1998 const isSlot = dirName === 'slot';1999 const startOffset = name.lastIndexOf(match[2]);2000 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));2001 let content = match[2];2002 let isStatic = true;2003 if (content.startsWith('[')) {2004 isStatic = false;2005 if (!content.endsWith(']')) {2006 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);2007 content = content.slice(1);2008 }2009 else {2010 content = content.slice(1, content.length - 1);2011 }2012 }2013 else if (isSlot) {2014 // #1241 special case for v-slot: vuetify relies extensively on slot2015 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x2016 // supports such usage so we are keeping it consistent with 2.x.2017 content += match[3] || '';2018 }2019 arg = {2020 type: 4 /* SIMPLE_EXPRESSION */,2021 content,2022 isStatic,2023 constType: isStatic2024 ? 3 /* CAN_STRINGIFY */2025 : 0 /* NOT_CONSTANT */,2026 loc2027 };2028 }2029 if (value && value.isQuoted) {2030 const valueLoc = value.loc;2031 valueLoc.start.offset++;2032 valueLoc.start.column++;2033 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);2034 valueLoc.source = valueLoc.source.slice(1, -1);2035 }2036 const modifiers = match[3] ? match[3].slice(1).split('.') : [];2037 if (isPropShorthand)2038 modifiers.push('prop');2039 // 2.x compat v-bind:foo.sync -> v-model:foo2040 if (dirName === 'bind' && arg) {2041 if (modifiers.includes('sync') &&2042 checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {2043 dirName = 'model';2044 modifiers.splice(modifiers.indexOf('sync'), 1);2045 }2046 if ((process.env.NODE_ENV !== 'production') && modifiers.includes('prop')) {2047 checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);2048 }2049 }2050 return {2051 type: 7 /* DIRECTIVE */,2052 name: dirName,2053 exp: value && {2054 type: 4 /* SIMPLE_EXPRESSION */,2055 content: value.content,2056 isStatic: false,2057 // Treat as non-constant by default. This can be potentially set to2058 // other values by `transformExpression` to make it eligible for hoisting.2059 constType: 0 /* NOT_CONSTANT */,2060 loc: value.loc2061 },2062 arg,2063 modifiers,2064 loc2065 };2066 }2067 // missing directive name or illegal directive name2068 if (!context.inVPre && startsWith(name, 'v-')) {2069 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);2070 }2071 return {2072 type: 6 /* ATTRIBUTE */,2073 name,2074 value: value && {2075 type: 2 /* TEXT */,2076 content: value.content,2077 loc: value.loc2078 },2079 loc2080 };2081}2082function parseAttributeValue(context) {2083 const start = getCursor(context);2084 let content;2085 const quote = context.source[0];2086 const isQuoted = quote === `"` || quote === `'`;2087 if (isQuoted) {2088 // Quoted value.2089 advanceBy(context, 1);2090 const endIndex = context.source.indexOf(quote);2091 if (endIndex === -1) {2092 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);2093 }2094 else {2095 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);2096 advanceBy(context, 1);2097 }2098 }2099 else {2100 // Unquoted2101 const match = /^[^\t\r\n\f >]+/.exec(context.source);2102 if (!match) {2103 return undefined;2104 }2105 const unexpectedChars = /["'<=`]/g;2106 let m;2107 while ((m = unexpectedChars.exec(match[0]))) {2108 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);2109 }2110 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);2111 }2112 return { content, isQuoted, loc: getSelection(context, start) };2113}2114function parseInterpolation(context, mode) {2115 const [open, close] = context.options.delimiters;2116 const closeIndex = context.source.indexOf(close, open.length);2117 if (closeIndex === -1) {2118 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);2119 return undefined;2120 }2121 const start = getCursor(context);2122 advanceBy(context, open.length);2123 const innerStart = getCursor(context);2124 const innerEnd = getCursor(context);2125 const rawContentLength = closeIndex - open.length;2126 const rawContent = context.source.slice(0, rawContentLength);2127 const preTrimContent = parseTextData(context, rawContentLength, mode);2128 const content = preTrimContent.trim();2129 const startOffset = preTrimContent.indexOf(content);2130 if (startOffset > 0) {2131 advancePositionWithMutation(innerStart, rawContent, startOffset);2132 }2133 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);2134 advancePositionWithMutation(innerEnd, rawContent, endOffset);2135 advanceBy(context, close.length);2136 return {2137 type: 5 /* INTERPOLATION */,2138 content: {2139 type: 4 /* SIMPLE_EXPRESSION */,2140 isStatic: false,2141 // Set `isConstant` to false by default and will decide in transformExpression2142 constType: 0 /* NOT_CONSTANT */,2143 content,2144 loc: getSelection(context, innerStart, innerEnd)2145 },2146 loc: getSelection(context, start)2147 };2148}2149function parseText(context, mode) {2150 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];2151 let endIndex = context.source.length;2152 for (let i = 0; i < endTokens.length; i++) {2153 const index = context.source.indexOf(endTokens[i], 1);2154 if (index !== -1 && endIndex > index) {2155 endIndex = index;2156 }2157 }2158 const start = getCursor(context);2159 const content = parseTextData(context, endIndex, mode);2160 return {2161 type: 2 /* TEXT */,2162 content,2163 loc: getSelection(context, start)2164 };2165}2166/**2167 * Get text data with a given length from the current location.2168 * This translates HTML entities in the text data.2169 */2170function parseTextData(context, length, mode) {2171 const rawText = context.source.slice(0, length);2172 advanceBy(context, length);2173 if (mode === 2 /* RAWTEXT */ ||2174 mode === 3 /* CDATA */ ||2175 !rawText.includes('&')) {2176 return rawText;2177 }2178 else {2179 // DATA or RCDATA containing "&"". Entity decoding required.2180 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);2181 }2182}2183function getCursor(context) {2184 const { column, line, offset } = context;2185 return { column, line, offset };2186}2187function getSelection(context, start, end) {2188 end = end || getCursor(context);2189 return {2190 start,2191 end,2192 source: context.originalSource.slice(start.offset, end.offset)2193 };2194}2195function last(xs) {2196 return xs[xs.length - 1];2197}2198function startsWith(source, searchString) {2199 return source.startsWith(searchString);2200}2201function advanceBy(context, numberOfCharacters) {2202 const { source } = context;2203 advancePositionWithMutation(context, source, numberOfCharacters);2204 context.source = source.slice(numberOfCharacters);2205}2206function advanceSpaces(context) {2207 const match = /^[\t\r\n\f ]+/.exec(context.source);2208 if (match) {2209 advanceBy(context, match[0].length);2210 }2211}2212function getNewPosition(context, start, numberOfCharacters) {2213 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);2214}2215function emitError(context, code, offset, loc = getCursor(context)) {2216 if (offset) {2217 loc.offset += offset;2218 loc.column += offset;2219 }2220 context.options.onError(createCompilerError(code, {2221 start: loc,2222 end: loc,2223 source: ''2224 }));2225}2226function isEnd(context, mode, ancestors) {2227 const s = context.source;2228 switch (mode) {2229 case 0 /* DATA */:2230 if (startsWith(s, '</')) {2231 // TODO: probably bad performance2232 for (let i = ancestors.length - 1; i >= 0; --i) {2233 if (startsWithEndTagOpen(s, ancestors[i].tag)) {2234 return true;2235 }2236 }2237 }2238 break;2239 case 1 /* RCDATA */:2240 case 2 /* RAWTEXT */: {2241 const parent = last(ancestors);2242 if (parent && startsWithEndTagOpen(s, parent.tag)) {2243 return true;2244 }2245 break;2246 }2247 case 3 /* CDATA */:2248 if (startsWith(s, ']]>')) {2249 return true;2250 }2251 break;2252 }2253 return !s;2254}2255function startsWithEndTagOpen(source, tag) {2256 return (startsWith(source, '</') &&2257 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&2258 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));2259}2260function hoistStatic(root, context) {2261 walk(root, context, 2262 // Root node is unfortunately non-hoistable due to potential parent2263 // fallthrough attributes.2264 isSingleElementRoot(root, root.children[0]));2265}2266function isSingleElementRoot(root, child) {2267 const { children } = root;2268 return (children.length === 1 &&2269 child.type === 1 /* ELEMENT */ &&2270 !isSlotOutlet(child));2271}2272function walk(node, context, doNotHoistNode = false) {2273 const { children } = node;2274 const originalCount = children.length;2275 let hoistedCount = 0;2276 for (let i = 0; i < children.length; i++) {2277 const child = children[i];2278 // only plain elements & text calls are eligible for hoisting.2279 if (child.type === 1 /* ELEMENT */ &&2280 child.tagType === 0 /* ELEMENT */) {2281 const constantType = doNotHoistNode2282 ? 0 /* NOT_CONSTANT */2283 : getConstantType(child, context);2284 if (constantType > 0 /* NOT_CONSTANT */) {2285 if (constantType >= 2 /* CAN_HOIST */) {2286 child.codegenNode.patchFlag =2287 -1 /* HOISTED */ + ((process.env.NODE_ENV !== 'production') ? ` /* HOISTED */` : ``);2288 child.codegenNode = context.hoist(child.codegenNode);2289 hoistedCount++;2290 continue;2291 }2292 }2293 else {2294 // node may contain dynamic children, but its props may be eligible for2295 // hoisting.2296 const codegenNode = child.codegenNode;2297 if (codegenNode.type === 13 /* VNODE_CALL */) {2298 const flag = getPatchFlag(codegenNode);2299 if ((!flag ||2300 flag === 512 /* NEED_PATCH */ ||2301 flag === 1 /* TEXT */) &&2302 getGeneratedPropsConstantType(child, context) >=2303 2 /* CAN_HOIST */) {2304 const props = getNodeProps(child);2305 if (props) {2306 codegenNode.props = context.hoist(props);2307 }2308 }2309 if (codegenNode.dynamicProps) {2310 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);2311 }2312 }2313 }2314 }2315 else if (child.type === 12 /* TEXT_CALL */ &&2316 getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {2317 child.codegenNode = context.hoist(child.codegenNode);2318 hoistedCount++;2319 }2320 // walk further2321 if (child.type === 1 /* ELEMENT */) {2322 const isComponent = child.tagType === 1 /* COMPONENT */;2323 if (isComponent) {2324 context.scopes.vSlot++;2325 }2326 walk(child, context);2327 if (isComponent) {2328 context.scopes.vSlot--;2329 }2330 }2331 else if (child.type === 11 /* FOR */) {2332 // Do not hoist v-for single child because it has to be a block2333 walk(child, context, child.children.length === 1);2334 }2335 else if (child.type === 9 /* IF */) {2336 for (let i = 0; i < child.branches.length; i++) {2337 // Do not hoist v-if single child because it has to be a block2338 walk(child.branches[i], context, child.branches[i].children.length === 1);2339 }2340 }2341 }2342 if (hoistedCount && context.transformHoist) {2343 context.transformHoist(children, context, node);2344 }2345 // all children were hoisted - the entire children array is hoistable.2346 if (hoistedCount &&2347 hoistedCount === originalCount &&2348 node.type === 1 /* ELEMENT */ &&2349 node.tagType === 0 /* ELEMENT */ &&2350 node.codegenNode &&2351 node.codegenNode.type === 13 /* VNODE_CALL */ &&2352 isArray(node.codegenNode.children)) {2353 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));2354 }2355}2356function getConstantType(node, context) {2357 const { constantCache } = context;2358 switch (node.type) {2359 case 1 /* ELEMENT */:2360 if (node.tagType !== 0 /* ELEMENT */) {2361 return 0 /* NOT_CONSTANT */;2362 }2363 const cached = constantCache.get(node);2364 if (cached !== undefined) {2365 return cached;2366 }2367 const codegenNode = node.codegenNode;2368 if (codegenNode.type !== 13 /* VNODE_CALL */) {2369 return 0 /* NOT_CONSTANT */;2370 }2371 if (codegenNode.isBlock &&2372 node.tag !== 'svg' &&2373 node.tag !== 'foreignObject') {2374 return 0 /* NOT_CONSTANT */;2375 }2376 const flag = getPatchFlag(codegenNode);2377 if (!flag) {2378 let returnType = 3 /* CAN_STRINGIFY */;2379 // Element itself has no patch flag. However we still need to check:2380 // 1. Even for a node with no patch flag, it is possible for it to contain2381 // non-hoistable expressions that refers to scope variables, e.g. compiler2382 // injected keys or cached event handlers. Therefore we need to always2383 // check the codegenNode's props to be sure.2384 const generatedPropsType = getGeneratedPropsConstantType(node, context);2385 if (generatedPropsType === 0 /* NOT_CONSTANT */) {2386 constantCache.set(node, 0 /* NOT_CONSTANT */);2387 return 0 /* NOT_CONSTANT */;2388 }2389 if (generatedPropsType < returnType) {2390 returnType = generatedPropsType;2391 }2392 // 2. its children.2393 for (let i = 0; i < node.children.length; i++) {2394 const childType = getConstantType(node.children[i], context);2395 if (childType === 0 /* NOT_CONSTANT */) {2396 constantCache.set(node, 0 /* NOT_CONSTANT */);2397 return 0 /* NOT_CONSTANT */;2398 }2399 if (childType < returnType) {2400 returnType = childType;2401 }2402 }2403 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-02404 // type, check if any of the props can cause the type to be lowered2405 // we can skip can_patch because it's guaranteed by the absence of a2406 // patchFlag.2407 if (returnType > 1 /* CAN_SKIP_PATCH */) {2408 for (let i = 0; i < node.props.length; i++) {2409 const p = node.props[i];2410 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {2411 const expType = getConstantType(p.exp, context);2412 if (expType === 0 /* NOT_CONSTANT */) {2413 constantCache.set(node, 0 /* NOT_CONSTANT */);2414 return 0 /* NOT_CONSTANT */;2415 }2416 if (expType < returnType) {2417 returnType = expType;2418 }2419 }2420 }2421 }2422 // only svg/foreignObject could be block here, however if they are2423 // static then they don't need to be blocks since there will be no2424 // nested updates.2425 if (codegenNode.isBlock) {2426 context.removeHelper(OPEN_BLOCK);2427 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));2428 codegenNode.isBlock = false;2429 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));2430 }2431 constantCache.set(node, returnType);2432 return returnType;2433 }2434 else {2435 constantCache.set(node, 0 /* NOT_CONSTANT */);2436 return 0 /* NOT_CONSTANT */;2437 }2438 case 2 /* TEXT */:2439 case 3 /* COMMENT */:2440 return 3 /* CAN_STRINGIFY */;2441 case 9 /* IF */:2442 case 11 /* FOR */:2443 case 10 /* IF_BRANCH */:2444 return 0 /* NOT_CONSTANT */;2445 case 5 /* INTERPOLATION */:2446 case 12 /* TEXT_CALL */:2447 return getConstantType(node.content, context);2448 case 4 /* SIMPLE_EXPRESSION */:2449 return node.constType;2450 case 8 /* COMPOUND_EXPRESSION */:2451 let returnType = 3 /* CAN_STRINGIFY */;2452 for (let i = 0; i < node.children.length; i++) {2453 const child = node.children[i];2454 if (isString(child) || isSymbol(child)) {2455 continue;2456 }2457 const childType = getConstantType(child, context);2458 if (childType === 0 /* NOT_CONSTANT */) {2459 return 0 /* NOT_CONSTANT */;2460 }2461 else if (childType < returnType) {2462 returnType = childType;2463 }2464 }2465 return returnType;2466 default:2467 if ((process.env.NODE_ENV !== 'production')) ;2468 return 0 /* NOT_CONSTANT */;2469 }2470}2471const allowHoistedHelperSet = new Set([2472 NORMALIZE_CLASS,2473 NORMALIZE_STYLE,2474 NORMALIZE_PROPS,2475 GUARD_REACTIVE_PROPS2476]);2477function getConstantTypeOfHelperCall(value, context) {2478 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&2479 !isString(value.callee) &&2480 allowHoistedHelperSet.has(value.callee)) {2481 const arg = value.arguments[0];2482 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {2483 return getConstantType(arg, context);2484 }2485 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {2486 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`2487 return getConstantTypeOfHelperCall(arg, context);2488 }2489 }2490 return 0 /* NOT_CONSTANT */;2491}2492function getGeneratedPropsConstantType(node, context) {2493 let returnType = 3 /* CAN_STRINGIFY */;2494 const props = getNodeProps(node);2495 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {2496 const { properties } = props;2497 for (let i = 0; i < properties.length; i++) {2498 const { key, value } = properties[i];2499 const keyType = getConstantType(key, context);2500 if (keyType === 0 /* NOT_CONSTANT */) {2501 return keyType;2502 }2503 if (keyType < returnType) {2504 returnType = keyType;2505 }2506 let valueType;2507 if (value.type === 4 /* SIMPLE_EXPRESSION */) {2508 valueType = getConstantType(value, context);2509 }2510 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {2511 // some helper calls can be hoisted,2512 // such as the `normalizeProps` generated by the compiler for pre-normalize class,2513 // in this case we need to respect the ConstantType of the helper's arguments2514 valueType = getConstantTypeOfHelperCall(value, context);2515 }2516 else {2517 valueType = 0 /* NOT_CONSTANT */;2518 }2519 if (valueType === 0 /* NOT_CONSTANT */) {2520 return valueType;2521 }2522 if (valueType < returnType) {2523 returnType = valueType;2524 }2525 }2526 }2527 return returnType;2528}2529function getNodeProps(node) {2530 const codegenNode = node.codegenNode;2531 if (codegenNode.type === 13 /* VNODE_CALL */) {2532 return codegenNode.props;2533 }2534}2535function getPatchFlag(node) {2536 const flag = node.patchFlag;2537 return flag ? parseInt(flag, 10) : undefined;2538}2539function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {2540 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);2541 const context = {2542 // options2543 selfName: nameMatch && capitalize(camelize$1(nameMatch[1])),2544 prefixIdentifiers,2545 hoistStatic,2546 cacheHandlers,2547 nodeTransforms,2548 directiveTransforms,2549 transformHoist,2550 isBuiltInComponent,2551 isCustomElement,2552 expressionPlugins,2553 scopeId,2554 slotted,2555 ssr,2556 inSSR,2557 ssrCssVars,2558 bindingMetadata,2559 inline,2560 isTS,2561 onError,2562 onWarn,2563 compatConfig,2564 // state2565 root,2566 helpers: new Map(),2567 components: new Set(),2568 directives: new Set(),2569 hoists: [],2570 imports: [],2571 constantCache: new Map(),2572 temps: 0,2573 cached: 0,2574 identifiers: Object.create(null),2575 scopes: {2576 vFor: 0,2577 vSlot: 0,2578 vPre: 0,2579 vOnce: 02580 },2581 parent: null,2582 currentNode: root,2583 childIndex: 0,2584 inVOnce: false,2585 // methods2586 helper(name) {2587 const count = context.helpers.get(name) || 0;2588 context.helpers.set(name, count + 1);2589 return name;2590 },2591 removeHelper(name) {2592 const count = context.helpers.get(name);2593 if (count) {2594 const currentCount = count - 1;2595 if (!currentCount) {2596 context.helpers.delete(name);2597 }2598 else {2599 context.helpers.set(name, currentCount);2600 }2601 }2602 },2603 helperString(name) {2604 return `_${helperNameMap[context.helper(name)]}`;2605 },2606 replaceNode(node) {2607 /* istanbul ignore if */2608 if ((process.env.NODE_ENV !== 'production')) {2609 if (!context.currentNode) {2610 throw new Error(`Node being replaced is already removed.`);2611 }2612 if (!context.parent) {2613 throw new Error(`Cannot replace root node.`);2614 }2615 }2616 context.parent.children[context.childIndex] = context.currentNode = node;2617 },2618 removeNode(node) {2619 if ((process.env.NODE_ENV !== 'production') && !context.parent) {2620 throw new Error(`Cannot remove root node.`);2621 }2622 const list = context.parent.children;2623 const removalIndex = node2624 ? list.indexOf(node)2625 : context.currentNode2626 ? context.childIndex2627 : -1;2628 /* istanbul ignore if */2629 if ((process.env.NODE_ENV !== 'production') && removalIndex < 0) {2630 throw new Error(`node being removed is not a child of current parent`);2631 }2632 if (!node || node === context.currentNode) {2633 // current node removed2634 context.currentNode = null;2635 context.onNodeRemoved();2636 }2637 else {2638 // sibling node removed2639 if (context.childIndex > removalIndex) {2640 context.childIndex--;2641 context.onNodeRemoved();2642 }2643 }2644 context.parent.children.splice(removalIndex, 1);2645 },2646 onNodeRemoved: () => { },2647 addIdentifiers(exp) {2648 },2649 removeIdentifiers(exp) {2650 },2651 hoist(exp) {2652 if (isString(exp))2653 exp = createSimpleExpression(exp);2654 context.hoists.push(exp);2655 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2656 identifier.hoisted = exp;2657 return identifier;2658 },2659 cache(exp, isVNode = false) {2660 return createCacheExpression(context.cached++, exp, isVNode);2661 }2662 };2663 {2664 context.filters = new Set();2665 }2666 return context;2667}2668function transform(root, options) {2669 const context = createTransformContext(root, options);2670 traverseNode(root, context);2671 if (options.hoistStatic) {2672 hoistStatic(root, context);2673 }2674 if (!options.ssr) {2675 createRootCodegen(root, context);2676 }2677 // finalize meta information2678 root.helpers = [...context.helpers.keys()];2679 root.components = [...context.components];2680 root.directives = [...context.directives];2681 root.imports = context.imports;2682 root.hoists = context.hoists;2683 root.temps = context.temps;2684 root.cached = context.cached;2685 {2686 root.filters = [...context.filters];2687 }2688}2689function createRootCodegen(root, context) {2690 const { helper } = context;2691 const { children } = root;2692 if (children.length === 1) {2693 const child = children[0];2694 // if the single child is an element, turn it into a block.2695 if (isSingleElementRoot(root, child) && child.codegenNode) {2696 // single element root is never hoisted so codegenNode will never be2697 // SimpleExpressionNode2698 const codegenNode = child.codegenNode;2699 if (codegenNode.type === 13 /* VNODE_CALL */) {2700 makeBlock(codegenNode, context);2701 }2702 root.codegenNode = codegenNode;2703 }2704 else {2705 // - single <slot/>, IfNode, ForNode: already blocks.2706 // - single text node: always patched.2707 // root codegen falls through via genNode()2708 root.codegenNode = child;2709 }2710 }2711 else if (children.length > 1) {2712 // root has multiple nodes - return a fragment block.2713 let patchFlag = 64 /* STABLE_FRAGMENT */;2714 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];2715 // check if the fragment actually contains a single valid child with2716 // the rest being comments2717 if ((process.env.NODE_ENV !== 'production') &&2718 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2719 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2720 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2721 }2722 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, undefined, false /* isComponent */);2723 }2724 else ;2725}2726function traverseChildren(parent, context) {2727 let i = 0;2728 const nodeRemoved = () => {2729 i--;2730 };2731 for (; i < parent.children.length; i++) {2732 const child = parent.children[i];2733 if (isString(child))2734 continue;2735 context.parent = parent;2736 context.childIndex = i;2737 context.onNodeRemoved = nodeRemoved;2738 traverseNode(child, context);2739 }2740}2741function traverseNode(node, context) {2742 context.currentNode = node;2743 // apply transform plugins2744 const { nodeTransforms } = context;2745 const exitFns = [];2746 for (let i = 0; i < nodeTransforms.length; i++) {2747 const onExit = nodeTransforms[i](node, context);2748 if (onExit) {2749 if (isArray(onExit)) {2750 exitFns.push(...onExit);2751 }2752 else {2753 exitFns.push(onExit);2754 }2755 }2756 if (!context.currentNode) {2757 // node was removed2758 return;2759 }2760 else {2761 // node may have been replaced2762 node = context.currentNode;2763 }2764 }2765 switch (node.type) {2766 case 3 /* COMMENT */:2767 if (!context.ssr) {2768 // inject import for the Comment symbol, which is needed for creating2769 // comment nodes with `createVNode`2770 context.helper(CREATE_COMMENT);2771 }2772 break;2773 case 5 /* INTERPOLATION */:2774 // no need to traverse, but we need to inject toString helper2775 if (!context.ssr) {2776 context.helper(TO_DISPLAY_STRING);2777 }2778 break;2779 // for container types, further traverse downwards2780 case 9 /* IF */:2781 for (let i = 0; i < node.branches.length; i++) {2782 traverseNode(node.branches[i], context);2783 }2784 break;2785 case 10 /* IF_BRANCH */:2786 case 11 /* FOR */:2787 case 1 /* ELEMENT */:2788 case 0 /* ROOT */:2789 traverseChildren(node, context);2790 break;2791 }2792 // exit transforms2793 context.currentNode = node;2794 let i = exitFns.length;2795 while (i--) {2796 exitFns[i]();2797 }2798}2799function createStructuralDirectiveTransform(name, fn) {2800 const matches = isString(name)2801 ? (n) => n === name2802 : (n) => name.test(n);2803 return (node, context) => {2804 if (node.type === 1 /* ELEMENT */) {2805 const { props } = node;2806 // structural directive transforms are not concerned with slots2807 // as they are handled separately in vSlot.ts2808 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2809 return;2810 }2811 const exitFns = [];2812 for (let i = 0; i < props.length; i++) {2813 const prop = props[i];2814 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2815 // structural directives are removed to avoid infinite recursion2816 // also we remove them *before* applying so that it can further2817 // traverse itself in case it moves the node around2818 props.splice(i, 1);2819 i--;2820 const onExit = fn(node, prop, context);2821 if (onExit)2822 exitFns.push(onExit);2823 }2824 }2825 return exitFns;2826 }2827 };2828}2829const PURE_ANNOTATION = `/*#__PURE__*/`;2830function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {2831 const context = {2832 mode,2833 prefixIdentifiers,2834 sourceMap,2835 filename,2836 scopeId,2837 optimizeImports,2838 runtimeGlobalName,2839 runtimeModuleName,2840 ssrRuntimeModuleName,2841 ssr,2842 isTS,2843 inSSR,2844 source: ast.loc.source,2845 code: ``,2846 column: 1,2847 line: 1,2848 offset: 0,2849 indentLevel: 0,2850 pure: false,2851 map: undefined,2852 helper(key) {2853 return `_${helperNameMap[key]}`;2854 },2855 push(code, node) {2856 context.code += code;2857 },2858 indent() {2859 newline(++context.indentLevel);2860 },2861 deindent(withoutNewLine = false) {2862 if (withoutNewLine) {2863 --context.indentLevel;2864 }2865 else {2866 newline(--context.indentLevel);2867 }2868 },2869 newline() {2870 newline(context.indentLevel);2871 }2872 };2873 function newline(n) {2874 context.push('\n' + ` `.repeat(n));2875 }2876 return context;2877}2878function generate(ast, options = {}) {2879 const context = createCodegenContext(ast, options);2880 if (options.onContextCreated)2881 options.onContextCreated(context);2882 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2883 const hasHelpers = ast.helpers.length > 0;2884 const useWithBlock = !prefixIdentifiers && mode !== 'module';2885 // preambles2886 // in setup() inline mode, the preamble is generated in a sub context2887 // and returned separately.2888 const preambleContext = context;2889 {2890 genFunctionPreamble(ast, preambleContext);2891 }2892 // enter render function2893 const functionName = ssr ? `ssrRender` : `render`;2894 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2895 const signature = args.join(', ');2896 {2897 push(`function ${functionName}(${signature}) {`);2898 }2899 indent();2900 if (useWithBlock) {2901 push(`with (_ctx) {`);2902 indent();2903 // function mode const declarations should be inside with block2904 // also they should be renamed to avoid collision with user properties2905 if (hasHelpers) {2906 push(`const { ${ast.helpers2907 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2908 .join(', ')} } = _Vue`);2909 push(`\n`);2910 newline();2911 }2912 }2913 // generate asset resolution statements2914 if (ast.components.length) {2915 genAssets(ast.components, 'component', context);2916 if (ast.directives.length || ast.temps > 0) {2917 newline();2918 }2919 }2920 if (ast.directives.length) {2921 genAssets(ast.directives, 'directive', context);2922 if (ast.temps > 0) {2923 newline();2924 }2925 }2926 if (ast.filters && ast.filters.length) {2927 newline();2928 genAssets(ast.filters, 'filter', context);2929 newline();2930 }2931 if (ast.temps > 0) {2932 push(`let `);2933 for (let i = 0; i < ast.temps; i++) {2934 push(`${i > 0 ? `, ` : ``}_temp${i}`);2935 }2936 }2937 if (ast.components.length || ast.directives.length || ast.temps) {2938 push(`\n`);2939 newline();2940 }2941 // generate the VNode tree expression2942 if (!ssr) {2943 push(`return `);2944 }2945 if (ast.codegenNode) {2946 genNode(ast.codegenNode, context);2947 }2948 else {2949 push(`null`);2950 }2951 if (useWithBlock) {2952 deindent();2953 push(`}`);2954 }2955 deindent();2956 push(`}`);2957 return {2958 ast,2959 code: context.code,2960 preamble: ``,2961 // SourceMapGenerator does have toJSON() method but it's not in the types2962 map: context.map ? context.map.toJSON() : undefined2963 };2964}2965function genFunctionPreamble(ast, context) {2966 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2967 const VueBinding = runtimeGlobalName;2968 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2969 // Generate const declaration for helpers2970 // In prefix mode, we place the const declaration at top so it's done2971 // only once; But if we not prefixing, we place the declaration inside the2972 // with block so it doesn't incur the `in` check cost for every helper access.2973 if (ast.helpers.length > 0) {2974 {2975 // "with" mode.2976 // save Vue in a separate variable to avoid collision2977 push(`const _Vue = ${VueBinding}\n`);2978 // in "with" mode, helpers are declared inside the with block to avoid2979 // has check cost, but hoists are lifted out of the function - we need2980 // to provide the helper here.2981 if (ast.hoists.length) {2982 const staticHelpers = [2983 CREATE_VNODE,2984 CREATE_ELEMENT_VNODE,2985 CREATE_COMMENT,2986 CREATE_TEXT,2987 CREATE_STATIC2988 ]2989 .filter(helper => ast.helpers.includes(helper))2990 .map(aliasHelper)2991 .join(', ');2992 push(`const { ${staticHelpers} } = _Vue\n`);2993 }2994 }2995 }2996 genHoists(ast.hoists, context);2997 newline();2998 push(`return `);2999}3000function genAssets(assets, type, { helper, push, newline, isTS }) {3001 const resolver = helper(type === 'filter'3002 ? RESOLVE_FILTER3003 : type === 'component'3004 ? RESOLVE_COMPONENT3005 : RESOLVE_DIRECTIVE);3006 for (let i = 0; i < assets.length; i++) {3007 let id = assets[i];3008 // potential component implicit self-reference inferred from SFC filename3009 const maybeSelfReference = id.endsWith('__self');3010 if (maybeSelfReference) {3011 id = id.slice(0, -6);3012 }3013 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);3014 if (i < assets.length - 1) {3015 newline();3016 }3017 }3018}3019function genHoists(hoists, context) {3020 if (!hoists.length) {3021 return;3022 }3023 context.pure = true;3024 const { push, newline, helper, scopeId, mode } = context;3025 newline();3026 for (let i = 0; i < hoists.length; i++) {3027 const exp = hoists[i];3028 if (exp) {3029 push(`const _hoisted_${i + 1} = ${``}`);3030 genNode(exp, context);3031 newline();3032 }3033 }3034 context.pure = false;3035}3036function isText$1(n) {3037 return (isString(n) ||3038 n.type === 4 /* SIMPLE_EXPRESSION */ ||3039 n.type === 2 /* TEXT */ ||3040 n.type === 5 /* INTERPOLATION */ ||3041 n.type === 8 /* COMPOUND_EXPRESSION */);3042}3043function genNodeListAsArray(nodes, context) {3044 const multilines = nodes.length > 3 ||3045 (((process.env.NODE_ENV !== 'production')) && nodes.some(n => isArray(n) || !isText$1(n)));3046 context.push(`[`);3047 multilines && context.indent();3048 genNodeList(nodes, context, multilines);3049 multilines && context.deindent();3050 context.push(`]`);3051}3052function genNodeList(nodes, context, multilines = false, comma = true) {3053 const { push, newline } = context;3054 for (let i = 0; i < nodes.length; i++) {3055 const node = nodes[i];3056 if (isString(node)) {3057 push(node);3058 }3059 else if (isArray(node)) {3060 genNodeListAsArray(node, context);3061 }3062 else {3063 genNode(node, context);3064 }3065 if (i < nodes.length - 1) {3066 if (multilines) {3067 comma && push(',');3068 newline();3069 }3070 else {3071 comma && push(', ');3072 }3073 }3074 }3075}3076function genNode(node, context) {3077 if (isString(node)) {3078 context.push(node);3079 return;3080 }3081 if (isSymbol(node)) {3082 context.push(context.helper(node));3083 return;3084 }3085 switch (node.type) {3086 case 1 /* ELEMENT */:3087 case 9 /* IF */:3088 case 11 /* FOR */:3089 (process.env.NODE_ENV !== 'production') &&3090 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +3091 `Apply appropriate transforms first.`);3092 genNode(node.codegenNode, context);3093 break;3094 case 2 /* TEXT */:3095 genText(node, context);3096 break;3097 case 4 /* SIMPLE_EXPRESSION */:3098 genExpression(node, context);3099 break;3100 case 5 /* INTERPOLATION */:3101 genInterpolation(node, context);3102 break;3103 case 12 /* TEXT_CALL */:3104 genNode(node.codegenNode, context);3105 break;3106 case 8 /* COMPOUND_EXPRESSION */:3107 genCompoundExpression(node, context);3108 break;3109 case 3 /* COMMENT */:3110 genComment(node, context);3111 break;3112 case 13 /* VNODE_CALL */:3113 genVNodeCall(node, context);3114 break;3115 case 14 /* JS_CALL_EXPRESSION */:3116 genCallExpression(node, context);3117 break;3118 case 15 /* JS_OBJECT_EXPRESSION */:3119 genObjectExpression(node, context);3120 break;3121 case 17 /* JS_ARRAY_EXPRESSION */:3122 genArrayExpression(node, context);3123 break;3124 case 18 /* JS_FUNCTION_EXPRESSION */:3125 genFunctionExpression(node, context);3126 break;3127 case 19 /* JS_CONDITIONAL_EXPRESSION */:3128 genConditionalExpression(node, context);3129 break;3130 case 20 /* JS_CACHE_EXPRESSION */:3131 genCacheExpression(node, context);3132 break;3133 case 21 /* JS_BLOCK_STATEMENT */:3134 genNodeList(node.body, context, true, false);3135 break;3136 // SSR only types3137 case 22 /* JS_TEMPLATE_LITERAL */:3138 break;3139 case 23 /* JS_IF_STATEMENT */:3140 break;3141 case 24 /* JS_ASSIGNMENT_EXPRESSION */:3142 break;3143 case 25 /* JS_SEQUENCE_EXPRESSION */:3144 break;3145 case 26 /* JS_RETURN_STATEMENT */:3146 break;3147 /* istanbul ignore next */3148 case 10 /* IF_BRANCH */:3149 // noop3150 break;3151 default:3152 if ((process.env.NODE_ENV !== 'production')) {3153 assert(false, `unhandled codegen node type: ${node.type}`);3154 // make sure we exhaust all possible types3155 const exhaustiveCheck = node;3156 return exhaustiveCheck;3157 }3158 }3159}3160function genText(node, context) {3161 context.push(JSON.stringify(node.content), node);3162}3163function genExpression(node, context) {3164 const { content, isStatic } = node;3165 context.push(isStatic ? JSON.stringify(content) : content, node);3166}3167function genInterpolation(node, context) {3168 const { push, helper, pure } = context;3169 if (pure)3170 push(PURE_ANNOTATION);3171 push(`${helper(TO_DISPLAY_STRING)}(`);3172 genNode(node.content, context);3173 push(`)`);3174}3175function genCompoundExpression(node, context) {3176 for (let i = 0; i < node.children.length; i++) {3177 const child = node.children[i];3178 if (isString(child)) {3179 context.push(child);3180 }3181 else {3182 genNode(child, context);3183 }3184 }3185}3186function genExpressionAsPropertyKey(node, context) {3187 const { push } = context;3188 if (node.type === 8 /* COMPOUND_EXPRESSION */) {3189 push(`[`);3190 genCompoundExpression(node, context);3191 push(`]`);3192 }3193 else if (node.isStatic) {3194 // only quote keys if necessary3195 const text = isSimpleIdentifier(node.content)3196 ? node.content3197 : JSON.stringify(node.content);3198 push(text, node);3199 }3200 else {3201 push(`[${node.content}]`, node);3202 }3203}3204function genComment(node, context) {3205 const { push, helper, pure } = context;3206 if (pure) {3207 push(PURE_ANNOTATION);3208 }3209 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);3210}3211function genVNodeCall(node, context) {3212 const { push, helper, pure } = context;3213 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;3214 if (directives) {3215 push(helper(WITH_DIRECTIVES) + `(`);3216 }3217 if (isBlock) {3218 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);3219 }3220 if (pure) {3221 push(PURE_ANNOTATION);3222 }3223 const callHelper = isBlock3224 ? getVNodeBlockHelper(context.inSSR, isComponent)3225 : getVNodeHelper(context.inSSR, isComponent);3226 push(helper(callHelper) + `(`, node);3227 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);3228 push(`)`);3229 if (isBlock) {3230 push(`)`);3231 }3232 if (directives) {3233 push(`, `);3234 genNode(directives, context);3235 push(`)`);3236 }3237}3238function genNullableArgs(args) {3239 let i = args.length;3240 while (i--) {3241 if (args[i] != null)3242 break;3243 }3244 return args.slice(0, i + 1).map(arg => arg || `null`);3245}3246// JavaScript3247function genCallExpression(node, context) {3248 const { push, helper, pure } = context;3249 const callee = isString(node.callee) ? node.callee : helper(node.callee);3250 if (pure) {3251 push(PURE_ANNOTATION);3252 }3253 push(callee + `(`, node);3254 genNodeList(node.arguments, context);3255 push(`)`);3256}3257function genObjectExpression(node, context) {3258 const { push, indent, deindent, newline } = context;3259 const { properties } = node;3260 if (!properties.length) {3261 push(`{}`, node);3262 return;3263 }3264 const multilines = properties.length > 1 ||3265 (((process.env.NODE_ENV !== 'production')) &&3266 properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));3267 push(multilines ? `{` : `{ `);3268 multilines && indent();3269 for (let i = 0; i < properties.length; i++) {3270 const { key, value } = properties[i];3271 // key3272 genExpressionAsPropertyKey(key, context);3273 push(`: `);3274 // value3275 genNode(value, context);3276 if (i < properties.length - 1) {3277 // will only reach this if it's multilines3278 push(`,`);3279 newline();3280 }3281 }3282 multilines && deindent();3283 push(multilines ? `}` : ` }`);3284}3285function genArrayExpression(node, context) {3286 genNodeListAsArray(node.elements, context);3287}3288function genFunctionExpression(node, context) {3289 const { push, indent, deindent } = context;3290 const { params, returns, body, newline, isSlot } = node;3291 if (isSlot) {3292 // wrap slot functions with owner context3293 push(`_${helperNameMap[WITH_CTX]}(`);3294 }3295 push(`(`, node);3296 if (isArray(params)) {3297 genNodeList(params, context);3298 }3299 else if (params) {3300 genNode(params, context);3301 }3302 push(`) => `);3303 if (newline || body) {3304 push(`{`);3305 indent();3306 }3307 if (returns) {3308 if (newline) {3309 push(`return `);3310 }3311 if (isArray(returns)) {3312 genNodeListAsArray(returns, context);3313 }3314 else {3315 genNode(returns, context);3316 }3317 }3318 else if (body) {3319 genNode(body, context);3320 }3321 if (newline || body) {3322 deindent();3323 push(`}`);3324 }3325 if (isSlot) {3326 if (node.isNonScopedSlot) {3327 push(`, undefined, true`);3328 }3329 push(`)`);3330 }3331}3332function genConditionalExpression(node, context) {3333 const { test, consequent, alternate, newline: needNewline } = node;3334 const { push, indent, deindent, newline } = context;3335 if (test.type === 4 /* SIMPLE_EXPRESSION */) {3336 const needsParens = !isSimpleIdentifier(test.content);3337 needsParens && push(`(`);3338 genExpression(test, context);3339 needsParens && push(`)`);3340 }3341 else {3342 push(`(`);3343 genNode(test, context);3344 push(`)`);3345 }3346 needNewline && indent();3347 context.indentLevel++;3348 needNewline || push(` `);3349 push(`? `);3350 genNode(consequent, context);3351 context.indentLevel--;3352 needNewline && newline();3353 needNewline || push(` `);3354 push(`: `);3355 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;3356 if (!isNested) {3357 context.indentLevel++;3358 }3359 genNode(alternate, context);3360 if (!isNested) {3361 context.indentLevel--;3362 }3363 needNewline && deindent(true /* without newline */);3364}3365function genCacheExpression(node, context) {3366 const { push, helper, indent, deindent, newline } = context;3367 push(`_cache[${node.index}] || (`);3368 if (node.isVNode) {3369 indent();3370 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);3371 newline();3372 }3373 push(`_cache[${node.index}] = `);3374 genNode(node.value, context);3375 if (node.isVNode) {3376 push(`,`);3377 newline();3378 push(`${helper(SET_BLOCK_TRACKING)}(1),`);3379 newline();3380 push(`_cache[${node.index}]`);3381 deindent();3382 }3383 push(`)`);3384}3385function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {3386 {3387 return;3388 }3389}3390function isReferencedIdentifier(id, parent, parentStack) {3391 {3392 return false;3393 }3394}3395function isInDestructureAssignment(parent, parentStack) {3396 if (parent &&3397 (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {3398 let i = parentStack.length;3399 while (i--) {3400 const p = parentStack[i];3401 if (p.type === 'AssignmentExpression') {3402 return true;3403 }3404 else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {3405 break;3406 }3407 }3408 }3409 return false;3410}3411function walkFunctionParams(node, onIdent) {3412 for (const p of node.params) {3413 for (const id of extractIdentifiers(p)) {3414 onIdent(id);3415 }3416 }3417}3418function walkBlockDeclarations(block, onIdent) {3419 for (const stmt of block.body) {3420 if (stmt.type === 'VariableDeclaration') {3421 if (stmt.declare)3422 continue;3423 for (const decl of stmt.declarations) {3424 for (const id of extractIdentifiers(decl.id)) {3425 onIdent(id);3426 }3427 }3428 }3429 else if (stmt.type === 'FunctionDeclaration' ||3430 stmt.type === 'ClassDeclaration') {3431 if (stmt.declare || !stmt.id)3432 continue;3433 onIdent(stmt.id);3434 }3435 }3436}3437function extractIdentifiers(param, nodes = []) {3438 switch (param.type) {3439 case 'Identifier':3440 nodes.push(param);3441 break;3442 case 'MemberExpression':3443 let object = param;3444 while (object.type === 'MemberExpression') {3445 object = object.object;3446 }3447 nodes.push(object);3448 break;3449 case 'ObjectPattern':3450 for (const prop of param.properties) {3451 if (prop.type === 'RestElement') {3452 extractIdentifiers(prop.argument, nodes);3453 }3454 else {3455 extractIdentifiers(prop.value, nodes);3456 }3457 }3458 break;3459 case 'ArrayPattern':3460 param.elements.forEach(element => {3461 if (element)3462 extractIdentifiers(element, nodes);3463 });3464 break;3465 case 'RestElement':3466 extractIdentifiers(param.argument, nodes);3467 break;3468 case 'AssignmentPattern':3469 extractIdentifiers(param.left, nodes);3470 break;3471 }3472 return nodes;3473}3474const isFunctionType = (node) => {3475 return /Function(?:Expression|Declaration)$|Method$/.test(node.type);3476};3477const isStaticProperty = (node) => node &&3478 (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&3479 !node.computed;3480const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;3481// these keywords should not appear inside expressions, but operators like3482// typeof, instanceof and in are allowed3483const prohibitedKeywordRE = new RegExp('\\b' +3484 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +3485 'super,throw,while,yield,delete,export,import,return,switch,default,' +3486 'extends,finally,continue,debugger,function,arguments,typeof,void')3487 .split(',')3488 .join('\\b|\\b') +3489 '\\b');3490// strip strings in expressions3491const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;3492/**3493 * Validate a non-prefixed expression.3494 * This is only called when using the in-browser runtime compiler since it3495 * doesn't prefix expressions.3496 */3497function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {3498 const exp = node.content;3499 // empty expressions are validated per-directive since some directives3500 // do allow empty expressions.3501 if (!exp.trim()) {3502 return;3503 }3504 try {3505 new Function(asRawStatements3506 ? ` ${exp} `3507 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);3508 }3509 catch (e) {3510 let message = e.message;3511 const keywordMatch = exp3512 .replace(stripStringRE, '')3513 .match(prohibitedKeywordRE);3514 if (keywordMatch) {3515 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;3516 }3517 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));3518 }3519}3520const transformExpression = (node, context) => {3521 if (node.type === 5 /* INTERPOLATION */) {3522 node.content = processExpression(node.content, context);3523 }3524 else if (node.type === 1 /* ELEMENT */) {3525 // handle directives on element3526 for (let i = 0; i < node.props.length; i++) {3527 const dir = node.props[i];3528 // do not process for v-on & v-for since they are special handled3529 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3530 const exp = dir.exp;3531 const arg = dir.arg;3532 // do not process exp if this is v-on:arg - we need special handling3533 // for wrapping inline statements.3534 if (exp &&3535 exp.type === 4 /* SIMPLE_EXPRESSION */ &&3536 !(dir.name === 'on' && arg)) {3537 dir.exp = processExpression(exp, context, 3538 // slot args must be processed as function params3539 dir.name === 'slot');3540 }3541 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3542 dir.arg = processExpression(arg, context);3543 }3544 }3545 }3546 }3547};3548// Important: since this function uses Node.js only dependencies, it should3549// always be used with a leading !true check so that it can be3550// tree-shaken from the browser build.3551function processExpression(node, context, 3552// some expressions like v-slot props & v-for aliases should be parsed as3553// function params3554asParams = false, 3555// v-on handler values may contain multiple statements3556asRawStatements = false, localVars = Object.create(context.identifiers)) {3557 {3558 if ((process.env.NODE_ENV !== 'production')) {3559 // simple in-browser validation (same logic in 2.x)3560 validateBrowserExpression(node, context, asParams, asRawStatements);3561 }3562 return node;3563 }3564}3565const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3566 return processIf(node, dir, context, (ifNode, branch, isRoot) => {3567 // #1587: We need to dynamically increment the key based on the current3568 // node's sibling nodes, since chained v-if/else branches are3569 // rendered at the same depth3570 const siblings = context.parent.children;3571 let i = siblings.indexOf(ifNode);3572 let key = 0;3573 while (i-- >= 0) {3574 const sibling = siblings[i];3575 if (sibling && sibling.type === 9 /* IF */) {3576 key += sibling.branches.length;3577 }3578 }3579 // Exit callback. Complete the codegenNode when all children have been3580 // transformed.3581 return () => {3582 if (isRoot) {3583 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3584 }3585 else {3586 // attach this branch's codegen node to the v-if root.3587 const parentCondition = getParentCondition(ifNode.codegenNode);3588 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3589 }3590 };3591 });3592});3593// target-agnostic transform used for both Client and SSR3594function processIf(node, dir, context, processCodegen) {3595 if (dir.name !== 'else' &&3596 (!dir.exp || !dir.exp.content.trim())) {3597 const loc = dir.exp ? dir.exp.loc : node.loc;3598 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3599 dir.exp = createSimpleExpression(`true`, false, loc);3600 }3601 if ((process.env.NODE_ENV !== 'production') && true && dir.exp) {3602 validateBrowserExpression(dir.exp, context);3603 }3604 if (dir.name === 'if') {3605 const branch = createIfBranch(node, dir);3606 const ifNode = {3607 type: 9 /* IF */,3608 loc: node.loc,3609 branches: [branch]3610 };3611 context.replaceNode(ifNode);3612 if (processCodegen) {3613 return processCodegen(ifNode, branch, true);3614 }3615 }3616 else {3617 // locate the adjacent v-if3618 const siblings = context.parent.children;3619 const comments = [];3620 let i = siblings.indexOf(node);3621 while (i-- >= -1) {3622 const sibling = siblings[i];3623 if ((process.env.NODE_ENV !== 'production') && sibling && sibling.type === 3 /* COMMENT */) {3624 context.removeNode(sibling);3625 comments.unshift(sibling);3626 continue;3627 }3628 if (sibling &&3629 sibling.type === 2 /* TEXT */ &&3630 !sibling.content.trim().length) {3631 context.removeNode(sibling);3632 continue;3633 }3634 if (sibling && sibling.type === 9 /* IF */) {3635 // Check if v-else was followed by v-else-if3636 if (dir.name === 'else-if' &&3637 sibling.branches[sibling.branches.length - 1].condition === undefined) {3638 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3639 }3640 // move the node to the if node's branches3641 context.removeNode();3642 const branch = createIfBranch(node, dir);3643 if ((process.env.NODE_ENV !== 'production') &&3644 comments.length &&3645 // #3619 ignore comments if the v-if is direct child of <transition>3646 !(context.parent &&3647 context.parent.type === 1 /* ELEMENT */ &&3648 isBuiltInType(context.parent.tag, 'transition'))) {3649 branch.children = [...comments, ...branch.children];3650 }3651 // check if user is forcing same key on different branches3652 if ((process.env.NODE_ENV !== 'production') || !true) {3653 const key = branch.userKey;3654 if (key) {3655 sibling.branches.forEach(({ userKey }) => {3656 if (isSameKey(userKey, key)) {3657 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3658 }3659 });3660 }3661 }3662 sibling.branches.push(branch);3663 const onExit = processCodegen && processCodegen(sibling, branch, false);3664 // since the branch was removed, it will not be traversed.3665 // make sure to traverse here.3666 traverseNode(branch, context);3667 // call on exit3668 if (onExit)3669 onExit();3670 // make sure to reset currentNode after traversal to indicate this3671 // node has been removed.3672 context.currentNode = null;3673 }3674 else {3675 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3676 }3677 break;3678 }3679 }3680}3681function createIfBranch(node, dir) {3682 return {3683 type: 10 /* IF_BRANCH */,3684 loc: node.loc,3685 condition: dir.name === 'else' ? undefined : dir.exp,3686 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3687 ? node.children3688 : [node],3689 userKey: findProp(node, `key`)3690 };3691}3692function createCodegenNodeForBranch(branch, keyIndex, context) {3693 if (branch.condition) {3694 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3695 // make sure to pass in asBlock: true so that the comment node call3696 // closes the current block.3697 createCallExpression(context.helper(CREATE_COMMENT), [3698 (process.env.NODE_ENV !== 'production') ? '"v-if"' : '""',3699 'true'3700 ]));3701 }3702 else {3703 return createChildrenCodegenNode(branch, keyIndex, context);3704 }3705}3706function createChildrenCodegenNode(branch, keyIndex, context) {3707 const { helper } = context;3708 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3709 const { children } = branch;3710 const firstChild = children[0];3711 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3712 if (needFragmentWrapper) {3713 if (children.length === 1 && firstChild.type === 11 /* FOR */) {3714 // optimize away nested fragments when child is a ForNode3715 const vnodeCall = firstChild.codegenNode;3716 injectProp(vnodeCall, keyProperty, context);3717 return vnodeCall;3718 }3719 else {3720 let patchFlag = 64 /* STABLE_FRAGMENT */;3721 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];3722 // check if the fragment actually contains a single valid child with3723 // the rest being comments3724 if ((process.env.NODE_ENV !== 'production') &&3725 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3726 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3727 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3728 }3729 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, false, false /* isComponent */, branch.loc);3730 }3731 }3732 else {3733 const ret = firstChild.codegenNode;3734 const vnodeCall = getMemoedVNodeCall(ret);3735 // Change createVNode to createBlock.3736 if (vnodeCall.type === 13 /* VNODE_CALL */) {3737 makeBlock(vnodeCall, context);3738 }3739 // inject branch key3740 injectProp(vnodeCall, keyProperty, context);3741 return ret;3742 }3743}3744function isSameKey(a, b) {3745 if (!a || a.type !== b.type) {3746 return false;3747 }3748 if (a.type === 6 /* ATTRIBUTE */) {3749 if (a.value.content !== b.value.content) {3750 return false;3751 }3752 }3753 else {3754 // directive3755 const exp = a.exp;3756 const branchExp = b.exp;3757 if (exp.type !== branchExp.type) {3758 return false;3759 }3760 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3761 exp.isStatic !== branchExp.isStatic ||3762 exp.content !== branchExp.content) {3763 return false;3764 }3765 }3766 return true;3767}3768function getParentCondition(node) {3769 while (true) {3770 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3771 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3772 node = node.alternate;3773 }3774 else {3775 return node;3776 }3777 }3778 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3779 node = node.value;3780 }3781 }3782}3783const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3784 const { helper, removeHelper } = context;3785 return processFor(node, dir, context, forNode => {3786 // create the loop render function expression now, and add the3787 // iterator on exit after all children have been traversed3788 const renderExp = createCallExpression(helper(RENDER_LIST), [3789 forNode.source3790 ]);3791 const isTemplate = isTemplateNode(node);3792 const memo = findDir(node, 'memo');3793 const keyProp = findProp(node, `key`);3794 const keyExp = keyProp &&3795 (keyProp.type === 6 /* ATTRIBUTE */3796 ? createSimpleExpression(keyProp.value.content, true)3797 : keyProp.exp);3798 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3799 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3800 forNode.source.constType > 0 /* NOT_CONSTANT */;3801 const fragmentFlag = isStableFragment3802 ? 64 /* STABLE_FRAGMENT */3803 : keyProp3804 ? 128 /* KEYED_FRAGMENT */3805 : 256 /* UNKEYED_FRAGMENT */;3806 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3807 ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[fragmentFlag]} */` : ``), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3808 return () => {3809 // finish the codegen now that all children have been traversed3810 let childBlock;3811 const { children } = forNode;3812 // check <template v-for> key placement3813 if (((process.env.NODE_ENV !== 'production') || !true) && isTemplate) {3814 node.children.some(c => {3815 if (c.type === 1 /* ELEMENT */) {3816 const key = findProp(c, 'key');3817 if (key) {3818 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3819 return true;3820 }3821 }3822 });3823 }3824 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3825 const slotOutlet = isSlotOutlet(node)3826 ? node3827 : isTemplate &&3828 node.children.length === 1 &&3829 isSlotOutlet(node.children[0])3830 ? node.children[0] // api-extractor somehow fails to infer this3831 : null;3832 if (slotOutlet) {3833 // <slot v-for="..."> or <template v-for="..."><slot/></template>3834 childBlock = slotOutlet.codegenNode;3835 if (isTemplate && keyProperty) {3836 // <template v-for="..." :key="..."><slot/></template>3837 // we need to inject the key to the renderSlot() call.3838 // the props for renderSlot is passed as the 3rd argument.3839 injectProp(childBlock, keyProperty, context);3840 }3841 }3842 else if (needFragmentWrapper) {3843 // <template v-for="..."> with text or multi-elements3844 // should generate a fragment block for each loop3845 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3846 ((process.env.NODE_ENV !== 'production')3847 ? ` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3848 : ``), undefined, undefined, true, undefined, false /* isComponent */);3849 }3850 else {3851 // Normal element v-for. Directly use the child's codegenNode3852 // but mark it as a block.3853 childBlock = children[0]3854 .codegenNode;3855 if (isTemplate && keyProperty) {3856 injectProp(childBlock, keyProperty, context);3857 }3858 if (childBlock.isBlock !== !isStableFragment) {3859 if (childBlock.isBlock) {3860 // switch from block to vnode3861 removeHelper(OPEN_BLOCK);3862 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3863 }3864 else {3865 // switch from vnode to block3866 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3867 }3868 }3869 childBlock.isBlock = !isStableFragment;3870 if (childBlock.isBlock) {3871 helper(OPEN_BLOCK);3872 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3873 }3874 else {3875 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3876 }3877 }3878 if (memo) {3879 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3880 createSimpleExpression(`_cached`)3881 ]));3882 loop.body = createBlockStatement([3883 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3884 createCompoundExpression([3885 `if (_cached`,3886 ...(keyExp ? [` && _cached.key === `, keyExp] : []),3887 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3888 ]),3889 createCompoundExpression([`const _item = `, childBlock]),3890 createSimpleExpression(`_item.memo = _memo`),3891 createSimpleExpression(`return _item`)3892 ]);3893 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3894 }3895 else {3896 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3897 }3898 };3899 });3900});3901// target-agnostic transform used for both Client and SSR3902function processFor(node, dir, context, processCodegen) {3903 if (!dir.exp) {3904 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3905 return;3906 }3907 const parseResult = parseForExpression(3908 // can only be simple expression because vFor transform is applied3909 // before expression transform.3910 dir.exp, context);3911 if (!parseResult) {3912 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3913 return;3914 }3915 const { addIdentifiers, removeIdentifiers, scopes } = context;3916 const { source, value, key, index } = parseResult;3917 const forNode = {3918 type: 11 /* FOR */,3919 loc: dir.loc,3920 source,3921 valueAlias: value,3922 keyAlias: key,3923 objectIndexAlias: index,3924 parseResult,3925 children: isTemplateNode(node) ? node.children : [node]3926 };3927 context.replaceNode(forNode);3928 // bookkeeping3929 scopes.vFor++;3930 const onExit = processCodegen && processCodegen(forNode);3931 return () => {3932 scopes.vFor--;3933 if (onExit)3934 onExit();3935 };3936}3937const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3938// This regex doesn't cover the case if key or index aliases have destructuring,3939// but those do not make sense in the first place, so this works in practice.3940const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3941const stripParensRE = /^\(|\)$/g;3942function parseForExpression(input, context) {3943 const loc = input.loc;3944 const exp = input.content;3945 const inMatch = exp.match(forAliasRE);3946 if (!inMatch)3947 return;3948 const [, LHS, RHS] = inMatch;3949 const result = {3950 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3951 value: undefined,3952 key: undefined,3953 index: undefined3954 };3955 if ((process.env.NODE_ENV !== 'production') && true) {3956 validateBrowserExpression(result.source, context);3957 }3958 let valueContent = LHS.trim().replace(stripParensRE, '').trim();3959 const trimmedOffset = LHS.indexOf(valueContent);3960 const iteratorMatch = valueContent.match(forIteratorRE);3961 if (iteratorMatch) {3962 valueContent = valueContent.replace(forIteratorRE, '').trim();3963 const keyContent = iteratorMatch[1].trim();3964 let keyOffset;3965 if (keyContent) {3966 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3967 result.key = createAliasExpression(loc, keyContent, keyOffset);3968 if ((process.env.NODE_ENV !== 'production') && true) {3969 validateBrowserExpression(result.key, context, true);3970 }3971 }3972 if (iteratorMatch[2]) {3973 const indexContent = iteratorMatch[2].trim();3974 if (indexContent) {3975 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3976 ? keyOffset + keyContent.length3977 : trimmedOffset + valueContent.length));3978 if ((process.env.NODE_ENV !== 'production') && true) {3979 validateBrowserExpression(result.index, context, true);3980 }3981 }3982 }3983 }3984 if (valueContent) {3985 result.value = createAliasExpression(loc, valueContent, trimmedOffset);3986 if ((process.env.NODE_ENV !== 'production') && true) {3987 validateBrowserExpression(result.value, context, true);3988 }3989 }3990 return result;3991}3992function createAliasExpression(range, content, offset) {3993 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3994}3995function createForLoopParams({ value, key, index }, memoArgs = []) {3996 return createParamsList([value, key, index, ...memoArgs]);3997}3998function createParamsList(args) {3999 let i = args.length;4000 while (i--) {4001 if (args[i])4002 break;4003 }4004 return args4005 .slice(0, i + 1)4006 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));4007}4008const defaultFallback = createSimpleExpression(`undefined`, false);4009// A NodeTransform that:4010// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed4011// by transformExpression. This is only applied in non-browser builds with4012// { prefixIdentifiers: true }.4013// 2. Track v-slot depths so that we know a slot is inside another slot.4014// Note the exit callback is executed before buildSlots() on the same node,4015// so only nested slots see positive numbers.4016const trackSlotScopes = (node, context) => {4017 if (node.type === 1 /* ELEMENT */ &&4018 (node.tagType === 1 /* COMPONENT */ ||4019 node.tagType === 3 /* TEMPLATE */)) {4020 // We are only checking non-empty v-slot here4021 // since we only care about slots that introduce scope variables.4022 const vSlot = findDir(node, 'slot');4023 if (vSlot) {4024 context.scopes.vSlot++;4025 return () => {4026 context.scopes.vSlot--;4027 };4028 }4029 }4030};4031// A NodeTransform that tracks scope identifiers for scoped slots with v-for.4032// This transform is only applied in non-browser builds with { prefixIdentifiers: true }4033const trackVForSlotScopes = (node, context) => {4034 let vFor;4035 if (isTemplateNode(node) &&4036 node.props.some(isVSlot) &&4037 (vFor = findDir(node, 'for'))) {4038 const result = (vFor.parseResult = parseForExpression(vFor.exp, context));4039 if (result) {4040 const { value, key, index } = result;4041 const { addIdentifiers, removeIdentifiers } = context;4042 value && addIdentifiers(value);4043 key && addIdentifiers(key);4044 index && addIdentifiers(index);4045 return () => {4046 value && removeIdentifiers(value);4047 key && removeIdentifiers(key);4048 index && removeIdentifiers(index);4049 };4050 }4051 }4052};4053const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);4054// Instead of being a DirectiveTransform, v-slot processing is called during4055// transformElement to build the slots object for a component.4056function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {4057 context.helper(WITH_CTX);4058 const { children, loc } = node;4059 const slotsProperties = [];4060 const dynamicSlots = [];4061 // If the slot is inside a v-for or another v-slot, force it to be dynamic4062 // since it likely uses a scope variable.4063 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;4064 // 1. Check for slot with slotProps on component itself.4065 // <Comp v-slot="{ prop }"/>4066 const onComponentSlot = findDir(node, 'slot', true);4067 if (onComponentSlot) {4068 const { arg, exp } = onComponentSlot;4069 if (arg && !isStaticExp(arg)) {4070 hasDynamicSlots = true;4071 }4072 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));4073 }4074 // 2. Iterate through children and check for template slots4075 // <template v-slot:foo="{ prop }">4076 let hasTemplateSlots = false;4077 let hasNamedDefaultSlot = false;4078 const implicitDefaultChildren = [];4079 const seenSlotNames = new Set();4080 for (let i = 0; i < children.length; i++) {4081 const slotElement = children[i];4082 let slotDir;4083 if (!isTemplateNode(slotElement) ||4084 !(slotDir = findDir(slotElement, 'slot', true))) {4085 // not a <template v-slot>, skip.4086 if (slotElement.type !== 3 /* COMMENT */) {4087 implicitDefaultChildren.push(slotElement);4088 }4089 continue;4090 }4091 if (onComponentSlot) {4092 // already has on-component slot - this is incorrect usage.4093 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));4094 break;4095 }4096 hasTemplateSlots = true;4097 const { children: slotChildren, loc: slotLoc } = slotElement;4098 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;4099 // check if name is dynamic.4100 let staticSlotName;4101 if (isStaticExp(slotName)) {4102 staticSlotName = slotName ? slotName.content : `default`;4103 }4104 else {4105 hasDynamicSlots = true;4106 }4107 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);4108 // check if this slot is conditional (v-if/v-for)4109 let vIf;4110 let vElse;4111 let vFor;4112 if ((vIf = findDir(slotElement, 'if'))) {4113 hasDynamicSlots = true;4114 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));4115 }4116 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {4117 // find adjacent v-if4118 let j = i;4119 let prev;4120 while (j--) {4121 prev = children[j];4122 if (prev.type !== 3 /* COMMENT */) {4123 break;4124 }4125 }4126 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {4127 // remove node4128 children.splice(i, 1);4129 i--;4130 // attach this slot to previous conditional4131 let conditional = dynamicSlots[dynamicSlots.length - 1];4132 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {4133 conditional = conditional.alternate;4134 }4135 conditional.alternate = vElse.exp4136 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)4137 : buildDynamicSlot(slotName, slotFunction);4138 }4139 else {4140 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));4141 }4142 }4143 else if ((vFor = findDir(slotElement, 'for'))) {4144 hasDynamicSlots = true;4145 const parseResult = vFor.parseResult ||4146 parseForExpression(vFor.exp, context);4147 if (parseResult) {4148 // Render the dynamic slots as an array and add it to the createSlot()4149 // args. The runtime knows how to handle it appropriately.4150 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [4151 parseResult.source,4152 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)4153 ]));4154 }4155 else {4156 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));4157 }4158 }4159 else {4160 // check duplicate static names4161 if (staticSlotName) {4162 if (seenSlotNames.has(staticSlotName)) {4163 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));4164 continue;4165 }4166 seenSlotNames.add(staticSlotName);4167 if (staticSlotName === 'default') {4168 hasNamedDefaultSlot = true;4169 }4170 }4171 slotsProperties.push(createObjectProperty(slotName, slotFunction));4172 }4173 }4174 if (!onComponentSlot) {4175 const buildDefaultSlotProperty = (props, children) => {4176 const fn = buildSlotFn(props, children, loc);4177 if (context.compatConfig) {4178 fn.isNonScopedSlot = true;4179 }4180 return createObjectProperty(`default`, fn);4181 };4182 if (!hasTemplateSlots) {4183 // implicit default slot (on component)4184 slotsProperties.push(buildDefaultSlotProperty(undefined, children));4185 }4186 else if (implicitDefaultChildren.length &&4187 // #37664188 // with whitespace: 'preserve', whitespaces between slots will end up in4189 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.4190 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {4191 // implicit default slot (mixed with named slots)4192 if (hasNamedDefaultSlot) {4193 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));4194 }4195 else {4196 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));4197 }4198 }4199 }4200 const slotFlag = hasDynamicSlots4201 ? 2 /* DYNAMIC */4202 : hasForwardedSlots(node.children)4203 ? 3 /* FORWARDED */4204 : 1 /* STABLE */;4205 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 4206 // 2 = compiled but dynamic = can skip normalization, but must run diff4207 // 1 = compiled and static = can skip normalization AND diff as optimized4208 createSimpleExpression(slotFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${slotFlagsText[slotFlag]} */` : ``), false))), loc);4209 if (dynamicSlots.length) {4210 slots = createCallExpression(context.helper(CREATE_SLOTS), [4211 slots,4212 createArrayExpression(dynamicSlots)4213 ]);4214 }4215 return {4216 slots,4217 hasDynamicSlots4218 };4219}4220function buildDynamicSlot(name, fn) {4221 return createObjectExpression([4222 createObjectProperty(`name`, name),4223 createObjectProperty(`fn`, fn)4224 ]);4225}4226function hasForwardedSlots(children) {4227 for (let i = 0; i < children.length; i++) {4228 const child = children[i];4229 switch (child.type) {4230 case 1 /* ELEMENT */:4231 if (child.tagType === 2 /* SLOT */ ||4232 hasForwardedSlots(child.children)) {4233 return true;4234 }4235 break;4236 case 9 /* IF */:4237 if (hasForwardedSlots(child.branches))4238 return true;4239 break;4240 case 10 /* IF_BRANCH */:4241 case 11 /* FOR */:4242 if (hasForwardedSlots(child.children))4243 return true;4244 break;4245 }4246 }4247 return false;4248}4249function isNonWhitespaceContent(node) {4250 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)4251 return true;4252 return node.type === 2 /* TEXT */4253 ? !!node.content.trim()4254 : isNonWhitespaceContent(node.content);4255}4256// some directive transforms (e.g. v-model) may return a symbol for runtime4257// import, which should be used instead of a resolveDirective call.4258const directiveImportMap = new WeakMap();4259// generate a JavaScript AST for this element's codegen4260const transformElement = (node, context) => {4261 // perform the work on exit, after all child expressions have been4262 // processed and merged.4263 return function postTransformElement() {4264 node = context.currentNode;4265 if (!(node.type === 1 /* ELEMENT */ &&4266 (node.tagType === 0 /* ELEMENT */ ||4267 node.tagType === 1 /* COMPONENT */))) {4268 return;4269 }4270 const { tag, props } = node;4271 const isComponent = node.tagType === 1 /* COMPONENT */;4272 // The goal of the transform is to create a codegenNode implementing the4273 // VNodeCall interface.4274 let vnodeTag = isComponent4275 ? resolveComponentType(node, context)4276 : `"${tag}"`;4277 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;4278 let vnodeProps;4279 let vnodeChildren;4280 let vnodePatchFlag;4281 let patchFlag = 0;4282 let vnodeDynamicProps;4283 let dynamicPropNames;4284 let vnodeDirectives;4285 let shouldUseBlock = 4286 // dynamic component may resolve to plain elements4287 isDynamicComponent ||4288 vnodeTag === TELEPORT ||4289 vnodeTag === SUSPENSE ||4290 (!isComponent &&4291 // <svg> and <foreignObject> must be forced into blocks so that block4292 // updates inside get proper isSVG flag at runtime. (#639, #643)4293 // This is technically web-specific, but splitting the logic out of core4294 // leads to too much unnecessary complexity.4295 (tag === 'svg' || tag === 'foreignObject'));4296 // props4297 if (props.length > 0) {4298 const propsBuildResult = buildProps(node, context);4299 vnodeProps = propsBuildResult.props;4300 patchFlag = propsBuildResult.patchFlag;4301 dynamicPropNames = propsBuildResult.dynamicPropNames;4302 const directives = propsBuildResult.directives;4303 vnodeDirectives =4304 directives && directives.length4305 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))4306 : undefined;4307 if (propsBuildResult.shouldUseBlock) {4308 shouldUseBlock = true;4309 }4310 }4311 // children4312 if (node.children.length > 0) {4313 if (vnodeTag === KEEP_ALIVE) {4314 // Although a built-in component, we compile KeepAlive with raw children4315 // instead of slot functions so that it can be used inside Transition4316 // or other Transition-wrapping HOCs.4317 // To ensure correct updates with block optimizations, we need to:4318 // 1. Force keep-alive into a block. This avoids its children being4319 // collected by a parent block.4320 shouldUseBlock = true;4321 // 2. Force keep-alive to always be updated, since it uses raw children.4322 patchFlag |= 1024 /* DYNAMIC_SLOTS */;4323 if ((process.env.NODE_ENV !== 'production') && node.children.length > 1) {4324 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {4325 start: node.children[0].loc.start,4326 end: node.children[node.children.length - 1].loc.end,4327 source: ''4328 }));4329 }4330 }4331 const shouldBuildAsSlots = isComponent &&4332 // Teleport is not a real component and has dedicated runtime handling4333 vnodeTag !== TELEPORT &&4334 // explained above.4335 vnodeTag !== KEEP_ALIVE;4336 if (shouldBuildAsSlots) {4337 const { slots, hasDynamicSlots } = buildSlots(node, context);4338 vnodeChildren = slots;4339 if (hasDynamicSlots) {4340 patchFlag |= 1024 /* DYNAMIC_SLOTS */;4341 }4342 }4343 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {4344 const child = node.children[0];4345 const type = child.type;4346 // check for dynamic text children4347 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||4348 type === 8 /* COMPOUND_EXPRESSION */;4349 if (hasDynamicTextChild &&4350 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4351 patchFlag |= 1 /* TEXT */;4352 }4353 // pass directly if the only child is a text node4354 // (plain / interpolation / expression)4355 if (hasDynamicTextChild || type === 2 /* TEXT */) {4356 vnodeChildren = child;4357 }4358 else {4359 vnodeChildren = node.children;4360 }4361 }4362 else {4363 vnodeChildren = node.children;4364 }4365 }4366 // patchFlag & dynamicPropNames4367 if (patchFlag !== 0) {4368 if ((process.env.NODE_ENV !== 'production')) {4369 if (patchFlag < 0) {4370 // special flags (negative and mutually exclusive)4371 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;4372 }4373 else {4374 // bitwise flags4375 const flagNames = Object.keys(PatchFlagNames)4376 .map(Number)4377 .filter(n => n > 0 && patchFlag & n)4378 .map(n => PatchFlagNames[n])4379 .join(`, `);4380 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;4381 }4382 }4383 else {4384 vnodePatchFlag = String(patchFlag);4385 }4386 if (dynamicPropNames && dynamicPropNames.length) {4387 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);4388 }4389 }4390 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);4391 };4392};4393function resolveComponentType(node, context, ssr = false) {4394 let { tag } = node;4395 // 1. dynamic component4396 const isExplicitDynamic = isComponentTag(tag);4397 const isProp = findProp(node, 'is');4398 if (isProp) {4399 if (isExplicitDynamic ||4400 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {4401 const exp = isProp.type === 6 /* ATTRIBUTE */4402 ? isProp.value && createSimpleExpression(isProp.value.content, true)4403 : isProp.exp;4404 if (exp) {4405 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4406 exp4407 ]);4408 }4409 }4410 else if (isProp.type === 6 /* ATTRIBUTE */ &&4411 isProp.value.content.startsWith('vue:')) {4412 // <button is="vue:xxx">4413 // if not <component>, only is value that starts with "vue:" will be4414 // treated as component by the parse phase and reach here, unless it's4415 // compat mode where all is values are considered components4416 tag = isProp.value.content.slice(4);4417 }4418 }4419 // 1.5 v-is (TODO: Deprecate)4420 const isDir = !isExplicitDynamic && findDir(node, 'is');4421 if (isDir && isDir.exp) {4422 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4423 isDir.exp4424 ]);4425 }4426 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)4427 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);4428 if (builtIn) {4429 // built-ins are simply fallthroughs / have special handling during ssr4430 // so we don't need to import their runtime equivalents4431 if (!ssr)4432 context.helper(builtIn);4433 return builtIn;4434 }4435 // 5. user component (resolve)4436 context.helper(RESOLVE_COMPONENT);4437 context.components.add(tag);4438 return toValidAssetId(tag, `component`);4439}4440function buildProps(node, context, props = node.props, ssr = false) {4441 const { tag, loc: elementLoc, children } = node;4442 const isComponent = node.tagType === 1 /* COMPONENT */;4443 let properties = [];4444 const mergeArgs = [];4445 const runtimeDirectives = [];4446 const hasChildren = children.length > 0;4447 let shouldUseBlock = false;4448 // patchFlag analysis4449 let patchFlag = 0;4450 let hasRef = false;4451 let hasClassBinding = false;4452 let hasStyleBinding = false;4453 let hasHydrationEventBinding = false;4454 let hasDynamicKeys = false;4455 let hasVnodeHook = false;4456 const dynamicPropNames = [];4457 const analyzePatchFlag = ({ key, value }) => {4458 if (isStaticExp(key)) {4459 const name = key.content;4460 const isEventHandler = isOn(name);4461 if (!isComponent &&4462 isEventHandler &&4463 // omit the flag for click handlers because hydration gives click4464 // dedicated fast path.4465 name.toLowerCase() !== 'onclick' &&4466 // omit v-model handlers4467 name !== 'onUpdate:modelValue' &&4468 // omit onVnodeXXX hooks4469 !isReservedProp(name)) {4470 hasHydrationEventBinding = true;4471 }4472 if (isEventHandler && isReservedProp(name)) {4473 hasVnodeHook = true;4474 }4475 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||4476 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||4477 value.type === 8 /* COMPOUND_EXPRESSION */) &&4478 getConstantType(value, context) > 0)) {4479 // skip if the prop is a cached handler or has constant value4480 return;4481 }4482 if (name === 'ref') {4483 hasRef = true;4484 }4485 else if (name === 'class') {4486 hasClassBinding = true;4487 }4488 else if (name === 'style') {4489 hasStyleBinding = true;4490 }4491 else if (name !== 'key' && !dynamicPropNames.includes(name)) {4492 dynamicPropNames.push(name);4493 }4494 // treat the dynamic class and style binding of the component as dynamic props4495 if (isComponent &&4496 (name === 'class' || name === 'style') &&4497 !dynamicPropNames.includes(name)) {4498 dynamicPropNames.push(name);4499 }4500 }4501 else {4502 hasDynamicKeys = true;4503 }4504 };4505 for (let i = 0; i < props.length; i++) {4506 // static attribute4507 const prop = props[i];4508 if (prop.type === 6 /* ATTRIBUTE */) {4509 const { loc, name, value } = prop;4510 let isStatic = true;4511 if (name === 'ref') {4512 hasRef = true;4513 if (context.scopes.vFor > 0) {4514 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4515 }4516 }4517 // skip is on <component>, or is="vue:xxx"4518 if (name === 'is' &&4519 (isComponentTag(tag) ||4520 (value && value.content.startsWith('vue:')) ||4521 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4522 continue;4523 }4524 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));4525 }4526 else {4527 // directives4528 const { name, arg, exp, loc } = prop;4529 const isVBind = name === 'bind';4530 const isVOn = name === 'on';4531 // skip v-slot - it is handled by its dedicated transform.4532 if (name === 'slot') {4533 if (!isComponent) {4534 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4535 }4536 continue;4537 }4538 // skip v-once/v-memo - they are handled by dedicated transforms.4539 if (name === 'once' || name === 'memo') {4540 continue;4541 }4542 // skip v-is and :is on <component>4543 if (name === 'is' ||4544 (isVBind &&4545 isStaticArgOf(arg, 'is') &&4546 (isComponentTag(tag) ||4547 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4548 continue;4549 }4550 // skip v-on in SSR compilation4551 if (isVOn && ssr) {4552 continue;4553 }4554 if (4555 // #938: elements with dynamic keys should be forced into blocks4556 (isVBind && isStaticArgOf(arg, 'key')) ||4557 // inline before-update hooks need to force block so that it is invoked4558 // before children4559 (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {4560 shouldUseBlock = true;4561 }4562 if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {4563 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4564 }4565 // special case for v-bind and v-on with no argument4566 if (!arg && (isVBind || isVOn)) {4567 hasDynamicKeys = true;4568 if (exp) {4569 if (properties.length) {4570 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4571 properties = [];4572 }4573 if (isVBind) {4574 {4575 // 2.x v-bind object order compat4576 if ((process.env.NODE_ENV !== 'production')) {4577 const hasOverridableKeys = mergeArgs.some(arg => {4578 if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {4579 return arg.properties.some(({ key }) => {4580 if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||4581 !key.isStatic) {4582 return true;4583 }4584 return (key.content !== 'class' &&4585 key.content !== 'style' &&4586 !isOn(key.content));4587 });4588 }4589 else {4590 // dynamic expression4591 return true;4592 }4593 });4594 if (hasOverridableKeys) {4595 checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);4596 }4597 }4598 if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4599 mergeArgs.unshift(exp);4600 continue;4601 }4602 }4603 mergeArgs.push(exp);4604 }4605 else {4606 // v-on="obj" -> toHandlers(obj)4607 mergeArgs.push({4608 type: 14 /* JS_CALL_EXPRESSION */,4609 loc,4610 callee: context.helper(TO_HANDLERS),4611 arguments: [exp]4612 });4613 }4614 }4615 else {4616 context.onError(createCompilerError(isVBind4617 ? 34 /* X_V_BIND_NO_EXPRESSION */4618 : 35 /* X_V_ON_NO_EXPRESSION */, loc));4619 }4620 continue;4621 }4622 const directiveTransform = context.directiveTransforms[name];4623 if (directiveTransform) {4624 // has built-in directive transform.4625 const { props, needRuntime } = directiveTransform(prop, node, context);4626 !ssr && props.forEach(analyzePatchFlag);4627 properties.push(...props);4628 if (needRuntime) {4629 runtimeDirectives.push(prop);4630 if (isSymbol(needRuntime)) {4631 directiveImportMap.set(prop, needRuntime);4632 }4633 }4634 }4635 else if (!isBuiltInDirective(name)) {4636 // no built-in transform, this is a user custom directive.4637 runtimeDirectives.push(prop);4638 // custom dirs may use beforeUpdate so they need to force blocks4639 // to ensure before-update gets called before children update4640 if (hasChildren) {4641 shouldUseBlock = true;4642 }4643 }4644 }4645 }4646 let propsExpression = undefined;4647 // has v-bind="object" or v-on="object", wrap with mergeProps4648 if (mergeArgs.length) {4649 if (properties.length) {4650 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4651 }4652 if (mergeArgs.length > 1) {4653 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4654 }4655 else {4656 // single v-bind with nothing else - no need for a mergeProps call4657 propsExpression = mergeArgs[0];4658 }4659 }4660 else if (properties.length) {4661 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4662 }4663 // patchFlag analysis4664 if (hasDynamicKeys) {4665 patchFlag |= 16 /* FULL_PROPS */;4666 }4667 else {4668 if (hasClassBinding && !isComponent) {4669 patchFlag |= 2 /* CLASS */;4670 }4671 if (hasStyleBinding && !isComponent) {4672 patchFlag |= 4 /* STYLE */;4673 }4674 if (dynamicPropNames.length) {4675 patchFlag |= 8 /* PROPS */;4676 }4677 if (hasHydrationEventBinding) {4678 patchFlag |= 32 /* HYDRATE_EVENTS */;4679 }4680 }4681 if (!shouldUseBlock &&4682 (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4683 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4684 patchFlag |= 512 /* NEED_PATCH */;4685 }4686 // pre-normalize props, SSR is skipped for now4687 if (!context.inSSR && propsExpression) {4688 switch (propsExpression.type) {4689 case 15 /* JS_OBJECT_EXPRESSION */:4690 // means that there is no v-bind,4691 // but still need to deal with dynamic key binding4692 let classKeyIndex = -1;4693 let styleKeyIndex = -1;4694 let hasDynamicKey = false;4695 for (let i = 0; i < propsExpression.properties.length; i++) {4696 const key = propsExpression.properties[i].key;4697 if (isStaticExp(key)) {4698 if (key.content === 'class') {4699 classKeyIndex = i;4700 }4701 else if (key.content === 'style') {4702 styleKeyIndex = i;4703 }4704 }4705 else if (!key.isHandlerKey) {4706 hasDynamicKey = true;4707 }4708 }4709 const classProp = propsExpression.properties[classKeyIndex];4710 const styleProp = propsExpression.properties[styleKeyIndex];4711 // no dynamic key4712 if (!hasDynamicKey) {4713 if (classProp && !isStaticExp(classProp.value)) {4714 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4715 }4716 if (styleProp &&4717 !isStaticExp(styleProp.value) &&4718 // the static style is compiled into an object,4719 // so use `hasStyleBinding` to ensure that it is a dynamic style binding4720 (hasStyleBinding ||4721 // v-bind:style and style both exist,4722 // v-bind:style with static literal object4723 styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4724 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4725 }4726 }4727 else {4728 // dynamic key binding, wrap with `normalizeProps`4729 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4730 }4731 break;4732 case 14 /* JS_CALL_EXPRESSION */:4733 // mergeProps call, do nothing4734 break;4735 default:4736 // single v-bind4737 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4738 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4739 propsExpression4740 ])4741 ]);4742 break;4743 }4744 }4745 return {4746 props: propsExpression,4747 directives: runtimeDirectives,4748 patchFlag,4749 dynamicPropNames,4750 shouldUseBlock4751 };4752}4753// Dedupe props in an object literal.4754// Literal duplicated attributes would have been warned during the parse phase,4755// however, it's possible to encounter duplicated `onXXX` handlers with different4756// modifiers. We also need to merge static and dynamic class / style attributes.4757// - onXXX handlers / style: merge into array4758// - class: merge into single expression with concatenation4759function dedupeProperties(properties) {4760 const knownProps = new Map();4761 const deduped = [];4762 for (let i = 0; i < properties.length; i++) {4763 const prop = properties[i];4764 // dynamic keys are always allowed4765 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4766 deduped.push(prop);4767 continue;4768 }4769 const name = prop.key.content;4770 const existing = knownProps.get(name);4771 if (existing) {4772 if (name === 'style' || name === 'class' || isOn(name)) {4773 mergeAsArray(existing, prop);4774 }4775 // unexpected duplicate, should have emitted error during parse4776 }4777 else {4778 knownProps.set(name, prop);4779 deduped.push(prop);4780 }4781 }4782 return deduped;4783}4784function mergeAsArray(existing, incoming) {4785 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4786 existing.value.elements.push(incoming.value);4787 }4788 else {4789 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4790 }4791}4792function buildDirectiveArgs(dir, context) {4793 const dirArgs = [];4794 const runtime = directiveImportMap.get(dir);4795 if (runtime) {4796 // built-in directive with runtime4797 dirArgs.push(context.helperString(runtime));4798 }4799 else {4800 {4801 // inject statement for resolving directive4802 context.helper(RESOLVE_DIRECTIVE);4803 context.directives.add(dir.name);4804 dirArgs.push(toValidAssetId(dir.name, `directive`));4805 }4806 }4807 const { loc } = dir;4808 if (dir.exp)4809 dirArgs.push(dir.exp);4810 if (dir.arg) {4811 if (!dir.exp) {4812 dirArgs.push(`void 0`);4813 }4814 dirArgs.push(dir.arg);4815 }4816 if (Object.keys(dir.modifiers).length) {4817 if (!dir.arg) {4818 if (!dir.exp) {4819 dirArgs.push(`void 0`);4820 }4821 dirArgs.push(`void 0`);4822 }4823 const trueExpression = createSimpleExpression(`true`, false, loc);4824 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4825 }4826 return createArrayExpression(dirArgs, dir.loc);4827}4828function stringifyDynamicPropNames(props) {4829 let propsNamesString = `[`;4830 for (let i = 0, l = props.length; i < l; i++) {4831 propsNamesString += JSON.stringify(props[i]);4832 if (i < l - 1)4833 propsNamesString += ', ';4834 }4835 return propsNamesString + `]`;4836}4837function isComponentTag(tag) {4838 return tag === 'component' || tag === 'Component';4839}4840(process.env.NODE_ENV !== 'production')4841 ? Object.freeze({})4842 : {};4843(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];4844const cacheStringFunction = (fn) => {4845 const cache = Object.create(null);4846 return ((str) => {4847 const hit = cache[str];4848 return hit || (cache[str] = fn(str));4849 });4850};4851const camelizeRE = /-(\w)/g;4852/**4853 * @private4854 */4855const camelize = cacheStringFunction((str) => {4856 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));4857});4858const transformSlotOutlet = (node, context) => {4859 if (isSlotOutlet(node)) {4860 const { children, loc } = node;4861 const { slotName, slotProps } = processSlotOutlet(node, context);4862 const slotArgs = [4863 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4864 slotName,4865 '{}',4866 'undefined',4867 'true'4868 ];4869 let expectedLen = 2;4870 if (slotProps) {4871 slotArgs[2] = slotProps;4872 expectedLen = 3;4873 }4874 if (children.length) {4875 slotArgs[3] = createFunctionExpression([], children, false, false, loc);4876 expectedLen = 4;4877 }4878 if (context.scopeId && !context.slotted) {4879 expectedLen = 5;4880 }4881 slotArgs.splice(expectedLen); // remove unused arguments4882 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4883 }4884};4885function processSlotOutlet(node, context) {4886 let slotName = `"default"`;4887 let slotProps = undefined;4888 const nonNameProps = [];4889 for (let i = 0; i < node.props.length; i++) {4890 const p = node.props[i];4891 if (p.type === 6 /* ATTRIBUTE */) {4892 if (p.value) {4893 if (p.name === 'name') {4894 slotName = JSON.stringify(p.value.content);4895 }4896 else {4897 p.name = camelize(p.name);4898 nonNameProps.push(p);4899 }4900 }4901 }4902 else {4903 if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {4904 if (p.exp)4905 slotName = p.exp;4906 }4907 else {4908 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4909 p.arg.content = camelize(p.arg.content);4910 }4911 nonNameProps.push(p);4912 }4913 }4914 }4915 if (nonNameProps.length > 0) {4916 const { props, directives } = buildProps(node, context, nonNameProps);4917 slotProps = props;4918 if (directives.length) {4919 context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4920 }4921 }4922 return {4923 slotName,4924 slotProps4925 };4926}4927const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;4928const transformOn = (dir, node, context, augmentor) => {4929 const { loc, modifiers, arg } = dir;4930 if (!dir.exp && !modifiers.length) {4931 context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));4932 }4933 let eventName;4934 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4935 if (arg.isStatic) {4936 let rawName = arg.content;4937 // TODO deprecate @vnodeXXX usage4938 if (rawName.startsWith('vue:')) {4939 rawName = `vnode-${rawName.slice(4)}`;4940 }4941 // for all event listeners, auto convert it to camelCase. See issue #22494942 eventName = createSimpleExpression(toHandlerKey(camelize$1(rawName)), true, arg.loc);4943 }4944 else {4945 // #23884946 eventName = createCompoundExpression([4947 `${context.helperString(TO_HANDLER_KEY)}(`,4948 arg,4949 `)`4950 ]);4951 }4952 }4953 else {4954 // already a compound expression.4955 eventName = arg;4956 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4957 eventName.children.push(`)`);4958 }4959 // handler processing4960 let exp = dir.exp;4961 if (exp && !exp.content.trim()) {4962 exp = undefined;4963 }4964 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;4965 if (exp) {4966 const isMemberExp = isMemberExpression(exp.content);4967 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4968 const hasMultipleStatements = exp.content.includes(`;`);4969 if ((process.env.NODE_ENV !== 'production') && true) {4970 validateBrowserExpression(exp, context, false, hasMultipleStatements);4971 }4972 if (isInlineStatement || (shouldCache && isMemberExp)) {4973 // wrap inline statement in a function expression4974 exp = createCompoundExpression([4975 `${isInlineStatement4976 ? `$event`4977 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4978 exp,4979 hasMultipleStatements ? `}` : `)`4980 ]);4981 }4982 }4983 let ret = {4984 props: [4985 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4986 ]4987 };4988 // apply extended compiler augmentor4989 if (augmentor) {4990 ret = augmentor(ret);4991 }4992 if (shouldCache) {4993 // cache handlers so that it's always the same handler being passed down.4994 // this avoids unnecessary re-renders when users use inline handlers on4995 // components.4996 ret.props[0].value = context.cache(ret.props[0].value);4997 }4998 // mark the key as handler for props normalization check4999 ret.props.forEach(p => (p.key.isHandlerKey = true));5000 return ret;5001};5002// v-bind without arg is handled directly in ./transformElements.ts due to it affecting5003// codegen for the entire props object. This transform here is only for v-bind5004// *with* args.5005const transformBind = (dir, _node, context) => {5006 const { exp, modifiers, loc } = dir;5007 const arg = dir.arg;5008 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {5009 arg.children.unshift(`(`);5010 arg.children.push(`) || ""`);5011 }5012 else if (!arg.isStatic) {5013 arg.content = `${arg.content} || ""`;5014 }5015 // .sync is replaced by v-model:arg5016 if (modifiers.includes('camel')) {5017 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5018 if (arg.isStatic) {5019 arg.content = camelize$1(arg.content);5020 }5021 else {5022 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;5023 }5024 }5025 else {5026 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);5027 arg.children.push(`)`);5028 }5029 }5030 if (!context.inSSR) {5031 if (modifiers.includes('prop')) {5032 injectPrefix(arg, '.');5033 }5034 if (modifiers.includes('attr')) {5035 injectPrefix(arg, '^');5036 }5037 }5038 if (!exp ||5039 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {5040 context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));5041 return {5042 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]5043 };5044 }5045 return {5046 props: [createObjectProperty(arg, exp)]5047 };5048};5049const injectPrefix = (arg, prefix) => {5050 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5051 if (arg.isStatic) {5052 arg.content = prefix + arg.content;5053 }5054 else {5055 arg.content = `\`${prefix}\${${arg.content}}\``;5056 }5057 }5058 else {5059 arg.children.unshift(`'${prefix}' + (`);5060 arg.children.push(`)`);5061 }5062};5063// Merge adjacent text nodes and expressions into a single expression5064// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.5065const transformText = (node, context) => {5066 if (node.type === 0 /* ROOT */ ||5067 node.type === 1 /* ELEMENT */ ||5068 node.type === 11 /* FOR */ ||5069 node.type === 10 /* IF_BRANCH */) {5070 // perform the transform on node exit so that all expressions have already5071 // been processed.5072 return () => {5073 const children = node.children;5074 let currentContainer = undefined;5075 let hasText = false;5076 for (let i = 0; i < children.length; i++) {5077 const child = children[i];5078 if (isText(child)) {5079 hasText = true;5080 for (let j = i + 1; j < children.length; j++) {5081 const next = children[j];5082 if (isText(next)) {5083 if (!currentContainer) {5084 currentContainer = children[i] = {5085 type: 8 /* COMPOUND_EXPRESSION */,5086 loc: child.loc,5087 children: [child]5088 };5089 }5090 // merge adjacent text node into current5091 currentContainer.children.push(` + `, next);5092 children.splice(j, 1);5093 j--;5094 }5095 else {5096 currentContainer = undefined;5097 break;5098 }5099 }5100 }5101 }5102 if (!hasText ||5103 // if this is a plain element with a single text child, leave it5104 // as-is since the runtime has dedicated fast path for this by directly5105 // setting textContent of the element.5106 // for component root it's always normalized anyway.5107 (children.length === 1 &&5108 (node.type === 0 /* ROOT */ ||5109 (node.type === 1 /* ELEMENT */ &&5110 node.tagType === 0 /* ELEMENT */ &&5111 // #37565112 // custom directives can potentially add DOM elements arbitrarily,5113 // we need to avoid setting textContent of the element at runtime5114 // to avoid accidentally overwriting the DOM elements added5115 // by the user through custom directives.5116 !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&5117 !context.directiveTransforms[p.name]) &&5118 // in compat mode, <template> tags with no special directives5119 // will be rendered as a fragment so its children must be5120 // converted into vnodes.5121 !(node.tag === 'template'))))) {5122 return;5123 }5124 // pre-convert text nodes into createTextVNode(text) calls to avoid5125 // runtime normalization.5126 for (let i = 0; i < children.length; i++) {5127 const child = children[i];5128 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {5129 const callArgs = [];5130 // createTextVNode defaults to single whitespace, so if it is a5131 // single space the code could be an empty call to save bytes.5132 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {5133 callArgs.push(child);5134 }5135 // mark dynamic text with flag so it gets patched inside a block5136 if (!context.ssr &&5137 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {5138 callArgs.push(1 /* TEXT */ +5139 ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[1 /* TEXT */]} */` : ``));5140 }5141 children[i] = {5142 type: 12 /* TEXT_CALL */,5143 content: child,5144 loc: child.loc,5145 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)5146 };5147 }5148 }5149 };5150 }5151};5152const seen = new WeakSet();5153const transformOnce = (node, context) => {5154 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {5155 if (seen.has(node) || context.inVOnce) {5156 return;5157 }5158 seen.add(node);5159 context.inVOnce = true;5160 context.helper(SET_BLOCK_TRACKING);5161 return () => {5162 context.inVOnce = false;5163 const cur = context.currentNode;5164 if (cur.codegenNode) {5165 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);5166 }5167 };5168 }5169};5170const transformModel = (dir, node, context) => {5171 const { exp, arg } = dir;5172 if (!exp) {5173 context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));5174 return createTransformProps();5175 }5176 const rawExp = exp.loc.source;5177 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;5178 const maybeRef = !true /* SETUP_CONST */;5179 if (!expString.trim() ||5180 (!isMemberExpression(expString) && !maybeRef)) {5181 context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));5182 return createTransformProps();5183 }5184 const propName = arg ? arg : createSimpleExpression('modelValue', true);5185 const eventName = arg5186 ? isStaticExp(arg)5187 ? `onUpdate:${arg.content}`5188 : createCompoundExpression(['"onUpdate:" + ', arg])5189 : `onUpdate:modelValue`;5190 let assignmentExp;5191 const eventArg = context.isTS ? `($event: any)` : `$event`;5192 {5193 assignmentExp = createCompoundExpression([5194 `${eventArg} => ((`,5195 exp,5196 `) = $event)`5197 ]);5198 }5199 const props = [5200 // modelValue: foo5201 createObjectProperty(propName, dir.exp),5202 // "onUpdate:modelValue": $event => (foo = $event)5203 createObjectProperty(eventName, assignmentExp)5204 ];5205 // modelModifiers: { foo: true, "bar-baz": true }5206 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {5207 const modifiers = dir.modifiers5208 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)5209 .join(`, `);5210 const modifiersKey = arg5211 ? isStaticExp(arg)5212 ? `${arg.content}Modifiers`5213 : createCompoundExpression([arg, ' + "Modifiers"'])5214 : `modelModifiers`;5215 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));5216 }5217 return createTransformProps(props);5218};5219function createTransformProps(props = []) {5220 return { props };5221}5222const validDivisionCharRE = /[\w).+\-_$\]]/;5223const transformFilter = (node, context) => {5224 if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {5225 return;5226 }5227 if (node.type === 5 /* INTERPOLATION */) {5228 // filter rewrite is applied before expression transform so only5229 // simple expressions are possible at this stage5230 rewriteFilter(node.content, context);5231 }5232 if (node.type === 1 /* ELEMENT */) {5233 node.props.forEach((prop) => {5234 if (prop.type === 7 /* DIRECTIVE */ &&5235 prop.name !== 'for' &&5236 prop.exp) {5237 rewriteFilter(prop.exp, context);5238 }5239 });5240 }5241};5242function rewriteFilter(node, context) {5243 if (node.type === 4 /* SIMPLE_EXPRESSION */) {5244 parseFilter(node, context);5245 }5246 else {5247 for (let i = 0; i < node.children.length; i++) {5248 const child = node.children[i];5249 if (typeof child !== 'object')5250 continue;5251 if (child.type === 4 /* SIMPLE_EXPRESSION */) {5252 parseFilter(child, context);5253 }5254 else if (child.type === 8 /* COMPOUND_EXPRESSION */) {5255 rewriteFilter(node, context);5256 }5257 else if (child.type === 5 /* INTERPOLATION */) {5258 rewriteFilter(child.content, context);5259 }5260 }5261 }5262}5263function parseFilter(node, context) {5264 const exp = node.content;5265 let inSingle = false;5266 let inDouble = false;5267 let inTemplateString = false;5268 let inRegex = false;5269 let curly = 0;5270 let square = 0;5271 let paren = 0;5272 let lastFilterIndex = 0;5273 let c, prev, i, expression, filters = [];5274 for (i = 0; i < exp.length; i++) {5275 prev = c;5276 c = exp.charCodeAt(i);5277 if (inSingle) {5278 if (c === 0x27 && prev !== 0x5c)5279 inSingle = false;5280 }5281 else if (inDouble) {5282 if (c === 0x22 && prev !== 0x5c)5283 inDouble = false;5284 }5285 else if (inTemplateString) {5286 if (c === 0x60 && prev !== 0x5c)5287 inTemplateString = false;5288 }5289 else if (inRegex) {5290 if (c === 0x2f && prev !== 0x5c)5291 inRegex = false;5292 }5293 else if (c === 0x7c && // pipe5294 exp.charCodeAt(i + 1) !== 0x7c &&5295 exp.charCodeAt(i - 1) !== 0x7c &&5296 !curly &&5297 !square &&5298 !paren) {5299 if (expression === undefined) {5300 // first filter, end of expression5301 lastFilterIndex = i + 1;5302 expression = exp.slice(0, i).trim();5303 }5304 else {5305 pushFilter();5306 }5307 }5308 else {5309 switch (c) {5310 case 0x22:5311 inDouble = true;5312 break; // "5313 case 0x27:5314 inSingle = true;5315 break; // '5316 case 0x60:5317 inTemplateString = true;5318 break; // `5319 case 0x28:5320 paren++;5321 break; // (5322 case 0x29:5323 paren--;5324 break; // )5325 case 0x5b:5326 square++;5327 break; // [5328 case 0x5d:5329 square--;5330 break; // ]5331 case 0x7b:5332 curly++;5333 break; // {5334 case 0x7d:5335 curly--;5336 break; // }5337 }5338 if (c === 0x2f) {5339 // /5340 let j = i - 1;5341 let p;5342 // find first non-whitespace prev char5343 for (; j >= 0; j--) {5344 p = exp.charAt(j);5345 if (p !== ' ')5346 break;5347 }5348 if (!p || !validDivisionCharRE.test(p)) {5349 inRegex = true;5350 }5351 }5352 }5353 }5354 if (expression === undefined) {5355 expression = exp.slice(0, i).trim();5356 }5357 else if (lastFilterIndex !== 0) {5358 pushFilter();5359 }5360 function pushFilter() {5361 filters.push(exp.slice(lastFilterIndex, i).trim());5362 lastFilterIndex = i + 1;5363 }5364 if (filters.length) {5365 (process.env.NODE_ENV !== 'production') &&5366 warnDeprecation("COMPILER_FILTER" /* COMPILER_FILTERS */, context, node.loc);5367 for (i = 0; i < filters.length; i++) {5368 expression = wrapFilter(expression, filters[i], context);5369 }5370 node.content = expression;5371 }5372}5373function wrapFilter(exp, filter, context) {5374 context.helper(RESOLVE_FILTER);5375 const i = filter.indexOf('(');5376 if (i < 0) {5377 context.filters.add(filter);5378 return `${toValidAssetId(filter, 'filter')}(${exp})`;5379 }5380 else {5381 const name = filter.slice(0, i);5382 const args = filter.slice(i + 1);5383 context.filters.add(name);5384 return `${toValidAssetId(name, 'filter')}(${exp}${args !== ')' ? ',' + args : args}`;5385 }5386}5387const seen$1 = new WeakSet();5388const transformMemo = (node, context) => {5389 if (node.type === 1 /* ELEMENT */) {5390 const dir = findDir(node, 'memo');5391 if (!dir || seen$1.has(node)) {5392 return;5393 }5394 seen$1.add(node);5395 return () => {5396 const codegenNode = node.codegenNode ||5397 context.currentNode.codegenNode;5398 if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {5399 // non-component sub tree should be turned into a block5400 if (node.tagType !== 1 /* COMPONENT */) {5401 makeBlock(codegenNode, context);5402 }5403 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [5404 dir.exp,5405 createFunctionExpression(undefined, codegenNode),5406 `_cache`,5407 String(context.cached++)5408 ]);5409 }5410 };5411 }5412};5413function getBaseTransformPreset(prefixIdentifiers) {5414 return [5415 [5416 transformOnce,5417 transformIf,5418 transformMemo,5419 transformFor,5420 ...([transformFilter] ),5421 ...((process.env.NODE_ENV !== 'production')5422 ? [transformExpression]5423 : []),5424 transformSlotOutlet,5425 transformElement,5426 trackSlotScopes,5427 transformText5428 ],5429 {5430 on: transformOn,5431 bind: transformBind,5432 model: transformModel5433 }5434 ];5435}5436// we name it `baseCompile` so that higher order compilers like5437// @vue/compiler-dom can export `compile` while re-exporting everything else.5438function baseCompile(template, options = {}) {5439 const onError = options.onError || defaultOnError;5440 const isModuleMode = options.mode === 'module';5441 /* istanbul ignore if */5442 {5443 if (options.prefixIdentifiers === true) {5444 onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));5445 }5446 else if (isModuleMode) {5447 onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));5448 }5449 }5450 const prefixIdentifiers = !true ;5451 if (options.cacheHandlers) {5452 onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));5453 }5454 if (options.scopeId && !isModuleMode) {5455 onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));5456 }5457 const ast = isString(template) ? baseParse(template, options) : template;5458 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();5459 transform(ast, extend({}, options, {5460 prefixIdentifiers,5461 nodeTransforms: [5462 ...nodeTransforms,5463 ...(options.nodeTransforms || []) // user transforms5464 ],5465 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms5466 )5467 }));5468 return generate(ast, extend({}, options, {5469 prefixIdentifiers5470 }));5471}5472const noopDirectiveTransform = () => ({ props: [] });5473var compilerCore_esmBundler = {5474 __proto__: null,5475 BASE_TRANSITION: BASE_TRANSITION,5476 CAMELIZE: CAMELIZE,5477 CAPITALIZE: CAPITALIZE,5478 CREATE_BLOCK: CREATE_BLOCK,5479 CREATE_COMMENT: CREATE_COMMENT,5480 CREATE_ELEMENT_BLOCK: CREATE_ELEMENT_BLOCK,5481 CREATE_ELEMENT_VNODE: CREATE_ELEMENT_VNODE,5482 CREATE_SLOTS: CREATE_SLOTS,5483 CREATE_STATIC: CREATE_STATIC,5484 CREATE_TEXT: CREATE_TEXT,5485 CREATE_VNODE: CREATE_VNODE,5486 FRAGMENT: FRAGMENT,5487 GUARD_REACTIVE_PROPS: GUARD_REACTIVE_PROPS,5488 IS_MEMO_SAME: IS_MEMO_SAME,5489 IS_REF: IS_REF,5490 KEEP_ALIVE: KEEP_ALIVE,5491 MERGE_PROPS: MERGE_PROPS,5492 NORMALIZE_CLASS: NORMALIZE_CLASS,5493 NORMALIZE_PROPS: NORMALIZE_PROPS,5494 NORMALIZE_STYLE: NORMALIZE_STYLE,5495 OPEN_BLOCK: OPEN_BLOCK,5496 POP_SCOPE_ID: POP_SCOPE_ID,5497 PUSH_SCOPE_ID: PUSH_SCOPE_ID,5498 RENDER_LIST: RENDER_LIST,5499 RENDER_SLOT: RENDER_SLOT,5500 RESOLVE_COMPONENT: RESOLVE_COMPONENT,5501 RESOLVE_DIRECTIVE: RESOLVE_DIRECTIVE,5502 RESOLVE_DYNAMIC_COMPONENT: RESOLVE_DYNAMIC_COMPONENT,5503 RESOLVE_FILTER: RESOLVE_FILTER,5504 SET_BLOCK_TRACKING: SET_BLOCK_TRACKING,5505 SUSPENSE: SUSPENSE,5506 TELEPORT: TELEPORT,5507 TO_DISPLAY_STRING: TO_DISPLAY_STRING,5508 TO_HANDLERS: TO_HANDLERS,5509 TO_HANDLER_KEY: TO_HANDLER_KEY,5510 UNREF: UNREF,5511 WITH_CTX: WITH_CTX,5512 WITH_DIRECTIVES: WITH_DIRECTIVES,5513 WITH_MEMO: WITH_MEMO,5514 advancePositionWithClone: advancePositionWithClone,5515 advancePositionWithMutation: advancePositionWithMutation,5516 assert: assert,5517 baseCompile: baseCompile,5518 baseParse: baseParse,5519 buildDirectiveArgs: buildDirectiveArgs,5520 buildProps: buildProps,5521 buildSlots: buildSlots,5522 checkCompatEnabled: checkCompatEnabled,5523 createArrayExpression: createArrayExpression,5524 createAssignmentExpression: createAssignmentExpression,5525 createBlockStatement: createBlockStatement,5526 createCacheExpression: createCacheExpression,5527 createCallExpression: createCallExpression,5528 createCompilerError: createCompilerError,5529 createCompoundExpression: createCompoundExpression,5530 createConditionalExpression: createConditionalExpression,5531 createForLoopParams: createForLoopParams,5532 createFunctionExpression: createFunctionExpression,5533 createIfStatement: createIfStatement,5534 createInterpolation: createInterpolation,5535 createObjectExpression: createObjectExpression,5536 createObjectProperty: createObjectProperty,5537 createReturnStatement: createReturnStatement,5538 createRoot: createRoot,5539 createSequenceExpression: createSequenceExpression,5540 createSimpleExpression: createSimpleExpression,5541 createStructuralDirectiveTransform: createStructuralDirectiveTransform,5542 createTemplateLiteral: createTemplateLiteral,5543 createTransformContext: createTransformContext,5544 createVNodeCall: createVNodeCall,5545 extractIdentifiers: extractIdentifiers,5546 findDir: findDir,5547 findProp: findProp,5548 generate: generate,5549 getBaseTransformPreset: getBaseTransformPreset,5550 getInnerRange: getInnerRange,5551 getMemoedVNodeCall: getMemoedVNodeCall,5552 getVNodeBlockHelper: getVNodeBlockHelper,5553 getVNodeHelper: getVNodeHelper,5554 hasDynamicKeyVBind: hasDynamicKeyVBind,5555 hasScopeRef: hasScopeRef,5556 helperNameMap: helperNameMap,5557 injectProp: injectProp,5558 isBuiltInType: isBuiltInType,5559 isCoreComponent: isCoreComponent,5560 isFunctionType: isFunctionType,5561 isInDestructureAssignment: isInDestructureAssignment,5562 isMemberExpression: isMemberExpression,5563 isMemberExpressionBrowser: isMemberExpressionBrowser,5564 isMemberExpressionNode: isMemberExpressionNode,5565 isReferencedIdentifier: isReferencedIdentifier,5566 isSimpleIdentifier: isSimpleIdentifier,5567 isSlotOutlet: isSlotOutlet,5568 isStaticArgOf: isStaticArgOf,5569 isStaticExp: isStaticExp,5570 isStaticProperty: isStaticProperty,5571 isStaticPropertyKey: isStaticPropertyKey,5572 isTemplateNode: isTemplateNode,5573 isText: isText,5574 isVSlot: isVSlot,5575 locStub: locStub,5576 makeBlock: makeBlock,5577 noopDirectiveTransform: noopDirectiveTransform,5578 processExpression: processExpression,5579 processFor: processFor,5580 processIf: processIf,5581 processSlotOutlet: processSlotOutlet,5582 registerRuntimeHelpers: registerRuntimeHelpers,5583 resolveComponentType: resolveComponentType,5584 toValidAssetId: toValidAssetId,5585 trackSlotScopes: trackSlotScopes,5586 trackVForSlotScopes: trackVForSlotScopes,5587 transform: transform,5588 transformBind: transformBind,5589 transformElement: transformElement,5590 transformExpression: transformExpression,5591 transformModel: transformModel,5592 transformOn: transformOn,5593 traverseNode: traverseNode,5594 walkBlockDeclarations: walkBlockDeclarations,5595 walkFunctionParams: walkFunctionParams,5596 walkIdentifiers: walkIdentifiers,5597 warnDeprecation: warnDeprecation,5598 generateCodeFrame: generateCodeFrame5599};5600var require$$0 = /*@__PURE__*/build.getAugmentedNamespace(compilerCore_esmBundler);5601var require$$1 = /*@__PURE__*/build.getAugmentedNamespace(shared_esmBundler);5602(function (exports) {5603Object.defineProperty(exports, '__esModule', { value: true });5604var compilerCore = require$$0;5605var shared = require$$1;5606const V_MODEL_RADIO = Symbol(`vModelRadio` );5607const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );5608const V_MODEL_TEXT = Symbol(`vModelText` );5609const V_MODEL_SELECT = Symbol(`vModelSelect` );5610const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );5611const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );5612const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );5613const V_SHOW = Symbol(`vShow` );5614const TRANSITION = Symbol(`Transition` );5615const TRANSITION_GROUP = Symbol(`TransitionGroup` );5616compilerCore.registerRuntimeHelpers({5617 [V_MODEL_RADIO]: `vModelRadio`,5618 [V_MODEL_CHECKBOX]: `vModelCheckbox`,5619 [V_MODEL_TEXT]: `vModelText`,5620 [V_MODEL_SELECT]: `vModelSelect`,5621 [V_MODEL_DYNAMIC]: `vModelDynamic`,5622 [V_ON_WITH_MODIFIERS]: `withModifiers`,5623 [V_ON_WITH_KEYS]: `withKeys`,5624 [V_SHOW]: `vShow`,5625 [TRANSITION]: `Transition`,5626 [TRANSITION_GROUP]: `TransitionGroup`5627});5628var namedCharacterReferences = {5629 GT: ">",5630 gt: ">",5631 LT: "<",5632 lt: "<",5633 "ac;": "â¾",5634 "af;": "â¡",5635 AMP: "&",5636 amp: "&",5637 "ap;": "â",5638 "DD;": "â
",5639 "dd;": "â
",5640 deg: "°",5641 "ee;": "â
",5642 "eg;": "âª",5643 "el;": "âª",5644 ETH: "Ã",5645 eth: "ð",5646 "gE;": "â§",5647 "ge;": "â¥",5648 "Gg;": "â",5649 "gg;": "â«",5650 "gl;": "â·",5651 "GT;": ">",5652 "Gt;": "â«",5653 "gt;": ">",5654 "ic;": "â£",5655 "ii;": "â
",5656 "Im;": "â",5657 "in;": "â",5658 "it;": "â¢",5659 "lE;": "â¦",5660 "le;": "â¤",5661 "lg;": "â¶",5662 "Ll;": "â",5663 "ll;": "âª",5664 "LT;": "<",5665 "Lt;": "âª",5666 "lt;": "<",5667 "mp;": "â",5668 "Mu;": "Î",5669 "mu;": "μ",5670 "ne;": "â ",5671 "ni;": "â",5672 not: "¬",5673 "Nu;": "Î",5674 "nu;": "ν",5675 "Or;": "â©",5676 "or;": "â¨",5677 "oS;": "â",5678 "Pi;": "Î ",5679 "pi;": "Ï",5680 "pm;": "±",5681 "Pr;": "⪻",5682 "pr;": "âº",5683 "Re;": "â",5684 REG: "®",5685 reg: "®",5686 "rx;": "â",5687 "Sc;": "⪼",5688 "sc;": "â»",5689 shy: "Â",5690 uml: "¨",5691 "wp;": "â",5692 "wr;": "â",5693 "Xi;": "Î",5694 "xi;": "ξ",5695 yen: "Â¥",5696 "acd;": "â¿",5697 "acE;": "â¾Ì³",5698 "Acy;": "Ð",5699 "acy;": "а",5700 "Afr;": "ð",5701 "afr;": "ð",5702 "AMP;": "&",5703 "amp;": "&",5704 "And;": "â©",5705 "and;": "â§",5706 "ang;": "â ",5707 "apE;": "â©°",5708 "ape;": "â",5709 "ast;": "*",5710 Auml: "Ã",5711 auml: "ä",5712 "Bcy;": "Ð",5713 "bcy;": "б",5714 "Bfr;": "ð
",5715 "bfr;": "ð",5716 "bne;": "=â¥",5717 "bot;": "â¥",5718 "Cap;": "â",5719 "cap;": "â©",5720 cent: "¢",5721 "Cfr;": "â",5722 "cfr;": "ð ",5723 "Chi;": "Χ",5724 "chi;": "Ï",5725 "cir;": "â",5726 COPY: "©",5727 copy: "©",5728 "Cup;": "â",5729 "cup;": "âª",5730 "Dcy;": "Ð",5731 "dcy;": "д",5732 "deg;": "°",5733 "Del;": "â",5734 "Dfr;": "ð",5735 "dfr;": "ð¡",5736 "die;": "¨",5737 "div;": "÷",5738 "Dot;": "¨",5739 "dot;": "Ë",5740 "Ecy;": "Ð",5741 "ecy;": "Ñ",5742 "Efr;": "ð",5743 "efr;": "ð¢",5744 "egs;": "âª",5745 "ell;": "â",5746 "els;": "âª",5747 "ENG;": "Å",5748 "eng;": "Å",5749 "Eta;": "Î",5750 "eta;": "η",5751 "ETH;": "Ã",5752 "eth;": "ð",5753 Euml: "Ã",5754 euml: "ë",5755 "Fcy;": "Ф",5756 "fcy;": "Ñ",5757 "Ffr;": "ð",5758 "ffr;": "ð£",5759 "gap;": "âª",5760 "Gcy;": "Ð",5761 "gcy;": "г",5762 "gEl;": "âª",5763 "gel;": "â",5764 "geq;": "â¥",5765 "ges;": "⩾",5766 "Gfr;": "ð",5767 "gfr;": "ð¤",5768 "ggg;": "â",5769 "gla;": "⪥",5770 "glE;": "âª",5771 "glj;": "⪤",5772 "gnE;": "â©",5773 "gne;": "âª",5774 "Hat;": "^",5775 "Hfr;": "â",5776 "hfr;": "ð¥",5777 "Icy;": "Ð",5778 "icy;": "и",5779 "iff;": "â",5780 "Ifr;": "â",5781 "ifr;": "ð¦",5782 "Int;": "â¬",5783 "int;": "â«",5784 Iuml: "Ã",5785 iuml: "ï",5786 "Jcy;": "Ð",5787 "jcy;": "й",5788 "Jfr;": "ð",5789 "jfr;": "ð§",5790 "Kcy;": "Ð",5791 "kcy;": "к",5792 "Kfr;": "ð",5793 "kfr;": "ð¨",5794 "lap;": "âª
",5795 "lat;": "⪫",5796 "Lcy;": "Ð",5797 "lcy;": "л",5798 "lEg;": "âª",5799 "leg;": "â",5800 "leq;": "â¤",5801 "les;": "⩽",5802 "Lfr;": "ð",5803 "lfr;": "ð©",5804 "lgE;": "âª",5805 "lnE;": "â¨",5806 "lne;": "âª",5807 "loz;": "â",5808 "lrm;": "â",5809 "Lsh;": "â°",5810 "lsh;": "â°",5811 macr: "¯",5812 "Map;": "â¤
",5813 "map;": "â¦",5814 "Mcy;": "Ð",5815 "mcy;": "м",5816 "Mfr;": "ð",5817 "mfr;": "ðª",5818 "mho;": "â§",5819 "mid;": "â£",5820 "nap;": "â",5821 nbsp: " ",5822 "Ncy;": "Ð",5823 "ncy;": "н",5824 "Nfr;": "ð",5825 "nfr;": "ð«",5826 "ngE;": "â§Ì¸",5827 "nge;": "â±",5828 "nGg;": "â̸",5829 "nGt;": "â«â",5830 "ngt;": "â¯",5831 "nis;": "â¼",5832 "niv;": "â",5833 "nlE;": "â¦Ì¸",5834 "nle;": "â°",5835 "nLl;": "â̸",5836 "nLt;": "âªâ",5837 "nlt;": "â®",5838 "Not;": "⫬",5839 "not;": "¬",5840 "npr;": "â",5841 "nsc;": "â",5842 "num;": "#",5843 "Ocy;": "Ð",5844 "ocy;": "о",5845 "Ofr;": "ð",5846 "ofr;": "ð¬",5847 "ogt;": "â§",5848 "ohm;": "Ω",5849 "olt;": "â§",5850 "ord;": "â©",5851 ordf: "ª",5852 ordm: "º",5853 "orv;": "â©",5854 Ouml: "Ã",5855 ouml: "ö",5856 "par;": "â¥",5857 para: "¶",5858 "Pcy;": "Ð",5859 "pcy;": "п",5860 "Pfr;": "ð",5861 "pfr;": "ð",5862 "Phi;": "Φ",5863 "phi;": "Ï",5864 "piv;": "Ï",5865 "prE;": "⪳",5866 "pre;": "⪯",5867 "Psi;": "Ψ",5868 "psi;": "Ï",5869 "Qfr;": "ð",5870 "qfr;": "ð®",5871 QUOT: "\"",5872 quot: "\"",5873 "Rcy;": "Ð ",5874 "rcy;": "Ñ",5875 "REG;": "®",5876 "reg;": "®",5877 "Rfr;": "â",5878 "rfr;": "ð¯",5879 "Rho;": "Ρ",5880 "rho;": "Ï",5881 "rlm;": "â",5882 "Rsh;": "â±",5883 "rsh;": "â±",5884 "scE;": "⪴",5885 "sce;": "⪰",5886 "Scy;": "С",5887 "scy;": "Ñ",5888 sect: "§",5889 "Sfr;": "ð",5890 "sfr;": "ð°",5891 "shy;": "Â",5892 "sim;": "â¼",5893 "smt;": "⪪",5894 "sol;": "/",5895 "squ;": "â¡",5896 "Sub;": "â",5897 "sub;": "â",5898 "Sum;": "â",5899 "sum;": "â",5900 "Sup;": "â",5901 "sup;": "â",5902 sup1: "¹",5903 sup2: "²",5904 sup3: "³",5905 "Tab;": "\t",5906 "Tau;": "Τ",5907 "tau;": "Ï",5908 "Tcy;": "Т",5909 "tcy;": "Ñ",5910 "Tfr;": "ð",5911 "tfr;": "ð±",5912 "top;": "â¤",5913 "Ucy;": "У",5914 "ucy;": "Ñ",5915 "Ufr;": "ð",5916 "ufr;": "ð²",5917 "uml;": "¨",5918 Uuml: "Ã",5919 uuml: "ü",5920 "Vcy;": "Ð",5921 "vcy;": "в",5922 "Vee;": "â",5923 "vee;": "â¨",5924 "Vfr;": "ð",5925 "vfr;": "ð³",5926 "Wfr;": "ð",5927 "wfr;": "ð´",5928 "Xfr;": "ð",5929 "xfr;": "ðµ",5930 "Ycy;": "Ы",5931 "ycy;": "Ñ",5932 "yen;": "Â¥",5933 "Yfr;": "ð",5934 "yfr;": "ð¶",5935 yuml: "ÿ",5936 "Zcy;": "Ð",5937 "zcy;": "з",5938 "Zfr;": "â¨",5939 "zfr;": "ð·",5940 "zwj;": "â",5941 Acirc: "Ã",5942 acirc: "â",5943 acute: "´",5944 AElig: "Ã",5945 aelig: "æ",5946 "andd;": "â©",5947 "andv;": "â©",5948 "ange;": "⦤",5949 "Aopf;": "ð¸",5950 "aopf;": "ð",5951 "apid;": "â",5952 "apos;": "'",5953 Aring: "Ã
",5954 aring: "Ã¥",5955 "Ascr;": "ð",5956 "ascr;": "ð¶",5957 "Auml;": "Ã",5958 "auml;": "ä",5959 "Barv;": "⫧",5960 "bbrk;": "âµ",5961 "Beta;": "Î",5962 "beta;": "β",5963 "beth;": "â¶",5964 "bNot;": "â«",5965 "bnot;": "â",5966 "Bopf;": "ð¹",5967 "bopf;": "ð",5968 "boxH;": "â",5969 "boxh;": "â",5970 "boxV;": "â",5971 "boxv;": "â",5972 "Bscr;": "â¬",5973 "bscr;": "ð·",5974 "bsim;": "â½",5975 "bsol;": "\\",5976 "bull;": "â¢",5977 "bump;": "â",5978 "caps;": "â©ï¸",5979 "Cdot;": "Ä",5980 "cdot;": "Ä",5981 cedil: "¸",5982 "cent;": "¢",5983 "CHcy;": "Ч",5984 "chcy;": "Ñ",5985 "circ;": "Ë",5986 "cirE;": "â§",5987 "cire;": "â",5988 "comp;": "â",5989 "cong;": "â
",5990 "Copf;": "â",5991 "copf;": "ð",5992 "COPY;": "©",5993 "copy;": "©",5994 "Cscr;": "ð",5995 "cscr;": "ð¸",5996 "csub;": "â«",5997 "csup;": "â«",5998 "cups;": "âªï¸",5999 "Darr;": "â¡",6000 "dArr;": "â",6001 "darr;": "â",6002 "dash;": "â",6003 "dHar;": "⥥",6004 "diam;": "â",6005 "DJcy;": "Ð",6006 "djcy;": "Ñ",6007 "Dopf;": "ð»",6008 "dopf;": "ð",6009 "Dscr;": "ð",6010 "dscr;": "ð¹",6011 "DScy;": "Ð
",6012 "dscy;": "Ñ",6013 "dsol;": "⧶",6014 "dtri;": "â¿",6015 "DZcy;": "Ð",6016 "dzcy;": "Ñ",6017 "ecir;": "â",6018 Ecirc: "Ã",6019 ecirc: "ê",6020 "Edot;": "Ä",6021 "eDot;": "â",6022 "edot;": "Ä",6023 "emsp;": "â",6024 "ensp;": "â",6025 "Eopf;": "ð¼",6026 "eopf;": "ð",6027 "epar;": "â",6028 "epsi;": "ε",6029 "Escr;": "â°",6030 "escr;": "â¯",6031 "Esim;": "⩳",6032 "esim;": "â",6033 "Euml;": "Ã",6034 "euml;": "ë",6035 "euro;": "â¬",6036 "excl;": "!",6037 "flat;": "â",6038 "fnof;": "Æ",6039 "Fopf;": "ð½",6040 "fopf;": "ð",6041 "fork;": "â",6042 "Fscr;": "â±",6043 "fscr;": "ð»",6044 "Gdot;": "Ä ",6045 "gdot;": "Ä¡",6046 "geqq;": "â§",6047 "gesl;": "âï¸",6048 "GJcy;": "Ð",6049 "gjcy;": "Ñ",6050 "gnap;": "âª",6051 "gneq;": "âª",6052 "Gopf;": "ð¾",6053 "gopf;": "ð",6054 "Gscr;": "ð¢",6055 "gscr;": "â",6056 "gsim;": "â³",6057 "gtcc;": "⪧",6058 "gvnE;": "â©ï¸",6059 "half;": "½",6060 "hArr;": "â",6061 "harr;": "â",6062 "hbar;": "â",6063 "Hopf;": "â",6064 "hopf;": "ð",6065 "Hscr;": "â",6066 "hscr;": "ð½",6067 Icirc: "Ã",6068 icirc: "î",6069 "Idot;": "Ä°",6070 "IEcy;": "Ð",6071 "iecy;": "е",6072 iexcl: "¡",6073 "imof;": "â·",6074 "IOcy;": "Ð",6075 "iocy;": "Ñ",6076 "Iopf;": "ð",6077 "iopf;": "ð",6078 "Iota;": "Î",6079 "iota;": "ι",6080 "Iscr;": "â",6081 "iscr;": "ð¾",6082 "isin;": "â",6083 "Iuml;": "Ã",6084 "iuml;": "ï",6085 "Jopf;": "ð",6086 "jopf;": "ð",6087 "Jscr;": "ð¥",6088 "jscr;": "ð¿",6089 "KHcy;": "Ð¥",6090 "khcy;": "Ñ
",6091 "KJcy;": "Ð",6092 "kjcy;": "Ñ",6093 "Kopf;": "ð",6094 "kopf;": "ð",6095 "Kscr;": "ð¦",6096 "kscr;": "ð",6097 "Lang;": "âª",6098 "lang;": "â¨",6099 laquo: "«",6100 "Larr;": "â",6101 "lArr;": "â",6102 "larr;": "â",6103 "late;": "âª",6104 "lcub;": "{",6105 "ldca;": "⤶",6106 "ldsh;": "â²",6107 "leqq;": "â¦",6108 "lesg;": "âï¸",6109 "lHar;": "⥢",6110 "LJcy;": "Ð",6111 "ljcy;": "Ñ",6112 "lnap;": "âª",6113 "lneq;": "âª",6114 "Lopf;": "ð",6115 "lopf;": "ð",6116 "lozf;": "⧫",6117 "lpar;": "(",6118 "Lscr;": "â",6119 "lscr;": "ð",6120 "lsim;": "â²",6121 "lsqb;": "[",6122 "ltcc;": "⪦",6123 "ltri;": "â",6124 "lvnE;": "â¨ï¸",6125 "macr;": "¯",6126 "male;": "â",6127 "malt;": "â ",6128 micro: "µ",6129 "mlcp;": "â«",6130 "mldr;": "â¦",6131 "Mopf;": "ð",6132 "mopf;": "ð",6133 "Mscr;": "â³",6134 "mscr;": "ð",6135 "nang;": "â â",6136 "napE;": "⩰̸",6137 "nbsp;": " ",6138 "ncap;": "â©",6139 "ncup;": "â©",6140 "ngeq;": "â±",6141 "nges;": "⩾̸",6142 "ngtr;": "â¯",6143 "nGtv;": "â«Ì¸",6144 "nisd;": "âº",6145 "NJcy;": "Ð",6146 "njcy;": "Ñ",6147 "nldr;": "â¥",6148 "nleq;": "â°",6149 "nles;": "⩽̸",6150 "nLtv;": "âªÌ¸",6151 "nmid;": "â¤",6152 "Nopf;": "â",6153 "nopf;": "ð",6154 "npar;": "â¦",6155 "npre;": "⪯̸",6156 "nsce;": "⪰̸",6157 "Nscr;": "ð©",6158 "nscr;": "ð",6159 "nsim;": "â",6160 "nsub;": "â",6161 "nsup;": "â
",6162 "ntgl;": "â¹",6163 "ntlg;": "â¸",6164 "nvap;": "ââ",6165 "nvge;": "â¥â",6166 "nvgt;": ">â",6167 "nvle;": "â¤â",6168 "nvlt;": "<â",6169 "oast;": "â",6170 "ocir;": "â",6171 Ocirc: "Ã",6172 ocirc: "ô",6173 "odiv;": "⨸",6174 "odot;": "â",6175 "ogon;": "Ë",6176 "oint;": "â®",6177 "omid;": "⦶",6178 "Oopf;": "ð",6179 "oopf;": "ð ",6180 "opar;": "⦷",6181 "ordf;": "ª",6182 "ordm;": "º",6183 "oror;": "â©",6184 "Oscr;": "ðª",6185 "oscr;": "â´",6186 "osol;": "â",6187 "Ouml;": "Ã",6188 "ouml;": "ö",6189 "para;": "¶",6190 "part;": "â",6191 "perp;": "â¥",6192 "phiv;": "Ï",6193 "plus;": "+",6194 "Popf;": "â",6195 "popf;": "ð¡",6196 pound: "£",6197 "prap;": "⪷",6198 "prec;": "âº",6199 "prnE;": "⪵",6200 "prod;": "â",6201 "prop;": "â",6202 "Pscr;": "ð«",6203 "pscr;": "ð
",6204 "qint;": "â¨",6205 "Qopf;": "â",6206 "qopf;": "ð¢",6207 "Qscr;": "ð¬",6208 "qscr;": "ð",6209 "QUOT;": "\"",6210 "quot;": "\"",6211 "race;": "â½Ì±",6212 "Rang;": "â«",6213 "rang;": "â©",6214 raquo: "»",6215 "Rarr;": "â ",6216 "rArr;": "â",6217 "rarr;": "â",6218 "rcub;": "}",6219 "rdca;": "⤷",6220 "rdsh;": "â³",6221 "real;": "â",6222 "rect;": "â",6223 "rHar;": "⥤",6224 "rhov;": "ϱ",6225 "ring;": "Ë",6226 "Ropf;": "â",6227 "ropf;": "ð£",6228 "rpar;": ")",6229 "Rscr;": "â",6230 "rscr;": "ð",6231 "rsqb;": "]",6232 "rtri;": "â¹",6233 "scap;": "⪸",6234 "scnE;": "⪶",6235 "sdot;": "â
",6236 "sect;": "§",6237 "semi;": ";",6238 "sext;": "â¶",6239 "SHcy;": "Ш",6240 "shcy;": "Ñ",6241 "sime;": "â",6242 "simg;": "âª",6243 "siml;": "âª",6244 "smid;": "â£",6245 "smte;": "⪬",6246 "solb;": "â§",6247 "Sopf;": "ð",6248 "sopf;": "ð¤",6249 "spar;": "â¥",6250 "Sqrt;": "â",6251 "squf;": "âª",6252 "Sscr;": "ð®",6253 "sscr;": "ð",6254 "Star;": "â",6255 "star;": "â",6256 "subE;": "â«
",6257 "sube;": "â",6258 "succ;": "â»",6259 "sung;": "âª",6260 "sup1;": "¹",6261 "sup2;": "²",6262 "sup3;": "³",6263 "supE;": "â«",6264 "supe;": "â",6265 szlig: "Ã",6266 "tbrk;": "â´",6267 "tdot;": "â",6268 THORN: "Ã",6269 thorn: "þ",6270 times: "Ã",6271 "tint;": "â",6272 "toea;": "⤨",6273 "Topf;": "ð",6274 "topf;": "ð¥",6275 "tosa;": "⤩",6276 "trie;": "â",6277 "Tscr;": "ð¯",6278 "tscr;": "ð",6279 "TScy;": "Ц",6280 "tscy;": "Ñ",6281 "Uarr;": "â",6282 "uArr;": "â",6283 "uarr;": "â",6284 Ucirc: "Ã",6285 ucirc: "û",6286 "uHar;": "⥣",6287 "Uopf;": "ð",6288 "uopf;": "ð¦",6289 "Upsi;": "Ï",6290 "upsi;": "Ï
",6291 "Uscr;": "ð°",6292 "uscr;": "ð",6293 "utri;": "âµ",6294 "Uuml;": "Ã",6295 "uuml;": "ü",6296 "vArr;": "â",6297 "varr;": "â",6298 "Vbar;": "â««",6299 "vBar;": "⫨",6300 "Vert;": "â",6301 "vert;": "|",6302 "Vopf;": "ð",6303 "vopf;": "ð§",6304 "Vscr;": "ð±",6305 "vscr;": "ð",6306 "Wopf;": "ð",6307 "wopf;": "ð¨",6308 "Wscr;": "ð²",6309 "wscr;": "ð",6310 "xcap;": "â",6311 "xcup;": "â",6312 "xmap;": "â¼",6313 "xnis;": "â»",6314 "Xopf;": "ð",6315 "xopf;": "ð©",6316 "Xscr;": "ð³",6317 "xscr;": "ð",6318 "xvee;": "â",6319 "YAcy;": "Я",6320 "yacy;": "Ñ",6321 "YIcy;": "Ð",6322 "yicy;": "Ñ",6323 "Yopf;": "ð",6324 "yopf;": "ðª",6325 "Yscr;": "ð´",6326 "yscr;": "ð",6327 "YUcy;": "Ю",6328 "yucy;": "Ñ",6329 "Yuml;": "Ÿ",6330 "yuml;": "ÿ",6331 "Zdot;": "Å»",6332 "zdot;": "ż",6333 "Zeta;": "Î",6334 "zeta;": "ζ",6335 "ZHcy;": "Ð",6336 "zhcy;": "ж",6337 "Zopf;": "â¤",6338 "zopf;": "ð«",6339 "Zscr;": "ðµ",6340 "zscr;": "ð",6341 "zwnj;": "â",6342 Aacute: "Ã",6343 aacute: "á",6344 "Acirc;": "Ã",6345 "acirc;": "â",6346 "acute;": "´",6347 "AElig;": "Ã",6348 "aelig;": "æ",6349 Agrave: "Ã",6350 agrave: "à ",6351 "aleph;": "âµ",6352 "Alpha;": "Î",6353 "alpha;": "α",6354 "Amacr;": "Ä",6355 "amacr;": "Ä",6356 "amalg;": "⨿",6357 "angle;": "â ",6358 "angrt;": "â",6359 "angst;": "Ã
",6360 "Aogon;": "Ä",6361 "aogon;": "Ä
",6362 "Aring;": "Ã
",6363 "aring;": "Ã¥",6364 "asymp;": "â",6365 Atilde: "Ã",6366 atilde: "ã",6367 "awint;": "â¨",6368 "bcong;": "â",6369 "bdquo;": "â",6370 "bepsi;": "϶",6371 "blank;": "â£",6372 "blk12;": "â",6373 "blk14;": "â",6374 "blk34;": "â",6375 "block;": "â",6376 "boxDL;": "â",6377 "boxDl;": "â",6378 "boxdL;": "â",6379 "boxdl;": "â",6380 "boxDR;": "â",6381 "boxDr;": "â",6382 "boxdR;": "â",6383 "boxdr;": "â",6384 "boxHD;": "â¦",6385 "boxHd;": "â¤",6386 "boxhD;": "â¥",6387 "boxhd;": "â¬",6388 "boxHU;": "â©",6389 "boxHu;": "â§",6390 "boxhU;": "â¨",6391 "boxhu;": "â´",6392 "boxUL;": "â",6393 "boxUl;": "â",6394 "boxuL;": "â",6395 "boxul;": "â",6396 "boxUR;": "â",6397 "boxUr;": "â",6398 "boxuR;": "â",6399 "boxur;": "â",6400 "boxVH;": "â¬",6401 "boxVh;": "â«",6402 "boxvH;": "âª",6403 "boxvh;": "â¼",6404 "boxVL;": "â£",6405 "boxVl;": "â¢",6406 "boxvL;": "â¡",6407 "boxvl;": "â¤",6408 "boxVR;": "â ",6409 "boxVr;": "â",6410 "boxvR;": "â",6411 "boxvr;": "â",6412 "Breve;": "Ë",6413 "breve;": "Ë",6414 brvbar: "¦",6415 "bsemi;": "â",6416 "bsime;": "â",6417 "bsolb;": "â§
",6418 "bumpE;": "⪮",6419 "bumpe;": "â",6420 "caret;": "â",6421 "caron;": "Ë",6422 "ccaps;": "â©",6423 Ccedil: "Ã",6424 ccedil: "ç",6425 "Ccirc;": "Ä",6426 "ccirc;": "Ä",6427 "ccups;": "â©",6428 "cedil;": "¸",6429 "check;": "â",6430 "clubs;": "â£",6431 "Colon;": "â·",6432 "colon;": ":",6433 "comma;": ",",6434 "crarr;": "âµ",6435 "Cross;": "⨯",6436 "cross;": "â",6437 "csube;": "â«",6438 "csupe;": "â«",6439 "ctdot;": "â¯",6440 "cuepr;": "â",6441 "cuesc;": "â",6442 "cupor;": "â©
",6443 curren: "¤",6444 "cuvee;": "â",6445 "cuwed;": "â",6446 "cwint;": "â±",6447 "Dashv;": "⫤",6448 "dashv;": "â£",6449 "dblac;": "Ë",6450 "ddarr;": "â",6451 "Delta;": "Î",6452 "delta;": "δ",6453 "dharl;": "â",6454 "dharr;": "â",6455 "diams;": "â¦",6456 "disin;": "â²",6457 divide: "÷",6458 "doteq;": "â",6459 "dtdot;": "â±",6460 "dtrif;": "â¾",6461 "duarr;": "âµ",6462 "duhar;": "⥯",6463 Eacute: "Ã",6464 eacute: "é",6465 "Ecirc;": "Ã",6466 "ecirc;": "ê",6467 "eDDot;": "â©·",6468 "efDot;": "â",6469 Egrave: "Ã",6470 egrave: "è",6471 "Emacr;": "Ä",6472 "emacr;": "Ä",6473 "empty;": "â
",6474 "Eogon;": "Ä",6475 "eogon;": "Ä",6476 "eplus;": "⩱",6477 "epsiv;": "ϵ",6478 "eqsim;": "â",6479 "Equal;": "⩵",6480 "equiv;": "â¡",6481 "erarr;": "⥱",6482 "erDot;": "â",6483 "esdot;": "â",6484 "exist;": "â",6485 "fflig;": "ï¬",6486 "filig;": "ï¬",6487 "fjlig;": "fj",6488 "fllig;": "ï¬",6489 "fltns;": "â±",6490 "forkv;": "â«",6491 frac12: "½",6492 frac14: "¼",6493 frac34: "¾",6494 "frasl;": "â",6495 "frown;": "â¢",6496 "Gamma;": "Î",6497 "gamma;": "γ",6498 "Gcirc;": "Ä",6499 "gcirc;": "Ä",6500 "gescc;": "⪩",6501 "gimel;": "â·",6502 "gneqq;": "â©",6503 "gnsim;": "â§",6504 "grave;": "`",6505 "gsime;": "âª",6506 "gsiml;": "âª",6507 "gtcir;": "⩺",6508 "gtdot;": "â",6509 "Hacek;": "Ë",6510 "harrw;": "â",6511 "Hcirc;": "Ĥ",6512 "hcirc;": "Ä¥",6513 "hoarr;": "â¿",6514 Iacute: "Ã",6515 iacute: "Ã",6516 "Icirc;": "Ã",6517 "icirc;": "î",6518 "iexcl;": "¡",6519 Igrave: "Ã",6520 igrave: "ì",6521 "iiint;": "â",6522 "iiota;": "â©",6523 "IJlig;": "IJ",6524 "ijlig;": "ij",6525 "Imacr;": "Ī",6526 "imacr;": "Ä«",6527 "image;": "â",6528 "imath;": "ı",6529 "imped;": "Ƶ",6530 "infin;": "â",6531 "Iogon;": "Ä®",6532 "iogon;": "į",6533 "iprod;": "⨼",6534 iquest: "¿",6535 "isinE;": "â¹",6536 "isins;": "â´",6537 "isinv;": "â",6538 "Iukcy;": "Ð",6539 "iukcy;": "Ñ",6540 "Jcirc;": "Ä´",6541 "jcirc;": "ĵ",6542 "jmath;": "È·",6543 "Jukcy;": "Ð",6544 "jukcy;": "Ñ",6545 "Kappa;": "Î",6546 "kappa;": "κ",6547 "lAarr;": "â",6548 "langd;": "â¦",6549 "laquo;": "«",6550 "larrb;": "â¤",6551 "lates;": "âªï¸",6552 "lBarr;": "â¤",6553 "lbarr;": "â¤",6554 "lbbrk;": "â²",6555 "lbrke;": "â¦",6556 "lceil;": "â",6557 "ldquo;": "â",6558 "lescc;": "⪨",6559 "lhard;": "â½",6560 "lharu;": "â¼",6561 "lhblk;": "â",6562 "llarr;": "â",6563 "lltri;": "âº",6564 "lneqq;": "â¨",6565 "lnsim;": "â¦",6566 "loang;": "â¬",6567 "loarr;": "â½",6568 "lobrk;": "â¦",6569 "lopar;": "â¦
",6570 "lrarr;": "â",6571 "lrhar;": "â",6572 "lrtri;": "â¿",6573 "lsime;": "âª",6574 "lsimg;": "âª",6575 "lsquo;": "â",6576 "ltcir;": "⩹",6577 "ltdot;": "â",6578 "ltrie;": "â´",6579 "ltrif;": "â",6580 "mdash;": "â",6581 "mDDot;": "âº",6582 "micro;": "µ",6583 middot: "·",6584 "minus;": "â",6585 "mumap;": "â¸",6586 "nabla;": "â",6587 "napid;": "â̸",6588 "napos;": "Å",6589 "natur;": "â®",6590 "nbump;": "â̸",6591 "ncong;": "â",6592 "ndash;": "â",6593 "neArr;": "â",6594 "nearr;": "â",6595 "nedot;": "â̸",6596 "nesim;": "â̸",6597 "ngeqq;": "â§Ì¸",6598 "ngsim;": "âµ",6599 "nhArr;": "â",6600 "nharr;": "â®",6601 "nhpar;": "⫲",6602 "nlArr;": "â",6603 "nlarr;": "â",6604 "nleqq;": "â¦Ì¸",6605 "nless;": "â®",6606 "nlsim;": "â´",6607 "nltri;": "âª",6608 "notin;": "â",6609 "notni;": "â",6610 "npart;": "â̸",6611 "nprec;": "â",6612 "nrArr;": "â",6613 "nrarr;": "â",6614 "nrtri;": "â«",6615 "nsime;": "â",6616 "nsmid;": "â¤",6617 "nspar;": "â¦",6618 "nsubE;": "â«
̸",6619 "nsube;": "â",6620 "nsucc;": "â",6621 "nsupE;": "â«Ì¸",6622 "nsupe;": "â",6623 Ntilde: "Ã",6624 ntilde: "ñ",6625 "numsp;": "â",6626 "nvsim;": "â¼â",6627 "nwArr;": "â",6628 "nwarr;": "â",6629 Oacute: "Ã",6630 oacute: "ó",6631 "Ocirc;": "Ã",6632 "ocirc;": "ô",6633 "odash;": "â",6634 "OElig;": "Å",6635 "oelig;": "Å",6636 "ofcir;": "⦿",6637 Ograve: "Ã",6638 ograve: "ò",6639 "ohbar;": "⦵",6640 "olarr;": "âº",6641 "olcir;": "⦾",6642 "oline;": "â¾",6643 "Omacr;": "Å",6644 "omacr;": "Å",6645 "Omega;": "Ω",6646 "omega;": "Ï",6647 "operp;": "⦹",6648 "oplus;": "â",6649 "orarr;": "â»",6650 "order;": "â´",6651 Oslash: "Ã",6652 oslash: "ø",6653 Otilde: "Ã",6654 otilde: "õ",6655 "ovbar;": "â½",6656 "parsl;": "⫽",6657 "phone;": "â",6658 "plusb;": "â",6659 "pluse;": "⩲",6660 plusmn: "±",6661 "pound;": "£",6662 "prcue;": "â¼",6663 "Prime;": "â³",6664 "prime;": "â²",6665 "prnap;": "⪹",6666 "prsim;": "â¾",6667 "quest;": "?",6668 "rAarr;": "â",6669 "radic;": "â",6670 "rangd;": "â¦",6671 "range;": "⦥",6672 "raquo;": "»",6673 "rarrb;": "â¥",6674 "rarrc;": "⤳",6675 "rarrw;": "â",6676 "ratio;": "â¶",6677 "RBarr;": "â¤",6678 "rBarr;": "â¤",6679 "rbarr;": "â¤",6680 "rbbrk;": "â³",6681 "rbrke;": "â¦",6682 "rceil;": "â",6683 "rdquo;": "â",6684 "reals;": "â",6685 "rhard;": "â",6686 "rharu;": "â",6687 "rlarr;": "â",6688 "rlhar;": "â",6689 "rnmid;": "â«®",6690 "roang;": "â",6691 "roarr;": "â¾",6692 "robrk;": "â§",6693 "ropar;": "â¦",6694 "rrarr;": "â",6695 "rsquo;": "â",6696 "rtrie;": "âµ",6697 "rtrif;": "â¸",6698 "sbquo;": "â",6699 "sccue;": "â½",6700 "Scirc;": "Å",6701 "scirc;": "Å",6702 "scnap;": "⪺",6703 "scsim;": "â¿",6704 "sdotb;": "â¡",6705 "sdote;": "⩦",6706 "seArr;": "â",6707 "searr;": "â",6708 "setmn;": "â",6709 "sharp;": "â¯",6710 "Sigma;": "Σ",6711 "sigma;": "Ï",6712 "simeq;": "â",6713 "simgE;": "⪠",6714 "simlE;": "âª",6715 "simne;": "â",6716 "slarr;": "â",6717 "smile;": "â£",6718 "smtes;": "⪬ï¸",6719 "sqcap;": "â",6720 "sqcup;": "â",6721 "sqsub;": "â",6722 "sqsup;": "â",6723 "srarr;": "â",6724 "starf;": "â
",6725 "strns;": "¯",6726 "subnE;": "â«",6727 "subne;": "â",6728 "supnE;": "â«",6729 "supne;": "â",6730 "swArr;": "â",6731 "swarr;": "â",6732 "szlig;": "Ã",6733 "Theta;": "Î",6734 "theta;": "θ",6735 "thkap;": "â",6736 "THORN;": "Ã",6737 "thorn;": "þ",6738 "Tilde;": "â¼",6739 "tilde;": "Ë",6740 "times;": "Ã",6741 "TRADE;": "â¢",6742 "trade;": "â¢",6743 "trisb;": "â§",6744 "TSHcy;": "Ð",6745 "tshcy;": "Ñ",6746 "twixt;": "â¬",6747 Uacute: "Ã",6748 uacute: "ú",6749 "Ubrcy;": "Ð",6750 "ubrcy;": "Ñ",6751 "Ucirc;": "Ã",6752 "ucirc;": "û",6753 "udarr;": "â
",6754 "udhar;": "⥮",6755 Ugrave: "Ã",6756 ugrave: "ù",6757 "uharl;": "â¿",6758 "uharr;": "â¾",6759 "uhblk;": "â",6760 "ultri;": "â¸",6761 "Umacr;": "Ū",6762 "umacr;": "Å«",6763 "Union;": "â",6764 "Uogon;": "Ų",6765 "uogon;": "ų",6766 "uplus;": "â",6767 "upsih;": "Ï",6768 "UpTee;": "â¥",6769 "Uring;": "Å®",6770 "uring;": "ů",6771 "urtri;": "â¹",6772 "utdot;": "â°",6773 "utrif;": "â´",6774 "uuarr;": "â",6775 "varpi;": "Ï",6776 "vBarv;": "â«©",6777 "VDash;": "â«",6778 "Vdash;": "â©",6779 "vDash;": "â¨",6780 "vdash;": "â¢",6781 "veeeq;": "â",6782 "vltri;": "â²",6783 "vnsub;": "ââ",6784 "vnsup;": "ââ",6785 "vprop;": "â",6786 "vrtri;": "â³",6787 "Wcirc;": "Å´",6788 "wcirc;": "ŵ",6789 "Wedge;": "â",6790 "wedge;": "â§",6791 "xcirc;": "â¯",6792 "xdtri;": "â½",6793 "xhArr;": "âº",6794 "xharr;": "â·",6795 "xlArr;": "â¸",6796 "xlarr;": "âµ",6797 "xodot;": "â¨",6798 "xrArr;": "â¹",6799 "xrarr;": "â¶",6800 "xutri;": "â³",6801 Yacute: "Ã",6802 yacute: "ý",6803 "Ycirc;": "Ŷ",6804 "ycirc;": "Å·",6805 "Aacute;": "Ã",6806 "aacute;": "á",6807 "Abreve;": "Ä",6808 "abreve;": "Ä",6809 "Agrave;": "Ã",6810 "agrave;": "à ",6811 "andand;": "â©",6812 "angmsd;": "â¡",6813 "angsph;": "â¢",6814 "apacir;": "⩯",6815 "approx;": "â",6816 "Assign;": "â",6817 "Atilde;": "Ã",6818 "atilde;": "ã",6819 "barvee;": "â½",6820 "Barwed;": "â",6821 "barwed;": "â
",6822 "becaus;": "âµ",6823 "bernou;": "â¬",6824 "bigcap;": "â",6825 "bigcup;": "â",6826 "bigvee;": "â",6827 "bkarow;": "â¤",6828 "bottom;": "â¥",6829 "bowtie;": "â",6830 "boxbox;": "â§",6831 "bprime;": "âµ",6832 "brvbar;": "¦",6833 "bullet;": "â¢",6834 "Bumpeq;": "â",6835 "bumpeq;": "â",6836 "Cacute;": "Ä",6837 "cacute;": "Ä",6838 "capand;": "â©",6839 "capcap;": "â©",6840 "capcup;": "â©",6841 "capdot;": "â©",6842 "Ccaron;": "Ä",6843 "ccaron;": "Ä",6844 "Ccedil;": "Ã",6845 "ccedil;": "ç",6846 "circeq;": "â",6847 "cirmid;": "⫯",6848 "Colone;": "â©´",6849 "colone;": "â",6850 "commat;": "@",6851 "compfn;": "â",6852 "Conint;": "â¯",6853 "conint;": "â®",6854 "coprod;": "â",6855 "copysr;": "â",6856 "cularr;": "â¶",6857 "CupCap;": "â",6858 "cupcap;": "â©",6859 "cupcup;": "â©",6860 "cupdot;": "â",6861 "curarr;": "â·",6862 "curren;": "¤",6863 "cylcty;": "â",6864 "Dagger;": "â¡",6865 "dagger;": "â ",6866 "daleth;": "â¸",6867 "Dcaron;": "Ä",6868 "dcaron;": "Ä",6869 "dfisht;": "⥿",6870 "divide;": "÷",6871 "divonx;": "â",6872 "dlcorn;": "â",6873 "dlcrop;": "â",6874 "dollar;": "$",6875 "DotDot;": "â",6876 "drcorn;": "â",6877 "drcrop;": "â",6878 "Dstrok;": "Ä",6879 "dstrok;": "Ä",6880 "Eacute;": "Ã",6881 "eacute;": "é",6882 "easter;": "â©®",6883 "Ecaron;": "Ä",6884 "ecaron;": "Ä",6885 "ecolon;": "â",6886 "Egrave;": "Ã",6887 "egrave;": "è",6888 "egsdot;": "âª",6889 "elsdot;": "âª",6890 "emptyv;": "â
",6891 "emsp13;": "â",6892 "emsp14;": "â
",6893 "eparsl;": "⧣",6894 "eqcirc;": "â",6895 "equals;": "=",6896 "equest;": "â",6897 "Exists;": "â",6898 "female;": "â",6899 "ffilig;": "ï¬",6900 "ffllig;": "ï¬",6901 "ForAll;": "â",6902 "forall;": "â",6903 "frac12;": "½",6904 "frac13;": "â
",6905 "frac14;": "¼",6906 "frac15;": "â
",6907 "frac16;": "â
",6908 "frac18;": "â
",6909 "frac23;": "â
",6910 "frac25;": "â
",6911 "frac34;": "¾",6912 "frac35;": "â
",6913 "frac38;": "â
",6914 "frac45;": "â
",6915 "frac56;": "â
",6916 "frac58;": "â
",6917 "frac78;": "â
",6918 "gacute;": "ǵ",6919 "Gammad;": "Ï",6920 "gammad;": "Ï",6921 "Gbreve;": "Ä",6922 "gbreve;": "Ä",6923 "Gcedil;": "Ä¢",6924 "gesdot;": "âª",6925 "gesles;": "âª",6926 "gtlPar;": "â¦",6927 "gtrarr;": "⥸",6928 "gtrdot;": "â",6929 "gtrsim;": "â³",6930 "hairsp;": "â",6931 "hamilt;": "â",6932 "HARDcy;": "Ъ",6933 "hardcy;": "Ñ",6934 "hearts;": "â¥",6935 "hellip;": "â¦",6936 "hercon;": "â¹",6937 "homtht;": "â»",6938 "horbar;": "â",6939 "hslash;": "â",6940 "Hstrok;": "Ħ",6941 "hstrok;": "ħ",6942 "hybull;": "â",6943 "hyphen;": "â",6944 "Iacute;": "Ã",6945 "iacute;": "Ã",6946 "Igrave;": "Ã",6947 "igrave;": "ì",6948 "iiiint;": "â¨",6949 "iinfin;": "â§",6950 "incare;": "â
",6951 "inodot;": "ı",6952 "intcal;": "âº",6953 "iquest;": "¿",6954 "isinsv;": "â³",6955 "Itilde;": "Ĩ",6956 "itilde;": "Ä©",6957 "Jsercy;": "Ð",6958 "jsercy;": "Ñ",6959 "kappav;": "Ï°",6960 "Kcedil;": "Ķ",6961 "kcedil;": "Ä·",6962 "kgreen;": "ĸ",6963 "Lacute;": "Ĺ",6964 "lacute;": "ĺ",6965 "lagran;": "â",6966 "Lambda;": "Î",6967 "lambda;": "λ",6968 "langle;": "â¨",6969 "larrfs;": "â¤",6970 "larrhk;": "â©",6971 "larrlp;": "â«",6972 "larrpl;": "⤹",6973 "larrtl;": "â¢",6974 "lAtail;": "â¤",6975 "latail;": "â¤",6976 "lbrace;": "{",6977 "lbrack;": "[",6978 "Lcaron;": "Ľ",6979 "lcaron;": "ľ",6980 "Lcedil;": "Ä»",6981 "lcedil;": "ļ",6982 "ldquor;": "â",6983 "lesdot;": "â©¿",6984 "lesges;": "âª",6985 "lfisht;": "⥼",6986 "lfloor;": "â",6987 "lharul;": "⥪",6988 "llhard;": "⥫",6989 "Lmidot;": "Ä¿",6990 "lmidot;": "Å",6991 "lmoust;": "â°",6992 "loplus;": "â¨",6993 "lowast;": "â",6994 "lowbar;": "_",6995 "lparlt;": "â¦",6996 "lrhard;": "â¥",6997 "lsaquo;": "â¹",6998 "lsquor;": "â",6999 "Lstrok;": "Å",7000 "lstrok;": "Å",7001 "lthree;": "â",7002 "ltimes;": "â",7003 "ltlarr;": "⥶",7004 "ltrPar;": "â¦",7005 "mapsto;": "â¦",7006 "marker;": "â®",7007 "mcomma;": "⨩",7008 "midast;": "*",7009 "midcir;": "â«°",7010 "middot;": "·",7011 "minusb;": "â",7012 "minusd;": "â¸",7013 "mnplus;": "â",7014 "models;": "â§",7015 "mstpos;": "â¾",7016 "Nacute;": "Å",7017 "nacute;": "Å",7018 "nbumpe;": "â̸",7019 "Ncaron;": "Å",7020 "ncaron;": "Å",7021 "Ncedil;": "Å
",7022 "ncedil;": "Å",7023 "nearhk;": "⤤",7024 "nequiv;": "â¢",7025 "nesear;": "⤨",7026 "nexist;": "â",7027 "nltrie;": "â¬",7028 "notinE;": "â¹Ì¸",7029 "nparsl;": "⫽â¥",7030 "nprcue;": "â ",7031 "nrarrc;": "⤳̸",7032 "nrarrw;": "â̸",7033 "nrtrie;": "â",7034 "nsccue;": "â¡",7035 "nsimeq;": "â",7036 "Ntilde;": "Ã",7037 "ntilde;": "ñ",7038 "numero;": "â",7039 "nVDash;": "â¯",7040 "nVdash;": "â®",7041 "nvDash;": "â",7042 "nvdash;": "â¬",7043 "nvHarr;": "â¤",7044 "nvlArr;": "â¤",7045 "nvrArr;": "â¤",7046 "nwarhk;": "⤣",7047 "nwnear;": "⤧",7048 "Oacute;": "Ã",7049 "oacute;": "ó",7050 "Odblac;": "Å",7051 "odblac;": "Å",7052 "odsold;": "⦼",7053 "Ograve;": "Ã",7054 "ograve;": "ò",7055 "ominus;": "â",7056 "origof;": "â¶",7057 "Oslash;": "Ã",7058 "oslash;": "ø",7059 "Otilde;": "Ã",7060 "otilde;": "õ",7061 "Otimes;": "⨷",7062 "otimes;": "â",7063 "parsim;": "⫳",7064 "percnt;": "%",7065 "period;": ".",7066 "permil;": "â°",7067 "phmmat;": "â³",7068 "planck;": "â",7069 "plankv;": "â",7070 "plusdo;": "â",7071 "plusdu;": "⨥",7072 "plusmn;": "±",7073 "preceq;": "⪯",7074 "primes;": "â",7075 "prnsim;": "â¨",7076 "propto;": "â",7077 "prurel;": "â°",7078 "puncsp;": "â",7079 "qprime;": "â",7080 "Racute;": "Å",7081 "racute;": "Å",7082 "rangle;": "â©",7083 "rarrap;": "⥵",7084 "rarrfs;": "â¤",7085 "rarrhk;": "âª",7086 "rarrlp;": "â¬",7087 "rarrpl;": "â¥
",7088 "Rarrtl;": "â¤",7089 "rarrtl;": "â£",7090 "rAtail;": "â¤",7091 "ratail;": "â¤",7092 "rbrace;": "}",7093 "rbrack;": "]",7094 "Rcaron;": "Å",7095 "rcaron;": "Å",7096 "Rcedil;": "Å",7097 "rcedil;": "Å",7098 "rdquor;": "â",7099 "rfisht;": "⥽",7100 "rfloor;": "â",7101 "rharul;": "⥬",7102 "rmoust;": "â±",7103 "roplus;": "⨮",7104 "rpargt;": "â¦",7105 "rsaquo;": "âº",7106 "rsquor;": "â",7107 "rthree;": "â",7108 "rtimes;": "â",7109 "Sacute;": "Å",7110 "sacute;": "Å",7111 "Scaron;": "Å ",7112 "scaron;": "Å¡",7113 "Scedil;": "Å",7114 "scedil;": "Å",7115 "scnsim;": "â©",7116 "searhk;": "⤥",7117 "seswar;": "⤩",7118 "sfrown;": "â¢",7119 "SHCHcy;": "Щ",7120 "shchcy;": "Ñ",7121 "sigmaf;": "Ï",7122 "sigmav;": "Ï",7123 "simdot;": "⩪",7124 "smashp;": "⨳",7125 "SOFTcy;": "Ь",7126 "softcy;": "Ñ",7127 "solbar;": "â¿",7128 "spades;": "â ",7129 "sqcaps;": "âï¸",7130 "sqcups;": "âï¸",7131 "sqsube;": "â",7132 "sqsupe;": "â",7133 "Square;": "â¡",7134 "square;": "â¡",7135 "squarf;": "âª",7136 "ssetmn;": "â",7137 "ssmile;": "â£",7138 "sstarf;": "â",7139 "subdot;": "⪽",7140 "Subset;": "â",7141 "subset;": "â",7142 "subsim;": "â«",7143 "subsub;": "â«",7144 "subsup;": "â«",7145 "succeq;": "⪰",7146 "supdot;": "⪾",7147 "Supset;": "â",7148 "supset;": "â",7149 "supsim;": "â«",7150 "supsub;": "â«",7151 "supsup;": "â«",7152 "swarhk;": "⤦",7153 "swnwar;": "⤪",7154 "target;": "â",7155 "Tcaron;": "Ť",7156 "tcaron;": "Å¥",7157 "Tcedil;": "Å¢",7158 "tcedil;": "Å£",7159 "telrec;": "â",7160 "there4;": "â´",7161 "thetav;": "Ï",7162 "thinsp;": "â",7163 "thksim;": "â¼",7164 "timesb;": "â ",7165 "timesd;": "⨰",7166 "topbot;": "â¶",7167 "topcir;": "⫱",7168 "tprime;": "â´",7169 "tridot;": "â¬",7170 "Tstrok;": "Ŧ",7171 "tstrok;": "ŧ",7172 "Uacute;": "Ã",7173 "uacute;": "ú",7174 "Ubreve;": "Ŭ",7175 "ubreve;": "Å",7176 "Udblac;": "Å°",7177 "udblac;": "ű",7178 "ufisht;": "⥾",7179 "Ugrave;": "Ã",7180 "ugrave;": "ù",7181 "ulcorn;": "â",7182 "ulcrop;": "â",7183 "urcorn;": "â",7184 "urcrop;": "â",7185 "Utilde;": "Ũ",7186 "utilde;": "Å©",7187 "vangrt;": "â¦",7188 "varphi;": "Ï",7189 "varrho;": "ϱ",7190 "Vdashl;": "⫦",7191 "veebar;": "â»",7192 "vellip;": "â®",7193 "Verbar;": "â",7194 "verbar;": "|",7195 "vsubnE;": "â«ï¸",7196 "vsubne;": "âï¸",7197 "vsupnE;": "â«ï¸",7198 "vsupne;": "âï¸",7199 "Vvdash;": "âª",7200 "wedbar;": "â©",7201 "wedgeq;": "â",7202 "weierp;": "â",7203 "wreath;": "â",7204 "xoplus;": "â¨",7205 "xotime;": "â¨",7206 "xsqcup;": "â¨",7207 "xuplus;": "â¨",7208 "xwedge;": "â",7209 "Yacute;": "Ã",7210 "yacute;": "ý",7211 "Zacute;": "Ź",7212 "zacute;": "ź",7213 "Zcaron;": "Ž",7214 "zcaron;": "ž",7215 "zeetrf;": "â¨",7216 "alefsym;": "âµ",7217 "angrtvb;": "â¾",7218 "angzarr;": "â¼",7219 "asympeq;": "â",7220 "backsim;": "â½",7221 "Because;": "âµ",7222 "because;": "âµ",7223 "bemptyv;": "⦰",7224 "between;": "â¬",7225 "bigcirc;": "â¯",7226 "bigodot;": "â¨",7227 "bigstar;": "â
",7228 "bnequiv;": "â¡â¥",7229 "boxplus;": "â",7230 "Cayleys;": "â",7231 "Cconint;": "â°",7232 "ccupssm;": "â©",7233 "Cedilla;": "¸",7234 "cemptyv;": "⦲",7235 "cirscir;": "â§",7236 "coloneq;": "â",7237 "congdot;": "â©",7238 "cudarrl;": "⤸",7239 "cudarrr;": "⤵",7240 "cularrp;": "⤽",7241 "curarrm;": "⤼",7242 "dbkarow;": "â¤",7243 "ddagger;": "â¡",7244 "ddotseq;": "â©·",7245 "demptyv;": "⦱",7246 "Diamond;": "â",7247 "diamond;": "â",7248 "digamma;": "Ï",7249 "dotplus;": "â",7250 "DownTee;": "â¤",7251 "dwangle;": "⦦",7252 "Element;": "â",7253 "Epsilon;": "Î",7254 "epsilon;": "ε",7255 "eqcolon;": "â",7256 "equivDD;": "⩸",7257 "gesdoto;": "âª",7258 "gtquest;": "⩼",7259 "gtrless;": "â·",7260 "harrcir;": "â¥",7261 "Implies;": "â",7262 "intprod;": "⨼",7263 "isindot;": "âµ",7264 "larrbfs;": "â¤",7265 "larrsim;": "⥳",7266 "lbrksld;": "â¦",7267 "lbrkslu;": "â¦",7268 "ldrdhar;": "⥧",7269 "LeftTee;": "â£",7270 "lesdoto;": "âª",7271 "lessdot;": "â",7272 "lessgtr;": "â¶",7273 "lesssim;": "â²",7274 "lotimes;": "⨴",7275 "lozenge;": "â",7276 "ltquest;": "â©»",7277 "luruhar;": "⥦",7278 "maltese;": "â ",7279 "minusdu;": "⨪",7280 "napprox;": "â",7281 "natural;": "â®",7282 "nearrow;": "â",7283 "NewLine;": "\n",7284 "nexists;": "â",7285 "NoBreak;": "â ",7286 "notinva;": "â",7287 "notinvb;": "â·",7288 "notinvc;": "â¶",7289 "NotLess;": "â®",7290 "notniva;": "â",7291 "notnivb;": "â¾",7292 "notnivc;": "â½",7293 "npolint;": "â¨",7294 "npreceq;": "⪯̸",7295 "nsqsube;": "â¢",7296 "nsqsupe;": "â£",7297 "nsubset;": "ââ",7298 "nsucceq;": "⪰̸",7299 "nsupset;": "ââ",7300 "nvinfin;": "â§",7301 "nvltrie;": "â´â",7302 "nvrtrie;": "âµâ",7303 "nwarrow;": "â",7304 "olcross;": "⦻",7305 "Omicron;": "Î",7306 "omicron;": "ο",7307 "orderof;": "â´",7308 "orslope;": "â©",7309 "OverBar;": "â¾",7310 "pertenk;": "â±",7311 "planckh;": "â",7312 "pluscir;": "⨢",7313 "plussim;": "⨦",7314 "plustwo;": "⨧",7315 "precsim;": "â¾",7316 "Product;": "â",7317 "quatint;": "â¨",7318 "questeq;": "â",7319 "rarrbfs;": "⤠",7320 "rarrsim;": "⥴",7321 "rbrksld;": "â¦",7322 "rbrkslu;": "â¦",7323 "rdldhar;": "⥩",7324 "realine;": "â",7325 "rotimes;": "⨵",7326 "ruluhar;": "⥨",7327 "searrow;": "â",7328 "simplus;": "⨤",7329 "simrarr;": "⥲",7330 "subedot;": "â«",7331 "submult;": "â«",7332 "subplus;": "⪿",7333 "subrarr;": "⥹",7334 "succsim;": "â¿",7335 "supdsub;": "â«",7336 "supedot;": "â«",7337 "suphsol;": "â",7338 "suphsub;": "â«",7339 "suplarr;": "⥻",7340 "supmult;": "â«",7341 "supplus;": "â«",7342 "swarrow;": "â",7343 "topfork;": "â«",7344 "triplus;": "⨹",7345 "tritime;": "⨻",7346 "UpArrow;": "â",7347 "Uparrow;": "â",7348 "uparrow;": "â",7349 "Upsilon;": "Î¥",7350 "upsilon;": "Ï
",7351 "uwangle;": "⦧",7352 "vzigzag;": "â¦",7353 "zigrarr;": "â",7354 "andslope;": "â©",7355 "angmsdaa;": "⦨",7356 "angmsdab;": "⦩",7357 "angmsdac;": "⦪",7358 "angmsdad;": "⦫",7359 "angmsdae;": "⦬",7360 "angmsdaf;": "â¦",7361 "angmsdag;": "⦮",7362 "angmsdah;": "⦯",7363 "angrtvbd;": "â¦",7364 "approxeq;": "â",7365 "awconint;": "â³",7366 "backcong;": "â",7367 "barwedge;": "â
",7368 "bbrktbrk;": "â¶",7369 "bigoplus;": "â¨",7370 "bigsqcup;": "â¨",7371 "biguplus;": "â¨",7372 "bigwedge;": "â",7373 "boxminus;": "â",7374 "boxtimes;": "â ",7375 "bsolhsub;": "â",7376 "capbrcup;": "â©",7377 "circledR;": "®",7378 "circledS;": "â",7379 "cirfnint;": "â¨",7380 "clubsuit;": "â£",7381 "cupbrcap;": "â©",7382 "curlyvee;": "â",7383 "cwconint;": "â²",7384 "DDotrahd;": "â¤",7385 "doteqdot;": "â",7386 "DotEqual;": "â",7387 "dotminus;": "â¸",7388 "drbkarow;": "â¤",7389 "dzigrarr;": "â¿",7390 "elinters;": "â§",7391 "emptyset;": "â
",7392 "eqvparsl;": "⧥",7393 "fpartint;": "â¨",7394 "geqslant;": "⩾",7395 "gesdotol;": "âª",7396 "gnapprox;": "âª",7397 "hksearow;": "⤥",7398 "hkswarow;": "⤦",7399 "imagline;": "â",7400 "imagpart;": "â",7401 "infintie;": "â§",7402 "integers;": "â¤",7403 "Integral;": "â«",7404 "intercal;": "âº",7405 "intlarhk;": "â¨",7406 "laemptyv;": "⦴",7407 "ldrushar;": "â¥",7408 "leqslant;": "⩽",7409 "lesdotor;": "âª",7410 "LessLess;": "⪡",7411 "llcorner;": "â",7412 "lnapprox;": "âª",7413 "lrcorner;": "â",7414 "lurdshar;": "â¥",7415 "mapstoup;": "â¥",7416 "multimap;": "â¸",7417 "naturals;": "â",7418 "ncongdot;": "â©Ì¸",7419 "NotEqual;": "â ",7420 "notindot;": "âµÌ¸",7421 "NotTilde;": "â",7422 "otimesas;": "⨶",7423 "parallel;": "â¥",7424 "PartialD;": "â",7425 "plusacir;": "⨣",7426 "pointint;": "â¨",7427 "Precedes;": "âº",7428 "precneqq;": "⪵",7429 "precnsim;": "â¨",7430 "profalar;": "â®",7431 "profline;": "â",7432 "profsurf;": "â",7433 "raemptyv;": "⦳",7434 "realpart;": "â",7435 "RightTee;": "â¢",7436 "rppolint;": "â¨",7437 "rtriltri;": "â§",7438 "scpolint;": "â¨",7439 "setminus;": "â",7440 "shortmid;": "â£",7441 "smeparsl;": "⧤",7442 "sqsubset;": "â",7443 "sqsupset;": "â",7444 "subseteq;": "â",7445 "Succeeds;": "â»",7446 "succneqq;": "⪶",7447 "succnsim;": "â©",7448 "SuchThat;": "â",7449 "Superset;": "â",7450 "supseteq;": "â",7451 "thetasym;": "Ï",7452 "thicksim;": "â¼",7453 "timesbar;": "⨱",7454 "triangle;": "âµ",7455 "triminus;": "⨺",7456 "trpezium;": "â¢",7457 "Uarrocir;": "â¥",7458 "ulcorner;": "â",7459 "UnderBar;": "_",7460 "urcorner;": "â",7461 "varkappa;": "Ï°",7462 "varsigma;": "Ï",7463 "vartheta;": "Ï",7464 "backprime;": "âµ",7465 "backsimeq;": "â",7466 "Backslash;": "â",7467 "bigotimes;": "â¨",7468 "CenterDot;": "·",7469 "centerdot;": "·",7470 "checkmark;": "â",7471 "CircleDot;": "â",7472 "complexes;": "â",7473 "Congruent;": "â¡",7474 "Coproduct;": "â",7475 "dotsquare;": "â¡",7476 "DoubleDot;": "¨",7477 "DownArrow;": "â",7478 "Downarrow;": "â",7479 "downarrow;": "â",7480 "DownBreve;": "Ì",7481 "gtrapprox;": "âª",7482 "gtreqless;": "â",7483 "gvertneqq;": "â©ï¸",7484 "heartsuit;": "â¥",7485 "HumpEqual;": "â",7486 "LeftArrow;": "â",7487 "Leftarrow;": "â",7488 "leftarrow;": "â",7489 "LeftFloor;": "â",7490 "lesseqgtr;": "â",7491 "LessTilde;": "â²",7492 "lvertneqq;": "â¨ï¸",7493 "Mellintrf;": "â³",7494 "MinusPlus;": "â",7495 "ngeqslant;": "⩾̸",7496 "nleqslant;": "⩽̸",7497 "NotCupCap;": "â",7498 "NotExists;": "â",7499 "NotSubset;": "ââ",7500 "nparallel;": "â¦",7501 "nshortmid;": "â¤",7502 "nsubseteq;": "â",7503 "nsupseteq;": "â",7504 "OverBrace;": "â",7505 "pitchfork;": "â",7506 "PlusMinus;": "±",7507 "rationals;": "â",7508 "spadesuit;": "â ",7509 "subseteqq;": "â«
",7510 "subsetneq;": "â",7511 "supseteqq;": "â«",7512 "supsetneq;": "â",7513 "Therefore;": "â´",7514 "therefore;": "â´",7515 "ThinSpace;": "â",7516 "triangleq;": "â",7517 "TripleDot;": "â",7518 "UnionPlus;": "â",7519 "varpropto;": "â",7520 "Bernoullis;": "â¬",7521 "circledast;": "â",7522 "CirclePlus;": "â",7523 "complement;": "â",7524 "curlywedge;": "â",7525 "eqslantgtr;": "âª",7526 "EqualTilde;": "â",7527 "Fouriertrf;": "â±",7528 "gtreqqless;": "âª",7529 "ImaginaryI;": "â
",7530 "Laplacetrf;": "â",7531 "LeftVector;": "â¼",7532 "lessapprox;": "âª
",7533 "lesseqqgtr;": "âª",7534 "Lleftarrow;": "â",7535 "lmoustache;": "â°",7536 "longmapsto;": "â¼",7537 "mapstodown;": "â§",7538 "mapstoleft;": "â¤",7539 "nLeftarrow;": "â",7540 "nleftarrow;": "â",7541 "NotElement;": "â",7542 "NotGreater;": "â¯",7543 "nsubseteqq;": "â«
̸",7544 "nsupseteqq;": "â«Ì¸",7545 "precapprox;": "⪷",7546 "Proportion;": "â·",7547 "RightArrow;": "â",7548 "Rightarrow;": "â",7549 "rightarrow;": "â",7550 "RightFloor;": "â",7551 "rmoustache;": "â±",7552 "sqsubseteq;": "â",7553 "sqsupseteq;": "â",7554 "subsetneqq;": "â«",7555 "succapprox;": "⪸",7556 "supsetneqq;": "â«",7557 "ThickSpace;": "ââ",7558 "TildeEqual;": "â",7559 "TildeTilde;": "â",7560 "UnderBrace;": "â",7561 "UpArrowBar;": "â¤",7562 "UpTeeArrow;": "â¥",7563 "upuparrows;": "â",7564 "varepsilon;": "ϵ",7565 "varnothing;": "â
",7566 "backepsilon;": "϶",7567 "blacksquare;": "âª",7568 "circledcirc;": "â",7569 "circleddash;": "â",7570 "CircleMinus;": "â",7571 "CircleTimes;": "â",7572 "curlyeqprec;": "â",7573 "curlyeqsucc;": "â",7574 "diamondsuit;": "â¦",7575 "eqslantless;": "âª",7576 "Equilibrium;": "â",7577 "expectation;": "â°",7578 "GreaterLess;": "â·",7579 "LeftCeiling;": "â",7580 "LessGreater;": "â¶",7581 "MediumSpace;": "â",7582 "NotLessLess;": "âªÌ¸",7583 "NotPrecedes;": "â",7584 "NotSucceeds;": "â",7585 "NotSuperset;": "ââ",7586 "nRightarrow;": "â",7587 "nrightarrow;": "â",7588 "OverBracket;": "â´",7589 "preccurlyeq;": "â¼",7590 "precnapprox;": "⪹",7591 "quaternions;": "â",7592 "RightVector;": "â",7593 "Rrightarrow;": "â",7594 "RuleDelayed;": "⧴",7595 "SmallCircle;": "â",7596 "SquareUnion;": "â",7597 "straightphi;": "Ï",7598 "SubsetEqual;": "â",7599 "succcurlyeq;": "â½",7600 "succnapprox;": "⪺",7601 "thickapprox;": "â",7602 "UpDownArrow;": "â",7603 "Updownarrow;": "â",7604 "updownarrow;": "â",7605 "VerticalBar;": "â£",7606 "blacklozenge;": "⧫",7607 "DownArrowBar;": "â¤",7608 "DownTeeArrow;": "â§",7609 "ExponentialE;": "â
",7610 "exponentiale;": "â
",7611 "GreaterEqual;": "â¥",7612 "GreaterTilde;": "â³",7613 "HilbertSpace;": "â",7614 "HumpDownHump;": "â",7615 "Intersection;": "â",7616 "LeftArrowBar;": "â¤",7617 "LeftTeeArrow;": "â¤",7618 "LeftTriangle;": "â²",7619 "LeftUpVector;": "â¿",7620 "NotCongruent;": "â¢",7621 "NotHumpEqual;": "â̸",7622 "NotLessEqual;": "â°",7623 "NotLessTilde;": "â´",7624 "Proportional;": "â",7625 "RightCeiling;": "â",7626 "risingdotseq;": "â",7627 "RoundImplies;": "⥰",7628 "ShortUpArrow;": "â",7629 "SquareSubset;": "â",7630 "triangledown;": "â¿",7631 "triangleleft;": "â",7632 "UnderBracket;": "âµ",7633 "varsubsetneq;": "âï¸",7634 "varsupsetneq;": "âï¸",7635 "VerticalLine;": "|",7636 "ApplyFunction;": "â¡",7637 "bigtriangleup;": "â³",7638 "blacktriangle;": "â´",7639 "DifferentialD;": "â
",7640 "divideontimes;": "â",7641 "DoubleLeftTee;": "⫤",7642 "DoubleUpArrow;": "â",7643 "fallingdotseq;": "â",7644 "hookleftarrow;": "â©",7645 "leftarrowtail;": "â¢",7646 "leftharpoonup;": "â¼",7647 "LeftTeeVector;": "â¥",7648 "LeftVectorBar;": "â¥",7649 "LessFullEqual;": "â¦",7650 "LongLeftArrow;": "âµ",7651 "Longleftarrow;": "â¸",7652 "longleftarrow;": "âµ",7653 "looparrowleft;": "â«",7654 "measuredangle;": "â¡",7655 "NotEqualTilde;": "â̸",7656 "NotTildeEqual;": "â",7657 "NotTildeTilde;": "â",7658 "ntriangleleft;": "âª",7659 "Poincareplane;": "â",7660 "PrecedesEqual;": "⪯",7661 "PrecedesTilde;": "â¾",7662 "RightArrowBar;": "â¥",7663 "RightTeeArrow;": "â¦",7664 "RightTriangle;": "â³",7665 "RightUpVector;": "â¾",7666 "shortparallel;": "â¥",7667 "smallsetminus;": "â",7668 "SucceedsEqual;": "⪰",7669 "SucceedsTilde;": "â¿",7670 "SupersetEqual;": "â",7671 "triangleright;": "â¹",7672 "UpEquilibrium;": "⥮",7673 "upharpoonleft;": "â¿",7674 "varsubsetneqq;": "â«ï¸",7675 "varsupsetneqq;": "â«ï¸",7676 "VerticalTilde;": "â",7677 "VeryThinSpace;": "â",7678 "curvearrowleft;": "â¶",7679 "DiacriticalDot;": "Ë",7680 "doublebarwedge;": "â",7681 "DoubleRightTee;": "â¨",7682 "downdownarrows;": "â",7683 "DownLeftVector;": "â½",7684 "GreaterGreater;": "⪢",7685 "hookrightarrow;": "âª",7686 "HorizontalLine;": "â",7687 "InvisibleComma;": "â£",7688 "InvisibleTimes;": "â¢",7689 "LeftDownVector;": "â",7690 "leftleftarrows;": "â",7691 "LeftRightArrow;": "â",7692 "Leftrightarrow;": "â",7693 "leftrightarrow;": "â",7694 "leftthreetimes;": "â",7695 "LessSlantEqual;": "⩽",7696 "LongRightArrow;": "â¶",7697 "Longrightarrow;": "â¹",7698 "longrightarrow;": "â¶",7699 "looparrowright;": "â¬",7700 "LowerLeftArrow;": "â",7701 "NestedLessLess;": "âª",7702 "NotGreaterLess;": "â¹",7703 "NotLessGreater;": "â¸",7704 "NotSubsetEqual;": "â",7705 "NotVerticalBar;": "â¤",7706 "nshortparallel;": "â¦",7707 "ntriangleright;": "â«",7708 "OpenCurlyQuote;": "â",7709 "ReverseElement;": "â",7710 "rightarrowtail;": "â£",7711 "rightharpoonup;": "â",7712 "RightTeeVector;": "â¥",7713 "RightVectorBar;": "â¥",7714 "ShortDownArrow;": "â",7715 "ShortLeftArrow;": "â",7716 "SquareSuperset;": "â",7717 "TildeFullEqual;": "â
",7718 "trianglelefteq;": "â´",7719 "upharpoonright;": "â¾",7720 "UpperLeftArrow;": "â",7721 "ZeroWidthSpace;": "â",7722 "bigtriangledown;": "â½",7723 "circlearrowleft;": "âº",7724 "CloseCurlyQuote;": "â",7725 "ContourIntegral;": "â®",7726 "curvearrowright;": "â·",7727 "DoubleDownArrow;": "â",7728 "DoubleLeftArrow;": "â",7729 "downharpoonleft;": "â",7730 "DownRightVector;": "â",7731 "leftharpoondown;": "â½",7732 "leftrightarrows;": "â",7733 "LeftRightVector;": "â¥",7734 "LeftTriangleBar;": "â§",7735 "LeftUpTeeVector;": "⥠",7736 "LeftUpVectorBar;": "â¥",7737 "LowerRightArrow;": "â",7738 "nLeftrightarrow;": "â",7739 "nleftrightarrow;": "â®",7740 "NotGreaterEqual;": "â±",7741 "NotGreaterTilde;": "âµ",7742 "NotHumpDownHump;": "â̸",7743 "NotLeftTriangle;": "âª",7744 "NotSquareSubset;": "â̸",7745 "ntrianglelefteq;": "â¬",7746 "OverParenthesis;": "â",7747 "RightDownVector;": "â",7748 "rightleftarrows;": "â",7749 "rightsquigarrow;": "â",7750 "rightthreetimes;": "â",7751 "ShortRightArrow;": "â",7752 "straightepsilon;": "ϵ",7753 "trianglerighteq;": "âµ",7754 "UpperRightArrow;": "â",7755 "vartriangleleft;": "â²",7756 "circlearrowright;": "â»",7757 "DiacriticalAcute;": "´",7758 "DiacriticalGrave;": "`",7759 "DiacriticalTilde;": "Ë",7760 "DoubleRightArrow;": "â",7761 "DownArrowUpArrow;": "âµ",7762 "downharpoonright;": "â",7763 "EmptySmallSquare;": "â»",7764 "GreaterEqualLess;": "â",7765 "GreaterFullEqual;": "â§",7766 "LeftAngleBracket;": "â¨",7767 "LeftUpDownVector;": "â¥",7768 "LessEqualGreater;": "â",7769 "NonBreakingSpace;": " ",7770 "NotPrecedesEqual;": "⪯̸",7771 "NotRightTriangle;": "â«",7772 "NotSucceedsEqual;": "⪰̸",7773 "NotSucceedsTilde;": "â¿Ì¸",7774 "NotSupersetEqual;": "â",7775 "ntrianglerighteq;": "â",7776 "rightharpoondown;": "â",7777 "rightrightarrows;": "â",7778 "RightTriangleBar;": "â§",7779 "RightUpTeeVector;": "â¥",7780 "RightUpVectorBar;": "â¥",7781 "twoheadleftarrow;": "â",7782 "UnderParenthesis;": "â",7783 "UpArrowDownArrow;": "â
",7784 "vartriangleright;": "â³",7785 "blacktriangledown;": "â¾",7786 "blacktriangleleft;": "â",7787 "DoubleUpDownArrow;": "â",7788 "DoubleVerticalBar;": "â¥",7789 "DownLeftTeeVector;": "â¥",7790 "DownLeftVectorBar;": "â¥",7791 "FilledSmallSquare;": "â¼",7792 "GreaterSlantEqual;": "⩾",7793 "LeftDoubleBracket;": "â¦",7794 "LeftDownTeeVector;": "⥡",7795 "LeftDownVectorBar;": "â¥",7796 "leftrightharpoons;": "â",7797 "LeftTriangleEqual;": "â´",7798 "NegativeThinSpace;": "â",7799 "NotGreaterGreater;": "â«Ì¸",7800 "NotLessSlantEqual;": "⩽̸",7801 "NotNestedLessLess;": "⪡̸",7802 "NotReverseElement;": "â",7803 "NotSquareSuperset;": "â̸",7804 "NotTildeFullEqual;": "â",7805 "RightAngleBracket;": "â©",7806 "rightleftharpoons;": "â",7807 "RightUpDownVector;": "â¥",7808 "SquareSubsetEqual;": "â",7809 "twoheadrightarrow;": "â ",7810 "VerticalSeparator;": "â",7811 "blacktriangleright;": "â¸",7812 "DownRightTeeVector;": "â¥",7813 "DownRightVectorBar;": "â¥",7814 "LongLeftRightArrow;": "â·",7815 "Longleftrightarrow;": "âº",7816 "longleftrightarrow;": "â·",7817 "NegativeThickSpace;": "â",7818 "NotLeftTriangleBar;": "â§Ì¸",7819 "PrecedesSlantEqual;": "â¼",7820 "ReverseEquilibrium;": "â",7821 "RightDoubleBracket;": "â§",7822 "RightDownTeeVector;": "â¥",7823 "RightDownVectorBar;": "â¥",7824 "RightTriangleEqual;": "âµ",7825 "SquareIntersection;": "â",7826 "SucceedsSlantEqual;": "â½",7827 "DoubleLongLeftArrow;": "â¸",7828 "DownLeftRightVector;": "â¥",7829 "LeftArrowRightArrow;": "â",7830 "leftrightsquigarrow;": "â",7831 "NegativeMediumSpace;": "â",7832 "NotGreaterFullEqual;": "â§Ì¸",7833 "NotRightTriangleBar;": "â§Ì¸",7834 "RightArrowLeftArrow;": "â",7835 "SquareSupersetEqual;": "â",7836 "CapitalDifferentialD;": "â
",7837 "DoubleLeftRightArrow;": "â",7838 "DoubleLongRightArrow;": "â¹",7839 "EmptyVerySmallSquare;": "â«",7840 "NestedGreaterGreater;": "â«",7841 "NotDoubleVerticalBar;": "â¦",7842 "NotGreaterSlantEqual;": "⩾̸",7843 "NotLeftTriangleEqual;": "â¬",7844 "NotSquareSubsetEqual;": "â¢",7845 "OpenCurlyDoubleQuote;": "â",7846 "ReverseUpEquilibrium;": "⥯",7847 "CloseCurlyDoubleQuote;": "â",7848 "DoubleContourIntegral;": "â¯",7849 "FilledVerySmallSquare;": "âª",7850 "NegativeVeryThinSpace;": "â",7851 "NotPrecedesSlantEqual;": "â ",7852 "NotRightTriangleEqual;": "â",7853 "NotSucceedsSlantEqual;": "â¡",7854 "DiacriticalDoubleAcute;": "Ë",7855 "NotSquareSupersetEqual;": "â£",7856 "NotNestedGreaterGreater;": "⪢̸",7857 "ClockwiseContourIntegral;": "â²",7858 "DoubleLongLeftRightArrow;": "âº",7859 "CounterClockwiseContourIntegral;": "â³"7860};7861// lazy compute this to make this file tree-shakable for browser7862let maxCRNameLength;7863const decodeHtml = (rawText, asAttr) => {7864 let offset = 0;7865 const end = rawText.length;7866 let decodedText = '';7867 function advance(length) {7868 offset += length;7869 rawText = rawText.slice(length);7870 }7871 while (offset < end) {7872 const head = /&(?:#x?)?/i.exec(rawText);7873 if (!head || offset + head.index >= end) {7874 const remaining = end - offset;7875 decodedText += rawText.slice(0, remaining);7876 advance(remaining);7877 break;7878 }7879 // Advance to the "&".7880 decodedText += rawText.slice(0, head.index);7881 advance(head.index);7882 if (head[0] === '&') {7883 // Named character reference.7884 let name = '';7885 let value = undefined;7886 if (/[0-9a-z]/i.test(rawText[1])) {7887 if (!maxCRNameLength) {7888 maxCRNameLength = Object.keys(namedCharacterReferences).reduce((max, name) => Math.max(max, name.length), 0);7889 }7890 for (let length = maxCRNameLength; !value && length > 0; --length) {7891 name = rawText.slice(1, 1 + length);7892 value = namedCharacterReferences[name];7893 }7894 if (value) {7895 const semi = name.endsWith(';');7896 if (asAttr &&7897 !semi &&7898 /[=a-z0-9]/i.test(rawText[name.length + 1] || '')) {7899 decodedText += '&' + name;7900 advance(1 + name.length);7901 }7902 else {7903 decodedText += value;7904 advance(1 + name.length);7905 }7906 }7907 else {7908 decodedText += '&' + name;7909 advance(1 + name.length);7910 }7911 }7912 else {7913 decodedText += '&';7914 advance(1);7915 }7916 }7917 else {7918 // Numeric character reference.7919 const hex = head[0] === '&#x';7920 const pattern = hex ? /^&#x([0-9a-f]+);?/i : /^&#([0-9]+);?/;7921 const body = pattern.exec(rawText);7922 if (!body) {7923 decodedText += head[0];7924 advance(head[0].length);7925 }7926 else {7927 // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state7928 let cp = Number.parseInt(body[1], hex ? 16 : 10);7929 if (cp === 0) {7930 cp = 0xfffd;7931 }7932 else if (cp > 0x10ffff) {7933 cp = 0xfffd;7934 }7935 else if (cp >= 0xd800 && cp <= 0xdfff) {7936 cp = 0xfffd;7937 }7938 else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) ;7939 else if ((cp >= 0x01 && cp <= 0x08) ||7940 cp === 0x0b ||7941 (cp >= 0x0d && cp <= 0x1f) ||7942 (cp >= 0x7f && cp <= 0x9f)) {7943 cp = CCR_REPLACEMENTS[cp] || cp;7944 }7945 decodedText += String.fromCodePoint(cp);7946 advance(body[0].length);7947 }7948 }7949 }7950 return decodedText;7951};7952// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state7953const CCR_REPLACEMENTS = {7954 0x80: 0x20ac,7955 0x82: 0x201a,7956 0x83: 0x0192,7957 0x84: 0x201e,7958 0x85: 0x2026,7959 0x86: 0x2020,7960 0x87: 0x2021,7961 0x88: 0x02c6,7962 0x89: 0x2030,7963 0x8a: 0x0160,7964 0x8b: 0x2039,7965 0x8c: 0x0152,7966 0x8e: 0x017d,7967 0x91: 0x2018,7968 0x92: 0x2019,7969 0x93: 0x201c,7970 0x94: 0x201d,7971 0x95: 0x2022,7972 0x96: 0x2013,7973 0x97: 0x2014,7974 0x98: 0x02dc,7975 0x99: 0x2122,7976 0x9a: 0x0161,7977 0x9b: 0x203a,7978 0x9c: 0x0153,7979 0x9e: 0x017e,7980 0x9f: 0x01787981};7982const isRawTextContainer = /*#__PURE__*/ shared.makeMap('style,iframe,script,noscript', true);7983const parserOptions = {7984 isVoidTag: shared.isVoidTag,7985 isNativeTag: tag => shared.isHTMLTag(tag) || shared.isSVGTag(tag),7986 isPreTag: tag => tag === 'pre',7987 decodeEntities: decodeHtml,7988 isBuiltInComponent: (tag) => {7989 if (compilerCore.isBuiltInType(tag, `Transition`)) {7990 return TRANSITION;7991 }7992 else if (compilerCore.isBuiltInType(tag, `TransitionGroup`)) {7993 return TRANSITION_GROUP;7994 }7995 },7996 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher7997 getNamespace(tag, parent) {7998 let ns = parent ? parent.ns : 0 /* HTML */;7999 if (parent && ns === 2 /* MATH_ML */) {8000 if (parent.tag === 'annotation-xml') {8001 if (tag === 'svg') {8002 return 1 /* SVG */;8003 }8004 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&8005 a.name === 'encoding' &&8006 a.value != null &&8007 (a.value.content === 'text/html' ||8008 a.value.content === 'application/xhtml+xml'))) {8009 ns = 0 /* HTML */;8010 }8011 }8012 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&8013 tag !== 'mglyph' &&8014 tag !== 'malignmark') {8015 ns = 0 /* HTML */;8016 }8017 }8018 else if (parent && ns === 1 /* SVG */) {8019 if (parent.tag === 'foreignObject' ||8020 parent.tag === 'desc' ||8021 parent.tag === 'title') {8022 ns = 0 /* HTML */;8023 }8024 }8025 if (ns === 0 /* HTML */) {8026 if (tag === 'svg') {8027 return 1 /* SVG */;8028 }8029 if (tag === 'math') {8030 return 2 /* MATH_ML */;8031 }8032 }8033 return ns;8034 },8035 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments8036 getTextMode({ tag, ns }) {8037 if (ns === 0 /* HTML */) {8038 if (tag === 'textarea' || tag === 'title') {8039 return 1 /* RCDATA */;8040 }8041 if (isRawTextContainer(tag)) {8042 return 2 /* RAWTEXT */;8043 }8044 }8045 return 0 /* DATA */;8046 }8047};8048// Parse inline CSS strings for static style attributes into an object.8049// This is a NodeTransform since it works on the static `style` attribute and8050// converts it into a dynamic equivalent:8051// style="color: red" -> :style='{ "color": "red" }'8052// It is then processed by `transformElement` and included in the generated8053// props.8054const transformStyle = node => {8055 if (node.type === 1 /* ELEMENT */) {8056 node.props.forEach((p, i) => {8057 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {8058 // replace p with an expression node8059 node.props[i] = {8060 type: 7 /* DIRECTIVE */,8061 name: `bind`,8062 arg: compilerCore.createSimpleExpression(`style`, true, p.loc),8063 exp: parseInlineCSS(p.value.content, p.loc),8064 modifiers: [],8065 loc: p.loc8066 };8067 }8068 });8069 }8070};8071const parseInlineCSS = (cssText, loc) => {8072 const normalized = shared.parseStringStyle(cssText);8073 return compilerCore.createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);8074};8075function createDOMCompilerError(code, loc) {8076 return compilerCore.createCompilerError(code, loc, DOMErrorMessages );8077}8078const DOMErrorMessages = {8079 [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,8080 [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,8081 [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,8082 [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,8083 [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,8084 [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,8085 [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,8086 [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,8087 [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,8088 [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,8089 [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`8090};8091const transformVHtml = (dir, node, context) => {8092 const { exp, loc } = dir;8093 if (!exp) {8094 context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));8095 }8096 if (node.children.length) {8097 context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));8098 node.children.length = 0;8099 }8100 return {8101 props: [8102 compilerCore.createObjectProperty(compilerCore.createSimpleExpression(`innerHTML`, true, loc), exp || compilerCore.createSimpleExpression('', true))8103 ]8104 };8105};8106const transformVText = (dir, node, context) => {8107 const { exp, loc } = dir;8108 if (!exp) {8109 context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));8110 }8111 if (node.children.length) {8112 context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));8113 node.children.length = 0;8114 }8115 return {8116 props: [8117 compilerCore.createObjectProperty(compilerCore.createSimpleExpression(`textContent`, true), exp8118 ? compilerCore.createCallExpression(context.helperString(compilerCore.TO_DISPLAY_STRING), [exp], loc)8119 : compilerCore.createSimpleExpression('', true))8120 ]8121 };8122};8123const transformModel = (dir, node, context) => {8124 const baseResult = compilerCore.transformModel(dir, node, context);8125 // base transform has errors OR component v-model (only need props)8126 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {8127 return baseResult;8128 }8129 if (dir.arg) {8130 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));8131 }8132 function checkDuplicatedValue() {8133 const value = compilerCore.findProp(node, 'value');8134 if (value) {8135 context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));8136 }8137 }8138 const { tag } = node;8139 const isCustomElement = context.isCustomElement(tag);8140 if (tag === 'input' ||8141 tag === 'textarea' ||8142 tag === 'select' ||8143 isCustomElement) {8144 let directiveToUse = V_MODEL_TEXT;8145 let isInvalidType = false;8146 if (tag === 'input' || isCustomElement) {8147 const type = compilerCore.findProp(node, `type`);8148 if (type) {8149 if (type.type === 7 /* DIRECTIVE */) {8150 // :type="foo"8151 directiveToUse = V_MODEL_DYNAMIC;8152 }8153 else if (type.value) {8154 switch (type.value.content) {8155 case 'radio':8156 directiveToUse = V_MODEL_RADIO;8157 break;8158 case 'checkbox':8159 directiveToUse = V_MODEL_CHECKBOX;8160 break;8161 case 'file':8162 isInvalidType = true;8163 context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));8164 break;8165 default:8166 // text type8167 checkDuplicatedValue();8168 break;8169 }8170 }8171 }8172 else if (compilerCore.hasDynamicKeyVBind(node)) {8173 // element has bindings with dynamic keys, which can possibly contain8174 // "type".8175 directiveToUse = V_MODEL_DYNAMIC;8176 }8177 else {8178 // text type8179 checkDuplicatedValue();8180 }8181 }8182 else if (tag === 'select') {8183 directiveToUse = V_MODEL_SELECT;8184 }8185 else {8186 // textarea8187 checkDuplicatedValue();8188 }8189 // inject runtime directive8190 // by returning the helper symbol via needRuntime8191 // the import will replaced a resolveDirective call.8192 if (!isInvalidType) {8193 baseResult.needRuntime = context.helper(directiveToUse);8194 }8195 }8196 else {8197 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));8198 }8199 // native vmodel doesn't need the `modelValue` props since they are also8200 // passed to the runtime as `binding.value`. removing it reduces code size.8201 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&8202 p.key.content === 'modelValue'));8203 return baseResult;8204};8205const isEventOptionModifier = /*#__PURE__*/ shared.makeMap(`passive,once,capture`);8206const isNonKeyModifier = /*#__PURE__*/ shared.makeMap(8207// event propagation management8208`stop,prevent,self,` +8209 // system modifiers + exact8210 `ctrl,shift,alt,meta,exact,` +8211 // mouse8212 `middle`);8213// left & right could be mouse or key modifiers based on event type8214const maybeKeyModifier = /*#__PURE__*/ shared.makeMap('left,right');8215const isKeyboardEvent = /*#__PURE__*/ shared.makeMap(`onkeyup,onkeydown,onkeypress`, true);8216const resolveModifiers = (key, modifiers, context, loc) => {8217 const keyModifiers = [];8218 const nonKeyModifiers = [];8219 const eventOptionModifiers = [];8220 for (let i = 0; i < modifiers.length; i++) {8221 const modifier = modifiers[i];8222 if (modifier === 'native' &&8223 compilerCore.checkCompatEnabled("COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */, context, loc)) {8224 eventOptionModifiers.push(modifier);8225 }8226 else if (isEventOptionModifier(modifier)) {8227 // eventOptionModifiers: modifiers for addEventListener() options,8228 // e.g. .passive & .capture8229 eventOptionModifiers.push(modifier);8230 }8231 else {8232 // runtimeModifiers: modifiers that needs runtime guards8233 if (maybeKeyModifier(modifier)) {8234 if (compilerCore.isStaticExp(key)) {8235 if (isKeyboardEvent(key.content)) {8236 keyModifiers.push(modifier);8237 }...
compiler-dom.global.js
Source:compiler-dom.global.js
...954 // in v3 mode, only enable if explicitly set to true955 // otherwise enable for any non-false value956 return mode === 3 ? value === true : value !== false;957 }958 function checkCompatEnabled(key, context, loc, ...args) {959 const enabled = isCompatEnabled(key, context);960 if (enabled) {961 warnDeprecation(key, context, loc, ...args);962 }963 return enabled;964 }965 function warnDeprecation(key, context, loc, ...args) {966 const val = getCompatValue(key, context);967 if (val === 'suppress-warning') {968 return;969 }970 const { message, link } = deprecationData[key];971 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;972 const err = new SyntaxError(msg);973 err.code = key;974 if (loc)975 err.loc = loc;976 context.onWarn(err);977 }978 // The default decoder only provides escapes for characters reserved as part of979 // the template syntax, and is only used if the custom renderer did not provide980 // a platform-specific decoder.981 const decodeRE = /&(gt|lt|amp|apos|quot);/g;982 const decodeMap = {983 gt: '>',984 lt: '<',985 amp: '&',986 apos: "'",987 quot: '"'988 };989 const defaultParserOptions = {990 delimiters: [`{{`, `}}`],991 getNamespace: () => 0 /* HTML */,992 getTextMode: () => 0 /* DATA */,993 isVoidTag: NO,994 isPreTag: NO,995 isCustomElement: NO,996 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),997 onError: defaultOnError,998 onWarn: defaultOnWarn,999 comments: true1000 };1001 function baseParse(content, options = {}) {1002 const context = createParserContext(content, options);1003 const start = getCursor(context);1004 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));1005 }1006 function createParserContext(content, rawOptions) {1007 const options = extend({}, defaultParserOptions);1008 let key;1009 for (key in rawOptions) {1010 // @ts-ignore1011 options[key] =1012 rawOptions[key] === undefined1013 ? defaultParserOptions[key]1014 : rawOptions[key];1015 }1016 return {1017 options,1018 column: 1,1019 line: 1,1020 offset: 0,1021 originalSource: content,1022 source: content,1023 inPre: false,1024 inVPre: false,1025 onWarn: options.onWarn1026 };1027 }1028 function parseChildren(context, mode, ancestors) {1029 const parent = last(ancestors);1030 const ns = parent ? parent.ns : 0 /* HTML */;1031 const nodes = [];1032 while (!isEnd(context, mode, ancestors)) {1033 const s = context.source;1034 let node = undefined;1035 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {1036 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {1037 // '{{'1038 node = parseInterpolation(context, mode);1039 }1040 else if (mode === 0 /* DATA */ && s[0] === '<') {1041 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state1042 if (s.length === 1) {1043 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);1044 }1045 else if (s[1] === '!') {1046 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state1047 if (startsWith(s, '<!--')) {1048 node = parseComment(context);1049 }1050 else if (startsWith(s, '<!DOCTYPE')) {1051 // Ignore DOCTYPE by a limitation.1052 node = parseBogusComment(context);1053 }1054 else if (startsWith(s, '<![CDATA[')) {1055 if (ns !== 0 /* HTML */) {1056 node = parseCDATA(context, ancestors);1057 }1058 else {1059 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);1060 node = parseBogusComment(context);1061 }1062 }1063 else {1064 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);1065 node = parseBogusComment(context);1066 }1067 }1068 else if (s[1] === '/') {1069 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state1070 if (s.length === 2) {1071 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);1072 }1073 else if (s[2] === '>') {1074 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);1075 advanceBy(context, 3);1076 continue;1077 }1078 else if (/[a-z]/i.test(s[2])) {1079 emitError(context, 23 /* X_INVALID_END_TAG */);1080 parseTag(context, 1 /* End */, parent);1081 continue;1082 }1083 else {1084 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);1085 node = parseBogusComment(context);1086 }1087 }1088 else if (/[a-z]/i.test(s[1])) {1089 node = parseElement(context, ancestors);1090 // 2.x <template> with no directive compat1091 if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&1092 node &&1093 node.tag === 'template' &&1094 !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&1095 isSpecialTemplateDirective(p.name))) {1096 warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);1097 node = node.children;1098 }1099 }1100 else if (s[1] === '?') {1101 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);1102 node = parseBogusComment(context);1103 }1104 else {1105 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);1106 }1107 }1108 }1109 if (!node) {1110 node = parseText(context, mode);1111 }1112 if (isArray(node)) {1113 for (let i = 0; i < node.length; i++) {1114 pushNode(nodes, node[i]);1115 }1116 }1117 else {1118 pushNode(nodes, node);1119 }1120 }1121 // Whitespace handling strategy like v21122 let removedWhitespace = false;1123 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {1124 const shouldCondense = context.options.whitespace !== 'preserve';1125 for (let i = 0; i < nodes.length; i++) {1126 const node = nodes[i];1127 if (!context.inPre && node.type === 2 /* TEXT */) {1128 if (!/[^\t\r\n\f ]/.test(node.content)) {1129 const prev = nodes[i - 1];1130 const next = nodes[i + 1];1131 // Remove if:1132 // - the whitespace is the first or last node, or:1133 // - (condense mode) the whitespace is adjacent to a comment, or:1134 // - (condense mode) the whitespace is between two elements AND contains newline1135 if (!prev ||1136 !next ||1137 (shouldCondense &&1138 (prev.type === 3 /* COMMENT */ ||1139 next.type === 3 /* COMMENT */ ||1140 (prev.type === 1 /* ELEMENT */ &&1141 next.type === 1 /* ELEMENT */ &&1142 /[\r\n]/.test(node.content))))) {1143 removedWhitespace = true;1144 nodes[i] = null;1145 }1146 else {1147 // Otherwise, the whitespace is condensed into a single space1148 node.content = ' ';1149 }1150 }1151 else if (shouldCondense) {1152 // in condense mode, consecutive whitespaces in text are condensed1153 // down to a single space.1154 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1155 }1156 }1157 // Remove comment nodes if desired by configuration.1158 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {1159 removedWhitespace = true;1160 nodes[i] = null;1161 }1162 }1163 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1164 // remove leading newline per html spec1165 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1166 const first = nodes[0];1167 if (first && first.type === 2 /* TEXT */) {1168 first.content = first.content.replace(/^\r?\n/, '');1169 }1170 }1171 }1172 return removedWhitespace ? nodes.filter(Boolean) : nodes;1173 }1174 function pushNode(nodes, node) {1175 if (node.type === 2 /* TEXT */) {1176 const prev = last(nodes);1177 // Merge if both this and the previous node are text and those are1178 // consecutive. This happens for cases like "a < b".1179 if (prev &&1180 prev.type === 2 /* TEXT */ &&1181 prev.loc.end.offset === node.loc.start.offset) {1182 prev.content += node.content;1183 prev.loc.end = node.loc.end;1184 prev.loc.source += node.loc.source;1185 return;1186 }1187 }1188 nodes.push(node);1189 }1190 function parseCDATA(context, ancestors) {1191 advanceBy(context, 9);1192 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1193 if (context.source.length === 0) {1194 emitError(context, 6 /* EOF_IN_CDATA */);1195 }1196 else {1197 advanceBy(context, 3);1198 }1199 return nodes;1200 }1201 function parseComment(context) {1202 const start = getCursor(context);1203 let content;1204 // Regular comment.1205 const match = /--(\!)?>/.exec(context.source);1206 if (!match) {1207 content = context.source.slice(4);1208 advanceBy(context, context.source.length);1209 emitError(context, 7 /* EOF_IN_COMMENT */);1210 }1211 else {1212 if (match.index <= 3) {1213 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1214 }1215 if (match[1]) {1216 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1217 }1218 content = context.source.slice(4, match.index);1219 // Advancing with reporting nested comments.1220 const s = context.source.slice(0, match.index);1221 let prevIndex = 1, nestedIndex = 0;1222 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1223 advanceBy(context, nestedIndex - prevIndex + 1);1224 if (nestedIndex + 4 < s.length) {1225 emitError(context, 16 /* NESTED_COMMENT */);1226 }1227 prevIndex = nestedIndex + 1;1228 }1229 advanceBy(context, match.index + match[0].length - prevIndex + 1);1230 }1231 return {1232 type: 3 /* COMMENT */,1233 content,1234 loc: getSelection(context, start)1235 };1236 }1237 function parseBogusComment(context) {1238 const start = getCursor(context);1239 const contentStart = context.source[1] === '?' ? 1 : 2;1240 let content;1241 const closeIndex = context.source.indexOf('>');1242 if (closeIndex === -1) {1243 content = context.source.slice(contentStart);1244 advanceBy(context, context.source.length);1245 }1246 else {1247 content = context.source.slice(contentStart, closeIndex);1248 advanceBy(context, closeIndex + 1);1249 }1250 return {1251 type: 3 /* COMMENT */,1252 content,1253 loc: getSelection(context, start)1254 };1255 }1256 function parseElement(context, ancestors) {1257 // Start tag.1258 const wasInPre = context.inPre;1259 const wasInVPre = context.inVPre;1260 const parent = last(ancestors);1261 const element = parseTag(context, 0 /* Start */, parent);1262 const isPreBoundary = context.inPre && !wasInPre;1263 const isVPreBoundary = context.inVPre && !wasInVPre;1264 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1265 // #4030 self-closing <pre> tag1266 if (isPreBoundary) {1267 context.inPre = false;1268 }1269 if (isVPreBoundary) {1270 context.inVPre = false;1271 }1272 return element;1273 }1274 // Children.1275 ancestors.push(element);1276 const mode = context.options.getTextMode(element, parent);1277 const children = parseChildren(context, mode, ancestors);1278 ancestors.pop();1279 // 2.x inline-template compat1280 {1281 const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1282 if (inlineTemplateProp &&1283 checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1284 const loc = getSelection(context, element.loc.end);1285 inlineTemplateProp.value = {1286 type: 2 /* TEXT */,1287 content: loc.source,1288 loc1289 };1290 }1291 }1292 element.children = children;1293 // End tag.1294 if (startsWithEndTagOpen(context.source, element.tag)) {1295 parseTag(context, 1 /* End */, parent);1296 }1297 else {1298 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1299 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1300 const first = children[0];1301 if (first && startsWith(first.loc.source, '<!--')) {1302 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1303 }1304 }1305 }1306 element.loc = getSelection(context, element.loc.start);1307 if (isPreBoundary) {1308 context.inPre = false;1309 }1310 if (isVPreBoundary) {1311 context.inVPre = false;1312 }1313 return element;1314 }1315 const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);1316 function parseTag(context, type, parent) {1317 // Tag open.1318 const start = getCursor(context);1319 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1320 const tag = match[1];1321 const ns = context.options.getNamespace(tag, parent);1322 advanceBy(context, match[0].length);1323 advanceSpaces(context);1324 // save current state in case we need to re-parse attributes with v-pre1325 const cursor = getCursor(context);1326 const currentSource = context.source;1327 // check <pre> tag1328 if (context.options.isPreTag(tag)) {1329 context.inPre = true;1330 }1331 // Attributes.1332 let props = parseAttributes(context, type);1333 // check v-pre1334 if (type === 0 /* Start */ &&1335 !context.inVPre &&1336 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1337 context.inVPre = true;1338 // reset context1339 extend(context, cursor);1340 context.source = currentSource;1341 // re-parse attrs and filter out v-pre itself1342 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1343 }1344 // Tag close.1345 let isSelfClosing = false;1346 if (context.source.length === 0) {1347 emitError(context, 9 /* EOF_IN_TAG */);1348 }1349 else {1350 isSelfClosing = startsWith(context.source, '/>');1351 if (type === 1 /* End */ && isSelfClosing) {1352 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1353 }1354 advanceBy(context, isSelfClosing ? 2 : 1);1355 }1356 if (type === 1 /* End */) {1357 return;1358 }1359 // 2.x deprecation checks1360 if (isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1361 let hasIf = false;1362 let hasFor = false;1363 for (let i = 0; i < props.length; i++) {1364 const p = props[i];1365 if (p.type === 7 /* DIRECTIVE */) {1366 if (p.name === 'if') {1367 hasIf = true;1368 }1369 else if (p.name === 'for') {1370 hasFor = true;1371 }1372 }1373 if (hasIf && hasFor) {1374 warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1375 }1376 }1377 }1378 let tagType = 0 /* ELEMENT */;1379 if (!context.inVPre) {1380 if (tag === 'slot') {1381 tagType = 2 /* SLOT */;1382 }1383 else if (tag === 'template') {1384 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1385 tagType = 3 /* TEMPLATE */;1386 }1387 }1388 else if (isComponent(tag, props, context)) {1389 tagType = 1 /* COMPONENT */;1390 }1391 }1392 return {1393 type: 1 /* ELEMENT */,1394 ns,1395 tag,1396 tagType,1397 props,1398 isSelfClosing,1399 children: [],1400 loc: getSelection(context, start),1401 codegenNode: undefined // to be created during transform phase1402 };1403 }1404 function isComponent(tag, props, context) {1405 const options = context.options;1406 if (options.isCustomElement(tag)) {1407 return false;1408 }1409 if (tag === 'component' ||1410 /^[A-Z]/.test(tag) ||1411 isCoreComponent(tag) ||1412 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1413 (options.isNativeTag && !options.isNativeTag(tag))) {1414 return true;1415 }1416 // at this point the tag should be a native tag, but check for potential "is"1417 // casting1418 for (let i = 0; i < props.length; i++) {1419 const p = props[i];1420 if (p.type === 6 /* ATTRIBUTE */) {1421 if (p.name === 'is' && p.value) {1422 if (p.value.content.startsWith('vue:')) {1423 return true;1424 }1425 else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1426 return true;1427 }1428 }1429 }1430 else {1431 // directive1432 // v-is (TODO Deprecate)1433 if (p.name === 'is') {1434 return true;1435 }1436 else if (1437 // :is on plain element - only treat as component in compat mode1438 p.name === 'bind' &&1439 isBindKey(p.arg, 'is') &&1440 true &&1441 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1442 return true;1443 }1444 }1445 }1446 }1447 function parseAttributes(context, type) {1448 const props = [];1449 const attributeNames = new Set();1450 while (context.source.length > 0 &&1451 !startsWith(context.source, '>') &&1452 !startsWith(context.source, '/>')) {1453 if (startsWith(context.source, '/')) {1454 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1455 advanceBy(context, 1);1456 advanceSpaces(context);1457 continue;1458 }1459 if (type === 1 /* End */) {1460 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1461 }1462 const attr = parseAttribute(context, attributeNames);1463 // Trim whitespace between class1464 // https://github.com/vuejs/vue-next/issues/42511465 if (attr.type === 6 /* ATTRIBUTE */ &&1466 attr.value &&1467 attr.name === 'class') {1468 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1469 }1470 if (type === 0 /* Start */) {1471 props.push(attr);1472 }1473 if (/^[^\t\r\n\f />]/.test(context.source)) {1474 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1475 }1476 advanceSpaces(context);1477 }1478 return props;1479 }1480 function parseAttribute(context, nameSet) {1481 // Name.1482 const start = getCursor(context);1483 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1484 const name = match[0];1485 if (nameSet.has(name)) {1486 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1487 }1488 nameSet.add(name);1489 if (name[0] === '=') {1490 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1491 }1492 {1493 const pattern = /["'<]/g;1494 let m;1495 while ((m = pattern.exec(name))) {1496 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1497 }1498 }1499 advanceBy(context, name.length);1500 // Value1501 let value = undefined;1502 if (/^[\t\r\n\f ]*=/.test(context.source)) {1503 advanceSpaces(context);1504 advanceBy(context, 1);1505 advanceSpaces(context);1506 value = parseAttributeValue(context);1507 if (!value) {1508 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1509 }1510 }1511 const loc = getSelection(context, start);1512 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1513 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1514 let isPropShorthand = startsWith(name, '.');1515 let dirName = match[1] ||1516 (isPropShorthand || startsWith(name, ':')1517 ? 'bind'1518 : startsWith(name, '@')1519 ? 'on'1520 : 'slot');1521 let arg;1522 if (match[2]) {1523 const isSlot = dirName === 'slot';1524 const startOffset = name.lastIndexOf(match[2]);1525 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1526 let content = match[2];1527 let isStatic = true;1528 if (content.startsWith('[')) {1529 isStatic = false;1530 if (!content.endsWith(']')) {1531 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1532 content = content.slice(1);1533 }1534 else {1535 content = content.slice(1, content.length - 1);1536 }1537 }1538 else if (isSlot) {1539 // #1241 special case for v-slot: vuetify relies extensively on slot1540 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1541 // supports such usage so we are keeping it consistent with 2.x.1542 content += match[3] || '';1543 }1544 arg = {1545 type: 4 /* SIMPLE_EXPRESSION */,1546 content,1547 isStatic,1548 constType: isStatic1549 ? 3 /* CAN_STRINGIFY */1550 : 0 /* NOT_CONSTANT */,1551 loc1552 };1553 }1554 if (value && value.isQuoted) {1555 const valueLoc = value.loc;1556 valueLoc.start.offset++;1557 valueLoc.start.column++;1558 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1559 valueLoc.source = valueLoc.source.slice(1, -1);1560 }1561 const modifiers = match[3] ? match[3].slice(1).split('.') : [];1562 if (isPropShorthand)1563 modifiers.push('prop');1564 // 2.x compat v-bind:foo.sync -> v-model:foo1565 if (dirName === 'bind' && arg) {1566 if (modifiers.includes('sync') &&1567 checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1568 dirName = 'model';1569 modifiers.splice(modifiers.indexOf('sync'), 1);1570 }1571 if (modifiers.includes('prop')) {1572 checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1573 }1574 }1575 return {1576 type: 7 /* DIRECTIVE */,1577 name: dirName,1578 exp: value && {1579 type: 4 /* SIMPLE_EXPRESSION */,1580 content: value.content,1581 isStatic: false,1582 // Treat as non-constant by default. This can be potentially set to1583 // other values by `transformExpression` to make it eligible for hoisting.1584 constType: 0 /* NOT_CONSTANT */,1585 loc: value.loc1586 },1587 arg,1588 modifiers,1589 loc1590 };1591 }1592 // missing directive name or illegal directive name1593 if (!context.inVPre && startsWith(name, 'v-')) {1594 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1595 }1596 return {1597 type: 6 /* ATTRIBUTE */,1598 name,1599 value: value && {1600 type: 2 /* TEXT */,1601 content: value.content,1602 loc: value.loc1603 },1604 loc1605 };1606 }1607 function parseAttributeValue(context) {1608 const start = getCursor(context);1609 let content;1610 const quote = context.source[0];1611 const isQuoted = quote === `"` || quote === `'`;1612 if (isQuoted) {1613 // Quoted value.1614 advanceBy(context, 1);1615 const endIndex = context.source.indexOf(quote);1616 if (endIndex === -1) {1617 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1618 }1619 else {1620 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1621 advanceBy(context, 1);1622 }1623 }1624 else {1625 // Unquoted1626 const match = /^[^\t\r\n\f >]+/.exec(context.source);1627 if (!match) {1628 return undefined;1629 }1630 const unexpectedChars = /["'<=`]/g;1631 let m;1632 while ((m = unexpectedChars.exec(match[0]))) {1633 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1634 }1635 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1636 }1637 return { content, isQuoted, loc: getSelection(context, start) };1638 }1639 function parseInterpolation(context, mode) {1640 const [open, close] = context.options.delimiters;1641 const closeIndex = context.source.indexOf(close, open.length);1642 if (closeIndex === -1) {1643 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1644 return undefined;1645 }1646 const start = getCursor(context);1647 advanceBy(context, open.length);1648 const innerStart = getCursor(context);1649 const innerEnd = getCursor(context);1650 const rawContentLength = closeIndex - open.length;1651 const rawContent = context.source.slice(0, rawContentLength);1652 const preTrimContent = parseTextData(context, rawContentLength, mode);1653 const content = preTrimContent.trim();1654 const startOffset = preTrimContent.indexOf(content);1655 if (startOffset > 0) {1656 advancePositionWithMutation(innerStart, rawContent, startOffset);1657 }1658 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1659 advancePositionWithMutation(innerEnd, rawContent, endOffset);1660 advanceBy(context, close.length);1661 return {1662 type: 5 /* INTERPOLATION */,1663 content: {1664 type: 4 /* SIMPLE_EXPRESSION */,1665 isStatic: false,1666 // Set `isConstant` to false by default and will decide in transformExpression1667 constType: 0 /* NOT_CONSTANT */,1668 content,1669 loc: getSelection(context, innerStart, innerEnd)1670 },1671 loc: getSelection(context, start)1672 };1673 }1674 function parseText(context, mode) {1675 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1676 let endIndex = context.source.length;1677 for (let i = 0; i < endTokens.length; i++) {1678 const index = context.source.indexOf(endTokens[i], 1);1679 if (index !== -1 && endIndex > index) {1680 endIndex = index;1681 }1682 }1683 const start = getCursor(context);1684 const content = parseTextData(context, endIndex, mode);1685 return {1686 type: 2 /* TEXT */,1687 content,1688 loc: getSelection(context, start)1689 };1690 }1691 /**1692 * Get text data with a given length from the current location.1693 * This translates HTML entities in the text data.1694 */1695 function parseTextData(context, length, mode) {1696 const rawText = context.source.slice(0, length);1697 advanceBy(context, length);1698 if (mode === 2 /* RAWTEXT */ ||1699 mode === 3 /* CDATA */ ||1700 rawText.indexOf('&') === -1) {1701 return rawText;1702 }1703 else {1704 // DATA or RCDATA containing "&"". Entity decoding required.1705 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1706 }1707 }1708 function getCursor(context) {1709 const { column, line, offset } = context;1710 return { column, line, offset };1711 }1712 function getSelection(context, start, end) {1713 end = end || getCursor(context);1714 return {1715 start,1716 end,1717 source: context.originalSource.slice(start.offset, end.offset)1718 };1719 }1720 function last(xs) {1721 return xs[xs.length - 1];1722 }1723 function startsWith(source, searchString) {1724 return source.startsWith(searchString);1725 }1726 function advanceBy(context, numberOfCharacters) {1727 const { source } = context;1728 advancePositionWithMutation(context, source, numberOfCharacters);1729 context.source = source.slice(numberOfCharacters);1730 }1731 function advanceSpaces(context) {1732 const match = /^[\t\r\n\f ]+/.exec(context.source);1733 if (match) {1734 advanceBy(context, match[0].length);1735 }1736 }1737 function getNewPosition(context, start, numberOfCharacters) {1738 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1739 }1740 function emitError(context, code, offset, loc = getCursor(context)) {1741 if (offset) {1742 loc.offset += offset;1743 loc.column += offset;1744 }1745 context.options.onError(createCompilerError(code, {1746 start: loc,1747 end: loc,1748 source: ''1749 }));1750 }1751 function isEnd(context, mode, ancestors) {1752 const s = context.source;1753 switch (mode) {1754 case 0 /* DATA */:1755 if (startsWith(s, '</')) {1756 // TODO: probably bad performance1757 for (let i = ancestors.length - 1; i >= 0; --i) {1758 if (startsWithEndTagOpen(s, ancestors[i].tag)) {1759 return true;1760 }1761 }1762 }1763 break;1764 case 1 /* RCDATA */:1765 case 2 /* RAWTEXT */: {1766 const parent = last(ancestors);1767 if (parent && startsWithEndTagOpen(s, parent.tag)) {1768 return true;1769 }1770 break;1771 }1772 case 3 /* CDATA */:1773 if (startsWith(s, ']]>')) {1774 return true;1775 }1776 break;1777 }1778 return !s;1779 }1780 function startsWithEndTagOpen(source, tag) {1781 return (startsWith(source, '</') &&1782 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1783 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1784 }1785 function hoistStatic(root, context) {1786 walk(root, context, 1787 // Root node is unfortunately non-hoistable due to potential parent1788 // fallthrough attributes.1789 isSingleElementRoot(root, root.children[0]));1790 }1791 function isSingleElementRoot(root, child) {1792 const { children } = root;1793 return (children.length === 1 &&1794 child.type === 1 /* ELEMENT */ &&1795 !isSlotOutlet(child));1796 }1797 function walk(node, context, doNotHoistNode = false) {1798 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces1799 // static bindings with expressions. These expressions are guaranteed to be1800 // constant so they are still eligible for hoisting, but they are only1801 // available at runtime and therefore cannot be evaluated ahead of time.1802 // This is only a concern for pre-stringification (via transformHoist by1803 // @vue/compiler-dom), but doing it here allows us to perform only one full1804 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its1805 // stringification threshold is met.1806 let canStringify = true;1807 const { children } = node;1808 const originalCount = children.length;1809 let hoistedCount = 0;1810 for (let i = 0; i < children.length; i++) {1811 const child = children[i];1812 // only plain elements & text calls are eligible for hoisting.1813 if (child.type === 1 /* ELEMENT */ &&1814 child.tagType === 0 /* ELEMENT */) {1815 const constantType = doNotHoistNode1816 ? 0 /* NOT_CONSTANT */1817 : getConstantType(child, context);1818 if (constantType > 0 /* NOT_CONSTANT */) {1819 if (constantType < 3 /* CAN_STRINGIFY */) {1820 canStringify = false;1821 }1822 if (constantType >= 2 /* CAN_HOIST */) {1823 child.codegenNode.patchFlag =1824 -1 /* HOISTED */ + (` /* HOISTED */` );1825 child.codegenNode = context.hoist(child.codegenNode);1826 hoistedCount++;1827 continue;1828 }1829 }1830 else {1831 // node may contain dynamic children, but its props may be eligible for1832 // hoisting.1833 const codegenNode = child.codegenNode;1834 if (codegenNode.type === 13 /* VNODE_CALL */) {1835 const flag = getPatchFlag(codegenNode);1836 if ((!flag ||1837 flag === 512 /* NEED_PATCH */ ||1838 flag === 1 /* TEXT */) &&1839 getGeneratedPropsConstantType(child, context) >=1840 2 /* CAN_HOIST */) {1841 const props = getNodeProps(child);1842 if (props) {1843 codegenNode.props = context.hoist(props);1844 }1845 }1846 if (codegenNode.dynamicProps) {1847 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1848 }1849 }1850 }1851 }1852 else if (child.type === 12 /* TEXT_CALL */) {1853 const contentType = getConstantType(child.content, context);1854 if (contentType > 0) {1855 if (contentType < 3 /* CAN_STRINGIFY */) {1856 canStringify = false;1857 }1858 if (contentType >= 2 /* CAN_HOIST */) {1859 child.codegenNode = context.hoist(child.codegenNode);1860 hoistedCount++;1861 }1862 }1863 }1864 // walk further1865 if (child.type === 1 /* ELEMENT */) {1866 const isComponent = child.tagType === 1 /* COMPONENT */;1867 if (isComponent) {1868 context.scopes.vSlot++;1869 }1870 walk(child, context);1871 if (isComponent) {1872 context.scopes.vSlot--;1873 }1874 }1875 else if (child.type === 11 /* FOR */) {1876 // Do not hoist v-for single child because it has to be a block1877 walk(child, context, child.children.length === 1);1878 }1879 else if (child.type === 9 /* IF */) {1880 for (let i = 0; i < child.branches.length; i++) {1881 // Do not hoist v-if single child because it has to be a block1882 walk(child.branches[i], context, child.branches[i].children.length === 1);1883 }1884 }1885 }1886 if (canStringify && hoistedCount && context.transformHoist) {1887 context.transformHoist(children, context, node);1888 }1889 // all children were hoisted - the entire children array is hoistable.1890 if (hoistedCount &&1891 hoistedCount === originalCount &&1892 node.type === 1 /* ELEMENT */ &&1893 node.tagType === 0 /* ELEMENT */ &&1894 node.codegenNode &&1895 node.codegenNode.type === 13 /* VNODE_CALL */ &&1896 isArray(node.codegenNode.children)) {1897 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1898 }1899 }1900 function getConstantType(node, context) {1901 const { constantCache } = context;1902 switch (node.type) {1903 case 1 /* ELEMENT */:1904 if (node.tagType !== 0 /* ELEMENT */) {1905 return 0 /* NOT_CONSTANT */;1906 }1907 const cached = constantCache.get(node);1908 if (cached !== undefined) {1909 return cached;1910 }1911 const codegenNode = node.codegenNode;1912 if (codegenNode.type !== 13 /* VNODE_CALL */) {1913 return 0 /* NOT_CONSTANT */;1914 }1915 const flag = getPatchFlag(codegenNode);1916 if (!flag) {1917 let returnType = 3 /* CAN_STRINGIFY */;1918 // Element itself has no patch flag. However we still need to check:1919 // 1. Even for a node with no patch flag, it is possible for it to contain1920 // non-hoistable expressions that refers to scope variables, e.g. compiler1921 // injected keys or cached event handlers. Therefore we need to always1922 // check the codegenNode's props to be sure.1923 const generatedPropsType = getGeneratedPropsConstantType(node, context);1924 if (generatedPropsType === 0 /* NOT_CONSTANT */) {1925 constantCache.set(node, 0 /* NOT_CONSTANT */);1926 return 0 /* NOT_CONSTANT */;1927 }1928 if (generatedPropsType < returnType) {1929 returnType = generatedPropsType;1930 }1931 // 2. its children.1932 for (let i = 0; i < node.children.length; i++) {1933 const childType = getConstantType(node.children[i], context);1934 if (childType === 0 /* NOT_CONSTANT */) {1935 constantCache.set(node, 0 /* NOT_CONSTANT */);1936 return 0 /* NOT_CONSTANT */;1937 }1938 if (childType < returnType) {1939 returnType = childType;1940 }1941 }1942 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01943 // type, check if any of the props can cause the type to be lowered1944 // we can skip can_patch because it's guaranteed by the absence of a1945 // patchFlag.1946 if (returnType > 1 /* CAN_SKIP_PATCH */) {1947 for (let i = 0; i < node.props.length; i++) {1948 const p = node.props[i];1949 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1950 const expType = getConstantType(p.exp, context);1951 if (expType === 0 /* NOT_CONSTANT */) {1952 constantCache.set(node, 0 /* NOT_CONSTANT */);1953 return 0 /* NOT_CONSTANT */;1954 }1955 if (expType < returnType) {1956 returnType = expType;1957 }1958 }1959 }1960 }1961 // only svg/foreignObject could be block here, however if they are1962 // static then they don't need to be blocks since there will be no1963 // nested updates.1964 if (codegenNode.isBlock) {1965 context.removeHelper(OPEN_BLOCK);1966 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1967 codegenNode.isBlock = false;1968 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1969 }1970 constantCache.set(node, returnType);1971 return returnType;1972 }1973 else {1974 constantCache.set(node, 0 /* NOT_CONSTANT */);1975 return 0 /* NOT_CONSTANT */;1976 }1977 case 2 /* TEXT */:1978 case 3 /* COMMENT */:1979 return 3 /* CAN_STRINGIFY */;1980 case 9 /* IF */:1981 case 11 /* FOR */:1982 case 10 /* IF_BRANCH */:1983 return 0 /* NOT_CONSTANT */;1984 case 5 /* INTERPOLATION */:1985 case 12 /* TEXT_CALL */:1986 return getConstantType(node.content, context);1987 case 4 /* SIMPLE_EXPRESSION */:1988 return node.constType;1989 case 8 /* COMPOUND_EXPRESSION */:1990 let returnType = 3 /* CAN_STRINGIFY */;1991 for (let i = 0; i < node.children.length; i++) {1992 const child = node.children[i];1993 if (isString(child) || isSymbol(child)) {1994 continue;1995 }1996 const childType = getConstantType(child, context);1997 if (childType === 0 /* NOT_CONSTANT */) {1998 return 0 /* NOT_CONSTANT */;1999 }2000 else if (childType < returnType) {2001 returnType = childType;2002 }2003 }2004 return returnType;2005 default:2006 return 0 /* NOT_CONSTANT */;2007 }2008 }2009 const allowHoistedHelperSet = new Set([2010 NORMALIZE_CLASS,2011 NORMALIZE_STYLE,2012 NORMALIZE_PROPS,2013 GUARD_REACTIVE_PROPS2014 ]);2015 function getConstantTypeOfHelperCall(value, context) {2016 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&2017 !isString(value.callee) &&2018 allowHoistedHelperSet.has(value.callee)) {2019 const arg = value.arguments[0];2020 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {2021 return getConstantType(arg, context);2022 }2023 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {2024 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`2025 return getConstantTypeOfHelperCall(arg, context);2026 }2027 }2028 return 0 /* NOT_CONSTANT */;2029 }2030 function getGeneratedPropsConstantType(node, context) {2031 let returnType = 3 /* CAN_STRINGIFY */;2032 const props = getNodeProps(node);2033 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {2034 const { properties } = props;2035 for (let i = 0; i < properties.length; i++) {2036 const { key, value } = properties[i];2037 const keyType = getConstantType(key, context);2038 if (keyType === 0 /* NOT_CONSTANT */) {2039 return keyType;2040 }2041 if (keyType < returnType) {2042 returnType = keyType;2043 }2044 let valueType;2045 if (value.type === 4 /* SIMPLE_EXPRESSION */) {2046 valueType = getConstantType(value, context);2047 }2048 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {2049 // some helper calls can be hoisted,2050 // such as the `normalizeProps` generated by the compiler for pre-normalize class,2051 // in this case we need to respect the ConstantType of the helper's argments2052 valueType = getConstantTypeOfHelperCall(value, context);2053 }2054 else {2055 valueType = 0 /* NOT_CONSTANT */;2056 }2057 if (valueType === 0 /* NOT_CONSTANT */) {2058 return valueType;2059 }2060 if (valueType < returnType) {2061 returnType = valueType;2062 }2063 }2064 }2065 return returnType;2066 }2067 function getNodeProps(node) {2068 const codegenNode = node.codegenNode;2069 if (codegenNode.type === 13 /* VNODE_CALL */) {2070 return codegenNode.props;2071 }2072 }2073 function getPatchFlag(node) {2074 const flag = node.patchFlag;2075 return flag ? parseInt(flag, 10) : undefined;2076 }2077 function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {2078 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);2079 const context = {2080 // options2081 selfName: nameMatch && capitalize(camelize(nameMatch[1])),2082 prefixIdentifiers,2083 hoistStatic,2084 cacheHandlers,2085 nodeTransforms,2086 directiveTransforms,2087 transformHoist,2088 isBuiltInComponent,2089 isCustomElement,2090 expressionPlugins,2091 scopeId,2092 slotted,2093 ssr,2094 inSSR,2095 ssrCssVars,2096 bindingMetadata,2097 inline,2098 isTS,2099 onError,2100 onWarn,2101 compatConfig,2102 // state2103 root,2104 helpers: new Map(),2105 components: new Set(),2106 directives: new Set(),2107 hoists: [],2108 imports: [],2109 constantCache: new Map(),2110 temps: 0,2111 cached: 0,2112 identifiers: Object.create(null),2113 scopes: {2114 vFor: 0,2115 vSlot: 0,2116 vPre: 0,2117 vOnce: 02118 },2119 parent: null,2120 currentNode: root,2121 childIndex: 0,2122 inVOnce: false,2123 // methods2124 helper(name) {2125 const count = context.helpers.get(name) || 0;2126 context.helpers.set(name, count + 1);2127 return name;2128 },2129 removeHelper(name) {2130 const count = context.helpers.get(name);2131 if (count) {2132 const currentCount = count - 1;2133 if (!currentCount) {2134 context.helpers.delete(name);2135 }2136 else {2137 context.helpers.set(name, currentCount);2138 }2139 }2140 },2141 helperString(name) {2142 return `_${helperNameMap[context.helper(name)]}`;2143 },2144 replaceNode(node) {2145 /* istanbul ignore if */2146 {2147 if (!context.currentNode) {2148 throw new Error(`Node being replaced is already removed.`);2149 }2150 if (!context.parent) {2151 throw new Error(`Cannot replace root node.`);2152 }2153 }2154 context.parent.children[context.childIndex] = context.currentNode = node;2155 },2156 removeNode(node) {2157 if (!context.parent) {2158 throw new Error(`Cannot remove root node.`);2159 }2160 const list = context.parent.children;2161 const removalIndex = node2162 ? list.indexOf(node)2163 : context.currentNode2164 ? context.childIndex2165 : -1;2166 /* istanbul ignore if */2167 if (removalIndex < 0) {2168 throw new Error(`node being removed is not a child of current parent`);2169 }2170 if (!node || node === context.currentNode) {2171 // current node removed2172 context.currentNode = null;2173 context.onNodeRemoved();2174 }2175 else {2176 // sibling node removed2177 if (context.childIndex > removalIndex) {2178 context.childIndex--;2179 context.onNodeRemoved();2180 }2181 }2182 context.parent.children.splice(removalIndex, 1);2183 },2184 onNodeRemoved: () => { },2185 addIdentifiers(exp) {2186 },2187 removeIdentifiers(exp) {2188 },2189 hoist(exp) {2190 if (isString(exp))2191 exp = createSimpleExpression(exp);2192 context.hoists.push(exp);2193 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2194 identifier.hoisted = exp;2195 return identifier;2196 },2197 cache(exp, isVNode = false) {2198 return createCacheExpression(context.cached++, exp, isVNode);2199 }2200 };2201 {2202 context.filters = new Set();2203 }2204 return context;2205 }2206 function transform(root, options) {2207 const context = createTransformContext(root, options);2208 traverseNode(root, context);2209 if (options.hoistStatic) {2210 hoistStatic(root, context);2211 }2212 if (!options.ssr) {2213 createRootCodegen(root, context);2214 }2215 // finalize meta information2216 root.helpers = [...context.helpers.keys()];2217 root.components = [...context.components];2218 root.directives = [...context.directives];2219 root.imports = context.imports;2220 root.hoists = context.hoists;2221 root.temps = context.temps;2222 root.cached = context.cached;2223 {2224 root.filters = [...context.filters];2225 }2226 }2227 function createRootCodegen(root, context) {2228 const { helper } = context;2229 const { children } = root;2230 if (children.length === 1) {2231 const child = children[0];2232 // if the single child is an element, turn it into a block.2233 if (isSingleElementRoot(root, child) && child.codegenNode) {2234 // single element root is never hoisted so codegenNode will never be2235 // SimpleExpressionNode2236 const codegenNode = child.codegenNode;2237 if (codegenNode.type === 13 /* VNODE_CALL */) {2238 makeBlock(codegenNode, context);2239 }2240 root.codegenNode = codegenNode;2241 }2242 else {2243 // - single <slot/>, IfNode, ForNode: already blocks.2244 // - single text node: always patched.2245 // root codegen falls through via genNode()2246 root.codegenNode = child;2247 }2248 }2249 else if (children.length > 1) {2250 // root has multiple nodes - return a fragment block.2251 let patchFlag = 64 /* STABLE_FRAGMENT */;2252 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];2253 // check if the fragment actually contains a single valid child with2254 // the rest being comments2255 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2256 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2257 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2258 }2259 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);2260 }2261 else ;2262 }2263 function traverseChildren(parent, context) {2264 let i = 0;2265 const nodeRemoved = () => {2266 i--;2267 };2268 for (; i < parent.children.length; i++) {2269 const child = parent.children[i];2270 if (isString(child))2271 continue;2272 context.parent = parent;2273 context.childIndex = i;2274 context.onNodeRemoved = nodeRemoved;2275 traverseNode(child, context);2276 }2277 }2278 function traverseNode(node, context) {2279 context.currentNode = node;2280 // apply transform plugins2281 const { nodeTransforms } = context;2282 const exitFns = [];2283 for (let i = 0; i < nodeTransforms.length; i++) {2284 const onExit = nodeTransforms[i](node, context);2285 if (onExit) {2286 if (isArray(onExit)) {2287 exitFns.push(...onExit);2288 }2289 else {2290 exitFns.push(onExit);2291 }2292 }2293 if (!context.currentNode) {2294 // node was removed2295 return;2296 }2297 else {2298 // node may have been replaced2299 node = context.currentNode;2300 }2301 }2302 switch (node.type) {2303 case 3 /* COMMENT */:2304 if (!context.ssr) {2305 // inject import for the Comment symbol, which is needed for creating2306 // comment nodes with `createVNode`2307 context.helper(CREATE_COMMENT);2308 }2309 break;2310 case 5 /* INTERPOLATION */:2311 // no need to traverse, but we need to inject toString helper2312 if (!context.ssr) {2313 context.helper(TO_DISPLAY_STRING);2314 }2315 break;2316 // for container types, further traverse downwards2317 case 9 /* IF */:2318 for (let i = 0; i < node.branches.length; i++) {2319 traverseNode(node.branches[i], context);2320 }2321 break;2322 case 10 /* IF_BRANCH */:2323 case 11 /* FOR */:2324 case 1 /* ELEMENT */:2325 case 0 /* ROOT */:2326 traverseChildren(node, context);2327 break;2328 }2329 // exit transforms2330 context.currentNode = node;2331 let i = exitFns.length;2332 while (i--) {2333 exitFns[i]();2334 }2335 }2336 function createStructuralDirectiveTransform(name, fn) {2337 const matches = isString(name)2338 ? (n) => n === name2339 : (n) => name.test(n);2340 return (node, context) => {2341 if (node.type === 1 /* ELEMENT */) {2342 const { props } = node;2343 // structural directive transforms are not concerned with slots2344 // as they are handled separately in vSlot.ts2345 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2346 return;2347 }2348 const exitFns = [];2349 for (let i = 0; i < props.length; i++) {2350 const prop = props[i];2351 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2352 // structural directives are removed to avoid infinite recursion2353 // also we remove them *before* applying so that it can further2354 // traverse itself in case it moves the node around2355 props.splice(i, 1);2356 i--;2357 const onExit = fn(node, prop, context);2358 if (onExit)2359 exitFns.push(onExit);2360 }2361 }2362 return exitFns;2363 }2364 };2365 }2366 const PURE_ANNOTATION = `/*#__PURE__*/`;2367 function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {2368 const context = {2369 mode,2370 prefixIdentifiers,2371 sourceMap,2372 filename,2373 scopeId,2374 optimizeImports,2375 runtimeGlobalName,2376 runtimeModuleName,2377 ssrRuntimeModuleName,2378 ssr,2379 isTS,2380 inSSR,2381 source: ast.loc.source,2382 code: ``,2383 column: 1,2384 line: 1,2385 offset: 0,2386 indentLevel: 0,2387 pure: false,2388 map: undefined,2389 helper(key) {2390 return `_${helperNameMap[key]}`;2391 },2392 push(code, node) {2393 context.code += code;2394 },2395 indent() {2396 newline(++context.indentLevel);2397 },2398 deindent(withoutNewLine = false) {2399 if (withoutNewLine) {2400 --context.indentLevel;2401 }2402 else {2403 newline(--context.indentLevel);2404 }2405 },2406 newline() {2407 newline(context.indentLevel);2408 }2409 };2410 function newline(n) {2411 context.push('\n' + ` `.repeat(n));2412 }2413 return context;2414 }2415 function generate(ast, options = {}) {2416 const context = createCodegenContext(ast, options);2417 if (options.onContextCreated)2418 options.onContextCreated(context);2419 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2420 const hasHelpers = ast.helpers.length > 0;2421 const useWithBlock = !prefixIdentifiers && mode !== 'module';2422 // preambles2423 // in setup() inline mode, the preamble is generated in a sub context2424 // and returned separately.2425 const preambleContext = context;2426 {2427 genFunctionPreamble(ast, preambleContext);2428 }2429 // enter render function2430 const functionName = ssr ? `ssrRender` : `render`;2431 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2432 const signature = args.join(', ');2433 {2434 push(`function ${functionName}(${signature}) {`);2435 }2436 indent();2437 if (useWithBlock) {2438 push(`with (_ctx) {`);2439 indent();2440 // function mode const declarations should be inside with block2441 // also they should be renamed to avoid collision with user properties2442 if (hasHelpers) {2443 push(`const { ${ast.helpers2444 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2445 .join(', ')} } = _Vue`);2446 push(`\n`);2447 newline();2448 }2449 }2450 // generate asset resolution statements2451 if (ast.components.length) {2452 genAssets(ast.components, 'component', context);2453 if (ast.directives.length || ast.temps > 0) {2454 newline();2455 }2456 }2457 if (ast.directives.length) {2458 genAssets(ast.directives, 'directive', context);2459 if (ast.temps > 0) {2460 newline();2461 }2462 }2463 if (ast.filters && ast.filters.length) {2464 newline();2465 genAssets(ast.filters, 'filter', context);2466 newline();2467 }2468 if (ast.temps > 0) {2469 push(`let `);2470 for (let i = 0; i < ast.temps; i++) {2471 push(`${i > 0 ? `, ` : ``}_temp${i}`);2472 }2473 }2474 if (ast.components.length || ast.directives.length || ast.temps) {2475 push(`\n`);2476 newline();2477 }2478 // generate the VNode tree expression2479 if (!ssr) {2480 push(`return `);2481 }2482 if (ast.codegenNode) {2483 genNode(ast.codegenNode, context);2484 }2485 else {2486 push(`null`);2487 }2488 if (useWithBlock) {2489 deindent();2490 push(`}`);2491 }2492 deindent();2493 push(`}`);2494 return {2495 ast,2496 code: context.code,2497 preamble: ``,2498 // SourceMapGenerator does have toJSON() method but it's not in the types2499 map: context.map ? context.map.toJSON() : undefined2500 };2501 }2502 function genFunctionPreamble(ast, context) {2503 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2504 const VueBinding = runtimeGlobalName;2505 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2506 // Generate const declaration for helpers2507 // In prefix mode, we place the const declaration at top so it's done2508 // only once; But if we not prefixing, we place the declaration inside the2509 // with block so it doesn't incur the `in` check cost for every helper access.2510 if (ast.helpers.length > 0) {2511 {2512 // "with" mode.2513 // save Vue in a separate variable to avoid collision2514 push(`const _Vue = ${VueBinding}\n`);2515 // in "with" mode, helpers are declared inside the with block to avoid2516 // has check cost, but hoists are lifted out of the function - we need2517 // to provide the helper here.2518 if (ast.hoists.length) {2519 const staticHelpers = [2520 CREATE_VNODE,2521 CREATE_ELEMENT_VNODE,2522 CREATE_COMMENT,2523 CREATE_TEXT,2524 CREATE_STATIC2525 ]2526 .filter(helper => ast.helpers.includes(helper))2527 .map(aliasHelper)2528 .join(', ');2529 push(`const { ${staticHelpers} } = _Vue\n`);2530 }2531 }2532 }2533 genHoists(ast.hoists, context);2534 newline();2535 push(`return `);2536 }2537 function genAssets(assets, type, { helper, push, newline, isTS }) {2538 const resolver = helper(type === 'filter'2539 ? RESOLVE_FILTER2540 : type === 'component'2541 ? RESOLVE_COMPONENT2542 : RESOLVE_DIRECTIVE);2543 for (let i = 0; i < assets.length; i++) {2544 let id = assets[i];2545 // potential component implicit self-reference inferred from SFC filename2546 const maybeSelfReference = id.endsWith('__self');2547 if (maybeSelfReference) {2548 id = id.slice(0, -6);2549 }2550 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2551 if (i < assets.length - 1) {2552 newline();2553 }2554 }2555 }2556 function genHoists(hoists, context) {2557 if (!hoists.length) {2558 return;2559 }2560 context.pure = true;2561 const { push, newline, helper, scopeId, mode } = context;2562 newline();2563 for (let i = 0; i < hoists.length; i++) {2564 const exp = hoists[i];2565 if (exp) {2566 push(`const _hoisted_${i + 1} = ${``}`);2567 genNode(exp, context);2568 newline();2569 }2570 }2571 context.pure = false;2572 }2573 function isText$1(n) {2574 return (isString(n) ||2575 n.type === 4 /* SIMPLE_EXPRESSION */ ||2576 n.type === 2 /* TEXT */ ||2577 n.type === 5 /* INTERPOLATION */ ||2578 n.type === 8 /* COMPOUND_EXPRESSION */);2579 }2580 function genNodeListAsArray(nodes, context) {2581 const multilines = nodes.length > 3 ||2582 (nodes.some(n => isArray(n) || !isText$1(n)));2583 context.push(`[`);2584 multilines && context.indent();2585 genNodeList(nodes, context, multilines);2586 multilines && context.deindent();2587 context.push(`]`);2588 }2589 function genNodeList(nodes, context, multilines = false, comma = true) {2590 const { push, newline } = context;2591 for (let i = 0; i < nodes.length; i++) {2592 const node = nodes[i];2593 if (isString(node)) {2594 push(node);2595 }2596 else if (isArray(node)) {2597 genNodeListAsArray(node, context);2598 }2599 else {2600 genNode(node, context);2601 }2602 if (i < nodes.length - 1) {2603 if (multilines) {2604 comma && push(',');2605 newline();2606 }2607 else {2608 comma && push(', ');2609 }2610 }2611 }2612 }2613 function genNode(node, context) {2614 if (isString(node)) {2615 context.push(node);2616 return;2617 }2618 if (isSymbol(node)) {2619 context.push(context.helper(node));2620 return;2621 }2622 switch (node.type) {2623 case 1 /* ELEMENT */:2624 case 9 /* IF */:2625 case 11 /* FOR */:2626 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2627 `Apply appropriate transforms first.`);2628 genNode(node.codegenNode, context);2629 break;2630 case 2 /* TEXT */:2631 genText(node, context);2632 break;2633 case 4 /* SIMPLE_EXPRESSION */:2634 genExpression(node, context);2635 break;2636 case 5 /* INTERPOLATION */:2637 genInterpolation(node, context);2638 break;2639 case 12 /* TEXT_CALL */:2640 genNode(node.codegenNode, context);2641 break;2642 case 8 /* COMPOUND_EXPRESSION */:2643 genCompoundExpression(node, context);2644 break;2645 case 3 /* COMMENT */:2646 genComment(node, context);2647 break;2648 case 13 /* VNODE_CALL */:2649 genVNodeCall(node, context);2650 break;2651 case 14 /* JS_CALL_EXPRESSION */:2652 genCallExpression(node, context);2653 break;2654 case 15 /* JS_OBJECT_EXPRESSION */:2655 genObjectExpression(node, context);2656 break;2657 case 17 /* JS_ARRAY_EXPRESSION */:2658 genArrayExpression(node, context);2659 break;2660 case 18 /* JS_FUNCTION_EXPRESSION */:2661 genFunctionExpression(node, context);2662 break;2663 case 19 /* JS_CONDITIONAL_EXPRESSION */:2664 genConditionalExpression(node, context);2665 break;2666 case 20 /* JS_CACHE_EXPRESSION */:2667 genCacheExpression(node, context);2668 break;2669 case 21 /* JS_BLOCK_STATEMENT */:2670 genNodeList(node.body, context, true, false);2671 break;2672 // SSR only types2673 case 22 /* JS_TEMPLATE_LITERAL */:2674 break;2675 case 23 /* JS_IF_STATEMENT */:2676 break;2677 case 24 /* JS_ASSIGNMENT_EXPRESSION */:2678 break;2679 case 25 /* JS_SEQUENCE_EXPRESSION */:2680 break;2681 case 26 /* JS_RETURN_STATEMENT */:2682 break;2683 /* istanbul ignore next */2684 case 10 /* IF_BRANCH */:2685 // noop2686 break;2687 default:2688 {2689 assert(false, `unhandled codegen node type: ${node.type}`);2690 // make sure we exhaust all possible types2691 const exhaustiveCheck = node;2692 return exhaustiveCheck;2693 }2694 }2695 }2696 function genText(node, context) {2697 context.push(JSON.stringify(node.content), node);2698 }2699 function genExpression(node, context) {2700 const { content, isStatic } = node;2701 context.push(isStatic ? JSON.stringify(content) : content, node);2702 }2703 function genInterpolation(node, context) {2704 const { push, helper, pure } = context;2705 if (pure)2706 push(PURE_ANNOTATION);2707 push(`${helper(TO_DISPLAY_STRING)}(`);2708 genNode(node.content, context);2709 push(`)`);2710 }2711 function genCompoundExpression(node, context) {2712 for (let i = 0; i < node.children.length; i++) {2713 const child = node.children[i];2714 if (isString(child)) {2715 context.push(child);2716 }2717 else {2718 genNode(child, context);2719 }2720 }2721 }2722 function genExpressionAsPropertyKey(node, context) {2723 const { push } = context;2724 if (node.type === 8 /* COMPOUND_EXPRESSION */) {2725 push(`[`);2726 genCompoundExpression(node, context);2727 push(`]`);2728 }2729 else if (node.isStatic) {2730 // only quote keys if necessary2731 const text = isSimpleIdentifier(node.content)2732 ? node.content2733 : JSON.stringify(node.content);2734 push(text, node);2735 }2736 else {2737 push(`[${node.content}]`, node);2738 }2739 }2740 function genComment(node, context) {2741 const { push, helper, pure } = context;2742 if (pure) {2743 push(PURE_ANNOTATION);2744 }2745 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2746 }2747 function genVNodeCall(node, context) {2748 const { push, helper, pure } = context;2749 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2750 if (directives) {2751 push(helper(WITH_DIRECTIVES) + `(`);2752 }2753 if (isBlock) {2754 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2755 }2756 if (pure) {2757 push(PURE_ANNOTATION);2758 }2759 const callHelper = isBlock2760 ? getVNodeBlockHelper(context.inSSR, isComponent)2761 : getVNodeHelper(context.inSSR, isComponent);2762 push(helper(callHelper) + `(`, node);2763 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2764 push(`)`);2765 if (isBlock) {2766 push(`)`);2767 }2768 if (directives) {2769 push(`, `);2770 genNode(directives, context);2771 push(`)`);2772 }2773 }2774 function genNullableArgs(args) {2775 let i = args.length;2776 while (i--) {2777 if (args[i] != null)2778 break;2779 }2780 return args.slice(0, i + 1).map(arg => arg || `null`);2781 }2782 // JavaScript2783 function genCallExpression(node, context) {2784 const { push, helper, pure } = context;2785 const callee = isString(node.callee) ? node.callee : helper(node.callee);2786 if (pure) {2787 push(PURE_ANNOTATION);2788 }2789 push(callee + `(`, node);2790 genNodeList(node.arguments, context);2791 push(`)`);2792 }2793 function genObjectExpression(node, context) {2794 const { push, indent, deindent, newline } = context;2795 const { properties } = node;2796 if (!properties.length) {2797 push(`{}`, node);2798 return;2799 }2800 const multilines = properties.length > 1 ||2801 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2802 push(multilines ? `{` : `{ `);2803 multilines && indent();2804 for (let i = 0; i < properties.length; i++) {2805 const { key, value } = properties[i];2806 // key2807 genExpressionAsPropertyKey(key, context);2808 push(`: `);2809 // value2810 genNode(value, context);2811 if (i < properties.length - 1) {2812 // will only reach this if it's multilines2813 push(`,`);2814 newline();2815 }2816 }2817 multilines && deindent();2818 push(multilines ? `}` : ` }`);2819 }2820 function genArrayExpression(node, context) {2821 genNodeListAsArray(node.elements, context);2822 }2823 function genFunctionExpression(node, context) {2824 const { push, indent, deindent } = context;2825 const { params, returns, body, newline, isSlot } = node;2826 if (isSlot) {2827 // wrap slot functions with owner context2828 push(`_${helperNameMap[WITH_CTX]}(`);2829 }2830 push(`(`, node);2831 if (isArray(params)) {2832 genNodeList(params, context);2833 }2834 else if (params) {2835 genNode(params, context);2836 }2837 push(`) => `);2838 if (newline || body) {2839 push(`{`);2840 indent();2841 }2842 if (returns) {2843 if (newline) {2844 push(`return `);2845 }2846 if (isArray(returns)) {2847 genNodeListAsArray(returns, context);2848 }2849 else {2850 genNode(returns, context);2851 }2852 }2853 else if (body) {2854 genNode(body, context);2855 }2856 if (newline || body) {2857 deindent();2858 push(`}`);2859 }2860 if (isSlot) {2861 if (node.isNonScopedSlot) {2862 push(`, undefined, true`);2863 }2864 push(`)`);2865 }2866 }2867 function genConditionalExpression(node, context) {2868 const { test, consequent, alternate, newline: needNewline } = node;2869 const { push, indent, deindent, newline } = context;2870 if (test.type === 4 /* SIMPLE_EXPRESSION */) {2871 const needsParens = !isSimpleIdentifier(test.content);2872 needsParens && push(`(`);2873 genExpression(test, context);2874 needsParens && push(`)`);2875 }2876 else {2877 push(`(`);2878 genNode(test, context);2879 push(`)`);2880 }2881 needNewline && indent();2882 context.indentLevel++;2883 needNewline || push(` `);2884 push(`? `);2885 genNode(consequent, context);2886 context.indentLevel--;2887 needNewline && newline();2888 needNewline || push(` `);2889 push(`: `);2890 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2891 if (!isNested) {2892 context.indentLevel++;2893 }2894 genNode(alternate, context);2895 if (!isNested) {2896 context.indentLevel--;2897 }2898 needNewline && deindent(true /* without newline */);2899 }2900 function genCacheExpression(node, context) {2901 const { push, helper, indent, deindent, newline } = context;2902 push(`_cache[${node.index}] || (`);2903 if (node.isVNode) {2904 indent();2905 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2906 newline();2907 }2908 push(`_cache[${node.index}] = `);2909 genNode(node.value, context);2910 if (node.isVNode) {2911 push(`,`);2912 newline();2913 push(`${helper(SET_BLOCK_TRACKING)}(1),`);2914 newline();2915 push(`_cache[${node.index}]`);2916 deindent();2917 }2918 push(`)`);2919 }2920 function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2921 {2922 return;2923 }2924 }2925 function isReferencedIdentifier(id, parent, parentStack) {2926 {2927 return false;2928 }2929 }2930 function isInDestructureAssignment(parent, parentStack) {2931 if (parent &&2932 (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {2933 let i = parentStack.length;2934 while (i--) {2935 const p = parentStack[i];2936 if (p.type === 'AssignmentExpression') {2937 return true;2938 }2939 else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {2940 break;2941 }2942 }2943 }2944 return false;2945 }2946 function walkFunctionParams(node, onIdent) {2947 for (const p of node.params) {2948 for (const id of extractIdentifiers(p)) {2949 onIdent(id);2950 }2951 }2952 }2953 function walkBlockDeclarations(block, onIdent) {2954 for (const stmt of block.body) {2955 if (stmt.type === 'VariableDeclaration') {2956 if (stmt.declare)2957 continue;2958 for (const decl of stmt.declarations) {2959 for (const id of extractIdentifiers(decl.id)) {2960 onIdent(id);2961 }2962 }2963 }2964 else if (stmt.type === 'FunctionDeclaration' ||2965 stmt.type === 'ClassDeclaration') {2966 if (stmt.declare || !stmt.id)2967 continue;2968 onIdent(stmt.id);2969 }2970 }2971 }2972 function extractIdentifiers(param, nodes = []) {2973 switch (param.type) {2974 case 'Identifier':2975 nodes.push(param);2976 break;2977 case 'MemberExpression':2978 let object = param;2979 while (object.type === 'MemberExpression') {2980 object = object.object;2981 }2982 nodes.push(object);2983 break;2984 case 'ObjectPattern':2985 for (const prop of param.properties) {2986 if (prop.type === 'RestElement') {2987 extractIdentifiers(prop.argument, nodes);2988 }2989 else {2990 extractIdentifiers(prop.value, nodes);2991 }2992 }2993 break;2994 case 'ArrayPattern':2995 param.elements.forEach(element => {2996 if (element)2997 extractIdentifiers(element, nodes);2998 });2999 break;3000 case 'RestElement':3001 extractIdentifiers(param.argument, nodes);3002 break;3003 case 'AssignmentPattern':3004 extractIdentifiers(param.left, nodes);3005 break;3006 }3007 return nodes;3008 }3009 const isFunctionType = (node) => {3010 return /Function(?:Expression|Declaration)$|Method$/.test(node.type);3011 };3012 const isStaticProperty = (node) => node &&3013 (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&3014 !node.computed;3015 const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;3016 // these keywords should not appear inside expressions, but operators like3017 // typeof, instanceof and in are allowed3018 const prohibitedKeywordRE = new RegExp('\\b' +3019 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +3020 'super,throw,while,yield,delete,export,import,return,switch,default,' +3021 'extends,finally,continue,debugger,function,arguments,typeof,void')3022 .split(',')3023 .join('\\b|\\b') +3024 '\\b');3025 // strip strings in expressions3026 const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;3027 /**3028 * Validate a non-prefixed expression.3029 * This is only called when using the in-browser runtime compiler since it3030 * doesn't prefix expressions.3031 */3032 function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {3033 const exp = node.content;3034 // empty expressions are validated per-directive since some directives3035 // do allow empty expressions.3036 if (!exp.trim()) {3037 return;3038 }3039 try {3040 new Function(asRawStatements3041 ? ` ${exp} `3042 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);3043 }3044 catch (e) {3045 let message = e.message;3046 const keywordMatch = exp3047 .replace(stripStringRE, '')3048 .match(prohibitedKeywordRE);3049 if (keywordMatch) {3050 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;3051 }3052 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));3053 }3054 }3055 const transformExpression = (node, context) => {3056 if (node.type === 5 /* INTERPOLATION */) {3057 node.content = processExpression(node.content, context);3058 }3059 else if (node.type === 1 /* ELEMENT */) {3060 // handle directives on element3061 for (let i = 0; i < node.props.length; i++) {3062 const dir = node.props[i];3063 // do not process for v-on & v-for since they are special handled3064 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3065 const exp = dir.exp;3066 const arg = dir.arg;3067 // do not process exp if this is v-on:arg - we need special handling3068 // for wrapping inline statements.3069 if (exp &&3070 exp.type === 4 /* SIMPLE_EXPRESSION */ &&3071 !(dir.name === 'on' && arg)) {3072 dir.exp = processExpression(exp, context, 3073 // slot args must be processed as function params3074 dir.name === 'slot');3075 }3076 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3077 dir.arg = processExpression(arg, context);3078 }3079 }3080 }3081 }3082 };3083 // Important: since this function uses Node.js only dependencies, it should3084 // always be used with a leading !true check so that it can be3085 // tree-shaken from the browser build.3086 function processExpression(node, context, 3087 // some expressions like v-slot props & v-for aliases should be parsed as3088 // function params3089 asParams = false, 3090 // v-on handler values may contain multiple statements3091 asRawStatements = false, localVars = Object.create(context.identifiers)) {3092 {3093 {3094 // simple in-browser validation (same logic in 2.x)3095 validateBrowserExpression(node, context, asParams, asRawStatements);3096 }3097 return node;3098 }3099 }3100 const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3101 return processIf(node, dir, context, (ifNode, branch, isRoot) => {3102 // #1587: We need to dynamically increment the key based on the current3103 // node's sibling nodes, since chained v-if/else branches are3104 // rendered at the same depth3105 const siblings = context.parent.children;3106 let i = siblings.indexOf(ifNode);3107 let key = 0;3108 while (i-- >= 0) {3109 const sibling = siblings[i];3110 if (sibling && sibling.type === 9 /* IF */) {3111 key += sibling.branches.length;3112 }3113 }3114 // Exit callback. Complete the codegenNode when all children have been3115 // transformed.3116 return () => {3117 if (isRoot) {3118 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3119 }3120 else {3121 // attach this branch's codegen node to the v-if root.3122 const parentCondition = getParentCondition(ifNode.codegenNode);3123 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3124 }3125 };3126 });3127 });3128 // target-agnostic transform used for both Client and SSR3129 function processIf(node, dir, context, processCodegen) {3130 if (dir.name !== 'else' &&3131 (!dir.exp || !dir.exp.content.trim())) {3132 const loc = dir.exp ? dir.exp.loc : node.loc;3133 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3134 dir.exp = createSimpleExpression(`true`, false, loc);3135 }3136 if (dir.exp) {3137 validateBrowserExpression(dir.exp, context);3138 }3139 if (dir.name === 'if') {3140 const branch = createIfBranch(node, dir);3141 const ifNode = {3142 type: 9 /* IF */,3143 loc: node.loc,3144 branches: [branch]3145 };3146 context.replaceNode(ifNode);3147 if (processCodegen) {3148 return processCodegen(ifNode, branch, true);3149 }3150 }3151 else {3152 // locate the adjacent v-if3153 const siblings = context.parent.children;3154 const comments = [];3155 let i = siblings.indexOf(node);3156 while (i-- >= -1) {3157 const sibling = siblings[i];3158 if (sibling && sibling.type === 3 /* COMMENT */) {3159 context.removeNode(sibling);3160 comments.unshift(sibling);3161 continue;3162 }3163 if (sibling &&3164 sibling.type === 2 /* TEXT */ &&3165 !sibling.content.trim().length) {3166 context.removeNode(sibling);3167 continue;3168 }3169 if (sibling && sibling.type === 9 /* IF */) {3170 // Check if v-else was followed by v-else-if3171 if (dir.name === 'else-if' &&3172 sibling.branches[sibling.branches.length - 1].condition === undefined) {3173 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3174 }3175 // move the node to the if node's branches3176 context.removeNode();3177 const branch = createIfBranch(node, dir);3178 if (comments.length &&3179 // #3619 ignore comments if the v-if is direct child of <transition>3180 !(context.parent &&3181 context.parent.type === 1 /* ELEMENT */ &&3182 isBuiltInType(context.parent.tag, 'transition'))) {3183 branch.children = [...comments, ...branch.children];3184 }3185 // check if user is forcing same key on different branches3186 {3187 const key = branch.userKey;3188 if (key) {3189 sibling.branches.forEach(({ userKey }) => {3190 if (isSameKey(userKey, key)) {3191 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3192 }3193 });3194 }3195 }3196 sibling.branches.push(branch);3197 const onExit = processCodegen && processCodegen(sibling, branch, false);3198 // since the branch was removed, it will not be traversed.3199 // make sure to traverse here.3200 traverseNode(branch, context);3201 // call on exit3202 if (onExit)3203 onExit();3204 // make sure to reset currentNode after traversal to indicate this3205 // node has been removed.3206 context.currentNode = null;3207 }3208 else {3209 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3210 }3211 break;3212 }3213 }3214 }3215 function createIfBranch(node, dir) {3216 return {3217 type: 10 /* IF_BRANCH */,3218 loc: node.loc,3219 condition: dir.name === 'else' ? undefined : dir.exp,3220 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3221 ? node.children3222 : [node],3223 userKey: findProp(node, `key`)3224 };3225 }3226 function createCodegenNodeForBranch(branch, keyIndex, context) {3227 if (branch.condition) {3228 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3229 // make sure to pass in asBlock: true so that the comment node call3230 // closes the current block.3231 createCallExpression(context.helper(CREATE_COMMENT), [3232 '"v-if"' ,3233 'true'3234 ]));3235 }3236 else {3237 return createChildrenCodegenNode(branch, keyIndex, context);3238 }3239 }3240 function createChildrenCodegenNode(branch, keyIndex, context) {3241 const { helper } = context;3242 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3243 const { children } = branch;3244 const firstChild = children[0];3245 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3246 if (needFragmentWrapper) {3247 if (children.length === 1 && firstChild.type === 11 /* FOR */) {3248 // optimize away nested fragments when child is a ForNode3249 const vnodeCall = firstChild.codegenNode;3250 injectProp(vnodeCall, keyProperty, context);3251 return vnodeCall;3252 }3253 else {3254 let patchFlag = 64 /* STABLE_FRAGMENT */;3255 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];3256 // check if the fragment actually contains a single valid child with3257 // the rest being comments3258 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3259 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3260 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3261 }3262 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);3263 }3264 }3265 else {3266 const ret = firstChild.codegenNode;3267 const vnodeCall = getMemoedVNodeCall(ret);3268 // Change createVNode to createBlock.3269 if (vnodeCall.type === 13 /* VNODE_CALL */) {3270 makeBlock(vnodeCall, context);3271 }3272 // inject branch key3273 injectProp(vnodeCall, keyProperty, context);3274 return ret;3275 }3276 }3277 function isSameKey(a, b) {3278 if (!a || a.type !== b.type) {3279 return false;3280 }3281 if (a.type === 6 /* ATTRIBUTE */) {3282 if (a.value.content !== b.value.content) {3283 return false;3284 }3285 }3286 else {3287 // directive3288 const exp = a.exp;3289 const branchExp = b.exp;3290 if (exp.type !== branchExp.type) {3291 return false;3292 }3293 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3294 exp.isStatic !== branchExp.isStatic ||3295 exp.content !== branchExp.content) {3296 return false;3297 }3298 }3299 return true;3300 }3301 function getParentCondition(node) {3302 while (true) {3303 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3304 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3305 node = node.alternate;3306 }3307 else {3308 return node;3309 }3310 }3311 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3312 node = node.value;3313 }3314 }3315 }3316 const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3317 const { helper, removeHelper } = context;3318 return processFor(node, dir, context, forNode => {3319 // create the loop render function expression now, and add the3320 // iterator on exit after all children have been traversed3321 const renderExp = createCallExpression(helper(RENDER_LIST), [3322 forNode.source3323 ]);3324 const memo = findDir(node, 'memo');3325 const keyProp = findProp(node, `key`);3326 const keyExp = keyProp &&3327 (keyProp.type === 6 /* ATTRIBUTE */3328 ? createSimpleExpression(keyProp.value.content, true)3329 : keyProp.exp);3330 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3331 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3332 forNode.source.constType > 0 /* NOT_CONSTANT */;3333 const fragmentFlag = isStableFragment3334 ? 64 /* STABLE_FRAGMENT */3335 : keyProp3336 ? 128 /* KEYED_FRAGMENT */3337 : 256 /* UNKEYED_FRAGMENT */;3338 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3339 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3340 return () => {3341 // finish the codegen now that all children have been traversed3342 let childBlock;3343 const isTemplate = isTemplateNode(node);3344 const { children } = forNode;3345 // check <template v-for> key placement3346 if (isTemplate) {3347 node.children.some(c => {3348 if (c.type === 1 /* ELEMENT */) {3349 const key = findProp(c, 'key');3350 if (key) {3351 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3352 return true;3353 }3354 }3355 });3356 }3357 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3358 const slotOutlet = isSlotOutlet(node)3359 ? node3360 : isTemplate &&3361 node.children.length === 1 &&3362 isSlotOutlet(node.children[0])3363 ? node.children[0] // api-extractor somehow fails to infer this3364 : null;3365 if (slotOutlet) {3366 // <slot v-for="..."> or <template v-for="..."><slot/></template>3367 childBlock = slotOutlet.codegenNode;3368 if (isTemplate && keyProperty) {3369 // <template v-for="..." :key="..."><slot/></template>3370 // we need to inject the key to the renderSlot() call.3371 // the props for renderSlot is passed as the 3rd argument.3372 injectProp(childBlock, keyProperty, context);3373 }3374 }3375 else if (needFragmentWrapper) {3376 // <template v-for="..."> with text or multi-elements3377 // should generate a fragment block for each loop3378 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3379 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3380 ), undefined, undefined, true, undefined, false /* isComponent */);3381 }3382 else {3383 // Normal element v-for. Directly use the child's codegenNode3384 // but mark it as a block.3385 childBlock = children[0]3386 .codegenNode;3387 if (isTemplate && keyProperty) {3388 injectProp(childBlock, keyProperty, context);3389 }3390 if (childBlock.isBlock !== !isStableFragment) {3391 if (childBlock.isBlock) {3392 // switch from block to vnode3393 removeHelper(OPEN_BLOCK);3394 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3395 }3396 else {3397 // switch from vnode to block3398 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3399 }3400 }3401 childBlock.isBlock = !isStableFragment;3402 if (childBlock.isBlock) {3403 helper(OPEN_BLOCK);3404 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3405 }3406 else {3407 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3408 }3409 }3410 if (memo) {3411 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3412 createSimpleExpression(`_cached`)3413 ]));3414 loop.body = createBlockStatement([3415 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3416 createCompoundExpression([3417 `if (_cached`,3418 ...(keyExp ? [` && _cached.key === `, keyExp] : []),3419 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3420 ]),3421 createCompoundExpression([`const _item = `, childBlock]),3422 createSimpleExpression(`_item.memo = _memo`),3423 createSimpleExpression(`return _item`)3424 ]);3425 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3426 }3427 else {3428 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3429 }3430 };3431 });3432 });3433 // target-agnostic transform used for both Client and SSR3434 function processFor(node, dir, context, processCodegen) {3435 if (!dir.exp) {3436 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3437 return;3438 }3439 const parseResult = parseForExpression(3440 // can only be simple expression because vFor transform is applied3441 // before expression transform.3442 dir.exp, context);3443 if (!parseResult) {3444 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3445 return;3446 }3447 const { addIdentifiers, removeIdentifiers, scopes } = context;3448 const { source, value, key, index } = parseResult;3449 const forNode = {3450 type: 11 /* FOR */,3451 loc: dir.loc,3452 source,3453 valueAlias: value,3454 keyAlias: key,3455 objectIndexAlias: index,3456 parseResult,3457 children: isTemplateNode(node) ? node.children : [node]3458 };3459 context.replaceNode(forNode);3460 // bookkeeping3461 scopes.vFor++;3462 const onExit = processCodegen && processCodegen(forNode);3463 return () => {3464 scopes.vFor--;3465 if (onExit)3466 onExit();3467 };3468 }3469 const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3470 // This regex doesn't cover the case if key or index aliases have destructuring,3471 // but those do not make sense in the first place, so this works in practice.3472 const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3473 const stripParensRE = /^\(|\)$/g;3474 function parseForExpression(input, context) {3475 const loc = input.loc;3476 const exp = input.content;3477 const inMatch = exp.match(forAliasRE);3478 if (!inMatch)3479 return;3480 const [, LHS, RHS] = inMatch;3481 const result = {3482 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3483 value: undefined,3484 key: undefined,3485 index: undefined3486 };3487 {3488 validateBrowserExpression(result.source, context);3489 }3490 let valueContent = LHS.trim().replace(stripParensRE, '').trim();3491 const trimmedOffset = LHS.indexOf(valueContent);3492 const iteratorMatch = valueContent.match(forIteratorRE);3493 if (iteratorMatch) {3494 valueContent = valueContent.replace(forIteratorRE, '').trim();3495 const keyContent = iteratorMatch[1].trim();3496 let keyOffset;3497 if (keyContent) {3498 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3499 result.key = createAliasExpression(loc, keyContent, keyOffset);3500 {3501 validateBrowserExpression(result.key, context, true);3502 }3503 }3504 if (iteratorMatch[2]) {3505 const indexContent = iteratorMatch[2].trim();3506 if (indexContent) {3507 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3508 ? keyOffset + keyContent.length3509 : trimmedOffset + valueContent.length));3510 {3511 validateBrowserExpression(result.index, context, true);3512 }3513 }3514 }3515 }3516 if (valueContent) {3517 result.value = createAliasExpression(loc, valueContent, trimmedOffset);3518 {3519 validateBrowserExpression(result.value, context, true);3520 }3521 }3522 return result;3523 }3524 function createAliasExpression(range, content, offset) {3525 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3526 }3527 function createForLoopParams({ value, key, index }, memoArgs = []) {3528 return createParamsList([value, key, index, ...memoArgs]);3529 }3530 function createParamsList(args) {3531 let i = args.length;3532 while (i--) {3533 if (args[i])3534 break;3535 }3536 return args3537 .slice(0, i + 1)3538 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));3539 }3540 const defaultFallback = createSimpleExpression(`undefined`, false);3541 // A NodeTransform that:3542 // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3543 // by transformExpression. This is only applied in non-browser builds with3544 // { prefixIdentifiers: true }.3545 // 2. Track v-slot depths so that we know a slot is inside another slot.3546 // Note the exit callback is executed before buildSlots() on the same node,3547 // so only nested slots see positive numbers.3548 const trackSlotScopes = (node, context) => {3549 if (node.type === 1 /* ELEMENT */ &&3550 (node.tagType === 1 /* COMPONENT */ ||3551 node.tagType === 3 /* TEMPLATE */)) {3552 // We are only checking non-empty v-slot here3553 // since we only care about slots that introduce scope variables.3554 const vSlot = findDir(node, 'slot');3555 if (vSlot) {3556 vSlot.exp;3557 context.scopes.vSlot++;3558 return () => {3559 context.scopes.vSlot--;3560 };3561 }3562 }3563 };3564 // A NodeTransform that tracks scope identifiers for scoped slots with v-for.3565 // This transform is only applied in non-browser builds with { prefixIdentifiers: true }3566 const trackVForSlotScopes = (node, context) => {3567 let vFor;3568 if (isTemplateNode(node) &&3569 node.props.some(isVSlot) &&3570 (vFor = findDir(node, 'for'))) {3571 const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3572 if (result) {3573 const { value, key, index } = result;3574 const { addIdentifiers, removeIdentifiers } = context;3575 value && addIdentifiers(value);3576 key && addIdentifiers(key);3577 index && addIdentifiers(index);3578 return () => {3579 value && removeIdentifiers(value);3580 key && removeIdentifiers(key);3581 index && removeIdentifiers(index);3582 };3583 }3584 }3585 };3586 const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3587 // Instead of being a DirectiveTransform, v-slot processing is called during3588 // transformElement to build the slots object for a component.3589 function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3590 context.helper(WITH_CTX);3591 const { children, loc } = node;3592 const slotsProperties = [];3593 const dynamicSlots = [];3594 // If the slot is inside a v-for or another v-slot, force it to be dynamic3595 // since it likely uses a scope variable.3596 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3597 // 1. Check for slot with slotProps on component itself.3598 // <Comp v-slot="{ prop }"/>3599 const onComponentSlot = findDir(node, 'slot', true);3600 if (onComponentSlot) {3601 const { arg, exp } = onComponentSlot;3602 if (arg && !isStaticExp(arg)) {3603 hasDynamicSlots = true;3604 }3605 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));3606 }3607 // 2. Iterate through children and check for template slots3608 // <template v-slot:foo="{ prop }">3609 let hasTemplateSlots = false;3610 let hasNamedDefaultSlot = false;3611 const implicitDefaultChildren = [];3612 const seenSlotNames = new Set();3613 for (let i = 0; i < children.length; i++) {3614 const slotElement = children[i];3615 let slotDir;3616 if (!isTemplateNode(slotElement) ||3617 !(slotDir = findDir(slotElement, 'slot', true))) {3618 // not a <template v-slot>, skip.3619 if (slotElement.type !== 3 /* COMMENT */) {3620 implicitDefaultChildren.push(slotElement);3621 }3622 continue;3623 }3624 if (onComponentSlot) {3625 // already has on-component slot - this is incorrect usage.3626 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3627 break;3628 }3629 hasTemplateSlots = true;3630 const { children: slotChildren, loc: slotLoc } = slotElement;3631 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3632 // check if name is dynamic.3633 let staticSlotName;3634 if (isStaticExp(slotName)) {3635 staticSlotName = slotName ? slotName.content : `default`;3636 }3637 else {3638 hasDynamicSlots = true;3639 }3640 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3641 // check if this slot is conditional (v-if/v-for)3642 let vIf;3643 let vElse;3644 let vFor;3645 if ((vIf = findDir(slotElement, 'if'))) {3646 hasDynamicSlots = true;3647 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3648 }3649 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3650 // find adjacent v-if3651 let j = i;3652 let prev;3653 while (j--) {3654 prev = children[j];3655 if (prev.type !== 3 /* COMMENT */) {3656 break;3657 }3658 }3659 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3660 // remove node3661 children.splice(i, 1);3662 i--;3663 // attach this slot to previous conditional3664 let conditional = dynamicSlots[dynamicSlots.length - 1];3665 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3666 conditional = conditional.alternate;3667 }3668 conditional.alternate = vElse.exp3669 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3670 : buildDynamicSlot(slotName, slotFunction);3671 }3672 else {3673 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3674 }3675 }3676 else if ((vFor = findDir(slotElement, 'for'))) {3677 hasDynamicSlots = true;3678 const parseResult = vFor.parseResult ||3679 parseForExpression(vFor.exp, context);3680 if (parseResult) {3681 // Render the dynamic slots as an array and add it to the createSlot()3682 // args. The runtime knows how to handle it appropriately.3683 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3684 parseResult.source,3685 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3686 ]));3687 }3688 else {3689 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3690 }3691 }3692 else {3693 // check duplicate static names3694 if (staticSlotName) {3695 if (seenSlotNames.has(staticSlotName)) {3696 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3697 continue;3698 }3699 seenSlotNames.add(staticSlotName);3700 if (staticSlotName === 'default') {3701 hasNamedDefaultSlot = true;3702 }3703 }3704 slotsProperties.push(createObjectProperty(slotName, slotFunction));3705 }3706 }3707 if (!onComponentSlot) {3708 const buildDefaultSlotProperty = (props, children) => {3709 const fn = buildSlotFn(props, children, loc);3710 if (context.compatConfig) {3711 fn.isNonScopedSlot = true;3712 }3713 return createObjectProperty(`default`, fn);3714 };3715 if (!hasTemplateSlots) {3716 // implicit default slot (on component)3717 slotsProperties.push(buildDefaultSlotProperty(undefined, children));3718 }3719 else if (implicitDefaultChildren.length &&3720 // #37663721 // with whitespace: 'preserve', whitespaces between slots will end up in3722 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.3723 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {3724 // implicit default slot (mixed with named slots)3725 if (hasNamedDefaultSlot) {3726 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));3727 }3728 else {3729 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));3730 }3731 }3732 }3733 const slotFlag = hasDynamicSlots3734 ? 2 /* DYNAMIC */3735 : hasForwardedSlots(node.children)3736 ? 3 /* FORWARDED */3737 : 1 /* STABLE */;3738 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 3739 // 2 = compiled but dynamic = can skip normalization, but must run diff3740 // 1 = compiled and static = can skip normalization AND diff as optimized3741 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);3742 if (dynamicSlots.length) {3743 slots = createCallExpression(context.helper(CREATE_SLOTS), [3744 slots,3745 createArrayExpression(dynamicSlots)3746 ]);3747 }3748 return {3749 slots,3750 hasDynamicSlots3751 };3752 }3753 function buildDynamicSlot(name, fn) {3754 return createObjectExpression([3755 createObjectProperty(`name`, name),3756 createObjectProperty(`fn`, fn)3757 ]);3758 }3759 function hasForwardedSlots(children) {3760 for (let i = 0; i < children.length; i++) {3761 const child = children[i];3762 switch (child.type) {3763 case 1 /* ELEMENT */:3764 if (child.tagType === 2 /* SLOT */ ||3765 hasForwardedSlots(child.children)) {3766 return true;3767 }3768 break;3769 case 9 /* IF */:3770 if (hasForwardedSlots(child.branches))3771 return true;3772 break;3773 case 10 /* IF_BRANCH */:3774 case 11 /* FOR */:3775 if (hasForwardedSlots(child.children))3776 return true;3777 break;3778 }3779 }3780 return false;3781 }3782 function isNonWhitespaceContent(node) {3783 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)3784 return true;3785 return node.type === 2 /* TEXT */3786 ? !!node.content.trim()3787 : isNonWhitespaceContent(node.content);3788 }3789 // some directive transforms (e.g. v-model) may return a symbol for runtime3790 // import, which should be used instead of a resolveDirective call.3791 const directiveImportMap = new WeakMap();3792 // generate a JavaScript AST for this element's codegen3793 const transformElement = (node, context) => {3794 // perform the work on exit, after all child expressions have been3795 // processed and merged.3796 return function postTransformElement() {3797 node = context.currentNode;3798 if (!(node.type === 1 /* ELEMENT */ &&3799 (node.tagType === 0 /* ELEMENT */ ||3800 node.tagType === 1 /* COMPONENT */))) {3801 return;3802 }3803 const { tag, props } = node;3804 const isComponent = node.tagType === 1 /* COMPONENT */;3805 // The goal of the transform is to create a codegenNode implementing the3806 // VNodeCall interface.3807 let vnodeTag = isComponent3808 ? resolveComponentType(node, context)3809 : `"${tag}"`;3810 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;3811 let vnodeProps;3812 let vnodeChildren;3813 let vnodePatchFlag;3814 let patchFlag = 0;3815 let vnodeDynamicProps;3816 let dynamicPropNames;3817 let vnodeDirectives;3818 let shouldUseBlock = 3819 // dynamic component may resolve to plain elements3820 isDynamicComponent ||3821 vnodeTag === TELEPORT ||3822 vnodeTag === SUSPENSE ||3823 (!isComponent &&3824 // <svg> and <foreignObject> must be forced into blocks so that block3825 // updates inside get proper isSVG flag at runtime. (#639, #643)3826 // This is technically web-specific, but splitting the logic out of core3827 // leads to too much unnecessary complexity.3828 (tag === 'svg' ||3829 tag === 'foreignObject' ||3830 // #938: elements with dynamic keys should be forced into blocks3831 findProp(node, 'key', true)));3832 // props3833 if (props.length > 0) {3834 const propsBuildResult = buildProps(node, context);3835 vnodeProps = propsBuildResult.props;3836 patchFlag = propsBuildResult.patchFlag;3837 dynamicPropNames = propsBuildResult.dynamicPropNames;3838 const directives = propsBuildResult.directives;3839 vnodeDirectives =3840 directives && directives.length3841 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))3842 : undefined;3843 }3844 // children3845 if (node.children.length > 0) {3846 if (vnodeTag === KEEP_ALIVE) {3847 // Although a built-in component, we compile KeepAlive with raw children3848 // instead of slot functions so that it can be used inside Transition3849 // or other Transition-wrapping HOCs.3850 // To ensure correct updates with block optimizations, we need to:3851 // 1. Force keep-alive into a block. This avoids its children being3852 // collected by a parent block.3853 shouldUseBlock = true;3854 // 2. Force keep-alive to always be updated, since it uses raw children.3855 patchFlag |= 1024 /* DYNAMIC_SLOTS */;3856 if (node.children.length > 1) {3857 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {3858 start: node.children[0].loc.start,3859 end: node.children[node.children.length - 1].loc.end,3860 source: ''3861 }));3862 }3863 }3864 const shouldBuildAsSlots = isComponent &&3865 // Teleport is not a real component and has dedicated runtime handling3866 vnodeTag !== TELEPORT &&3867 // explained above.3868 vnodeTag !== KEEP_ALIVE;3869 if (shouldBuildAsSlots) {3870 const { slots, hasDynamicSlots } = buildSlots(node, context);3871 vnodeChildren = slots;3872 if (hasDynamicSlots) {3873 patchFlag |= 1024 /* DYNAMIC_SLOTS */;3874 }3875 }3876 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {3877 const child = node.children[0];3878 const type = child.type;3879 // check for dynamic text children3880 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||3881 type === 8 /* COMPOUND_EXPRESSION */;3882 if (hasDynamicTextChild &&3883 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {3884 patchFlag |= 1 /* TEXT */;3885 }3886 // pass directly if the only child is a text node3887 // (plain / interpolation / expression)3888 if (hasDynamicTextChild || type === 2 /* TEXT */) {3889 vnodeChildren = child;3890 }3891 else {3892 vnodeChildren = node.children;3893 }3894 }3895 else {3896 vnodeChildren = node.children;3897 }3898 }3899 // patchFlag & dynamicPropNames3900 if (patchFlag !== 0) {3901 {3902 if (patchFlag < 0) {3903 // special flags (negative and mutually exclusive)3904 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;3905 }3906 else {3907 // bitwise flags3908 const flagNames = Object.keys(PatchFlagNames)3909 .map(Number)3910 .filter(n => n > 0 && patchFlag & n)3911 .map(n => PatchFlagNames[n])3912 .join(`, `);3913 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;3914 }3915 }3916 if (dynamicPropNames && dynamicPropNames.length) {3917 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);3918 }3919 }3920 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);3921 };3922 };3923 function resolveComponentType(node, context, ssr = false) {3924 let { tag } = node;3925 // 1. dynamic component3926 const isExplicitDynamic = isComponentTag(tag);3927 const isProp = findProp(node, 'is');3928 if (isProp) {3929 if (isExplicitDynamic ||3930 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {3931 const exp = isProp.type === 6 /* ATTRIBUTE */3932 ? isProp.value && createSimpleExpression(isProp.value.content, true)3933 : isProp.exp;3934 if (exp) {3935 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3936 exp3937 ]);3938 }3939 }3940 else if (isProp.type === 6 /* ATTRIBUTE */ &&3941 isProp.value.content.startsWith('vue:')) {3942 // <button is="vue:xxx">3943 // if not <component>, only is value that starts with "vue:" will be3944 // treated as component by the parse phase and reach here, unless it's3945 // compat mode where all is values are considered components3946 tag = isProp.value.content.slice(4);3947 }3948 }3949 // 1.5 v-is (TODO: Deprecate)3950 const isDir = !isExplicitDynamic && findDir(node, 'is');3951 if (isDir && isDir.exp) {3952 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3953 isDir.exp3954 ]);3955 }3956 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)3957 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);3958 if (builtIn) {3959 // built-ins are simply fallthroughs / have special handling during ssr3960 // so we don't need to import their runtime equivalents3961 if (!ssr)3962 context.helper(builtIn);3963 return builtIn;3964 }3965 // 5. user component (resolve)3966 context.helper(RESOLVE_COMPONENT);3967 context.components.add(tag);3968 return toValidAssetId(tag, `component`);3969 }3970 function buildProps(node, context, props = node.props, ssr = false) {3971 const { tag, loc: elementLoc } = node;3972 const isComponent = node.tagType === 1 /* COMPONENT */;3973 let properties = [];3974 const mergeArgs = [];3975 const runtimeDirectives = [];3976 // patchFlag analysis3977 let patchFlag = 0;3978 let hasRef = false;3979 let hasClassBinding = false;3980 let hasStyleBinding = false;3981 let hasHydrationEventBinding = false;3982 let hasDynamicKeys = false;3983 let hasVnodeHook = false;3984 const dynamicPropNames = [];3985 const analyzePatchFlag = ({ key, value }) => {3986 if (isStaticExp(key)) {3987 const name = key.content;3988 const isEventHandler = isOn(name);3989 if (!isComponent &&3990 isEventHandler &&3991 // omit the flag for click handlers because hydration gives click3992 // dedicated fast path.3993 name.toLowerCase() !== 'onclick' &&3994 // omit v-model handlers3995 name !== 'onUpdate:modelValue' &&3996 // omit onVnodeXXX hooks3997 !isReservedProp(name)) {3998 hasHydrationEventBinding = true;3999 }4000 if (isEventHandler && isReservedProp(name)) {4001 hasVnodeHook = true;4002 }4003 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||4004 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||4005 value.type === 8 /* COMPOUND_EXPRESSION */) &&4006 getConstantType(value, context) > 0)) {4007 // skip if the prop is a cached handler or has constant value4008 return;4009 }4010 if (name === 'ref') {4011 hasRef = true;4012 }4013 else if (name === 'class') {4014 hasClassBinding = true;4015 }4016 else if (name === 'style') {4017 hasStyleBinding = true;4018 }4019 else if (name !== 'key' && !dynamicPropNames.includes(name)) {4020 dynamicPropNames.push(name);4021 }4022 // treat the dynamic class and style binding of the component as dynamic props4023 if (isComponent &&4024 (name === 'class' || name === 'style') &&4025 !dynamicPropNames.includes(name)) {4026 dynamicPropNames.push(name);4027 }4028 }4029 else {4030 hasDynamicKeys = true;4031 }4032 };4033 for (let i = 0; i < props.length; i++) {4034 // static attribute4035 const prop = props[i];4036 if (prop.type === 6 /* ATTRIBUTE */) {4037 const { loc, name, value } = prop;4038 let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);4039 if (name === 'ref') {4040 hasRef = true;4041 }4042 // skip is on <component>, or is="vue:xxx"4043 if (name === 'is' &&4044 (isComponentTag(tag) ||4045 (value && value.content.startsWith('vue:')) ||4046 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4047 continue;4048 }4049 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));4050 }4051 else {4052 // directives4053 const { name, arg, exp, loc } = prop;4054 const isVBind = name === 'bind';4055 const isVOn = name === 'on';4056 // skip v-slot - it is handled by its dedicated transform.4057 if (name === 'slot') {4058 if (!isComponent) {4059 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4060 }4061 continue;4062 }4063 // skip v-once/v-memo - they are handled by dedicated transforms.4064 if (name === 'once' || name === 'memo') {4065 continue;4066 }4067 // skip v-is and :is on <component>4068 if (name === 'is' ||4069 (isVBind &&4070 isBindKey(arg, 'is') &&4071 (isComponentTag(tag) ||4072 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4073 continue;4074 }4075 // skip v-on in SSR compilation4076 if (isVOn && ssr) {4077 continue;4078 }4079 // special case for v-bind and v-on with no argument4080 if (!arg && (isVBind || isVOn)) {4081 hasDynamicKeys = true;4082 if (exp) {4083 if (properties.length) {4084 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4085 properties = [];4086 }4087 if (isVBind) {4088 {4089 // 2.x v-bind object order compat4090 {4091 const hasOverridableKeys = mergeArgs.some(arg => {4092 if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {4093 return arg.properties.some(({ key }) => {4094 if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||4095 !key.isStatic) {4096 return true;4097 }4098 return (key.content !== 'class' &&4099 key.content !== 'style' &&4100 !isOn(key.content));4101 });4102 }4103 else {4104 // dynamic expression4105 return true;4106 }4107 });4108 if (hasOverridableKeys) {4109 checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);4110 }4111 }4112 if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4113 mergeArgs.unshift(exp);4114 continue;4115 }4116 }4117 mergeArgs.push(exp);4118 }4119 else {4120 // v-on="obj" -> toHandlers(obj)4121 mergeArgs.push({4122 type: 14 /* JS_CALL_EXPRESSION */,4123 loc,4124 callee: context.helper(TO_HANDLERS),4125 arguments: [exp]4126 });4127 }4128 }4129 else {4130 context.onError(createCompilerError(isVBind4131 ? 34 /* X_V_BIND_NO_EXPRESSION */4132 : 35 /* X_V_ON_NO_EXPRESSION */, loc));4133 }4134 continue;4135 }4136 const directiveTransform = context.directiveTransforms[name];4137 if (directiveTransform) {4138 // has built-in directive transform.4139 const { props, needRuntime } = directiveTransform(prop, node, context);4140 !ssr && props.forEach(analyzePatchFlag);4141 properties.push(...props);4142 if (needRuntime) {4143 runtimeDirectives.push(prop);4144 if (isSymbol(needRuntime)) {4145 directiveImportMap.set(prop, needRuntime);4146 }4147 }4148 }4149 else {4150 // no built-in transform, this is a user custom directive.4151 runtimeDirectives.push(prop);4152 }4153 }4154 if (prop.type === 6 /* ATTRIBUTE */ &&4155 prop.name === 'ref' &&4156 context.scopes.vFor > 0 &&4157 checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {4158 properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));4159 }4160 }4161 let propsExpression = undefined;4162 // has v-bind="object" or v-on="object", wrap with mergeProps4163 if (mergeArgs.length) {4164 if (properties.length) {4165 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4166 }4167 if (mergeArgs.length > 1) {4168 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4169 }4170 else {4171 // single v-bind with nothing else - no need for a mergeProps call4172 propsExpression = mergeArgs[0];4173 }4174 }4175 else if (properties.length) {4176 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4177 }4178 // patchFlag analysis4179 if (hasDynamicKeys) {4180 patchFlag |= 16 /* FULL_PROPS */;4181 }4182 else {4183 if (hasClassBinding && !isComponent) {4184 patchFlag |= 2 /* CLASS */;4185 }4186 if (hasStyleBinding && !isComponent) {4187 patchFlag |= 4 /* STYLE */;4188 }4189 if (dynamicPropNames.length) {4190 patchFlag |= 8 /* PROPS */;4191 }4192 if (hasHydrationEventBinding) {4193 patchFlag |= 32 /* HYDRATE_EVENTS */;4194 }4195 }4196 if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4197 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4198 patchFlag |= 512 /* NEED_PATCH */;4199 }4200 // pre-normalize props, SSR is skipped for now4201 if (!context.inSSR && propsExpression) {4202 switch (propsExpression.type) {4203 case 15 /* JS_OBJECT_EXPRESSION */:4204 // means that there is no v-bind,4205 // but still need to deal with dynamic key binding4206 let classKeyIndex = -1;4207 let styleKeyIndex = -1;4208 let hasDynamicKey = false;4209 for (let i = 0; i < propsExpression.properties.length; i++) {4210 const key = propsExpression.properties[i].key;4211 if (isStaticExp(key)) {4212 if (key.content === 'class') {4213 classKeyIndex = i;4214 }4215 else if (key.content === 'style') {4216 styleKeyIndex = i;4217 }4218 }4219 else if (!key.isHandlerKey) {4220 hasDynamicKey = true;4221 }4222 }4223 const classProp = propsExpression.properties[classKeyIndex];4224 const styleProp = propsExpression.properties[styleKeyIndex];4225 // no dynamic key4226 if (!hasDynamicKey) {4227 if (classProp && !isStaticExp(classProp.value)) {4228 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4229 }4230 if (styleProp &&4231 !isStaticExp(styleProp.value) &&4232 // the static style is compiled into an object,4233 // so use `hasStyleBinding` to ensure that it is a dynamic style binding4234 (hasStyleBinding ||4235 // v-bind:style and style both exist,4236 // v-bind:style with static literal object4237 styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4238 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4239 }4240 }4241 else {4242 // dynamic key binding, wrap with `normalizeProps`4243 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4244 }4245 break;4246 case 14 /* JS_CALL_EXPRESSION */:4247 // mergeProps call, do nothing4248 break;4249 default:4250 // single v-bind4251 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4252 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4253 propsExpression4254 ])4255 ]);4256 break;4257 }4258 }4259 return {4260 props: propsExpression,4261 directives: runtimeDirectives,4262 patchFlag,4263 dynamicPropNames4264 };4265 }4266 // Dedupe props in an object literal.4267 // Literal duplicated attributes would have been warned during the parse phase,4268 // however, it's possible to encounter duplicated `onXXX` handlers with different4269 // modifiers. We also need to merge static and dynamic class / style attributes.4270 // - onXXX handlers / style: merge into array4271 // - class: merge into single expression with concatenation4272 function dedupeProperties(properties) {4273 const knownProps = new Map();4274 const deduped = [];4275 for (let i = 0; i < properties.length; i++) {4276 const prop = properties[i];4277 // dynamic keys are always allowed4278 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4279 deduped.push(prop);4280 continue;4281 }4282 const name = prop.key.content;4283 const existing = knownProps.get(name);4284 if (existing) {4285 if (name === 'style' || name === 'class' || isOn(name)) {4286 mergeAsArray(existing, prop);4287 }4288 // unexpected duplicate, should have emitted error during parse4289 }4290 else {4291 knownProps.set(name, prop);4292 deduped.push(prop);4293 }4294 }4295 return deduped;4296 }4297 function mergeAsArray(existing, incoming) {4298 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4299 existing.value.elements.push(incoming.value);4300 }4301 else {4302 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4303 }4304 }4305 function buildDirectiveArgs(dir, context) {4306 const dirArgs = [];4307 const runtime = directiveImportMap.get(dir);4308 if (runtime) {4309 // built-in directive with runtime4310 dirArgs.push(context.helperString(runtime));4311 }4312 else {4313 {4314 // inject statement for resolving directive4315 context.helper(RESOLVE_DIRECTIVE);4316 context.directives.add(dir.name);4317 dirArgs.push(toValidAssetId(dir.name, `directive`));4318 }4319 }4320 const { loc } = dir;4321 if (dir.exp)4322 dirArgs.push(dir.exp);4323 if (dir.arg) {4324 if (!dir.exp) {4325 dirArgs.push(`void 0`);4326 }4327 dirArgs.push(dir.arg);4328 }4329 if (Object.keys(dir.modifiers).length) {4330 if (!dir.arg) {4331 if (!dir.exp) {4332 dirArgs.push(`void 0`);4333 }4334 dirArgs.push(`void 0`);4335 }4336 const trueExpression = createSimpleExpression(`true`, false, loc);4337 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4338 }4339 return createArrayExpression(dirArgs, dir.loc);4340 }4341 function stringifyDynamicPropNames(props) {4342 let propsNamesString = `[`;4343 for (let i = 0, l = props.length; i < l; i++) {4344 propsNamesString += JSON.stringify(props[i]);4345 if (i < l - 1)4346 propsNamesString += ', ';4347 }4348 return propsNamesString + `]`;4349 }4350 function isComponentTag(tag) {4351 return tag[0].toLowerCase() + tag.slice(1) === 'component';4352 }4353 const transformSlotOutlet = (node, context) => {4354 if (isSlotOutlet(node)) {4355 const { children, loc } = node;4356 const { slotName, slotProps } = processSlotOutlet(node, context);4357 const slotArgs = [4358 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4359 slotName,4360 '{}',4361 'undefined',4362 'true'4363 ];4364 let expectedLen = 2;4365 if (slotProps) {4366 slotArgs[2] = slotProps;4367 expectedLen = 3;4368 }4369 if (children.length) {4370 slotArgs[3] = createFunctionExpression([], children, false, false, loc);4371 expectedLen = 4;4372 }4373 if (context.scopeId && !context.slotted) {4374 expectedLen = 5;4375 }4376 slotArgs.splice(expectedLen); // remove unused arguments4377 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4378 }4379 };4380 function processSlotOutlet(node, context) {4381 let slotName = `"default"`;4382 let slotProps = undefined;4383 const nonNameProps = [];4384 for (let i = 0; i < node.props.length; i++) {4385 const p = node.props[i];4386 if (p.type === 6 /* ATTRIBUTE */) {4387 if (p.value) {4388 if (p.name === 'name') {4389 slotName = JSON.stringify(p.value.content);4390 }4391 else {4392 p.name = camelize(p.name);4393 nonNameProps.push(p);4394 }4395 }4396 }4397 else {4398 if (p.name === 'bind' && isBindKey(p.arg, 'name')) {4399 if (p.exp)4400 slotName = p.exp;4401 }4402 else {4403 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4404 p.arg.content = camelize(p.arg.content);4405 }4406 nonNameProps.push(p);4407 }4408 }4409 }4410 if (nonNameProps.length > 0) {4411 const { props, directives } = buildProps(node, context, nonNameProps);4412 slotProps = props;4413 if (directives.length) {4414 context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4415 }4416 }4417 return {4418 slotName,4419 slotProps4420 };4421 }4422 const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;4423 const transformOn = (dir, node, context, augmentor) => {4424 const { loc, modifiers, arg } = dir;4425 if (!dir.exp && !modifiers.length) {4426 context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));4427 }4428 let eventName;4429 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4430 if (arg.isStatic) {4431 const rawName = arg.content;4432 // for all event listeners, auto convert it to camelCase. See issue #22494433 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);4434 }4435 else {4436 // #23884437 eventName = createCompoundExpression([4438 `${context.helperString(TO_HANDLER_KEY)}(`,4439 arg,4440 `)`4441 ]);4442 }4443 }4444 else {4445 // already a compound expression.4446 eventName = arg;4447 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4448 eventName.children.push(`)`);4449 }4450 // handler processing4451 let exp = dir.exp;4452 if (exp && !exp.content.trim()) {4453 exp = undefined;4454 }4455 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;4456 if (exp) {4457 const isMemberExp = isMemberExpression(exp.content);4458 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4459 const hasMultipleStatements = exp.content.includes(`;`);4460 {4461 validateBrowserExpression(exp, context, false, hasMultipleStatements);4462 }4463 if (isInlineStatement || (shouldCache && isMemberExp)) {4464 // wrap inline statement in a function expression4465 exp = createCompoundExpression([4466 `${isInlineStatement4467 ? `$event`4468 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4469 exp,4470 hasMultipleStatements ? `}` : `)`4471 ]);4472 }4473 }4474 let ret = {4475 props: [4476 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4477 ]4478 };4479 // apply extended compiler augmentor4480 if (augmentor) {4481 ret = augmentor(ret);4482 }4483 if (shouldCache) {4484 // cache handlers so that it's always the same handler being passed down.4485 // this avoids unnecessary re-renders when users use inline handlers on4486 // components.4487 ret.props[0].value = context.cache(ret.props[0].value);4488 }4489 // mark the key as handler for props normalization check4490 ret.props.forEach(p => (p.key.isHandlerKey = true));4491 return ret;4492 };4493 // v-bind without arg is handled directly in ./transformElements.ts due to it affecting4494 // codegen for the entire props object. This transform here is only for v-bind4495 // *with* args.4496 const transformBind = (dir, _node, context) => {4497 const { exp, modifiers, loc } = dir;4498 const arg = dir.arg;4499 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {4500 arg.children.unshift(`(`);4501 arg.children.push(`) || ""`);4502 }4503 else if (!arg.isStatic) {4504 arg.content = `${arg.content} || ""`;4505 }4506 // .sync is replaced by v-model:arg4507 if (modifiers.includes('camel')) {4508 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4509 if (arg.isStatic) {4510 arg.content = camelize(arg.content);4511 }4512 else {4513 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;4514 }4515 }4516 else {4517 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);4518 arg.children.push(`)`);4519 }4520 }4521 if (!context.inSSR) {4522 if (modifiers.includes('prop')) {4523 injectPrefix(arg, '.');4524 }4525 if (modifiers.includes('attr')) {4526 injectPrefix(arg, '^');4527 }4528 }4529 if (!exp ||4530 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {4531 context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));4532 return {4533 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]4534 };4535 }4536 return {4537 props: [createObjectProperty(arg, exp)]4538 };4539 };4540 const injectPrefix = (arg, prefix) => {4541 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4542 if (arg.isStatic) {4543 arg.content = prefix + arg.content;4544 }4545 else {4546 arg.content = `\`${prefix}\${${arg.content}}\``;4547 }4548 }4549 else {4550 arg.children.unshift(`'${prefix}' + (`);4551 arg.children.push(`)`);4552 }4553 };4554 // Merge adjacent text nodes and expressions into a single expression4555 // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.4556 const transformText = (node, context) => {4557 if (node.type === 0 /* ROOT */ ||4558 node.type === 1 /* ELEMENT */ ||4559 node.type === 11 /* FOR */ ||4560 node.type === 10 /* IF_BRANCH */) {4561 // perform the transform on node exit so that all expressions have already4562 // been processed.4563 return () => {4564 const children = node.children;4565 let currentContainer = undefined;4566 let hasText = false;4567 for (let i = 0; i < children.length; i++) {4568 const child = children[i];4569 if (isText(child)) {4570 hasText = true;4571 for (let j = i + 1; j < children.length; j++) {4572 const next = children[j];4573 if (isText(next)) {4574 if (!currentContainer) {4575 currentContainer = children[i] = {4576 type: 8 /* COMPOUND_EXPRESSION */,4577 loc: child.loc,4578 children: [child]4579 };4580 }4581 // merge adjacent text node into current4582 currentContainer.children.push(` + `, next);4583 children.splice(j, 1);4584 j--;4585 }4586 else {4587 currentContainer = undefined;4588 break;4589 }4590 }4591 }4592 }4593 if (!hasText ||4594 // if this is a plain element with a single text child, leave it4595 // as-is since the runtime has dedicated fast path for this by directly4596 // setting textContent of the element.4597 // for component root it's always normalized anyway.4598 (children.length === 1 &&4599 (node.type === 0 /* ROOT */ ||4600 (node.type === 1 /* ELEMENT */ &&4601 node.tagType === 0 /* ELEMENT */ &&4602 // #37564603 // custom directives can potentially add DOM elements arbitrarily,4604 // we need to avoid setting textContent of the element at runtime4605 // to avoid accidentally overwriting the DOM elements added4606 // by the user through custom directives.4607 !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&4608 !context.directiveTransforms[p.name]) &&4609 // in compat mode, <template> tags with no special directives4610 // will be rendered as a fragment so its children must be4611 // converted into vnodes.4612 !(node.tag === 'template'))))) {4613 return;4614 }4615 // pre-convert text nodes into createTextVNode(text) calls to avoid4616 // runtime normalization.4617 for (let i = 0; i < children.length; i++) {4618 const child = children[i];4619 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {4620 const callArgs = [];4621 // createTextVNode defaults to single whitespace, so if it is a4622 // single space the code could be an empty call to save bytes.4623 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {4624 callArgs.push(child);4625 }4626 // mark dynamic text with flag so it gets patched inside a block4627 if (!context.ssr &&4628 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4629 callArgs.push(1 /* TEXT */ +4630 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));4631 }4632 children[i] = {4633 type: 12 /* TEXT_CALL */,4634 content: child,4635 loc: child.loc,4636 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)4637 };4638 }4639 }4640 };4641 }4642 };4643 const seen = new WeakSet();4644 const transformOnce = (node, context) => {4645 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {4646 if (seen.has(node) || context.inVOnce) {4647 return;4648 }4649 seen.add(node);4650 context.inVOnce = true;4651 context.helper(SET_BLOCK_TRACKING);4652 return () => {4653 context.inVOnce = false;4654 const cur = context.currentNode;4655 if (cur.codegenNode) {4656 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);4657 }4658 };4659 }4660 };4661 const transformModel = (dir, node, context) => {4662 const { exp, arg } = dir;4663 if (!exp) {4664 context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));4665 return createTransformProps();4666 }4667 const rawExp = exp.loc.source;4668 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;4669 // im SFC <script setup> inline mode, the exp may have been transformed into4670 // _unref(exp)4671 context.bindingMetadata[rawExp];4672 const maybeRef = !true /* SETUP_CONST */;4673 if (!expString.trim() ||4674 (!isMemberExpression(expString) && !maybeRef)) {4675 context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));4676 return createTransformProps();4677 }4678 const propName = arg ? arg : createSimpleExpression('modelValue', true);4679 const eventName = arg4680 ? isStaticExp(arg)4681 ? `onUpdate:${arg.content}`4682 : createCompoundExpression(['"onUpdate:" + ', arg])4683 : `onUpdate:modelValue`;4684 let assignmentExp;4685 const eventArg = context.isTS ? `($event: any)` : `$event`;4686 {4687 assignmentExp = createCompoundExpression([4688 `${eventArg} => ((`,4689 exp,4690 `) = $event)`4691 ]);4692 }4693 const props = [4694 // modelValue: foo4695 createObjectProperty(propName, dir.exp),4696 // "onUpdate:modelValue": $event => (foo = $event)4697 createObjectProperty(eventName, assignmentExp)4698 ];4699 // modelModifiers: { foo: true, "bar-baz": true }4700 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {4701 const modifiers = dir.modifiers4702 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)4703 .join(`, `);4704 const modifiersKey = arg4705 ? isStaticExp(arg)4706 ? `${arg.content}Modifiers`4707 : createCompoundExpression([arg, ' + "Modifiers"'])4708 : `modelModifiers`;4709 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));4710 }4711 return createTransformProps(props);4712 };4713 function createTransformProps(props = []) {4714 return { props };4715 }4716 const validDivisionCharRE = /[\w).+\-_$\]]/;4717 const transformFilter = (node, context) => {4718 if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {4719 return;4720 }4721 if (node.type === 5 /* INTERPOLATION */) {4722 // filter rewrite is applied before expression transform so only4723 // simple expressions are possible at this stage4724 rewriteFilter(node.content, context);4725 }4726 if (node.type === 1 /* ELEMENT */) {4727 node.props.forEach((prop) => {4728 if (prop.type === 7 /* DIRECTIVE */ &&4729 prop.name !== 'for' &&4730 prop.exp) {4731 rewriteFilter(prop.exp, context);4732 }4733 });4734 }4735 };4736 function rewriteFilter(node, context) {4737 if (node.type === 4 /* SIMPLE_EXPRESSION */) {4738 parseFilter(node, context);4739 }4740 else {4741 for (let i = 0; i < node.children.length; i++) {4742 const child = node.children[i];4743 if (typeof child !== 'object')4744 continue;4745 if (child.type === 4 /* SIMPLE_EXPRESSION */) {4746 parseFilter(child, context);4747 }4748 else if (child.type === 8 /* COMPOUND_EXPRESSION */) {4749 rewriteFilter(node, context);4750 }4751 else if (child.type === 5 /* INTERPOLATION */) {4752 rewriteFilter(child.content, context);4753 }4754 }4755 }4756 }4757 function parseFilter(node, context) {4758 const exp = node.content;4759 let inSingle = false;4760 let inDouble = false;4761 let inTemplateString = false;4762 let inRegex = false;4763 let curly = 0;4764 let square = 0;4765 let paren = 0;4766 let lastFilterIndex = 0;4767 let c, prev, i, expression, filters = [];4768 for (i = 0; i < exp.length; i++) {4769 prev = c;4770 c = exp.charCodeAt(i);4771 if (inSingle) {4772 if (c === 0x27 && prev !== 0x5c)4773 inSingle = false;4774 }4775 else if (inDouble) {4776 if (c === 0x22 && prev !== 0x5c)4777 inDouble = false;4778 }4779 else if (inTemplateString) {4780 if (c === 0x60 && prev !== 0x5c)4781 inTemplateString = false;4782 }4783 else if (inRegex) {4784 if (c === 0x2f && prev !== 0x5c)4785 inRegex = false;4786 }4787 else if (c === 0x7c && // pipe4788 exp.charCodeAt(i + 1) !== 0x7c &&4789 exp.charCodeAt(i - 1) !== 0x7c &&4790 !curly &&4791 !square &&4792 !paren) {4793 if (expression === undefined) {4794 // first filter, end of expression4795 lastFilterIndex = i + 1;4796 expression = exp.slice(0, i).trim();4797 }4798 else {4799 pushFilter();4800 }4801 }4802 else {4803 switch (c) {4804 case 0x22:4805 inDouble = true;4806 break; // "4807 case 0x27:4808 inSingle = true;4809 break; // '4810 case 0x60:4811 inTemplateString = true;4812 break; // `4813 case 0x28:4814 paren++;4815 break; // (4816 case 0x29:4817 paren--;4818 break; // )4819 case 0x5b:4820 square++;4821 break; // [4822 case 0x5d:4823 square--;4824 break; // ]4825 case 0x7b:4826 curly++;4827 break; // {4828 case 0x7d:4829 curly--;4830 break; // }4831 }4832 if (c === 0x2f) {4833 // /4834 let j = i - 1;4835 let p;4836 // find first non-whitespace prev char4837 for (; j >= 0; j--) {4838 p = exp.charAt(j);4839 if (p !== ' ')4840 break;4841 }4842 if (!p || !validDivisionCharRE.test(p)) {4843 inRegex = true;4844 }4845 }4846 }4847 }4848 if (expression === undefined) {4849 expression = exp.slice(0, i).trim();4850 }4851 else if (lastFilterIndex !== 0) {4852 pushFilter();4853 }4854 function pushFilter() {4855 filters.push(exp.slice(lastFilterIndex, i).trim());4856 lastFilterIndex = i + 1;4857 }4858 if (filters.length) {4859 warnDeprecation("COMPILER_FILTER" /* COMPILER_FILTERS */, context, node.loc);4860 for (i = 0; i < filters.length; i++) {4861 expression = wrapFilter(expression, filters[i], context);4862 }4863 node.content = expression;4864 }4865 }4866 function wrapFilter(exp, filter, context) {4867 context.helper(RESOLVE_FILTER);4868 const i = filter.indexOf('(');4869 if (i < 0) {4870 context.filters.add(filter);4871 return `${toValidAssetId(filter, 'filter')}(${exp})`;4872 }4873 else {4874 const name = filter.slice(0, i);4875 const args = filter.slice(i + 1);4876 context.filters.add(name);4877 return `${toValidAssetId(name, 'filter')}(${exp}${args !== ')' ? ',' + args : args}`;4878 }4879 }4880 const seen$1 = new WeakSet();4881 const transformMemo = (node, context) => {4882 if (node.type === 1 /* ELEMENT */) {4883 const dir = findDir(node, 'memo');4884 if (!dir || seen$1.has(node)) {4885 return;4886 }4887 seen$1.add(node);4888 return () => {4889 const codegenNode = node.codegenNode ||4890 context.currentNode.codegenNode;4891 if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {4892 // non-component sub tree should be turned into a block4893 if (node.tagType !== 1 /* COMPONENT */) {4894 makeBlock(codegenNode, context);4895 }4896 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [4897 dir.exp,4898 createFunctionExpression(undefined, codegenNode),4899 `_cache`,4900 String(context.cached++)4901 ]);4902 }4903 };4904 }4905 };4906 function getBaseTransformPreset(prefixIdentifiers) {4907 return [4908 [4909 transformOnce,4910 transformIf,4911 transformMemo,4912 transformFor,4913 ...([transformFilter] ),4914 ...([transformExpression]4915 ),4916 transformSlotOutlet,4917 transformElement,4918 trackSlotScopes,4919 transformText4920 ],4921 {4922 on: transformOn,4923 bind: transformBind,4924 model: transformModel4925 }4926 ];4927 }4928 // we name it `baseCompile` so that higher order compilers like4929 // @vue/compiler-dom can export `compile` while re-exporting everything else.4930 function baseCompile(template, options = {}) {4931 const onError = options.onError || defaultOnError;4932 const isModuleMode = options.mode === 'module';4933 /* istanbul ignore if */4934 {4935 if (options.prefixIdentifiers === true) {4936 onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));4937 }4938 else if (isModuleMode) {4939 onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));4940 }4941 }4942 const prefixIdentifiers = !true ;4943 if (options.cacheHandlers) {4944 onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));4945 }4946 if (options.scopeId && !isModuleMode) {4947 onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));4948 }4949 const ast = isString(template) ? baseParse(template, options) : template;4950 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();4951 transform(ast, extend({}, options, {4952 prefixIdentifiers,4953 nodeTransforms: [4954 ...nodeTransforms,4955 ...(options.nodeTransforms || []) // user transforms4956 ],4957 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms4958 )4959 }));4960 return generate(ast, extend({}, options, {4961 prefixIdentifiers4962 }));4963 }4964 const noopDirectiveTransform = () => ({ props: [] });4965 const V_MODEL_RADIO = Symbol(`vModelRadio` );4966 const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );4967 const V_MODEL_TEXT = Symbol(`vModelText` );4968 const V_MODEL_SELECT = Symbol(`vModelSelect` );4969 const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );4970 const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );4971 const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );4972 const V_SHOW = Symbol(`vShow` );4973 const TRANSITION = Symbol(`Transition` );4974 const TRANSITION_GROUP = Symbol(`TransitionGroup` );4975 registerRuntimeHelpers({4976 [V_MODEL_RADIO]: `vModelRadio`,4977 [V_MODEL_CHECKBOX]: `vModelCheckbox`,4978 [V_MODEL_TEXT]: `vModelText`,4979 [V_MODEL_SELECT]: `vModelSelect`,4980 [V_MODEL_DYNAMIC]: `vModelDynamic`,4981 [V_ON_WITH_MODIFIERS]: `withModifiers`,4982 [V_ON_WITH_KEYS]: `withKeys`,4983 [V_SHOW]: `vShow`,4984 [TRANSITION]: `Transition`,4985 [TRANSITION_GROUP]: `TransitionGroup`4986 });4987 /* eslint-disable no-restricted-globals */4988 let decoder;4989 function decodeHtmlBrowser(raw, asAttr = false) {4990 if (!decoder) {4991 decoder = document.createElement('div');4992 }4993 if (asAttr) {4994 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '"')}">`;4995 return decoder.children[0].getAttribute('foo');4996 }4997 else {4998 decoder.innerHTML = raw;4999 return decoder.textContent;5000 }5001 }5002 const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);5003 const parserOptions = {5004 isVoidTag,5005 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),5006 isPreTag: tag => tag === 'pre',5007 decodeEntities: decodeHtmlBrowser ,5008 isBuiltInComponent: (tag) => {5009 if (isBuiltInType(tag, `Transition`)) {5010 return TRANSITION;5011 }5012 else if (isBuiltInType(tag, `TransitionGroup`)) {5013 return TRANSITION_GROUP;5014 }5015 },5016 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher5017 getNamespace(tag, parent) {5018 let ns = parent ? parent.ns : 0 /* HTML */;5019 if (parent && ns === 2 /* MATH_ML */) {5020 if (parent.tag === 'annotation-xml') {5021 if (tag === 'svg') {5022 return 1 /* SVG */;5023 }5024 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&5025 a.name === 'encoding' &&5026 a.value != null &&5027 (a.value.content === 'text/html' ||5028 a.value.content === 'application/xhtml+xml'))) {5029 ns = 0 /* HTML */;5030 }5031 }5032 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&5033 tag !== 'mglyph' &&5034 tag !== 'malignmark') {5035 ns = 0 /* HTML */;5036 }5037 }5038 else if (parent && ns === 1 /* SVG */) {5039 if (parent.tag === 'foreignObject' ||5040 parent.tag === 'desc' ||5041 parent.tag === 'title') {5042 ns = 0 /* HTML */;5043 }5044 }5045 if (ns === 0 /* HTML */) {5046 if (tag === 'svg') {5047 return 1 /* SVG */;5048 }5049 if (tag === 'math') {5050 return 2 /* MATH_ML */;5051 }5052 }5053 return ns;5054 },5055 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments5056 getTextMode({ tag, ns }) {5057 if (ns === 0 /* HTML */) {5058 if (tag === 'textarea' || tag === 'title') {5059 return 1 /* RCDATA */;5060 }5061 if (isRawTextContainer(tag)) {5062 return 2 /* RAWTEXT */;5063 }5064 }5065 return 0 /* DATA */;5066 }5067 };5068 // Parse inline CSS strings for static style attributes into an object.5069 // This is a NodeTransform since it works on the static `style` attribute and5070 // converts it into a dynamic equivalent:5071 // style="color: red" -> :style='{ "color": "red" }'5072 // It is then processed by `transformElement` and included in the generated5073 // props.5074 const transformStyle = node => {5075 if (node.type === 1 /* ELEMENT */) {5076 node.props.forEach((p, i) => {5077 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {5078 // replace p with an expression node5079 node.props[i] = {5080 type: 7 /* DIRECTIVE */,5081 name: `bind`,5082 arg: createSimpleExpression(`style`, true, p.loc),5083 exp: parseInlineCSS(p.value.content, p.loc),5084 modifiers: [],5085 loc: p.loc5086 };5087 }5088 });5089 }5090 };5091 const parseInlineCSS = (cssText, loc) => {5092 const normalized = parseStringStyle(cssText);5093 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);5094 };5095 function createDOMCompilerError(code, loc) {5096 return createCompilerError(code, loc, DOMErrorMessages );5097 }5098 const DOMErrorMessages = {5099 [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,5100 [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,5101 [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,5102 [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,5103 [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,5104 [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,5105 [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,5106 [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,5107 [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,5108 [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,5109 [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`5110 };5111 const transformVHtml = (dir, node, context) => {5112 const { exp, loc } = dir;5113 if (!exp) {5114 context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));5115 }5116 if (node.children.length) {5117 context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));5118 node.children.length = 0;5119 }5120 return {5121 props: [5122 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))5123 ]5124 };5125 };5126 const transformVText = (dir, node, context) => {5127 const { exp, loc } = dir;5128 if (!exp) {5129 context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));5130 }5131 if (node.children.length) {5132 context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));5133 node.children.length = 0;5134 }5135 return {5136 props: [5137 createObjectProperty(createSimpleExpression(`textContent`, true), exp5138 ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)5139 : createSimpleExpression('', true))5140 ]5141 };5142 };5143 const transformModel$1 = (dir, node, context) => {5144 const baseResult = transformModel(dir, node, context);5145 // base transform has errors OR component v-model (only need props)5146 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {5147 return baseResult;5148 }5149 if (dir.arg) {5150 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));5151 }5152 function checkDuplicatedValue() {5153 const value = findProp(node, 'value');5154 if (value) {5155 context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));5156 }5157 }5158 const { tag } = node;5159 const isCustomElement = context.isCustomElement(tag);5160 if (tag === 'input' ||5161 tag === 'textarea' ||5162 tag === 'select' ||5163 isCustomElement) {5164 let directiveToUse = V_MODEL_TEXT;5165 let isInvalidType = false;5166 if (tag === 'input' || isCustomElement) {5167 const type = findProp(node, `type`);5168 if (type) {5169 if (type.type === 7 /* DIRECTIVE */) {5170 // :type="foo"5171 directiveToUse = V_MODEL_DYNAMIC;5172 }5173 else if (type.value) {5174 switch (type.value.content) {5175 case 'radio':5176 directiveToUse = V_MODEL_RADIO;5177 break;5178 case 'checkbox':5179 directiveToUse = V_MODEL_CHECKBOX;5180 break;5181 case 'file':5182 isInvalidType = true;5183 context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));5184 break;5185 default:5186 // text type5187 checkDuplicatedValue();5188 break;5189 }5190 }5191 }5192 else if (hasDynamicKeyVBind(node)) {5193 // element has bindings with dynamic keys, which can possibly contain5194 // "type".5195 directiveToUse = V_MODEL_DYNAMIC;5196 }5197 else {5198 // text type5199 checkDuplicatedValue();5200 }5201 }5202 else if (tag === 'select') {5203 directiveToUse = V_MODEL_SELECT;5204 }5205 else {5206 // textarea5207 checkDuplicatedValue();5208 }5209 // inject runtime directive5210 // by returning the helper symbol via needRuntime5211 // the import will replaced a resolveDirective call.5212 if (!isInvalidType) {5213 baseResult.needRuntime = context.helper(directiveToUse);5214 }5215 }5216 else {5217 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));5218 }5219 // native vmodel doesn't need the `modelValue` props since they are also5220 // passed to the runtime as `binding.value`. removing it reduces code size.5221 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&5222 p.key.content === 'modelValue'));5223 return baseResult;5224 };5225 const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);5226 const isNonKeyModifier = /*#__PURE__*/ makeMap(5227 // event propagation management5228`stop,prevent,self,` +5229 // system modifiers + exact5230 `ctrl,shift,alt,meta,exact,` +5231 // mouse5232 `middle`);5233 // left & right could be mouse or key modifiers based on event type5234 const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');5235 const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);5236 const resolveModifiers = (key, modifiers, context, loc) => {5237 const keyModifiers = [];5238 const nonKeyModifiers = [];5239 const eventOptionModifiers = [];5240 for (let i = 0; i < modifiers.length; i++) {5241 const modifier = modifiers[i];5242 if (modifier === 'native' &&5243 checkCompatEnabled("COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */, context, loc)) {5244 eventOptionModifiers.push(modifier);5245 }5246 else if (isEventOptionModifier(modifier)) {5247 // eventOptionModifiers: modifiers for addEventListener() options,5248 // e.g. .passive & .capture5249 eventOptionModifiers.push(modifier);5250 }5251 else {5252 // runtimeModifiers: modifiers that needs runtime guards5253 if (maybeKeyModifier(modifier)) {5254 if (isStaticExp(key)) {5255 if (isKeyboardEvent(key.content)) {5256 keyModifiers.push(modifier);5257 }
...
compiler-core.cjs.js
Source:compiler-core.cjs.js
...800 // in v3 mode, only enable if explicitly set to true801 // otherwise enable for any non-false value802 return mode === 3 ? value === true : value !== false;803}804function checkCompatEnabled(key, context, loc, ...args) {805 const enabled = isCompatEnabled(key, context);806 if (enabled) {807 warnDeprecation(key, context, loc, ...args);808 }809 return enabled;810}811function warnDeprecation(key, context, loc, ...args) {812 const val = getCompatValue(key, context);813 if (val === 'suppress-warning') {814 return;815 }816 const { message, link } = deprecationData[key];817 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;818 const err = new SyntaxError(msg);819 err.code = key;820 if (loc)821 err.loc = loc;822 context.onWarn(err);823}824// The default decoder only provides escapes for characters reserved as part of825// the template syntax, and is only used if the custom renderer did not provide826// a platform-specific decoder.827const decodeRE = /&(gt|lt|amp|apos|quot);/g;828const decodeMap = {829 gt: '>',830 lt: '<',831 amp: '&',832 apos: "'",833 quot: '"'834};835const defaultParserOptions = {836 delimiters: [`{{`, `}}`],837 getNamespace: () => 0 /* HTML */,838 getTextMode: () => 0 /* DATA */,839 isVoidTag: shared.NO,840 isPreTag: shared.NO,841 isCustomElement: shared.NO,842 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),843 onError: defaultOnError,844 onWarn: defaultOnWarn,845 comments: true846};847function baseParse(content, options = {}) {848 const context = createParserContext(content, options);849 const start = getCursor(context);850 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));851}852function createParserContext(content, rawOptions) {853 const options = shared.extend({}, defaultParserOptions);854 let key;855 for (key in rawOptions) {856 // @ts-ignore857 options[key] =858 rawOptions[key] === undefined859 ? defaultParserOptions[key]860 : rawOptions[key];861 }862 return {863 options,864 column: 1,865 line: 1,866 offset: 0,867 originalSource: content,868 source: content,869 inPre: false,870 inVPre: false,871 onWarn: options.onWarn872 };873}874function parseChildren(context, mode, ancestors) {875 const parent = last(ancestors);876 const ns = parent ? parent.ns : 0 /* HTML */;877 const nodes = [];878 while (!isEnd(context, mode, ancestors)) {879 const s = context.source;880 let node = undefined;881 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {882 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {883 // '{{'884 node = parseInterpolation(context, mode);885 }886 else if (mode === 0 /* DATA */ && s[0] === '<') {887 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state888 if (s.length === 1) {889 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);890 }891 else if (s[1] === '!') {892 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state893 if (startsWith(s, '<!--')) {894 node = parseComment(context);895 }896 else if (startsWith(s, '<!DOCTYPE')) {897 // Ignore DOCTYPE by a limitation.898 node = parseBogusComment(context);899 }900 else if (startsWith(s, '<![CDATA[')) {901 if (ns !== 0 /* HTML */) {902 node = parseCDATA(context, ancestors);903 }904 else {905 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);906 node = parseBogusComment(context);907 }908 }909 else {910 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);911 node = parseBogusComment(context);912 }913 }914 else if (s[1] === '/') {915 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state916 if (s.length === 2) {917 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);918 }919 else if (s[2] === '>') {920 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);921 advanceBy(context, 3);922 continue;923 }924 else if (/[a-z]/i.test(s[2])) {925 emitError(context, 23 /* X_INVALID_END_TAG */);926 parseTag(context, 1 /* End */, parent);927 continue;928 }929 else {930 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);931 node = parseBogusComment(context);932 }933 }934 else if (/[a-z]/i.test(s[1])) {935 node = parseElement(context, ancestors);936 // 2.x <template> with no directive compat937 if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&938 node &&939 node.tag === 'template' &&940 !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&941 isSpecialTemplateDirective(p.name))) {942 warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);943 node = node.children;944 }945 }946 else if (s[1] === '?') {947 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);948 node = parseBogusComment(context);949 }950 else {951 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);952 }953 }954 }955 if (!node) {956 node = parseText(context, mode);957 }958 if (shared.isArray(node)) {959 for (let i = 0; i < node.length; i++) {960 pushNode(nodes, node[i]);961 }962 }963 else {964 pushNode(nodes, node);965 }966 }967 // Whitespace handling strategy like v2968 let removedWhitespace = false;969 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {970 const shouldCondense = context.options.whitespace !== 'preserve';971 for (let i = 0; i < nodes.length; i++) {972 const node = nodes[i];973 if (!context.inPre && node.type === 2 /* TEXT */) {974 if (!/[^\t\r\n\f ]/.test(node.content)) {975 const prev = nodes[i - 1];976 const next = nodes[i + 1];977 // Remove if:978 // - the whitespace is the first or last node, or:979 // - (condense mode) the whitespace is adjacent to a comment, or:980 // - (condense mode) the whitespace is between two elements AND contains newline981 if (!prev ||982 !next ||983 (shouldCondense &&984 (prev.type === 3 /* COMMENT */ ||985 next.type === 3 /* COMMENT */ ||986 (prev.type === 1 /* ELEMENT */ &&987 next.type === 1 /* ELEMENT */ &&988 /[\r\n]/.test(node.content))))) {989 removedWhitespace = true;990 nodes[i] = null;991 }992 else {993 // Otherwise, the whitespace is condensed into a single space994 node.content = ' ';995 }996 }997 else if (shouldCondense) {998 // in condense mode, consecutive whitespaces in text are condensed999 // down to a single space.1000 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1001 }1002 }1003 // Remove comment nodes if desired by configuration.1004 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {1005 removedWhitespace = true;1006 nodes[i] = null;1007 }1008 }1009 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1010 // remove leading newline per html spec1011 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1012 const first = nodes[0];1013 if (first && first.type === 2 /* TEXT */) {1014 first.content = first.content.replace(/^\r?\n/, '');1015 }1016 }1017 }1018 return removedWhitespace ? nodes.filter(Boolean) : nodes;1019}1020function pushNode(nodes, node) {1021 if (node.type === 2 /* TEXT */) {1022 const prev = last(nodes);1023 // Merge if both this and the previous node are text and those are1024 // consecutive. This happens for cases like "a < b".1025 if (prev &&1026 prev.type === 2 /* TEXT */ &&1027 prev.loc.end.offset === node.loc.start.offset) {1028 prev.content += node.content;1029 prev.loc.end = node.loc.end;1030 prev.loc.source += node.loc.source;1031 return;1032 }1033 }1034 nodes.push(node);1035}1036function parseCDATA(context, ancestors) {1037 advanceBy(context, 9);1038 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1039 if (context.source.length === 0) {1040 emitError(context, 6 /* EOF_IN_CDATA */);1041 }1042 else {1043 advanceBy(context, 3);1044 }1045 return nodes;1046}1047function parseComment(context) {1048 const start = getCursor(context);1049 let content;1050 // Regular comment.1051 const match = /--(\!)?>/.exec(context.source);1052 if (!match) {1053 content = context.source.slice(4);1054 advanceBy(context, context.source.length);1055 emitError(context, 7 /* EOF_IN_COMMENT */);1056 }1057 else {1058 if (match.index <= 3) {1059 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1060 }1061 if (match[1]) {1062 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1063 }1064 content = context.source.slice(4, match.index);1065 // Advancing with reporting nested comments.1066 const s = context.source.slice(0, match.index);1067 let prevIndex = 1, nestedIndex = 0;1068 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1069 advanceBy(context, nestedIndex - prevIndex + 1);1070 if (nestedIndex + 4 < s.length) {1071 emitError(context, 16 /* NESTED_COMMENT */);1072 }1073 prevIndex = nestedIndex + 1;1074 }1075 advanceBy(context, match.index + match[0].length - prevIndex + 1);1076 }1077 return {1078 type: 3 /* COMMENT */,1079 content,1080 loc: getSelection(context, start)1081 };1082}1083function parseBogusComment(context) {1084 const start = getCursor(context);1085 const contentStart = context.source[1] === '?' ? 1 : 2;1086 let content;1087 const closeIndex = context.source.indexOf('>');1088 if (closeIndex === -1) {1089 content = context.source.slice(contentStart);1090 advanceBy(context, context.source.length);1091 }1092 else {1093 content = context.source.slice(contentStart, closeIndex);1094 advanceBy(context, closeIndex + 1);1095 }1096 return {1097 type: 3 /* COMMENT */,1098 content,1099 loc: getSelection(context, start)1100 };1101}1102function parseElement(context, ancestors) {1103 // Start tag.1104 const wasInPre = context.inPre;1105 const wasInVPre = context.inVPre;1106 const parent = last(ancestors);1107 const element = parseTag(context, 0 /* Start */, parent);1108 const isPreBoundary = context.inPre && !wasInPre;1109 const isVPreBoundary = context.inVPre && !wasInVPre;1110 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1111 // #4030 self-closing <pre> tag1112 if (isPreBoundary) {1113 context.inPre = false;1114 }1115 if (isVPreBoundary) {1116 context.inVPre = false;1117 }1118 return element;1119 }1120 // Children.1121 ancestors.push(element);1122 const mode = context.options.getTextMode(element, parent);1123 const children = parseChildren(context, mode, ancestors);1124 ancestors.pop();1125 // 2.x inline-template compat1126 {1127 const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1128 if (inlineTemplateProp &&1129 checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1130 const loc = getSelection(context, element.loc.end);1131 inlineTemplateProp.value = {1132 type: 2 /* TEXT */,1133 content: loc.source,1134 loc1135 };1136 }1137 }1138 element.children = children;1139 // End tag.1140 if (startsWithEndTagOpen(context.source, element.tag)) {1141 parseTag(context, 1 /* End */, parent);1142 }1143 else {1144 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1145 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1146 const first = children[0];1147 if (first && startsWith(first.loc.source, '<!--')) {1148 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1149 }1150 }1151 }1152 element.loc = getSelection(context, element.loc.start);1153 if (isPreBoundary) {1154 context.inPre = false;1155 }1156 if (isVPreBoundary) {1157 context.inVPre = false;1158 }1159 return element;1160}1161const isSpecialTemplateDirective = /*#__PURE__*/ shared.makeMap(`if,else,else-if,for,slot`);1162function parseTag(context, type, parent) {1163 // Tag open.1164 const start = getCursor(context);1165 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1166 const tag = match[1];1167 const ns = context.options.getNamespace(tag, parent);1168 advanceBy(context, match[0].length);1169 advanceSpaces(context);1170 // save current state in case we need to re-parse attributes with v-pre1171 const cursor = getCursor(context);1172 const currentSource = context.source;1173 // check <pre> tag1174 if (context.options.isPreTag(tag)) {1175 context.inPre = true;1176 }1177 // Attributes.1178 let props = parseAttributes(context, type);1179 // check v-pre1180 if (type === 0 /* Start */ &&1181 !context.inVPre &&1182 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1183 context.inVPre = true;1184 // reset context1185 shared.extend(context, cursor);1186 context.source = currentSource;1187 // re-parse attrs and filter out v-pre itself1188 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1189 }1190 // Tag close.1191 let isSelfClosing = false;1192 if (context.source.length === 0) {1193 emitError(context, 9 /* EOF_IN_TAG */);1194 }1195 else {1196 isSelfClosing = startsWith(context.source, '/>');1197 if (type === 1 /* End */ && isSelfClosing) {1198 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1199 }1200 advanceBy(context, isSelfClosing ? 2 : 1);1201 }1202 if (type === 1 /* End */) {1203 return;1204 }1205 // 2.x deprecation checks1206 if (isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1207 let hasIf = false;1208 let hasFor = false;1209 for (let i = 0; i < props.length; i++) {1210 const p = props[i];1211 if (p.type === 7 /* DIRECTIVE */) {1212 if (p.name === 'if') {1213 hasIf = true;1214 }1215 else if (p.name === 'for') {1216 hasFor = true;1217 }1218 }1219 if (hasIf && hasFor) {1220 warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1221 }1222 }1223 }1224 let tagType = 0 /* ELEMENT */;1225 if (!context.inVPre) {1226 if (tag === 'slot') {1227 tagType = 2 /* SLOT */;1228 }1229 else if (tag === 'template') {1230 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1231 tagType = 3 /* TEMPLATE */;1232 }1233 }1234 else if (isComponent(tag, props, context)) {1235 tagType = 1 /* COMPONENT */;1236 }1237 }1238 return {1239 type: 1 /* ELEMENT */,1240 ns,1241 tag,1242 tagType,1243 props,1244 isSelfClosing,1245 children: [],1246 loc: getSelection(context, start),1247 codegenNode: undefined // to be created during transform phase1248 };1249}1250function isComponent(tag, props, context) {1251 const options = context.options;1252 if (options.isCustomElement(tag)) {1253 return false;1254 }1255 if (tag === 'component' ||1256 /^[A-Z]/.test(tag) ||1257 isCoreComponent(tag) ||1258 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1259 (options.isNativeTag && !options.isNativeTag(tag))) {1260 return true;1261 }1262 // at this point the tag should be a native tag, but check for potential "is"1263 // casting1264 for (let i = 0; i < props.length; i++) {1265 const p = props[i];1266 if (p.type === 6 /* ATTRIBUTE */) {1267 if (p.name === 'is' && p.value) {1268 if (p.value.content.startsWith('vue:')) {1269 return true;1270 }1271 else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1272 return true;1273 }1274 }1275 }1276 else {1277 // directive1278 // v-is (TODO Deprecate)1279 if (p.name === 'is') {1280 return true;1281 }1282 else if (1283 // :is on plain element - only treat as component in compat mode1284 p.name === 'bind' &&1285 isBindKey(p.arg, 'is') &&1286 true &&1287 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1288 return true;1289 }1290 }1291 }1292}1293function parseAttributes(context, type) {1294 const props = [];1295 const attributeNames = new Set();1296 while (context.source.length > 0 &&1297 !startsWith(context.source, '>') &&1298 !startsWith(context.source, '/>')) {1299 if (startsWith(context.source, '/')) {1300 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1301 advanceBy(context, 1);1302 advanceSpaces(context);1303 continue;1304 }1305 if (type === 1 /* End */) {1306 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1307 }1308 const attr = parseAttribute(context, attributeNames);1309 // Trim whitespace between class1310 // https://github.com/vuejs/vue-next/issues/42511311 if (attr.type === 6 /* ATTRIBUTE */ &&1312 attr.value &&1313 attr.name === 'class') {1314 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1315 }1316 if (type === 0 /* Start */) {1317 props.push(attr);1318 }1319 if (/^[^\t\r\n\f />]/.test(context.source)) {1320 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1321 }1322 advanceSpaces(context);1323 }1324 return props;1325}1326function parseAttribute(context, nameSet) {1327 // Name.1328 const start = getCursor(context);1329 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1330 const name = match[0];1331 if (nameSet.has(name)) {1332 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1333 }1334 nameSet.add(name);1335 if (name[0] === '=') {1336 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1337 }1338 {1339 const pattern = /["'<]/g;1340 let m;1341 while ((m = pattern.exec(name))) {1342 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1343 }1344 }1345 advanceBy(context, name.length);1346 // Value1347 let value = undefined;1348 if (/^[\t\r\n\f ]*=/.test(context.source)) {1349 advanceSpaces(context);1350 advanceBy(context, 1);1351 advanceSpaces(context);1352 value = parseAttributeValue(context);1353 if (!value) {1354 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1355 }1356 }1357 const loc = getSelection(context, start);1358 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1359 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1360 let isPropShorthand = startsWith(name, '.');1361 let dirName = match[1] ||1362 (isPropShorthand || startsWith(name, ':')1363 ? 'bind'1364 : startsWith(name, '@')1365 ? 'on'1366 : 'slot');1367 let arg;1368 if (match[2]) {1369 const isSlot = dirName === 'slot';1370 const startOffset = name.lastIndexOf(match[2]);1371 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1372 let content = match[2];1373 let isStatic = true;1374 if (content.startsWith('[')) {1375 isStatic = false;1376 if (!content.endsWith(']')) {1377 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1378 content = content.slice(1);1379 }1380 else {1381 content = content.slice(1, content.length - 1);1382 }1383 }1384 else if (isSlot) {1385 // #1241 special case for v-slot: vuetify relies extensively on slot1386 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1387 // supports such usage so we are keeping it consistent with 2.x.1388 content += match[3] || '';1389 }1390 arg = {1391 type: 4 /* SIMPLE_EXPRESSION */,1392 content,1393 isStatic,1394 constType: isStatic1395 ? 3 /* CAN_STRINGIFY */1396 : 0 /* NOT_CONSTANT */,1397 loc1398 };1399 }1400 if (value && value.isQuoted) {1401 const valueLoc = value.loc;1402 valueLoc.start.offset++;1403 valueLoc.start.column++;1404 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1405 valueLoc.source = valueLoc.source.slice(1, -1);1406 }1407 const modifiers = match[3] ? match[3].slice(1).split('.') : [];1408 if (isPropShorthand)1409 modifiers.push('prop');1410 // 2.x compat v-bind:foo.sync -> v-model:foo1411 if (dirName === 'bind' && arg) {1412 if (modifiers.includes('sync') &&1413 checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1414 dirName = 'model';1415 modifiers.splice(modifiers.indexOf('sync'), 1);1416 }1417 if (modifiers.includes('prop')) {1418 checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1419 }1420 }1421 return {1422 type: 7 /* DIRECTIVE */,1423 name: dirName,1424 exp: value && {1425 type: 4 /* SIMPLE_EXPRESSION */,1426 content: value.content,1427 isStatic: false,1428 // Treat as non-constant by default. This can be potentially set to1429 // other values by `transformExpression` to make it eligible for hoisting.1430 constType: 0 /* NOT_CONSTANT */,1431 loc: value.loc1432 },1433 arg,1434 modifiers,1435 loc1436 };1437 }1438 // missing directive name or illegal directive name1439 if (!context.inVPre && startsWith(name, 'v-')) {1440 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1441 }1442 return {1443 type: 6 /* ATTRIBUTE */,1444 name,1445 value: value && {1446 type: 2 /* TEXT */,1447 content: value.content,1448 loc: value.loc1449 },1450 loc1451 };1452}1453function parseAttributeValue(context) {1454 const start = getCursor(context);1455 let content;1456 const quote = context.source[0];1457 const isQuoted = quote === `"` || quote === `'`;1458 if (isQuoted) {1459 // Quoted value.1460 advanceBy(context, 1);1461 const endIndex = context.source.indexOf(quote);1462 if (endIndex === -1) {1463 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1464 }1465 else {1466 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1467 advanceBy(context, 1);1468 }1469 }1470 else {1471 // Unquoted1472 const match = /^[^\t\r\n\f >]+/.exec(context.source);1473 if (!match) {1474 return undefined;1475 }1476 const unexpectedChars = /["'<=`]/g;1477 let m;1478 while ((m = unexpectedChars.exec(match[0]))) {1479 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1480 }1481 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1482 }1483 return { content, isQuoted, loc: getSelection(context, start) };1484}1485function parseInterpolation(context, mode) {1486 const [open, close] = context.options.delimiters;1487 const closeIndex = context.source.indexOf(close, open.length);1488 if (closeIndex === -1) {1489 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1490 return undefined;1491 }1492 const start = getCursor(context);1493 advanceBy(context, open.length);1494 const innerStart = getCursor(context);1495 const innerEnd = getCursor(context);1496 const rawContentLength = closeIndex - open.length;1497 const rawContent = context.source.slice(0, rawContentLength);1498 const preTrimContent = parseTextData(context, rawContentLength, mode);1499 const content = preTrimContent.trim();1500 const startOffset = preTrimContent.indexOf(content);1501 if (startOffset > 0) {1502 advancePositionWithMutation(innerStart, rawContent, startOffset);1503 }1504 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1505 advancePositionWithMutation(innerEnd, rawContent, endOffset);1506 advanceBy(context, close.length);1507 return {1508 type: 5 /* INTERPOLATION */,1509 content: {1510 type: 4 /* SIMPLE_EXPRESSION */,1511 isStatic: false,1512 // Set `isConstant` to false by default and will decide in transformExpression1513 constType: 0 /* NOT_CONSTANT */,1514 content,1515 loc: getSelection(context, innerStart, innerEnd)1516 },1517 loc: getSelection(context, start)1518 };1519}1520function parseText(context, mode) {1521 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1522 let endIndex = context.source.length;1523 for (let i = 0; i < endTokens.length; i++) {1524 const index = context.source.indexOf(endTokens[i], 1);1525 if (index !== -1 && endIndex > index) {1526 endIndex = index;1527 }1528 }1529 const start = getCursor(context);1530 const content = parseTextData(context, endIndex, mode);1531 return {1532 type: 2 /* TEXT */,1533 content,1534 loc: getSelection(context, start)1535 };1536}1537/**1538 * Get text data with a given length from the current location.1539 * This translates HTML entities in the text data.1540 */1541function parseTextData(context, length, mode) {1542 const rawText = context.source.slice(0, length);1543 advanceBy(context, length);1544 if (mode === 2 /* RAWTEXT */ ||1545 mode === 3 /* CDATA */ ||1546 rawText.indexOf('&') === -1) {1547 return rawText;1548 }1549 else {1550 // DATA or RCDATA containing "&"". Entity decoding required.1551 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1552 }1553}1554function getCursor(context) {1555 const { column, line, offset } = context;1556 return { column, line, offset };1557}1558function getSelection(context, start, end) {1559 end = end || getCursor(context);1560 return {1561 start,1562 end,1563 source: context.originalSource.slice(start.offset, end.offset)1564 };1565}1566function last(xs) {1567 return xs[xs.length - 1];1568}1569function startsWith(source, searchString) {1570 return source.startsWith(searchString);1571}1572function advanceBy(context, numberOfCharacters) {1573 const { source } = context;1574 advancePositionWithMutation(context, source, numberOfCharacters);1575 context.source = source.slice(numberOfCharacters);1576}1577function advanceSpaces(context) {1578 const match = /^[\t\r\n\f ]+/.exec(context.source);1579 if (match) {1580 advanceBy(context, match[0].length);1581 }1582}1583function getNewPosition(context, start, numberOfCharacters) {1584 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1585}1586function emitError(context, code, offset, loc = getCursor(context)) {1587 if (offset) {1588 loc.offset += offset;1589 loc.column += offset;1590 }1591 context.options.onError(createCompilerError(code, {1592 start: loc,1593 end: loc,1594 source: ''1595 }));1596}1597function isEnd(context, mode, ancestors) {1598 const s = context.source;1599 switch (mode) {1600 case 0 /* DATA */:1601 if (startsWith(s, '</')) {1602 // TODO: probably bad performance1603 for (let i = ancestors.length - 1; i >= 0; --i) {1604 if (startsWithEndTagOpen(s, ancestors[i].tag)) {1605 return true;1606 }1607 }1608 }1609 break;1610 case 1 /* RCDATA */:1611 case 2 /* RAWTEXT */: {1612 const parent = last(ancestors);1613 if (parent && startsWithEndTagOpen(s, parent.tag)) {1614 return true;1615 }1616 break;1617 }1618 case 3 /* CDATA */:1619 if (startsWith(s, ']]>')) {1620 return true;1621 }1622 break;1623 }1624 return !s;1625}1626function startsWithEndTagOpen(source, tag) {1627 return (startsWith(source, '</') &&1628 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1629 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1630}1631function hoistStatic(root, context) {1632 walk(root, context, 1633 // Root node is unfortunately non-hoistable due to potential parent1634 // fallthrough attributes.1635 isSingleElementRoot(root, root.children[0]));1636}1637function isSingleElementRoot(root, child) {1638 const { children } = root;1639 return (children.length === 1 &&1640 child.type === 1 /* ELEMENT */ &&1641 !isSlotOutlet(child));1642}1643function walk(node, context, doNotHoistNode = false) {1644 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces1645 // static bindings with expressions. These expressions are guaranteed to be1646 // constant so they are still eligible for hoisting, but they are only1647 // available at runtime and therefore cannot be evaluated ahead of time.1648 // This is only a concern for pre-stringification (via transformHoist by1649 // @vue/compiler-dom), but doing it here allows us to perform only one full1650 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its1651 // stringification threshold is met.1652 let canStringify = true;1653 const { children } = node;1654 const originalCount = children.length;1655 let hoistedCount = 0;1656 for (let i = 0; i < children.length; i++) {1657 const child = children[i];1658 // only plain elements & text calls are eligible for hoisting.1659 if (child.type === 1 /* ELEMENT */ &&1660 child.tagType === 0 /* ELEMENT */) {1661 const constantType = doNotHoistNode1662 ? 0 /* NOT_CONSTANT */1663 : getConstantType(child, context);1664 if (constantType > 0 /* NOT_CONSTANT */) {1665 if (constantType < 3 /* CAN_STRINGIFY */) {1666 canStringify = false;1667 }1668 if (constantType >= 2 /* CAN_HOIST */) {1669 child.codegenNode.patchFlag =1670 -1 /* HOISTED */ + (` /* HOISTED */` );1671 child.codegenNode = context.hoist(child.codegenNode);1672 hoistedCount++;1673 continue;1674 }1675 }1676 else {1677 // node may contain dynamic children, but its props may be eligible for1678 // hoisting.1679 const codegenNode = child.codegenNode;1680 if (codegenNode.type === 13 /* VNODE_CALL */) {1681 const flag = getPatchFlag(codegenNode);1682 if ((!flag ||1683 flag === 512 /* NEED_PATCH */ ||1684 flag === 1 /* TEXT */) &&1685 getGeneratedPropsConstantType(child, context) >=1686 2 /* CAN_HOIST */) {1687 const props = getNodeProps(child);1688 if (props) {1689 codegenNode.props = context.hoist(props);1690 }1691 }1692 if (codegenNode.dynamicProps) {1693 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1694 }1695 }1696 }1697 }1698 else if (child.type === 12 /* TEXT_CALL */) {1699 const contentType = getConstantType(child.content, context);1700 if (contentType > 0) {1701 if (contentType < 3 /* CAN_STRINGIFY */) {1702 canStringify = false;1703 }1704 if (contentType >= 2 /* CAN_HOIST */) {1705 child.codegenNode = context.hoist(child.codegenNode);1706 hoistedCount++;1707 }1708 }1709 }1710 // walk further1711 if (child.type === 1 /* ELEMENT */) {1712 const isComponent = child.tagType === 1 /* COMPONENT */;1713 if (isComponent) {1714 context.scopes.vSlot++;1715 }1716 walk(child, context);1717 if (isComponent) {1718 context.scopes.vSlot--;1719 }1720 }1721 else if (child.type === 11 /* FOR */) {1722 // Do not hoist v-for single child because it has to be a block1723 walk(child, context, child.children.length === 1);1724 }1725 else if (child.type === 9 /* IF */) {1726 for (let i = 0; i < child.branches.length; i++) {1727 // Do not hoist v-if single child because it has to be a block1728 walk(child.branches[i], context, child.branches[i].children.length === 1);1729 }1730 }1731 }1732 if (canStringify && hoistedCount && context.transformHoist) {1733 context.transformHoist(children, context, node);1734 }1735 // all children were hoisted - the entire children array is hoistable.1736 if (hoistedCount &&1737 hoistedCount === originalCount &&1738 node.type === 1 /* ELEMENT */ &&1739 node.tagType === 0 /* ELEMENT */ &&1740 node.codegenNode &&1741 node.codegenNode.type === 13 /* VNODE_CALL */ &&1742 shared.isArray(node.codegenNode.children)) {1743 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1744 }1745}1746function getConstantType(node, context) {1747 const { constantCache } = context;1748 switch (node.type) {1749 case 1 /* ELEMENT */:1750 if (node.tagType !== 0 /* ELEMENT */) {1751 return 0 /* NOT_CONSTANT */;1752 }1753 const cached = constantCache.get(node);1754 if (cached !== undefined) {1755 return cached;1756 }1757 const codegenNode = node.codegenNode;1758 if (codegenNode.type !== 13 /* VNODE_CALL */) {1759 return 0 /* NOT_CONSTANT */;1760 }1761 const flag = getPatchFlag(codegenNode);1762 if (!flag) {1763 let returnType = 3 /* CAN_STRINGIFY */;1764 // Element itself has no patch flag. However we still need to check:1765 // 1. Even for a node with no patch flag, it is possible for it to contain1766 // non-hoistable expressions that refers to scope variables, e.g. compiler1767 // injected keys or cached event handlers. Therefore we need to always1768 // check the codegenNode's props to be sure.1769 const generatedPropsType = getGeneratedPropsConstantType(node, context);1770 if (generatedPropsType === 0 /* NOT_CONSTANT */) {1771 constantCache.set(node, 0 /* NOT_CONSTANT */);1772 return 0 /* NOT_CONSTANT */;1773 }1774 if (generatedPropsType < returnType) {1775 returnType = generatedPropsType;1776 }1777 // 2. its children.1778 for (let i = 0; i < node.children.length; i++) {1779 const childType = getConstantType(node.children[i], context);1780 if (childType === 0 /* NOT_CONSTANT */) {1781 constantCache.set(node, 0 /* NOT_CONSTANT */);1782 return 0 /* NOT_CONSTANT */;1783 }1784 if (childType < returnType) {1785 returnType = childType;1786 }1787 }1788 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01789 // type, check if any of the props can cause the type to be lowered1790 // we can skip can_patch because it's guaranteed by the absence of a1791 // patchFlag.1792 if (returnType > 1 /* CAN_SKIP_PATCH */) {1793 for (let i = 0; i < node.props.length; i++) {1794 const p = node.props[i];1795 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1796 const expType = getConstantType(p.exp, context);1797 if (expType === 0 /* NOT_CONSTANT */) {1798 constantCache.set(node, 0 /* NOT_CONSTANT */);1799 return 0 /* NOT_CONSTANT */;1800 }1801 if (expType < returnType) {1802 returnType = expType;1803 }1804 }1805 }1806 }1807 // only svg/foreignObject could be block here, however if they are1808 // static then they don't need to be blocks since there will be no1809 // nested updates.1810 if (codegenNode.isBlock) {1811 context.removeHelper(OPEN_BLOCK);1812 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1813 codegenNode.isBlock = false;1814 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1815 }1816 constantCache.set(node, returnType);1817 return returnType;1818 }1819 else {1820 constantCache.set(node, 0 /* NOT_CONSTANT */);1821 return 0 /* NOT_CONSTANT */;1822 }1823 case 2 /* TEXT */:1824 case 3 /* COMMENT */:1825 return 3 /* CAN_STRINGIFY */;1826 case 9 /* IF */:1827 case 11 /* FOR */:1828 case 10 /* IF_BRANCH */:1829 return 0 /* NOT_CONSTANT */;1830 case 5 /* INTERPOLATION */:1831 case 12 /* TEXT_CALL */:1832 return getConstantType(node.content, context);1833 case 4 /* SIMPLE_EXPRESSION */:1834 return node.constType;1835 case 8 /* COMPOUND_EXPRESSION */:1836 let returnType = 3 /* CAN_STRINGIFY */;1837 for (let i = 0; i < node.children.length; i++) {1838 const child = node.children[i];1839 if (shared.isString(child) || shared.isSymbol(child)) {1840 continue;1841 }1842 const childType = getConstantType(child, context);1843 if (childType === 0 /* NOT_CONSTANT */) {1844 return 0 /* NOT_CONSTANT */;1845 }1846 else if (childType < returnType) {1847 returnType = childType;1848 }1849 }1850 return returnType;1851 default:1852 return 0 /* NOT_CONSTANT */;1853 }1854}1855const allowHoistedHelperSet = new Set([1856 NORMALIZE_CLASS,1857 NORMALIZE_STYLE,1858 NORMALIZE_PROPS,1859 GUARD_REACTIVE_PROPS1860]);1861function getConstantTypeOfHelperCall(value, context) {1862 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&1863 !shared.isString(value.callee) &&1864 allowHoistedHelperSet.has(value.callee)) {1865 const arg = value.arguments[0];1866 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {1867 return getConstantType(arg, context);1868 }1869 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {1870 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`1871 return getConstantTypeOfHelperCall(arg, context);1872 }1873 }1874 return 0 /* NOT_CONSTANT */;1875}1876function getGeneratedPropsConstantType(node, context) {1877 let returnType = 3 /* CAN_STRINGIFY */;1878 const props = getNodeProps(node);1879 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {1880 const { properties } = props;1881 for (let i = 0; i < properties.length; i++) {1882 const { key, value } = properties[i];1883 const keyType = getConstantType(key, context);1884 if (keyType === 0 /* NOT_CONSTANT */) {1885 return keyType;1886 }1887 if (keyType < returnType) {1888 returnType = keyType;1889 }1890 let valueType;1891 if (value.type === 4 /* SIMPLE_EXPRESSION */) {1892 valueType = getConstantType(value, context);1893 }1894 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {1895 // some helper calls can be hoisted,1896 // such as the `normalizeProps` generated by the compiler for pre-normalize class,1897 // in this case we need to respect the ConstantType of the helper's argments1898 valueType = getConstantTypeOfHelperCall(value, context);1899 }1900 else {1901 valueType = 0 /* NOT_CONSTANT */;1902 }1903 if (valueType === 0 /* NOT_CONSTANT */) {1904 return valueType;1905 }1906 if (valueType < returnType) {1907 returnType = valueType;1908 }1909 }1910 }1911 return returnType;1912}1913function getNodeProps(node) {1914 const codegenNode = node.codegenNode;1915 if (codegenNode.type === 13 /* VNODE_CALL */) {1916 return codegenNode.props;1917 }1918}1919function getPatchFlag(node) {1920 const flag = node.patchFlag;1921 return flag ? parseInt(flag, 10) : undefined;1922}1923function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = shared.NOOP, isCustomElement = shared.NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = shared.EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {1924 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);1925 const context = {1926 // options1927 selfName: nameMatch && shared.capitalize(shared.camelize(nameMatch[1])),1928 prefixIdentifiers,1929 hoistStatic,1930 cacheHandlers,1931 nodeTransforms,1932 directiveTransforms,1933 transformHoist,1934 isBuiltInComponent,1935 isCustomElement,1936 expressionPlugins,1937 scopeId,1938 slotted,1939 ssr,1940 inSSR,1941 ssrCssVars,1942 bindingMetadata,1943 inline,1944 isTS,1945 onError,1946 onWarn,1947 compatConfig,1948 // state1949 root,1950 helpers: new Map(),1951 components: new Set(),1952 directives: new Set(),1953 hoists: [],1954 imports: [],1955 constantCache: new Map(),1956 temps: 0,1957 cached: 0,1958 identifiers: Object.create(null),1959 scopes: {1960 vFor: 0,1961 vSlot: 0,1962 vPre: 0,1963 vOnce: 01964 },1965 parent: null,1966 currentNode: root,1967 childIndex: 0,1968 inVOnce: false,1969 // methods1970 helper(name) {1971 const count = context.helpers.get(name) || 0;1972 context.helpers.set(name, count + 1);1973 return name;1974 },1975 removeHelper(name) {1976 const count = context.helpers.get(name);1977 if (count) {1978 const currentCount = count - 1;1979 if (!currentCount) {1980 context.helpers.delete(name);1981 }1982 else {1983 context.helpers.set(name, currentCount);1984 }1985 }1986 },1987 helperString(name) {1988 return `_${helperNameMap[context.helper(name)]}`;1989 },1990 replaceNode(node) {1991 /* istanbul ignore if */1992 {1993 if (!context.currentNode) {1994 throw new Error(`Node being replaced is already removed.`);1995 }1996 if (!context.parent) {1997 throw new Error(`Cannot replace root node.`);1998 }1999 }2000 context.parent.children[context.childIndex] = context.currentNode = node;2001 },2002 removeNode(node) {2003 if (!context.parent) {2004 throw new Error(`Cannot remove root node.`);2005 }2006 const list = context.parent.children;2007 const removalIndex = node2008 ? list.indexOf(node)2009 : context.currentNode2010 ? context.childIndex2011 : -1;2012 /* istanbul ignore if */2013 if (removalIndex < 0) {2014 throw new Error(`node being removed is not a child of current parent`);2015 }2016 if (!node || node === context.currentNode) {2017 // current node removed2018 context.currentNode = null;2019 context.onNodeRemoved();2020 }2021 else {2022 // sibling node removed2023 if (context.childIndex > removalIndex) {2024 context.childIndex--;2025 context.onNodeRemoved();2026 }2027 }2028 context.parent.children.splice(removalIndex, 1);2029 },2030 onNodeRemoved: () => { },2031 addIdentifiers(exp) {2032 // identifier tracking only happens in non-browser builds.2033 {2034 if (shared.isString(exp)) {2035 addId(exp);2036 }2037 else if (exp.identifiers) {2038 exp.identifiers.forEach(addId);2039 }2040 else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {2041 addId(exp.content);2042 }2043 }2044 },2045 removeIdentifiers(exp) {2046 {2047 if (shared.isString(exp)) {2048 removeId(exp);2049 }2050 else if (exp.identifiers) {2051 exp.identifiers.forEach(removeId);2052 }2053 else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {2054 removeId(exp.content);2055 }2056 }2057 },2058 hoist(exp) {2059 if (shared.isString(exp))2060 exp = createSimpleExpression(exp);2061 context.hoists.push(exp);2062 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2063 identifier.hoisted = exp;2064 return identifier;2065 },2066 cache(exp, isVNode = false) {2067 return createCacheExpression(context.cached++, exp, isVNode);2068 }2069 };2070 {2071 context.filters = new Set();2072 }2073 function addId(id) {2074 const { identifiers } = context;2075 if (identifiers[id] === undefined) {2076 identifiers[id] = 0;2077 }2078 identifiers[id]++;2079 }2080 function removeId(id) {2081 context.identifiers[id]--;2082 }2083 return context;2084}2085function transform(root, options) {2086 const context = createTransformContext(root, options);2087 traverseNode(root, context);2088 if (options.hoistStatic) {2089 hoistStatic(root, context);2090 }2091 if (!options.ssr) {2092 createRootCodegen(root, context);2093 }2094 // finalize meta information2095 root.helpers = [...context.helpers.keys()];2096 root.components = [...context.components];2097 root.directives = [...context.directives];2098 root.imports = context.imports;2099 root.hoists = context.hoists;2100 root.temps = context.temps;2101 root.cached = context.cached;2102 {2103 root.filters = [...context.filters];2104 }2105}2106function createRootCodegen(root, context) {2107 const { helper } = context;2108 const { children } = root;2109 if (children.length === 1) {2110 const child = children[0];2111 // if the single child is an element, turn it into a block.2112 if (isSingleElementRoot(root, child) && child.codegenNode) {2113 // single element root is never hoisted so codegenNode will never be2114 // SimpleExpressionNode2115 const codegenNode = child.codegenNode;2116 if (codegenNode.type === 13 /* VNODE_CALL */) {2117 makeBlock(codegenNode, context);2118 }2119 root.codegenNode = codegenNode;2120 }2121 else {2122 // - single <slot/>, IfNode, ForNode: already blocks.2123 // - single text node: always patched.2124 // root codegen falls through via genNode()2125 root.codegenNode = child;2126 }2127 }2128 else if (children.length > 1) {2129 // root has multiple nodes - return a fragment block.2130 let patchFlag = 64 /* STABLE_FRAGMENT */;2131 let patchFlagText = shared.PatchFlagNames[64 /* STABLE_FRAGMENT */];2132 // check if the fragment actually contains a single valid child with2133 // the rest being comments2134 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2135 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2136 patchFlagText += `, ${shared.PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2137 }2138 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);2139 }2140 else ;2141}2142function traverseChildren(parent, context) {2143 let i = 0;2144 const nodeRemoved = () => {2145 i--;2146 };2147 for (; i < parent.children.length; i++) {2148 const child = parent.children[i];2149 if (shared.isString(child))2150 continue;2151 context.parent = parent;2152 context.childIndex = i;2153 context.onNodeRemoved = nodeRemoved;2154 traverseNode(child, context);2155 }2156}2157function traverseNode(node, context) {2158 context.currentNode = node;2159 // apply transform plugins2160 const { nodeTransforms } = context;2161 const exitFns = [];2162 for (let i = 0; i < nodeTransforms.length; i++) {2163 const onExit = nodeTransforms[i](node, context);2164 if (onExit) {2165 if (shared.isArray(onExit)) {2166 exitFns.push(...onExit);2167 }2168 else {2169 exitFns.push(onExit);2170 }2171 }2172 if (!context.currentNode) {2173 // node was removed2174 return;2175 }2176 else {2177 // node may have been replaced2178 node = context.currentNode;2179 }2180 }2181 switch (node.type) {2182 case 3 /* COMMENT */:2183 if (!context.ssr) {2184 // inject import for the Comment symbol, which is needed for creating2185 // comment nodes with `createVNode`2186 context.helper(CREATE_COMMENT);2187 }2188 break;2189 case 5 /* INTERPOLATION */:2190 // no need to traverse, but we need to inject toString helper2191 if (!context.ssr) {2192 context.helper(TO_DISPLAY_STRING);2193 }2194 break;2195 // for container types, further traverse downwards2196 case 9 /* IF */:2197 for (let i = 0; i < node.branches.length; i++) {2198 traverseNode(node.branches[i], context);2199 }2200 break;2201 case 10 /* IF_BRANCH */:2202 case 11 /* FOR */:2203 case 1 /* ELEMENT */:2204 case 0 /* ROOT */:2205 traverseChildren(node, context);2206 break;2207 }2208 // exit transforms2209 context.currentNode = node;2210 let i = exitFns.length;2211 while (i--) {2212 exitFns[i]();2213 }2214}2215function createStructuralDirectiveTransform(name, fn) {2216 const matches = shared.isString(name)2217 ? (n) => n === name2218 : (n) => name.test(n);2219 return (node, context) => {2220 if (node.type === 1 /* ELEMENT */) {2221 const { props } = node;2222 // structural directive transforms are not concerned with slots2223 // as they are handled separately in vSlot.ts2224 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2225 return;2226 }2227 const exitFns = [];2228 for (let i = 0; i < props.length; i++) {2229 const prop = props[i];2230 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2231 // structural directives are removed to avoid infinite recursion2232 // also we remove them *before* applying so that it can further2233 // traverse itself in case it moves the node around2234 props.splice(i, 1);2235 i--;2236 const onExit = fn(node, prop, context);2237 if (onExit)2238 exitFns.push(onExit);2239 }2240 }2241 return exitFns;2242 }2243 };2244}2245const PURE_ANNOTATION = `/*#__PURE__*/`;2246function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap: sourceMap$1 = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {2247 const context = {2248 mode,2249 prefixIdentifiers,2250 sourceMap: sourceMap$1,2251 filename,2252 scopeId,2253 optimizeImports,2254 runtimeGlobalName,2255 runtimeModuleName,2256 ssrRuntimeModuleName,2257 ssr,2258 isTS,2259 inSSR,2260 source: ast.loc.source,2261 code: ``,2262 column: 1,2263 line: 1,2264 offset: 0,2265 indentLevel: 0,2266 pure: false,2267 map: undefined,2268 helper(key) {2269 return `_${helperNameMap[key]}`;2270 },2271 push(code, node) {2272 context.code += code;2273 if (context.map) {2274 if (node) {2275 let name;2276 if (node.type === 4 /* SIMPLE_EXPRESSION */ && !node.isStatic) {2277 const content = node.content.replace(/^_ctx\./, '');2278 if (content !== node.content && isSimpleIdentifier(content)) {2279 name = content;2280 }2281 }2282 addMapping(node.loc.start, name);2283 }2284 advancePositionWithMutation(context, code);2285 if (node && node.loc !== locStub) {2286 addMapping(node.loc.end);2287 }2288 }2289 },2290 indent() {2291 newline(++context.indentLevel);2292 },2293 deindent(withoutNewLine = false) {2294 if (withoutNewLine) {2295 --context.indentLevel;2296 }2297 else {2298 newline(--context.indentLevel);2299 }2300 },2301 newline() {2302 newline(context.indentLevel);2303 }2304 };2305 function newline(n) {2306 context.push('\n' + ` `.repeat(n));2307 }2308 function addMapping(loc, name) {2309 context.map.addMapping({2310 name,2311 source: context.filename,2312 original: {2313 line: loc.line,2314 column: loc.column - 1 // source-map column is 0 based2315 },2316 generated: {2317 line: context.line,2318 column: context.column - 12319 }2320 });2321 }2322 if (sourceMap$1) {2323 // lazy require source-map implementation, only in non-browser builds2324 context.map = new sourceMap.SourceMapGenerator();2325 context.map.setSourceContent(filename, context.source);2326 }2327 return context;2328}2329function generate(ast, options = {}) {2330 const context = createCodegenContext(ast, options);2331 if (options.onContextCreated)2332 options.onContextCreated(context);2333 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2334 const hasHelpers = ast.helpers.length > 0;2335 const useWithBlock = !prefixIdentifiers && mode !== 'module';2336 const genScopeId = scopeId != null && mode === 'module';2337 const isSetupInlined = !!options.inline;2338 // preambles2339 // in setup() inline mode, the preamble is generated in a sub context2340 // and returned separately.2341 const preambleContext = isSetupInlined2342 ? createCodegenContext(ast, options)2343 : context;2344 if (mode === 'module') {2345 genModulePreamble(ast, preambleContext, genScopeId, isSetupInlined);2346 }2347 else {2348 genFunctionPreamble(ast, preambleContext);2349 }2350 // enter render function2351 const functionName = ssr ? `ssrRender` : `render`;2352 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2353 if (options.bindingMetadata && !options.inline) {2354 // binding optimization args2355 args.push('$props', '$setup', '$data', '$options');2356 }2357 const signature = options.isTS2358 ? args.map(arg => `${arg}: any`).join(',')2359 : args.join(', ');2360 if (isSetupInlined) {2361 push(`(${signature}) => {`);2362 }2363 else {2364 push(`function ${functionName}(${signature}) {`);2365 }2366 indent();2367 if (useWithBlock) {2368 push(`with (_ctx) {`);2369 indent();2370 // function mode const declarations should be inside with block2371 // also they should be renamed to avoid collision with user properties2372 if (hasHelpers) {2373 push(`const { ${ast.helpers2374 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2375 .join(', ')} } = _Vue`);2376 push(`\n`);2377 newline();2378 }2379 }2380 // generate asset resolution statements2381 if (ast.components.length) {2382 genAssets(ast.components, 'component', context);2383 if (ast.directives.length || ast.temps > 0) {2384 newline();2385 }2386 }2387 if (ast.directives.length) {2388 genAssets(ast.directives, 'directive', context);2389 if (ast.temps > 0) {2390 newline();2391 }2392 }2393 if (ast.filters && ast.filters.length) {2394 newline();2395 genAssets(ast.filters, 'filter', context);2396 newline();2397 }2398 if (ast.temps > 0) {2399 push(`let `);2400 for (let i = 0; i < ast.temps; i++) {2401 push(`${i > 0 ? `, ` : ``}_temp${i}`);2402 }2403 }2404 if (ast.components.length || ast.directives.length || ast.temps) {2405 push(`\n`);2406 newline();2407 }2408 // generate the VNode tree expression2409 if (!ssr) {2410 push(`return `);2411 }2412 if (ast.codegenNode) {2413 genNode(ast.codegenNode, context);2414 }2415 else {2416 push(`null`);2417 }2418 if (useWithBlock) {2419 deindent();2420 push(`}`);2421 }2422 deindent();2423 push(`}`);2424 return {2425 ast,2426 code: context.code,2427 preamble: isSetupInlined ? preambleContext.code : ``,2428 // SourceMapGenerator does have toJSON() method but it's not in the types2429 map: context.map ? context.map.toJSON() : undefined2430 };2431}2432function genFunctionPreamble(ast, context) {2433 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2434 const VueBinding = ssr2435 ? `require(${JSON.stringify(runtimeModuleName)})`2436 : runtimeGlobalName;2437 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2438 // Generate const declaration for helpers2439 // In prefix mode, we place the const declaration at top so it's done2440 // only once; But if we not prefixing, we place the declaration inside the2441 // with block so it doesn't incur the `in` check cost for every helper access.2442 if (ast.helpers.length > 0) {2443 if (prefixIdentifiers) {2444 push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`);2445 }2446 else {2447 // "with" mode.2448 // save Vue in a separate variable to avoid collision2449 push(`const _Vue = ${VueBinding}\n`);2450 // in "with" mode, helpers are declared inside the with block to avoid2451 // has check cost, but hoists are lifted out of the function - we need2452 // to provide the helper here.2453 if (ast.hoists.length) {2454 const staticHelpers = [2455 CREATE_VNODE,2456 CREATE_ELEMENT_VNODE,2457 CREATE_COMMENT,2458 CREATE_TEXT,2459 CREATE_STATIC2460 ]2461 .filter(helper => ast.helpers.includes(helper))2462 .map(aliasHelper)2463 .join(', ');2464 push(`const { ${staticHelpers} } = _Vue\n`);2465 }2466 }2467 }2468 // generate variables for ssr helpers2469 if (ast.ssrHelpers && ast.ssrHelpers.length) {2470 // ssr guarantees prefixIdentifier: true2471 push(`const { ${ast.ssrHelpers2472 .map(aliasHelper)2473 .join(', ')} } = require("${ssrRuntimeModuleName}")\n`);2474 }2475 genHoists(ast.hoists, context);2476 newline();2477 push(`return `);2478}2479function genModulePreamble(ast, context, genScopeId, inline) {2480 const { push, newline, optimizeImports, runtimeModuleName, ssrRuntimeModuleName } = context;2481 if (genScopeId && ast.hoists.length) {2482 ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID);2483 }2484 // generate import statements for helpers2485 if (ast.helpers.length) {2486 if (optimizeImports) {2487 // when bundled with webpack with code-split, calling an import binding2488 // as a function leads to it being wrapped with `Object(a.b)` or `(0,a.b)`,2489 // incurring both payload size increase and potential perf overhead.2490 // therefore we assign the imports to variables (which is a constant ~50b2491 // cost per-component instead of scaling with template size)2492 push(`import { ${ast.helpers2493 .map(s => helperNameMap[s])2494 .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`);2495 push(`\n// Binding optimization for webpack code-split\nconst ${ast.helpers2496 .map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`)2497 .join(', ')}\n`);2498 }2499 else {2500 push(`import { ${ast.helpers2501 .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)2502 .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`);2503 }2504 }2505 if (ast.ssrHelpers && ast.ssrHelpers.length) {2506 push(`import { ${ast.ssrHelpers2507 .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)2508 .join(', ')} } from "${ssrRuntimeModuleName}"\n`);2509 }2510 if (ast.imports.length) {2511 genImports(ast.imports, context);2512 newline();2513 }2514 genHoists(ast.hoists, context);2515 newline();2516 if (!inline) {2517 push(`export `);2518 }2519}2520function genAssets(assets, type, { helper, push, newline, isTS }) {2521 const resolver = helper(type === 'filter'2522 ? RESOLVE_FILTER2523 : type === 'component'2524 ? RESOLVE_COMPONENT2525 : RESOLVE_DIRECTIVE);2526 for (let i = 0; i < assets.length; i++) {2527 let id = assets[i];2528 // potential component implicit self-reference inferred from SFC filename2529 const maybeSelfReference = id.endsWith('__self');2530 if (maybeSelfReference) {2531 id = id.slice(0, -6);2532 }2533 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2534 if (i < assets.length - 1) {2535 newline();2536 }2537 }2538}2539function genHoists(hoists, context) {2540 if (!hoists.length) {2541 return;2542 }2543 context.pure = true;2544 const { push, newline, helper, scopeId, mode } = context;2545 const genScopeId = scopeId != null && mode !== 'function';2546 newline();2547 // generate inlined withScopeId helper2548 if (genScopeId) {2549 push(`const _withScopeId = n => (${helper(PUSH_SCOPE_ID)}("${scopeId}"),n=n(),${helper(POP_SCOPE_ID)}(),n)`);2550 newline();2551 }2552 for (let i = 0; i < hoists.length; i++) {2553 const exp = hoists[i];2554 if (exp) {2555 const needScopeIdWrapper = genScopeId && exp.type === 13 /* VNODE_CALL */;2556 push(`const _hoisted_${i + 1} = ${needScopeIdWrapper ? `${PURE_ANNOTATION} _withScopeId(() => ` : ``}`);2557 genNode(exp, context);2558 if (needScopeIdWrapper) {2559 push(`)`);2560 }2561 newline();2562 }2563 }2564 context.pure = false;2565}2566function genImports(importsOptions, context) {2567 if (!importsOptions.length) {2568 return;2569 }2570 importsOptions.forEach(imports => {2571 context.push(`import `);2572 genNode(imports.exp, context);2573 context.push(` from '${imports.path}'`);2574 context.newline();2575 });2576}2577function isText$1(n) {2578 return (shared.isString(n) ||2579 n.type === 4 /* SIMPLE_EXPRESSION */ ||2580 n.type === 2 /* TEXT */ ||2581 n.type === 5 /* INTERPOLATION */ ||2582 n.type === 8 /* COMPOUND_EXPRESSION */);2583}2584function genNodeListAsArray(nodes, context) {2585 const multilines = nodes.length > 3 ||2586 (nodes.some(n => shared.isArray(n) || !isText$1(n)));2587 context.push(`[`);2588 multilines && context.indent();2589 genNodeList(nodes, context, multilines);2590 multilines && context.deindent();2591 context.push(`]`);2592}2593function genNodeList(nodes, context, multilines = false, comma = true) {2594 const { push, newline } = context;2595 for (let i = 0; i < nodes.length; i++) {2596 const node = nodes[i];2597 if (shared.isString(node)) {2598 push(node);2599 }2600 else if (shared.isArray(node)) {2601 genNodeListAsArray(node, context);2602 }2603 else {2604 genNode(node, context);2605 }2606 if (i < nodes.length - 1) {2607 if (multilines) {2608 comma && push(',');2609 newline();2610 }2611 else {2612 comma && push(', ');2613 }2614 }2615 }2616}2617function genNode(node, context) {2618 if (shared.isString(node)) {2619 context.push(node);2620 return;2621 }2622 if (shared.isSymbol(node)) {2623 context.push(context.helper(node));2624 return;2625 }2626 switch (node.type) {2627 case 1 /* ELEMENT */:2628 case 9 /* IF */:2629 case 11 /* FOR */:2630 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2631 `Apply appropriate transforms first.`);2632 genNode(node.codegenNode, context);2633 break;2634 case 2 /* TEXT */:2635 genText(node, context);2636 break;2637 case 4 /* SIMPLE_EXPRESSION */:2638 genExpression(node, context);2639 break;2640 case 5 /* INTERPOLATION */:2641 genInterpolation(node, context);2642 break;2643 case 12 /* TEXT_CALL */:2644 genNode(node.codegenNode, context);2645 break;2646 case 8 /* COMPOUND_EXPRESSION */:2647 genCompoundExpression(node, context);2648 break;2649 case 3 /* COMMENT */:2650 genComment(node, context);2651 break;2652 case 13 /* VNODE_CALL */:2653 genVNodeCall(node, context);2654 break;2655 case 14 /* JS_CALL_EXPRESSION */:2656 genCallExpression(node, context);2657 break;2658 case 15 /* JS_OBJECT_EXPRESSION */:2659 genObjectExpression(node, context);2660 break;2661 case 17 /* JS_ARRAY_EXPRESSION */:2662 genArrayExpression(node, context);2663 break;2664 case 18 /* JS_FUNCTION_EXPRESSION */:2665 genFunctionExpression(node, context);2666 break;2667 case 19 /* JS_CONDITIONAL_EXPRESSION */:2668 genConditionalExpression(node, context);2669 break;2670 case 20 /* JS_CACHE_EXPRESSION */:2671 genCacheExpression(node, context);2672 break;2673 case 21 /* JS_BLOCK_STATEMENT */:2674 genNodeList(node.body, context, true, false);2675 break;2676 // SSR only types2677 case 22 /* JS_TEMPLATE_LITERAL */:2678 genTemplateLiteral(node, context);2679 break;2680 case 23 /* JS_IF_STATEMENT */:2681 genIfStatement(node, context);2682 break;2683 case 24 /* JS_ASSIGNMENT_EXPRESSION */:2684 genAssignmentExpression(node, context);2685 break;2686 case 25 /* JS_SEQUENCE_EXPRESSION */:2687 genSequenceExpression(node, context);2688 break;2689 case 26 /* JS_RETURN_STATEMENT */:2690 genReturnStatement(node, context);2691 break;2692 /* istanbul ignore next */2693 case 10 /* IF_BRANCH */:2694 // noop2695 break;2696 default:2697 {2698 assert(false, `unhandled codegen node type: ${node.type}`);2699 // make sure we exhaust all possible types2700 const exhaustiveCheck = node;2701 return exhaustiveCheck;2702 }2703 }2704}2705function genText(node, context) {2706 context.push(JSON.stringify(node.content), node);2707}2708function genExpression(node, context) {2709 const { content, isStatic } = node;2710 context.push(isStatic ? JSON.stringify(content) : content, node);2711}2712function genInterpolation(node, context) {2713 const { push, helper, pure } = context;2714 if (pure)2715 push(PURE_ANNOTATION);2716 push(`${helper(TO_DISPLAY_STRING)}(`);2717 genNode(node.content, context);2718 push(`)`);2719}2720function genCompoundExpression(node, context) {2721 for (let i = 0; i < node.children.length; i++) {2722 const child = node.children[i];2723 if (shared.isString(child)) {2724 context.push(child);2725 }2726 else {2727 genNode(child, context);2728 }2729 }2730}2731function genExpressionAsPropertyKey(node, context) {2732 const { push } = context;2733 if (node.type === 8 /* COMPOUND_EXPRESSION */) {2734 push(`[`);2735 genCompoundExpression(node, context);2736 push(`]`);2737 }2738 else if (node.isStatic) {2739 // only quote keys if necessary2740 const text = isSimpleIdentifier(node.content)2741 ? node.content2742 : JSON.stringify(node.content);2743 push(text, node);2744 }2745 else {2746 push(`[${node.content}]`, node);2747 }2748}2749function genComment(node, context) {2750 const { push, helper, pure } = context;2751 if (pure) {2752 push(PURE_ANNOTATION);2753 }2754 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2755}2756function genVNodeCall(node, context) {2757 const { push, helper, pure } = context;2758 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2759 if (directives) {2760 push(helper(WITH_DIRECTIVES) + `(`);2761 }2762 if (isBlock) {2763 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2764 }2765 if (pure) {2766 push(PURE_ANNOTATION);2767 }2768 const callHelper = isBlock2769 ? getVNodeBlockHelper(context.inSSR, isComponent)2770 : getVNodeHelper(context.inSSR, isComponent);2771 push(helper(callHelper) + `(`, node);2772 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2773 push(`)`);2774 if (isBlock) {2775 push(`)`);2776 }2777 if (directives) {2778 push(`, `);2779 genNode(directives, context);2780 push(`)`);2781 }2782}2783function genNullableArgs(args) {2784 let i = args.length;2785 while (i--) {2786 if (args[i] != null)2787 break;2788 }2789 return args.slice(0, i + 1).map(arg => arg || `null`);2790}2791// JavaScript2792function genCallExpression(node, context) {2793 const { push, helper, pure } = context;2794 const callee = shared.isString(node.callee) ? node.callee : helper(node.callee);2795 if (pure) {2796 push(PURE_ANNOTATION);2797 }2798 push(callee + `(`, node);2799 genNodeList(node.arguments, context);2800 push(`)`);2801}2802function genObjectExpression(node, context) {2803 const { push, indent, deindent, newline } = context;2804 const { properties } = node;2805 if (!properties.length) {2806 push(`{}`, node);2807 return;2808 }2809 const multilines = properties.length > 1 ||2810 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2811 push(multilines ? `{` : `{ `);2812 multilines && indent();2813 for (let i = 0; i < properties.length; i++) {2814 const { key, value } = properties[i];2815 // key2816 genExpressionAsPropertyKey(key, context);2817 push(`: `);2818 // value2819 genNode(value, context);2820 if (i < properties.length - 1) {2821 // will only reach this if it's multilines2822 push(`,`);2823 newline();2824 }2825 }2826 multilines && deindent();2827 push(multilines ? `}` : ` }`);2828}2829function genArrayExpression(node, context) {2830 genNodeListAsArray(node.elements, context);2831}2832function genFunctionExpression(node, context) {2833 const { push, indent, deindent } = context;2834 const { params, returns, body, newline, isSlot } = node;2835 if (isSlot) {2836 // wrap slot functions with owner context2837 push(`_${helperNameMap[WITH_CTX]}(`);2838 }2839 push(`(`, node);2840 if (shared.isArray(params)) {2841 genNodeList(params, context);2842 }2843 else if (params) {2844 genNode(params, context);2845 }2846 push(`) => `);2847 if (newline || body) {2848 push(`{`);2849 indent();2850 }2851 if (returns) {2852 if (newline) {2853 push(`return `);2854 }2855 if (shared.isArray(returns)) {2856 genNodeListAsArray(returns, context);2857 }2858 else {2859 genNode(returns, context);2860 }2861 }2862 else if (body) {2863 genNode(body, context);2864 }2865 if (newline || body) {2866 deindent();2867 push(`}`);2868 }2869 if (isSlot) {2870 if (node.isNonScopedSlot) {2871 push(`, undefined, true`);2872 }2873 push(`)`);2874 }2875}2876function genConditionalExpression(node, context) {2877 const { test, consequent, alternate, newline: needNewline } = node;2878 const { push, indent, deindent, newline } = context;2879 if (test.type === 4 /* SIMPLE_EXPRESSION */) {2880 const needsParens = !isSimpleIdentifier(test.content);2881 needsParens && push(`(`);2882 genExpression(test, context);2883 needsParens && push(`)`);2884 }2885 else {2886 push(`(`);2887 genNode(test, context);2888 push(`)`);2889 }2890 needNewline && indent();2891 context.indentLevel++;2892 needNewline || push(` `);2893 push(`? `);2894 genNode(consequent, context);2895 context.indentLevel--;2896 needNewline && newline();2897 needNewline || push(` `);2898 push(`: `);2899 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2900 if (!isNested) {2901 context.indentLevel++;2902 }2903 genNode(alternate, context);2904 if (!isNested) {2905 context.indentLevel--;2906 }2907 needNewline && deindent(true /* without newline */);2908}2909function genCacheExpression(node, context) {2910 const { push, helper, indent, deindent, newline } = context;2911 push(`_cache[${node.index}] || (`);2912 if (node.isVNode) {2913 indent();2914 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2915 newline();2916 }2917 push(`_cache[${node.index}] = `);2918 genNode(node.value, context);2919 if (node.isVNode) {2920 push(`,`);2921 newline();2922 push(`${helper(SET_BLOCK_TRACKING)}(1),`);2923 newline();2924 push(`_cache[${node.index}]`);2925 deindent();2926 }2927 push(`)`);2928}2929function genTemplateLiteral(node, context) {2930 const { push, indent, deindent } = context;2931 push('`');2932 const l = node.elements.length;2933 const multilines = l > 3;2934 for (let i = 0; i < l; i++) {2935 const e = node.elements[i];2936 if (shared.isString(e)) {2937 push(e.replace(/(`|\$|\\)/g, '\\$1'));2938 }2939 else {2940 push('${');2941 if (multilines)2942 indent();2943 genNode(e, context);2944 if (multilines)2945 deindent();2946 push('}');2947 }2948 }2949 push('`');2950}2951function genIfStatement(node, context) {2952 const { push, indent, deindent } = context;2953 const { test, consequent, alternate } = node;2954 push(`if (`);2955 genNode(test, context);2956 push(`) {`);2957 indent();2958 genNode(consequent, context);2959 deindent();2960 push(`}`);2961 if (alternate) {2962 push(` else `);2963 if (alternate.type === 23 /* JS_IF_STATEMENT */) {2964 genIfStatement(alternate, context);2965 }2966 else {2967 push(`{`);2968 indent();2969 genNode(alternate, context);2970 deindent();2971 push(`}`);2972 }2973 }2974}2975function genAssignmentExpression(node, context) {2976 genNode(node.left, context);2977 context.push(` = `);2978 genNode(node.right, context);2979}2980function genSequenceExpression(node, context) {2981 context.push(`(`);2982 genNodeList(node.expressions, context);2983 context.push(`)`);2984}2985function genReturnStatement({ returns }, context) {2986 context.push(`return `);2987 if (shared.isArray(returns)) {2988 genNodeListAsArray(returns, context);2989 }2990 else {2991 genNode(returns, context);2992 }2993}2994function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2995 const rootExp = root.type === 'Program' &&2996 root.body[0].type === 'ExpressionStatement' &&2997 root.body[0].expression;2998 estreeWalker.walk(root, {2999 enter(node, parent) {3000 parent && parentStack.push(parent);3001 if (parent &&3002 parent.type.startsWith('TS') &&3003 parent.type !== 'TSAsExpression' &&3004 parent.type !== 'TSNonNullExpression' &&3005 parent.type !== 'TSTypeAssertion') {3006 return this.skip();3007 }3008 if (node.type === 'Identifier') {3009 const isLocal = !!knownIds[node.name];3010 const isRefed = isReferencedIdentifier(node, parent, parentStack);3011 if (includeAll || (isRefed && !isLocal)) {3012 onIdentifier(node, parent, parentStack, isRefed, isLocal);3013 }3014 }3015 else if (node.type === 'ObjectProperty' &&3016 parent.type === 'ObjectPattern') {3017 node.inPattern = true;3018 }3019 else if (isFunctionType(node)) {3020 // walk function expressions and add its arguments to known identifiers3021 // so that we don't prefix them3022 walkFunctionParams(node, id => markScopeIdentifier(node, id, knownIds));3023 }3024 else if (node.type === 'BlockStatement') {3025 // #3445 record block-level local variables3026 walkBlockDeclarations(node, id => markScopeIdentifier(node, id, knownIds));3027 }3028 },3029 leave(node, parent) {3030 parent && parentStack.pop();3031 if (node !== rootExp && node.scopeIds) {3032 for (const id of node.scopeIds) {3033 knownIds[id]--;3034 if (knownIds[id] === 0) {3035 delete knownIds[id];3036 }3037 }3038 }3039 }3040 });3041}3042function isReferencedIdentifier(id, parent, parentStack) {3043 if (!parent) {3044 return true;3045 }3046 // is a special keyword but parsed as identifier3047 if (id.name === 'arguments') {3048 return false;3049 }3050 if (isReferenced(id, parent)) {3051 return true;3052 }3053 // babel's isReferenced check returns false for ids being assigned to, so we3054 // need to cover those cases here3055 switch (parent.type) {3056 case 'AssignmentExpression':3057 case 'AssignmentPattern':3058 return true;3059 case 'ObjectPattern':3060 case 'ArrayPattern':3061 return isInDestructureAssignment(parent, parentStack);3062 }3063 return false;3064}3065function isInDestructureAssignment(parent, parentStack) {3066 if (parent &&3067 (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {3068 let i = parentStack.length;3069 while (i--) {3070 const p = parentStack[i];3071 if (p.type === 'AssignmentExpression') {3072 return true;3073 }3074 else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {3075 break;3076 }3077 }3078 }3079 return false;3080}3081function walkFunctionParams(node, onIdent) {3082 for (const p of node.params) {3083 for (const id of extractIdentifiers(p)) {3084 onIdent(id);3085 }3086 }3087}3088function walkBlockDeclarations(block, onIdent) {3089 for (const stmt of block.body) {3090 if (stmt.type === 'VariableDeclaration') {3091 if (stmt.declare)3092 continue;3093 for (const decl of stmt.declarations) {3094 for (const id of extractIdentifiers(decl.id)) {3095 onIdent(id);3096 }3097 }3098 }3099 else if (stmt.type === 'FunctionDeclaration' ||3100 stmt.type === 'ClassDeclaration') {3101 if (stmt.declare || !stmt.id)3102 continue;3103 onIdent(stmt.id);3104 }3105 }3106}3107function extractIdentifiers(param, nodes = []) {3108 switch (param.type) {3109 case 'Identifier':3110 nodes.push(param);3111 break;3112 case 'MemberExpression':3113 let object = param;3114 while (object.type === 'MemberExpression') {3115 object = object.object;3116 }3117 nodes.push(object);3118 break;3119 case 'ObjectPattern':3120 for (const prop of param.properties) {3121 if (prop.type === 'RestElement') {3122 extractIdentifiers(prop.argument, nodes);3123 }3124 else {3125 extractIdentifiers(prop.value, nodes);3126 }3127 }3128 break;3129 case 'ArrayPattern':3130 param.elements.forEach(element => {3131 if (element)3132 extractIdentifiers(element, nodes);3133 });3134 break;3135 case 'RestElement':3136 extractIdentifiers(param.argument, nodes);3137 break;3138 case 'AssignmentPattern':3139 extractIdentifiers(param.left, nodes);3140 break;3141 }3142 return nodes;3143}3144function markScopeIdentifier(node, child, knownIds) {3145 const { name } = child;3146 if (node.scopeIds && node.scopeIds.has(name)) {3147 return;3148 }3149 if (name in knownIds) {3150 knownIds[name]++;3151 }3152 else {3153 knownIds[name] = 1;3154 }3155 (node.scopeIds || (node.scopeIds = new Set())).add(name);3156}3157const isFunctionType = (node) => {3158 return /Function(?:Expression|Declaration)$|Method$/.test(node.type);3159};3160const isStaticProperty = (node) => node &&3161 (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&3162 !node.computed;3163const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;3164/**3165 * Copied from https://github.com/babel/babel/blob/main/packages/babel-types/src/validators/isReferenced.ts3166 * To avoid runtime dependency on @babel/types (which includes process references)3167 * This file should not change very often in babel but we may need to keep it3168 * up-to-date from time to time.3169 *3170 * https://github.com/babel/babel/blob/main/LICENSE3171 *3172 */3173function isReferenced(node, parent, grandparent) {3174 switch (parent.type) {3175 // yes: PARENT[NODE]3176 // yes: NODE.child3177 // no: parent.NODE3178 case 'MemberExpression':3179 case 'OptionalMemberExpression':3180 if (parent.property === node) {3181 return !!parent.computed;3182 }3183 return parent.object === node;3184 case 'JSXMemberExpression':3185 return parent.object === node;3186 // no: let NODE = init;3187 // yes: let id = NODE;3188 case 'VariableDeclarator':3189 return parent.init === node;3190 // yes: () => NODE3191 // no: (NODE) => {}3192 case 'ArrowFunctionExpression':3193 return parent.body === node;3194 // no: class { #NODE; }3195 // no: class { get #NODE() {} }3196 // no: class { #NODE() {} }3197 // no: class { fn() { return this.#NODE; } }3198 case 'PrivateName':3199 return false;3200 // no: class { NODE() {} }3201 // yes: class { [NODE]() {} }3202 // no: class { foo(NODE) {} }3203 case 'ClassMethod':3204 case 'ClassPrivateMethod':3205 case 'ObjectMethod':3206 if (parent.key === node) {3207 return !!parent.computed;3208 }3209 return false;3210 // yes: { [NODE]: "" }3211 // no: { NODE: "" }3212 // depends: { NODE }3213 // depends: { key: NODE }3214 case 'ObjectProperty':3215 if (parent.key === node) {3216 return !!parent.computed;3217 }3218 // parent.value === node3219 return !grandparent || grandparent.type !== 'ObjectPattern';3220 // no: class { NODE = value; }3221 // yes: class { [NODE] = value; }3222 // yes: class { key = NODE; }3223 case 'ClassProperty':3224 if (parent.key === node) {3225 return !!parent.computed;3226 }3227 return true;3228 case 'ClassPrivateProperty':3229 return parent.key !== node;3230 // no: class NODE {}3231 // yes: class Foo extends NODE {}3232 case 'ClassDeclaration':3233 case 'ClassExpression':3234 return parent.superClass === node;3235 // yes: left = NODE;3236 // no: NODE = right;3237 case 'AssignmentExpression':3238 return parent.right === node;3239 // no: [NODE = foo] = [];3240 // yes: [foo = NODE] = [];3241 case 'AssignmentPattern':3242 return parent.right === node;3243 // no: NODE: for (;;) {}3244 case 'LabeledStatement':3245 return false;3246 // no: try {} catch (NODE) {}3247 case 'CatchClause':3248 return false;3249 // no: function foo(...NODE) {}3250 case 'RestElement':3251 return false;3252 case 'BreakStatement':3253 case 'ContinueStatement':3254 return false;3255 // no: function NODE() {}3256 // no: function foo(NODE) {}3257 case 'FunctionDeclaration':3258 case 'FunctionExpression':3259 return false;3260 // no: export NODE from "foo";3261 // no: export * as NODE from "foo";3262 case 'ExportNamespaceSpecifier':3263 case 'ExportDefaultSpecifier':3264 return false;3265 // no: export { foo as NODE };3266 // yes: export { NODE as foo };3267 // no: export { NODE as foo } from "foo";3268 case 'ExportSpecifier':3269 // @ts-expect-error3270 if (grandparent === null || grandparent === void 0 ? void 0 : grandparent.source) {3271 return false;3272 }3273 return parent.local === node;3274 // no: import NODE from "foo";3275 // no: import * as NODE from "foo";3276 // no: import { NODE as foo } from "foo";3277 // no: import { foo as NODE } from "foo";3278 // no: import NODE from "bar";3279 case 'ImportDefaultSpecifier':3280 case 'ImportNamespaceSpecifier':3281 case 'ImportSpecifier':3282 return false;3283 // no: import "foo" assert { NODE: "json" }3284 case 'ImportAttribute':3285 return false;3286 // no: <div NODE="foo" />3287 case 'JSXAttribute':3288 return false;3289 // no: [NODE] = [];3290 // no: ({ NODE }) = [];3291 case 'ObjectPattern':3292 case 'ArrayPattern':3293 return false;3294 // no: new.NODE3295 // no: NODE.target3296 case 'MetaProperty':3297 return false;3298 // yes: type X = { somePropert: NODE }3299 // no: type X = { NODE: OtherType }3300 case 'ObjectTypeProperty':3301 return parent.key !== node;3302 // yes: enum X { Foo = NODE }3303 // no: enum X { NODE }3304 case 'TSEnumMember':3305 return parent.id !== node;3306 // yes: { [NODE]: value }3307 // no: { NODE: value }3308 case 'TSPropertySignature':3309 if (parent.key === node) {3310 return !!parent.computed;3311 }3312 return true;3313 }3314 return true;3315}3316const isLiteralWhitelisted = /*#__PURE__*/ shared.makeMap('true,false,null,this');3317const transformExpression = (node, context) => {3318 if (node.type === 5 /* INTERPOLATION */) {3319 node.content = processExpression(node.content, context);3320 }3321 else if (node.type === 1 /* ELEMENT */) {3322 // handle directives on element3323 for (let i = 0; i < node.props.length; i++) {3324 const dir = node.props[i];3325 // do not process for v-on & v-for since they are special handled3326 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3327 const exp = dir.exp;3328 const arg = dir.arg;3329 // do not process exp if this is v-on:arg - we need special handling3330 // for wrapping inline statements.3331 if (exp &&3332 exp.type === 4 /* SIMPLE_EXPRESSION */ &&3333 !(dir.name === 'on' && arg)) {3334 dir.exp = processExpression(exp, context, 3335 // slot args must be processed as function params3336 dir.name === 'slot');3337 }3338 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3339 dir.arg = processExpression(arg, context);3340 }3341 }3342 }3343 }3344};3345// Important: since this function uses Node.js only dependencies, it should3346// always be used with a leading !false check so that it can be3347// tree-shaken from the browser build.3348function processExpression(node, context, 3349// some expressions like v-slot props & v-for aliases should be parsed as3350// function params3351asParams = false, 3352// v-on handler values may contain multiple statements3353asRawStatements = false, localVars = Object.create(context.identifiers)) {3354 if (!context.prefixIdentifiers || !node.content.trim()) {3355 return node;3356 }3357 const { inline, bindingMetadata } = context;3358 const rewriteIdentifier = (raw, parent, id) => {3359 const type = shared.hasOwn(bindingMetadata, raw) && bindingMetadata[raw];3360 if (inline) {3361 // x = y3362 const isAssignmentLVal = parent && parent.type === 'AssignmentExpression' && parent.left === id;3363 // x++3364 const isUpdateArg = parent && parent.type === 'UpdateExpression' && parent.argument === id;3365 // ({ x } = y)3366 const isDestructureAssignment = parent && isInDestructureAssignment(parent, parentStack);3367 if (type === "setup-const" /* SETUP_CONST */ || localVars[raw]) {3368 return raw;3369 }3370 else if (type === "setup-ref" /* SETUP_REF */) {3371 return `${raw}.value`;3372 }3373 else if (type === "setup-maybe-ref" /* SETUP_MAYBE_REF */) {3374 // const binding that may or may not be ref3375 // if it's not a ref, then assignments don't make sense -3376 // so we ignore the non-ref assignment case and generate code3377 // that assumes the value to be a ref for more efficiency3378 return isAssignmentLVal || isUpdateArg || isDestructureAssignment3379 ? `${raw}.value`3380 : `${context.helperString(UNREF)}(${raw})`;3381 }3382 else if (type === "setup-let" /* SETUP_LET */) {3383 if (isAssignmentLVal) {3384 // let binding.3385 // this is a bit more tricky as we need to cover the case where3386 // let is a local non-ref value, and we need to replicate the3387 // right hand side value.3388 // x = y --> isRef(x) ? x.value = y : x = y3389 const { right: rVal, operator } = parent;3390 const rExp = rawExp.slice(rVal.start - 1, rVal.end - 1);3391 const rExpString = stringifyExpression(processExpression(createSimpleExpression(rExp, false), context, false, false, knownIds));3392 return `${context.helperString(IS_REF)}(${raw})${context.isTS ? ` //@ts-ignore\n` : ``} ? ${raw}.value ${operator} ${rExpString} : ${raw}`;3393 }3394 else if (isUpdateArg) {3395 // make id replace parent in the code range so the raw update operator3396 // is removed3397 id.start = parent.start;3398 id.end = parent.end;3399 const { prefix: isPrefix, operator } = parent;3400 const prefix = isPrefix ? operator : ``;3401 const postfix = isPrefix ? `` : operator;3402 // let binding.3403 // x++ --> isRef(a) ? a.value++ : a++3404 return `${context.helperString(IS_REF)}(${raw})${context.isTS ? ` //@ts-ignore\n` : ``} ? ${prefix}${raw}.value${postfix} : ${prefix}${raw}${postfix}`;3405 }3406 else if (isDestructureAssignment) {3407 // TODO3408 // let binding in a destructure assignment - it's very tricky to3409 // handle both possible cases here without altering the original3410 // structure of the code, so we just assume it's not a ref here3411 // for now3412 return raw;3413 }3414 else {3415 return `${context.helperString(UNREF)}(${raw})`;3416 }3417 }3418 else if (type === "props" /* PROPS */) {3419 // use __props which is generated by compileScript so in ts mode3420 // it gets correct type3421 return `__props.${raw}`;3422 }3423 else if (type === "props-aliased" /* PROPS_ALIASED */) {3424 // prop with a different local alias (from defineProps() destructure)3425 return `__props.${bindingMetadata.__propsAliases[raw]}`;3426 }3427 }3428 else {3429 if (type && type.startsWith('setup')) {3430 // setup bindings in non-inline mode3431 return `$setup.${raw}`;3432 }3433 else if (type === "props-aliased" /* PROPS_ALIASED */) {3434 return `$props.${bindingMetadata.__propsAliases[raw]}`;3435 }3436 else if (type) {3437 return `$${type}.${raw}`;3438 }3439 }3440 // fallback to ctx3441 return `_ctx.${raw}`;3442 };3443 // fast path if expression is a simple identifier.3444 const rawExp = node.content;3445 // bail constant on parens (function invocation) and dot (member access)3446 const bailConstant = rawExp.indexOf(`(`) > -1 || rawExp.indexOf('.') > 0;3447 if (isSimpleIdentifier(rawExp)) {3448 const isScopeVarReference = context.identifiers[rawExp];3449 const isAllowedGlobal = shared.isGloballyWhitelisted(rawExp);3450 const isLiteral = isLiteralWhitelisted(rawExp);3451 if (!asParams && !isScopeVarReference && !isAllowedGlobal && !isLiteral) {3452 // const bindings exposed from setup can be skipped for patching but3453 // cannot be hoisted to module scope3454 if (bindingMetadata[node.content] === "setup-const" /* SETUP_CONST */) {3455 node.constType = 1 /* CAN_SKIP_PATCH */;3456 }3457 node.content = rewriteIdentifier(rawExp);3458 }3459 else if (!isScopeVarReference) {3460 if (isLiteral) {3461 node.constType = 3 /* CAN_STRINGIFY */;3462 }3463 else {3464 node.constType = 2 /* CAN_HOIST */;3465 }3466 }3467 return node;3468 }3469 let ast;3470 // exp needs to be parsed differently:3471 // 1. Multiple inline statements (v-on, with presence of `;`): parse as raw3472 // exp, but make sure to pad with spaces for consistent ranges3473 // 2. Expressions: wrap with parens (for e.g. object expressions)3474 // 3. Function arguments (v-for, v-slot): place in a function argument position3475 const source = asRawStatements3476 ? ` ${rawExp} `3477 : `(${rawExp})${asParams ? `=>{}` : ``}`;3478 try {3479 ast = parser.parse(source, {3480 plugins: context.expressionPlugins3481 }).program;3482 }3483 catch (e) {3484 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, e.message));3485 return node;3486 }3487 const ids = [];3488 const parentStack = [];3489 const knownIds = Object.create(context.identifiers);3490 walkIdentifiers(ast, (node, parent, _, isReferenced, isLocal) => {3491 if (isStaticPropertyKey(node, parent)) {3492 return;3493 }3494 // v2 wrapped filter call3495 if (node.name.startsWith('_filter_')) {3496 return;3497 }3498 const needPrefix = isReferenced && canPrefix(node);3499 if (needPrefix && !isLocal) {3500 if (isStaticProperty(parent) && parent.shorthand) {3501 node.prefix = `${node.name}: `;3502 }3503 node.name = rewriteIdentifier(node.name, parent, node);3504 ids.push(node);3505 }3506 else {3507 // The identifier is considered constant unless it's pointing to a3508 // local scope variable (a v-for alias, or a v-slot prop)3509 if (!(needPrefix && isLocal) && !bailConstant) {3510 node.isConstant = true;3511 }3512 // also generate sub-expressions for other identifiers for better3513 // source map support. (except for property keys which are static)3514 ids.push(node);3515 }3516 }, true, // invoke on ALL identifiers3517 parentStack, knownIds);3518 // We break up the compound expression into an array of strings and sub3519 // expressions (for identifiers that have been prefixed). In codegen, if3520 // an ExpressionNode has the `.children` property, it will be used instead of3521 // `.content`.3522 const children = [];3523 ids.sort((a, b) => a.start - b.start);3524 ids.forEach((id, i) => {3525 // range is offset by -1 due to the wrapping parens when parsed3526 const start = id.start - 1;3527 const end = id.end - 1;3528 const last = ids[i - 1];3529 const leadingText = rawExp.slice(last ? last.end - 1 : 0, start);3530 if (leadingText.length || id.prefix) {3531 children.push(leadingText + (id.prefix || ``));3532 }3533 const source = rawExp.slice(start, end);3534 children.push(createSimpleExpression(id.name, false, {3535 source,3536 start: advancePositionWithClone(node.loc.start, source, start),3537 end: advancePositionWithClone(node.loc.start, source, end)3538 }, id.isConstant ? 3 /* CAN_STRINGIFY */ : 0 /* NOT_CONSTANT */));3539 if (i === ids.length - 1 && end < rawExp.length) {3540 children.push(rawExp.slice(end));3541 }3542 });3543 let ret;3544 if (children.length) {3545 ret = createCompoundExpression(children, node.loc);3546 }3547 else {3548 ret = node;3549 ret.constType = bailConstant3550 ? 0 /* NOT_CONSTANT */3551 : 3 /* CAN_STRINGIFY */;3552 }3553 ret.identifiers = Object.keys(knownIds);3554 return ret;3555}3556function canPrefix(id) {3557 // skip whitelisted globals3558 if (shared.isGloballyWhitelisted(id.name)) {3559 return false;3560 }3561 // special case for webpack compilation3562 if (id.name === 'require') {3563 return false;3564 }3565 return true;3566}3567function stringifyExpression(exp) {3568 if (shared.isString(exp)) {3569 return exp;3570 }3571 else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {3572 return exp.content;3573 }3574 else {3575 return exp.children3576 .map(stringifyExpression)3577 .join('');3578 }3579}3580const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3581 return processIf(node, dir, context, (ifNode, branch, isRoot) => {3582 // #1587: We need to dynamically increment the key based on the current3583 // node's sibling nodes, since chained v-if/else branches are3584 // rendered at the same depth3585 const siblings = context.parent.children;3586 let i = siblings.indexOf(ifNode);3587 let key = 0;3588 while (i-- >= 0) {3589 const sibling = siblings[i];3590 if (sibling && sibling.type === 9 /* IF */) {3591 key += sibling.branches.length;3592 }3593 }3594 // Exit callback. Complete the codegenNode when all children have been3595 // transformed.3596 return () => {3597 if (isRoot) {3598 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3599 }3600 else {3601 // attach this branch's codegen node to the v-if root.3602 const parentCondition = getParentCondition(ifNode.codegenNode);3603 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3604 }3605 };3606 });3607});3608// target-agnostic transform used for both Client and SSR3609function processIf(node, dir, context, processCodegen) {3610 if (dir.name !== 'else' &&3611 (!dir.exp || !dir.exp.content.trim())) {3612 const loc = dir.exp ? dir.exp.loc : node.loc;3613 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3614 dir.exp = createSimpleExpression(`true`, false, loc);3615 }3616 if (context.prefixIdentifiers && dir.exp) {3617 // dir.exp can only be simple expression because vIf transform is applied3618 // before expression transform.3619 dir.exp = processExpression(dir.exp, context);3620 }3621 if (dir.name === 'if') {3622 const branch = createIfBranch(node, dir);3623 const ifNode = {3624 type: 9 /* IF */,3625 loc: node.loc,3626 branches: [branch]3627 };3628 context.replaceNode(ifNode);3629 if (processCodegen) {3630 return processCodegen(ifNode, branch, true);3631 }3632 }3633 else {3634 // locate the adjacent v-if3635 const siblings = context.parent.children;3636 const comments = [];3637 let i = siblings.indexOf(node);3638 while (i-- >= -1) {3639 const sibling = siblings[i];3640 if (sibling && sibling.type === 3 /* COMMENT */) {3641 context.removeNode(sibling);3642 comments.unshift(sibling);3643 continue;3644 }3645 if (sibling &&3646 sibling.type === 2 /* TEXT */ &&3647 !sibling.content.trim().length) {3648 context.removeNode(sibling);3649 continue;3650 }3651 if (sibling && sibling.type === 9 /* IF */) {3652 // Check if v-else was followed by v-else-if3653 if (dir.name === 'else-if' &&3654 sibling.branches[sibling.branches.length - 1].condition === undefined) {3655 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3656 }3657 // move the node to the if node's branches3658 context.removeNode();3659 const branch = createIfBranch(node, dir);3660 if (comments.length &&3661 // #3619 ignore comments if the v-if is direct child of <transition>3662 !(context.parent &&3663 context.parent.type === 1 /* ELEMENT */ &&3664 isBuiltInType(context.parent.tag, 'transition'))) {3665 branch.children = [...comments, ...branch.children];3666 }3667 // check if user is forcing same key on different branches3668 {3669 const key = branch.userKey;3670 if (key) {3671 sibling.branches.forEach(({ userKey }) => {3672 if (isSameKey(userKey, key)) {3673 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3674 }3675 });3676 }3677 }3678 sibling.branches.push(branch);3679 const onExit = processCodegen && processCodegen(sibling, branch, false);3680 // since the branch was removed, it will not be traversed.3681 // make sure to traverse here.3682 traverseNode(branch, context);3683 // call on exit3684 if (onExit)3685 onExit();3686 // make sure to reset currentNode after traversal to indicate this3687 // node has been removed.3688 context.currentNode = null;3689 }3690 else {3691 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3692 }3693 break;3694 }3695 }3696}3697function createIfBranch(node, dir) {3698 return {3699 type: 10 /* IF_BRANCH */,3700 loc: node.loc,3701 condition: dir.name === 'else' ? undefined : dir.exp,3702 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3703 ? node.children3704 : [node],3705 userKey: findProp(node, `key`)3706 };3707}3708function createCodegenNodeForBranch(branch, keyIndex, context) {3709 if (branch.condition) {3710 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3711 // make sure to pass in asBlock: true so that the comment node call3712 // closes the current block.3713 createCallExpression(context.helper(CREATE_COMMENT), [3714 '"v-if"' ,3715 'true'3716 ]));3717 }3718 else {3719 return createChildrenCodegenNode(branch, keyIndex, context);3720 }3721}3722function createChildrenCodegenNode(branch, keyIndex, context) {3723 const { helper } = context;3724 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3725 const { children } = branch;3726 const firstChild = children[0];3727 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3728 if (needFragmentWrapper) {3729 if (children.length === 1 && firstChild.type === 11 /* FOR */) {3730 // optimize away nested fragments when child is a ForNode3731 const vnodeCall = firstChild.codegenNode;3732 injectProp(vnodeCall, keyProperty, context);3733 return vnodeCall;3734 }3735 else {3736 let patchFlag = 64 /* STABLE_FRAGMENT */;3737 let patchFlagText = shared.PatchFlagNames[64 /* STABLE_FRAGMENT */];3738 // check if the fragment actually contains a single valid child with3739 // the rest being comments3740 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3741 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3742 patchFlagText += `, ${shared.PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3743 }3744 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);3745 }3746 }3747 else {3748 const ret = firstChild.codegenNode;3749 const vnodeCall = getMemoedVNodeCall(ret);3750 // Change createVNode to createBlock.3751 if (vnodeCall.type === 13 /* VNODE_CALL */) {3752 makeBlock(vnodeCall, context);3753 }3754 // inject branch key3755 injectProp(vnodeCall, keyProperty, context);3756 return ret;3757 }3758}3759function isSameKey(a, b) {3760 if (!a || a.type !== b.type) {3761 return false;3762 }3763 if (a.type === 6 /* ATTRIBUTE */) {3764 if (a.value.content !== b.value.content) {3765 return false;3766 }3767 }3768 else {3769 // directive3770 const exp = a.exp;3771 const branchExp = b.exp;3772 if (exp.type !== branchExp.type) {3773 return false;3774 }3775 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3776 exp.isStatic !== branchExp.isStatic ||3777 exp.content !== branchExp.content) {3778 return false;3779 }3780 }3781 return true;3782}3783function getParentCondition(node) {3784 while (true) {3785 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3786 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3787 node = node.alternate;3788 }3789 else {3790 return node;3791 }3792 }3793 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3794 node = node.value;3795 }3796 }3797}3798const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3799 const { helper, removeHelper } = context;3800 return processFor(node, dir, context, forNode => {3801 // create the loop render function expression now, and add the3802 // iterator on exit after all children have been traversed3803 const renderExp = createCallExpression(helper(RENDER_LIST), [3804 forNode.source3805 ]);3806 const memo = findDir(node, 'memo');3807 const keyProp = findProp(node, `key`);3808 const keyExp = keyProp &&3809 (keyProp.type === 6 /* ATTRIBUTE */3810 ? createSimpleExpression(keyProp.value.content, true)3811 : keyProp.exp);3812 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3813 if (context.prefixIdentifiers &&3814 keyProperty &&3815 keyProp.type !== 6 /* ATTRIBUTE */) {3816 // #2085 process :key expression needs to be processed in order for it3817 // to behave consistently for <template v-for> and <div v-for>.3818 // In the case of `<template v-for>`, the node is discarded and never3819 // traversed so its key expression won't be processed by the normal3820 // transforms.3821 keyProperty.value = processExpression(keyProperty.value, context);3822 }3823 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3824 forNode.source.constType > 0 /* NOT_CONSTANT */;3825 const fragmentFlag = isStableFragment3826 ? 64 /* STABLE_FRAGMENT */3827 : keyProp3828 ? 128 /* KEYED_FRAGMENT */3829 : 256 /* UNKEYED_FRAGMENT */;3830 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3831 (` /* ${shared.PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3832 return () => {3833 // finish the codegen now that all children have been traversed3834 let childBlock;3835 const isTemplate = isTemplateNode(node);3836 const { children } = forNode;3837 // check <template v-for> key placement3838 if (isTemplate) {3839 node.children.some(c => {3840 if (c.type === 1 /* ELEMENT */) {3841 const key = findProp(c, 'key');3842 if (key) {3843 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3844 return true;3845 }3846 }3847 });3848 }3849 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3850 const slotOutlet = isSlotOutlet(node)3851 ? node3852 : isTemplate &&3853 node.children.length === 1 &&3854 isSlotOutlet(node.children[0])3855 ? node.children[0] // api-extractor somehow fails to infer this3856 : null;3857 if (slotOutlet) {3858 // <slot v-for="..."> or <template v-for="..."><slot/></template>3859 childBlock = slotOutlet.codegenNode;3860 if (isTemplate && keyProperty) {3861 // <template v-for="..." :key="..."><slot/></template>3862 // we need to inject the key to the renderSlot() call.3863 // the props for renderSlot is passed as the 3rd argument.3864 injectProp(childBlock, keyProperty, context);3865 }3866 }3867 else if (needFragmentWrapper) {3868 // <template v-for="..."> with text or multi-elements3869 // should generate a fragment block for each loop3870 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3871 (` /* ${shared.PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3872 ), undefined, undefined, true, undefined, false /* isComponent */);3873 }3874 else {3875 // Normal element v-for. Directly use the child's codegenNode3876 // but mark it as a block.3877 childBlock = children[0]3878 .codegenNode;3879 if (isTemplate && keyProperty) {3880 injectProp(childBlock, keyProperty, context);3881 }3882 if (childBlock.isBlock !== !isStableFragment) {3883 if (childBlock.isBlock) {3884 // switch from block to vnode3885 removeHelper(OPEN_BLOCK);3886 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3887 }3888 else {3889 // switch from vnode to block3890 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3891 }3892 }3893 childBlock.isBlock = !isStableFragment;3894 if (childBlock.isBlock) {3895 helper(OPEN_BLOCK);3896 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3897 }3898 else {3899 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3900 }3901 }3902 if (memo) {3903 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3904 createSimpleExpression(`_cached`)3905 ]));3906 loop.body = createBlockStatement([3907 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3908 createCompoundExpression([3909 `if (_cached`,3910 ...(keyExp ? [` && _cached.key === `, keyExp] : []),3911 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3912 ]),3913 createCompoundExpression([`const _item = `, childBlock]),3914 createSimpleExpression(`_item.memo = _memo`),3915 createSimpleExpression(`return _item`)3916 ]);3917 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3918 }3919 else {3920 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3921 }3922 };3923 });3924});3925// target-agnostic transform used for both Client and SSR3926function processFor(node, dir, context, processCodegen) {3927 if (!dir.exp) {3928 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3929 return;3930 }3931 const parseResult = parseForExpression(3932 // can only be simple expression because vFor transform is applied3933 // before expression transform.3934 dir.exp, context);3935 if (!parseResult) {3936 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3937 return;3938 }3939 const { addIdentifiers, removeIdentifiers, scopes } = context;3940 const { source, value, key, index } = parseResult;3941 const forNode = {3942 type: 11 /* FOR */,3943 loc: dir.loc,3944 source,3945 valueAlias: value,3946 keyAlias: key,3947 objectIndexAlias: index,3948 parseResult,3949 children: isTemplateNode(node) ? node.children : [node]3950 };3951 context.replaceNode(forNode);3952 // bookkeeping3953 scopes.vFor++;3954 if (context.prefixIdentifiers) {3955 // scope management3956 // inject identifiers to context3957 value && addIdentifiers(value);3958 key && addIdentifiers(key);3959 index && addIdentifiers(index);3960 }3961 const onExit = processCodegen && processCodegen(forNode);3962 return () => {3963 scopes.vFor--;3964 if (context.prefixIdentifiers) {3965 value && removeIdentifiers(value);3966 key && removeIdentifiers(key);3967 index && removeIdentifiers(index);3968 }3969 if (onExit)3970 onExit();3971 };3972}3973const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3974// This regex doesn't cover the case if key or index aliases have destructuring,3975// but those do not make sense in the first place, so this works in practice.3976const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3977const stripParensRE = /^\(|\)$/g;3978function parseForExpression(input, context) {3979 const loc = input.loc;3980 const exp = input.content;3981 const inMatch = exp.match(forAliasRE);3982 if (!inMatch)3983 return;3984 const [, LHS, RHS] = inMatch;3985 const result = {3986 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3987 value: undefined,3988 key: undefined,3989 index: undefined3990 };3991 if (context.prefixIdentifiers) {3992 result.source = processExpression(result.source, context);3993 }3994 let valueContent = LHS.trim().replace(stripParensRE, '').trim();3995 const trimmedOffset = LHS.indexOf(valueContent);3996 const iteratorMatch = valueContent.match(forIteratorRE);3997 if (iteratorMatch) {3998 valueContent = valueContent.replace(forIteratorRE, '').trim();3999 const keyContent = iteratorMatch[1].trim();4000 let keyOffset;4001 if (keyContent) {4002 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);4003 result.key = createAliasExpression(loc, keyContent, keyOffset);4004 if (context.prefixIdentifiers) {4005 result.key = processExpression(result.key, context, true);4006 }4007 }4008 if (iteratorMatch[2]) {4009 const indexContent = iteratorMatch[2].trim();4010 if (indexContent) {4011 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key4012 ? keyOffset + keyContent.length4013 : trimmedOffset + valueContent.length));4014 if (context.prefixIdentifiers) {4015 result.index = processExpression(result.index, context, true);4016 }4017 }4018 }4019 }4020 if (valueContent) {4021 result.value = createAliasExpression(loc, valueContent, trimmedOffset);4022 if (context.prefixIdentifiers) {4023 result.value = processExpression(result.value, context, true);4024 }4025 }4026 return result;4027}4028function createAliasExpression(range, content, offset) {4029 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));4030}4031function createForLoopParams({ value, key, index }, memoArgs = []) {4032 return createParamsList([value, key, index, ...memoArgs]);4033}4034function createParamsList(args) {4035 let i = args.length;4036 while (i--) {4037 if (args[i])4038 break;4039 }4040 return args4041 .slice(0, i + 1)4042 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));4043}4044const defaultFallback = createSimpleExpression(`undefined`, false);4045// A NodeTransform that:4046// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed4047// by transformExpression. This is only applied in non-browser builds with4048// { prefixIdentifiers: true }.4049// 2. Track v-slot depths so that we know a slot is inside another slot.4050// Note the exit callback is executed before buildSlots() on the same node,4051// so only nested slots see positive numbers.4052const trackSlotScopes = (node, context) => {4053 if (node.type === 1 /* ELEMENT */ &&4054 (node.tagType === 1 /* COMPONENT */ ||4055 node.tagType === 3 /* TEMPLATE */)) {4056 // We are only checking non-empty v-slot here4057 // since we only care about slots that introduce scope variables.4058 const vSlot = findDir(node, 'slot');4059 if (vSlot) {4060 const slotProps = vSlot.exp;4061 if (context.prefixIdentifiers) {4062 slotProps && context.addIdentifiers(slotProps);4063 }4064 context.scopes.vSlot++;4065 return () => {4066 if (context.prefixIdentifiers) {4067 slotProps && context.removeIdentifiers(slotProps);4068 }4069 context.scopes.vSlot--;4070 };4071 }4072 }4073};4074// A NodeTransform that tracks scope identifiers for scoped slots with v-for.4075// This transform is only applied in non-browser builds with { prefixIdentifiers: true }4076const trackVForSlotScopes = (node, context) => {4077 let vFor;4078 if (isTemplateNode(node) &&4079 node.props.some(isVSlot) &&4080 (vFor = findDir(node, 'for'))) {4081 const result = (vFor.parseResult = parseForExpression(vFor.exp, context));4082 if (result) {4083 const { value, key, index } = result;4084 const { addIdentifiers, removeIdentifiers } = context;4085 value && addIdentifiers(value);4086 key && addIdentifiers(key);4087 index && addIdentifiers(index);4088 return () => {4089 value && removeIdentifiers(value);4090 key && removeIdentifiers(key);4091 index && removeIdentifiers(index);4092 };4093 }4094 }4095};4096const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);4097// Instead of being a DirectiveTransform, v-slot processing is called during4098// transformElement to build the slots object for a component.4099function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {4100 context.helper(WITH_CTX);4101 const { children, loc } = node;4102 const slotsProperties = [];4103 const dynamicSlots = [];4104 // If the slot is inside a v-for or another v-slot, force it to be dynamic4105 // since it likely uses a scope variable.4106 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;4107 // with `prefixIdentifiers: true`, this can be further optimized to make4108 // it dynamic only when the slot actually uses the scope variables.4109 if (!context.ssr && context.prefixIdentifiers) {4110 hasDynamicSlots = hasScopeRef(node, context.identifiers);4111 }4112 // 1. Check for slot with slotProps on component itself.4113 // <Comp v-slot="{ prop }"/>4114 const onComponentSlot = findDir(node, 'slot', true);4115 if (onComponentSlot) {4116 const { arg, exp } = onComponentSlot;4117 if (arg && !isStaticExp(arg)) {4118 hasDynamicSlots = true;4119 }4120 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));4121 }4122 // 2. Iterate through children and check for template slots4123 // <template v-slot:foo="{ prop }">4124 let hasTemplateSlots = false;4125 let hasNamedDefaultSlot = false;4126 const implicitDefaultChildren = [];4127 const seenSlotNames = new Set();4128 for (let i = 0; i < children.length; i++) {4129 const slotElement = children[i];4130 let slotDir;4131 if (!isTemplateNode(slotElement) ||4132 !(slotDir = findDir(slotElement, 'slot', true))) {4133 // not a <template v-slot>, skip.4134 if (slotElement.type !== 3 /* COMMENT */) {4135 implicitDefaultChildren.push(slotElement);4136 }4137 continue;4138 }4139 if (onComponentSlot) {4140 // already has on-component slot - this is incorrect usage.4141 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));4142 break;4143 }4144 hasTemplateSlots = true;4145 const { children: slotChildren, loc: slotLoc } = slotElement;4146 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;4147 // check if name is dynamic.4148 let staticSlotName;4149 if (isStaticExp(slotName)) {4150 staticSlotName = slotName ? slotName.content : `default`;4151 }4152 else {4153 hasDynamicSlots = true;4154 }4155 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);4156 // check if this slot is conditional (v-if/v-for)4157 let vIf;4158 let vElse;4159 let vFor;4160 if ((vIf = findDir(slotElement, 'if'))) {4161 hasDynamicSlots = true;4162 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));4163 }4164 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {4165 // find adjacent v-if4166 let j = i;4167 let prev;4168 while (j--) {4169 prev = children[j];4170 if (prev.type !== 3 /* COMMENT */) {4171 break;4172 }4173 }4174 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {4175 // remove node4176 children.splice(i, 1);4177 i--;4178 // attach this slot to previous conditional4179 let conditional = dynamicSlots[dynamicSlots.length - 1];4180 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {4181 conditional = conditional.alternate;4182 }4183 conditional.alternate = vElse.exp4184 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)4185 : buildDynamicSlot(slotName, slotFunction);4186 }4187 else {4188 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));4189 }4190 }4191 else if ((vFor = findDir(slotElement, 'for'))) {4192 hasDynamicSlots = true;4193 const parseResult = vFor.parseResult ||4194 parseForExpression(vFor.exp, context);4195 if (parseResult) {4196 // Render the dynamic slots as an array and add it to the createSlot()4197 // args. The runtime knows how to handle it appropriately.4198 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [4199 parseResult.source,4200 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)4201 ]));4202 }4203 else {4204 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));4205 }4206 }4207 else {4208 // check duplicate static names4209 if (staticSlotName) {4210 if (seenSlotNames.has(staticSlotName)) {4211 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));4212 continue;4213 }4214 seenSlotNames.add(staticSlotName);4215 if (staticSlotName === 'default') {4216 hasNamedDefaultSlot = true;4217 }4218 }4219 slotsProperties.push(createObjectProperty(slotName, slotFunction));4220 }4221 }4222 if (!onComponentSlot) {4223 const buildDefaultSlotProperty = (props, children) => {4224 const fn = buildSlotFn(props, children, loc);4225 if (context.compatConfig) {4226 fn.isNonScopedSlot = true;4227 }4228 return createObjectProperty(`default`, fn);4229 };4230 if (!hasTemplateSlots) {4231 // implicit default slot (on component)4232 slotsProperties.push(buildDefaultSlotProperty(undefined, children));4233 }4234 else if (implicitDefaultChildren.length &&4235 // #37664236 // with whitespace: 'preserve', whitespaces between slots will end up in4237 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.4238 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {4239 // implicit default slot (mixed with named slots)4240 if (hasNamedDefaultSlot) {4241 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));4242 }4243 else {4244 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));4245 }4246 }4247 }4248 const slotFlag = hasDynamicSlots4249 ? 2 /* DYNAMIC */4250 : hasForwardedSlots(node.children)4251 ? 3 /* FORWARDED */4252 : 1 /* STABLE */;4253 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 4254 // 2 = compiled but dynamic = can skip normalization, but must run diff4255 // 1 = compiled and static = can skip normalization AND diff as optimized4256 createSimpleExpression(slotFlag + (` /* ${shared.slotFlagsText[slotFlag]} */` ), false))), loc);4257 if (dynamicSlots.length) {4258 slots = createCallExpression(context.helper(CREATE_SLOTS), [4259 slots,4260 createArrayExpression(dynamicSlots)4261 ]);4262 }4263 return {4264 slots,4265 hasDynamicSlots4266 };4267}4268function buildDynamicSlot(name, fn) {4269 return createObjectExpression([4270 createObjectProperty(`name`, name),4271 createObjectProperty(`fn`, fn)4272 ]);4273}4274function hasForwardedSlots(children) {4275 for (let i = 0; i < children.length; i++) {4276 const child = children[i];4277 switch (child.type) {4278 case 1 /* ELEMENT */:4279 if (child.tagType === 2 /* SLOT */ ||4280 hasForwardedSlots(child.children)) {4281 return true;4282 }4283 break;4284 case 9 /* IF */:4285 if (hasForwardedSlots(child.branches))4286 return true;4287 break;4288 case 10 /* IF_BRANCH */:4289 case 11 /* FOR */:4290 if (hasForwardedSlots(child.children))4291 return true;4292 break;4293 }4294 }4295 return false;4296}4297function isNonWhitespaceContent(node) {4298 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)4299 return true;4300 return node.type === 2 /* TEXT */4301 ? !!node.content.trim()4302 : isNonWhitespaceContent(node.content);4303}4304// some directive transforms (e.g. v-model) may return a symbol for runtime4305// import, which should be used instead of a resolveDirective call.4306const directiveImportMap = new WeakMap();4307// generate a JavaScript AST for this element's codegen4308const transformElement = (node, context) => {4309 // perform the work on exit, after all child expressions have been4310 // processed and merged.4311 return function postTransformElement() {4312 node = context.currentNode;4313 if (!(node.type === 1 /* ELEMENT */ &&4314 (node.tagType === 0 /* ELEMENT */ ||4315 node.tagType === 1 /* COMPONENT */))) {4316 return;4317 }4318 const { tag, props } = node;4319 const isComponent = node.tagType === 1 /* COMPONENT */;4320 // The goal of the transform is to create a codegenNode implementing the4321 // VNodeCall interface.4322 let vnodeTag = isComponent4323 ? resolveComponentType(node, context)4324 : `"${tag}"`;4325 const isDynamicComponent = shared.isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;4326 let vnodeProps;4327 let vnodeChildren;4328 let vnodePatchFlag;4329 let patchFlag = 0;4330 let vnodeDynamicProps;4331 let dynamicPropNames;4332 let vnodeDirectives;4333 let shouldUseBlock = 4334 // dynamic component may resolve to plain elements4335 isDynamicComponent ||4336 vnodeTag === TELEPORT ||4337 vnodeTag === SUSPENSE ||4338 (!isComponent &&4339 // <svg> and <foreignObject> must be forced into blocks so that block4340 // updates inside get proper isSVG flag at runtime. (#639, #643)4341 // This is technically web-specific, but splitting the logic out of core4342 // leads to too much unnecessary complexity.4343 (tag === 'svg' ||4344 tag === 'foreignObject' ||4345 // #938: elements with dynamic keys should be forced into blocks4346 findProp(node, 'key', true)));4347 // props4348 if (props.length > 0) {4349 const propsBuildResult = buildProps(node, context);4350 vnodeProps = propsBuildResult.props;4351 patchFlag = propsBuildResult.patchFlag;4352 dynamicPropNames = propsBuildResult.dynamicPropNames;4353 const directives = propsBuildResult.directives;4354 vnodeDirectives =4355 directives && directives.length4356 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))4357 : undefined;4358 }4359 // children4360 if (node.children.length > 0) {4361 if (vnodeTag === KEEP_ALIVE) {4362 // Although a built-in component, we compile KeepAlive with raw children4363 // instead of slot functions so that it can be used inside Transition4364 // or other Transition-wrapping HOCs.4365 // To ensure correct updates with block optimizations, we need to:4366 // 1. Force keep-alive into a block. This avoids its children being4367 // collected by a parent block.4368 shouldUseBlock = true;4369 // 2. Force keep-alive to always be updated, since it uses raw children.4370 patchFlag |= 1024 /* DYNAMIC_SLOTS */;4371 if (node.children.length > 1) {4372 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {4373 start: node.children[0].loc.start,4374 end: node.children[node.children.length - 1].loc.end,4375 source: ''4376 }));4377 }4378 }4379 const shouldBuildAsSlots = isComponent &&4380 // Teleport is not a real component and has dedicated runtime handling4381 vnodeTag !== TELEPORT &&4382 // explained above.4383 vnodeTag !== KEEP_ALIVE;4384 if (shouldBuildAsSlots) {4385 const { slots, hasDynamicSlots } = buildSlots(node, context);4386 vnodeChildren = slots;4387 if (hasDynamicSlots) {4388 patchFlag |= 1024 /* DYNAMIC_SLOTS */;4389 }4390 }4391 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {4392 const child = node.children[0];4393 const type = child.type;4394 // check for dynamic text children4395 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||4396 type === 8 /* COMPOUND_EXPRESSION */;4397 if (hasDynamicTextChild &&4398 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4399 patchFlag |= 1 /* TEXT */;4400 }4401 // pass directly if the only child is a text node4402 // (plain / interpolation / expression)4403 if (hasDynamicTextChild || type === 2 /* TEXT */) {4404 vnodeChildren = child;4405 }4406 else {4407 vnodeChildren = node.children;4408 }4409 }4410 else {4411 vnodeChildren = node.children;4412 }4413 }4414 // patchFlag & dynamicPropNames4415 if (patchFlag !== 0) {4416 {4417 if (patchFlag < 0) {4418 // special flags (negative and mutually exclusive)4419 vnodePatchFlag = patchFlag + ` /* ${shared.PatchFlagNames[patchFlag]} */`;4420 }4421 else {4422 // bitwise flags4423 const flagNames = Object.keys(shared.PatchFlagNames)4424 .map(Number)4425 .filter(n => n > 0 && patchFlag & n)4426 .map(n => shared.PatchFlagNames[n])4427 .join(`, `);4428 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;4429 }4430 }4431 if (dynamicPropNames && dynamicPropNames.length) {4432 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);4433 }4434 }4435 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);4436 };4437};4438function resolveComponentType(node, context, ssr = false) {4439 let { tag } = node;4440 // 1. dynamic component4441 const isExplicitDynamic = isComponentTag(tag);4442 const isProp = findProp(node, 'is');4443 if (isProp) {4444 if (isExplicitDynamic ||4445 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {4446 const exp = isProp.type === 6 /* ATTRIBUTE */4447 ? isProp.value && createSimpleExpression(isProp.value.content, true)4448 : isProp.exp;4449 if (exp) {4450 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4451 exp4452 ]);4453 }4454 }4455 else if (isProp.type === 6 /* ATTRIBUTE */ &&4456 isProp.value.content.startsWith('vue:')) {4457 // <button is="vue:xxx">4458 // if not <component>, only is value that starts with "vue:" will be4459 // treated as component by the parse phase and reach here, unless it's4460 // compat mode where all is values are considered components4461 tag = isProp.value.content.slice(4);4462 }4463 }4464 // 1.5 v-is (TODO: Deprecate)4465 const isDir = !isExplicitDynamic && findDir(node, 'is');4466 if (isDir && isDir.exp) {4467 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4468 isDir.exp4469 ]);4470 }4471 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)4472 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);4473 if (builtIn) {4474 // built-ins are simply fallthroughs / have special handling during ssr4475 // so we don't need to import their runtime equivalents4476 if (!ssr)4477 context.helper(builtIn);4478 return builtIn;4479 }4480 // 3. user component (from setup bindings)4481 // this is skipped in browser build since browser builds do not perform4482 // binding analysis.4483 {4484 const fromSetup = resolveSetupReference(tag, context);4485 if (fromSetup) {4486 return fromSetup;4487 }4488 const dotIndex = tag.indexOf('.');4489 if (dotIndex > 0) {4490 const ns = resolveSetupReference(tag.slice(0, dotIndex), context);4491 if (ns) {4492 return ns + tag.slice(dotIndex);4493 }4494 }4495 }4496 // 4. Self referencing component (inferred from filename)4497 if (context.selfName &&4498 shared.capitalize(shared.camelize(tag)) === context.selfName) {4499 context.helper(RESOLVE_COMPONENT);4500 // codegen.ts has special check for __self postfix when generating4501 // component imports, which will pass additional `maybeSelfReference` flag4502 // to `resolveComponent`.4503 context.components.add(tag + `__self`);4504 return toValidAssetId(tag, `component`);4505 }4506 // 5. user component (resolve)4507 context.helper(RESOLVE_COMPONENT);4508 context.components.add(tag);4509 return toValidAssetId(tag, `component`);4510}4511function resolveSetupReference(name, context) {4512 const bindings = context.bindingMetadata;4513 if (!bindings || bindings.__isScriptSetup === false) {4514 return;4515 }4516 const camelName = shared.camelize(name);4517 const PascalName = shared.capitalize(camelName);4518 const checkType = (type) => {4519 if (bindings[name] === type) {4520 return name;4521 }4522 if (bindings[camelName] === type) {4523 return camelName;4524 }4525 if (bindings[PascalName] === type) {4526 return PascalName;4527 }4528 };4529 const fromConst = checkType("setup-const" /* SETUP_CONST */);4530 if (fromConst) {4531 return context.inline4532 ? // in inline mode, const setup bindings (e.g. imports) can be used as-is4533 fromConst4534 : `$setup[${JSON.stringify(fromConst)}]`;4535 }4536 const fromMaybeRef = checkType("setup-let" /* SETUP_LET */) ||4537 checkType("setup-ref" /* SETUP_REF */) ||4538 checkType("setup-maybe-ref" /* SETUP_MAYBE_REF */);4539 if (fromMaybeRef) {4540 return context.inline4541 ? // setup scope bindings that may be refs need to be unrefed4542 `${context.helperString(UNREF)}(${fromMaybeRef})`4543 : `$setup[${JSON.stringify(fromMaybeRef)}]`;4544 }4545}4546function buildProps(node, context, props = node.props, ssr = false) {4547 const { tag, loc: elementLoc } = node;4548 const isComponent = node.tagType === 1 /* COMPONENT */;4549 let properties = [];4550 const mergeArgs = [];4551 const runtimeDirectives = [];4552 // patchFlag analysis4553 let patchFlag = 0;4554 let hasRef = false;4555 let hasClassBinding = false;4556 let hasStyleBinding = false;4557 let hasHydrationEventBinding = false;4558 let hasDynamicKeys = false;4559 let hasVnodeHook = false;4560 const dynamicPropNames = [];4561 const analyzePatchFlag = ({ key, value }) => {4562 if (isStaticExp(key)) {4563 const name = key.content;4564 const isEventHandler = shared.isOn(name);4565 if (!isComponent &&4566 isEventHandler &&4567 // omit the flag for click handlers because hydration gives click4568 // dedicated fast path.4569 name.toLowerCase() !== 'onclick' &&4570 // omit v-model handlers4571 name !== 'onUpdate:modelValue' &&4572 // omit onVnodeXXX hooks4573 !shared.isReservedProp(name)) {4574 hasHydrationEventBinding = true;4575 }4576 if (isEventHandler && shared.isReservedProp(name)) {4577 hasVnodeHook = true;4578 }4579 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||4580 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||4581 value.type === 8 /* COMPOUND_EXPRESSION */) &&4582 getConstantType(value, context) > 0)) {4583 // skip if the prop is a cached handler or has constant value4584 return;4585 }4586 if (name === 'ref') {4587 hasRef = true;4588 }4589 else if (name === 'class') {4590 hasClassBinding = true;4591 }4592 else if (name === 'style') {4593 hasStyleBinding = true;4594 }4595 else if (name !== 'key' && !dynamicPropNames.includes(name)) {4596 dynamicPropNames.push(name);4597 }4598 // treat the dynamic class and style binding of the component as dynamic props4599 if (isComponent &&4600 (name === 'class' || name === 'style') &&4601 !dynamicPropNames.includes(name)) {4602 dynamicPropNames.push(name);4603 }4604 }4605 else {4606 hasDynamicKeys = true;4607 }4608 };4609 for (let i = 0; i < props.length; i++) {4610 // static attribute4611 const prop = props[i];4612 if (prop.type === 6 /* ATTRIBUTE */) {4613 const { loc, name, value } = prop;4614 let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);4615 if (name === 'ref') {4616 hasRef = true;4617 // in inline mode there is no setupState object, so we can't use string4618 // keys to set the ref. Instead, we need to transform it to pass the4619 // actual ref instead.4620 if (context.inline && (value === null || value === void 0 ? void 0 : value.content)) {4621 valueNode = createFunctionExpression(['_value', '_refs']);4622 valueNode.body = createBlockStatement(processInlineRef(context, value.content));4623 }4624 }4625 // skip is on <component>, or is="vue:xxx"4626 if (name === 'is' &&4627 (isComponentTag(tag) ||4628 (value && value.content.startsWith('vue:')) ||4629 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4630 continue;4631 }4632 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));4633 }4634 else {4635 // directives4636 const { name, arg, exp, loc } = prop;4637 const isVBind = name === 'bind';4638 const isVOn = name === 'on';4639 // skip v-slot - it is handled by its dedicated transform.4640 if (name === 'slot') {4641 if (!isComponent) {4642 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4643 }4644 continue;4645 }4646 // skip v-once/v-memo - they are handled by dedicated transforms.4647 if (name === 'once' || name === 'memo') {4648 continue;4649 }4650 // skip v-is and :is on <component>4651 if (name === 'is' ||4652 (isVBind &&4653 isBindKey(arg, 'is') &&4654 (isComponentTag(tag) ||4655 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4656 continue;4657 }4658 // skip v-on in SSR compilation4659 if (isVOn && ssr) {4660 continue;4661 }4662 // special case for v-bind and v-on with no argument4663 if (!arg && (isVBind || isVOn)) {4664 hasDynamicKeys = true;4665 if (exp) {4666 if (properties.length) {4667 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4668 properties = [];4669 }4670 if (isVBind) {4671 {4672 // 2.x v-bind object order compat4673 {4674 const hasOverridableKeys = mergeArgs.some(arg => {4675 if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {4676 return arg.properties.some(({ key }) => {4677 if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||4678 !key.isStatic) {4679 return true;4680 }4681 return (key.content !== 'class' &&4682 key.content !== 'style' &&4683 !shared.isOn(key.content));4684 });4685 }4686 else {4687 // dynamic expression4688 return true;4689 }4690 });4691 if (hasOverridableKeys) {4692 checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);4693 }4694 }4695 if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4696 mergeArgs.unshift(exp);4697 continue;4698 }4699 }4700 mergeArgs.push(exp);4701 }4702 else {4703 // v-on="obj" -> toHandlers(obj)4704 mergeArgs.push({4705 type: 14 /* JS_CALL_EXPRESSION */,4706 loc,4707 callee: context.helper(TO_HANDLERS),4708 arguments: [exp]4709 });4710 }4711 }4712 else {4713 context.onError(createCompilerError(isVBind4714 ? 34 /* X_V_BIND_NO_EXPRESSION */4715 : 35 /* X_V_ON_NO_EXPRESSION */, loc));4716 }4717 continue;4718 }4719 const directiveTransform = context.directiveTransforms[name];4720 if (directiveTransform) {4721 // has built-in directive transform.4722 const { props, needRuntime } = directiveTransform(prop, node, context);4723 !ssr && props.forEach(analyzePatchFlag);4724 properties.push(...props);4725 if (needRuntime) {4726 runtimeDirectives.push(prop);4727 if (shared.isSymbol(needRuntime)) {4728 directiveImportMap.set(prop, needRuntime);4729 }4730 }4731 }4732 else {4733 // no built-in transform, this is a user custom directive.4734 runtimeDirectives.push(prop);4735 }4736 }4737 if (prop.type === 6 /* ATTRIBUTE */ &&4738 prop.name === 'ref' &&4739 context.scopes.vFor > 0 &&4740 checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {4741 properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));4742 }4743 }4744 let propsExpression = undefined;4745 // has v-bind="object" or v-on="object", wrap with mergeProps4746 if (mergeArgs.length) {4747 if (properties.length) {4748 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4749 }4750 if (mergeArgs.length > 1) {4751 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4752 }4753 else {4754 // single v-bind with nothing else - no need for a mergeProps call
...
compiler-dom.esm-browser.js
Source:compiler-dom.esm-browser.js
...952 // in v3 mode, only enable if explicitly set to true953 // otherwise enable for any non-false value954 return mode === 3 ? value === true : value !== false;955}956function checkCompatEnabled(key, context, loc, ...args) {957 const enabled = isCompatEnabled(key, context);958 if (enabled) {959 warnDeprecation(key, context, loc, ...args);960 }961 return enabled;962}963function warnDeprecation(key, context, loc, ...args) {964 const val = getCompatValue(key, context);965 if (val === 'suppress-warning') {966 return;967 }968 const { message, link } = deprecationData[key];969 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;970 const err = new SyntaxError(msg);971 err.code = key;972 if (loc)973 err.loc = loc;974 context.onWarn(err);975}976// The default decoder only provides escapes for characters reserved as part of977// the template syntax, and is only used if the custom renderer did not provide978// a platform-specific decoder.979const decodeRE = /&(gt|lt|amp|apos|quot);/g;980const decodeMap = {981 gt: '>',982 lt: '<',983 amp: '&',984 apos: "'",985 quot: '"'986};987const defaultParserOptions = {988 delimiters: [`{{`, `}}`],989 getNamespace: () => 0 /* HTML */,990 getTextMode: () => 0 /* DATA */,991 isVoidTag: NO,992 isPreTag: NO,993 isCustomElement: NO,994 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),995 onError: defaultOnError,996 onWarn: defaultOnWarn,997 comments: true998};999function baseParse(content, options = {}) {1000 const context = createParserContext(content, options);1001 const start = getCursor(context);1002 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));1003}1004function createParserContext(content, rawOptions) {1005 const options = extend({}, defaultParserOptions);1006 let key;1007 for (key in rawOptions) {1008 // @ts-ignore1009 options[key] =1010 rawOptions[key] === undefined1011 ? defaultParserOptions[key]1012 : rawOptions[key];1013 }1014 return {1015 options,1016 column: 1,1017 line: 1,1018 offset: 0,1019 originalSource: content,1020 source: content,1021 inPre: false,1022 inVPre: false,1023 onWarn: options.onWarn1024 };1025}1026function parseChildren(context, mode, ancestors) {1027 const parent = last(ancestors);1028 const ns = parent ? parent.ns : 0 /* HTML */;1029 const nodes = [];1030 while (!isEnd(context, mode, ancestors)) {1031 const s = context.source;1032 let node = undefined;1033 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {1034 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {1035 // '{{'1036 node = parseInterpolation(context, mode);1037 }1038 else if (mode === 0 /* DATA */ && s[0] === '<') {1039 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state1040 if (s.length === 1) {1041 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);1042 }1043 else if (s[1] === '!') {1044 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state1045 if (startsWith(s, '<!--')) {1046 node = parseComment(context);1047 }1048 else if (startsWith(s, '<!DOCTYPE')) {1049 // Ignore DOCTYPE by a limitation.1050 node = parseBogusComment(context);1051 }1052 else if (startsWith(s, '<![CDATA[')) {1053 if (ns !== 0 /* HTML */) {1054 node = parseCDATA(context, ancestors);1055 }1056 else {1057 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);1058 node = parseBogusComment(context);1059 }1060 }1061 else {1062 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);1063 node = parseBogusComment(context);1064 }1065 }1066 else if (s[1] === '/') {1067 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state1068 if (s.length === 2) {1069 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);1070 }1071 else if (s[2] === '>') {1072 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);1073 advanceBy(context, 3);1074 continue;1075 }1076 else if (/[a-z]/i.test(s[2])) {1077 emitError(context, 23 /* X_INVALID_END_TAG */);1078 parseTag(context, 1 /* End */, parent);1079 continue;1080 }1081 else {1082 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);1083 node = parseBogusComment(context);1084 }1085 }1086 else if (/[a-z]/i.test(s[1])) {1087 node = parseElement(context, ancestors);1088 // 2.x <template> with no directive compat1089 if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&1090 node &&1091 node.tag === 'template' &&1092 !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&1093 isSpecialTemplateDirective(p.name))) {1094 warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);1095 node = node.children;1096 }1097 }1098 else if (s[1] === '?') {1099 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);1100 node = parseBogusComment(context);1101 }1102 else {1103 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);1104 }1105 }1106 }1107 if (!node) {1108 node = parseText(context, mode);1109 }1110 if (isArray(node)) {1111 for (let i = 0; i < node.length; i++) {1112 pushNode(nodes, node[i]);1113 }1114 }1115 else {1116 pushNode(nodes, node);1117 }1118 }1119 // Whitespace handling strategy like v21120 let removedWhitespace = false;1121 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {1122 const shouldCondense = context.options.whitespace !== 'preserve';1123 for (let i = 0; i < nodes.length; i++) {1124 const node = nodes[i];1125 if (!context.inPre && node.type === 2 /* TEXT */) {1126 if (!/[^\t\r\n\f ]/.test(node.content)) {1127 const prev = nodes[i - 1];1128 const next = nodes[i + 1];1129 // Remove if:1130 // - the whitespace is the first or last node, or:1131 // - (condense mode) the whitespace is adjacent to a comment, or:1132 // - (condense mode) the whitespace is between two elements AND contains newline1133 if (!prev ||1134 !next ||1135 (shouldCondense &&1136 (prev.type === 3 /* COMMENT */ ||1137 next.type === 3 /* COMMENT */ ||1138 (prev.type === 1 /* ELEMENT */ &&1139 next.type === 1 /* ELEMENT */ &&1140 /[\r\n]/.test(node.content))))) {1141 removedWhitespace = true;1142 nodes[i] = null;1143 }1144 else {1145 // Otherwise, the whitespace is condensed into a single space1146 node.content = ' ';1147 }1148 }1149 else if (shouldCondense) {1150 // in condense mode, consecutive whitespaces in text are condensed1151 // down to a single space.1152 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1153 }1154 }1155 // Remove comment nodes if desired by configuration.1156 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {1157 removedWhitespace = true;1158 nodes[i] = null;1159 }1160 }1161 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1162 // remove leading newline per html spec1163 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1164 const first = nodes[0];1165 if (first && first.type === 2 /* TEXT */) {1166 first.content = first.content.replace(/^\r?\n/, '');1167 }1168 }1169 }1170 return removedWhitespace ? nodes.filter(Boolean) : nodes;1171}1172function pushNode(nodes, node) {1173 if (node.type === 2 /* TEXT */) {1174 const prev = last(nodes);1175 // Merge if both this and the previous node are text and those are1176 // consecutive. This happens for cases like "a < b".1177 if (prev &&1178 prev.type === 2 /* TEXT */ &&1179 prev.loc.end.offset === node.loc.start.offset) {1180 prev.content += node.content;1181 prev.loc.end = node.loc.end;1182 prev.loc.source += node.loc.source;1183 return;1184 }1185 }1186 nodes.push(node);1187}1188function parseCDATA(context, ancestors) {1189 advanceBy(context, 9);1190 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1191 if (context.source.length === 0) {1192 emitError(context, 6 /* EOF_IN_CDATA */);1193 }1194 else {1195 advanceBy(context, 3);1196 }1197 return nodes;1198}1199function parseComment(context) {1200 const start = getCursor(context);1201 let content;1202 // Regular comment.1203 const match = /--(\!)?>/.exec(context.source);1204 if (!match) {1205 content = context.source.slice(4);1206 advanceBy(context, context.source.length);1207 emitError(context, 7 /* EOF_IN_COMMENT */);1208 }1209 else {1210 if (match.index <= 3) {1211 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1212 }1213 if (match[1]) {1214 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1215 }1216 content = context.source.slice(4, match.index);1217 // Advancing with reporting nested comments.1218 const s = context.source.slice(0, match.index);1219 let prevIndex = 1, nestedIndex = 0;1220 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1221 advanceBy(context, nestedIndex - prevIndex + 1);1222 if (nestedIndex + 4 < s.length) {1223 emitError(context, 16 /* NESTED_COMMENT */);1224 }1225 prevIndex = nestedIndex + 1;1226 }1227 advanceBy(context, match.index + match[0].length - prevIndex + 1);1228 }1229 return {1230 type: 3 /* COMMENT */,1231 content,1232 loc: getSelection(context, start)1233 };1234}1235function parseBogusComment(context) {1236 const start = getCursor(context);1237 const contentStart = context.source[1] === '?' ? 1 : 2;1238 let content;1239 const closeIndex = context.source.indexOf('>');1240 if (closeIndex === -1) {1241 content = context.source.slice(contentStart);1242 advanceBy(context, context.source.length);1243 }1244 else {1245 content = context.source.slice(contentStart, closeIndex);1246 advanceBy(context, closeIndex + 1);1247 }1248 return {1249 type: 3 /* COMMENT */,1250 content,1251 loc: getSelection(context, start)1252 };1253}1254function parseElement(context, ancestors) {1255 // Start tag.1256 const wasInPre = context.inPre;1257 const wasInVPre = context.inVPre;1258 const parent = last(ancestors);1259 const element = parseTag(context, 0 /* Start */, parent);1260 const isPreBoundary = context.inPre && !wasInPre;1261 const isVPreBoundary = context.inVPre && !wasInVPre;1262 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1263 // #4030 self-closing <pre> tag1264 if (isPreBoundary) {1265 context.inPre = false;1266 }1267 if (isVPreBoundary) {1268 context.inVPre = false;1269 }1270 return element;1271 }1272 // Children.1273 ancestors.push(element);1274 const mode = context.options.getTextMode(element, parent);1275 const children = parseChildren(context, mode, ancestors);1276 ancestors.pop();1277 // 2.x inline-template compat1278 {1279 const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1280 if (inlineTemplateProp &&1281 checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1282 const loc = getSelection(context, element.loc.end);1283 inlineTemplateProp.value = {1284 type: 2 /* TEXT */,1285 content: loc.source,1286 loc1287 };1288 }1289 }1290 element.children = children;1291 // End tag.1292 if (startsWithEndTagOpen(context.source, element.tag)) {1293 parseTag(context, 1 /* End */, parent);1294 }1295 else {1296 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1297 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1298 const first = children[0];1299 if (first && startsWith(first.loc.source, '<!--')) {1300 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1301 }1302 }1303 }1304 element.loc = getSelection(context, element.loc.start);1305 if (isPreBoundary) {1306 context.inPre = false;1307 }1308 if (isVPreBoundary) {1309 context.inVPre = false;1310 }1311 return element;1312}1313const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);1314function parseTag(context, type, parent) {1315 // Tag open.1316 const start = getCursor(context);1317 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1318 const tag = match[1];1319 const ns = context.options.getNamespace(tag, parent);1320 advanceBy(context, match[0].length);1321 advanceSpaces(context);1322 // save current state in case we need to re-parse attributes with v-pre1323 const cursor = getCursor(context);1324 const currentSource = context.source;1325 // check <pre> tag1326 if (context.options.isPreTag(tag)) {1327 context.inPre = true;1328 }1329 // Attributes.1330 let props = parseAttributes(context, type);1331 // check v-pre1332 if (type === 0 /* Start */ &&1333 !context.inVPre &&1334 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1335 context.inVPre = true;1336 // reset context1337 extend(context, cursor);1338 context.source = currentSource;1339 // re-parse attrs and filter out v-pre itself1340 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1341 }1342 // Tag close.1343 let isSelfClosing = false;1344 if (context.source.length === 0) {1345 emitError(context, 9 /* EOF_IN_TAG */);1346 }1347 else {1348 isSelfClosing = startsWith(context.source, '/>');1349 if (type === 1 /* End */ && isSelfClosing) {1350 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1351 }1352 advanceBy(context, isSelfClosing ? 2 : 1);1353 }1354 if (type === 1 /* End */) {1355 return;1356 }1357 // 2.x deprecation checks1358 if (isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1359 let hasIf = false;1360 let hasFor = false;1361 for (let i = 0; i < props.length; i++) {1362 const p = props[i];1363 if (p.type === 7 /* DIRECTIVE */) {1364 if (p.name === 'if') {1365 hasIf = true;1366 }1367 else if (p.name === 'for') {1368 hasFor = true;1369 }1370 }1371 if (hasIf && hasFor) {1372 warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1373 }1374 }1375 }1376 let tagType = 0 /* ELEMENT */;1377 if (!context.inVPre) {1378 if (tag === 'slot') {1379 tagType = 2 /* SLOT */;1380 }1381 else if (tag === 'template') {1382 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1383 tagType = 3 /* TEMPLATE */;1384 }1385 }1386 else if (isComponent(tag, props, context)) {1387 tagType = 1 /* COMPONENT */;1388 }1389 }1390 return {1391 type: 1 /* ELEMENT */,1392 ns,1393 tag,1394 tagType,1395 props,1396 isSelfClosing,1397 children: [],1398 loc: getSelection(context, start),1399 codegenNode: undefined // to be created during transform phase1400 };1401}1402function isComponent(tag, props, context) {1403 const options = context.options;1404 if (options.isCustomElement(tag)) {1405 return false;1406 }1407 if (tag === 'component' ||1408 /^[A-Z]/.test(tag) ||1409 isCoreComponent(tag) ||1410 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1411 (options.isNativeTag && !options.isNativeTag(tag))) {1412 return true;1413 }1414 // at this point the tag should be a native tag, but check for potential "is"1415 // casting1416 for (let i = 0; i < props.length; i++) {1417 const p = props[i];1418 if (p.type === 6 /* ATTRIBUTE */) {1419 if (p.name === 'is' && p.value) {1420 if (p.value.content.startsWith('vue:')) {1421 return true;1422 }1423 else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1424 return true;1425 }1426 }1427 }1428 else {1429 // directive1430 // v-is (TODO Deprecate)1431 if (p.name === 'is') {1432 return true;1433 }1434 else if (1435 // :is on plain element - only treat as component in compat mode1436 p.name === 'bind' &&1437 isBindKey(p.arg, 'is') &&1438 true &&1439 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1440 return true;1441 }1442 }1443 }1444}1445function parseAttributes(context, type) {1446 const props = [];1447 const attributeNames = new Set();1448 while (context.source.length > 0 &&1449 !startsWith(context.source, '>') &&1450 !startsWith(context.source, '/>')) {1451 if (startsWith(context.source, '/')) {1452 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1453 advanceBy(context, 1);1454 advanceSpaces(context);1455 continue;1456 }1457 if (type === 1 /* End */) {1458 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1459 }1460 const attr = parseAttribute(context, attributeNames);1461 // Trim whitespace between class1462 // https://github.com/vuejs/vue-next/issues/42511463 if (attr.type === 6 /* ATTRIBUTE */ &&1464 attr.value &&1465 attr.name === 'class') {1466 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1467 }1468 if (type === 0 /* Start */) {1469 props.push(attr);1470 }1471 if (/^[^\t\r\n\f />]/.test(context.source)) {1472 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1473 }1474 advanceSpaces(context);1475 }1476 return props;1477}1478function parseAttribute(context, nameSet) {1479 // Name.1480 const start = getCursor(context);1481 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1482 const name = match[0];1483 if (nameSet.has(name)) {1484 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1485 }1486 nameSet.add(name);1487 if (name[0] === '=') {1488 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1489 }1490 {1491 const pattern = /["'<]/g;1492 let m;1493 while ((m = pattern.exec(name))) {1494 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1495 }1496 }1497 advanceBy(context, name.length);1498 // Value1499 let value = undefined;1500 if (/^[\t\r\n\f ]*=/.test(context.source)) {1501 advanceSpaces(context);1502 advanceBy(context, 1);1503 advanceSpaces(context);1504 value = parseAttributeValue(context);1505 if (!value) {1506 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1507 }1508 }1509 const loc = getSelection(context, start);1510 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1511 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1512 let isPropShorthand = startsWith(name, '.');1513 let dirName = match[1] ||1514 (isPropShorthand || startsWith(name, ':')1515 ? 'bind'1516 : startsWith(name, '@')1517 ? 'on'1518 : 'slot');1519 let arg;1520 if (match[2]) {1521 const isSlot = dirName === 'slot';1522 const startOffset = name.lastIndexOf(match[2]);1523 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1524 let content = match[2];1525 let isStatic = true;1526 if (content.startsWith('[')) {1527 isStatic = false;1528 if (!content.endsWith(']')) {1529 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1530 content = content.slice(1);1531 }1532 else {1533 content = content.slice(1, content.length - 1);1534 }1535 }1536 else if (isSlot) {1537 // #1241 special case for v-slot: vuetify relies extensively on slot1538 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1539 // supports such usage so we are keeping it consistent with 2.x.1540 content += match[3] || '';1541 }1542 arg = {1543 type: 4 /* SIMPLE_EXPRESSION */,1544 content,1545 isStatic,1546 constType: isStatic1547 ? 3 /* CAN_STRINGIFY */1548 : 0 /* NOT_CONSTANT */,1549 loc1550 };1551 }1552 if (value && value.isQuoted) {1553 const valueLoc = value.loc;1554 valueLoc.start.offset++;1555 valueLoc.start.column++;1556 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1557 valueLoc.source = valueLoc.source.slice(1, -1);1558 }1559 const modifiers = match[3] ? match[3].slice(1).split('.') : [];1560 if (isPropShorthand)1561 modifiers.push('prop');1562 // 2.x compat v-bind:foo.sync -> v-model:foo1563 if (dirName === 'bind' && arg) {1564 if (modifiers.includes('sync') &&1565 checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1566 dirName = 'model';1567 modifiers.splice(modifiers.indexOf('sync'), 1);1568 }1569 if (modifiers.includes('prop')) {1570 checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1571 }1572 }1573 return {1574 type: 7 /* DIRECTIVE */,1575 name: dirName,1576 exp: value && {1577 type: 4 /* SIMPLE_EXPRESSION */,1578 content: value.content,1579 isStatic: false,1580 // Treat as non-constant by default. This can be potentially set to1581 // other values by `transformExpression` to make it eligible for hoisting.1582 constType: 0 /* NOT_CONSTANT */,1583 loc: value.loc1584 },1585 arg,1586 modifiers,1587 loc1588 };1589 }1590 // missing directive name or illegal directive name1591 if (!context.inVPre && startsWith(name, 'v-')) {1592 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1593 }1594 return {1595 type: 6 /* ATTRIBUTE */,1596 name,1597 value: value && {1598 type: 2 /* TEXT */,1599 content: value.content,1600 loc: value.loc1601 },1602 loc1603 };1604}1605function parseAttributeValue(context) {1606 const start = getCursor(context);1607 let content;1608 const quote = context.source[0];1609 const isQuoted = quote === `"` || quote === `'`;1610 if (isQuoted) {1611 // Quoted value.1612 advanceBy(context, 1);1613 const endIndex = context.source.indexOf(quote);1614 if (endIndex === -1) {1615 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1616 }1617 else {1618 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1619 advanceBy(context, 1);1620 }1621 }1622 else {1623 // Unquoted1624 const match = /^[^\t\r\n\f >]+/.exec(context.source);1625 if (!match) {1626 return undefined;1627 }1628 const unexpectedChars = /["'<=`]/g;1629 let m;1630 while ((m = unexpectedChars.exec(match[0]))) {1631 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1632 }1633 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1634 }1635 return { content, isQuoted, loc: getSelection(context, start) };1636}1637function parseInterpolation(context, mode) {1638 const [open, close] = context.options.delimiters;1639 const closeIndex = context.source.indexOf(close, open.length);1640 if (closeIndex === -1) {1641 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1642 return undefined;1643 }1644 const start = getCursor(context);1645 advanceBy(context, open.length);1646 const innerStart = getCursor(context);1647 const innerEnd = getCursor(context);1648 const rawContentLength = closeIndex - open.length;1649 const rawContent = context.source.slice(0, rawContentLength);1650 const preTrimContent = parseTextData(context, rawContentLength, mode);1651 const content = preTrimContent.trim();1652 const startOffset = preTrimContent.indexOf(content);1653 if (startOffset > 0) {1654 advancePositionWithMutation(innerStart, rawContent, startOffset);1655 }1656 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1657 advancePositionWithMutation(innerEnd, rawContent, endOffset);1658 advanceBy(context, close.length);1659 return {1660 type: 5 /* INTERPOLATION */,1661 content: {1662 type: 4 /* SIMPLE_EXPRESSION */,1663 isStatic: false,1664 // Set `isConstant` to false by default and will decide in transformExpression1665 constType: 0 /* NOT_CONSTANT */,1666 content,1667 loc: getSelection(context, innerStart, innerEnd)1668 },1669 loc: getSelection(context, start)1670 };1671}1672function parseText(context, mode) {1673 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1674 let endIndex = context.source.length;1675 for (let i = 0; i < endTokens.length; i++) {1676 const index = context.source.indexOf(endTokens[i], 1);1677 if (index !== -1 && endIndex > index) {1678 endIndex = index;1679 }1680 }1681 const start = getCursor(context);1682 const content = parseTextData(context, endIndex, mode);1683 return {1684 type: 2 /* TEXT */,1685 content,1686 loc: getSelection(context, start)1687 };1688}1689/**1690 * Get text data with a given length from the current location.1691 * This translates HTML entities in the text data.1692 */1693function parseTextData(context, length, mode) {1694 const rawText = context.source.slice(0, length);1695 advanceBy(context, length);1696 if (mode === 2 /* RAWTEXT */ ||1697 mode === 3 /* CDATA */ ||1698 rawText.indexOf('&') === -1) {1699 return rawText;1700 }1701 else {1702 // DATA or RCDATA containing "&"". Entity decoding required.1703 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1704 }1705}1706function getCursor(context) {1707 const { column, line, offset } = context;1708 return { column, line, offset };1709}1710function getSelection(context, start, end) {1711 end = end || getCursor(context);1712 return {1713 start,1714 end,1715 source: context.originalSource.slice(start.offset, end.offset)1716 };1717}1718function last(xs) {1719 return xs[xs.length - 1];1720}1721function startsWith(source, searchString) {1722 return source.startsWith(searchString);1723}1724function advanceBy(context, numberOfCharacters) {1725 const { source } = context;1726 advancePositionWithMutation(context, source, numberOfCharacters);1727 context.source = source.slice(numberOfCharacters);1728}1729function advanceSpaces(context) {1730 const match = /^[\t\r\n\f ]+/.exec(context.source);1731 if (match) {1732 advanceBy(context, match[0].length);1733 }1734}1735function getNewPosition(context, start, numberOfCharacters) {1736 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1737}1738function emitError(context, code, offset, loc = getCursor(context)) {1739 if (offset) {1740 loc.offset += offset;1741 loc.column += offset;1742 }1743 context.options.onError(createCompilerError(code, {1744 start: loc,1745 end: loc,1746 source: ''1747 }));1748}1749function isEnd(context, mode, ancestors) {1750 const s = context.source;1751 switch (mode) {1752 case 0 /* DATA */:1753 if (startsWith(s, '</')) {1754 // TODO: probably bad performance1755 for (let i = ancestors.length - 1; i >= 0; --i) {1756 if (startsWithEndTagOpen(s, ancestors[i].tag)) {1757 return true;1758 }1759 }1760 }1761 break;1762 case 1 /* RCDATA */:1763 case 2 /* RAWTEXT */: {1764 const parent = last(ancestors);1765 if (parent && startsWithEndTagOpen(s, parent.tag)) {1766 return true;1767 }1768 break;1769 }1770 case 3 /* CDATA */:1771 if (startsWith(s, ']]>')) {1772 return true;1773 }1774 break;1775 }1776 return !s;1777}1778function startsWithEndTagOpen(source, tag) {1779 return (startsWith(source, '</') &&1780 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1781 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1782}1783function hoistStatic(root, context) {1784 walk(root, context, 1785 // Root node is unfortunately non-hoistable due to potential parent1786 // fallthrough attributes.1787 isSingleElementRoot(root, root.children[0]));1788}1789function isSingleElementRoot(root, child) {1790 const { children } = root;1791 return (children.length === 1 &&1792 child.type === 1 /* ELEMENT */ &&1793 !isSlotOutlet(child));1794}1795function walk(node, context, doNotHoistNode = false) {1796 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces1797 // static bindings with expressions. These expressions are guaranteed to be1798 // constant so they are still eligible for hoisting, but they are only1799 // available at runtime and therefore cannot be evaluated ahead of time.1800 // This is only a concern for pre-stringification (via transformHoist by1801 // @vue/compiler-dom), but doing it here allows us to perform only one full1802 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its1803 // stringification threshold is met.1804 let canStringify = true;1805 const { children } = node;1806 const originalCount = children.length;1807 let hoistedCount = 0;1808 for (let i = 0; i < children.length; i++) {1809 const child = children[i];1810 // only plain elements & text calls are eligible for hoisting.1811 if (child.type === 1 /* ELEMENT */ &&1812 child.tagType === 0 /* ELEMENT */) {1813 const constantType = doNotHoistNode1814 ? 0 /* NOT_CONSTANT */1815 : getConstantType(child, context);1816 if (constantType > 0 /* NOT_CONSTANT */) {1817 if (constantType < 3 /* CAN_STRINGIFY */) {1818 canStringify = false;1819 }1820 if (constantType >= 2 /* CAN_HOIST */) {1821 child.codegenNode.patchFlag =1822 -1 /* HOISTED */ + (` /* HOISTED */` );1823 child.codegenNode = context.hoist(child.codegenNode);1824 hoistedCount++;1825 continue;1826 }1827 }1828 else {1829 // node may contain dynamic children, but its props may be eligible for1830 // hoisting.1831 const codegenNode = child.codegenNode;1832 if (codegenNode.type === 13 /* VNODE_CALL */) {1833 const flag = getPatchFlag(codegenNode);1834 if ((!flag ||1835 flag === 512 /* NEED_PATCH */ ||1836 flag === 1 /* TEXT */) &&1837 getGeneratedPropsConstantType(child, context) >=1838 2 /* CAN_HOIST */) {1839 const props = getNodeProps(child);1840 if (props) {1841 codegenNode.props = context.hoist(props);1842 }1843 }1844 if (codegenNode.dynamicProps) {1845 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1846 }1847 }1848 }1849 }1850 else if (child.type === 12 /* TEXT_CALL */) {1851 const contentType = getConstantType(child.content, context);1852 if (contentType > 0) {1853 if (contentType < 3 /* CAN_STRINGIFY */) {1854 canStringify = false;1855 }1856 if (contentType >= 2 /* CAN_HOIST */) {1857 child.codegenNode = context.hoist(child.codegenNode);1858 hoistedCount++;1859 }1860 }1861 }1862 // walk further1863 if (child.type === 1 /* ELEMENT */) {1864 const isComponent = child.tagType === 1 /* COMPONENT */;1865 if (isComponent) {1866 context.scopes.vSlot++;1867 }1868 walk(child, context);1869 if (isComponent) {1870 context.scopes.vSlot--;1871 }1872 }1873 else if (child.type === 11 /* FOR */) {1874 // Do not hoist v-for single child because it has to be a block1875 walk(child, context, child.children.length === 1);1876 }1877 else if (child.type === 9 /* IF */) {1878 for (let i = 0; i < child.branches.length; i++) {1879 // Do not hoist v-if single child because it has to be a block1880 walk(child.branches[i], context, child.branches[i].children.length === 1);1881 }1882 }1883 }1884 if (canStringify && hoistedCount && context.transformHoist) {1885 context.transformHoist(children, context, node);1886 }1887 // all children were hoisted - the entire children array is hoistable.1888 if (hoistedCount &&1889 hoistedCount === originalCount &&1890 node.type === 1 /* ELEMENT */ &&1891 node.tagType === 0 /* ELEMENT */ &&1892 node.codegenNode &&1893 node.codegenNode.type === 13 /* VNODE_CALL */ &&1894 isArray(node.codegenNode.children)) {1895 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1896 }1897}1898function getConstantType(node, context) {1899 const { constantCache } = context;1900 switch (node.type) {1901 case 1 /* ELEMENT */:1902 if (node.tagType !== 0 /* ELEMENT */) {1903 return 0 /* NOT_CONSTANT */;1904 }1905 const cached = constantCache.get(node);1906 if (cached !== undefined) {1907 return cached;1908 }1909 const codegenNode = node.codegenNode;1910 if (codegenNode.type !== 13 /* VNODE_CALL */) {1911 return 0 /* NOT_CONSTANT */;1912 }1913 const flag = getPatchFlag(codegenNode);1914 if (!flag) {1915 let returnType = 3 /* CAN_STRINGIFY */;1916 // Element itself has no patch flag. However we still need to check:1917 // 1. Even for a node with no patch flag, it is possible for it to contain1918 // non-hoistable expressions that refers to scope variables, e.g. compiler1919 // injected keys or cached event handlers. Therefore we need to always1920 // check the codegenNode's props to be sure.1921 const generatedPropsType = getGeneratedPropsConstantType(node, context);1922 if (generatedPropsType === 0 /* NOT_CONSTANT */) {1923 constantCache.set(node, 0 /* NOT_CONSTANT */);1924 return 0 /* NOT_CONSTANT */;1925 }1926 if (generatedPropsType < returnType) {1927 returnType = generatedPropsType;1928 }1929 // 2. its children.1930 for (let i = 0; i < node.children.length; i++) {1931 const childType = getConstantType(node.children[i], context);1932 if (childType === 0 /* NOT_CONSTANT */) {1933 constantCache.set(node, 0 /* NOT_CONSTANT */);1934 return 0 /* NOT_CONSTANT */;1935 }1936 if (childType < returnType) {1937 returnType = childType;1938 }1939 }1940 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01941 // type, check if any of the props can cause the type to be lowered1942 // we can skip can_patch because it's guaranteed by the absence of a1943 // patchFlag.1944 if (returnType > 1 /* CAN_SKIP_PATCH */) {1945 for (let i = 0; i < node.props.length; i++) {1946 const p = node.props[i];1947 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1948 const expType = getConstantType(p.exp, context);1949 if (expType === 0 /* NOT_CONSTANT */) {1950 constantCache.set(node, 0 /* NOT_CONSTANT */);1951 return 0 /* NOT_CONSTANT */;1952 }1953 if (expType < returnType) {1954 returnType = expType;1955 }1956 }1957 }1958 }1959 // only svg/foreignObject could be block here, however if they are1960 // static then they don't need to be blocks since there will be no1961 // nested updates.1962 if (codegenNode.isBlock) {1963 context.removeHelper(OPEN_BLOCK);1964 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1965 codegenNode.isBlock = false;1966 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1967 }1968 constantCache.set(node, returnType);1969 return returnType;1970 }1971 else {1972 constantCache.set(node, 0 /* NOT_CONSTANT */);1973 return 0 /* NOT_CONSTANT */;1974 }1975 case 2 /* TEXT */:1976 case 3 /* COMMENT */:1977 return 3 /* CAN_STRINGIFY */;1978 case 9 /* IF */:1979 case 11 /* FOR */:1980 case 10 /* IF_BRANCH */:1981 return 0 /* NOT_CONSTANT */;1982 case 5 /* INTERPOLATION */:1983 case 12 /* TEXT_CALL */:1984 return getConstantType(node.content, context);1985 case 4 /* SIMPLE_EXPRESSION */:1986 return node.constType;1987 case 8 /* COMPOUND_EXPRESSION */:1988 let returnType = 3 /* CAN_STRINGIFY */;1989 for (let i = 0; i < node.children.length; i++) {1990 const child = node.children[i];1991 if (isString(child) || isSymbol(child)) {1992 continue;1993 }1994 const childType = getConstantType(child, context);1995 if (childType === 0 /* NOT_CONSTANT */) {1996 return 0 /* NOT_CONSTANT */;1997 }1998 else if (childType < returnType) {1999 returnType = childType;2000 }2001 }2002 return returnType;2003 default:2004 return 0 /* NOT_CONSTANT */;2005 }2006}2007const allowHoistedHelperSet = new Set([2008 NORMALIZE_CLASS,2009 NORMALIZE_STYLE,2010 NORMALIZE_PROPS,2011 GUARD_REACTIVE_PROPS2012]);2013function getConstantTypeOfHelperCall(value, context) {2014 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&2015 !isString(value.callee) &&2016 allowHoistedHelperSet.has(value.callee)) {2017 const arg = value.arguments[0];2018 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {2019 return getConstantType(arg, context);2020 }2021 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {2022 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`2023 return getConstantTypeOfHelperCall(arg, context);2024 }2025 }2026 return 0 /* NOT_CONSTANT */;2027}2028function getGeneratedPropsConstantType(node, context) {2029 let returnType = 3 /* CAN_STRINGIFY */;2030 const props = getNodeProps(node);2031 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {2032 const { properties } = props;2033 for (let i = 0; i < properties.length; i++) {2034 const { key, value } = properties[i];2035 const keyType = getConstantType(key, context);2036 if (keyType === 0 /* NOT_CONSTANT */) {2037 return keyType;2038 }2039 if (keyType < returnType) {2040 returnType = keyType;2041 }2042 let valueType;2043 if (value.type === 4 /* SIMPLE_EXPRESSION */) {2044 valueType = getConstantType(value, context);2045 }2046 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {2047 // some helper calls can be hoisted,2048 // such as the `normalizeProps` generated by the compiler for pre-normalize class,2049 // in this case we need to respect the ConstantType of the helper's argments2050 valueType = getConstantTypeOfHelperCall(value, context);2051 }2052 else {2053 valueType = 0 /* NOT_CONSTANT */;2054 }2055 if (valueType === 0 /* NOT_CONSTANT */) {2056 return valueType;2057 }2058 if (valueType < returnType) {2059 returnType = valueType;2060 }2061 }2062 }2063 return returnType;2064}2065function getNodeProps(node) {2066 const codegenNode = node.codegenNode;2067 if (codegenNode.type === 13 /* VNODE_CALL */) {2068 return codegenNode.props;2069 }2070}2071function getPatchFlag(node) {2072 const flag = node.patchFlag;2073 return flag ? parseInt(flag, 10) : undefined;2074}2075function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {2076 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);2077 const context = {2078 // options2079 selfName: nameMatch && capitalize(camelize(nameMatch[1])),2080 prefixIdentifiers,2081 hoistStatic,2082 cacheHandlers,2083 nodeTransforms,2084 directiveTransforms,2085 transformHoist,2086 isBuiltInComponent,2087 isCustomElement,2088 expressionPlugins,2089 scopeId,2090 slotted,2091 ssr,2092 inSSR,2093 ssrCssVars,2094 bindingMetadata,2095 inline,2096 isTS,2097 onError,2098 onWarn,2099 compatConfig,2100 // state2101 root,2102 helpers: new Map(),2103 components: new Set(),2104 directives: new Set(),2105 hoists: [],2106 imports: [],2107 constantCache: new Map(),2108 temps: 0,2109 cached: 0,2110 identifiers: Object.create(null),2111 scopes: {2112 vFor: 0,2113 vSlot: 0,2114 vPre: 0,2115 vOnce: 02116 },2117 parent: null,2118 currentNode: root,2119 childIndex: 0,2120 inVOnce: false,2121 // methods2122 helper(name) {2123 const count = context.helpers.get(name) || 0;2124 context.helpers.set(name, count + 1);2125 return name;2126 },2127 removeHelper(name) {2128 const count = context.helpers.get(name);2129 if (count) {2130 const currentCount = count - 1;2131 if (!currentCount) {2132 context.helpers.delete(name);2133 }2134 else {2135 context.helpers.set(name, currentCount);2136 }2137 }2138 },2139 helperString(name) {2140 return `_${helperNameMap[context.helper(name)]}`;2141 },2142 replaceNode(node) {2143 /* istanbul ignore if */2144 {2145 if (!context.currentNode) {2146 throw new Error(`Node being replaced is already removed.`);2147 }2148 if (!context.parent) {2149 throw new Error(`Cannot replace root node.`);2150 }2151 }2152 context.parent.children[context.childIndex] = context.currentNode = node;2153 },2154 removeNode(node) {2155 if (!context.parent) {2156 throw new Error(`Cannot remove root node.`);2157 }2158 const list = context.parent.children;2159 const removalIndex = node2160 ? list.indexOf(node)2161 : context.currentNode2162 ? context.childIndex2163 : -1;2164 /* istanbul ignore if */2165 if (removalIndex < 0) {2166 throw new Error(`node being removed is not a child of current parent`);2167 }2168 if (!node || node === context.currentNode) {2169 // current node removed2170 context.currentNode = null;2171 context.onNodeRemoved();2172 }2173 else {2174 // sibling node removed2175 if (context.childIndex > removalIndex) {2176 context.childIndex--;2177 context.onNodeRemoved();2178 }2179 }2180 context.parent.children.splice(removalIndex, 1);2181 },2182 onNodeRemoved: () => { },2183 addIdentifiers(exp) {2184 },2185 removeIdentifiers(exp) {2186 },2187 hoist(exp) {2188 if (isString(exp))2189 exp = createSimpleExpression(exp);2190 context.hoists.push(exp);2191 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2192 identifier.hoisted = exp;2193 return identifier;2194 },2195 cache(exp, isVNode = false) {2196 return createCacheExpression(context.cached++, exp, isVNode);2197 }2198 };2199 {2200 context.filters = new Set();2201 }2202 return context;2203}2204function transform(root, options) {2205 const context = createTransformContext(root, options);2206 traverseNode(root, context);2207 if (options.hoistStatic) {2208 hoistStatic(root, context);2209 }2210 if (!options.ssr) {2211 createRootCodegen(root, context);2212 }2213 // finalize meta information2214 root.helpers = [...context.helpers.keys()];2215 root.components = [...context.components];2216 root.directives = [...context.directives];2217 root.imports = context.imports;2218 root.hoists = context.hoists;2219 root.temps = context.temps;2220 root.cached = context.cached;2221 {2222 root.filters = [...context.filters];2223 }2224}2225function createRootCodegen(root, context) {2226 const { helper } = context;2227 const { children } = root;2228 if (children.length === 1) {2229 const child = children[0];2230 // if the single child is an element, turn it into a block.2231 if (isSingleElementRoot(root, child) && child.codegenNode) {2232 // single element root is never hoisted so codegenNode will never be2233 // SimpleExpressionNode2234 const codegenNode = child.codegenNode;2235 if (codegenNode.type === 13 /* VNODE_CALL */) {2236 makeBlock(codegenNode, context);2237 }2238 root.codegenNode = codegenNode;2239 }2240 else {2241 // - single <slot/>, IfNode, ForNode: already blocks.2242 // - single text node: always patched.2243 // root codegen falls through via genNode()2244 root.codegenNode = child;2245 }2246 }2247 else if (children.length > 1) {2248 // root has multiple nodes - return a fragment block.2249 let patchFlag = 64 /* STABLE_FRAGMENT */;2250 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];2251 // check if the fragment actually contains a single valid child with2252 // the rest being comments2253 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2254 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2255 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2256 }2257 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);2258 }2259 else ;2260}2261function traverseChildren(parent, context) {2262 let i = 0;2263 const nodeRemoved = () => {2264 i--;2265 };2266 for (; i < parent.children.length; i++) {2267 const child = parent.children[i];2268 if (isString(child))2269 continue;2270 context.parent = parent;2271 context.childIndex = i;2272 context.onNodeRemoved = nodeRemoved;2273 traverseNode(child, context);2274 }2275}2276function traverseNode(node, context) {2277 context.currentNode = node;2278 // apply transform plugins2279 const { nodeTransforms } = context;2280 const exitFns = [];2281 for (let i = 0; i < nodeTransforms.length; i++) {2282 const onExit = nodeTransforms[i](node, context);2283 if (onExit) {2284 if (isArray(onExit)) {2285 exitFns.push(...onExit);2286 }2287 else {2288 exitFns.push(onExit);2289 }2290 }2291 if (!context.currentNode) {2292 // node was removed2293 return;2294 }2295 else {2296 // node may have been replaced2297 node = context.currentNode;2298 }2299 }2300 switch (node.type) {2301 case 3 /* COMMENT */:2302 if (!context.ssr) {2303 // inject import for the Comment symbol, which is needed for creating2304 // comment nodes with `createVNode`2305 context.helper(CREATE_COMMENT);2306 }2307 break;2308 case 5 /* INTERPOLATION */:2309 // no need to traverse, but we need to inject toString helper2310 if (!context.ssr) {2311 context.helper(TO_DISPLAY_STRING);2312 }2313 break;2314 // for container types, further traverse downwards2315 case 9 /* IF */:2316 for (let i = 0; i < node.branches.length; i++) {2317 traverseNode(node.branches[i], context);2318 }2319 break;2320 case 10 /* IF_BRANCH */:2321 case 11 /* FOR */:2322 case 1 /* ELEMENT */:2323 case 0 /* ROOT */:2324 traverseChildren(node, context);2325 break;2326 }2327 // exit transforms2328 context.currentNode = node;2329 let i = exitFns.length;2330 while (i--) {2331 exitFns[i]();2332 }2333}2334function createStructuralDirectiveTransform(name, fn) {2335 const matches = isString(name)2336 ? (n) => n === name2337 : (n) => name.test(n);2338 return (node, context) => {2339 if (node.type === 1 /* ELEMENT */) {2340 const { props } = node;2341 // structural directive transforms are not concerned with slots2342 // as they are handled separately in vSlot.ts2343 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2344 return;2345 }2346 const exitFns = [];2347 for (let i = 0; i < props.length; i++) {2348 const prop = props[i];2349 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2350 // structural directives are removed to avoid infinite recursion2351 // also we remove them *before* applying so that it can further2352 // traverse itself in case it moves the node around2353 props.splice(i, 1);2354 i--;2355 const onExit = fn(node, prop, context);2356 if (onExit)2357 exitFns.push(onExit);2358 }2359 }2360 return exitFns;2361 }2362 };2363}2364const PURE_ANNOTATION = `/*#__PURE__*/`;2365function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {2366 const context = {2367 mode,2368 prefixIdentifiers,2369 sourceMap,2370 filename,2371 scopeId,2372 optimizeImports,2373 runtimeGlobalName,2374 runtimeModuleName,2375 ssrRuntimeModuleName,2376 ssr,2377 isTS,2378 inSSR,2379 source: ast.loc.source,2380 code: ``,2381 column: 1,2382 line: 1,2383 offset: 0,2384 indentLevel: 0,2385 pure: false,2386 map: undefined,2387 helper(key) {2388 return `_${helperNameMap[key]}`;2389 },2390 push(code, node) {2391 context.code += code;2392 },2393 indent() {2394 newline(++context.indentLevel);2395 },2396 deindent(withoutNewLine = false) {2397 if (withoutNewLine) {2398 --context.indentLevel;2399 }2400 else {2401 newline(--context.indentLevel);2402 }2403 },2404 newline() {2405 newline(context.indentLevel);2406 }2407 };2408 function newline(n) {2409 context.push('\n' + ` `.repeat(n));2410 }2411 return context;2412}2413function generate(ast, options = {}) {2414 const context = createCodegenContext(ast, options);2415 if (options.onContextCreated)2416 options.onContextCreated(context);2417 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2418 const hasHelpers = ast.helpers.length > 0;2419 const useWithBlock = !prefixIdentifiers && mode !== 'module';2420 // preambles2421 // in setup() inline mode, the preamble is generated in a sub context2422 // and returned separately.2423 const preambleContext = context;2424 {2425 genFunctionPreamble(ast, preambleContext);2426 }2427 // enter render function2428 const functionName = ssr ? `ssrRender` : `render`;2429 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2430 const signature = args.join(', ');2431 {2432 push(`function ${functionName}(${signature}) {`);2433 }2434 indent();2435 if (useWithBlock) {2436 push(`with (_ctx) {`);2437 indent();2438 // function mode const declarations should be inside with block2439 // also they should be renamed to avoid collision with user properties2440 if (hasHelpers) {2441 push(`const { ${ast.helpers2442 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2443 .join(', ')} } = _Vue`);2444 push(`\n`);2445 newline();2446 }2447 }2448 // generate asset resolution statements2449 if (ast.components.length) {2450 genAssets(ast.components, 'component', context);2451 if (ast.directives.length || ast.temps > 0) {2452 newline();2453 }2454 }2455 if (ast.directives.length) {2456 genAssets(ast.directives, 'directive', context);2457 if (ast.temps > 0) {2458 newline();2459 }2460 }2461 if (ast.filters && ast.filters.length) {2462 newline();2463 genAssets(ast.filters, 'filter', context);2464 newline();2465 }2466 if (ast.temps > 0) {2467 push(`let `);2468 for (let i = 0; i < ast.temps; i++) {2469 push(`${i > 0 ? `, ` : ``}_temp${i}`);2470 }2471 }2472 if (ast.components.length || ast.directives.length || ast.temps) {2473 push(`\n`);2474 newline();2475 }2476 // generate the VNode tree expression2477 if (!ssr) {2478 push(`return `);2479 }2480 if (ast.codegenNode) {2481 genNode(ast.codegenNode, context);2482 }2483 else {2484 push(`null`);2485 }2486 if (useWithBlock) {2487 deindent();2488 push(`}`);2489 }2490 deindent();2491 push(`}`);2492 return {2493 ast,2494 code: context.code,2495 preamble: ``,2496 // SourceMapGenerator does have toJSON() method but it's not in the types2497 map: context.map ? context.map.toJSON() : undefined2498 };2499}2500function genFunctionPreamble(ast, context) {2501 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2502 const VueBinding = runtimeGlobalName;2503 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2504 // Generate const declaration for helpers2505 // In prefix mode, we place the const declaration at top so it's done2506 // only once; But if we not prefixing, we place the declaration inside the2507 // with block so it doesn't incur the `in` check cost for every helper access.2508 if (ast.helpers.length > 0) {2509 {2510 // "with" mode.2511 // save Vue in a separate variable to avoid collision2512 push(`const _Vue = ${VueBinding}\n`);2513 // in "with" mode, helpers are declared inside the with block to avoid2514 // has check cost, but hoists are lifted out of the function - we need2515 // to provide the helper here.2516 if (ast.hoists.length) {2517 const staticHelpers = [2518 CREATE_VNODE,2519 CREATE_ELEMENT_VNODE,2520 CREATE_COMMENT,2521 CREATE_TEXT,2522 CREATE_STATIC2523 ]2524 .filter(helper => ast.helpers.includes(helper))2525 .map(aliasHelper)2526 .join(', ');2527 push(`const { ${staticHelpers} } = _Vue\n`);2528 }2529 }2530 }2531 genHoists(ast.hoists, context);2532 newline();2533 push(`return `);2534}2535function genAssets(assets, type, { helper, push, newline, isTS }) {2536 const resolver = helper(type === 'filter'2537 ? RESOLVE_FILTER2538 : type === 'component'2539 ? RESOLVE_COMPONENT2540 : RESOLVE_DIRECTIVE);2541 for (let i = 0; i < assets.length; i++) {2542 let id = assets[i];2543 // potential component implicit self-reference inferred from SFC filename2544 const maybeSelfReference = id.endsWith('__self');2545 if (maybeSelfReference) {2546 id = id.slice(0, -6);2547 }2548 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2549 if (i < assets.length - 1) {2550 newline();2551 }2552 }2553}2554function genHoists(hoists, context) {2555 if (!hoists.length) {2556 return;2557 }2558 context.pure = true;2559 const { push, newline, helper, scopeId, mode } = context;2560 newline();2561 for (let i = 0; i < hoists.length; i++) {2562 const exp = hoists[i];2563 if (exp) {2564 push(`const _hoisted_${i + 1} = ${``}`);2565 genNode(exp, context);2566 newline();2567 }2568 }2569 context.pure = false;2570}2571function isText$1(n) {2572 return (isString(n) ||2573 n.type === 4 /* SIMPLE_EXPRESSION */ ||2574 n.type === 2 /* TEXT */ ||2575 n.type === 5 /* INTERPOLATION */ ||2576 n.type === 8 /* COMPOUND_EXPRESSION */);2577}2578function genNodeListAsArray(nodes, context) {2579 const multilines = nodes.length > 3 ||2580 (nodes.some(n => isArray(n) || !isText$1(n)));2581 context.push(`[`);2582 multilines && context.indent();2583 genNodeList(nodes, context, multilines);2584 multilines && context.deindent();2585 context.push(`]`);2586}2587function genNodeList(nodes, context, multilines = false, comma = true) {2588 const { push, newline } = context;2589 for (let i = 0; i < nodes.length; i++) {2590 const node = nodes[i];2591 if (isString(node)) {2592 push(node);2593 }2594 else if (isArray(node)) {2595 genNodeListAsArray(node, context);2596 }2597 else {2598 genNode(node, context);2599 }2600 if (i < nodes.length - 1) {2601 if (multilines) {2602 comma && push(',');2603 newline();2604 }2605 else {2606 comma && push(', ');2607 }2608 }2609 }2610}2611function genNode(node, context) {2612 if (isString(node)) {2613 context.push(node);2614 return;2615 }2616 if (isSymbol(node)) {2617 context.push(context.helper(node));2618 return;2619 }2620 switch (node.type) {2621 case 1 /* ELEMENT */:2622 case 9 /* IF */:2623 case 11 /* FOR */:2624 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2625 `Apply appropriate transforms first.`);2626 genNode(node.codegenNode, context);2627 break;2628 case 2 /* TEXT */:2629 genText(node, context);2630 break;2631 case 4 /* SIMPLE_EXPRESSION */:2632 genExpression(node, context);2633 break;2634 case 5 /* INTERPOLATION */:2635 genInterpolation(node, context);2636 break;2637 case 12 /* TEXT_CALL */:2638 genNode(node.codegenNode, context);2639 break;2640 case 8 /* COMPOUND_EXPRESSION */:2641 genCompoundExpression(node, context);2642 break;2643 case 3 /* COMMENT */:2644 genComment(node, context);2645 break;2646 case 13 /* VNODE_CALL */:2647 genVNodeCall(node, context);2648 break;2649 case 14 /* JS_CALL_EXPRESSION */:2650 genCallExpression(node, context);2651 break;2652 case 15 /* JS_OBJECT_EXPRESSION */:2653 genObjectExpression(node, context);2654 break;2655 case 17 /* JS_ARRAY_EXPRESSION */:2656 genArrayExpression(node, context);2657 break;2658 case 18 /* JS_FUNCTION_EXPRESSION */:2659 genFunctionExpression(node, context);2660 break;2661 case 19 /* JS_CONDITIONAL_EXPRESSION */:2662 genConditionalExpression(node, context);2663 break;2664 case 20 /* JS_CACHE_EXPRESSION */:2665 genCacheExpression(node, context);2666 break;2667 case 21 /* JS_BLOCK_STATEMENT */:2668 genNodeList(node.body, context, true, false);2669 break;2670 // SSR only types2671 case 22 /* JS_TEMPLATE_LITERAL */:2672 break;2673 case 23 /* JS_IF_STATEMENT */:2674 break;2675 case 24 /* JS_ASSIGNMENT_EXPRESSION */:2676 break;2677 case 25 /* JS_SEQUENCE_EXPRESSION */:2678 break;2679 case 26 /* JS_RETURN_STATEMENT */:2680 break;2681 /* istanbul ignore next */2682 case 10 /* IF_BRANCH */:2683 // noop2684 break;2685 default:2686 {2687 assert(false, `unhandled codegen node type: ${node.type}`);2688 // make sure we exhaust all possible types2689 const exhaustiveCheck = node;2690 return exhaustiveCheck;2691 }2692 }2693}2694function genText(node, context) {2695 context.push(JSON.stringify(node.content), node);2696}2697function genExpression(node, context) {2698 const { content, isStatic } = node;2699 context.push(isStatic ? JSON.stringify(content) : content, node);2700}2701function genInterpolation(node, context) {2702 const { push, helper, pure } = context;2703 if (pure)2704 push(PURE_ANNOTATION);2705 push(`${helper(TO_DISPLAY_STRING)}(`);2706 genNode(node.content, context);2707 push(`)`);2708}2709function genCompoundExpression(node, context) {2710 for (let i = 0; i < node.children.length; i++) {2711 const child = node.children[i];2712 if (isString(child)) {2713 context.push(child);2714 }2715 else {2716 genNode(child, context);2717 }2718 }2719}2720function genExpressionAsPropertyKey(node, context) {2721 const { push } = context;2722 if (node.type === 8 /* COMPOUND_EXPRESSION */) {2723 push(`[`);2724 genCompoundExpression(node, context);2725 push(`]`);2726 }2727 else if (node.isStatic) {2728 // only quote keys if necessary2729 const text = isSimpleIdentifier(node.content)2730 ? node.content2731 : JSON.stringify(node.content);2732 push(text, node);2733 }2734 else {2735 push(`[${node.content}]`, node);2736 }2737}2738function genComment(node, context) {2739 const { push, helper, pure } = context;2740 if (pure) {2741 push(PURE_ANNOTATION);2742 }2743 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2744}2745function genVNodeCall(node, context) {2746 const { push, helper, pure } = context;2747 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2748 if (directives) {2749 push(helper(WITH_DIRECTIVES) + `(`);2750 }2751 if (isBlock) {2752 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2753 }2754 if (pure) {2755 push(PURE_ANNOTATION);2756 }2757 const callHelper = isBlock2758 ? getVNodeBlockHelper(context.inSSR, isComponent)2759 : getVNodeHelper(context.inSSR, isComponent);2760 push(helper(callHelper) + `(`, node);2761 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2762 push(`)`);2763 if (isBlock) {2764 push(`)`);2765 }2766 if (directives) {2767 push(`, `);2768 genNode(directives, context);2769 push(`)`);2770 }2771}2772function genNullableArgs(args) {2773 let i = args.length;2774 while (i--) {2775 if (args[i] != null)2776 break;2777 }2778 return args.slice(0, i + 1).map(arg => arg || `null`);2779}2780// JavaScript2781function genCallExpression(node, context) {2782 const { push, helper, pure } = context;2783 const callee = isString(node.callee) ? node.callee : helper(node.callee);2784 if (pure) {2785 push(PURE_ANNOTATION);2786 }2787 push(callee + `(`, node);2788 genNodeList(node.arguments, context);2789 push(`)`);2790}2791function genObjectExpression(node, context) {2792 const { push, indent, deindent, newline } = context;2793 const { properties } = node;2794 if (!properties.length) {2795 push(`{}`, node);2796 return;2797 }2798 const multilines = properties.length > 1 ||2799 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2800 push(multilines ? `{` : `{ `);2801 multilines && indent();2802 for (let i = 0; i < properties.length; i++) {2803 const { key, value } = properties[i];2804 // key2805 genExpressionAsPropertyKey(key, context);2806 push(`: `);2807 // value2808 genNode(value, context);2809 if (i < properties.length - 1) {2810 // will only reach this if it's multilines2811 push(`,`);2812 newline();2813 }2814 }2815 multilines && deindent();2816 push(multilines ? `}` : ` }`);2817}2818function genArrayExpression(node, context) {2819 genNodeListAsArray(node.elements, context);2820}2821function genFunctionExpression(node, context) {2822 const { push, indent, deindent } = context;2823 const { params, returns, body, newline, isSlot } = node;2824 if (isSlot) {2825 // wrap slot functions with owner context2826 push(`_${helperNameMap[WITH_CTX]}(`);2827 }2828 push(`(`, node);2829 if (isArray(params)) {2830 genNodeList(params, context);2831 }2832 else if (params) {2833 genNode(params, context);2834 }2835 push(`) => `);2836 if (newline || body) {2837 push(`{`);2838 indent();2839 }2840 if (returns) {2841 if (newline) {2842 push(`return `);2843 }2844 if (isArray(returns)) {2845 genNodeListAsArray(returns, context);2846 }2847 else {2848 genNode(returns, context);2849 }2850 }2851 else if (body) {2852 genNode(body, context);2853 }2854 if (newline || body) {2855 deindent();2856 push(`}`);2857 }2858 if (isSlot) {2859 if (node.isNonScopedSlot) {2860 push(`, undefined, true`);2861 }2862 push(`)`);2863 }2864}2865function genConditionalExpression(node, context) {2866 const { test, consequent, alternate, newline: needNewline } = node;2867 const { push, indent, deindent, newline } = context;2868 if (test.type === 4 /* SIMPLE_EXPRESSION */) {2869 const needsParens = !isSimpleIdentifier(test.content);2870 needsParens && push(`(`);2871 genExpression(test, context);2872 needsParens && push(`)`);2873 }2874 else {2875 push(`(`);2876 genNode(test, context);2877 push(`)`);2878 }2879 needNewline && indent();2880 context.indentLevel++;2881 needNewline || push(` `);2882 push(`? `);2883 genNode(consequent, context);2884 context.indentLevel--;2885 needNewline && newline();2886 needNewline || push(` `);2887 push(`: `);2888 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2889 if (!isNested) {2890 context.indentLevel++;2891 }2892 genNode(alternate, context);2893 if (!isNested) {2894 context.indentLevel--;2895 }2896 needNewline && deindent(true /* without newline */);2897}2898function genCacheExpression(node, context) {2899 const { push, helper, indent, deindent, newline } = context;2900 push(`_cache[${node.index}] || (`);2901 if (node.isVNode) {2902 indent();2903 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2904 newline();2905 }2906 push(`_cache[${node.index}] = `);2907 genNode(node.value, context);2908 if (node.isVNode) {2909 push(`,`);2910 newline();2911 push(`${helper(SET_BLOCK_TRACKING)}(1),`);2912 newline();2913 push(`_cache[${node.index}]`);2914 deindent();2915 }2916 push(`)`);2917}2918function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2919 {2920 return;2921 }2922}2923function isReferencedIdentifier(id, parent, parentStack) {2924 {2925 return false;2926 }2927}2928function isInDestructureAssignment(parent, parentStack) {2929 if (parent &&2930 (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {2931 let i = parentStack.length;2932 while (i--) {2933 const p = parentStack[i];2934 if (p.type === 'AssignmentExpression') {2935 return true;2936 }2937 else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {2938 break;2939 }2940 }2941 }2942 return false;2943}2944function walkFunctionParams(node, onIdent) {2945 for (const p of node.params) {2946 for (const id of extractIdentifiers(p)) {2947 onIdent(id);2948 }2949 }2950}2951function walkBlockDeclarations(block, onIdent) {2952 for (const stmt of block.body) {2953 if (stmt.type === 'VariableDeclaration') {2954 if (stmt.declare)2955 continue;2956 for (const decl of stmt.declarations) {2957 for (const id of extractIdentifiers(decl.id)) {2958 onIdent(id);2959 }2960 }2961 }2962 else if (stmt.type === 'FunctionDeclaration' ||2963 stmt.type === 'ClassDeclaration') {2964 if (stmt.declare || !stmt.id)2965 continue;2966 onIdent(stmt.id);2967 }2968 }2969}2970function extractIdentifiers(param, nodes = []) {2971 switch (param.type) {2972 case 'Identifier':2973 nodes.push(param);2974 break;2975 case 'MemberExpression':2976 let object = param;2977 while (object.type === 'MemberExpression') {2978 object = object.object;2979 }2980 nodes.push(object);2981 break;2982 case 'ObjectPattern':2983 for (const prop of param.properties) {2984 if (prop.type === 'RestElement') {2985 extractIdentifiers(prop.argument, nodes);2986 }2987 else {2988 extractIdentifiers(prop.value, nodes);2989 }2990 }2991 break;2992 case 'ArrayPattern':2993 param.elements.forEach(element => {2994 if (element)2995 extractIdentifiers(element, nodes);2996 });2997 break;2998 case 'RestElement':2999 extractIdentifiers(param.argument, nodes);3000 break;3001 case 'AssignmentPattern':3002 extractIdentifiers(param.left, nodes);3003 break;3004 }3005 return nodes;3006}3007const isFunctionType = (node) => {3008 return /Function(?:Expression|Declaration)$|Method$/.test(node.type);3009};3010const isStaticProperty = (node) => node &&3011 (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&3012 !node.computed;3013const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;3014// these keywords should not appear inside expressions, but operators like3015// typeof, instanceof and in are allowed3016const prohibitedKeywordRE = new RegExp('\\b' +3017 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +3018 'super,throw,while,yield,delete,export,import,return,switch,default,' +3019 'extends,finally,continue,debugger,function,arguments,typeof,void')3020 .split(',')3021 .join('\\b|\\b') +3022 '\\b');3023// strip strings in expressions3024const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;3025/**3026 * Validate a non-prefixed expression.3027 * This is only called when using the in-browser runtime compiler since it3028 * doesn't prefix expressions.3029 */3030function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {3031 const exp = node.content;3032 // empty expressions are validated per-directive since some directives3033 // do allow empty expressions.3034 if (!exp.trim()) {3035 return;3036 }3037 try {3038 new Function(asRawStatements3039 ? ` ${exp} `3040 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);3041 }3042 catch (e) {3043 let message = e.message;3044 const keywordMatch = exp3045 .replace(stripStringRE, '')3046 .match(prohibitedKeywordRE);3047 if (keywordMatch) {3048 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;3049 }3050 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));3051 }3052}3053const transformExpression = (node, context) => {3054 if (node.type === 5 /* INTERPOLATION */) {3055 node.content = processExpression(node.content, context);3056 }3057 else if (node.type === 1 /* ELEMENT */) {3058 // handle directives on element3059 for (let i = 0; i < node.props.length; i++) {3060 const dir = node.props[i];3061 // do not process for v-on & v-for since they are special handled3062 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3063 const exp = dir.exp;3064 const arg = dir.arg;3065 // do not process exp if this is v-on:arg - we need special handling3066 // for wrapping inline statements.3067 if (exp &&3068 exp.type === 4 /* SIMPLE_EXPRESSION */ &&3069 !(dir.name === 'on' && arg)) {3070 dir.exp = processExpression(exp, context, 3071 // slot args must be processed as function params3072 dir.name === 'slot');3073 }3074 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3075 dir.arg = processExpression(arg, context);3076 }3077 }3078 }3079 }3080};3081// Important: since this function uses Node.js only dependencies, it should3082// always be used with a leading !true check so that it can be3083// tree-shaken from the browser build.3084function processExpression(node, context, 3085// some expressions like v-slot props & v-for aliases should be parsed as3086// function params3087asParams = false, 3088// v-on handler values may contain multiple statements3089asRawStatements = false, localVars = Object.create(context.identifiers)) {3090 {3091 {3092 // simple in-browser validation (same logic in 2.x)3093 validateBrowserExpression(node, context, asParams, asRawStatements);3094 }3095 return node;3096 }3097}3098const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3099 return processIf(node, dir, context, (ifNode, branch, isRoot) => {3100 // #1587: We need to dynamically increment the key based on the current3101 // node's sibling nodes, since chained v-if/else branches are3102 // rendered at the same depth3103 const siblings = context.parent.children;3104 let i = siblings.indexOf(ifNode);3105 let key = 0;3106 while (i-- >= 0) {3107 const sibling = siblings[i];3108 if (sibling && sibling.type === 9 /* IF */) {3109 key += sibling.branches.length;3110 }3111 }3112 // Exit callback. Complete the codegenNode when all children have been3113 // transformed.3114 return () => {3115 if (isRoot) {3116 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3117 }3118 else {3119 // attach this branch's codegen node to the v-if root.3120 const parentCondition = getParentCondition(ifNode.codegenNode);3121 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3122 }3123 };3124 });3125});3126// target-agnostic transform used for both Client and SSR3127function processIf(node, dir, context, processCodegen) {3128 if (dir.name !== 'else' &&3129 (!dir.exp || !dir.exp.content.trim())) {3130 const loc = dir.exp ? dir.exp.loc : node.loc;3131 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3132 dir.exp = createSimpleExpression(`true`, false, loc);3133 }3134 if (dir.exp) {3135 validateBrowserExpression(dir.exp, context);3136 }3137 if (dir.name === 'if') {3138 const branch = createIfBranch(node, dir);3139 const ifNode = {3140 type: 9 /* IF */,3141 loc: node.loc,3142 branches: [branch]3143 };3144 context.replaceNode(ifNode);3145 if (processCodegen) {3146 return processCodegen(ifNode, branch, true);3147 }3148 }3149 else {3150 // locate the adjacent v-if3151 const siblings = context.parent.children;3152 const comments = [];3153 let i = siblings.indexOf(node);3154 while (i-- >= -1) {3155 const sibling = siblings[i];3156 if (sibling && sibling.type === 3 /* COMMENT */) {3157 context.removeNode(sibling);3158 comments.unshift(sibling);3159 continue;3160 }3161 if (sibling &&3162 sibling.type === 2 /* TEXT */ &&3163 !sibling.content.trim().length) {3164 context.removeNode(sibling);3165 continue;3166 }3167 if (sibling && sibling.type === 9 /* IF */) {3168 // Check if v-else was followed by v-else-if3169 if (dir.name === 'else-if' &&3170 sibling.branches[sibling.branches.length - 1].condition === undefined) {3171 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3172 }3173 // move the node to the if node's branches3174 context.removeNode();3175 const branch = createIfBranch(node, dir);3176 if (comments.length &&3177 // #3619 ignore comments if the v-if is direct child of <transition>3178 !(context.parent &&3179 context.parent.type === 1 /* ELEMENT */ &&3180 isBuiltInType(context.parent.tag, 'transition'))) {3181 branch.children = [...comments, ...branch.children];3182 }3183 // check if user is forcing same key on different branches3184 {3185 const key = branch.userKey;3186 if (key) {3187 sibling.branches.forEach(({ userKey }) => {3188 if (isSameKey(userKey, key)) {3189 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3190 }3191 });3192 }3193 }3194 sibling.branches.push(branch);3195 const onExit = processCodegen && processCodegen(sibling, branch, false);3196 // since the branch was removed, it will not be traversed.3197 // make sure to traverse here.3198 traverseNode(branch, context);3199 // call on exit3200 if (onExit)3201 onExit();3202 // make sure to reset currentNode after traversal to indicate this3203 // node has been removed.3204 context.currentNode = null;3205 }3206 else {3207 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3208 }3209 break;3210 }3211 }3212}3213function createIfBranch(node, dir) {3214 return {3215 type: 10 /* IF_BRANCH */,3216 loc: node.loc,3217 condition: dir.name === 'else' ? undefined : dir.exp,3218 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3219 ? node.children3220 : [node],3221 userKey: findProp(node, `key`)3222 };3223}3224function createCodegenNodeForBranch(branch, keyIndex, context) {3225 if (branch.condition) {3226 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3227 // make sure to pass in asBlock: true so that the comment node call3228 // closes the current block.3229 createCallExpression(context.helper(CREATE_COMMENT), [3230 '"v-if"' ,3231 'true'3232 ]));3233 }3234 else {3235 return createChildrenCodegenNode(branch, keyIndex, context);3236 }3237}3238function createChildrenCodegenNode(branch, keyIndex, context) {3239 const { helper } = context;3240 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3241 const { children } = branch;3242 const firstChild = children[0];3243 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3244 if (needFragmentWrapper) {3245 if (children.length === 1 && firstChild.type === 11 /* FOR */) {3246 // optimize away nested fragments when child is a ForNode3247 const vnodeCall = firstChild.codegenNode;3248 injectProp(vnodeCall, keyProperty, context);3249 return vnodeCall;3250 }3251 else {3252 let patchFlag = 64 /* STABLE_FRAGMENT */;3253 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];3254 // check if the fragment actually contains a single valid child with3255 // the rest being comments3256 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3257 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3258 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3259 }3260 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);3261 }3262 }3263 else {3264 const ret = firstChild.codegenNode;3265 const vnodeCall = getMemoedVNodeCall(ret);3266 // Change createVNode to createBlock.3267 if (vnodeCall.type === 13 /* VNODE_CALL */) {3268 makeBlock(vnodeCall, context);3269 }3270 // inject branch key3271 injectProp(vnodeCall, keyProperty, context);3272 return ret;3273 }3274}3275function isSameKey(a, b) {3276 if (!a || a.type !== b.type) {3277 return false;3278 }3279 if (a.type === 6 /* ATTRIBUTE */) {3280 if (a.value.content !== b.value.content) {3281 return false;3282 }3283 }3284 else {3285 // directive3286 const exp = a.exp;3287 const branchExp = b.exp;3288 if (exp.type !== branchExp.type) {3289 return false;3290 }3291 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3292 exp.isStatic !== branchExp.isStatic ||3293 exp.content !== branchExp.content) {3294 return false;3295 }3296 }3297 return true;3298}3299function getParentCondition(node) {3300 while (true) {3301 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3302 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3303 node = node.alternate;3304 }3305 else {3306 return node;3307 }3308 }3309 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3310 node = node.value;3311 }3312 }3313}3314const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3315 const { helper, removeHelper } = context;3316 return processFor(node, dir, context, forNode => {3317 // create the loop render function expression now, and add the3318 // iterator on exit after all children have been traversed3319 const renderExp = createCallExpression(helper(RENDER_LIST), [3320 forNode.source3321 ]);3322 const memo = findDir(node, 'memo');3323 const keyProp = findProp(node, `key`);3324 const keyExp = keyProp &&3325 (keyProp.type === 6 /* ATTRIBUTE */3326 ? createSimpleExpression(keyProp.value.content, true)3327 : keyProp.exp);3328 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3329 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3330 forNode.source.constType > 0 /* NOT_CONSTANT */;3331 const fragmentFlag = isStableFragment3332 ? 64 /* STABLE_FRAGMENT */3333 : keyProp3334 ? 128 /* KEYED_FRAGMENT */3335 : 256 /* UNKEYED_FRAGMENT */;3336 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3337 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3338 return () => {3339 // finish the codegen now that all children have been traversed3340 let childBlock;3341 const isTemplate = isTemplateNode(node);3342 const { children } = forNode;3343 // check <template v-for> key placement3344 if (isTemplate) {3345 node.children.some(c => {3346 if (c.type === 1 /* ELEMENT */) {3347 const key = findProp(c, 'key');3348 if (key) {3349 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3350 return true;3351 }3352 }3353 });3354 }3355 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3356 const slotOutlet = isSlotOutlet(node)3357 ? node3358 : isTemplate &&3359 node.children.length === 1 &&3360 isSlotOutlet(node.children[0])3361 ? node.children[0] // api-extractor somehow fails to infer this3362 : null;3363 if (slotOutlet) {3364 // <slot v-for="..."> or <template v-for="..."><slot/></template>3365 childBlock = slotOutlet.codegenNode;3366 if (isTemplate && keyProperty) {3367 // <template v-for="..." :key="..."><slot/></template>3368 // we need to inject the key to the renderSlot() call.3369 // the props for renderSlot is passed as the 3rd argument.3370 injectProp(childBlock, keyProperty, context);3371 }3372 }3373 else if (needFragmentWrapper) {3374 // <template v-for="..."> with text or multi-elements3375 // should generate a fragment block for each loop3376 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3377 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3378 ), undefined, undefined, true, undefined, false /* isComponent */);3379 }3380 else {3381 // Normal element v-for. Directly use the child's codegenNode3382 // but mark it as a block.3383 childBlock = children[0]3384 .codegenNode;3385 if (isTemplate && keyProperty) {3386 injectProp(childBlock, keyProperty, context);3387 }3388 if (childBlock.isBlock !== !isStableFragment) {3389 if (childBlock.isBlock) {3390 // switch from block to vnode3391 removeHelper(OPEN_BLOCK);3392 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3393 }3394 else {3395 // switch from vnode to block3396 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3397 }3398 }3399 childBlock.isBlock = !isStableFragment;3400 if (childBlock.isBlock) {3401 helper(OPEN_BLOCK);3402 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3403 }3404 else {3405 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3406 }3407 }3408 if (memo) {3409 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3410 createSimpleExpression(`_cached`)3411 ]));3412 loop.body = createBlockStatement([3413 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3414 createCompoundExpression([3415 `if (_cached`,3416 ...(keyExp ? [` && _cached.key === `, keyExp] : []),3417 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3418 ]),3419 createCompoundExpression([`const _item = `, childBlock]),3420 createSimpleExpression(`_item.memo = _memo`),3421 createSimpleExpression(`return _item`)3422 ]);3423 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3424 }3425 else {3426 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3427 }3428 };3429 });3430});3431// target-agnostic transform used for both Client and SSR3432function processFor(node, dir, context, processCodegen) {3433 if (!dir.exp) {3434 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3435 return;3436 }3437 const parseResult = parseForExpression(3438 // can only be simple expression because vFor transform is applied3439 // before expression transform.3440 dir.exp, context);3441 if (!parseResult) {3442 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3443 return;3444 }3445 const { addIdentifiers, removeIdentifiers, scopes } = context;3446 const { source, value, key, index } = parseResult;3447 const forNode = {3448 type: 11 /* FOR */,3449 loc: dir.loc,3450 source,3451 valueAlias: value,3452 keyAlias: key,3453 objectIndexAlias: index,3454 parseResult,3455 children: isTemplateNode(node) ? node.children : [node]3456 };3457 context.replaceNode(forNode);3458 // bookkeeping3459 scopes.vFor++;3460 const onExit = processCodegen && processCodegen(forNode);3461 return () => {3462 scopes.vFor--;3463 if (onExit)3464 onExit();3465 };3466}3467const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3468// This regex doesn't cover the case if key or index aliases have destructuring,3469// but those do not make sense in the first place, so this works in practice.3470const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3471const stripParensRE = /^\(|\)$/g;3472function parseForExpression(input, context) {3473 const loc = input.loc;3474 const exp = input.content;3475 const inMatch = exp.match(forAliasRE);3476 if (!inMatch)3477 return;3478 const [, LHS, RHS] = inMatch;3479 const result = {3480 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3481 value: undefined,3482 key: undefined,3483 index: undefined3484 };3485 {3486 validateBrowserExpression(result.source, context);3487 }3488 let valueContent = LHS.trim().replace(stripParensRE, '').trim();3489 const trimmedOffset = LHS.indexOf(valueContent);3490 const iteratorMatch = valueContent.match(forIteratorRE);3491 if (iteratorMatch) {3492 valueContent = valueContent.replace(forIteratorRE, '').trim();3493 const keyContent = iteratorMatch[1].trim();3494 let keyOffset;3495 if (keyContent) {3496 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3497 result.key = createAliasExpression(loc, keyContent, keyOffset);3498 {3499 validateBrowserExpression(result.key, context, true);3500 }3501 }3502 if (iteratorMatch[2]) {3503 const indexContent = iteratorMatch[2].trim();3504 if (indexContent) {3505 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3506 ? keyOffset + keyContent.length3507 : trimmedOffset + valueContent.length));3508 {3509 validateBrowserExpression(result.index, context, true);3510 }3511 }3512 }3513 }3514 if (valueContent) {3515 result.value = createAliasExpression(loc, valueContent, trimmedOffset);3516 {3517 validateBrowserExpression(result.value, context, true);3518 }3519 }3520 return result;3521}3522function createAliasExpression(range, content, offset) {3523 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3524}3525function createForLoopParams({ value, key, index }, memoArgs = []) {3526 return createParamsList([value, key, index, ...memoArgs]);3527}3528function createParamsList(args) {3529 let i = args.length;3530 while (i--) {3531 if (args[i])3532 break;3533 }3534 return args3535 .slice(0, i + 1)3536 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));3537}3538const defaultFallback = createSimpleExpression(`undefined`, false);3539// A NodeTransform that:3540// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3541// by transformExpression. This is only applied in non-browser builds with3542// { prefixIdentifiers: true }.3543// 2. Track v-slot depths so that we know a slot is inside another slot.3544// Note the exit callback is executed before buildSlots() on the same node,3545// so only nested slots see positive numbers.3546const trackSlotScopes = (node, context) => {3547 if (node.type === 1 /* ELEMENT */ &&3548 (node.tagType === 1 /* COMPONENT */ ||3549 node.tagType === 3 /* TEMPLATE */)) {3550 // We are only checking non-empty v-slot here3551 // since we only care about slots that introduce scope variables.3552 const vSlot = findDir(node, 'slot');3553 if (vSlot) {3554 vSlot.exp;3555 context.scopes.vSlot++;3556 return () => {3557 context.scopes.vSlot--;3558 };3559 }3560 }3561};3562// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3563// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3564const trackVForSlotScopes = (node, context) => {3565 let vFor;3566 if (isTemplateNode(node) &&3567 node.props.some(isVSlot) &&3568 (vFor = findDir(node, 'for'))) {3569 const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3570 if (result) {3571 const { value, key, index } = result;3572 const { addIdentifiers, removeIdentifiers } = context;3573 value && addIdentifiers(value);3574 key && addIdentifiers(key);3575 index && addIdentifiers(index);3576 return () => {3577 value && removeIdentifiers(value);3578 key && removeIdentifiers(key);3579 index && removeIdentifiers(index);3580 };3581 }3582 }3583};3584const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3585// Instead of being a DirectiveTransform, v-slot processing is called during3586// transformElement to build the slots object for a component.3587function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3588 context.helper(WITH_CTX);3589 const { children, loc } = node;3590 const slotsProperties = [];3591 const dynamicSlots = [];3592 // If the slot is inside a v-for or another v-slot, force it to be dynamic3593 // since it likely uses a scope variable.3594 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3595 // 1. Check for slot with slotProps on component itself.3596 // <Comp v-slot="{ prop }"/>3597 const onComponentSlot = findDir(node, 'slot', true);3598 if (onComponentSlot) {3599 const { arg, exp } = onComponentSlot;3600 if (arg && !isStaticExp(arg)) {3601 hasDynamicSlots = true;3602 }3603 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));3604 }3605 // 2. Iterate through children and check for template slots3606 // <template v-slot:foo="{ prop }">3607 let hasTemplateSlots = false;3608 let hasNamedDefaultSlot = false;3609 const implicitDefaultChildren = [];3610 const seenSlotNames = new Set();3611 for (let i = 0; i < children.length; i++) {3612 const slotElement = children[i];3613 let slotDir;3614 if (!isTemplateNode(slotElement) ||3615 !(slotDir = findDir(slotElement, 'slot', true))) {3616 // not a <template v-slot>, skip.3617 if (slotElement.type !== 3 /* COMMENT */) {3618 implicitDefaultChildren.push(slotElement);3619 }3620 continue;3621 }3622 if (onComponentSlot) {3623 // already has on-component slot - this is incorrect usage.3624 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3625 break;3626 }3627 hasTemplateSlots = true;3628 const { children: slotChildren, loc: slotLoc } = slotElement;3629 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3630 // check if name is dynamic.3631 let staticSlotName;3632 if (isStaticExp(slotName)) {3633 staticSlotName = slotName ? slotName.content : `default`;3634 }3635 else {3636 hasDynamicSlots = true;3637 }3638 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3639 // check if this slot is conditional (v-if/v-for)3640 let vIf;3641 let vElse;3642 let vFor;3643 if ((vIf = findDir(slotElement, 'if'))) {3644 hasDynamicSlots = true;3645 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3646 }3647 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3648 // find adjacent v-if3649 let j = i;3650 let prev;3651 while (j--) {3652 prev = children[j];3653 if (prev.type !== 3 /* COMMENT */) {3654 break;3655 }3656 }3657 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3658 // remove node3659 children.splice(i, 1);3660 i--;3661 // attach this slot to previous conditional3662 let conditional = dynamicSlots[dynamicSlots.length - 1];3663 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3664 conditional = conditional.alternate;3665 }3666 conditional.alternate = vElse.exp3667 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3668 : buildDynamicSlot(slotName, slotFunction);3669 }3670 else {3671 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3672 }3673 }3674 else if ((vFor = findDir(slotElement, 'for'))) {3675 hasDynamicSlots = true;3676 const parseResult = vFor.parseResult ||3677 parseForExpression(vFor.exp, context);3678 if (parseResult) {3679 // Render the dynamic slots as an array and add it to the createSlot()3680 // args. The runtime knows how to handle it appropriately.3681 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3682 parseResult.source,3683 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3684 ]));3685 }3686 else {3687 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3688 }3689 }3690 else {3691 // check duplicate static names3692 if (staticSlotName) {3693 if (seenSlotNames.has(staticSlotName)) {3694 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3695 continue;3696 }3697 seenSlotNames.add(staticSlotName);3698 if (staticSlotName === 'default') {3699 hasNamedDefaultSlot = true;3700 }3701 }3702 slotsProperties.push(createObjectProperty(slotName, slotFunction));3703 }3704 }3705 if (!onComponentSlot) {3706 const buildDefaultSlotProperty = (props, children) => {3707 const fn = buildSlotFn(props, children, loc);3708 if (context.compatConfig) {3709 fn.isNonScopedSlot = true;3710 }3711 return createObjectProperty(`default`, fn);3712 };3713 if (!hasTemplateSlots) {3714 // implicit default slot (on component)3715 slotsProperties.push(buildDefaultSlotProperty(undefined, children));3716 }3717 else if (implicitDefaultChildren.length &&3718 // #37663719 // with whitespace: 'preserve', whitespaces between slots will end up in3720 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.3721 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {3722 // implicit default slot (mixed with named slots)3723 if (hasNamedDefaultSlot) {3724 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));3725 }3726 else {3727 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));3728 }3729 }3730 }3731 const slotFlag = hasDynamicSlots3732 ? 2 /* DYNAMIC */3733 : hasForwardedSlots(node.children)3734 ? 3 /* FORWARDED */3735 : 1 /* STABLE */;3736 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 3737 // 2 = compiled but dynamic = can skip normalization, but must run diff3738 // 1 = compiled and static = can skip normalization AND diff as optimized3739 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);3740 if (dynamicSlots.length) {3741 slots = createCallExpression(context.helper(CREATE_SLOTS), [3742 slots,3743 createArrayExpression(dynamicSlots)3744 ]);3745 }3746 return {3747 slots,3748 hasDynamicSlots3749 };3750}3751function buildDynamicSlot(name, fn) {3752 return createObjectExpression([3753 createObjectProperty(`name`, name),3754 createObjectProperty(`fn`, fn)3755 ]);3756}3757function hasForwardedSlots(children) {3758 for (let i = 0; i < children.length; i++) {3759 const child = children[i];3760 switch (child.type) {3761 case 1 /* ELEMENT */:3762 if (child.tagType === 2 /* SLOT */ ||3763 hasForwardedSlots(child.children)) {3764 return true;3765 }3766 break;3767 case 9 /* IF */:3768 if (hasForwardedSlots(child.branches))3769 return true;3770 break;3771 case 10 /* IF_BRANCH */:3772 case 11 /* FOR */:3773 if (hasForwardedSlots(child.children))3774 return true;3775 break;3776 }3777 }3778 return false;3779}3780function isNonWhitespaceContent(node) {3781 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)3782 return true;3783 return node.type === 2 /* TEXT */3784 ? !!node.content.trim()3785 : isNonWhitespaceContent(node.content);3786}3787// some directive transforms (e.g. v-model) may return a symbol for runtime3788// import, which should be used instead of a resolveDirective call.3789const directiveImportMap = new WeakMap();3790// generate a JavaScript AST for this element's codegen3791const transformElement = (node, context) => {3792 // perform the work on exit, after all child expressions have been3793 // processed and merged.3794 return function postTransformElement() {3795 node = context.currentNode;3796 if (!(node.type === 1 /* ELEMENT */ &&3797 (node.tagType === 0 /* ELEMENT */ ||3798 node.tagType === 1 /* COMPONENT */))) {3799 return;3800 }3801 const { tag, props } = node;3802 const isComponent = node.tagType === 1 /* COMPONENT */;3803 // The goal of the transform is to create a codegenNode implementing the3804 // VNodeCall interface.3805 let vnodeTag = isComponent3806 ? resolveComponentType(node, context)3807 : `"${tag}"`;3808 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;3809 let vnodeProps;3810 let vnodeChildren;3811 let vnodePatchFlag;3812 let patchFlag = 0;3813 let vnodeDynamicProps;3814 let dynamicPropNames;3815 let vnodeDirectives;3816 let shouldUseBlock = 3817 // dynamic component may resolve to plain elements3818 isDynamicComponent ||3819 vnodeTag === TELEPORT ||3820 vnodeTag === SUSPENSE ||3821 (!isComponent &&3822 // <svg> and <foreignObject> must be forced into blocks so that block3823 // updates inside get proper isSVG flag at runtime. (#639, #643)3824 // This is technically web-specific, but splitting the logic out of core3825 // leads to too much unnecessary complexity.3826 (tag === 'svg' ||3827 tag === 'foreignObject' ||3828 // #938: elements with dynamic keys should be forced into blocks3829 findProp(node, 'key', true)));3830 // props3831 if (props.length > 0) {3832 const propsBuildResult = buildProps(node, context);3833 vnodeProps = propsBuildResult.props;3834 patchFlag = propsBuildResult.patchFlag;3835 dynamicPropNames = propsBuildResult.dynamicPropNames;3836 const directives = propsBuildResult.directives;3837 vnodeDirectives =3838 directives && directives.length3839 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))3840 : undefined;3841 }3842 // children3843 if (node.children.length > 0) {3844 if (vnodeTag === KEEP_ALIVE) {3845 // Although a built-in component, we compile KeepAlive with raw children3846 // instead of slot functions so that it can be used inside Transition3847 // or other Transition-wrapping HOCs.3848 // To ensure correct updates with block optimizations, we need to:3849 // 1. Force keep-alive into a block. This avoids its children being3850 // collected by a parent block.3851 shouldUseBlock = true;3852 // 2. Force keep-alive to always be updated, since it uses raw children.3853 patchFlag |= 1024 /* DYNAMIC_SLOTS */;3854 if (node.children.length > 1) {3855 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {3856 start: node.children[0].loc.start,3857 end: node.children[node.children.length - 1].loc.end,3858 source: ''3859 }));3860 }3861 }3862 const shouldBuildAsSlots = isComponent &&3863 // Teleport is not a real component and has dedicated runtime handling3864 vnodeTag !== TELEPORT &&3865 // explained above.3866 vnodeTag !== KEEP_ALIVE;3867 if (shouldBuildAsSlots) {3868 const { slots, hasDynamicSlots } = buildSlots(node, context);3869 vnodeChildren = slots;3870 if (hasDynamicSlots) {3871 patchFlag |= 1024 /* DYNAMIC_SLOTS */;3872 }3873 }3874 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {3875 const child = node.children[0];3876 const type = child.type;3877 // check for dynamic text children3878 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||3879 type === 8 /* COMPOUND_EXPRESSION */;3880 if (hasDynamicTextChild &&3881 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {3882 patchFlag |= 1 /* TEXT */;3883 }3884 // pass directly if the only child is a text node3885 // (plain / interpolation / expression)3886 if (hasDynamicTextChild || type === 2 /* TEXT */) {3887 vnodeChildren = child;3888 }3889 else {3890 vnodeChildren = node.children;3891 }3892 }3893 else {3894 vnodeChildren = node.children;3895 }3896 }3897 // patchFlag & dynamicPropNames3898 if (patchFlag !== 0) {3899 {3900 if (patchFlag < 0) {3901 // special flags (negative and mutually exclusive)3902 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;3903 }3904 else {3905 // bitwise flags3906 const flagNames = Object.keys(PatchFlagNames)3907 .map(Number)3908 .filter(n => n > 0 && patchFlag & n)3909 .map(n => PatchFlagNames[n])3910 .join(`, `);3911 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;3912 }3913 }3914 if (dynamicPropNames && dynamicPropNames.length) {3915 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);3916 }3917 }3918 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);3919 };3920};3921function resolveComponentType(node, context, ssr = false) {3922 let { tag } = node;3923 // 1. dynamic component3924 const isExplicitDynamic = isComponentTag(tag);3925 const isProp = findProp(node, 'is');3926 if (isProp) {3927 if (isExplicitDynamic ||3928 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {3929 const exp = isProp.type === 6 /* ATTRIBUTE */3930 ? isProp.value && createSimpleExpression(isProp.value.content, true)3931 : isProp.exp;3932 if (exp) {3933 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3934 exp3935 ]);3936 }3937 }3938 else if (isProp.type === 6 /* ATTRIBUTE */ &&3939 isProp.value.content.startsWith('vue:')) {3940 // <button is="vue:xxx">3941 // if not <component>, only is value that starts with "vue:" will be3942 // treated as component by the parse phase and reach here, unless it's3943 // compat mode where all is values are considered components3944 tag = isProp.value.content.slice(4);3945 }3946 }3947 // 1.5 v-is (TODO: Deprecate)3948 const isDir = !isExplicitDynamic && findDir(node, 'is');3949 if (isDir && isDir.exp) {3950 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3951 isDir.exp3952 ]);3953 }3954 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)3955 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);3956 if (builtIn) {3957 // built-ins are simply fallthroughs / have special handling during ssr3958 // so we don't need to import their runtime equivalents3959 if (!ssr)3960 context.helper(builtIn);3961 return builtIn;3962 }3963 // 5. user component (resolve)3964 context.helper(RESOLVE_COMPONENT);3965 context.components.add(tag);3966 return toValidAssetId(tag, `component`);3967}3968function buildProps(node, context, props = node.props, ssr = false) {3969 const { tag, loc: elementLoc } = node;3970 const isComponent = node.tagType === 1 /* COMPONENT */;3971 let properties = [];3972 const mergeArgs = [];3973 const runtimeDirectives = [];3974 // patchFlag analysis3975 let patchFlag = 0;3976 let hasRef = false;3977 let hasClassBinding = false;3978 let hasStyleBinding = false;3979 let hasHydrationEventBinding = false;3980 let hasDynamicKeys = false;3981 let hasVnodeHook = false;3982 const dynamicPropNames = [];3983 const analyzePatchFlag = ({ key, value }) => {3984 if (isStaticExp(key)) {3985 const name = key.content;3986 const isEventHandler = isOn(name);3987 if (!isComponent &&3988 isEventHandler &&3989 // omit the flag for click handlers because hydration gives click3990 // dedicated fast path.3991 name.toLowerCase() !== 'onclick' &&3992 // omit v-model handlers3993 name !== 'onUpdate:modelValue' &&3994 // omit onVnodeXXX hooks3995 !isReservedProp(name)) {3996 hasHydrationEventBinding = true;3997 }3998 if (isEventHandler && isReservedProp(name)) {3999 hasVnodeHook = true;4000 }4001 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||4002 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||4003 value.type === 8 /* COMPOUND_EXPRESSION */) &&4004 getConstantType(value, context) > 0)) {4005 // skip if the prop is a cached handler or has constant value4006 return;4007 }4008 if (name === 'ref') {4009 hasRef = true;4010 }4011 else if (name === 'class') {4012 hasClassBinding = true;4013 }4014 else if (name === 'style') {4015 hasStyleBinding = true;4016 }4017 else if (name !== 'key' && !dynamicPropNames.includes(name)) {4018 dynamicPropNames.push(name);4019 }4020 // treat the dynamic class and style binding of the component as dynamic props4021 if (isComponent &&4022 (name === 'class' || name === 'style') &&4023 !dynamicPropNames.includes(name)) {4024 dynamicPropNames.push(name);4025 }4026 }4027 else {4028 hasDynamicKeys = true;4029 }4030 };4031 for (let i = 0; i < props.length; i++) {4032 // static attribute4033 const prop = props[i];4034 if (prop.type === 6 /* ATTRIBUTE */) {4035 const { loc, name, value } = prop;4036 let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);4037 if (name === 'ref') {4038 hasRef = true;4039 }4040 // skip is on <component>, or is="vue:xxx"4041 if (name === 'is' &&4042 (isComponentTag(tag) ||4043 (value && value.content.startsWith('vue:')) ||4044 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4045 continue;4046 }4047 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));4048 }4049 else {4050 // directives4051 const { name, arg, exp, loc } = prop;4052 const isVBind = name === 'bind';4053 const isVOn = name === 'on';4054 // skip v-slot - it is handled by its dedicated transform.4055 if (name === 'slot') {4056 if (!isComponent) {4057 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4058 }4059 continue;4060 }4061 // skip v-once/v-memo - they are handled by dedicated transforms.4062 if (name === 'once' || name === 'memo') {4063 continue;4064 }4065 // skip v-is and :is on <component>4066 if (name === 'is' ||4067 (isVBind &&4068 isBindKey(arg, 'is') &&4069 (isComponentTag(tag) ||4070 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4071 continue;4072 }4073 // skip v-on in SSR compilation4074 if (isVOn && ssr) {4075 continue;4076 }4077 // special case for v-bind and v-on with no argument4078 if (!arg && (isVBind || isVOn)) {4079 hasDynamicKeys = true;4080 if (exp) {4081 if (properties.length) {4082 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4083 properties = [];4084 }4085 if (isVBind) {4086 {4087 // 2.x v-bind object order compat4088 {4089 const hasOverridableKeys = mergeArgs.some(arg => {4090 if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {4091 return arg.properties.some(({ key }) => {4092 if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||4093 !key.isStatic) {4094 return true;4095 }4096 return (key.content !== 'class' &&4097 key.content !== 'style' &&4098 !isOn(key.content));4099 });4100 }4101 else {4102 // dynamic expression4103 return true;4104 }4105 });4106 if (hasOverridableKeys) {4107 checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);4108 }4109 }4110 if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4111 mergeArgs.unshift(exp);4112 continue;4113 }4114 }4115 mergeArgs.push(exp);4116 }4117 else {4118 // v-on="obj" -> toHandlers(obj)4119 mergeArgs.push({4120 type: 14 /* JS_CALL_EXPRESSION */,4121 loc,4122 callee: context.helper(TO_HANDLERS),4123 arguments: [exp]4124 });4125 }4126 }4127 else {4128 context.onError(createCompilerError(isVBind4129 ? 34 /* X_V_BIND_NO_EXPRESSION */4130 : 35 /* X_V_ON_NO_EXPRESSION */, loc));4131 }4132 continue;4133 }4134 const directiveTransform = context.directiveTransforms[name];4135 if (directiveTransform) {4136 // has built-in directive transform.4137 const { props, needRuntime } = directiveTransform(prop, node, context);4138 !ssr && props.forEach(analyzePatchFlag);4139 properties.push(...props);4140 if (needRuntime) {4141 runtimeDirectives.push(prop);4142 if (isSymbol(needRuntime)) {4143 directiveImportMap.set(prop, needRuntime);4144 }4145 }4146 }4147 else {4148 // no built-in transform, this is a user custom directive.4149 runtimeDirectives.push(prop);4150 }4151 }4152 if (prop.type === 6 /* ATTRIBUTE */ &&4153 prop.name === 'ref' &&4154 context.scopes.vFor > 0 &&4155 checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {4156 properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));4157 }4158 }4159 let propsExpression = undefined;4160 // has v-bind="object" or v-on="object", wrap with mergeProps4161 if (mergeArgs.length) {4162 if (properties.length) {4163 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4164 }4165 if (mergeArgs.length > 1) {4166 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4167 }4168 else {4169 // single v-bind with nothing else - no need for a mergeProps call4170 propsExpression = mergeArgs[0];4171 }4172 }4173 else if (properties.length) {4174 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4175 }4176 // patchFlag analysis4177 if (hasDynamicKeys) {4178 patchFlag |= 16 /* FULL_PROPS */;4179 }4180 else {4181 if (hasClassBinding && !isComponent) {4182 patchFlag |= 2 /* CLASS */;4183 }4184 if (hasStyleBinding && !isComponent) {4185 patchFlag |= 4 /* STYLE */;4186 }4187 if (dynamicPropNames.length) {4188 patchFlag |= 8 /* PROPS */;4189 }4190 if (hasHydrationEventBinding) {4191 patchFlag |= 32 /* HYDRATE_EVENTS */;4192 }4193 }4194 if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4195 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4196 patchFlag |= 512 /* NEED_PATCH */;4197 }4198 // pre-normalize props, SSR is skipped for now4199 if (!context.inSSR && propsExpression) {4200 switch (propsExpression.type) {4201 case 15 /* JS_OBJECT_EXPRESSION */:4202 // means that there is no v-bind,4203 // but still need to deal with dynamic key binding4204 let classKeyIndex = -1;4205 let styleKeyIndex = -1;4206 let hasDynamicKey = false;4207 for (let i = 0; i < propsExpression.properties.length; i++) {4208 const key = propsExpression.properties[i].key;4209 if (isStaticExp(key)) {4210 if (key.content === 'class') {4211 classKeyIndex = i;4212 }4213 else if (key.content === 'style') {4214 styleKeyIndex = i;4215 }4216 }4217 else if (!key.isHandlerKey) {4218 hasDynamicKey = true;4219 }4220 }4221 const classProp = propsExpression.properties[classKeyIndex];4222 const styleProp = propsExpression.properties[styleKeyIndex];4223 // no dynamic key4224 if (!hasDynamicKey) {4225 if (classProp && !isStaticExp(classProp.value)) {4226 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4227 }4228 if (styleProp &&4229 !isStaticExp(styleProp.value) &&4230 // the static style is compiled into an object,4231 // so use `hasStyleBinding` to ensure that it is a dynamic style binding4232 (hasStyleBinding ||4233 // v-bind:style and style both exist,4234 // v-bind:style with static literal object4235 styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4236 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4237 }4238 }4239 else {4240 // dynamic key binding, wrap with `normalizeProps`4241 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4242 }4243 break;4244 case 14 /* JS_CALL_EXPRESSION */:4245 // mergeProps call, do nothing4246 break;4247 default:4248 // single v-bind4249 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4250 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4251 propsExpression4252 ])4253 ]);4254 break;4255 }4256 }4257 return {4258 props: propsExpression,4259 directives: runtimeDirectives,4260 patchFlag,4261 dynamicPropNames4262 };4263}4264// Dedupe props in an object literal.4265// Literal duplicated attributes would have been warned during the parse phase,4266// however, it's possible to encounter duplicated `onXXX` handlers with different4267// modifiers. We also need to merge static and dynamic class / style attributes.4268// - onXXX handlers / style: merge into array4269// - class: merge into single expression with concatenation4270function dedupeProperties(properties) {4271 const knownProps = new Map();4272 const deduped = [];4273 for (let i = 0; i < properties.length; i++) {4274 const prop = properties[i];4275 // dynamic keys are always allowed4276 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4277 deduped.push(prop);4278 continue;4279 }4280 const name = prop.key.content;4281 const existing = knownProps.get(name);4282 if (existing) {4283 if (name === 'style' || name === 'class' || isOn(name)) {4284 mergeAsArray(existing, prop);4285 }4286 // unexpected duplicate, should have emitted error during parse4287 }4288 else {4289 knownProps.set(name, prop);4290 deduped.push(prop);4291 }4292 }4293 return deduped;4294}4295function mergeAsArray(existing, incoming) {4296 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4297 existing.value.elements.push(incoming.value);4298 }4299 else {4300 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4301 }4302}4303function buildDirectiveArgs(dir, context) {4304 const dirArgs = [];4305 const runtime = directiveImportMap.get(dir);4306 if (runtime) {4307 // built-in directive with runtime4308 dirArgs.push(context.helperString(runtime));4309 }4310 else {4311 {4312 // inject statement for resolving directive4313 context.helper(RESOLVE_DIRECTIVE);4314 context.directives.add(dir.name);4315 dirArgs.push(toValidAssetId(dir.name, `directive`));4316 }4317 }4318 const { loc } = dir;4319 if (dir.exp)4320 dirArgs.push(dir.exp);4321 if (dir.arg) {4322 if (!dir.exp) {4323 dirArgs.push(`void 0`);4324 }4325 dirArgs.push(dir.arg);4326 }4327 if (Object.keys(dir.modifiers).length) {4328 if (!dir.arg) {4329 if (!dir.exp) {4330 dirArgs.push(`void 0`);4331 }4332 dirArgs.push(`void 0`);4333 }4334 const trueExpression = createSimpleExpression(`true`, false, loc);4335 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4336 }4337 return createArrayExpression(dirArgs, dir.loc);4338}4339function stringifyDynamicPropNames(props) {4340 let propsNamesString = `[`;4341 for (let i = 0, l = props.length; i < l; i++) {4342 propsNamesString += JSON.stringify(props[i]);4343 if (i < l - 1)4344 propsNamesString += ', ';4345 }4346 return propsNamesString + `]`;4347}4348function isComponentTag(tag) {4349 return tag[0].toLowerCase() + tag.slice(1) === 'component';4350}4351const transformSlotOutlet = (node, context) => {4352 if (isSlotOutlet(node)) {4353 const { children, loc } = node;4354 const { slotName, slotProps } = processSlotOutlet(node, context);4355 const slotArgs = [4356 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4357 slotName,4358 '{}',4359 'undefined',4360 'true'4361 ];4362 let expectedLen = 2;4363 if (slotProps) {4364 slotArgs[2] = slotProps;4365 expectedLen = 3;4366 }4367 if (children.length) {4368 slotArgs[3] = createFunctionExpression([], children, false, false, loc);4369 expectedLen = 4;4370 }4371 if (context.scopeId && !context.slotted) {4372 expectedLen = 5;4373 }4374 slotArgs.splice(expectedLen); // remove unused arguments4375 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4376 }4377};4378function processSlotOutlet(node, context) {4379 let slotName = `"default"`;4380 let slotProps = undefined;4381 const nonNameProps = [];4382 for (let i = 0; i < node.props.length; i++) {4383 const p = node.props[i];4384 if (p.type === 6 /* ATTRIBUTE */) {4385 if (p.value) {4386 if (p.name === 'name') {4387 slotName = JSON.stringify(p.value.content);4388 }4389 else {4390 p.name = camelize(p.name);4391 nonNameProps.push(p);4392 }4393 }4394 }4395 else {4396 if (p.name === 'bind' && isBindKey(p.arg, 'name')) {4397 if (p.exp)4398 slotName = p.exp;4399 }4400 else {4401 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4402 p.arg.content = camelize(p.arg.content);4403 }4404 nonNameProps.push(p);4405 }4406 }4407 }4408 if (nonNameProps.length > 0) {4409 const { props, directives } = buildProps(node, context, nonNameProps);4410 slotProps = props;4411 if (directives.length) {4412 context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4413 }4414 }4415 return {4416 slotName,4417 slotProps4418 };4419}4420const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;4421const transformOn = (dir, node, context, augmentor) => {4422 const { loc, modifiers, arg } = dir;4423 if (!dir.exp && !modifiers.length) {4424 context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));4425 }4426 let eventName;4427 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4428 if (arg.isStatic) {4429 const rawName = arg.content;4430 // for all event listeners, auto convert it to camelCase. See issue #22494431 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);4432 }4433 else {4434 // #23884435 eventName = createCompoundExpression([4436 `${context.helperString(TO_HANDLER_KEY)}(`,4437 arg,4438 `)`4439 ]);4440 }4441 }4442 else {4443 // already a compound expression.4444 eventName = arg;4445 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4446 eventName.children.push(`)`);4447 }4448 // handler processing4449 let exp = dir.exp;4450 if (exp && !exp.content.trim()) {4451 exp = undefined;4452 }4453 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;4454 if (exp) {4455 const isMemberExp = isMemberExpression(exp.content);4456 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4457 const hasMultipleStatements = exp.content.includes(`;`);4458 {4459 validateBrowserExpression(exp, context, false, hasMultipleStatements);4460 }4461 if (isInlineStatement || (shouldCache && isMemberExp)) {4462 // wrap inline statement in a function expression4463 exp = createCompoundExpression([4464 `${isInlineStatement4465 ? `$event`4466 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4467 exp,4468 hasMultipleStatements ? `}` : `)`4469 ]);4470 }4471 }4472 let ret = {4473 props: [4474 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4475 ]4476 };4477 // apply extended compiler augmentor4478 if (augmentor) {4479 ret = augmentor(ret);4480 }4481 if (shouldCache) {4482 // cache handlers so that it's always the same handler being passed down.4483 // this avoids unnecessary re-renders when users use inline handlers on4484 // components.4485 ret.props[0].value = context.cache(ret.props[0].value);4486 }4487 // mark the key as handler for props normalization check4488 ret.props.forEach(p => (p.key.isHandlerKey = true));4489 return ret;4490};4491// v-bind without arg is handled directly in ./transformElements.ts due to it affecting4492// codegen for the entire props object. This transform here is only for v-bind4493// *with* args.4494const transformBind = (dir, _node, context) => {4495 const { exp, modifiers, loc } = dir;4496 const arg = dir.arg;4497 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {4498 arg.children.unshift(`(`);4499 arg.children.push(`) || ""`);4500 }4501 else if (!arg.isStatic) {4502 arg.content = `${arg.content} || ""`;4503 }4504 // .sync is replaced by v-model:arg4505 if (modifiers.includes('camel')) {4506 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4507 if (arg.isStatic) {4508 arg.content = camelize(arg.content);4509 }4510 else {4511 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;4512 }4513 }4514 else {4515 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);4516 arg.children.push(`)`);4517 }4518 }4519 if (!context.inSSR) {4520 if (modifiers.includes('prop')) {4521 injectPrefix(arg, '.');4522 }4523 if (modifiers.includes('attr')) {4524 injectPrefix(arg, '^');4525 }4526 }4527 if (!exp ||4528 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {4529 context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));4530 return {4531 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]4532 };4533 }4534 return {4535 props: [createObjectProperty(arg, exp)]4536 };4537};4538const injectPrefix = (arg, prefix) => {4539 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4540 if (arg.isStatic) {4541 arg.content = prefix + arg.content;4542 }4543 else {4544 arg.content = `\`${prefix}\${${arg.content}}\``;4545 }4546 }4547 else {4548 arg.children.unshift(`'${prefix}' + (`);4549 arg.children.push(`)`);4550 }4551};4552// Merge adjacent text nodes and expressions into a single expression4553// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.4554const transformText = (node, context) => {4555 if (node.type === 0 /* ROOT */ ||4556 node.type === 1 /* ELEMENT */ ||4557 node.type === 11 /* FOR */ ||4558 node.type === 10 /* IF_BRANCH */) {4559 // perform the transform on node exit so that all expressions have already4560 // been processed.4561 return () => {4562 const children = node.children;4563 let currentContainer = undefined;4564 let hasText = false;4565 for (let i = 0; i < children.length; i++) {4566 const child = children[i];4567 if (isText(child)) {4568 hasText = true;4569 for (let j = i + 1; j < children.length; j++) {4570 const next = children[j];4571 if (isText(next)) {4572 if (!currentContainer) {4573 currentContainer = children[i] = {4574 type: 8 /* COMPOUND_EXPRESSION */,4575 loc: child.loc,4576 children: [child]4577 };4578 }4579 // merge adjacent text node into current4580 currentContainer.children.push(` + `, next);4581 children.splice(j, 1);4582 j--;4583 }4584 else {4585 currentContainer = undefined;4586 break;4587 }4588 }4589 }4590 }4591 if (!hasText ||4592 // if this is a plain element with a single text child, leave it4593 // as-is since the runtime has dedicated fast path for this by directly4594 // setting textContent of the element.4595 // for component root it's always normalized anyway.4596 (children.length === 1 &&4597 (node.type === 0 /* ROOT */ ||4598 (node.type === 1 /* ELEMENT */ &&4599 node.tagType === 0 /* ELEMENT */ &&4600 // #37564601 // custom directives can potentially add DOM elements arbitrarily,4602 // we need to avoid setting textContent of the element at runtime4603 // to avoid accidentally overwriting the DOM elements added4604 // by the user through custom directives.4605 !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&4606 !context.directiveTransforms[p.name]) &&4607 // in compat mode, <template> tags with no special directives4608 // will be rendered as a fragment so its children must be4609 // converted into vnodes.4610 !(node.tag === 'template'))))) {4611 return;4612 }4613 // pre-convert text nodes into createTextVNode(text) calls to avoid4614 // runtime normalization.4615 for (let i = 0; i < children.length; i++) {4616 const child = children[i];4617 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {4618 const callArgs = [];4619 // createTextVNode defaults to single whitespace, so if it is a4620 // single space the code could be an empty call to save bytes.4621 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {4622 callArgs.push(child);4623 }4624 // mark dynamic text with flag so it gets patched inside a block4625 if (!context.ssr &&4626 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4627 callArgs.push(1 /* TEXT */ +4628 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));4629 }4630 children[i] = {4631 type: 12 /* TEXT_CALL */,4632 content: child,4633 loc: child.loc,4634 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)4635 };4636 }4637 }4638 };4639 }4640};4641const seen = new WeakSet();4642const transformOnce = (node, context) => {4643 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {4644 if (seen.has(node) || context.inVOnce) {4645 return;4646 }4647 seen.add(node);4648 context.inVOnce = true;4649 context.helper(SET_BLOCK_TRACKING);4650 return () => {4651 context.inVOnce = false;4652 const cur = context.currentNode;4653 if (cur.codegenNode) {4654 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);4655 }4656 };4657 }4658};4659const transformModel = (dir, node, context) => {4660 const { exp, arg } = dir;4661 if (!exp) {4662 context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));4663 return createTransformProps();4664 }4665 const rawExp = exp.loc.source;4666 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;4667 // im SFC <script setup> inline mode, the exp may have been transformed into4668 // _unref(exp)4669 context.bindingMetadata[rawExp];4670 const maybeRef = !true /* SETUP_CONST */;4671 if (!expString.trim() ||4672 (!isMemberExpression(expString) && !maybeRef)) {4673 context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));4674 return createTransformProps();4675 }4676 const propName = arg ? arg : createSimpleExpression('modelValue', true);4677 const eventName = arg4678 ? isStaticExp(arg)4679 ? `onUpdate:${arg.content}`4680 : createCompoundExpression(['"onUpdate:" + ', arg])4681 : `onUpdate:modelValue`;4682 let assignmentExp;4683 const eventArg = context.isTS ? `($event: any)` : `$event`;4684 {4685 assignmentExp = createCompoundExpression([4686 `${eventArg} => ((`,4687 exp,4688 `) = $event)`4689 ]);4690 }4691 const props = [4692 // modelValue: foo4693 createObjectProperty(propName, dir.exp),4694 // "onUpdate:modelValue": $event => (foo = $event)4695 createObjectProperty(eventName, assignmentExp)4696 ];4697 // modelModifiers: { foo: true, "bar-baz": true }4698 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {4699 const modifiers = dir.modifiers4700 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)4701 .join(`, `);4702 const modifiersKey = arg4703 ? isStaticExp(arg)4704 ? `${arg.content}Modifiers`4705 : createCompoundExpression([arg, ' + "Modifiers"'])4706 : `modelModifiers`;4707 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));4708 }4709 return createTransformProps(props);4710};4711function createTransformProps(props = []) {4712 return { props };4713}4714const validDivisionCharRE = /[\w).+\-_$\]]/;4715const transformFilter = (node, context) => {4716 if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {4717 return;4718 }4719 if (node.type === 5 /* INTERPOLATION */) {4720 // filter rewrite is applied before expression transform so only4721 // simple expressions are possible at this stage4722 rewriteFilter(node.content, context);4723 }4724 if (node.type === 1 /* ELEMENT */) {4725 node.props.forEach((prop) => {4726 if (prop.type === 7 /* DIRECTIVE */ &&4727 prop.name !== 'for' &&4728 prop.exp) {4729 rewriteFilter(prop.exp, context);4730 }4731 });4732 }4733};4734function rewriteFilter(node, context) {4735 if (node.type === 4 /* SIMPLE_EXPRESSION */) {4736 parseFilter(node, context);4737 }4738 else {4739 for (let i = 0; i < node.children.length; i++) {4740 const child = node.children[i];4741 if (typeof child !== 'object')4742 continue;4743 if (child.type === 4 /* SIMPLE_EXPRESSION */) {4744 parseFilter(child, context);4745 }4746 else if (child.type === 8 /* COMPOUND_EXPRESSION */) {4747 rewriteFilter(node, context);4748 }4749 else if (child.type === 5 /* INTERPOLATION */) {4750 rewriteFilter(child.content, context);4751 }4752 }4753 }4754}4755function parseFilter(node, context) {4756 const exp = node.content;4757 let inSingle = false;4758 let inDouble = false;4759 let inTemplateString = false;4760 let inRegex = false;4761 let curly = 0;4762 let square = 0;4763 let paren = 0;4764 let lastFilterIndex = 0;4765 let c, prev, i, expression, filters = [];4766 for (i = 0; i < exp.length; i++) {4767 prev = c;4768 c = exp.charCodeAt(i);4769 if (inSingle) {4770 if (c === 0x27 && prev !== 0x5c)4771 inSingle = false;4772 }4773 else if (inDouble) {4774 if (c === 0x22 && prev !== 0x5c)4775 inDouble = false;4776 }4777 else if (inTemplateString) {4778 if (c === 0x60 && prev !== 0x5c)4779 inTemplateString = false;4780 }4781 else if (inRegex) {4782 if (c === 0x2f && prev !== 0x5c)4783 inRegex = false;4784 }4785 else if (c === 0x7c && // pipe4786 exp.charCodeAt(i + 1) !== 0x7c &&4787 exp.charCodeAt(i - 1) !== 0x7c &&4788 !curly &&4789 !square &&4790 !paren) {4791 if (expression === undefined) {4792 // first filter, end of expression4793 lastFilterIndex = i + 1;4794 expression = exp.slice(0, i).trim();4795 }4796 else {4797 pushFilter();4798 }4799 }4800 else {4801 switch (c) {4802 case 0x22:4803 inDouble = true;4804 break; // "4805 case 0x27:4806 inSingle = true;4807 break; // '4808 case 0x60:4809 inTemplateString = true;4810 break; // `4811 case 0x28:4812 paren++;4813 break; // (4814 case 0x29:4815 paren--;4816 break; // )4817 case 0x5b:4818 square++;4819 break; // [4820 case 0x5d:4821 square--;4822 break; // ]4823 case 0x7b:4824 curly++;4825 break; // {4826 case 0x7d:4827 curly--;4828 break; // }4829 }4830 if (c === 0x2f) {4831 // /4832 let j = i - 1;4833 let p;4834 // find first non-whitespace prev char4835 for (; j >= 0; j--) {4836 p = exp.charAt(j);4837 if (p !== ' ')4838 break;4839 }4840 if (!p || !validDivisionCharRE.test(p)) {4841 inRegex = true;4842 }4843 }4844 }4845 }4846 if (expression === undefined) {4847 expression = exp.slice(0, i).trim();4848 }4849 else if (lastFilterIndex !== 0) {4850 pushFilter();4851 }4852 function pushFilter() {4853 filters.push(exp.slice(lastFilterIndex, i).trim());4854 lastFilterIndex = i + 1;4855 }4856 if (filters.length) {4857 warnDeprecation("COMPILER_FILTER" /* COMPILER_FILTERS */, context, node.loc);4858 for (i = 0; i < filters.length; i++) {4859 expression = wrapFilter(expression, filters[i], context);4860 }4861 node.content = expression;4862 }4863}4864function wrapFilter(exp, filter, context) {4865 context.helper(RESOLVE_FILTER);4866 const i = filter.indexOf('(');4867 if (i < 0) {4868 context.filters.add(filter);4869 return `${toValidAssetId(filter, 'filter')}(${exp})`;4870 }4871 else {4872 const name = filter.slice(0, i);4873 const args = filter.slice(i + 1);4874 context.filters.add(name);4875 return `${toValidAssetId(name, 'filter')}(${exp}${args !== ')' ? ',' + args : args}`;4876 }4877}4878const seen$1 = new WeakSet();4879const transformMemo = (node, context) => {4880 if (node.type === 1 /* ELEMENT */) {4881 const dir = findDir(node, 'memo');4882 if (!dir || seen$1.has(node)) {4883 return;4884 }4885 seen$1.add(node);4886 return () => {4887 const codegenNode = node.codegenNode ||4888 context.currentNode.codegenNode;4889 if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {4890 // non-component sub tree should be turned into a block4891 if (node.tagType !== 1 /* COMPONENT */) {4892 makeBlock(codegenNode, context);4893 }4894 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [4895 dir.exp,4896 createFunctionExpression(undefined, codegenNode),4897 `_cache`,4898 String(context.cached++)4899 ]);4900 }4901 };4902 }4903};4904function getBaseTransformPreset(prefixIdentifiers) {4905 return [4906 [4907 transformOnce,4908 transformIf,4909 transformMemo,4910 transformFor,4911 ...([transformFilter] ),4912 ...([transformExpression]4913 ),4914 transformSlotOutlet,4915 transformElement,4916 trackSlotScopes,4917 transformText4918 ],4919 {4920 on: transformOn,4921 bind: transformBind,4922 model: transformModel4923 }4924 ];4925}4926// we name it `baseCompile` so that higher order compilers like4927// @vue/compiler-dom can export `compile` while re-exporting everything else.4928function baseCompile(template, options = {}) {4929 const onError = options.onError || defaultOnError;4930 const isModuleMode = options.mode === 'module';4931 /* istanbul ignore if */4932 {4933 if (options.prefixIdentifiers === true) {4934 onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));4935 }4936 else if (isModuleMode) {4937 onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));4938 }4939 }4940 const prefixIdentifiers = !true ;4941 if (options.cacheHandlers) {4942 onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));4943 }4944 if (options.scopeId && !isModuleMode) {4945 onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));4946 }4947 const ast = isString(template) ? baseParse(template, options) : template;4948 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();4949 transform(ast, extend({}, options, {4950 prefixIdentifiers,4951 nodeTransforms: [4952 ...nodeTransforms,4953 ...(options.nodeTransforms || []) // user transforms4954 ],4955 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms4956 )4957 }));4958 return generate(ast, extend({}, options, {4959 prefixIdentifiers4960 }));4961}4962const noopDirectiveTransform = () => ({ props: [] });4963const V_MODEL_RADIO = Symbol(`vModelRadio` );4964const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );4965const V_MODEL_TEXT = Symbol(`vModelText` );4966const V_MODEL_SELECT = Symbol(`vModelSelect` );4967const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );4968const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );4969const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );4970const V_SHOW = Symbol(`vShow` );4971const TRANSITION = Symbol(`Transition` );4972const TRANSITION_GROUP = Symbol(`TransitionGroup` );4973registerRuntimeHelpers({4974 [V_MODEL_RADIO]: `vModelRadio`,4975 [V_MODEL_CHECKBOX]: `vModelCheckbox`,4976 [V_MODEL_TEXT]: `vModelText`,4977 [V_MODEL_SELECT]: `vModelSelect`,4978 [V_MODEL_DYNAMIC]: `vModelDynamic`,4979 [V_ON_WITH_MODIFIERS]: `withModifiers`,4980 [V_ON_WITH_KEYS]: `withKeys`,4981 [V_SHOW]: `vShow`,4982 [TRANSITION]: `Transition`,4983 [TRANSITION_GROUP]: `TransitionGroup`4984});4985/* eslint-disable no-restricted-globals */4986let decoder;4987function decodeHtmlBrowser(raw, asAttr = false) {4988 if (!decoder) {4989 decoder = document.createElement('div');4990 }4991 if (asAttr) {4992 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '"')}">`;4993 return decoder.children[0].getAttribute('foo');4994 }4995 else {4996 decoder.innerHTML = raw;4997 return decoder.textContent;4998 }4999}5000const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);5001const parserOptions = {5002 isVoidTag,5003 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),5004 isPreTag: tag => tag === 'pre',5005 decodeEntities: decodeHtmlBrowser ,5006 isBuiltInComponent: (tag) => {5007 if (isBuiltInType(tag, `Transition`)) {5008 return TRANSITION;5009 }5010 else if (isBuiltInType(tag, `TransitionGroup`)) {5011 return TRANSITION_GROUP;5012 }5013 },5014 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher5015 getNamespace(tag, parent) {5016 let ns = parent ? parent.ns : 0 /* HTML */;5017 if (parent && ns === 2 /* MATH_ML */) {5018 if (parent.tag === 'annotation-xml') {5019 if (tag === 'svg') {5020 return 1 /* SVG */;5021 }5022 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&5023 a.name === 'encoding' &&5024 a.value != null &&5025 (a.value.content === 'text/html' ||5026 a.value.content === 'application/xhtml+xml'))) {5027 ns = 0 /* HTML */;5028 }5029 }5030 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&5031 tag !== 'mglyph' &&5032 tag !== 'malignmark') {5033 ns = 0 /* HTML */;5034 }5035 }5036 else if (parent && ns === 1 /* SVG */) {5037 if (parent.tag === 'foreignObject' ||5038 parent.tag === 'desc' ||5039 parent.tag === 'title') {5040 ns = 0 /* HTML */;5041 }5042 }5043 if (ns === 0 /* HTML */) {5044 if (tag === 'svg') {5045 return 1 /* SVG */;5046 }5047 if (tag === 'math') {5048 return 2 /* MATH_ML */;5049 }5050 }5051 return ns;5052 },5053 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments5054 getTextMode({ tag, ns }) {5055 if (ns === 0 /* HTML */) {5056 if (tag === 'textarea' || tag === 'title') {5057 return 1 /* RCDATA */;5058 }5059 if (isRawTextContainer(tag)) {5060 return 2 /* RAWTEXT */;5061 }5062 }5063 return 0 /* DATA */;5064 }5065};5066// Parse inline CSS strings for static style attributes into an object.5067// This is a NodeTransform since it works on the static `style` attribute and5068// converts it into a dynamic equivalent:5069// style="color: red" -> :style='{ "color": "red" }'5070// It is then processed by `transformElement` and included in the generated5071// props.5072const transformStyle = node => {5073 if (node.type === 1 /* ELEMENT */) {5074 node.props.forEach((p, i) => {5075 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {5076 // replace p with an expression node5077 node.props[i] = {5078 type: 7 /* DIRECTIVE */,5079 name: `bind`,5080 arg: createSimpleExpression(`style`, true, p.loc),5081 exp: parseInlineCSS(p.value.content, p.loc),5082 modifiers: [],5083 loc: p.loc5084 };5085 }5086 });5087 }5088};5089const parseInlineCSS = (cssText, loc) => {5090 const normalized = parseStringStyle(cssText);5091 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);5092};5093function createDOMCompilerError(code, loc) {5094 return createCompilerError(code, loc, DOMErrorMessages );5095}5096const DOMErrorMessages = {5097 [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,5098 [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,5099 [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,5100 [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,5101 [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,5102 [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,5103 [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,5104 [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,5105 [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,5106 [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,5107 [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`5108};5109const transformVHtml = (dir, node, context) => {5110 const { exp, loc } = dir;5111 if (!exp) {5112 context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));5113 }5114 if (node.children.length) {5115 context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));5116 node.children.length = 0;5117 }5118 return {5119 props: [5120 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))5121 ]5122 };5123};5124const transformVText = (dir, node, context) => {5125 const { exp, loc } = dir;5126 if (!exp) {5127 context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));5128 }5129 if (node.children.length) {5130 context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));5131 node.children.length = 0;5132 }5133 return {5134 props: [5135 createObjectProperty(createSimpleExpression(`textContent`, true), exp5136 ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)5137 : createSimpleExpression('', true))5138 ]5139 };5140};5141const transformModel$1 = (dir, node, context) => {5142 const baseResult = transformModel(dir, node, context);5143 // base transform has errors OR component v-model (only need props)5144 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {5145 return baseResult;5146 }5147 if (dir.arg) {5148 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));5149 }5150 function checkDuplicatedValue() {5151 const value = findProp(node, 'value');5152 if (value) {5153 context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));5154 }5155 }5156 const { tag } = node;5157 const isCustomElement = context.isCustomElement(tag);5158 if (tag === 'input' ||5159 tag === 'textarea' ||5160 tag === 'select' ||5161 isCustomElement) {5162 let directiveToUse = V_MODEL_TEXT;5163 let isInvalidType = false;5164 if (tag === 'input' || isCustomElement) {5165 const type = findProp(node, `type`);5166 if (type) {5167 if (type.type === 7 /* DIRECTIVE */) {5168 // :type="foo"5169 directiveToUse = V_MODEL_DYNAMIC;5170 }5171 else if (type.value) {5172 switch (type.value.content) {5173 case 'radio':5174 directiveToUse = V_MODEL_RADIO;5175 break;5176 case 'checkbox':5177 directiveToUse = V_MODEL_CHECKBOX;5178 break;5179 case 'file':5180 isInvalidType = true;5181 context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));5182 break;5183 default:5184 // text type5185 checkDuplicatedValue();5186 break;5187 }5188 }5189 }5190 else if (hasDynamicKeyVBind(node)) {5191 // element has bindings with dynamic keys, which can possibly contain5192 // "type".5193 directiveToUse = V_MODEL_DYNAMIC;5194 }5195 else {5196 // text type5197 checkDuplicatedValue();5198 }5199 }5200 else if (tag === 'select') {5201 directiveToUse = V_MODEL_SELECT;5202 }5203 else {5204 // textarea5205 checkDuplicatedValue();5206 }5207 // inject runtime directive5208 // by returning the helper symbol via needRuntime5209 // the import will replaced a resolveDirective call.5210 if (!isInvalidType) {5211 baseResult.needRuntime = context.helper(directiveToUse);5212 }5213 }5214 else {5215 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));5216 }5217 // native vmodel doesn't need the `modelValue` props since they are also5218 // passed to the runtime as `binding.value`. removing it reduces code size.5219 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&5220 p.key.content === 'modelValue'));5221 return baseResult;5222};5223const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);5224const isNonKeyModifier = /*#__PURE__*/ makeMap(5225// event propagation management5226`stop,prevent,self,` +5227 // system modifiers + exact5228 `ctrl,shift,alt,meta,exact,` +5229 // mouse5230 `middle`);5231// left & right could be mouse or key modifiers based on event type5232const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');5233const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);5234const resolveModifiers = (key, modifiers, context, loc) => {5235 const keyModifiers = [];5236 const nonKeyModifiers = [];5237 const eventOptionModifiers = [];5238 for (let i = 0; i < modifiers.length; i++) {5239 const modifier = modifiers[i];5240 if (modifier === 'native' &&5241 checkCompatEnabled("COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */, context, loc)) {5242 eventOptionModifiers.push(modifier);5243 }5244 else if (isEventOptionModifier(modifier)) {5245 // eventOptionModifiers: modifiers for addEventListener() options,5246 // e.g. .passive & .capture5247 eventOptionModifiers.push(modifier);5248 }5249 else {5250 // runtimeModifiers: modifiers that needs runtime guards5251 if (maybeKeyModifier(modifier)) {5252 if (isStaticExp(key)) {5253 if (isKeyboardEvent(key.content)) {5254 keyModifiers.push(modifier);5255 }
...
compiler-core.esm-bundler.js
Source:compiler-core.esm-bundler.js
...785 // in v3 mode, only enable if explicitly set to true786 // otherwise enable for any non-false value787 return mode === 3 ? value === true : value !== false;788}789function checkCompatEnabled(key, context, loc, ...args) {790 const enabled = isCompatEnabled(key, context);791 if ((process.env.NODE_ENV !== 'production') && enabled) {792 warnDeprecation(key, context, loc, ...args);793 }794 return enabled;795}796function warnDeprecation(key, context, loc, ...args) {797 const val = getCompatValue(key, context);798 if (val === 'suppress-warning') {799 return;800 }801 const { message, link } = deprecationData[key];802 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;803 const err = new SyntaxError(msg);804 err.code = key;805 if (loc)806 err.loc = loc;807 context.onWarn(err);808}809// The default decoder only provides escapes for characters reserved as part of810// the template syntax, and is only used if the custom renderer did not provide811// a platform-specific decoder.812const decodeRE = /&(gt|lt|amp|apos|quot);/g;813const decodeMap = {814 gt: '>',815 lt: '<',816 amp: '&',817 apos: "'",818 quot: '"'819};820const defaultParserOptions = {821 delimiters: [`{{`, `}}`],822 getNamespace: () => 0 /* HTML */,823 getTextMode: () => 0 /* DATA */,824 isVoidTag: NO,825 isPreTag: NO,826 isCustomElement: NO,827 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),828 onError: defaultOnError,829 onWarn: defaultOnWarn,830 comments: (process.env.NODE_ENV !== 'production')831};832function baseParse(content, options = {}) {833 const context = createParserContext(content, options);834 const start = getCursor(context);835 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));836}837function createParserContext(content, rawOptions) {838 const options = extend({}, defaultParserOptions);839 let key;840 for (key in rawOptions) {841 // @ts-ignore842 options[key] =843 rawOptions[key] === undefined844 ? defaultParserOptions[key]845 : rawOptions[key];846 }847 return {848 options,849 column: 1,850 line: 1,851 offset: 0,852 originalSource: content,853 source: content,854 inPre: false,855 inVPre: false,856 onWarn: options.onWarn857 };858}859function parseChildren(context, mode, ancestors) {860 const parent = last(ancestors);861 const ns = parent ? parent.ns : 0 /* HTML */;862 const nodes = [];863 while (!isEnd(context, mode, ancestors)) {864 const s = context.source;865 let node = undefined;866 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {867 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {868 // '{{'869 node = parseInterpolation(context, mode);870 }871 else if (mode === 0 /* DATA */ && s[0] === '<') {872 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state873 if (s.length === 1) {874 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);875 }876 else if (s[1] === '!') {877 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state878 if (startsWith(s, '<!--')) {879 node = parseComment(context);880 }881 else if (startsWith(s, '<!DOCTYPE')) {882 // Ignore DOCTYPE by a limitation.883 node = parseBogusComment(context);884 }885 else if (startsWith(s, '<![CDATA[')) {886 if (ns !== 0 /* HTML */) {887 node = parseCDATA(context, ancestors);888 }889 else {890 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);891 node = parseBogusComment(context);892 }893 }894 else {895 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);896 node = parseBogusComment(context);897 }898 }899 else if (s[1] === '/') {900 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state901 if (s.length === 2) {902 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);903 }904 else if (s[2] === '>') {905 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);906 advanceBy(context, 3);907 continue;908 }909 else if (/[a-z]/i.test(s[2])) {910 emitError(context, 23 /* X_INVALID_END_TAG */);911 parseTag(context, 1 /* End */, parent);912 continue;913 }914 else {915 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);916 node = parseBogusComment(context);917 }918 }919 else if (/[a-z]/i.test(s[1])) {920 node = parseElement(context, ancestors);921 // 2.x <template> with no directive compat922 if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&923 node &&924 node.tag === 'template' &&925 !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&926 isSpecialTemplateDirective(p.name))) {927 (process.env.NODE_ENV !== 'production') &&928 warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);929 node = node.children;930 }931 }932 else if (s[1] === '?') {933 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);934 node = parseBogusComment(context);935 }936 else {937 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);938 }939 }940 }941 if (!node) {942 node = parseText(context, mode);943 }944 if (isArray(node)) {945 for (let i = 0; i < node.length; i++) {946 pushNode(nodes, node[i]);947 }948 }949 else {950 pushNode(nodes, node);951 }952 }953 // Whitespace handling strategy like v2954 let removedWhitespace = false;955 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {956 const shouldCondense = context.options.whitespace !== 'preserve';957 for (let i = 0; i < nodes.length; i++) {958 const node = nodes[i];959 if (!context.inPre && node.type === 2 /* TEXT */) {960 if (!/[^\t\r\n\f ]/.test(node.content)) {961 const prev = nodes[i - 1];962 const next = nodes[i + 1];963 // Remove if:964 // - the whitespace is the first or last node, or:965 // - (condense mode) the whitespace is adjacent to a comment, or:966 // - (condense mode) the whitespace is between two elements AND contains newline967 if (!prev ||968 !next ||969 (shouldCondense &&970 (prev.type === 3 /* COMMENT */ ||971 next.type === 3 /* COMMENT */ ||972 (prev.type === 1 /* ELEMENT */ &&973 next.type === 1 /* ELEMENT */ &&974 /[\r\n]/.test(node.content))))) {975 removedWhitespace = true;976 nodes[i] = null;977 }978 else {979 // Otherwise, the whitespace is condensed into a single space980 node.content = ' ';981 }982 }983 else if (shouldCondense) {984 // in condense mode, consecutive whitespaces in text are condensed985 // down to a single space.986 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');987 }988 }989 // Remove comment nodes if desired by configuration.990 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {991 removedWhitespace = true;992 nodes[i] = null;993 }994 }995 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {996 // remove leading newline per html spec997 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element998 const first = nodes[0];999 if (first && first.type === 2 /* TEXT */) {1000 first.content = first.content.replace(/^\r?\n/, '');1001 }1002 }1003 }1004 return removedWhitespace ? nodes.filter(Boolean) : nodes;1005}1006function pushNode(nodes, node) {1007 if (node.type === 2 /* TEXT */) {1008 const prev = last(nodes);1009 // Merge if both this and the previous node are text and those are1010 // consecutive. This happens for cases like "a < b".1011 if (prev &&1012 prev.type === 2 /* TEXT */ &&1013 prev.loc.end.offset === node.loc.start.offset) {1014 prev.content += node.content;1015 prev.loc.end = node.loc.end;1016 prev.loc.source += node.loc.source;1017 return;1018 }1019 }1020 nodes.push(node);1021}1022function parseCDATA(context, ancestors) {1023 advanceBy(context, 9);1024 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1025 if (context.source.length === 0) {1026 emitError(context, 6 /* EOF_IN_CDATA */);1027 }1028 else {1029 advanceBy(context, 3);1030 }1031 return nodes;1032}1033function parseComment(context) {1034 const start = getCursor(context);1035 let content;1036 // Regular comment.1037 const match = /--(\!)?>/.exec(context.source);1038 if (!match) {1039 content = context.source.slice(4);1040 advanceBy(context, context.source.length);1041 emitError(context, 7 /* EOF_IN_COMMENT */);1042 }1043 else {1044 if (match.index <= 3) {1045 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1046 }1047 if (match[1]) {1048 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1049 }1050 content = context.source.slice(4, match.index);1051 // Advancing with reporting nested comments.1052 const s = context.source.slice(0, match.index);1053 let prevIndex = 1, nestedIndex = 0;1054 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1055 advanceBy(context, nestedIndex - prevIndex + 1);1056 if (nestedIndex + 4 < s.length) {1057 emitError(context, 16 /* NESTED_COMMENT */);1058 }1059 prevIndex = nestedIndex + 1;1060 }1061 advanceBy(context, match.index + match[0].length - prevIndex + 1);1062 }1063 return {1064 type: 3 /* COMMENT */,1065 content,1066 loc: getSelection(context, start)1067 };1068}1069function parseBogusComment(context) {1070 const start = getCursor(context);1071 const contentStart = context.source[1] === '?' ? 1 : 2;1072 let content;1073 const closeIndex = context.source.indexOf('>');1074 if (closeIndex === -1) {1075 content = context.source.slice(contentStart);1076 advanceBy(context, context.source.length);1077 }1078 else {1079 content = context.source.slice(contentStart, closeIndex);1080 advanceBy(context, closeIndex + 1);1081 }1082 return {1083 type: 3 /* COMMENT */,1084 content,1085 loc: getSelection(context, start)1086 };1087}1088function parseElement(context, ancestors) {1089 // Start tag.1090 const wasInPre = context.inPre;1091 const wasInVPre = context.inVPre;1092 const parent = last(ancestors);1093 const element = parseTag(context, 0 /* Start */, parent);1094 const isPreBoundary = context.inPre && !wasInPre;1095 const isVPreBoundary = context.inVPre && !wasInVPre;1096 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1097 // #4030 self-closing <pre> tag1098 if (isPreBoundary) {1099 context.inPre = false;1100 }1101 if (isVPreBoundary) {1102 context.inVPre = false;1103 }1104 return element;1105 }1106 // Children.1107 ancestors.push(element);1108 const mode = context.options.getTextMode(element, parent);1109 const children = parseChildren(context, mode, ancestors);1110 ancestors.pop();1111 // 2.x inline-template compat1112 {1113 const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1114 if (inlineTemplateProp &&1115 checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1116 const loc = getSelection(context, element.loc.end);1117 inlineTemplateProp.value = {1118 type: 2 /* TEXT */,1119 content: loc.source,1120 loc1121 };1122 }1123 }1124 element.children = children;1125 // End tag.1126 if (startsWithEndTagOpen(context.source, element.tag)) {1127 parseTag(context, 1 /* End */, parent);1128 }1129 else {1130 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1131 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1132 const first = children[0];1133 if (first && startsWith(first.loc.source, '<!--')) {1134 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1135 }1136 }1137 }1138 element.loc = getSelection(context, element.loc.start);1139 if (isPreBoundary) {1140 context.inPre = false;1141 }1142 if (isVPreBoundary) {1143 context.inVPre = false;1144 }1145 return element;1146}1147const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);1148function parseTag(context, type, parent) {1149 // Tag open.1150 const start = getCursor(context);1151 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1152 const tag = match[1];1153 const ns = context.options.getNamespace(tag, parent);1154 advanceBy(context, match[0].length);1155 advanceSpaces(context);1156 // save current state in case we need to re-parse attributes with v-pre1157 const cursor = getCursor(context);1158 const currentSource = context.source;1159 // check <pre> tag1160 if (context.options.isPreTag(tag)) {1161 context.inPre = true;1162 }1163 // Attributes.1164 let props = parseAttributes(context, type);1165 // check v-pre1166 if (type === 0 /* Start */ &&1167 !context.inVPre &&1168 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1169 context.inVPre = true;1170 // reset context1171 extend(context, cursor);1172 context.source = currentSource;1173 // re-parse attrs and filter out v-pre itself1174 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1175 }1176 // Tag close.1177 let isSelfClosing = false;1178 if (context.source.length === 0) {1179 emitError(context, 9 /* EOF_IN_TAG */);1180 }1181 else {1182 isSelfClosing = startsWith(context.source, '/>');1183 if (type === 1 /* End */ && isSelfClosing) {1184 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1185 }1186 advanceBy(context, isSelfClosing ? 2 : 1);1187 }1188 if (type === 1 /* End */) {1189 return;1190 }1191 // 2.x deprecation checks1192 if ((process.env.NODE_ENV !== 'production') &&1193 isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1194 let hasIf = false;1195 let hasFor = false;1196 for (let i = 0; i < props.length; i++) {1197 const p = props[i];1198 if (p.type === 7 /* DIRECTIVE */) {1199 if (p.name === 'if') {1200 hasIf = true;1201 }1202 else if (p.name === 'for') {1203 hasFor = true;1204 }1205 }1206 if (hasIf && hasFor) {1207 warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1208 }1209 }1210 }1211 let tagType = 0 /* ELEMENT */;1212 if (!context.inVPre) {1213 if (tag === 'slot') {1214 tagType = 2 /* SLOT */;1215 }1216 else if (tag === 'template') {1217 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1218 tagType = 3 /* TEMPLATE */;1219 }1220 }1221 else if (isComponent(tag, props, context)) {1222 tagType = 1 /* COMPONENT */;1223 }1224 }1225 return {1226 type: 1 /* ELEMENT */,1227 ns,1228 tag,1229 tagType,1230 props,1231 isSelfClosing,1232 children: [],1233 loc: getSelection(context, start),1234 codegenNode: undefined // to be created during transform phase1235 };1236}1237function isComponent(tag, props, context) {1238 const options = context.options;1239 if (options.isCustomElement(tag)) {1240 return false;1241 }1242 if (tag === 'component' ||1243 /^[A-Z]/.test(tag) ||1244 isCoreComponent(tag) ||1245 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1246 (options.isNativeTag && !options.isNativeTag(tag))) {1247 return true;1248 }1249 // at this point the tag should be a native tag, but check for potential "is"1250 // casting1251 for (let i = 0; i < props.length; i++) {1252 const p = props[i];1253 if (p.type === 6 /* ATTRIBUTE */) {1254 if (p.name === 'is' && p.value) {1255 if (p.value.content.startsWith('vue:')) {1256 return true;1257 }1258 else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1259 return true;1260 }1261 }1262 }1263 else {1264 // directive1265 // v-is (TODO Deprecate)1266 if (p.name === 'is') {1267 return true;1268 }1269 else if (1270 // :is on plain element - only treat as component in compat mode1271 p.name === 'bind' &&1272 isBindKey(p.arg, 'is') &&1273 true &&1274 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1275 return true;1276 }1277 }1278 }1279}1280function parseAttributes(context, type) {1281 const props = [];1282 const attributeNames = new Set();1283 while (context.source.length > 0 &&1284 !startsWith(context.source, '>') &&1285 !startsWith(context.source, '/>')) {1286 if (startsWith(context.source, '/')) {1287 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1288 advanceBy(context, 1);1289 advanceSpaces(context);1290 continue;1291 }1292 if (type === 1 /* End */) {1293 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1294 }1295 const attr = parseAttribute(context, attributeNames);1296 // Trim whitespace between class1297 // https://github.com/vuejs/vue-next/issues/42511298 if (attr.type === 6 /* ATTRIBUTE */ &&1299 attr.value &&1300 attr.name === 'class') {1301 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1302 }1303 if (type === 0 /* Start */) {1304 props.push(attr);1305 }1306 if (/^[^\t\r\n\f />]/.test(context.source)) {1307 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1308 }1309 advanceSpaces(context);1310 }1311 return props;1312}1313function parseAttribute(context, nameSet) {1314 // Name.1315 const start = getCursor(context);1316 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1317 const name = match[0];1318 if (nameSet.has(name)) {1319 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1320 }1321 nameSet.add(name);1322 if (name[0] === '=') {1323 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1324 }1325 {1326 const pattern = /["'<]/g;1327 let m;1328 while ((m = pattern.exec(name))) {1329 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1330 }1331 }1332 advanceBy(context, name.length);1333 // Value1334 let value = undefined;1335 if (/^[\t\r\n\f ]*=/.test(context.source)) {1336 advanceSpaces(context);1337 advanceBy(context, 1);1338 advanceSpaces(context);1339 value = parseAttributeValue(context);1340 if (!value) {1341 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1342 }1343 }1344 const loc = getSelection(context, start);1345 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1346 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1347 let isPropShorthand = startsWith(name, '.');1348 let dirName = match[1] ||1349 (isPropShorthand || startsWith(name, ':')1350 ? 'bind'1351 : startsWith(name, '@')1352 ? 'on'1353 : 'slot');1354 let arg;1355 if (match[2]) {1356 const isSlot = dirName === 'slot';1357 const startOffset = name.lastIndexOf(match[2]);1358 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1359 let content = match[2];1360 let isStatic = true;1361 if (content.startsWith('[')) {1362 isStatic = false;1363 if (!content.endsWith(']')) {1364 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1365 content = content.slice(1);1366 }1367 else {1368 content = content.slice(1, content.length - 1);1369 }1370 }1371 else if (isSlot) {1372 // #1241 special case for v-slot: vuetify relies extensively on slot1373 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1374 // supports such usage so we are keeping it consistent with 2.x.1375 content += match[3] || '';1376 }1377 arg = {1378 type: 4 /* SIMPLE_EXPRESSION */,1379 content,1380 isStatic,1381 constType: isStatic1382 ? 3 /* CAN_STRINGIFY */1383 : 0 /* NOT_CONSTANT */,1384 loc1385 };1386 }1387 if (value && value.isQuoted) {1388 const valueLoc = value.loc;1389 valueLoc.start.offset++;1390 valueLoc.start.column++;1391 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1392 valueLoc.source = valueLoc.source.slice(1, -1);1393 }1394 const modifiers = match[3] ? match[3].slice(1).split('.') : [];1395 if (isPropShorthand)1396 modifiers.push('prop');1397 // 2.x compat v-bind:foo.sync -> v-model:foo1398 if (dirName === 'bind' && arg) {1399 if (modifiers.includes('sync') &&1400 checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1401 dirName = 'model';1402 modifiers.splice(modifiers.indexOf('sync'), 1);1403 }1404 if ((process.env.NODE_ENV !== 'production') && modifiers.includes('prop')) {1405 checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1406 }1407 }1408 return {1409 type: 7 /* DIRECTIVE */,1410 name: dirName,1411 exp: value && {1412 type: 4 /* SIMPLE_EXPRESSION */,1413 content: value.content,1414 isStatic: false,1415 // Treat as non-constant by default. This can be potentially set to1416 // other values by `transformExpression` to make it eligible for hoisting.1417 constType: 0 /* NOT_CONSTANT */,1418 loc: value.loc1419 },1420 arg,1421 modifiers,1422 loc1423 };1424 }1425 // missing directive name or illegal directive name1426 if (!context.inVPre && startsWith(name, 'v-')) {1427 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1428 }1429 return {1430 type: 6 /* ATTRIBUTE */,1431 name,1432 value: value && {1433 type: 2 /* TEXT */,1434 content: value.content,1435 loc: value.loc1436 },1437 loc1438 };1439}1440function parseAttributeValue(context) {1441 const start = getCursor(context);1442 let content;1443 const quote = context.source[0];1444 const isQuoted = quote === `"` || quote === `'`;1445 if (isQuoted) {1446 // Quoted value.1447 advanceBy(context, 1);1448 const endIndex = context.source.indexOf(quote);1449 if (endIndex === -1) {1450 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1451 }1452 else {1453 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1454 advanceBy(context, 1);1455 }1456 }1457 else {1458 // Unquoted1459 const match = /^[^\t\r\n\f >]+/.exec(context.source);1460 if (!match) {1461 return undefined;1462 }1463 const unexpectedChars = /["'<=`]/g;1464 let m;1465 while ((m = unexpectedChars.exec(match[0]))) {1466 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1467 }1468 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1469 }1470 return { content, isQuoted, loc: getSelection(context, start) };1471}1472function parseInterpolation(context, mode) {1473 const [open, close] = context.options.delimiters;1474 const closeIndex = context.source.indexOf(close, open.length);1475 if (closeIndex === -1) {1476 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1477 return undefined;1478 }1479 const start = getCursor(context);1480 advanceBy(context, open.length);1481 const innerStart = getCursor(context);1482 const innerEnd = getCursor(context);1483 const rawContentLength = closeIndex - open.length;1484 const rawContent = context.source.slice(0, rawContentLength);1485 const preTrimContent = parseTextData(context, rawContentLength, mode);1486 const content = preTrimContent.trim();1487 const startOffset = preTrimContent.indexOf(content);1488 if (startOffset > 0) {1489 advancePositionWithMutation(innerStart, rawContent, startOffset);1490 }1491 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1492 advancePositionWithMutation(innerEnd, rawContent, endOffset);1493 advanceBy(context, close.length);1494 return {1495 type: 5 /* INTERPOLATION */,1496 content: {1497 type: 4 /* SIMPLE_EXPRESSION */,1498 isStatic: false,1499 // Set `isConstant` to false by default and will decide in transformExpression1500 constType: 0 /* NOT_CONSTANT */,1501 content,1502 loc: getSelection(context, innerStart, innerEnd)1503 },1504 loc: getSelection(context, start)1505 };1506}1507function parseText(context, mode) {1508 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1509 let endIndex = context.source.length;1510 for (let i = 0; i < endTokens.length; i++) {1511 const index = context.source.indexOf(endTokens[i], 1);1512 if (index !== -1 && endIndex > index) {1513 endIndex = index;1514 }1515 }1516 const start = getCursor(context);1517 const content = parseTextData(context, endIndex, mode);1518 return {1519 type: 2 /* TEXT */,1520 content,1521 loc: getSelection(context, start)1522 };1523}1524/**1525 * Get text data with a given length from the current location.1526 * This translates HTML entities in the text data.1527 */1528function parseTextData(context, length, mode) {1529 const rawText = context.source.slice(0, length);1530 advanceBy(context, length);1531 if (mode === 2 /* RAWTEXT */ ||1532 mode === 3 /* CDATA */ ||1533 rawText.indexOf('&') === -1) {1534 return rawText;1535 }1536 else {1537 // DATA or RCDATA containing "&"". Entity decoding required.1538 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1539 }1540}1541function getCursor(context) {1542 const { column, line, offset } = context;1543 return { column, line, offset };1544}1545function getSelection(context, start, end) {1546 end = end || getCursor(context);1547 return {1548 start,1549 end,1550 source: context.originalSource.slice(start.offset, end.offset)1551 };1552}1553function last(xs) {1554 return xs[xs.length - 1];1555}1556function startsWith(source, searchString) {1557 return source.startsWith(searchString);1558}1559function advanceBy(context, numberOfCharacters) {1560 const { source } = context;1561 advancePositionWithMutation(context, source, numberOfCharacters);1562 context.source = source.slice(numberOfCharacters);1563}1564function advanceSpaces(context) {1565 const match = /^[\t\r\n\f ]+/.exec(context.source);1566 if (match) {1567 advanceBy(context, match[0].length);1568 }1569}1570function getNewPosition(context, start, numberOfCharacters) {1571 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1572}1573function emitError(context, code, offset, loc = getCursor(context)) {1574 if (offset) {1575 loc.offset += offset;1576 loc.column += offset;1577 }1578 context.options.onError(createCompilerError(code, {1579 start: loc,1580 end: loc,1581 source: ''1582 }));1583}1584function isEnd(context, mode, ancestors) {1585 const s = context.source;1586 switch (mode) {1587 case 0 /* DATA */:1588 if (startsWith(s, '</')) {1589 // TODO: probably bad performance1590 for (let i = ancestors.length - 1; i >= 0; --i) {1591 if (startsWithEndTagOpen(s, ancestors[i].tag)) {1592 return true;1593 }1594 }1595 }1596 break;1597 case 1 /* RCDATA */:1598 case 2 /* RAWTEXT */: {1599 const parent = last(ancestors);1600 if (parent && startsWithEndTagOpen(s, parent.tag)) {1601 return true;1602 }1603 break;1604 }1605 case 3 /* CDATA */:1606 if (startsWith(s, ']]>')) {1607 return true;1608 }1609 break;1610 }1611 return !s;1612}1613function startsWithEndTagOpen(source, tag) {1614 return (startsWith(source, '</') &&1615 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1616 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1617}1618function hoistStatic(root, context) {1619 walk(root, context, 1620 // Root node is unfortunately non-hoistable due to potential parent1621 // fallthrough attributes.1622 isSingleElementRoot(root, root.children[0]));1623}1624function isSingleElementRoot(root, child) {1625 const { children } = root;1626 return (children.length === 1 &&1627 child.type === 1 /* ELEMENT */ &&1628 !isSlotOutlet(child));1629}1630function walk(node, context, doNotHoistNode = false) {1631 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces1632 // static bindings with expressions. These expressions are guaranteed to be1633 // constant so they are still eligible for hoisting, but they are only1634 // available at runtime and therefore cannot be evaluated ahead of time.1635 // This is only a concern for pre-stringification (via transformHoist by1636 // @vue/compiler-dom), but doing it here allows us to perform only one full1637 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its1638 // stringification threshold is met.1639 let canStringify = true;1640 const { children } = node;1641 const originalCount = children.length;1642 let hoistedCount = 0;1643 for (let i = 0; i < children.length; i++) {1644 const child = children[i];1645 // only plain elements & text calls are eligible for hoisting.1646 if (child.type === 1 /* ELEMENT */ &&1647 child.tagType === 0 /* ELEMENT */) {1648 const constantType = doNotHoistNode1649 ? 0 /* NOT_CONSTANT */1650 : getConstantType(child, context);1651 if (constantType > 0 /* NOT_CONSTANT */) {1652 if (constantType < 3 /* CAN_STRINGIFY */) {1653 canStringify = false;1654 }1655 if (constantType >= 2 /* CAN_HOIST */) {1656 child.codegenNode.patchFlag =1657 -1 /* HOISTED */ + ((process.env.NODE_ENV !== 'production') ? ` /* HOISTED */` : ``);1658 child.codegenNode = context.hoist(child.codegenNode);1659 hoistedCount++;1660 continue;1661 }1662 }1663 else {1664 // node may contain dynamic children, but its props may be eligible for1665 // hoisting.1666 const codegenNode = child.codegenNode;1667 if (codegenNode.type === 13 /* VNODE_CALL */) {1668 const flag = getPatchFlag(codegenNode);1669 if ((!flag ||1670 flag === 512 /* NEED_PATCH */ ||1671 flag === 1 /* TEXT */) &&1672 getGeneratedPropsConstantType(child, context) >=1673 2 /* CAN_HOIST */) {1674 const props = getNodeProps(child);1675 if (props) {1676 codegenNode.props = context.hoist(props);1677 }1678 }1679 if (codegenNode.dynamicProps) {1680 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1681 }1682 }1683 }1684 }1685 else if (child.type === 12 /* TEXT_CALL */) {1686 const contentType = getConstantType(child.content, context);1687 if (contentType > 0) {1688 if (contentType < 3 /* CAN_STRINGIFY */) {1689 canStringify = false;1690 }1691 if (contentType >= 2 /* CAN_HOIST */) {1692 child.codegenNode = context.hoist(child.codegenNode);1693 hoistedCount++;1694 }1695 }1696 }1697 // walk further1698 if (child.type === 1 /* ELEMENT */) {1699 const isComponent = child.tagType === 1 /* COMPONENT */;1700 if (isComponent) {1701 context.scopes.vSlot++;1702 }1703 walk(child, context);1704 if (isComponent) {1705 context.scopes.vSlot--;1706 }1707 }1708 else if (child.type === 11 /* FOR */) {1709 // Do not hoist v-for single child because it has to be a block1710 walk(child, context, child.children.length === 1);1711 }1712 else if (child.type === 9 /* IF */) {1713 for (let i = 0; i < child.branches.length; i++) {1714 // Do not hoist v-if single child because it has to be a block1715 walk(child.branches[i], context, child.branches[i].children.length === 1);1716 }1717 }1718 }1719 if (canStringify && hoistedCount && context.transformHoist) {1720 context.transformHoist(children, context, node);1721 }1722 // all children were hoisted - the entire children array is hoistable.1723 if (hoistedCount &&1724 hoistedCount === originalCount &&1725 node.type === 1 /* ELEMENT */ &&1726 node.tagType === 0 /* ELEMENT */ &&1727 node.codegenNode &&1728 node.codegenNode.type === 13 /* VNODE_CALL */ &&1729 isArray(node.codegenNode.children)) {1730 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1731 }1732}1733function getConstantType(node, context) {1734 const { constantCache } = context;1735 switch (node.type) {1736 case 1 /* ELEMENT */:1737 if (node.tagType !== 0 /* ELEMENT */) {1738 return 0 /* NOT_CONSTANT */;1739 }1740 const cached = constantCache.get(node);1741 if (cached !== undefined) {1742 return cached;1743 }1744 const codegenNode = node.codegenNode;1745 if (codegenNode.type !== 13 /* VNODE_CALL */) {1746 return 0 /* NOT_CONSTANT */;1747 }1748 const flag = getPatchFlag(codegenNode);1749 if (!flag) {1750 let returnType = 3 /* CAN_STRINGIFY */;1751 // Element itself has no patch flag. However we still need to check:1752 // 1. Even for a node with no patch flag, it is possible for it to contain1753 // non-hoistable expressions that refers to scope variables, e.g. compiler1754 // injected keys or cached event handlers. Therefore we need to always1755 // check the codegenNode's props to be sure.1756 const generatedPropsType = getGeneratedPropsConstantType(node, context);1757 if (generatedPropsType === 0 /* NOT_CONSTANT */) {1758 constantCache.set(node, 0 /* NOT_CONSTANT */);1759 return 0 /* NOT_CONSTANT */;1760 }1761 if (generatedPropsType < returnType) {1762 returnType = generatedPropsType;1763 }1764 // 2. its children.1765 for (let i = 0; i < node.children.length; i++) {1766 const childType = getConstantType(node.children[i], context);1767 if (childType === 0 /* NOT_CONSTANT */) {1768 constantCache.set(node, 0 /* NOT_CONSTANT */);1769 return 0 /* NOT_CONSTANT */;1770 }1771 if (childType < returnType) {1772 returnType = childType;1773 }1774 }1775 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01776 // type, check if any of the props can cause the type to be lowered1777 // we can skip can_patch because it's guaranteed by the absence of a1778 // patchFlag.1779 if (returnType > 1 /* CAN_SKIP_PATCH */) {1780 for (let i = 0; i < node.props.length; i++) {1781 const p = node.props[i];1782 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1783 const expType = getConstantType(p.exp, context);1784 if (expType === 0 /* NOT_CONSTANT */) {1785 constantCache.set(node, 0 /* NOT_CONSTANT */);1786 return 0 /* NOT_CONSTANT */;1787 }1788 if (expType < returnType) {1789 returnType = expType;1790 }1791 }1792 }1793 }1794 // only svg/foreignObject could be block here, however if they are1795 // static then they don't need to be blocks since there will be no1796 // nested updates.1797 if (codegenNode.isBlock) {1798 context.removeHelper(OPEN_BLOCK);1799 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1800 codegenNode.isBlock = false;1801 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1802 }1803 constantCache.set(node, returnType);1804 return returnType;1805 }1806 else {1807 constantCache.set(node, 0 /* NOT_CONSTANT */);1808 return 0 /* NOT_CONSTANT */;1809 }1810 case 2 /* TEXT */:1811 case 3 /* COMMENT */:1812 return 3 /* CAN_STRINGIFY */;1813 case 9 /* IF */:1814 case 11 /* FOR */:1815 case 10 /* IF_BRANCH */:1816 return 0 /* NOT_CONSTANT */;1817 case 5 /* INTERPOLATION */:1818 case 12 /* TEXT_CALL */:1819 return getConstantType(node.content, context);1820 case 4 /* SIMPLE_EXPRESSION */:1821 return node.constType;1822 case 8 /* COMPOUND_EXPRESSION */:1823 let returnType = 3 /* CAN_STRINGIFY */;1824 for (let i = 0; i < node.children.length; i++) {1825 const child = node.children[i];1826 if (isString(child) || isSymbol(child)) {1827 continue;1828 }1829 const childType = getConstantType(child, context);1830 if (childType === 0 /* NOT_CONSTANT */) {1831 return 0 /* NOT_CONSTANT */;1832 }1833 else if (childType < returnType) {1834 returnType = childType;1835 }1836 }1837 return returnType;1838 default:1839 if ((process.env.NODE_ENV !== 'production')) ;1840 return 0 /* NOT_CONSTANT */;1841 }1842}1843const allowHoistedHelperSet = new Set([1844 NORMALIZE_CLASS,1845 NORMALIZE_STYLE,1846 NORMALIZE_PROPS,1847 GUARD_REACTIVE_PROPS1848]);1849function getConstantTypeOfHelperCall(value, context) {1850 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&1851 !isString(value.callee) &&1852 allowHoistedHelperSet.has(value.callee)) {1853 const arg = value.arguments[0];1854 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {1855 return getConstantType(arg, context);1856 }1857 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {1858 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`1859 return getConstantTypeOfHelperCall(arg, context);1860 }1861 }1862 return 0 /* NOT_CONSTANT */;1863}1864function getGeneratedPropsConstantType(node, context) {1865 let returnType = 3 /* CAN_STRINGIFY */;1866 const props = getNodeProps(node);1867 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {1868 const { properties } = props;1869 for (let i = 0; i < properties.length; i++) {1870 const { key, value } = properties[i];1871 const keyType = getConstantType(key, context);1872 if (keyType === 0 /* NOT_CONSTANT */) {1873 return keyType;1874 }1875 if (keyType < returnType) {1876 returnType = keyType;1877 }1878 let valueType;1879 if (value.type === 4 /* SIMPLE_EXPRESSION */) {1880 valueType = getConstantType(value, context);1881 }1882 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {1883 // some helper calls can be hoisted,1884 // such as the `normalizeProps` generated by the compiler for pre-normalize class,1885 // in this case we need to respect the ConstantType of the helper's argments1886 valueType = getConstantTypeOfHelperCall(value, context);1887 }1888 else {1889 valueType = 0 /* NOT_CONSTANT */;1890 }1891 if (valueType === 0 /* NOT_CONSTANT */) {1892 return valueType;1893 }1894 if (valueType < returnType) {1895 returnType = valueType;1896 }1897 }1898 }1899 return returnType;1900}1901function getNodeProps(node) {1902 const codegenNode = node.codegenNode;1903 if (codegenNode.type === 13 /* VNODE_CALL */) {1904 return codegenNode.props;1905 }1906}1907function getPatchFlag(node) {1908 const flag = node.patchFlag;1909 return flag ? parseInt(flag, 10) : undefined;1910}1911function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {1912 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);1913 const context = {1914 // options1915 selfName: nameMatch && capitalize(camelize$1(nameMatch[1])),1916 prefixIdentifiers,1917 hoistStatic,1918 cacheHandlers,1919 nodeTransforms,1920 directiveTransforms,1921 transformHoist,1922 isBuiltInComponent,1923 isCustomElement,1924 expressionPlugins,1925 scopeId,1926 slotted,1927 ssr,1928 inSSR,1929 ssrCssVars,1930 bindingMetadata,1931 inline,1932 isTS,1933 onError,1934 onWarn,1935 compatConfig,1936 // state1937 root,1938 helpers: new Map(),1939 components: new Set(),1940 directives: new Set(),1941 hoists: [],1942 imports: [],1943 constantCache: new Map(),1944 temps: 0,1945 cached: 0,1946 identifiers: Object.create(null),1947 scopes: {1948 vFor: 0,1949 vSlot: 0,1950 vPre: 0,1951 vOnce: 01952 },1953 parent: null,1954 currentNode: root,1955 childIndex: 0,1956 inVOnce: false,1957 // methods1958 helper(name) {1959 const count = context.helpers.get(name) || 0;1960 context.helpers.set(name, count + 1);1961 return name;1962 },1963 removeHelper(name) {1964 const count = context.helpers.get(name);1965 if (count) {1966 const currentCount = count - 1;1967 if (!currentCount) {1968 context.helpers.delete(name);1969 }1970 else {1971 context.helpers.set(name, currentCount);1972 }1973 }1974 },1975 helperString(name) {1976 return `_${helperNameMap[context.helper(name)]}`;1977 },1978 replaceNode(node) {1979 /* istanbul ignore if */1980 if ((process.env.NODE_ENV !== 'production')) {1981 if (!context.currentNode) {1982 throw new Error(`Node being replaced is already removed.`);1983 }1984 if (!context.parent) {1985 throw new Error(`Cannot replace root node.`);1986 }1987 }1988 context.parent.children[context.childIndex] = context.currentNode = node;1989 },1990 removeNode(node) {1991 if ((process.env.NODE_ENV !== 'production') && !context.parent) {1992 throw new Error(`Cannot remove root node.`);1993 }1994 const list = context.parent.children;1995 const removalIndex = node1996 ? list.indexOf(node)1997 : context.currentNode1998 ? context.childIndex1999 : -1;2000 /* istanbul ignore if */2001 if ((process.env.NODE_ENV !== 'production') && removalIndex < 0) {2002 throw new Error(`node being removed is not a child of current parent`);2003 }2004 if (!node || node === context.currentNode) {2005 // current node removed2006 context.currentNode = null;2007 context.onNodeRemoved();2008 }2009 else {2010 // sibling node removed2011 if (context.childIndex > removalIndex) {2012 context.childIndex--;2013 context.onNodeRemoved();2014 }2015 }2016 context.parent.children.splice(removalIndex, 1);2017 },2018 onNodeRemoved: () => { },2019 addIdentifiers(exp) {2020 },2021 removeIdentifiers(exp) {2022 },2023 hoist(exp) {2024 if (isString(exp))2025 exp = createSimpleExpression(exp);2026 context.hoists.push(exp);2027 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2028 identifier.hoisted = exp;2029 return identifier;2030 },2031 cache(exp, isVNode = false) {2032 return createCacheExpression(context.cached++, exp, isVNode);2033 }2034 };2035 {2036 context.filters = new Set();2037 }2038 return context;2039}2040function transform(root, options) {2041 const context = createTransformContext(root, options);2042 traverseNode(root, context);2043 if (options.hoistStatic) {2044 hoistStatic(root, context);2045 }2046 if (!options.ssr) {2047 createRootCodegen(root, context);2048 }2049 // finalize meta information2050 root.helpers = [...context.helpers.keys()];2051 root.components = [...context.components];2052 root.directives = [...context.directives];2053 root.imports = context.imports;2054 root.hoists = context.hoists;2055 root.temps = context.temps;2056 root.cached = context.cached;2057 {2058 root.filters = [...context.filters];2059 }2060}2061function createRootCodegen(root, context) {2062 const { helper } = context;2063 const { children } = root;2064 if (children.length === 1) {2065 const child = children[0];2066 // if the single child is an element, turn it into a block.2067 if (isSingleElementRoot(root, child) && child.codegenNode) {2068 // single element root is never hoisted so codegenNode will never be2069 // SimpleExpressionNode2070 const codegenNode = child.codegenNode;2071 if (codegenNode.type === 13 /* VNODE_CALL */) {2072 makeBlock(codegenNode, context);2073 }2074 root.codegenNode = codegenNode;2075 }2076 else {2077 // - single <slot/>, IfNode, ForNode: already blocks.2078 // - single text node: always patched.2079 // root codegen falls through via genNode()2080 root.codegenNode = child;2081 }2082 }2083 else if (children.length > 1) {2084 // root has multiple nodes - return a fragment block.2085 let patchFlag = 64 /* STABLE_FRAGMENT */;2086 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];2087 // check if the fragment actually contains a single valid child with2088 // the rest being comments2089 if ((process.env.NODE_ENV !== 'production') &&2090 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2091 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2092 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2093 }2094 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, undefined, false /* isComponent */);2095 }2096 else ;2097}2098function traverseChildren(parent, context) {2099 let i = 0;2100 const nodeRemoved = () => {2101 i--;2102 };2103 for (; i < parent.children.length; i++) {2104 const child = parent.children[i];2105 if (isString(child))2106 continue;2107 context.parent = parent;2108 context.childIndex = i;2109 context.onNodeRemoved = nodeRemoved;2110 traverseNode(child, context);2111 }2112}2113function traverseNode(node, context) {2114 context.currentNode = node;2115 // apply transform plugins2116 const { nodeTransforms } = context;2117 const exitFns = [];2118 for (let i = 0; i < nodeTransforms.length; i++) {2119 const onExit = nodeTransforms[i](node, context);2120 if (onExit) {2121 if (isArray(onExit)) {2122 exitFns.push(...onExit);2123 }2124 else {2125 exitFns.push(onExit);2126 }2127 }2128 if (!context.currentNode) {2129 // node was removed2130 return;2131 }2132 else {2133 // node may have been replaced2134 node = context.currentNode;2135 }2136 }2137 switch (node.type) {2138 case 3 /* COMMENT */:2139 if (!context.ssr) {2140 // inject import for the Comment symbol, which is needed for creating2141 // comment nodes with `createVNode`2142 context.helper(CREATE_COMMENT);2143 }2144 break;2145 case 5 /* INTERPOLATION */:2146 // no need to traverse, but we need to inject toString helper2147 if (!context.ssr) {2148 context.helper(TO_DISPLAY_STRING);2149 }2150 break;2151 // for container types, further traverse downwards2152 case 9 /* IF */:2153 for (let i = 0; i < node.branches.length; i++) {2154 traverseNode(node.branches[i], context);2155 }2156 break;2157 case 10 /* IF_BRANCH */:2158 case 11 /* FOR */:2159 case 1 /* ELEMENT */:2160 case 0 /* ROOT */:2161 traverseChildren(node, context);2162 break;2163 }2164 // exit transforms2165 context.currentNode = node;2166 let i = exitFns.length;2167 while (i--) {2168 exitFns[i]();2169 }2170}2171function createStructuralDirectiveTransform(name, fn) {2172 const matches = isString(name)2173 ? (n) => n === name2174 : (n) => name.test(n);2175 return (node, context) => {2176 if (node.type === 1 /* ELEMENT */) {2177 const { props } = node;2178 // structural directive transforms are not concerned with slots2179 // as they are handled separately in vSlot.ts2180 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2181 return;2182 }2183 const exitFns = [];2184 for (let i = 0; i < props.length; i++) {2185 const prop = props[i];2186 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2187 // structural directives are removed to avoid infinite recursion2188 // also we remove them *before* applying so that it can further2189 // traverse itself in case it moves the node around2190 props.splice(i, 1);2191 i--;2192 const onExit = fn(node, prop, context);2193 if (onExit)2194 exitFns.push(onExit);2195 }2196 }2197 return exitFns;2198 }2199 };2200}2201const PURE_ANNOTATION = `/*#__PURE__*/`;2202function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {2203 const context = {2204 mode,2205 prefixIdentifiers,2206 sourceMap,2207 filename,2208 scopeId,2209 optimizeImports,2210 runtimeGlobalName,2211 runtimeModuleName,2212 ssrRuntimeModuleName,2213 ssr,2214 isTS,2215 inSSR,2216 source: ast.loc.source,2217 code: ``,2218 column: 1,2219 line: 1,2220 offset: 0,2221 indentLevel: 0,2222 pure: false,2223 map: undefined,2224 helper(key) {2225 return `_${helperNameMap[key]}`;2226 },2227 push(code, node) {2228 context.code += code;2229 },2230 indent() {2231 newline(++context.indentLevel);2232 },2233 deindent(withoutNewLine = false) {2234 if (withoutNewLine) {2235 --context.indentLevel;2236 }2237 else {2238 newline(--context.indentLevel);2239 }2240 },2241 newline() {2242 newline(context.indentLevel);2243 }2244 };2245 function newline(n) {2246 context.push('\n' + ` `.repeat(n));2247 }2248 return context;2249}2250function generate(ast, options = {}) {2251 const context = createCodegenContext(ast, options);2252 if (options.onContextCreated)2253 options.onContextCreated(context);2254 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2255 const hasHelpers = ast.helpers.length > 0;2256 const useWithBlock = !prefixIdentifiers && mode !== 'module';2257 // preambles2258 // in setup() inline mode, the preamble is generated in a sub context2259 // and returned separately.2260 const preambleContext = context;2261 {2262 genFunctionPreamble(ast, preambleContext);2263 }2264 // enter render function2265 const functionName = ssr ? `ssrRender` : `render`;2266 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2267 const signature = args.join(', ');2268 {2269 push(`function ${functionName}(${signature}) {`);2270 }2271 indent();2272 if (useWithBlock) {2273 push(`with (_ctx) {`);2274 indent();2275 // function mode const declarations should be inside with block2276 // also they should be renamed to avoid collision with user properties2277 if (hasHelpers) {2278 push(`const { ${ast.helpers2279 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2280 .join(', ')} } = _Vue`);2281 push(`\n`);2282 newline();2283 }2284 }2285 // generate asset resolution statements2286 if (ast.components.length) {2287 genAssets(ast.components, 'component', context);2288 if (ast.directives.length || ast.temps > 0) {2289 newline();2290 }2291 }2292 if (ast.directives.length) {2293 genAssets(ast.directives, 'directive', context);2294 if (ast.temps > 0) {2295 newline();2296 }2297 }2298 if (ast.filters && ast.filters.length) {2299 newline();2300 genAssets(ast.filters, 'filter', context);2301 newline();2302 }2303 if (ast.temps > 0) {2304 push(`let `);2305 for (let i = 0; i < ast.temps; i++) {2306 push(`${i > 0 ? `, ` : ``}_temp${i}`);2307 }2308 }2309 if (ast.components.length || ast.directives.length || ast.temps) {2310 push(`\n`);2311 newline();2312 }2313 // generate the VNode tree expression2314 if (!ssr) {2315 push(`return `);2316 }2317 if (ast.codegenNode) {2318 genNode(ast.codegenNode, context);2319 }2320 else {2321 push(`null`);2322 }2323 if (useWithBlock) {2324 deindent();2325 push(`}`);2326 }2327 deindent();2328 push(`}`);2329 return {2330 ast,2331 code: context.code,2332 preamble: ``,2333 // SourceMapGenerator does have toJSON() method but it's not in the types2334 map: context.map ? context.map.toJSON() : undefined2335 };2336}2337function genFunctionPreamble(ast, context) {2338 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2339 const VueBinding = runtimeGlobalName;2340 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2341 // Generate const declaration for helpers2342 // In prefix mode, we place the const declaration at top so it's done2343 // only once; But if we not prefixing, we place the declaration inside the2344 // with block so it doesn't incur the `in` check cost for every helper access.2345 if (ast.helpers.length > 0) {2346 {2347 // "with" mode.2348 // save Vue in a separate variable to avoid collision2349 push(`const _Vue = ${VueBinding}\n`);2350 // in "with" mode, helpers are declared inside the with block to avoid2351 // has check cost, but hoists are lifted out of the function - we need2352 // to provide the helper here.2353 if (ast.hoists.length) {2354 const staticHelpers = [2355 CREATE_VNODE,2356 CREATE_ELEMENT_VNODE,2357 CREATE_COMMENT,2358 CREATE_TEXT,2359 CREATE_STATIC2360 ]2361 .filter(helper => ast.helpers.includes(helper))2362 .map(aliasHelper)2363 .join(', ');2364 push(`const { ${staticHelpers} } = _Vue\n`);2365 }2366 }2367 }2368 genHoists(ast.hoists, context);2369 newline();2370 push(`return `);2371}2372function genAssets(assets, type, { helper, push, newline, isTS }) {2373 const resolver = helper(type === 'filter'2374 ? RESOLVE_FILTER2375 : type === 'component'2376 ? RESOLVE_COMPONENT2377 : RESOLVE_DIRECTIVE);2378 for (let i = 0; i < assets.length; i++) {2379 let id = assets[i];2380 // potential component implicit self-reference inferred from SFC filename2381 const maybeSelfReference = id.endsWith('__self');2382 if (maybeSelfReference) {2383 id = id.slice(0, -6);2384 }2385 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2386 if (i < assets.length - 1) {2387 newline();2388 }2389 }2390}2391function genHoists(hoists, context) {2392 if (!hoists.length) {2393 return;2394 }2395 context.pure = true;2396 const { push, newline, helper, scopeId, mode } = context;2397 newline();2398 for (let i = 0; i < hoists.length; i++) {2399 const exp = hoists[i];2400 if (exp) {2401 push(`const _hoisted_${i + 1} = ${``}`);2402 genNode(exp, context);2403 newline();2404 }2405 }2406 context.pure = false;2407}2408function isText$1(n) {2409 return (isString(n) ||2410 n.type === 4 /* SIMPLE_EXPRESSION */ ||2411 n.type === 2 /* TEXT */ ||2412 n.type === 5 /* INTERPOLATION */ ||2413 n.type === 8 /* COMPOUND_EXPRESSION */);2414}2415function genNodeListAsArray(nodes, context) {2416 const multilines = nodes.length > 3 ||2417 (((process.env.NODE_ENV !== 'production')) && nodes.some(n => isArray(n) || !isText$1(n)));2418 context.push(`[`);2419 multilines && context.indent();2420 genNodeList(nodes, context, multilines);2421 multilines && context.deindent();2422 context.push(`]`);2423}2424function genNodeList(nodes, context, multilines = false, comma = true) {2425 const { push, newline } = context;2426 for (let i = 0; i < nodes.length; i++) {2427 const node = nodes[i];2428 if (isString(node)) {2429 push(node);2430 }2431 else if (isArray(node)) {2432 genNodeListAsArray(node, context);2433 }2434 else {2435 genNode(node, context);2436 }2437 if (i < nodes.length - 1) {2438 if (multilines) {2439 comma && push(',');2440 newline();2441 }2442 else {2443 comma && push(', ');2444 }2445 }2446 }2447}2448function genNode(node, context) {2449 if (isString(node)) {2450 context.push(node);2451 return;2452 }2453 if (isSymbol(node)) {2454 context.push(context.helper(node));2455 return;2456 }2457 switch (node.type) {2458 case 1 /* ELEMENT */:2459 case 9 /* IF */:2460 case 11 /* FOR */:2461 (process.env.NODE_ENV !== 'production') &&2462 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2463 `Apply appropriate transforms first.`);2464 genNode(node.codegenNode, context);2465 break;2466 case 2 /* TEXT */:2467 genText(node, context);2468 break;2469 case 4 /* SIMPLE_EXPRESSION */:2470 genExpression(node, context);2471 break;2472 case 5 /* INTERPOLATION */:2473 genInterpolation(node, context);2474 break;2475 case 12 /* TEXT_CALL */:2476 genNode(node.codegenNode, context);2477 break;2478 case 8 /* COMPOUND_EXPRESSION */:2479 genCompoundExpression(node, context);2480 break;2481 case 3 /* COMMENT */:2482 genComment(node, context);2483 break;2484 case 13 /* VNODE_CALL */:2485 genVNodeCall(node, context);2486 break;2487 case 14 /* JS_CALL_EXPRESSION */:2488 genCallExpression(node, context);2489 break;2490 case 15 /* JS_OBJECT_EXPRESSION */:2491 genObjectExpression(node, context);2492 break;2493 case 17 /* JS_ARRAY_EXPRESSION */:2494 genArrayExpression(node, context);2495 break;2496 case 18 /* JS_FUNCTION_EXPRESSION */:2497 genFunctionExpression(node, context);2498 break;2499 case 19 /* JS_CONDITIONAL_EXPRESSION */:2500 genConditionalExpression(node, context);2501 break;2502 case 20 /* JS_CACHE_EXPRESSION */:2503 genCacheExpression(node, context);2504 break;2505 case 21 /* JS_BLOCK_STATEMENT */:2506 genNodeList(node.body, context, true, false);2507 break;2508 // SSR only types2509 case 22 /* JS_TEMPLATE_LITERAL */:2510 break;2511 case 23 /* JS_IF_STATEMENT */:2512 break;2513 case 24 /* JS_ASSIGNMENT_EXPRESSION */:2514 break;2515 case 25 /* JS_SEQUENCE_EXPRESSION */:2516 break;2517 case 26 /* JS_RETURN_STATEMENT */:2518 break;2519 /* istanbul ignore next */2520 case 10 /* IF_BRANCH */:2521 // noop2522 break;2523 default:2524 if ((process.env.NODE_ENV !== 'production')) {2525 assert(false, `unhandled codegen node type: ${node.type}`);2526 // make sure we exhaust all possible types2527 const exhaustiveCheck = node;2528 return exhaustiveCheck;2529 }2530 }2531}2532function genText(node, context) {2533 context.push(JSON.stringify(node.content), node);2534}2535function genExpression(node, context) {2536 const { content, isStatic } = node;2537 context.push(isStatic ? JSON.stringify(content) : content, node);2538}2539function genInterpolation(node, context) {2540 const { push, helper, pure } = context;2541 if (pure)2542 push(PURE_ANNOTATION);2543 push(`${helper(TO_DISPLAY_STRING)}(`);2544 genNode(node.content, context);2545 push(`)`);2546}2547function genCompoundExpression(node, context) {2548 for (let i = 0; i < node.children.length; i++) {2549 const child = node.children[i];2550 if (isString(child)) {2551 context.push(child);2552 }2553 else {2554 genNode(child, context);2555 }2556 }2557}2558function genExpressionAsPropertyKey(node, context) {2559 const { push } = context;2560 if (node.type === 8 /* COMPOUND_EXPRESSION */) {2561 push(`[`);2562 genCompoundExpression(node, context);2563 push(`]`);2564 }2565 else if (node.isStatic) {2566 // only quote keys if necessary2567 const text = isSimpleIdentifier(node.content)2568 ? node.content2569 : JSON.stringify(node.content);2570 push(text, node);2571 }2572 else {2573 push(`[${node.content}]`, node);2574 }2575}2576function genComment(node, context) {2577 const { push, helper, pure } = context;2578 if (pure) {2579 push(PURE_ANNOTATION);2580 }2581 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2582}2583function genVNodeCall(node, context) {2584 const { push, helper, pure } = context;2585 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2586 if (directives) {2587 push(helper(WITH_DIRECTIVES) + `(`);2588 }2589 if (isBlock) {2590 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2591 }2592 if (pure) {2593 push(PURE_ANNOTATION);2594 }2595 const callHelper = isBlock2596 ? getVNodeBlockHelper(context.inSSR, isComponent)2597 : getVNodeHelper(context.inSSR, isComponent);2598 push(helper(callHelper) + `(`, node);2599 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2600 push(`)`);2601 if (isBlock) {2602 push(`)`);2603 }2604 if (directives) {2605 push(`, `);2606 genNode(directives, context);2607 push(`)`);2608 }2609}2610function genNullableArgs(args) {2611 let i = args.length;2612 while (i--) {2613 if (args[i] != null)2614 break;2615 }2616 return args.slice(0, i + 1).map(arg => arg || `null`);2617}2618// JavaScript2619function genCallExpression(node, context) {2620 const { push, helper, pure } = context;2621 const callee = isString(node.callee) ? node.callee : helper(node.callee);2622 if (pure) {2623 push(PURE_ANNOTATION);2624 }2625 push(callee + `(`, node);2626 genNodeList(node.arguments, context);2627 push(`)`);2628}2629function genObjectExpression(node, context) {2630 const { push, indent, deindent, newline } = context;2631 const { properties } = node;2632 if (!properties.length) {2633 push(`{}`, node);2634 return;2635 }2636 const multilines = properties.length > 1 ||2637 (((process.env.NODE_ENV !== 'production')) &&2638 properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2639 push(multilines ? `{` : `{ `);2640 multilines && indent();2641 for (let i = 0; i < properties.length; i++) {2642 const { key, value } = properties[i];2643 // key2644 genExpressionAsPropertyKey(key, context);2645 push(`: `);2646 // value2647 genNode(value, context);2648 if (i < properties.length - 1) {2649 // will only reach this if it's multilines2650 push(`,`);2651 newline();2652 }2653 }2654 multilines && deindent();2655 push(multilines ? `}` : ` }`);2656}2657function genArrayExpression(node, context) {2658 genNodeListAsArray(node.elements, context);2659}2660function genFunctionExpression(node, context) {2661 const { push, indent, deindent } = context;2662 const { params, returns, body, newline, isSlot } = node;2663 if (isSlot) {2664 // wrap slot functions with owner context2665 push(`_${helperNameMap[WITH_CTX]}(`);2666 }2667 push(`(`, node);2668 if (isArray(params)) {2669 genNodeList(params, context);2670 }2671 else if (params) {2672 genNode(params, context);2673 }2674 push(`) => `);2675 if (newline || body) {2676 push(`{`);2677 indent();2678 }2679 if (returns) {2680 if (newline) {2681 push(`return `);2682 }2683 if (isArray(returns)) {2684 genNodeListAsArray(returns, context);2685 }2686 else {2687 genNode(returns, context);2688 }2689 }2690 else if (body) {2691 genNode(body, context);2692 }2693 if (newline || body) {2694 deindent();2695 push(`}`);2696 }2697 if (isSlot) {2698 if (node.isNonScopedSlot) {2699 push(`, undefined, true`);2700 }2701 push(`)`);2702 }2703}2704function genConditionalExpression(node, context) {2705 const { test, consequent, alternate, newline: needNewline } = node;2706 const { push, indent, deindent, newline } = context;2707 if (test.type === 4 /* SIMPLE_EXPRESSION */) {2708 const needsParens = !isSimpleIdentifier(test.content);2709 needsParens && push(`(`);2710 genExpression(test, context);2711 needsParens && push(`)`);2712 }2713 else {2714 push(`(`);2715 genNode(test, context);2716 push(`)`);2717 }2718 needNewline && indent();2719 context.indentLevel++;2720 needNewline || push(` `);2721 push(`? `);2722 genNode(consequent, context);2723 context.indentLevel--;2724 needNewline && newline();2725 needNewline || push(` `);2726 push(`: `);2727 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2728 if (!isNested) {2729 context.indentLevel++;2730 }2731 genNode(alternate, context);2732 if (!isNested) {2733 context.indentLevel--;2734 }2735 needNewline && deindent(true /* without newline */);2736}2737function genCacheExpression(node, context) {2738 const { push, helper, indent, deindent, newline } = context;2739 push(`_cache[${node.index}] || (`);2740 if (node.isVNode) {2741 indent();2742 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2743 newline();2744 }2745 push(`_cache[${node.index}] = `);2746 genNode(node.value, context);2747 if (node.isVNode) {2748 push(`,`);2749 newline();2750 push(`${helper(SET_BLOCK_TRACKING)}(1),`);2751 newline();2752 push(`_cache[${node.index}]`);2753 deindent();2754 }2755 push(`)`);2756}2757function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2758 {2759 return;2760 }2761}2762function isReferencedIdentifier(id, parent, parentStack) {2763 {2764 return false;2765 }2766}2767function isInDestructureAssignment(parent, parentStack) {2768 if (parent &&2769 (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {2770 let i = parentStack.length;2771 while (i--) {2772 const p = parentStack[i];2773 if (p.type === 'AssignmentExpression') {2774 return true;2775 }2776 else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {2777 break;2778 }2779 }2780 }2781 return false;2782}2783function walkFunctionParams(node, onIdent) {2784 for (const p of node.params) {2785 for (const id of extractIdentifiers(p)) {2786 onIdent(id);2787 }2788 }2789}2790function walkBlockDeclarations(block, onIdent) {2791 for (const stmt of block.body) {2792 if (stmt.type === 'VariableDeclaration') {2793 if (stmt.declare)2794 continue;2795 for (const decl of stmt.declarations) {2796 for (const id of extractIdentifiers(decl.id)) {2797 onIdent(id);2798 }2799 }2800 }2801 else if (stmt.type === 'FunctionDeclaration' ||2802 stmt.type === 'ClassDeclaration') {2803 if (stmt.declare || !stmt.id)2804 continue;2805 onIdent(stmt.id);2806 }2807 }2808}2809function extractIdentifiers(param, nodes = []) {2810 switch (param.type) {2811 case 'Identifier':2812 nodes.push(param);2813 break;2814 case 'MemberExpression':2815 let object = param;2816 while (object.type === 'MemberExpression') {2817 object = object.object;2818 }2819 nodes.push(object);2820 break;2821 case 'ObjectPattern':2822 for (const prop of param.properties) {2823 if (prop.type === 'RestElement') {2824 extractIdentifiers(prop.argument, nodes);2825 }2826 else {2827 extractIdentifiers(prop.value, nodes);2828 }2829 }2830 break;2831 case 'ArrayPattern':2832 param.elements.forEach(element => {2833 if (element)2834 extractIdentifiers(element, nodes);2835 });2836 break;2837 case 'RestElement':2838 extractIdentifiers(param.argument, nodes);2839 break;2840 case 'AssignmentPattern':2841 extractIdentifiers(param.left, nodes);2842 break;2843 }2844 return nodes;2845}2846const isFunctionType = (node) => {2847 return /Function(?:Expression|Declaration)$|Method$/.test(node.type);2848};2849const isStaticProperty = (node) => node &&2850 (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&2851 !node.computed;2852const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;2853// these keywords should not appear inside expressions, but operators like2854// typeof, instanceof and in are allowed2855const prohibitedKeywordRE = new RegExp('\\b' +2856 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +2857 'super,throw,while,yield,delete,export,import,return,switch,default,' +2858 'extends,finally,continue,debugger,function,arguments,typeof,void')2859 .split(',')2860 .join('\\b|\\b') +2861 '\\b');2862// strip strings in expressions2863const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;2864/**2865 * Validate a non-prefixed expression.2866 * This is only called when using the in-browser runtime compiler since it2867 * doesn't prefix expressions.2868 */2869function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {2870 const exp = node.content;2871 // empty expressions are validated per-directive since some directives2872 // do allow empty expressions.2873 if (!exp.trim()) {2874 return;2875 }2876 try {2877 new Function(asRawStatements2878 ? ` ${exp} `2879 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);2880 }2881 catch (e) {2882 let message = e.message;2883 const keywordMatch = exp2884 .replace(stripStringRE, '')2885 .match(prohibitedKeywordRE);2886 if (keywordMatch) {2887 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;2888 }2889 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));2890 }2891}2892const transformExpression = (node, context) => {2893 if (node.type === 5 /* INTERPOLATION */) {2894 node.content = processExpression(node.content, context);2895 }2896 else if (node.type === 1 /* ELEMENT */) {2897 // handle directives on element2898 for (let i = 0; i < node.props.length; i++) {2899 const dir = node.props[i];2900 // do not process for v-on & v-for since they are special handled2901 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {2902 const exp = dir.exp;2903 const arg = dir.arg;2904 // do not process exp if this is v-on:arg - we need special handling2905 // for wrapping inline statements.2906 if (exp &&2907 exp.type === 4 /* SIMPLE_EXPRESSION */ &&2908 !(dir.name === 'on' && arg)) {2909 dir.exp = processExpression(exp, context, 2910 // slot args must be processed as function params2911 dir.name === 'slot');2912 }2913 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {2914 dir.arg = processExpression(arg, context);2915 }2916 }2917 }2918 }2919};2920// Important: since this function uses Node.js only dependencies, it should2921// always be used with a leading !true check so that it can be2922// tree-shaken from the browser build.2923function processExpression(node, context, 2924// some expressions like v-slot props & v-for aliases should be parsed as2925// function params2926asParams = false, 2927// v-on handler values may contain multiple statements2928asRawStatements = false, localVars = Object.create(context.identifiers)) {2929 {2930 if ((process.env.NODE_ENV !== 'production')) {2931 // simple in-browser validation (same logic in 2.x)2932 validateBrowserExpression(node, context, asParams, asRawStatements);2933 }2934 return node;2935 }2936}2937const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {2938 return processIf(node, dir, context, (ifNode, branch, isRoot) => {2939 // #1587: We need to dynamically increment the key based on the current2940 // node's sibling nodes, since chained v-if/else branches are2941 // rendered at the same depth2942 const siblings = context.parent.children;2943 let i = siblings.indexOf(ifNode);2944 let key = 0;2945 while (i-- >= 0) {2946 const sibling = siblings[i];2947 if (sibling && sibling.type === 9 /* IF */) {2948 key += sibling.branches.length;2949 }2950 }2951 // Exit callback. Complete the codegenNode when all children have been2952 // transformed.2953 return () => {2954 if (isRoot) {2955 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);2956 }2957 else {2958 // attach this branch's codegen node to the v-if root.2959 const parentCondition = getParentCondition(ifNode.codegenNode);2960 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);2961 }2962 };2963 });2964});2965// target-agnostic transform used for both Client and SSR2966function processIf(node, dir, context, processCodegen) {2967 if (dir.name !== 'else' &&2968 (!dir.exp || !dir.exp.content.trim())) {2969 const loc = dir.exp ? dir.exp.loc : node.loc;2970 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));2971 dir.exp = createSimpleExpression(`true`, false, loc);2972 }2973 if ((process.env.NODE_ENV !== 'production') && true && dir.exp) {2974 validateBrowserExpression(dir.exp, context);2975 }2976 if (dir.name === 'if') {2977 const branch = createIfBranch(node, dir);2978 const ifNode = {2979 type: 9 /* IF */,2980 loc: node.loc,2981 branches: [branch]2982 };2983 context.replaceNode(ifNode);2984 if (processCodegen) {2985 return processCodegen(ifNode, branch, true);2986 }2987 }2988 else {2989 // locate the adjacent v-if2990 const siblings = context.parent.children;2991 const comments = [];2992 let i = siblings.indexOf(node);2993 while (i-- >= -1) {2994 const sibling = siblings[i];2995 if ((process.env.NODE_ENV !== 'production') && sibling && sibling.type === 3 /* COMMENT */) {2996 context.removeNode(sibling);2997 comments.unshift(sibling);2998 continue;2999 }3000 if (sibling &&3001 sibling.type === 2 /* TEXT */ &&3002 !sibling.content.trim().length) {3003 context.removeNode(sibling);3004 continue;3005 }3006 if (sibling && sibling.type === 9 /* IF */) {3007 // Check if v-else was followed by v-else-if3008 if (dir.name === 'else-if' &&3009 sibling.branches[sibling.branches.length - 1].condition === undefined) {3010 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3011 }3012 // move the node to the if node's branches3013 context.removeNode();3014 const branch = createIfBranch(node, dir);3015 if ((process.env.NODE_ENV !== 'production') &&3016 comments.length &&3017 // #3619 ignore comments if the v-if is direct child of <transition>3018 !(context.parent &&3019 context.parent.type === 1 /* ELEMENT */ &&3020 isBuiltInType(context.parent.tag, 'transition'))) {3021 branch.children = [...comments, ...branch.children];3022 }3023 // check if user is forcing same key on different branches3024 if ((process.env.NODE_ENV !== 'production') || !true) {3025 const key = branch.userKey;3026 if (key) {3027 sibling.branches.forEach(({ userKey }) => {3028 if (isSameKey(userKey, key)) {3029 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3030 }3031 });3032 }3033 }3034 sibling.branches.push(branch);3035 const onExit = processCodegen && processCodegen(sibling, branch, false);3036 // since the branch was removed, it will not be traversed.3037 // make sure to traverse here.3038 traverseNode(branch, context);3039 // call on exit3040 if (onExit)3041 onExit();3042 // make sure to reset currentNode after traversal to indicate this3043 // node has been removed.3044 context.currentNode = null;3045 }3046 else {3047 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3048 }3049 break;3050 }3051 }3052}3053function createIfBranch(node, dir) {3054 return {3055 type: 10 /* IF_BRANCH */,3056 loc: node.loc,3057 condition: dir.name === 'else' ? undefined : dir.exp,3058 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3059 ? node.children3060 : [node],3061 userKey: findProp(node, `key`)3062 };3063}3064function createCodegenNodeForBranch(branch, keyIndex, context) {3065 if (branch.condition) {3066 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3067 // make sure to pass in asBlock: true so that the comment node call3068 // closes the current block.3069 createCallExpression(context.helper(CREATE_COMMENT), [3070 (process.env.NODE_ENV !== 'production') ? '"v-if"' : '""',3071 'true'3072 ]));3073 }3074 else {3075 return createChildrenCodegenNode(branch, keyIndex, context);3076 }3077}3078function createChildrenCodegenNode(branch, keyIndex, context) {3079 const { helper } = context;3080 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3081 const { children } = branch;3082 const firstChild = children[0];3083 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3084 if (needFragmentWrapper) {3085 if (children.length === 1 && firstChild.type === 11 /* FOR */) {3086 // optimize away nested fragments when child is a ForNode3087 const vnodeCall = firstChild.codegenNode;3088 injectProp(vnodeCall, keyProperty, context);3089 return vnodeCall;3090 }3091 else {3092 let patchFlag = 64 /* STABLE_FRAGMENT */;3093 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];3094 // check if the fragment actually contains a single valid child with3095 // the rest being comments3096 if ((process.env.NODE_ENV !== 'production') &&3097 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3098 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3099 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3100 }3101 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, false, false /* isComponent */, branch.loc);3102 }3103 }3104 else {3105 const ret = firstChild.codegenNode;3106 const vnodeCall = getMemoedVNodeCall(ret);3107 // Change createVNode to createBlock.3108 if (vnodeCall.type === 13 /* VNODE_CALL */) {3109 makeBlock(vnodeCall, context);3110 }3111 // inject branch key3112 injectProp(vnodeCall, keyProperty, context);3113 return ret;3114 }3115}3116function isSameKey(a, b) {3117 if (!a || a.type !== b.type) {3118 return false;3119 }3120 if (a.type === 6 /* ATTRIBUTE */) {3121 if (a.value.content !== b.value.content) {3122 return false;3123 }3124 }3125 else {3126 // directive3127 const exp = a.exp;3128 const branchExp = b.exp;3129 if (exp.type !== branchExp.type) {3130 return false;3131 }3132 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3133 exp.isStatic !== branchExp.isStatic ||3134 exp.content !== branchExp.content) {3135 return false;3136 }3137 }3138 return true;3139}3140function getParentCondition(node) {3141 while (true) {3142 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3143 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3144 node = node.alternate;3145 }3146 else {3147 return node;3148 }3149 }3150 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3151 node = node.value;3152 }3153 }3154}3155const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3156 const { helper, removeHelper } = context;3157 return processFor(node, dir, context, forNode => {3158 // create the loop render function expression now, and add the3159 // iterator on exit after all children have been traversed3160 const renderExp = createCallExpression(helper(RENDER_LIST), [3161 forNode.source3162 ]);3163 const memo = findDir(node, 'memo');3164 const keyProp = findProp(node, `key`);3165 const keyExp = keyProp &&3166 (keyProp.type === 6 /* ATTRIBUTE */3167 ? createSimpleExpression(keyProp.value.content, true)3168 : keyProp.exp);3169 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3170 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3171 forNode.source.constType > 0 /* NOT_CONSTANT */;3172 const fragmentFlag = isStableFragment3173 ? 64 /* STABLE_FRAGMENT */3174 : keyProp3175 ? 128 /* KEYED_FRAGMENT */3176 : 256 /* UNKEYED_FRAGMENT */;3177 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3178 ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[fragmentFlag]} */` : ``), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3179 return () => {3180 // finish the codegen now that all children have been traversed3181 let childBlock;3182 const isTemplate = isTemplateNode(node);3183 const { children } = forNode;3184 // check <template v-for> key placement3185 if (((process.env.NODE_ENV !== 'production') || !true) && isTemplate) {3186 node.children.some(c => {3187 if (c.type === 1 /* ELEMENT */) {3188 const key = findProp(c, 'key');3189 if (key) {3190 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3191 return true;3192 }3193 }3194 });3195 }3196 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3197 const slotOutlet = isSlotOutlet(node)3198 ? node3199 : isTemplate &&3200 node.children.length === 1 &&3201 isSlotOutlet(node.children[0])3202 ? node.children[0] // api-extractor somehow fails to infer this3203 : null;3204 if (slotOutlet) {3205 // <slot v-for="..."> or <template v-for="..."><slot/></template>3206 childBlock = slotOutlet.codegenNode;3207 if (isTemplate && keyProperty) {3208 // <template v-for="..." :key="..."><slot/></template>3209 // we need to inject the key to the renderSlot() call.3210 // the props for renderSlot is passed as the 3rd argument.3211 injectProp(childBlock, keyProperty, context);3212 }3213 }3214 else if (needFragmentWrapper) {3215 // <template v-for="..."> with text or multi-elements3216 // should generate a fragment block for each loop3217 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3218 ((process.env.NODE_ENV !== 'production')3219 ? ` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3220 : ``), undefined, undefined, true, undefined, false /* isComponent */);3221 }3222 else {3223 // Normal element v-for. Directly use the child's codegenNode3224 // but mark it as a block.3225 childBlock = children[0]3226 .codegenNode;3227 if (isTemplate && keyProperty) {3228 injectProp(childBlock, keyProperty, context);3229 }3230 if (childBlock.isBlock !== !isStableFragment) {3231 if (childBlock.isBlock) {3232 // switch from block to vnode3233 removeHelper(OPEN_BLOCK);3234 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3235 }3236 else {3237 // switch from vnode to block3238 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3239 }3240 }3241 childBlock.isBlock = !isStableFragment;3242 if (childBlock.isBlock) {3243 helper(OPEN_BLOCK);3244 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3245 }3246 else {3247 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3248 }3249 }3250 if (memo) {3251 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3252 createSimpleExpression(`_cached`)3253 ]));3254 loop.body = createBlockStatement([3255 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3256 createCompoundExpression([3257 `if (_cached`,3258 ...(keyExp ? [` && _cached.key === `, keyExp] : []),3259 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3260 ]),3261 createCompoundExpression([`const _item = `, childBlock]),3262 createSimpleExpression(`_item.memo = _memo`),3263 createSimpleExpression(`return _item`)3264 ]);3265 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3266 }3267 else {3268 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3269 }3270 };3271 });3272});3273// target-agnostic transform used for both Client and SSR3274function processFor(node, dir, context, processCodegen) {3275 if (!dir.exp) {3276 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3277 return;3278 }3279 const parseResult = parseForExpression(3280 // can only be simple expression because vFor transform is applied3281 // before expression transform.3282 dir.exp, context);3283 if (!parseResult) {3284 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3285 return;3286 }3287 const { addIdentifiers, removeIdentifiers, scopes } = context;3288 const { source, value, key, index } = parseResult;3289 const forNode = {3290 type: 11 /* FOR */,3291 loc: dir.loc,3292 source,3293 valueAlias: value,3294 keyAlias: key,3295 objectIndexAlias: index,3296 parseResult,3297 children: isTemplateNode(node) ? node.children : [node]3298 };3299 context.replaceNode(forNode);3300 // bookkeeping3301 scopes.vFor++;3302 const onExit = processCodegen && processCodegen(forNode);3303 return () => {3304 scopes.vFor--;3305 if (onExit)3306 onExit();3307 };3308}3309const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3310// This regex doesn't cover the case if key or index aliases have destructuring,3311// but those do not make sense in the first place, so this works in practice.3312const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3313const stripParensRE = /^\(|\)$/g;3314function parseForExpression(input, context) {3315 const loc = input.loc;3316 const exp = input.content;3317 const inMatch = exp.match(forAliasRE);3318 if (!inMatch)3319 return;3320 const [, LHS, RHS] = inMatch;3321 const result = {3322 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3323 value: undefined,3324 key: undefined,3325 index: undefined3326 };3327 if ((process.env.NODE_ENV !== 'production') && true) {3328 validateBrowserExpression(result.source, context);3329 }3330 let valueContent = LHS.trim().replace(stripParensRE, '').trim();3331 const trimmedOffset = LHS.indexOf(valueContent);3332 const iteratorMatch = valueContent.match(forIteratorRE);3333 if (iteratorMatch) {3334 valueContent = valueContent.replace(forIteratorRE, '').trim();3335 const keyContent = iteratorMatch[1].trim();3336 let keyOffset;3337 if (keyContent) {3338 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3339 result.key = createAliasExpression(loc, keyContent, keyOffset);3340 if ((process.env.NODE_ENV !== 'production') && true) {3341 validateBrowserExpression(result.key, context, true);3342 }3343 }3344 if (iteratorMatch[2]) {3345 const indexContent = iteratorMatch[2].trim();3346 if (indexContent) {3347 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3348 ? keyOffset + keyContent.length3349 : trimmedOffset + valueContent.length));3350 if ((process.env.NODE_ENV !== 'production') && true) {3351 validateBrowserExpression(result.index, context, true);3352 }3353 }3354 }3355 }3356 if (valueContent) {3357 result.value = createAliasExpression(loc, valueContent, trimmedOffset);3358 if ((process.env.NODE_ENV !== 'production') && true) {3359 validateBrowserExpression(result.value, context, true);3360 }3361 }3362 return result;3363}3364function createAliasExpression(range, content, offset) {3365 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3366}3367function createForLoopParams({ value, key, index }, memoArgs = []) {3368 return createParamsList([value, key, index, ...memoArgs]);3369}3370function createParamsList(args) {3371 let i = args.length;3372 while (i--) {3373 if (args[i])3374 break;3375 }3376 return args3377 .slice(0, i + 1)3378 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));3379}3380const defaultFallback = createSimpleExpression(`undefined`, false);3381// A NodeTransform that:3382// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3383// by transformExpression. This is only applied in non-browser builds with3384// { prefixIdentifiers: true }.3385// 2. Track v-slot depths so that we know a slot is inside another slot.3386// Note the exit callback is executed before buildSlots() on the same node,3387// so only nested slots see positive numbers.3388const trackSlotScopes = (node, context) => {3389 if (node.type === 1 /* ELEMENT */ &&3390 (node.tagType === 1 /* COMPONENT */ ||3391 node.tagType === 3 /* TEMPLATE */)) {3392 // We are only checking non-empty v-slot here3393 // since we only care about slots that introduce scope variables.3394 const vSlot = findDir(node, 'slot');3395 if (vSlot) {3396 vSlot.exp;3397 context.scopes.vSlot++;3398 return () => {3399 context.scopes.vSlot--;3400 };3401 }3402 }3403};3404// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3405// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3406const trackVForSlotScopes = (node, context) => {3407 let vFor;3408 if (isTemplateNode(node) &&3409 node.props.some(isVSlot) &&3410 (vFor = findDir(node, 'for'))) {3411 const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3412 if (result) {3413 const { value, key, index } = result;3414 const { addIdentifiers, removeIdentifiers } = context;3415 value && addIdentifiers(value);3416 key && addIdentifiers(key);3417 index && addIdentifiers(index);3418 return () => {3419 value && removeIdentifiers(value);3420 key && removeIdentifiers(key);3421 index && removeIdentifiers(index);3422 };3423 }3424 }3425};3426const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3427// Instead of being a DirectiveTransform, v-slot processing is called during3428// transformElement to build the slots object for a component.3429function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3430 context.helper(WITH_CTX);3431 const { children, loc } = node;3432 const slotsProperties = [];3433 const dynamicSlots = [];3434 // If the slot is inside a v-for or another v-slot, force it to be dynamic3435 // since it likely uses a scope variable.3436 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3437 // 1. Check for slot with slotProps on component itself.3438 // <Comp v-slot="{ prop }"/>3439 const onComponentSlot = findDir(node, 'slot', true);3440 if (onComponentSlot) {3441 const { arg, exp } = onComponentSlot;3442 if (arg && !isStaticExp(arg)) {3443 hasDynamicSlots = true;3444 }3445 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));3446 }3447 // 2. Iterate through children and check for template slots3448 // <template v-slot:foo="{ prop }">3449 let hasTemplateSlots = false;3450 let hasNamedDefaultSlot = false;3451 const implicitDefaultChildren = [];3452 const seenSlotNames = new Set();3453 for (let i = 0; i < children.length; i++) {3454 const slotElement = children[i];3455 let slotDir;3456 if (!isTemplateNode(slotElement) ||3457 !(slotDir = findDir(slotElement, 'slot', true))) {3458 // not a <template v-slot>, skip.3459 if (slotElement.type !== 3 /* COMMENT */) {3460 implicitDefaultChildren.push(slotElement);3461 }3462 continue;3463 }3464 if (onComponentSlot) {3465 // already has on-component slot - this is incorrect usage.3466 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3467 break;3468 }3469 hasTemplateSlots = true;3470 const { children: slotChildren, loc: slotLoc } = slotElement;3471 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3472 // check if name is dynamic.3473 let staticSlotName;3474 if (isStaticExp(slotName)) {3475 staticSlotName = slotName ? slotName.content : `default`;3476 }3477 else {3478 hasDynamicSlots = true;3479 }3480 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3481 // check if this slot is conditional (v-if/v-for)3482 let vIf;3483 let vElse;3484 let vFor;3485 if ((vIf = findDir(slotElement, 'if'))) {3486 hasDynamicSlots = true;3487 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3488 }3489 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3490 // find adjacent v-if3491 let j = i;3492 let prev;3493 while (j--) {3494 prev = children[j];3495 if (prev.type !== 3 /* COMMENT */) {3496 break;3497 }3498 }3499 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3500 // remove node3501 children.splice(i, 1);3502 i--;3503 // attach this slot to previous conditional3504 let conditional = dynamicSlots[dynamicSlots.length - 1];3505 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3506 conditional = conditional.alternate;3507 }3508 conditional.alternate = vElse.exp3509 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3510 : buildDynamicSlot(slotName, slotFunction);3511 }3512 else {3513 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3514 }3515 }3516 else if ((vFor = findDir(slotElement, 'for'))) {3517 hasDynamicSlots = true;3518 const parseResult = vFor.parseResult ||3519 parseForExpression(vFor.exp, context);3520 if (parseResult) {3521 // Render the dynamic slots as an array and add it to the createSlot()3522 // args. The runtime knows how to handle it appropriately.3523 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3524 parseResult.source,3525 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3526 ]));3527 }3528 else {3529 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3530 }3531 }3532 else {3533 // check duplicate static names3534 if (staticSlotName) {3535 if (seenSlotNames.has(staticSlotName)) {3536 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3537 continue;3538 }3539 seenSlotNames.add(staticSlotName);3540 if (staticSlotName === 'default') {3541 hasNamedDefaultSlot = true;3542 }3543 }3544 slotsProperties.push(createObjectProperty(slotName, slotFunction));3545 }3546 }3547 if (!onComponentSlot) {3548 const buildDefaultSlotProperty = (props, children) => {3549 const fn = buildSlotFn(props, children, loc);3550 if (context.compatConfig) {3551 fn.isNonScopedSlot = true;3552 }3553 return createObjectProperty(`default`, fn);3554 };3555 if (!hasTemplateSlots) {3556 // implicit default slot (on component)3557 slotsProperties.push(buildDefaultSlotProperty(undefined, children));3558 }3559 else if (implicitDefaultChildren.length &&3560 // #37663561 // with whitespace: 'preserve', whitespaces between slots will end up in3562 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.3563 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {3564 // implicit default slot (mixed with named slots)3565 if (hasNamedDefaultSlot) {3566 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));3567 }3568 else {3569 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));3570 }3571 }3572 }3573 const slotFlag = hasDynamicSlots3574 ? 2 /* DYNAMIC */3575 : hasForwardedSlots(node.children)3576 ? 3 /* FORWARDED */3577 : 1 /* STABLE */;3578 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 3579 // 2 = compiled but dynamic = can skip normalization, but must run diff3580 // 1 = compiled and static = can skip normalization AND diff as optimized3581 createSimpleExpression(slotFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${slotFlagsText[slotFlag]} */` : ``), false))), loc);3582 if (dynamicSlots.length) {3583 slots = createCallExpression(context.helper(CREATE_SLOTS), [3584 slots,3585 createArrayExpression(dynamicSlots)3586 ]);3587 }3588 return {3589 slots,3590 hasDynamicSlots3591 };3592}3593function buildDynamicSlot(name, fn) {3594 return createObjectExpression([3595 createObjectProperty(`name`, name),3596 createObjectProperty(`fn`, fn)3597 ]);3598}3599function hasForwardedSlots(children) {3600 for (let i = 0; i < children.length; i++) {3601 const child = children[i];3602 switch (child.type) {3603 case 1 /* ELEMENT */:3604 if (child.tagType === 2 /* SLOT */ ||3605 hasForwardedSlots(child.children)) {3606 return true;3607 }3608 break;3609 case 9 /* IF */:3610 if (hasForwardedSlots(child.branches))3611 return true;3612 break;3613 case 10 /* IF_BRANCH */:3614 case 11 /* FOR */:3615 if (hasForwardedSlots(child.children))3616 return true;3617 break;3618 }3619 }3620 return false;3621}3622function isNonWhitespaceContent(node) {3623 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)3624 return true;3625 return node.type === 2 /* TEXT */3626 ? !!node.content.trim()3627 : isNonWhitespaceContent(node.content);3628}3629// some directive transforms (e.g. v-model) may return a symbol for runtime3630// import, which should be used instead of a resolveDirective call.3631const directiveImportMap = new WeakMap();3632// generate a JavaScript AST for this element's codegen3633const transformElement = (node, context) => {3634 // perform the work on exit, after all child expressions have been3635 // processed and merged.3636 return function postTransformElement() {3637 node = context.currentNode;3638 if (!(node.type === 1 /* ELEMENT */ &&3639 (node.tagType === 0 /* ELEMENT */ ||3640 node.tagType === 1 /* COMPONENT */))) {3641 return;3642 }3643 const { tag, props } = node;3644 const isComponent = node.tagType === 1 /* COMPONENT */;3645 // The goal of the transform is to create a codegenNode implementing the3646 // VNodeCall interface.3647 let vnodeTag = isComponent3648 ? resolveComponentType(node, context)3649 : `"${tag}"`;3650 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;3651 let vnodeProps;3652 let vnodeChildren;3653 let vnodePatchFlag;3654 let patchFlag = 0;3655 let vnodeDynamicProps;3656 let dynamicPropNames;3657 let vnodeDirectives;3658 let shouldUseBlock = 3659 // dynamic component may resolve to plain elements3660 isDynamicComponent ||3661 vnodeTag === TELEPORT ||3662 vnodeTag === SUSPENSE ||3663 (!isComponent &&3664 // <svg> and <foreignObject> must be forced into blocks so that block3665 // updates inside get proper isSVG flag at runtime. (#639, #643)3666 // This is technically web-specific, but splitting the logic out of core3667 // leads to too much unnecessary complexity.3668 (tag === 'svg' ||3669 tag === 'foreignObject' ||3670 // #938: elements with dynamic keys should be forced into blocks3671 findProp(node, 'key', true)));3672 // props3673 if (props.length > 0) {3674 const propsBuildResult = buildProps(node, context);3675 vnodeProps = propsBuildResult.props;3676 patchFlag = propsBuildResult.patchFlag;3677 dynamicPropNames = propsBuildResult.dynamicPropNames;3678 const directives = propsBuildResult.directives;3679 vnodeDirectives =3680 directives && directives.length3681 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))3682 : undefined;3683 }3684 // children3685 if (node.children.length > 0) {3686 if (vnodeTag === KEEP_ALIVE) {3687 // Although a built-in component, we compile KeepAlive with raw children3688 // instead of slot functions so that it can be used inside Transition3689 // or other Transition-wrapping HOCs.3690 // To ensure correct updates with block optimizations, we need to:3691 // 1. Force keep-alive into a block. This avoids its children being3692 // collected by a parent block.3693 shouldUseBlock = true;3694 // 2. Force keep-alive to always be updated, since it uses raw children.3695 patchFlag |= 1024 /* DYNAMIC_SLOTS */;3696 if ((process.env.NODE_ENV !== 'production') && node.children.length > 1) {3697 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {3698 start: node.children[0].loc.start,3699 end: node.children[node.children.length - 1].loc.end,3700 source: ''3701 }));3702 }3703 }3704 const shouldBuildAsSlots = isComponent &&3705 // Teleport is not a real component and has dedicated runtime handling3706 vnodeTag !== TELEPORT &&3707 // explained above.3708 vnodeTag !== KEEP_ALIVE;3709 if (shouldBuildAsSlots) {3710 const { slots, hasDynamicSlots } = buildSlots(node, context);3711 vnodeChildren = slots;3712 if (hasDynamicSlots) {3713 patchFlag |= 1024 /* DYNAMIC_SLOTS */;3714 }3715 }3716 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {3717 const child = node.children[0];3718 const type = child.type;3719 // check for dynamic text children3720 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||3721 type === 8 /* COMPOUND_EXPRESSION */;3722 if (hasDynamicTextChild &&3723 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {3724 patchFlag |= 1 /* TEXT */;3725 }3726 // pass directly if the only child is a text node3727 // (plain / interpolation / expression)3728 if (hasDynamicTextChild || type === 2 /* TEXT */) {3729 vnodeChildren = child;3730 }3731 else {3732 vnodeChildren = node.children;3733 }3734 }3735 else {3736 vnodeChildren = node.children;3737 }3738 }3739 // patchFlag & dynamicPropNames3740 if (patchFlag !== 0) {3741 if ((process.env.NODE_ENV !== 'production')) {3742 if (patchFlag < 0) {3743 // special flags (negative and mutually exclusive)3744 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;3745 }3746 else {3747 // bitwise flags3748 const flagNames = Object.keys(PatchFlagNames)3749 .map(Number)3750 .filter(n => n > 0 && patchFlag & n)3751 .map(n => PatchFlagNames[n])3752 .join(`, `);3753 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;3754 }3755 }3756 else {3757 vnodePatchFlag = String(patchFlag);3758 }3759 if (dynamicPropNames && dynamicPropNames.length) {3760 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);3761 }3762 }3763 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);3764 };3765};3766function resolveComponentType(node, context, ssr = false) {3767 let { tag } = node;3768 // 1. dynamic component3769 const isExplicitDynamic = isComponentTag(tag);3770 const isProp = findProp(node, 'is');3771 if (isProp) {3772 if (isExplicitDynamic ||3773 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {3774 const exp = isProp.type === 6 /* ATTRIBUTE */3775 ? isProp.value && createSimpleExpression(isProp.value.content, true)3776 : isProp.exp;3777 if (exp) {3778 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3779 exp3780 ]);3781 }3782 }3783 else if (isProp.type === 6 /* ATTRIBUTE */ &&3784 isProp.value.content.startsWith('vue:')) {3785 // <button is="vue:xxx">3786 // if not <component>, only is value that starts with "vue:" will be3787 // treated as component by the parse phase and reach here, unless it's3788 // compat mode where all is values are considered components3789 tag = isProp.value.content.slice(4);3790 }3791 }3792 // 1.5 v-is (TODO: Deprecate)3793 const isDir = !isExplicitDynamic && findDir(node, 'is');3794 if (isDir && isDir.exp) {3795 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3796 isDir.exp3797 ]);3798 }3799 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)3800 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);3801 if (builtIn) {3802 // built-ins are simply fallthroughs / have special handling during ssr3803 // so we don't need to import their runtime equivalents3804 if (!ssr)3805 context.helper(builtIn);3806 return builtIn;3807 }3808 // 5. user component (resolve)3809 context.helper(RESOLVE_COMPONENT);3810 context.components.add(tag);3811 return toValidAssetId(tag, `component`);3812}3813function buildProps(node, context, props = node.props, ssr = false) {3814 const { tag, loc: elementLoc } = node;3815 const isComponent = node.tagType === 1 /* COMPONENT */;3816 let properties = [];3817 const mergeArgs = [];3818 const runtimeDirectives = [];3819 // patchFlag analysis3820 let patchFlag = 0;3821 let hasRef = false;3822 let hasClassBinding = false;3823 let hasStyleBinding = false;3824 let hasHydrationEventBinding = false;3825 let hasDynamicKeys = false;3826 let hasVnodeHook = false;3827 const dynamicPropNames = [];3828 const analyzePatchFlag = ({ key, value }) => {3829 if (isStaticExp(key)) {3830 const name = key.content;3831 const isEventHandler = isOn(name);3832 if (!isComponent &&3833 isEventHandler &&3834 // omit the flag for click handlers because hydration gives click3835 // dedicated fast path.3836 name.toLowerCase() !== 'onclick' &&3837 // omit v-model handlers3838 name !== 'onUpdate:modelValue' &&3839 // omit onVnodeXXX hooks3840 !isReservedProp(name)) {3841 hasHydrationEventBinding = true;3842 }3843 if (isEventHandler && isReservedProp(name)) {3844 hasVnodeHook = true;3845 }3846 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||3847 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||3848 value.type === 8 /* COMPOUND_EXPRESSION */) &&3849 getConstantType(value, context) > 0)) {3850 // skip if the prop is a cached handler or has constant value3851 return;3852 }3853 if (name === 'ref') {3854 hasRef = true;3855 }3856 else if (name === 'class') {3857 hasClassBinding = true;3858 }3859 else if (name === 'style') {3860 hasStyleBinding = true;3861 }3862 else if (name !== 'key' && !dynamicPropNames.includes(name)) {3863 dynamicPropNames.push(name);3864 }3865 // treat the dynamic class and style binding of the component as dynamic props3866 if (isComponent &&3867 (name === 'class' || name === 'style') &&3868 !dynamicPropNames.includes(name)) {3869 dynamicPropNames.push(name);3870 }3871 }3872 else {3873 hasDynamicKeys = true;3874 }3875 };3876 for (let i = 0; i < props.length; i++) {3877 // static attribute3878 const prop = props[i];3879 if (prop.type === 6 /* ATTRIBUTE */) {3880 const { loc, name, value } = prop;3881 let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);3882 if (name === 'ref') {3883 hasRef = true;3884 }3885 // skip is on <component>, or is="vue:xxx"3886 if (name === 'is' &&3887 (isComponentTag(tag) ||3888 (value && value.content.startsWith('vue:')) ||3889 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {3890 continue;3891 }3892 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));3893 }3894 else {3895 // directives3896 const { name, arg, exp, loc } = prop;3897 const isVBind = name === 'bind';3898 const isVOn = name === 'on';3899 // skip v-slot - it is handled by its dedicated transform.3900 if (name === 'slot') {3901 if (!isComponent) {3902 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));3903 }3904 continue;3905 }3906 // skip v-once/v-memo - they are handled by dedicated transforms.3907 if (name === 'once' || name === 'memo') {3908 continue;3909 }3910 // skip v-is and :is on <component>3911 if (name === 'is' ||3912 (isVBind &&3913 isBindKey(arg, 'is') &&3914 (isComponentTag(tag) ||3915 (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {3916 continue;3917 }3918 // skip v-on in SSR compilation3919 if (isVOn && ssr) {3920 continue;3921 }3922 // special case for v-bind and v-on with no argument3923 if (!arg && (isVBind || isVOn)) {3924 hasDynamicKeys = true;3925 if (exp) {3926 if (properties.length) {3927 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));3928 properties = [];3929 }3930 if (isVBind) {3931 {3932 // 2.x v-bind object order compat3933 if ((process.env.NODE_ENV !== 'production')) {3934 const hasOverridableKeys = mergeArgs.some(arg => {3935 if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {3936 return arg.properties.some(({ key }) => {3937 if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||3938 !key.isStatic) {3939 return true;3940 }3941 return (key.content !== 'class' &&3942 key.content !== 'style' &&3943 !isOn(key.content));3944 });3945 }3946 else {3947 // dynamic expression3948 return true;3949 }3950 });3951 if (hasOverridableKeys) {3952 checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);3953 }3954 }3955 if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {3956 mergeArgs.unshift(exp);3957 continue;3958 }3959 }3960 mergeArgs.push(exp);3961 }3962 else {3963 // v-on="obj" -> toHandlers(obj)3964 mergeArgs.push({3965 type: 14 /* JS_CALL_EXPRESSION */,3966 loc,3967 callee: context.helper(TO_HANDLERS),3968 arguments: [exp]3969 });3970 }3971 }3972 else {3973 context.onError(createCompilerError(isVBind3974 ? 34 /* X_V_BIND_NO_EXPRESSION */3975 : 35 /* X_V_ON_NO_EXPRESSION */, loc));3976 }3977 continue;3978 }3979 const directiveTransform = context.directiveTransforms[name];3980 if (directiveTransform) {3981 // has built-in directive transform.3982 const { props, needRuntime } = directiveTransform(prop, node, context);3983 !ssr && props.forEach(analyzePatchFlag);3984 properties.push(...props);3985 if (needRuntime) {3986 runtimeDirectives.push(prop);3987 if (isSymbol(needRuntime)) {3988 directiveImportMap.set(prop, needRuntime);3989 }3990 }3991 }3992 else {3993 // no built-in transform, this is a user custom directive.3994 runtimeDirectives.push(prop);3995 }3996 }3997 if (prop.type === 6 /* ATTRIBUTE */ &&3998 prop.name === 'ref' &&3999 context.scopes.vFor > 0 &&4000 checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {4001 properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));4002 }4003 }4004 let propsExpression = undefined;4005 // has v-bind="object" or v-on="object", wrap with mergeProps4006 if (mergeArgs.length) {4007 if (properties.length) {4008 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4009 }4010 if (mergeArgs.length > 1) {4011 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4012 }4013 else {4014 // single v-bind with nothing else - no need for a mergeProps call
...
compiler-dom.esm-bundler.js
Source:compiler-dom.esm-bundler.js
...278 const eventOptionModifiers = [];279 for (let i = 0; i < modifiers.length; i++) {280 const modifier = modifiers[i];281 if (modifier === 'native' &&282 checkCompatEnabled("COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */, context, loc)) {283 eventOptionModifiers.push(modifier);284 }285 else if (isEventOptionModifier(modifier)) {286 // eventOptionModifiers: modifiers for addEventListener() options,287 // e.g. .passive & .capture288 eventOptionModifiers.push(modifier);289 }290 else {291 // runtimeModifiers: modifiers that needs runtime guards292 if (maybeKeyModifier(modifier)) {293 if (isStaticExp(key)) {294 if (isKeyboardEvent(key.content)) {295 keyModifiers.push(modifier);296 }...
index.js
Source:index.js
1import { checkCompatEnabled } from '@vue/compiler-core';2import { createStore } from 'vuex'3export default createStore({4 state: {5 sabores: [],6 adornos: [],7 nombre: "",8 telefono: "",9 correo: "",10 descripcion: "",11 totCho: 10,12 totVai: 10,13 totNar: 10,14 totZan: 10,15 totMar: 5,16 totBod: 5,17 totGok: 5,18 totVel: 519 },20 getters: {21 },22 mutations: {23 checkVain: function(state) {24 if (state.sabores.includes("Vainilla"))25 state.totVai++;26 else27 state.totVai--;28 },29 checkChoc: function(state) {30 if (state.sabores.includes("Chocolate"))31 state.totCho++;32 else33 state.totCho--;34 },35 checkNara: function(state) {36 if (state.sabores.includes("Naranja"))37 state.totNar++;38 else39 state.totNar--;40 },41 checkZana: function(state) {42 if (state.sabores.includes("Zanahoria"))43 state.totZan++;44 else45 state.totZan--;46 },47 checkBoda: function(state) {48 if (state.adornos.includes("Pareja"))49 state.totBod++;50 else51 state.totBod--;52 },53 checkMario: function(state) {54 if (state.adornos.includes("MarioBros"))55 state.totMar++;56 else57 state.totMar--;58 },59 checkGoku: function(state) {60 if (state.adornos.includes("Goku"))61 state.totGok++;62 else63 state.totGok--;64 },65 checkVela: function(state) {66 if (state.adornos.includes("Vela de número"))67 state.totVel++;68 else69 state.totVel--;70 }71 },72 actions: {73 },74 modules: {75 }...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 await page.screenshot({ path: `example.png` });6 await browser.close();7})();8"dependencies": {9 }10"dependencies": {11 }
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 const compatEnabled = await page._client.send('Browser.checkCompatEnabled');6 console.log(compatEnabled);7 await browser.close();8})();
Using AI Code Generation
1const { checkCompatEnabled } = require('playwright/lib/server/browserType');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 const isCompatEnabled = await checkCompatEnabled(page);7 await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11 const browser = await chromium.launch();12 const context = await browser.newContext();13 const page = await context.newPage();14 const isCompatEnabled = await page.checkCompatEnabled();15 await browser.close();16})();17const { chromium } = require('playwright');18(async () => {19 const browser = await chromium.launch();20 const context = await browser.newContext({ compat: false });21 const page = await context.newPage();22 const isCompatEnabled = await page.checkCompatEnabled();23 await browser.close();24})();25const { chromium } = require('playwright');26(async () => {27 const browser = await chromium.launch();28 const context = await browser.newContext();29 const page = await context.newPage();30 await page.evaluate(() => {31 });32 const isCompatEnabled = await page.checkCompatEnabled();33 await browser.close();34})();35const { chromium } = require('playwright');36(async () => {37 const browser = await chromium.launch();38 const context = await browser.newContext();39 const page = await context.newPage();
Using AI Code Generation
1const { checkCompatEnabled } = require('@playwright/test/lib/server/compatibility');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 console.log(checkCompatEnabled(context));8 await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext({14 });15 const page = await context.newPage();16 await browser.close();17})();18browserType.connect()19browserType.launchServer()20browserType.launchPersistentContext()21browser.newContext()22browserType.launch()
Using AI Code Generation
1const { chromium } = require('playwright-chromium');2const { checkCompatEnabled } = require('playwright-chromium/lib/server/chromium');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 const compatEnabled = await checkCompatEnabled(page);7 console.log('Compat enabled: ', compatEnabled);8 await browser.close();9})();
Using AI Code Generation
1const { checkCompatEnabled } = require('playwright/lib/server/chromium/crBrowser');2const browser = await chromium.launch();3const page = await browser.newPage();4await checkCompatEnabled(page);5await browser.close();6const { checkCompatEnabled } = require('playwright/lib/server/chromium/crBrowser');7const browser = await chromium.launch();8const page = await browser.newPage();9await checkCompatEnabled(page);10await browser.close();
Using AI Code Generation
1const { checkCompatEnabled } = require('playwright-core/lib/server/chromium/crBrowser');2const { launch } = require('playwright-core');3const browser = await launch({ headless: false });4const page = await browser.newPage();5const { enabled } = await checkCompatEnabled(page);6console.log(enabled);7await browser.close();8from playwright._impl._api_types import Error9from playwright._impl._transport import Transport10from playwright._impl._connection import ChannelOwner11from playwright.sync_api import sync_playwright12from playwright._impl._page import Page13with sync_playwright() as p:14 browser = p.chromium.launch(headless=False)15 page = browser.new_page()16 print(page._sync_check_compat_enabled())17 print(str(e))18 browser.close()19import com.microsoft.playwright.*;20public class Test {21 public static void main(String[] args) {22 try (Playwright playwright = Playwright.create()) {23 BrowserType chromium = playwright.chromium();24 Browser browser = chromium.launch(new BrowserType.LaunchOptions().setHeadless(false));25 Page page = browser.newPage();26 System.out.println(page.checkCompatEnabled());27 browser.close();28 }29 }30}31using Microsoft.Playwright;32using System;33{34 static void Main(string[] args)35 {36 using var playwright = Playwright.CreateAsync().Result;37 var browser = playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = false }).Result;38 var page = browser.NewPageAsync().Result;39 Console.WriteLine(page.CheckCompatEnabledAsync().Result);40 browser.CloseAsync().Wait();41 }42}43use Microsoft\Playwright\Playwright;44{45 public function test()46 {47 $playwright = Playwright::create();48 $browser = $playwright->chromium()->launch([49 ]);50 $page = $browser->newPage();51 print_r($page->checkCompat
Using AI Code Generation
1const { checkCompatEnabled } = require('playwright/lib/server/browserContext');2const context = browser.newContext();3const enabled = checkCompatEnabled(context);4console.log(enabled);5const { checkCompatEnabled } = require('playwright/lib/server/browserContext');6const context = browser.newContext();7const enabled = checkCompatEnabled(context);8console.log(enabled);9const { checkCompatEnabled } = require('playwright/lib/server/browserContext');10const context = browser.newContext();11const enabled = checkCompatEnabled(context);12console.log(enabled);13const { checkCompatEnabled } = require('playwright/lib/server/browserContext');14const context = browser.newContext();15const enabled = checkCompatEnabled(context);16console.log(enabled);17const { checkCompatEnabled } = require('playwright/lib/server/browserContext');18const context = browser.newContext();19const enabled = checkCompatEnabled(context);20console.log(enabled);21const { checkCompatEnabled } = require('playwright/lib/server/browserContext');22const context = browser.newContext();23const enabled = checkCompatEnabled(context);24console.log(enabled);25const { checkCompatEnabled } = require('playwright/lib/server/browserContext');26const context = browser.newContext();27const enabled = checkCompatEnabled(context);28console.log(enabled);29const { checkCompatEnabled } = require('playwright/lib/server/browserContext');30const context = browser.newContext();31const enabled = checkCompatEnabled(context);32console.log(enabled);33const { checkCompatEnabled } = require('playwright/lib/server/browserContext');34const context = browser.newContext();35const enabled = checkCompatEnabled(context);36console.log(enabled);37const { checkCompatEnabled } = require('playwright/lib/server/browserContext');38const context = browser.newContext();39const enabled = checkCompatEnabled(context);40console.log(enabled);41const { checkCompatEnabled } =
Using AI Code Generation
1const { checkCompatEnabled } = require('playwright-core/lib/server/browserType');2const isCompatEnabled = checkCompatEnabled();3console.log(isCompatEnabled);4const { chromium } = require('playwright');5(async () => {6 const browser = await chromium.launch({ browsers: 'chromium' });7 const context = await browser.newContext();8 const page = await context.newPage();9 await page.screenshot({ path: 'chromium-compat.png' });10 await browser.close();11})();12const { firefox } = require('playwright');13(async () => {14 const browser = await firefox.launch({ browsers: 'firefox' });15 const context = await browser.newContext();16 const page = await context.newPage();17 await page.screenshot({ path: 'firefox-compat.png' });18 await browser.close();19})();20const { webkit } = require('playwright');21(async () => {22 const browser = await webkit.launch({ browsers: 'webkit' });23 const context = await browser.newContext();24 const page = await context.newPage();
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!