8889841cutil.ts 0000666 00000001605 15051370047 0006101 0 ustar 00 import { 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.ts 0000666 00000000305 15051370047 0006227 0 ustar 00 import { baseOptions } from './options'
import { createCompiler } from 'compiler/index'
const { compile, compileToFunctions } = createCompiler(baseOptions)
export { compile, compileToFunctions }
modules/index.ts 0000666 00000000172 15051370047 0007701 0 ustar 00 import klass from './class'
import style from './style'
import model from './model'
export default [klass, style, model]
modules/model.ts 0000666 00000005225 15051370047 0007676 0 ustar 00 /**
* 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.ts 0000666 00000002470 15051370047 0007702 0 ustar 00 import { 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.ts 0000666 00000002605 15051370047 0007735 0 ustar 00 import { 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.ts 0000666 00000000174 15051370047 0010374 0 ustar 00 import model from './model'
import text from './text'
import html from './html'
export default {
model,
text,
html
}
directives/html.ts 0000666 00000000367 15051370047 0010235 0 ustar 00 import { 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.ts 0000666 00000013102 15051370047 0010360 0 ustar 00 import 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.ts 0000666 00000000371 15051370047 0010250 0 ustar 00 import { 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.ts 0000666 00000001050 15051370047 0006611 0 ustar 00 import {
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)
}