jsv-compiler
Version:
use vue3 template in .js
1,306 lines • 169 kB
JavaScript
'use strict';
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
var _a, _b;
Object.defineProperty(exports, '__esModule', { value: true });
var shared = require('@vue/shared');
var sourceMap = require('source-map');
var parser = require('@babel/parser');
var estreeWalker = require('estree-walker');
function defaultOnError(error) {
throw error;
}
function createCompilerError(code, loc, messages, additionalMessage) {
var msg = (messages || errorMessages)[code] + (additionalMessage || "");
var error = new SyntaxError(String(msg));
error.code = code;
error.loc = loc;
return error;
}
var errorMessages = (_a = {},
// parse errors
_a[0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */] = 'Illegal comment.',
_a[1 /* CDATA_IN_HTML_CONTENT */] = 'CDATA section is allowed only in XML context.',
_a[2 /* DUPLICATE_ATTRIBUTE */] = 'Duplicate attribute.',
_a[3 /* END_TAG_WITH_ATTRIBUTES */] = 'End tag cannot have attributes.',
_a[4 /* END_TAG_WITH_TRAILING_SOLIDUS */] = "Illegal '/' in tags.",
_a[5 /* EOF_BEFORE_TAG_NAME */] = 'Unexpected EOF in tag.',
_a[6 /* EOF_IN_CDATA */] = 'Unexpected EOF in CDATA section.',
_a[7 /* EOF_IN_COMMENT */] = 'Unexpected EOF in comment.',
_a[8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */] = 'Unexpected EOF in script.',
_a[9 /* EOF_IN_TAG */] = 'Unexpected EOF in tag.',
_a[10 /* INCORRECTLY_CLOSED_COMMENT */] = 'Incorrectly closed comment.',
_a[11 /* INCORRECTLY_OPENED_COMMENT */] = 'Incorrectly opened comment.',
_a[12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */] = "Illegal tag name. Use '<' to print '<'.",
_a[13 /* MISSING_ATTRIBUTE_VALUE */] = 'Attribute value was expected.',
_a[14 /* MISSING_END_TAG_NAME */] = 'End tag name was expected.',
_a[15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */] = 'Whitespace was expected.',
_a[16 /* NESTED_COMMENT */] = "Unexpected '<!--' in comment.",
_a[17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */] = 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
_a[18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */] = 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
_a[19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */] = "Attribute name cannot start with '='.",
_a[21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */] = "'<?' is allowed only in XML context.",
_a[22 /* UNEXPECTED_SOLIDUS_IN_TAG */] = "Illegal '/' in tags.",
// Vue-specific parse errors
_a[23 /* X_INVALID_END_TAG */] = 'Invalid end tag.',
_a[24 /* X_MISSING_END_TAG */] = 'Element is missing end tag.',
_a[25 /* X_MISSING_INTERPOLATION_END */] = 'Interpolation end sign was not found.',
_a[26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */] = 'End bracket for dynamic directive argument was not found. ' +
'Note that dynamic directive argument cannot contain spaces.',
// transform errors
_a[27 /* X_V_IF_NO_EXPRESSION */] = "v-if/v-else-if is missing expression.",
_a[28 /* X_V_IF_SAME_KEY */] = "v-if/else branches must use unique keys.",
_a[29 /* X_V_ELSE_NO_ADJACENT_IF */] = "v-else/v-else-if has no adjacent v-if.",
_a[30 /* X_V_FOR_NO_EXPRESSION */] = "v-for is missing expression.",
_a[31 /* X_V_FOR_MALFORMED_EXPRESSION */] = "v-for has invalid expression.",
_a[32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */] = "<template v-for> key should be placed on the <template> tag.",
_a[33 /* X_V_BIND_NO_EXPRESSION */] = "v-bind is missing expression.",
_a[34 /* X_V_ON_NO_EXPRESSION */] = "v-on is missing expression.",
_a[35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */] = "Unexpected custom directive on <slot> outlet.",
_a[36 /* X_V_SLOT_MIXED_SLOT_USAGE */] = "Mixed v-slot usage on both the component and nested <template>." +
"When there are multiple named slots, all slots should use <template> " +
"syntax to avoid scope ambiguity.",
_a[37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */] = "Duplicate slot names found. ",
_a[38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */] = "Extraneous children found when component already has explicitly named " +
"default slot. These children will be ignored.",
_a[39 /* X_V_SLOT_MISPLACED */] = "v-slot can only be used on components or <template> tags.",
_a[40 /* X_V_MODEL_NO_EXPRESSION */] = "v-model is missing expression.",
_a[41 /* X_V_MODEL_MALFORMED_EXPRESSION */] = "v-model value must be a valid JavaScript member expression.",
_a[42 /* X_V_MODEL_ON_SCOPE_VARIABLE */] = "v-model cannot be used on v-for or v-slot scope variables because they are not writable.",
_a[43 /* X_INVALID_EXPRESSION */] = "Error parsing JavaScript expression: ",
_a[44 /* X_KEEP_ALIVE_INVALID_CHILDREN */] = "<KeepAlive> expects exactly one child component.",
// generic errors
_a[45 /* X_PREFIX_ID_NOT_SUPPORTED */] = "\"prefixIdentifiers\" option is not supported in this build of compiler.",
_a[46 /* X_MODULE_MODE_NOT_SUPPORTED */] = "ES module mode is not supported in this build of compiler.",
_a[47 /* X_CACHE_HANDLER_NOT_SUPPORTED */] = "\"cacheHandlers\" option is only supported when the \"prefixIdentifiers\" option is enabled.",
_a[48 /* X_SCOPE_ID_NOT_SUPPORTED */] = "\"scopeId\" option is only supported in module mode.",
_a);
var FRAGMENT = Symbol("Fragment");
var TELEPORT = Symbol("Teleport");
var SUSPENSE = Symbol("Suspense");
var KEEP_ALIVE = Symbol("KeepAlive");
var BASE_TRANSITION = Symbol("BaseTransition");
var OPEN_BLOCK = Symbol("openBlock");
var CREATE_BLOCK = Symbol("createBlock");
var CREATE_VNODE = Symbol("createVNode");
var CREATE_COMMENT = Symbol("createCommentVNode");
var CREATE_TEXT = Symbol("createTextVNode");
var CREATE_STATIC = Symbol("createStaticVNode");
var RESOLVE_COMPONENT = Symbol("resolveComponent");
var RESOLVE_DYNAMIC_COMPONENT = Symbol("resolveDynamicComponent");
var RESOLVE_DIRECTIVE = Symbol("resolveDirective");
var WITH_DIRECTIVES = Symbol("withDirectives");
var RENDER_LIST = Symbol("renderList");
var RENDER_SLOT = Symbol("renderSlot");
var CREATE_SLOTS = Symbol("createSlots");
var TO_DISPLAY_STRING = Symbol("toDisplayString");
var MERGE_PROPS = Symbol("mergeProps");
var TO_HANDLERS = Symbol("toHandlers");
var CAMELIZE = Symbol("camelize");
var CAPITALIZE = Symbol("capitalize");
var SET_BLOCK_TRACKING = Symbol("setBlockTracking");
var PUSH_SCOPE_ID = Symbol("pushScopeId");
var POP_SCOPE_ID = Symbol("popScopeId");
var WITH_SCOPE_ID = Symbol("withScopeId");
var WITH_CTX = Symbol("withCtx");
// Name mapping for runtime helpers that need to be imported from 'vue' in
// generated code. Make sure these are correctly exported in the runtime!
// Using `any` here because TS doesn't allow symbols as index type.
var helperNameMap = (_b = {},
_b[FRAGMENT] = "Fragment",
_b[TELEPORT] = "Teleport",
_b[SUSPENSE] = "Suspense",
_b[KEEP_ALIVE] = "KeepAlive",
_b[BASE_TRANSITION] = "BaseTransition",
_b[OPEN_BLOCK] = "openBlock",
_b[CREATE_BLOCK] = "createBlock",
_b[CREATE_VNODE] = "createVNode",
_b[CREATE_COMMENT] = "createCommentVNode",
_b[CREATE_TEXT] = "createTextVNode",
_b[CREATE_STATIC] = "createStaticVNode",
_b[RESOLVE_COMPONENT] = "resolveComponent",
_b[RESOLVE_DYNAMIC_COMPONENT] = "resolveDynamicComponent",
_b[RESOLVE_DIRECTIVE] = "resolveDirective",
_b[WITH_DIRECTIVES] = "withDirectives",
_b[RENDER_LIST] = "renderList",
_b[RENDER_SLOT] = "renderSlot",
_b[CREATE_SLOTS] = "createSlots",
_b[TO_DISPLAY_STRING] = "toDisplayString",
_b[MERGE_PROPS] = "mergeProps",
_b[TO_HANDLERS] = "toHandlers",
_b[CAMELIZE] = "camelize",
_b[CAPITALIZE] = "capitalize",
_b[SET_BLOCK_TRACKING] = "setBlockTracking",
_b[PUSH_SCOPE_ID] = "pushScopeId",
_b[POP_SCOPE_ID] = "popScopeId",
_b[WITH_SCOPE_ID] = "withScopeId",
_b[WITH_CTX] = "withCtx",
_b);
function registerRuntimeHelpers(helpers) {
Object.getOwnPropertySymbols(helpers).forEach(function (s) {
helperNameMap[s] = helpers[s];
});
}
// AST Utilities ---------------------------------------------------------------
// Some expressions, e.g. sequence and conditional expressions, are never
// associated with template nodes, so their source locations are just a stub.
// Container types like CompoundExpression also don't need a real location.
var locStub = {
source: '',
start: { line: 1, column: 1, offset: 0 },
end: { line: 1, column: 1, offset: 0 }
};
function createRoot(children, loc) {
if (loc === void 0) { loc = locStub; }
return {
type: 0 /* ROOT */,
children: children,
helpers: [],
components: [],
directives: [],
hoists: [],
imports: [],
cached: 0,
temps: 0,
codegenNode: undefined,
loc: loc
};
}
function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, loc) {
if (isBlock === void 0) { isBlock = false; }
if (disableTracking === void 0) { disableTracking = false; }
if (loc === void 0) { loc = locStub; }
if (context) {
if (isBlock) {
context.helper(OPEN_BLOCK);
context.helper(CREATE_BLOCK);
}
else {
context.helper(CREATE_VNODE);
}
if (directives) {
context.helper(WITH_DIRECTIVES);
}
}
return {
type: 13 /* VNODE_CALL */,
tag: tag,
props: props,
children: children,
patchFlag: patchFlag,
dynamicProps: dynamicProps,
directives: directives,
isBlock: isBlock,
disableTracking: disableTracking,
loc: loc
};
}
function createArrayExpression(elements, loc) {
if (loc === void 0) { loc = locStub; }
return {
type: 17 /* JS_ARRAY_EXPRESSION */,
loc: loc,
elements: elements
};
}
function createObjectExpression(properties, loc) {
if (loc === void 0) { loc = locStub; }
return {
type: 15 /* JS_OBJECT_EXPRESSION */,
loc: loc,
properties: properties
};
}
function createObjectProperty(key, value) {
return {
type: 16 /* JS_PROPERTY */,
loc: locStub,
key: shared.isString(key) ? createSimpleExpression(key, true) : key,
value: value
};
}
function createSimpleExpression(content, isStatic, loc, isConstant) {
if (loc === void 0) { loc = locStub; }
if (isConstant === void 0) { isConstant = false; }
return {
type: 4 /* SIMPLE_EXPRESSION */,
loc: loc,
isConstant: isConstant,
content: content,
isStatic: isStatic
};
}
function createInterpolation(content, loc) {
return {
type: 5 /* INTERPOLATION */,
loc: loc,
content: shared.isString(content)
? createSimpleExpression(content, false, loc)
: content
};
}
function createCompoundExpression(children, loc) {
if (loc === void 0) { loc = locStub; }
return {
type: 8 /* COMPOUND_EXPRESSION */,
loc: loc,
children: children
};
}
function createCallExpression(callee, args, loc) {
if (args === void 0) { args = []; }
if (loc === void 0) { loc = locStub; }
return {
type: 14 /* JS_CALL_EXPRESSION */,
loc: loc,
callee: callee,
arguments: args
};
}
function createFunctionExpression(params, returns, newline, isSlot, loc) {
if (returns === void 0) { returns = undefined; }
if (newline === void 0) { newline = false; }
if (isSlot === void 0) { isSlot = false; }
if (loc === void 0) { loc = locStub; }
return {
type: 18 /* JS_FUNCTION_EXPRESSION */,
params: params,
returns: returns,
newline: newline,
isSlot: isSlot,
loc: loc
};
}
function createConditionalExpression(test, consequent, alternate, newline) {
if (newline === void 0) { newline = true; }
return {
type: 19 /* JS_CONDITIONAL_EXPRESSION */,
test: test,
consequent: consequent,
alternate: alternate,
newline: newline,
loc: locStub
};
}
function createCacheExpression(index, value, isVNode) {
if (isVNode === void 0) { isVNode = false; }
return {
type: 20 /* JS_CACHE_EXPRESSION */,
index: index,
value: value,
isVNode: isVNode,
loc: locStub
};
}
function createBlockStatement(body) {
return {
type: 21 /* JS_BLOCK_STATEMENT */,
body: body,
loc: locStub
};
}
function createTemplateLiteral(elements) {
return {
type: 22 /* JS_TEMPLATE_LITERAL */,
elements: elements,
loc: locStub
};
}
function createIfStatement(test, consequent, alternate) {
return {
type: 23 /* JS_IF_STATEMENT */,
test: test,
consequent: consequent,
alternate: alternate,
loc: locStub
};
}
function createAssignmentExpression(left, right) {
return {
type: 24 /* JS_ASSIGNMENT_EXPRESSION */,
left: left,
right: right,
loc: locStub
};
}
function createSequenceExpression(expressions) {
return {
type: 25 /* JS_SEQUENCE_EXPRESSION */,
expressions: expressions,
loc: locStub
};
}
function createReturnStatement(returns) {
return {
type: 26 /* JS_RETURN_STATEMENT */,
returns: returns,
loc: locStub
};
}
var isStaticExp = function (p) { return p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic; };
var isBuiltInType = function (tag, expected) { return tag === expected || tag === shared.hyphenate(expected); };
function isCoreComponent(tag) {
if (isBuiltInType(tag, 'Teleport')) {
return TELEPORT;
}
else if (isBuiltInType(tag, 'Suspense')) {
return SUSPENSE;
}
else if (isBuiltInType(tag, 'KeepAlive')) {
return KEEP_ALIVE;
}
else if (isBuiltInType(tag, 'BaseTransition')) {
return BASE_TRANSITION;
}
}
var nonIdentifierRE = /^\d|[^\$\w]/;
var isSimpleIdentifier = function (name) { return !nonIdentifierRE.test(name); };
var memberExpRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\[[^\]]+\])*$/;
var isMemberExpression = function (path) {
if (!path)
return false;
return memberExpRE.test(path.trim());
};
function getInnerRange(loc, offset, length) {
var source = loc.source.substr(offset, length);
var newLoc = {
source: source,
start: advancePositionWithClone(loc.start, loc.source, offset),
end: loc.end
};
if (length != null) {
newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
}
return newLoc;
}
function advancePositionWithClone(pos, source, numberOfCharacters) {
if (numberOfCharacters === void 0) { numberOfCharacters = source.length; }
return advancePositionWithMutation(shared.extend({}, pos), source, numberOfCharacters);
}
// advance by mutation without cloning (for performance reasons), since this
// gets called a lot in the parser
function advancePositionWithMutation(pos, source, numberOfCharacters) {
if (numberOfCharacters === void 0) { numberOfCharacters = source.length; }
var linesCount = 0;
var lastNewLinePos = -1;
for (var i = 0; i < numberOfCharacters; i++) {
if (source.charCodeAt(i) === 10 /* newline char code */) {
linesCount++;
lastNewLinePos = i;
}
}
pos.offset += numberOfCharacters;
pos.line += linesCount;
pos.column =
lastNewLinePos === -1
? pos.column + numberOfCharacters
: numberOfCharacters - lastNewLinePos;
return pos;
}
function assert(condition, msg) {
/* istanbul ignore if */
if (!condition) {
throw new Error(msg || "unexpected compiler condition");
}
}
function findDir(node, name, allowEmpty) {
if (allowEmpty === void 0) { allowEmpty = false; }
for (var i = 0; i < node.props.length; i++) {
var p = node.props[i];
if (p.type === 7 /* DIRECTIVE */ &&
(allowEmpty || p.exp) &&
(shared.isString(name) ? p.name === name : name.test(p.name))) {
return p;
}
}
}
function findProp(node, name, dynamicOnly, allowEmpty) {
if (dynamicOnly === void 0) { dynamicOnly = false; }
if (allowEmpty === void 0) { allowEmpty = false; }
for (var i = 0; i < node.props.length; i++) {
var p = node.props[i];
if (p.type === 6 /* ATTRIBUTE */) {
if (dynamicOnly)
continue;
if (p.name === name && (p.value || allowEmpty)) {
return p;
}
}
else if (p.name === 'bind' &&
(p.exp || allowEmpty) &&
isBindKey(p.arg, name)) {
return p;
}
}
}
function isBindKey(arg, name) {
return !!(arg && isStaticExp(arg) && arg.content === name);
}
function hasDynamicKeyVBind(node) {
return node.props.some(function (p) { return p.type === 7 /* DIRECTIVE */ &&
p.name === 'bind' &&
(!p.arg || // v-bind="obj"
p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
!p.arg.isStatic); } // v-bind:[foo]
);
}
function isText(node) {
return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
}
function isVSlot(p) {
return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
}
function isTemplateNode(node) {
return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
}
function isSlotOutlet(node) {
return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
}
function injectProp(node, prop, context) {
var propsWithInjection;
var props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
if (props == null || shared.isString(props)) {
propsWithInjection = createObjectExpression([prop]);
}
else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
// merged props... add ours
// only inject key to object literal if it's the first argument so that
// if doesn't override user provided keys
var first = props.arguments[0];
if (!shared.isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
first.properties.unshift(prop);
}
else {
props.arguments.unshift(createObjectExpression([prop]));
}
propsWithInjection = props;
}
else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
var alreadyExists = false;
// check existing key to avoid overriding user provided keys
if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
var propKeyName_1 = prop.key.content;
alreadyExists = props.properties.some(function (p) { return p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
p.key.content === propKeyName_1; });
}
if (!alreadyExists) {
props.properties.unshift(prop);
}
propsWithInjection = props;
}
else {
// single v-bind with expression, return a merged replacement
propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
createObjectExpression([prop]),
props
]);
}
if (node.type === 13 /* VNODE_CALL */) {
node.props = propsWithInjection;
}
else {
node.arguments[2] = propsWithInjection;
}
}
function toValidAssetId(name, type) {
return "_" + type + "_" + name.replace(/[^\w]/g, '_');
}
// Check if a node contains expressions that reference current context scope ids
function hasScopeRef(node, ids) {
if (!node || Object.keys(ids).length === 0) {
return false;
}
switch (node.type) {
case 1 /* ELEMENT */:
for (var i = 0; i < node.props.length; i++) {
var p = node.props[i];
if (p.type === 7 /* DIRECTIVE */ &&
(hasScopeRef(p.arg, ids) || hasScopeRef(p.exp, ids))) {
return true;
}
}
return node.children.some(function (c) { return hasScopeRef(c, ids); });
case 11 /* FOR */:
if (hasScopeRef(node.source, ids)) {
return true;
}
return node.children.some(function (c) { return hasScopeRef(c, ids); });
case 9 /* IF */:
return node.branches.some(function (b) { return hasScopeRef(b, ids); });
case 10 /* IF_BRANCH */:
if (hasScopeRef(node.condition, ids)) {
return true;
}
return node.children.some(function (c) { return hasScopeRef(c, ids); });
case 4 /* SIMPLE_EXPRESSION */:
return (!node.isStatic &&
isSimpleIdentifier(node.content) &&
!!ids[node.content]);
case 8 /* COMPOUND_EXPRESSION */:
return node.children.some(function (c) { return shared.isObject(c) && hasScopeRef(c, ids); });
case 5 /* INTERPOLATION */:
case 12 /* TEXT_CALL */:
return hasScopeRef(node.content, ids);
case 2 /* TEXT */:
case 3 /* COMMENT */:
return false;
default:
return false;
}
}
// The default decoder only provides escapes for characters reserved as part of
// the template syntax, and is only used if the custom renderer did not provide
// a platform-specific decoder.
var decodeRE = /&(gt|lt|amp|apos|quot);/g;
var decodeMap = {
gt: '>',
lt: '<',
amp: '&',
apos: "'",
quot: '"'
};
var defaultParserOptions = {
delimiters: ["{{", "}}"],
getNamespace: function () { return 0; } /* HTML */,
getTextMode: function () { return 0; } /* DATA */,
isVoidTag: shared.NO,
isPreTag: shared.NO,
isCustomElement: shared.NO,
decodeEntities: function (rawText) { return rawText.replace(decodeRE, function (_, p1) { return decodeMap[p1]; }); },
onError: defaultOnError,
comments: false
};
function baseParse(content, options) {
if (options === void 0) { options = {}; }
var context = createParserContext(content, options);
var start = getCursor(context);
return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
}
function createParserContext(content, rawOptions) {
var options = shared.extend({}, defaultParserOptions);
for (var key in rawOptions) {
// @ts-ignore
options[key] = rawOptions[key] || defaultParserOptions[key];
}
return {
options: options,
column: 1,
line: 1,
offset: 0,
originalSource: content,
source: content,
inPre: false,
inVPre: false
};
}
function parseChildren(context, mode, ancestors) {
var parent = last(ancestors);
var ns = parent ? parent.ns : 0 /* HTML */;
var nodes = [];
while (!isEnd(context, mode, ancestors)) {
var s = context.source;
var node = undefined;
if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
// '{{'
node = parseInterpolation(context, mode);
}
else if (mode === 0 /* DATA */ && s[0] === '<') {
// https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
if (s.length === 1) {
emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
}
else if (s[1] === '!') {
// https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
if (startsWith(s, '<!--')) {
node = parseComment(context);
}
else if (startsWith(s, '<!DOCTYPE')) {
// Ignore DOCTYPE by a limitation.
node = parseBogusComment(context);
}
else if (startsWith(s, '<![CDATA[')) {
if (ns !== 0 /* HTML */) {
node = parseCDATA(context, ancestors);
}
else {
emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
node = parseBogusComment(context);
}
}
else {
emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
node = parseBogusComment(context);
}
}
else if (s[1] === '/') {
// https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
if (s.length === 2) {
emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
}
else if (s[2] === '>') {
emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
advanceBy(context, 3);
continue;
}
else if (/[a-z]/i.test(s[2])) {
emitError(context, 23 /* X_INVALID_END_TAG */);
parseTag(context, 1 /* End */, parent);
continue;
}
else {
emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
node = parseBogusComment(context);
}
}
else if (/[a-z]/i.test(s[1])) {
node = parseElement(context, ancestors);
}
else if (s[1] === '?') {
emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
node = parseBogusComment(context);
}
else {
emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
}
}
}
if (!node) {
node = parseText(context, mode);
}
if (shared.isArray(node)) {
for (var i = 0; i < node.length; i++) {
pushNode(nodes, node[i]);
}
}
else {
pushNode(nodes, node);
}
}
// Whitespace management for more efficient output
// (same as v2 whitespace: 'condense')
var removedWhitespace = false;
if (mode !== 2 /* RAWTEXT */) {
if (!context.inPre) {
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (node.type === 2 /* TEXT */) {
if (!/[^\t\r\n\f ]/.test(node.content)) {
var prev = nodes[i - 1];
var next = nodes[i + 1];
// If:
// - the whitespace is the first or last node, or:
// - the whitespace is adjacent to a comment, or:
// - the whitespace is between two elements AND contains newline
// Then the whitespace is ignored.
if (!prev ||
!next ||
prev.type === 3 /* COMMENT */ ||
next.type === 3 /* COMMENT */ ||
(prev.type === 1 /* ELEMENT */ &&
next.type === 1 /* ELEMENT */ &&
/[\r\n]/.test(node.content))) {
removedWhitespace = true;
nodes[i] = null;
}
else {
// Otherwise, condensed consecutive whitespace inside the text
// down to a single space
node.content = ' ';
}
}
else {
node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
}
}
}
}
else if (parent && context.options.isPreTag(parent.tag)) {
// remove leading newline per html spec
// https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
var first = nodes[0];
if (first && first.type === 2 /* TEXT */) {
first.content = first.content.replace(/^\r?\n/, '');
}
}
}
return removedWhitespace ? nodes.filter(Boolean) : nodes;
}
function pushNode(nodes, node) {
if (node.type === 2 /* TEXT */) {
var prev = last(nodes);
// Merge if both this and the previous node are text and those are
// consecutive. This happens for cases like "a < b".
if (prev &&
prev.type === 2 /* TEXT */ &&
prev.loc.end.offset === node.loc.start.offset) {
prev.content += node.content;
prev.loc.end = node.loc.end;
prev.loc.source += node.loc.source;
return;
}
}
nodes.push(node);
}
function parseCDATA(context, ancestors) {
advanceBy(context, 9);
var nodes = parseChildren(context, 3 /* CDATA */, ancestors);
if (context.source.length === 0) {
emitError(context, 6 /* EOF_IN_CDATA */);
}
else {
advanceBy(context, 3);
}
return nodes;
}
function parseComment(context) {
var start = getCursor(context);
var content;
// Regular comment.
var match = /--(\!)?>/.exec(context.source);
if (!match) {
content = context.source.slice(4);
advanceBy(context, context.source.length);
emitError(context, 7 /* EOF_IN_COMMENT */);
}
else {
if (match.index <= 3) {
emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
}
if (match[1]) {
emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
}
content = context.source.slice(4, match.index);
// Advancing with reporting nested comments.
var s = context.source.slice(0, match.index);
var prevIndex = 1, nestedIndex = 0;
while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
advanceBy(context, nestedIndex - prevIndex + 1);
if (nestedIndex + 4 < s.length) {
emitError(context, 16 /* NESTED_COMMENT */);
}
prevIndex = nestedIndex + 1;
}
advanceBy(context, match.index + match[0].length - prevIndex + 1);
}
return {
type: 3 /* COMMENT */,
content: content,
loc: getSelection(context, start)
};
}
function parseBogusComment(context) {
var start = getCursor(context);
var contentStart = context.source[1] === '?' ? 1 : 2;
var content;
var closeIndex = context.source.indexOf('>');
if (closeIndex === -1) {
content = context.source.slice(contentStart);
advanceBy(context, context.source.length);
}
else {
content = context.source.slice(contentStart, closeIndex);
advanceBy(context, closeIndex + 1);
}
return {
type: 3 /* COMMENT */,
content: content,
loc: getSelection(context, start)
};
}
function parseElement(context, ancestors) {
// Start tag.
var wasInPre = context.inPre;
var wasInVPre = context.inVPre;
var parent = last(ancestors);
var element = parseTag(context, 0 /* Start */, parent);
var isPreBoundary = context.inPre && !wasInPre;
var isVPreBoundary = context.inVPre && !wasInVPre;
if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
return element;
}
// Children.
ancestors.push(element);
var mode = context.options.getTextMode(element, parent);
var children = parseChildren(context, mode, ancestors);
ancestors.pop();
element.children = children;
// End tag.
if (startsWithEndTagOpen(context.source, element.tag)) {
parseTag(context, 1 /* End */, parent);
}
else {
emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
var first = children[0];
if (first && startsWith(first.loc.source, '<!--')) {
emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
}
}
}
element.loc = getSelection(context, element.loc.start);
if (isPreBoundary) {
context.inPre = false;
}
if (isVPreBoundary) {
context.inVPre = false;
}
return element;
}
var isSpecialTemplateDirective = /*#__PURE__*/ shared.makeMap("if,else,else-if,for,slot");
/**
* Parse a tag (E.g. `<div id=a>`) with that type (start tag or end tag).
*/
function parseTag(context, type, parent) {
// Tag open.
var start = getCursor(context);
var match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
var tag = match[1];
var ns = context.options.getNamespace(tag, parent);
advanceBy(context, match[0].length);
advanceSpaces(context);
// save current state in case we need to re-parse attributes with v-pre
var cursor = getCursor(context);
var currentSource = context.source;
// Attributes.
var props = parseAttributes(context, type);
// check <pre> tag
if (context.options.isPreTag(tag)) {
context.inPre = true;
}
// check v-pre
if (!context.inVPre &&
props.some(function (p) { return p.type === 7 /* DIRECTIVE */ && p.name === 'pre'; })) {
context.inVPre = true;
// reset context
shared.extend(context, cursor);
context.source = currentSource;
// re-parse attrs and filter out v-pre itself
props = parseAttributes(context, type).filter(function (p) { return p.name !== 'v-pre'; });
}
// Tag close.
var isSelfClosing = false;
if (context.source.length === 0) {
emitError(context, 9 /* EOF_IN_TAG */);
}
else {
isSelfClosing = startsWith(context.source, '/>');
if (type === 1 /* End */ && isSelfClosing) {
emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
}
advanceBy(context, isSelfClosing ? 2 : 1);
}
var tagType = 0 /* ELEMENT */;
var options = context.options;
if (!context.inVPre && !options.isCustomElement(tag)) {
var hasVIs = props.some(function (p) { return p.type === 7 /* DIRECTIVE */ && p.name === 'is'; });
if (options.isNativeTag && !hasVIs) {
if (!options.isNativeTag(tag))
tagType = 1 /* COMPONENT */;
}
else if (hasVIs ||
isCoreComponent(tag) ||
(options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
/^[A-Z]/.test(tag) ||
tag === 'component') {
tagType = 1 /* COMPONENT */;
}
if (tag === 'slot') {
tagType = 2 /* SLOT */;
}
else if (tag === 'template' &&
props.some(function (p) {
return (p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name));
})) {
tagType = 3 /* TEMPLATE */;
}
}
return {
type: 1 /* ELEMENT */,
ns: ns,
tag: tag,
tagType: tagType,
props: props,
isSelfClosing: isSelfClosing,
children: [],
loc: getSelection(context, start),
codegenNode: undefined // to be created during transform phase
};
}
function parseAttributes(context, type) {
var props = [];
var attributeNames = new Set();
while (context.source.length > 0 &&
!startsWith(context.source, '>') &&
!startsWith(context.source, '/>')) {
if (startsWith(context.source, '/')) {
emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
advanceBy(context, 1);
advanceSpaces(context);
continue;
}
if (type === 1 /* End */) {
emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
}
var attr = parseAttribute(context, attributeNames);
if (type === 0 /* Start */) {
props.push(attr);
}
if (/^[^\t\r\n\f />]/.test(context.source)) {
emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
}
advanceSpaces(context);
}
return props;
}
function parseAttribute(context, nameSet) {
// Name.
var start = getCursor(context);
var match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
var name = match[0];
if (nameSet.has(name)) {
emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
}
nameSet.add(name);
if (name[0] === '=') {
emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
}
{
var pattern = /["'<]/g;
var m = void 0;
while ((m = pattern.exec(name))) {
emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
}
}
advanceBy(context, name.length);
// Value
var value = undefined;
if (/^[\t\r\n\f ]*=/.test(context.source)) {
advanceSpaces(context);
advanceBy(context, 1);
advanceSpaces(context);
value = parseAttributeValue(context);
if (!value) {
emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
}
}
var loc = getSelection(context, start);
if (!context.inVPre && /^(v-|:|@|#)/.test(name)) {
var match_1 = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
var dirName = match_1[1] ||
(startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot');
var arg = void 0;
if (match_1[2]) {
var isSlot = dirName === 'slot';
var startOffset = name.indexOf(match_1[2]);
var loc_1 = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match_1[2].length + ((isSlot && match_1[3]) || '').length));
var content = match_1[2];
var isStatic = true;
if (content.startsWith('[')) {
isStatic = false;
if (!content.endsWith(']')) {
emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
}
content = content.substr(1, content.length - 2);
}
else if (isSlot) {
// #1241 special case for v-slot: vuetify relies extensively on slot
// names containing dots. v-slot doesn't have any modifiers and Vue 2.x
// supports such usage so we are keeping it consistent with 2.x.
content += match_1[3] || '';
}
arg = {
type: 4 /* SIMPLE_EXPRESSION */,
content: content,
isStatic: isStatic,
isConstant: isStatic,
loc: loc_1
};
}
if (value && value.isQuoted) {
var valueLoc = value.loc;
valueLoc.start.offset++;
valueLoc.start.column++;
valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
valueLoc.source = valueLoc.source.slice(1, -1);
}
return {
type: 7 /* DIRECTIVE */,
name: dirName,
exp: value && {
type: 4 /* SIMPLE_EXPRESSION */,
content: value.content,
isStatic: false,
// Treat as non-constant by default. This can be potentially set to
// true by `transformExpression` to make it eligible for hoisting.
isConstant: false,
loc: value.loc
},
arg: arg,
modifiers: match_1[3] ? match_1[3].substr(1).split('.') : [],
loc: loc
};
}
return {
type: 6 /* ATTRIBUTE */,
name: name,
value: value && {
type: 2 /* TEXT */,
content: value.content,
loc: value.loc
},
loc: loc
};
}
function parseAttributeValue(context) {
var start = getCursor(context);
var content;
var quote = context.source[0];
var isQuoted = quote === "\"" || quote === "'";
if (isQuoted) {
// Quoted value.
advanceBy(context, 1);
var endIndex = context.source.indexOf(quote);
if (endIndex === -1) {
content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
}
else {
content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
advanceBy(context, 1);
}
}
else {
// Unquoted
var match = /^[^\t\r\n\f >]+/.exec(context.source);
if (!match) {
return undefined;
}
var unexpectedChars = /["'<=`]/g;
var m = void 0;
while ((m = unexpectedChars.exec(match[0]))) {
emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
}
content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
}
return { content: content, isQuoted: isQuoted, loc: getSelection(context, start) };
}
function parseInterpolation(context, mode) {
var _a = context.options.delimiters, open = _a[0], close = _a[1];
var closeIndex = context.source.indexOf(close, open.length);
if (closeIndex === -1) {
emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
return undefined;
}
var start = getCursor(context);
advanceBy(context, open.length);
var innerStart = getCursor(context);
var innerEnd = getCursor(context);
var rawContentLength = closeIndex - open.length;
var rawContent = context.source.slice(0, rawContentLength);
var preTrimContent = parseTextData(context, rawContentLength, mode);
var content = preTrimContent.trim();
var startOffset = preTrimContent.indexOf(content);
if (startOffset > 0) {
advancePositionWithMutation(innerStart, rawContent, startOffset);
}
var endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
advancePositionWithMutation(innerEnd, rawContent, endOffset);
advanceBy(context, close.length);
return {
type: 5 /* INTERPOLATION */,
content: {
type: 4 /* SIMPLE_EXPRESSION */,
isStatic: false,
// Set `isConstant` to false by default and will decide in transformExpression
isConstant: false,
content: content,
loc: getSelection(context, innerStart, innerEnd)
},
loc: getSelection(context, start)
};
}
function parseText(context, mode) {
var endTokens = ['<', context.options.delimiters[0]];
if (mode === 3 /* CDATA */) {
endTokens.push(']]>');
}
var endIndex = context.source.length;
for (var i = 0; i < endTokens.length; i++) {
var index = context.source.indexOf(endTokens[i], 1);
if (index !== -1 && endIndex > index) {
endIndex = index;
}
}
var start = getCursor(context);
var content = parseTextData(context, endIndex, mode);
return {
type: 2 /* TEXT */,
content: content,
loc: getSelection(context, start)
};
}
/**
* Get text data with a given length from the current location.
* This translates HTML entities in the text data.
*/
function parseTextData(context, length, mode) {
var rawText = context.source.slice(0, length);
advanceBy(context, length);
if (mode === 2 /* RAWTEXT */ ||
mode === 3 /* CDATA */ ||
rawText.indexOf('&') === -1) {
return rawText;
}
else {
// DATA or RCDATA containing "&"". Entity decoding required.
return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
}
}
function getCursor(context) {
var column = context.column, line = context.line, offset = context.offset;
return { column: column, line: line, offset: offset };
}
function getSelection(context, start, end) {
end = end || getCursor(context);
return {
start: start,
end: end,
source: context.originalSource.slice(start.offset, end.offset)
};
}
function last(xs) {
return xs[xs.length - 1];
}
function startsWith(source, searchString) {
return source.startsWith(searchString);
}
function advanceBy(context, numberOfCharacters) {
var source = context.source;
advancePositionWithMutation(context, source, numberOfCharacters);
context.source = source.slice(numberOfCharacters);
}
function advanceSpaces(context) {
var match = /^[\t\r\n\f ]+/.exec(context.source);
if (match) {
advanceBy(context, match[0].length);
}
}
function getNewPosition(context, start, numberOfCharacters) {
return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
}
function emitError(context, code, offset, loc) {
if (loc === void 0) { loc = getCursor(context); }
if (offset) {
loc.offset += offset;
loc.column += offset;
}
context.options.onError(createCompilerError(code, {
start: loc,
end: loc,
source: ''
}));
}
function isEnd(context, mode, ancestors) {
var s = context.source;
switch (mode) {
case 0 /* DATA */:
if (startsWith(s, '</')) {
//TODO: probably bad performance
for (var i = ancestors.length - 1; i >= 0; --i) {
if (startsWithEndTagOpen(s, ancestors[i].tag)) {
return true;
}
}
}
break;
case 1 /* RCDATA */:
case 2 /* RAWTEXT */: {
var parent_1 = last(ancestors);
if (parent_1 && startsWithEndTagOpen(s, parent_1.tag)) {
return true;
}
break;
}
case 3 /* CDATA */:
if (startsWith(s, ']]>')) {
return true;
}
break;
}
return !s;
}
function startsWithEndTagOpen(source, tag) {
return (startsWith(source, '</') &&
source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
/[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
}
function hoistStatic(root, context) {
walk(root, context, new Map(),
// Root node is unfortunately non-hoistable due to potential parent
// fallthrough attributes.
isSingleElementRoot(root, root.children[0]));
}
function isSingleElementRoot(root, child) {
var children = root.children;
return (children.length === 1 &&
child.type === 1 /* ELEMENT */ &&
!isSlotOutlet(child));
}
function walk(node, context, resultCache, doNotHoistNode) {
if (doNotHoistNode === void 0) { doNotHoistNode = false; }
var hasHoistedNode = false;
// Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
// static bindings with expressions. These expressions are guaranteed to be
// constant so they are still eligible for hoisting, but they are only
// available at runtime and therefore cannot be evaluated ahead of time.
// This is only a concern for pre-stringification (via transformHoist by
// @vue/compiler-dom), but doing it here allows us to perform only one full
// walk of the AST and allow `stringifyStatic` to stop walking as soon as its
// stringficiation threshold is met.
var hasRuntimeConstant = false;
var children = node.children;
for (var i = 0; i < children.length; i++) {
var child = children[i];
// only plain elements & text calls are eligible for hoisting.
if (child.type === 1 /* ELEMENT */ &&
child.tagType === 0 /* ELEMENT */) {
var staticType = void 0;
if (!doNotHoistNode &&
(staticType = getStaticType(child, resultCache)) > 0) {
if (staticType === 2 /* HAS_RUNTIME_CONSTANT */) {
hasRuntimeConstant = true;
}
child.codegenNode.patchFlag =
-1 /* HOISTED */ + (" /* HOISTED */");
child.codegenNode = context.hoist(child.codegenNode);
hasHoistedNode = true;
continue;
}
else {
// node may contain dynamic children, but its props may be eligible for
// hoisting.
var codegenNode = child.codegenNode;
if (codegenNode.type === 13 /* VNODE_CALL */) {
var flag = getPatchFlag(codegenNode);
if ((!flag ||
flag === 512 /* NEED_PATCH */ ||
flag === 1 /* TEXT */) &&
!hasNonHoistableProps(child)) {
var props = getNodeProps(child);
if (props) {
codegenNode.props = context.hoist(props);
}
}
}
}
}
else if (child.type === 12 /* TEXT_CALL */) {
var staticType = getStaticType(child.content, resultCache);
if (staticType > 0) {
if (staticType === 2 /* HAS_RUNTIME_CONSTANT */) {
hasRunti