, use
.', list[i]);
}
}
addAttr(el, name, JSON.stringify(value), list[i]);
// #6887 firefox doesn't update muted state if set via attribute
// even immediately after element creation
if (!el.component &&
name === 'muted' &&
platformMustUseProp(el.tag, el.attrsMap.type, name)) {
addProp(el, name, 'true', list[i]);
}
}
}
}
function checkInFor(el) {
let parent = el;
while (parent) {
if (parent.for !== undefined) {
return true;
}
parent = parent.parent;
}
return false;
}
function parseModifiers(name) {
const match = name.match(modifierRE);
if (match) {
const ret = {};
match.forEach(m => {
ret[m.slice(1)] = true;
});
return ret;
}
}
function makeAttrsMap(attrs) {
const map = {};
for (let i = 0, l = attrs.length; i < l; i++) {
if (process.env.NODE_ENV !== 'production' && map[attrs[i].name] && !isIE && !isEdge) {
warn$1('duplicate attribute: ' + attrs[i].name, attrs[i]);
}
map[attrs[i].name] = attrs[i].value;
}
return map;
}
// for script (e.g. type="x/template") or style, do not decode content
function isTextTag(el) {
return el.tag === 'script' || el.tag === 'style';
}
function isForbiddenTag(el) {
return (el.tag === 'style' ||
(el.tag === 'script' &&
(!el.attrsMap.type || el.attrsMap.type === 'text/javascript')));
}
const ieNSBug = /^xmlns:NS\d+/;
const ieNSPrefix = /^NS\d+:/;
/* istanbul ignore next */
function guardIESVGBug(attrs) {
const res = [];
for (let i = 0; i < attrs.length; i++) {
const attr = attrs[i];
if (!ieNSBug.test(attr.name)) {
attr.name = attr.name.replace(ieNSPrefix, '');
res.push(attr);
}
}
return res;
}
function checkForAliasModel(el, value) {
let _el = el;
while (_el) {
if (_el.for && _el.alias === value) {
warn$1(`<${el.tag} v-model="${value}">: ` +
`You are binding v-model directly to a v-for iteration alias. ` +
`This will not be able to modify the v-for source array because ` +
`writing to the alias is like modifying a function local variable. ` +
`Consider using an array of objects and use v-model on an object property instead.`, el.rawAttrsMap['v-model']);
}
_el = _el.parent;
}
}
/**
* Expand input[v-model] with dynamic type bindings into v-if-else chains
* Turn this:
*
* into this:
*
*
*
*/
function preTransformNode(el, options) {
if (el.tag === 'input') {
const map = el.attrsMap;
if (!map['v-model']) {
return;
}
let typeBinding;
if (map[':type'] || map['v-bind:type']) {
typeBinding = getBindingAttr(el, 'type');
}
if (!map.type && !typeBinding && map['v-bind']) {
typeBinding = `(${map['v-bind']}).type`;
}
if (typeBinding) {
const ifCondition = getAndRemoveAttr(el, 'v-if', true);
const ifConditionExtra = ifCondition ? `&&(${ifCondition})` : ``;
const hasElse = getAndRemoveAttr(el, 'v-else', true) != null;
const elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true);
// 1. checkbox
const branch0 = cloneASTElement(el);
// process for on the main node
processFor(branch0);
addRawAttr(branch0, 'type', 'checkbox');
processElement(branch0, options);
branch0.processed = true; // prevent it from double-processed
branch0.if = `(${typeBinding})==='checkbox'` + ifConditionExtra;
addIfCondition(branch0, {
exp: branch0.if,
block: branch0
});
// 2. add radio else-if condition
const branch1 = cloneASTElement(el);
getAndRemoveAttr(branch1, 'v-for', true);
addRawAttr(branch1, 'type', 'radio');
processElement(branch1, options);
addIfCondition(branch0, {
exp: `(${typeBinding})==='radio'` + ifConditionExtra,
block: branch1
});
// 3. other
const branch2 = cloneASTElement(el);
getAndRemoveAttr(branch2, 'v-for', true);
addRawAttr(branch2, ':type', typeBinding);
processElement(branch2, options);
addIfCondition(branch0, {
exp: ifCondition,
block: branch2
});
if (hasElse) {
branch0.else = true;
}
else if (elseIfCondition) {
branch0.elseif = elseIfCondition;
}
return branch0;
}
}
}
function cloneASTElement(el) {
return createASTElement(el.tag, el.attrsList.slice(), el.parent);
}
var model$1 = {
preTransformNode
};
var modules = [klass, style, model$1];
let warn;
// in some cases, the event used has to be determined at runtime
// so we used some reserved tokens during compile.
const RANGE_TOKEN = '__r';
function model(el, dir, _warn) {
warn = _warn;
const value = dir.value;
const modifiers = dir.modifiers;
const tag = el.tag;
const type = el.attrsMap.type;
if (process.env.NODE_ENV !== 'production') {
// inputs with type="file" are read only and setting the input's
// value will throw an error.
if (tag === 'input' && type === 'file') {
warn(`<${el.tag} v-model="${value}" type="file">:\n` +
`File inputs are read only. Use a v-on:change listener instead.`, el.rawAttrsMap['v-model']);
}
}
if (el.component) {
genComponentModel(el, value, modifiers);
// component v-model doesn't need extra runtime
return false;
}
else if (tag === 'select') {
genSelect(el, value, modifiers);
}
else if (tag === 'input' && type === 'checkbox') {
genCheckboxModel(el, value, modifiers);
}
else if (tag === 'input' && type === 'radio') {
genRadioModel(el, value, modifiers);
}
else if (tag === 'input' || tag === 'textarea') {
genDefaultModel(el, value, modifiers);
}
else {
genComponentModel(el, value, modifiers);
// component v-model doesn't need extra runtime
return false;
}
// ensure runtime directive metadata
return true;
}
function genCheckboxModel(el, value, modifiers) {
const number = modifiers && modifiers.number;
const valueBinding = getBindingAttr(el, 'value') || 'null';
const trueValueBinding = getBindingAttr(el, 'true-value') || 'true';
const falseValueBinding = getBindingAttr(el, 'false-value') || 'false';
addProp(el, 'checked', `Array.isArray(${value})` +
`?_i(${value},${valueBinding})>-1` +
(trueValueBinding === 'true'
? `:(${value})`
: `:_q(${value},${trueValueBinding})`));
addHandler(el, 'change', `var $$a=${value},` +
'$$el=$event.target,' +
`$$c=$$el.checked?(${trueValueBinding}):(${falseValueBinding});` +
'if(Array.isArray($$a)){' +
`var $$v=${number ? '_n(' + valueBinding + ')' : valueBinding},` +
'$$i=_i($$a,$$v);' +
`if($$el.checked){$$i<0&&(${genAssignmentCode(value, '$$a.concat([$$v])')})}` +
`else{$$i>-1&&(${genAssignmentCode(value, '$$a.slice(0,$$i).concat($$a.slice($$i+1))')})}` +
`}else{${genAssignmentCode(value, '$$c')}}`, null, true);
}
function genRadioModel(el, value, modifiers) {
const number = modifiers && modifiers.number;
let valueBinding = getBindingAttr(el, 'value') || 'null';
valueBinding = number ? `_n(${valueBinding})` : valueBinding;
addProp(el, 'checked', `_q(${value},${valueBinding})`);
addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true);
}
function genSelect(el, value, modifiers) {
const number = modifiers && modifiers.number;
const selectedVal = `Array.prototype.filter` +
`.call($event.target.options,function(o){return o.selected})` +
`.map(function(o){var val = "_value" in o ? o._value : o.value;` +
`return ${number ? '_n(val)' : 'val'}})`;
const assignment = '$event.target.multiple ? $$selectedVal : $$selectedVal[0]';
let code = `var $$selectedVal = ${selectedVal};`;
code = `${code} ${genAssignmentCode(value, assignment)}`;
addHandler(el, 'change', code, null, true);
}
function genDefaultModel(el, value, modifiers) {
const type = el.attrsMap.type;
// warn if v-bind:value conflicts with v-model
// except for inputs with v-bind:type
if (process.env.NODE_ENV !== 'production') {
const value = el.attrsMap['v-bind:value'] || el.attrsMap[':value'];
const typeBinding = el.attrsMap['v-bind:type'] || el.attrsMap[':type'];
if (value && !typeBinding) {
const binding = el.attrsMap['v-bind:value'] ? 'v-bind:value' : ':value';
warn(`${binding}="${value}" conflicts with v-model on the same element ` +
'because the latter already expands to a value binding internally', el.rawAttrsMap[binding]);
}
}
const { lazy, number, trim } = modifiers || {};
const needCompositionGuard = !lazy && type !== 'range';
const event = lazy ? 'change' : type === 'range' ? RANGE_TOKEN : 'input';
let valueExpression = '$event.target.value';
if (trim) {
valueExpression = `$event.target.value.trim()`;
}
if (number) {
valueExpression = `_n(${valueExpression})`;
}
let code = genAssignmentCode(value, valueExpression);
if (needCompositionGuard) {
code = `if($event.target.composing)return;${code}`;
}
addProp(el, 'value', `(${value})`);
addHandler(el, event, code, null, true);
if (trim || number) {
addHandler(el, 'blur', '$forceUpdate()');
}
}
function text(el, dir) {
if (dir.value) {
addProp(el, 'textContent', `_s(${dir.value})`, dir);
}
}
function html(el, dir) {
if (dir.value) {
addProp(el, 'innerHTML', `_s(${dir.value})`, dir);
}
}
var directives = {
model,
text,
html
};
const baseOptions = {
expectHTML: true,
modules,
directives,
isPreTag,
isUnaryTag,
mustUseProp,
canBeLeftOpenTag,
isReservedTag,
getTagNamespace,
staticKeys: genStaticKeys$1(modules)
};
let isStaticKey;
let isPlatformReservedTag$1;
const genStaticKeysCached = cached(genStaticKeys);
/**
* Goal of the optimizer: walk the generated template AST tree
* and detect sub-trees that are purely static, i.e. parts of
* the DOM that never needs to change.
*
* Once we detect these sub-trees, we can:
*
* 1. Hoist them into constants, so that we no longer need to
* create fresh nodes for them on each re-render;
* 2. Completely skip them in the patching process.
*/
function optimize$1(root, options) {
if (!root)
return;
isStaticKey = genStaticKeysCached(options.staticKeys || '');
isPlatformReservedTag$1 = options.isReservedTag || no;
// first pass: mark all non-static nodes.
markStatic(root);
// second pass: mark static roots.
markStaticRoots(root, false);
}
function genStaticKeys(keys) {
return makeMap('type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap' +
(keys ? ',' + keys : ''));
}
function markStatic(node) {
node.static = isStatic(node);
if (node.type === 1) {
// do not make component slot content static. this avoids
// 1. components not able to mutate slot nodes
// 2. static slot content fails for hot-reloading
if (!isPlatformReservedTag$1(node.tag) &&
node.tag !== 'slot' &&
node.attrsMap['inline-template'] == null) {
return;
}
for (let i = 0, l = node.children.length; i < l; i++) {
const child = node.children[i];
markStatic(child);
if (!child.static) {
node.static = false;
}
}
if (node.ifConditions) {
for (let i = 1, l = node.ifConditions.length; i < l; i++) {
const block = node.ifConditions[i].block;
markStatic(block);
if (!block.static) {
node.static = false;
}
}
}
}
}
function markStaticRoots(node, isInFor) {
if (node.type === 1) {
if (node.static || node.once) {
node.staticInFor = isInFor;
}
// For a node to qualify as a static root, it should have children that
// are not just static text. Otherwise the cost of hoisting out will
// outweigh the benefits and it's better off to just always render it fresh.
if (node.static &&
node.children.length &&
!(node.children.length === 1 && node.children[0].type === 3)) {
node.staticRoot = true;
return;
}
else {
node.staticRoot = false;
}
if (node.children) {
for (let i = 0, l = node.children.length; i < l; i++) {
markStaticRoots(node.children[i], isInFor || !!node.for);
}
}
if (node.ifConditions) {
for (let i = 1, l = node.ifConditions.length; i < l; i++) {
markStaticRoots(node.ifConditions[i].block, isInFor);
}
}
}
}
function isStatic(node) {
if (node.type === 2) {
// expression
return false;
}
if (node.type === 3) {
// text
return true;
}
return !!(node.pre ||
(!node.hasBindings && // no dynamic bindings
!node.if &&
!node.for && // not v-if or v-for or v-else
!isBuiltInTag(node.tag) && // not a built-in
isPlatformReservedTag$1(node.tag) && // not a component
!isDirectChildOfTemplateFor(node) &&
Object.keys(node).every(isStaticKey)));
}
function isDirectChildOfTemplateFor(node) {
while (node.parent) {
node = node.parent;
if (node.tag !== 'template') {
return false;
}
if (node.for) {
return true;
}
}
return false;
}
const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function(?:\s+[\w$]+)?\s*\(/;
const fnInvokeRE = /\([^)]*?\);*$/;
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/;
// KeyboardEvent.keyCode aliases
const keyCodes = {
esc: 27,
tab: 9,
enter: 13,
space: 32,
up: 38,
left: 37,
right: 39,
down: 40,
delete: [8, 46]
};
// KeyboardEvent.key aliases
const keyNames = {
// #7880: IE11 and Edge use `Esc` for Escape key name.
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
// #9112: IE11 uses `Spacebar` for Space key name.
space: [' ', 'Spacebar'],
// #7806: IE11 uses key names without `Arrow` prefix for arrow keys.
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
// #9112: IE11 uses `Del` for Delete key name.
delete: ['Backspace', 'Delete', 'Del']
};
// #4868: modifiers that prevent the execution of the listener
// need to explicitly return null so that we can determine whether to remove
// the listener for .once
const genGuard = condition => `if(${condition})return null;`;
const modifierCode = {
stop: '$event.stopPropagation();',
prevent: '$event.preventDefault();',
self: genGuard(`$event.target !== $event.currentTarget`),
ctrl: genGuard(`!$event.ctrlKey`),
shift: genGuard(`!$event.shiftKey`),
alt: genGuard(`!$event.altKey`),
meta: genGuard(`!$event.metaKey`),
left: genGuard(`'button' in $event && $event.button !== 0`),
middle: genGuard(`'button' in $event && $event.button !== 1`),
right: genGuard(`'button' in $event && $event.button !== 2`)
};
function genHandlers(events, isNative) {
const prefix = isNative ? 'nativeOn:' : 'on:';
let staticHandlers = ``;
let dynamicHandlers = ``;
for (const name in events) {
const handlerCode = genHandler(events[name]);
//@ts-expect-error
if (events[name] && events[name].dynamic) {
dynamicHandlers += `${name},${handlerCode},`;
}
else {
staticHandlers += `"${name}":${handlerCode},`;
}
}
staticHandlers = `{${staticHandlers.slice(0, -1)}}`;
if (dynamicHandlers) {
return prefix + `_d(${staticHandlers},[${dynamicHandlers.slice(0, -1)}])`;
}
else {
return prefix + staticHandlers;
}
}
function genHandler(handler) {
if (!handler) {
return 'function(){}';
}
if (Array.isArray(handler)) {
return `[${handler.map(handler => genHandler(handler)).join(',')}]`;
}
const isMethodPath = simplePathRE.test(handler.value);
const isFunctionExpression = fnExpRE.test(handler.value);
const isFunctionInvocation = simplePathRE.test(handler.value.replace(fnInvokeRE, ''));
if (!handler.modifiers) {
if (isMethodPath || isFunctionExpression) {
return handler.value;
}
return `function($event){${isFunctionInvocation ? `return ${handler.value}` : handler.value}}`; // inline statement
}
else {
let code = '';
let genModifierCode = '';
const keys = [];
for (const key in handler.modifiers) {
if (modifierCode[key]) {
genModifierCode += modifierCode[key];
// left/right
if (keyCodes[key]) {
keys.push(key);
}
}
else if (key === 'exact') {
const modifiers = handler.modifiers;
genModifierCode += genGuard(['ctrl', 'shift', 'alt', 'meta']
.filter(keyModifier => !modifiers[keyModifier])
.map(keyModifier => `$event.${keyModifier}Key`)
.join('||'));
}
else {
keys.push(key);
}
}
if (keys.length) {
code += genKeyFilter(keys);
}
// Make sure modifiers like prevent and stop get executed after key filtering
if (genModifierCode) {
code += genModifierCode;
}
const handlerCode = isMethodPath
? `return ${handler.value}.apply(null, arguments)`
: isFunctionExpression
? `return (${handler.value}).apply(null, arguments)`
: isFunctionInvocation
? `return ${handler.value}`
: handler.value;
return `function($event){${code}${handlerCode}}`;
}
}
function genKeyFilter(keys) {
return (
// make sure the key filters only apply to KeyboardEvents
// #9441: can't use 'keyCode' in $event because Chrome autofill fires fake
// key events that do not have keyCode property...
`if(!$event.type.indexOf('key')&&` +
`${keys.map(genFilterCode).join('&&')})return null;`);
}
function genFilterCode(key) {
const keyVal = parseInt(key, 10);
if (keyVal) {
return `$event.keyCode!==${keyVal}`;
}
const keyCode = keyCodes[key];
const keyName = keyNames[key];
return (`_k($event.keyCode,` +
`${JSON.stringify(key)},` +
`${JSON.stringify(keyCode)},` +
`$event.key,` +
`${JSON.stringify(keyName)}` +
`)`);
}
function on(el, dir) {
if (process.env.NODE_ENV !== 'production' && dir.modifiers) {
warn$2(`v-on without argument does not support modifiers.`);
}
el.wrapListeners = (code) => `_g(${code},${dir.value})`;
}
function bind(el, dir) {
el.wrapData = (code) => {
return `_b(${code},'${el.tag}',${dir.value},${dir.modifiers && dir.modifiers.prop ? 'true' : 'false'}${dir.modifiers && dir.modifiers.sync ? ',true' : ''})`;
};
}
var baseDirectives = {
on,
bind,
cloak: noop
};
class CodegenState {
constructor(options) {
this.options = options;
this.warn = options.warn || baseWarn;
this.transforms = pluckModuleFunction(options.modules, 'transformCode');
this.dataGenFns = pluckModuleFunction(options.modules, 'genData');
this.directives = extend(extend({}, baseDirectives), options.directives);
const isReservedTag = options.isReservedTag || no;
this.maybeComponent = (el) => !!el.component || !isReservedTag(el.tag);
this.onceId = 0;
this.staticRenderFns = [];
this.pre = false;
}
}
function generate$1(ast, options) {
const state = new CodegenState(options);
// fix #11483, Root level