8889841cutil.ts000066600000001605150513700470006101 0ustar00import { makeMap } from 'shared/util' export const isUnaryTag = makeMap( 'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' + 'link,meta,param,source,track,wbr' ) // Elements that you can, intentionally, leave open // (and which close themselves) export const canBeLeftOpenTag = makeMap( 'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source' ) // HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3 // Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content export const isNonPhrasingTag = makeMap( 'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' + 'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' + 'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' + 'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' + 'title,tr,track' ) index.ts000066600000000305150513700470006227 0ustar00import { baseOptions } from './options' import { createCompiler } from 'compiler/index' const { compile, compileToFunctions } = createCompiler(baseOptions) export { compile, compileToFunctions } modules/index.ts000066600000000172150513700470007701 0ustar00import klass from './class' import style from './style' import model from './model' export default [klass, style, model] modules/model.ts000066600000005225150513700470007676 0ustar00/** * Expand input[v-model] with dynamic type bindings into v-if-else chains * Turn this: * * into this: * * * */ import { addRawAttr, getBindingAttr, getAndRemoveAttr } from 'compiler/helpers' import { processFor, processElement, addIfCondition, createASTElement } from 'compiler/parser/index' import { ASTElement, CompilerOptions, ModuleOptions } from 'types/compiler' function preTransformNode(el: ASTElement, options: CompilerOptions) { 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) } export default { preTransformNode } as ModuleOptions modules/class.ts000066600000002470150513700470007702 0ustar00import { parseText } from 'compiler/parser/text-parser' import { getAndRemoveAttr, getBindingAttr, baseWarn } from 'compiler/helpers' import { ASTElement, CompilerOptions, ModuleOptions } from 'types/compiler' function transformNode(el: ASTElement, options: CompilerOptions) { const warn = options.warn || baseWarn const staticClass = getAndRemoveAttr(el, 'class') if (__DEV__ && staticClass) { const res = parseText(staticClass, options.delimiters) if (res) { warn( `class="${staticClass}": ` + 'Interpolation inside attributes has been removed. ' + 'Use v-bind or the colon shorthand instead. For example, ' + 'instead of
, use
.', el.rawAttrsMap['class'] ) } } if (staticClass) { el.staticClass = JSON.stringify(staticClass.replace(/\s+/g, ' ').trim()) } const classBinding = getBindingAttr(el, 'class', false /* getStatic */) if (classBinding) { el.classBinding = classBinding } } function genData(el: ASTElement): string { let data = '' if (el.staticClass) { data += `staticClass:${el.staticClass},` } if (el.classBinding) { data += `class:${el.classBinding},` } return data } export default { staticKeys: ['staticClass'], transformNode, genData } as ModuleOptions modules/style.ts000066600000002605150513700470007735 0ustar00import { parseText } from 'compiler/parser/text-parser' import { parseStyleText } from 'web/util/style' import { getAndRemoveAttr, getBindingAttr, baseWarn } from 'compiler/helpers' import { ASTElement, CompilerOptions, ModuleOptions } from 'types/compiler' function transformNode(el: ASTElement, options: CompilerOptions) { const warn = options.warn || baseWarn const staticStyle = getAndRemoveAttr(el, 'style') if (staticStyle) { /* istanbul ignore if */ if (__DEV__) { const res = parseText(staticStyle, options.delimiters) if (res) { warn( `style="${staticStyle}": ` + 'Interpolation inside attributes has been removed. ' + 'Use v-bind or the colon shorthand instead. For example, ' + 'instead of
, use
.', el.rawAttrsMap['style'] ) } } el.staticStyle = JSON.stringify(parseStyleText(staticStyle)) } const styleBinding = getBindingAttr(el, 'style', false /* getStatic */) if (styleBinding) { el.styleBinding = styleBinding } } function genData(el: ASTElement): string { let data = '' if (el.staticStyle) { data += `staticStyle:${el.staticStyle},` } if (el.styleBinding) { data += `style:(${el.styleBinding}),` } return data } export default { staticKeys: ['staticStyle'], transformNode, genData } as ModuleOptions directives/index.ts000066600000000174150513700470010374 0ustar00import model from './model' import text from './text' import html from './html' export default { model, text, html } directives/html.ts000066600000000367150513700470010235 0ustar00import { addProp } from 'compiler/helpers' import { ASTDirective, ASTElement } from 'types/compiler' export default function html(el: ASTElement, dir: ASTDirective) { if (dir.value) { addProp(el, 'innerHTML', `_s(${dir.value})`, dir) } } directives/model.ts000066600000013102150513700470010360 0ustar00import config from 'core/config' import { addHandler, addProp, getBindingAttr } from 'compiler/helpers' import { genComponentModel, genAssignmentCode } from 'compiler/directives/model' import { ASTDirective, ASTElement, ASTModifiers } from 'types/compiler' let warn // in some cases, the event used has to be determined at runtime // so we used some reserved tokens during compile. export const RANGE_TOKEN = '__r' export const CHECKBOX_RADIO_TOKEN = '__c' export default function model( el: ASTElement, dir: ASTDirective, _warn: Function ): boolean | undefined { warn = _warn const value = dir.value const modifiers = dir.modifiers const tag = el.tag const type = el.attrsMap.type if (__DEV__) { // 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 if (!config.isReservedTag(tag)) { genComponentModel(el, value, modifiers) // component v-model doesn't need extra runtime return false } else if (__DEV__) { warn( `<${el.tag} v-model="${value}">: ` + `v-model is not supported on this element type. ` + "If you are working with contenteditable, it's recommended to " + 'wrap a library dedicated for that purpose inside a custom component.', el.rawAttrsMap['v-model'] ) } // ensure runtime directive metadata return true } function genCheckboxModel( el: ASTElement, value: string, modifiers?: ASTModifiers | null ) { 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: ASTElement, value: string, modifiers?: ASTModifiers | null ) { 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: ASTElement, value: string, modifiers?: ASTModifiers | null ) { 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: ASTElement, value: string, modifiers?: ASTModifiers | null ): boolean | void { const type = el.attrsMap.type // warn if v-bind:value conflicts with v-model // except for inputs with v-bind:type if (__DEV__) { 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()') } } directives/text.ts000066600000000371150513700470010250 0ustar00import { addProp } from 'compiler/helpers' import { ASTDirective, ASTElement } from 'types/compiler' export default function text(el: ASTElement, dir: ASTDirective) { if (dir.value) { addProp(el, 'textContent', `_s(${dir.value})`, dir) } } options.ts000066600000001050150513700470006611 0ustar00import { isPreTag, mustUseProp, isReservedTag, getTagNamespace } from '../util/index' import modules from './modules/index' import directives from './directives/index' import { genStaticKeys } from 'shared/util' import { isUnaryTag, canBeLeftOpenTag } from './util' import { CompilerOptions } from 'types/compiler' export const baseOptions: CompilerOptions = { expectHTML: true, modules, directives, isPreTag, isUnaryTag, mustUseProp, canBeLeftOpenTag, isReservedTag, getTagNamespace, staticKeys: genStaticKeys(modules) }