const {
|
ID,
|
GET_DATA,
|
isVar,
|
getNewId,
|
getForEl,
|
updateForEleId,
|
updateScopedSlotEleId,
|
processForKey,
|
traverseNode
|
} = require('./util')
|
|
const {
|
parseIs,
|
parseRef,
|
parseSlotName,
|
parseIf,
|
parseFor,
|
parseText,
|
parseAttrs,
|
parseProps,
|
parseBinding
|
} = require('./parser/base-parser')
|
|
const parseTag = require('./parser/tag-parser')
|
const parseEvent = require('./parser/event-parser')
|
const parseBlock = require('./parser/block-parser')
|
const parseComponent = require('./parser/component-parser')
|
|
const parseWxsProps = require('./parser/wxs-props-parser')
|
const parseWxsEvents = require('./parser/wxs-events-parser')
|
|
const basePreTransformNode = require('./pre-transform-node')
|
|
function createGenVar (id, isScopedSlot) {
|
if (isScopedSlot) {
|
return function genVar (name, value) {
|
return `_svm.${GET_DATA}(${id},'${name}')`
|
}
|
}
|
return function genVar (name) {
|
return `${GET_DATA}(${id},'${name}')`
|
}
|
}
|
|
function parseKey (el, isScopedSlot) {
|
// add default key
|
processForKey(el)
|
|
if (el.key) { // renderList key
|
const forEl = getForEl(el)
|
if (forEl) {
|
if (!isVar(forEl.for)) {
|
return
|
}
|
if (forEl === el) { // <view v-for="item in items" :key="item.id"></view>
|
el.key = forEl.alias
|
} else { // <template v-for="item in items"><view :key="item.id+'1'"></view><view :key="item.id+'2'"></view></template>
|
const keyIndex = forEl.children.indexOf(el)
|
el.key = `${forEl.alias}['k${keyIndex}']`
|
}
|
} else {
|
isVar(el.key) && (el.key = createGenVar(el.attrsMap[ID], isScopedSlot)('a-key'))
|
}
|
}
|
}
|
|
function parseDirs (el, genVar, ignoreDirs, includeDirs = []) {
|
if (!el.directives) {
|
return
|
}
|
el.directives = el.directives.filter(dir => {
|
if (includeDirs.indexOf(dir.name) !== -1) {
|
if (ignoreDirs.indexOf(dir.name) === -1) {
|
dir.value && (dir.value = genVar('v-' + dir.name, dir.value))
|
dir.isDynamicArg && (dir.arg = genVar('v-' + dir.name + '-arg', dir.arg))
|
}
|
return true
|
}
|
})
|
}
|
|
const includeDirs = [
|
'text',
|
'html',
|
'bind',
|
'model',
|
'show',
|
'if',
|
'else',
|
'else-if',
|
'for',
|
'on',
|
'bind',
|
'slot',
|
'pre',
|
'cloak',
|
'once'
|
]
|
|
const ignoreDirs = ['model']
|
|
function transformNode (el, parent, state, isScopedSlot) {
|
if (el.type === 3) {
|
// fixed by xxxxxx 注意:保持平台一致性,trim 一下
|
el.text = el.text.trim()
|
return
|
}
|
parseBlock(el, parent)
|
parseComponent(el)
|
parseEvent(el)
|
// 更新 id
|
updateForEleId(el, state)
|
updateScopedSlotEleId(el, state)
|
|
if (el.type === 2) {
|
let pid = parent.attrsMap[ID]
|
if (isScopedSlot && String(pid).indexOf('_si') === -1) {
|
pid = getNewId(pid, '_si')
|
}
|
return parseText(el, parent, {
|
childIndex: state.childIndex || 0,
|
index: 0,
|
view: true,
|
// <uni-popup>{{content}}</uni-popup>
|
genVar: createGenVar(pid, isScopedSlot)
|
})
|
}
|
|
const genVar = createGenVar(el.attrsMap[ID], isScopedSlot)
|
|
parseIs(el, genVar)
|
parseRef(el, genVar)
|
parseSlotName(el, genVar)
|
if (parseFor(el, createGenVar, isScopedSlot)) {
|
if (el.alias[0] === '{') { // <div><li v-for=" { a, b } in items"></li></div>
|
el.alias = '$item'
|
}
|
}
|
parseKey(el, isScopedSlot)
|
|
parseIf(el, createGenVar, isScopedSlot)
|
parseBinding(el, genVar)
|
parseDirs(el, genVar, ignoreDirs, includeDirs)
|
parseWxsProps(el, {
|
isAppView: true
|
})
|
|
// if (el.attrs) { // TODO 过滤 dataset
|
// el.attrs = el.attrs.filter(attr => attr.name.indexOf('data-') !== 0)
|
// }
|
|
parseAttrs(el, genVar)
|
parseProps(el, genVar)
|
|
parseWxsEvents(el, {
|
filterModules: state.filterModules,
|
isAppView: true
|
})
|
}
|
|
function postTransformNode (el, options) {
|
if (!el.parent) { // 从根节点开始递归处理
|
if (options.root) { // 当根节点是由if,elseif,else组成
|
parseIf(options.root, createGenVar)
|
} else {
|
options.root = el
|
}
|
traverseNode(el, false, {
|
createGenVar,
|
forIteratorId: 0,
|
transformNode,
|
filterModules: options.filterModules
|
})
|
}
|
}
|
|
function handleViewEvents (events) {
|
Object.keys(events).forEach(name => {
|
const eventOpts = events[name]
|
// wxs
|
if (eventOpts.value && eventOpts.value.indexOf('$handleWxsEvent') !== -1) {
|
return
|
}
|
|
const modifiers = Object.create(null)
|
|
let type = name
|
const isPassive = type.charAt(0) === '&'
|
type = isPassive ? type.slice(1) : type
|
|
const isOnce = type.charAt(0) === '~'
|
type = isOnce ? type.slice(1) : type
|
|
const isCapture = type.charAt(0) === '!'
|
type = isCapture ? type.slice(1) : type
|
|
isPassive && (modifiers.passive = true)
|
isOnce && (modifiers.once = true)
|
isCapture && (modifiers.capture = true)
|
|
if (Array.isArray(eventOpts)) {
|
eventOpts.forEach(eventOpt => {
|
eventOpt.modifiers && Object.assign(modifiers, eventOpt.modifiers)
|
})
|
} else {
|
eventOpts.modifiers && Object.assign(modifiers, eventOpts.modifiers)
|
}
|
if (Object.keys(modifiers).length) {
|
events[name] = {
|
value: `$handleViewEvent($event,${JSON.stringify(modifiers)})`
|
}
|
} else {
|
events[name] = {
|
value: '$handleViewEvent($event)'
|
}
|
}
|
})
|
}
|
|
function genVModel (el, isScopedSlot) {
|
if (el.model) {
|
el.model.value = createGenVar(el.attrsMap[ID], isScopedSlot)('v-model', el.model.value)
|
if ((el.tag === 'v-uni-input' || el.tag === 'v-uni-textarea') && !(el.events && el.events.input)) {
|
el.model.callback = `function($$v){$handleVModelEvent(${el.attrsMap[ID]},$$v)}`
|
} else {
|
el.model.callback = 'function(){}'
|
}
|
}
|
}
|
|
function genData (el) {
|
delete el.$parentIterator3
|
|
genVModel(el)
|
|
// 放在 postTransformNode 中处理的时机太靠前,v-model 等指令会新增 event
|
el.events && handleViewEvents(el.events)
|
el.nativeEvents && handleViewEvents(el.nativeEvents)
|
return ''
|
}
|
|
module.exports = {
|
preTransformNode: function (el, options) {
|
parseTag(el)
|
return basePreTransformNode(el, options)
|
},
|
postTransformNode,
|
genData
|
}
|