@mpxjs/webpack-plugin 2.9.38 → 2.9.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,10 @@ const transDynamicClassExpr = require('./trans-dynamic-class-expr')
12
12
  const dash2hump = require('../utils/hump-dash').dash2hump
13
13
  const makeMap = require('../utils/make-map')
14
14
  const { isNonPhrasingTag } = require('../utils/dom-tag-config')
15
+ const setBaseWxml = require('../runtime-render/base-wxml')
16
+ const { parseExp } = require('./parse-exps')
15
17
 
18
+ const shallowStringify = require('../utils/shallow-stringify')
16
19
  const no = function () {
17
20
  return false
18
21
  }
@@ -34,7 +37,6 @@ const endTag = new RegExp(('^<\\/' + qnameCapture + '[^>]*>'))
34
37
  const doctype = /^<!DOCTYPE [^>]+>/i
35
38
  const comment = /^<!--/
36
39
  const conditionalComment = /^<!\[/
37
-
38
40
  let IS_REGEX_CAPTURING_BROKEN = false
39
41
  'x'.replace(/x(.)?/g, function (m, g) {
40
42
  IS_REGEX_CAPTURING_BROKEN = g === ''
@@ -62,7 +64,7 @@ function makeAttrsMap (attrs) {
62
64
  return map
63
65
  }
64
66
 
65
- function createASTElement (tag, attrs, parent) {
67
+ function createASTElement (tag, attrs = [], parent = null) {
66
68
  return {
67
69
  type: 1,
68
70
  tag: tag,
@@ -75,11 +77,11 @@ function createASTElement (tag, attrs, parent) {
75
77
 
76
78
  function isForbiddenTag (el) {
77
79
  return (
78
- el.tag === 'style' ||
79
- (el.tag === 'script' && (
80
- !el.attrsMap.type ||
81
- el.attrsMap.type === 'text/javascript'
82
- ))
80
+ el.tag === 'style' ||
81
+ (el.tag === 'script' && (
82
+ !el.attrsMap.type ||
83
+ el.attrsMap.type === 'text/javascript'
84
+ ))
83
85
  )
84
86
  }
85
87
 
@@ -88,25 +90,31 @@ function isForbiddenTag (el) {
88
90
  let warn$1
89
91
  let error$1
90
92
  let mode
93
+ let env
91
94
  let defs
92
95
  let i18n
93
96
  let srcMode
94
- let processingTemplate
97
+ let ctorType
98
+ let moduleId
95
99
  let isNative
100
+ let hasScoped
101
+ let hasVirtualHost
96
102
  let rulesRunner
97
103
  let currentEl
98
104
  let injectNodes = []
99
105
  let forScopes = []
100
106
  let forScopesMap = {}
101
- let hasI18n = false
102
- let i18nInjectableComputed = []
103
- let env
104
107
  let platformGetTagNamespace
105
108
  let filePath
106
109
  let refId
107
- let hasOptionalChain = false
110
+ let hasI18n = false
111
+ let i18nInjectableComputed = []
112
+ let hasOptionalChaining = false
113
+ let processingTemplate = false
114
+ const rulesResultMap = new Map()
108
115
 
109
116
  function updateForScopesMap () {
117
+ forScopesMap = {}
110
118
  forScopes.forEach((scope) => {
111
119
  forScopesMap[scope.index] = 'index'
112
120
  forScopesMap[scope.item] = 'item'
@@ -126,7 +134,6 @@ function popForScopes () {
126
134
  return scope
127
135
  }
128
136
 
129
- const rulesResultMap = new Map()
130
137
  const deleteErrorInResultMap = (node) => {
131
138
  rulesResultMap.delete(node)
132
139
  Array.isArray(node.children) && node.children.forEach(item => deleteErrorInResultMap(item))
@@ -278,8 +285,8 @@ function parseHTML (html, options) {
278
285
  endTagLength = endTag.length
279
286
  if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {
280
287
  text = text
281
- .replace(/<!--([\s\S]*?)-->/g, '$1')
282
- .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1')
288
+ .replace(/<!--([\s\S]*?)-->/g, '$1')
289
+ .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1')
283
290
  }
284
291
  if (shouldIgnoreFirstNewline(stackedTag, text)) {
285
292
  text = text.slice(1)
@@ -418,7 +425,7 @@ function parseHTML (html, options) {
418
425
  for (let i = stack.length - 1; i >= pos; i--) {
419
426
  if ((i > pos || !tagName) && options.warn) {
420
427
  options.warn(
421
- ('tag <' + (stack[i].tag) + '> has no matching end tag.')
428
+ ('tag <' + (stack[i].tag) + '> has no matching end tag.')
422
429
  )
423
430
  }
424
431
  if (options.end) {
@@ -595,10 +602,30 @@ function parseComponent (content, options) {
595
602
  }
596
603
 
597
604
  function parse (template, options) {
598
- rulesResultMap.clear()
605
+ // global var init
599
606
  warn$1 = options.warn || baseWarn
600
607
  error$1 = options.error || baseError
608
+ mode = options.mode || 'wx'
609
+ env = options.env
610
+ defs = options.defs || {}
611
+ srcMode = options.srcMode || mode
612
+ ctorType = options.ctorType
613
+ moduleId = options.moduleId
614
+ isNative = options.isNative
615
+ hasScoped = options.hasScoped
616
+ hasVirtualHost = options.hasVirtualHost
617
+ filePath = options.filePath
618
+ i18n = options.i18n
619
+ platformGetTagNamespace = options.getTagNamespace || no
620
+ refId = 0
621
+ injectNodes = []
622
+ forScopes = []
623
+ forScopesMap = {}
624
+ hasI18n = false
601
625
  i18nInjectableComputed = []
626
+ hasOptionalChaining = false
627
+ processingTemplate = false
628
+ rulesResultMap.clear()
602
629
 
603
630
  const _warn = content => {
604
631
  const currentElementRuleResult = rulesResultMap.get(currentEl) || rulesResultMap.set(currentEl, {
@@ -615,15 +642,6 @@ function parse (template, options) {
615
642
  currentElementRuleResult.errorArray.push(content)
616
643
  }
617
644
 
618
- mode = options.mode || 'wx'
619
- env = options.env
620
- defs = options.defs || {}
621
- srcMode = options.srcMode || mode
622
- isNative = options.isNative
623
- filePath = options.filePath
624
- i18n = options.i18n
625
- refId = 0
626
-
627
645
  rulesRunner = getRulesRunner({
628
646
  mode,
629
647
  srcMode,
@@ -636,14 +654,6 @@ function parse (template, options) {
636
654
  error: _error
637
655
  })
638
656
 
639
- injectNodes = []
640
- forScopes = []
641
- forScopesMap = {}
642
- hasI18n = false
643
- hasOptionalChain = false
644
-
645
- platformGetTagNamespace = options.getTagNamespace || no
646
-
647
657
  const stack = []
648
658
  let root
649
659
  const meta = {}
@@ -670,6 +680,7 @@ function parse (template, options) {
670
680
  const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag)
671
681
 
672
682
  const element = createASTElement(tag, attrs, currentParent)
683
+
673
684
  if (ns) {
674
685
  element.ns = ns
675
686
  }
@@ -677,9 +688,9 @@ function parse (template, options) {
677
688
  if (isForbiddenTag(element)) {
678
689
  element.forbidden = true
679
690
  warn$1(
680
- 'Templates should only be responsible for mapping the state to the ' +
681
- 'UI. Avoid placing tags with side-effects in your templates, such as ' +
682
- '<' + tag + '>' + ', as they will not be parsed.'
691
+ 'Templates should only be responsible for mapping the state to the ' +
692
+ 'UI. Avoid placing tags with side-effects in your templates, such as ' +
693
+ '<' + tag + '>' + ', as they will not be parsed.'
683
694
  )
684
695
  }
685
696
 
@@ -736,7 +747,7 @@ function parse (template, options) {
736
747
  parent: currentParent
737
748
  }
738
749
  children.push(el)
739
- processText(el)
750
+ options.runtimeCompile ? processTextDynamic(el) : processText(el)
740
751
  }
741
752
  }
742
753
  },
@@ -765,7 +776,7 @@ function parse (template, options) {
765
776
  }
766
777
  }
767
778
 
768
- if (hasOptionalChain) {
779
+ if (hasOptionalChaining) {
769
780
  injectWxs(meta, optionalChainWxsName, optionalChainWxsPath)
770
781
  }
771
782
 
@@ -785,7 +796,7 @@ function parse (template, options) {
785
796
  arr.push(item)
786
797
  }
787
798
  })
788
- arr.length && warn$1(`\n ${options.filePath} \n 组件 ${arr.join(' | ')} 注册了,但是未被对应的模板引用,建议删除!`)
799
+ arr.length && warn$1(`\n ${filePath} \n 组件 ${arr.join(' | ')} 注册了,但是未被对应的模板引用,建议删除!`)
789
800
  }
790
801
 
791
802
  return {
@@ -795,7 +806,7 @@ function parse (template, options) {
795
806
  }
796
807
 
797
808
  function getTempNode () {
798
- return createASTElement('temp-node', [])
809
+ return createASTElement('temp-node')
799
810
  }
800
811
 
801
812
  function addChild (parent, newChild, before) {
@@ -848,16 +859,25 @@ function modifyAttr (el, name, val) {
848
859
  }
849
860
  }
850
861
 
851
- function moveBaseDirective (target, from, isDelete = true) {
852
- target.for = from.for
853
- target.if = from.if
854
- target.elseif = from.elseif
855
- target.else = from.else
862
+ function postMoveBaseDirective (target, source, options, isDelete = true) {
863
+ target.for = source.for
864
+ target.if = source.if
865
+ target.elseif = source.elseif
866
+ target.else = source.else
867
+
868
+ if (options.runtimeCompile) {
869
+ postProcessForDynamic(target, config[mode])
870
+ postProcessIfDynamic(target, config[mode])
871
+ } else {
872
+ postProcessFor(target)
873
+ postProcessIf(target)
874
+ }
875
+
856
876
  if (isDelete) {
857
- delete from.for
858
- delete from.if
859
- delete from.elseif
860
- delete from.else
877
+ delete source.for
878
+ delete source.if
879
+ delete source.elseif
880
+ delete source.else
861
881
  }
862
882
  }
863
883
 
@@ -895,7 +915,7 @@ function stringify (str) {
895
915
 
896
916
  const genericRE = /^generic:(.+)$/
897
917
 
898
- function processComponentGenericsForWeb (el, options, meta) {
918
+ function processComponentGenericsWeb (el, options, meta) {
899
919
  if (options.componentGenerics && options.componentGenerics[el.tag]) {
900
920
  const generic = dash2hump(el.tag)
901
921
  el.tag = 'component'
@@ -907,7 +927,7 @@ function processComponentGenericsForWeb (el, options, meta) {
907
927
 
908
928
  let hasGeneric = false
909
929
 
910
- const genericHash = options.moduleId
930
+ const genericHash = moduleId
911
931
 
912
932
  el.attrsList.forEach((attr) => {
913
933
  if (genericRE.test(attr.name)) {
@@ -944,10 +964,10 @@ function processComponentIs (el, options) {
944
964
  return
945
965
  }
946
966
 
947
- options = options || {}
948
- el.components = options.usingComponents
949
- if (!el.components) {
950
- warn$1('Component in which <component> tag is used must have a nonblank usingComponents field')
967
+ const isInRange = makeMap(getAndRemoveAttr(el, 'range').val || '')
968
+ el.components = (options.usingComponents || []).filter(i => isInRange(i))
969
+ if (!el.components.length) {
970
+ warn$1('Component in which <component> tag is used must have a non blank usingComponents field')
951
971
  }
952
972
 
953
973
  const is = getAndRemoveAttr(el, 'is').val
@@ -960,7 +980,7 @@ function processComponentIs (el, options) {
960
980
 
961
981
  const eventIdentifier = '__mpx_event__'
962
982
 
963
- function parseFuncStr2 (str) {
983
+ function parseFuncStr (str, extraStr = '') {
964
984
  const funcRE = /^([^()]+)(\((.*)\))?/
965
985
  const match = funcRE.exec(str)
966
986
  if (match) {
@@ -978,7 +998,7 @@ function parseFuncStr2 (str) {
978
998
  }
979
999
  return {
980
1000
  hasArgs,
981
- expStr: `[${funcName + args}]`
1001
+ expStr: `[${funcName + args + extraStr}]`
982
1002
  }
983
1003
  }
984
1004
  }
@@ -1023,23 +1043,25 @@ function stringifyWithResolveComputed (modelValue) {
1023
1043
  return result.join('+')
1024
1044
  }
1025
1045
 
1026
- function processBindEvent (el, options) {
1046
+ function processEvent (el, options) {
1027
1047
  const eventConfigMap = {}
1028
- el.attrsList.forEach(function (attr) {
1029
- const parsedEvent = config[mode].event.parseEvent(attr.name)
1048
+ el.attrsList.forEach(function ({ name, value }) {
1049
+ const parsedEvent = config[mode].event.parseEvent(name)
1030
1050
 
1031
1051
  if (parsedEvent) {
1032
1052
  const type = parsedEvent.eventName
1033
1053
  const modifiers = (parsedEvent.modifier || '').split('.')
1034
- const parsedFunc = parseFuncStr2(attr.value)
1054
+ const prefix = parsedEvent.prefix
1055
+ // catch 场景下,下发的 eventconfig 里面包含特殊字符,用以运行时的判断
1056
+ const extraStr = options.runtimeCompile && prefix === 'catch' ? `, "__mpx_${prefix}"` : ''
1057
+ const parsedFunc = parseFuncStr(value, extraStr)
1035
1058
  if (parsedFunc) {
1036
1059
  if (!eventConfigMap[type]) {
1037
1060
  eventConfigMap[type] = {
1038
- rawName: attr.name,
1039
1061
  configs: []
1040
1062
  }
1041
1063
  }
1042
- eventConfigMap[type].configs.push(parsedFunc)
1064
+ eventConfigMap[type].configs.push(Object.assign({ name }, parsedFunc))
1043
1065
  if (modifiers.indexOf('proxy') > -1 || options.forceProxyEvent) {
1044
1066
  eventConfigMap[type].proxy = true
1045
1067
  }
@@ -1098,7 +1120,7 @@ function processBindEvent (el, options) {
1098
1120
 
1099
1121
  for (const type in eventConfigMap) {
1100
1122
  let needBind = false
1101
- let { configs, rawName, proxy } = eventConfigMap[type]
1123
+ const { configs, proxy } = eventConfigMap[type]
1102
1124
  delete eventConfigMap[type]
1103
1125
  if (proxy) {
1104
1126
  needBind = true
@@ -1116,19 +1138,25 @@ function processBindEvent (el, options) {
1116
1138
  }
1117
1139
 
1118
1140
  if (needBind) {
1119
- if (rawName) {
1120
- // 清空原始事件绑定
1121
- let has
1122
- do {
1123
- has = getAndRemoveAttr(el, rawName).has
1124
- } while (has)
1125
- // 清除修饰符
1126
- rawName = rawName.replace(/\..*/, '')
1127
- }
1141
+ let resultName
1142
+ configs.forEach(({ name }) => {
1143
+ if (name) {
1144
+ // 清空原始事件绑定
1145
+ let has
1146
+ do {
1147
+ has = getAndRemoveAttr(el, name).has
1148
+ } while (has)
1149
+
1150
+ if (!resultName) {
1151
+ // 清除修饰符
1152
+ resultName = name.replace(/\..*/, '')
1153
+ }
1154
+ }
1155
+ })
1128
1156
 
1129
1157
  addAttrs(el, [
1130
1158
  {
1131
- name: rawName || config[mode].event.getEvent(type),
1159
+ name: resultName || config[mode].event.getEvent(type),
1132
1160
  value: '__invoke'
1133
1161
  }
1134
1162
  ])
@@ -1141,7 +1169,7 @@ function processBindEvent (el, options) {
1141
1169
  if (!isEmptyObject(eventConfigMap)) {
1142
1170
  addAttrs(el, [{
1143
1171
  name: 'data-eventconfigs',
1144
- value: `{{${config[mode].event.shallowStringify(eventConfigMap)}}}`
1172
+ value: `{{${shallowStringify(eventConfigMap, true)}}}`
1145
1173
  }])
1146
1174
  }
1147
1175
  }
@@ -1150,6 +1178,164 @@ function wrapMustache (val) {
1150
1178
  return val && !tagRE.test(val) ? `{{${val}}}` : val
1151
1179
  }
1152
1180
 
1181
+ function parseOptionalChaining (str) {
1182
+ const wxsName = `${optionalChainWxsName}.g`
1183
+ let optionsRes
1184
+ while (optionsRes = /\?\./.exec(str)) {
1185
+ const strLength = str.length
1186
+ const grammarMap = {
1187
+ init () {
1188
+ const initKey = [
1189
+ {
1190
+ mapKey: '[]',
1191
+ mapValue: [
1192
+ {
1193
+ key: '[',
1194
+ value: 1
1195
+ },
1196
+ {
1197
+ key: ']',
1198
+ value: -1
1199
+ }
1200
+ ]
1201
+ },
1202
+ {
1203
+ mapKey: '()',
1204
+ mapValue: [
1205
+ {
1206
+ key: '(',
1207
+ value: 1
1208
+ },
1209
+ {
1210
+ key: ')',
1211
+ value: -1
1212
+ }
1213
+ ]
1214
+ }
1215
+ ]
1216
+ this.count = {}
1217
+ initKey.forEach(({ mapKey, mapValue }) => {
1218
+ mapValue.forEach(({ key, value }) => {
1219
+ this[key] = this.changeState(mapKey, value)
1220
+ })
1221
+ })
1222
+ },
1223
+ changeState (key, value) {
1224
+ if (!this.count[key]) {
1225
+ this.count[key] = 0
1226
+ }
1227
+ return () => {
1228
+ this.count[key] = this.count[key] + value
1229
+ return this.count[key]
1230
+ }
1231
+ },
1232
+ checkState () {
1233
+ return Object.values(this.count).find(i => i)
1234
+ }
1235
+ }
1236
+ let leftIndex = optionsRes.index
1237
+ let rightIndex = leftIndex + 2
1238
+ let haveNotGetValue = true
1239
+ let chainValue = ''
1240
+ let chainKey = ''
1241
+ let notCheck = false
1242
+ grammarMap.init()
1243
+ // 查 ?. 左边值
1244
+ while (haveNotGetValue && leftIndex > 0) {
1245
+ const left = str[leftIndex - 1]
1246
+ const grammar = grammarMap[left]
1247
+ if (notCheck) {
1248
+ // 处于表达式内
1249
+ chainValue = left + chainValue
1250
+ if (grammar) {
1251
+ grammar()
1252
+ if (!grammarMap.checkState()) {
1253
+ // 表达式结束
1254
+ notCheck = false
1255
+ }
1256
+ }
1257
+ } else if (~[']', ')'].indexOf(left)) {
1258
+ // 命中表达式,开始记录表达式
1259
+ chainValue = left + chainValue
1260
+ notCheck = true
1261
+ grammar()
1262
+ } else if (left !== ' ') {
1263
+ if (!/[A-Za-z0-9_$.]/.test(left)) {
1264
+ // 结束
1265
+ haveNotGetValue = false
1266
+ leftIndex++
1267
+ } else {
1268
+ // 正常语法
1269
+ chainValue = left + chainValue
1270
+ }
1271
+ }
1272
+ leftIndex--
1273
+ }
1274
+ if (grammarMap.checkState() && haveNotGetValue) {
1275
+ // 值查找结束但是语法未闭合或者处理到边界还未结束,抛异常
1276
+ throw new Error('[optionChain] option value illegal!!!')
1277
+ }
1278
+ haveNotGetValue = true
1279
+ let keyValue = ''
1280
+ // 查 ?. 右边key
1281
+ while (haveNotGetValue && rightIndex < strLength) {
1282
+ const right = str[rightIndex]
1283
+ const grammar = grammarMap[right]
1284
+ if (notCheck) {
1285
+ // 处于表达式内
1286
+ if (grammar) {
1287
+ grammar()
1288
+ if (grammarMap.checkState()) {
1289
+ keyValue += right
1290
+ } else {
1291
+ // 表达式结束
1292
+ notCheck = false
1293
+ chainKey += `,${keyValue}`
1294
+ keyValue = ''
1295
+ }
1296
+ } else {
1297
+ keyValue += right
1298
+ }
1299
+ } else if (~['[', '('].indexOf(right)) {
1300
+ // 命中表达式,开始记录表达式
1301
+ grammar()
1302
+ if (keyValue) {
1303
+ chainKey += `,'${keyValue}'`
1304
+ keyValue = ''
1305
+ }
1306
+ notCheck = true
1307
+ } else if (!/[A-Za-z0-9_$.?]/.test(right)) {
1308
+ // 结束
1309
+ haveNotGetValue = false
1310
+ rightIndex--
1311
+ } else if (right !== '?') {
1312
+ // 正常语法
1313
+ if (right === '.') {
1314
+ if (keyValue) {
1315
+ chainKey += `,'${keyValue}'`
1316
+ }
1317
+ keyValue = ''
1318
+ } else {
1319
+ keyValue += right
1320
+ }
1321
+ }
1322
+ rightIndex++
1323
+ }
1324
+ if (grammarMap.checkState() && haveNotGetValue) {
1325
+ // key值查找结束但是语法未闭合或者处理到边界还未结束,抛异常
1326
+ throw new Error('[optionChain] option key illegal!!!')
1327
+ }
1328
+ if (keyValue) {
1329
+ chainKey += `,'${keyValue}'`
1330
+ }
1331
+ str = str.slice(0, leftIndex) + `${wxsName}(${chainValue},[${chainKey.slice(1)}])` + str.slice(rightIndex)
1332
+ if (!hasOptionalChaining) {
1333
+ hasOptionalChaining = true
1334
+ }
1335
+ }
1336
+ return str
1337
+ }
1338
+
1153
1339
  function parseMustacheWithContext (raw = '') {
1154
1340
  return parseMustache(raw, (exp) => {
1155
1341
  if (defs) {
@@ -1163,8 +1349,9 @@ function parseMustacheWithContext (raw = '') {
1163
1349
  }
1164
1350
  })
1165
1351
  }
1352
+ // 处理可选链表达式
1353
+ exp = parseOptionalChaining(exp)
1166
1354
 
1167
- exp = parseOptionChain(exp)
1168
1355
  if (i18n) {
1169
1356
  for (const i18nFuncName of i18nFuncNames) {
1170
1357
  const funcNameRE = new RegExp(`(?<![A-Za-z0-9_$.])${i18nFuncName}\\(`)
@@ -1244,12 +1431,12 @@ function parseMustache (raw = '', expHandler = exp => exp, strHandler = str => s
1244
1431
  }
1245
1432
  }
1246
1433
 
1247
- function addExp (el, exp, isProps) {
1434
+ function addExp (el, exp, isProps, attrName) {
1248
1435
  if (exp) {
1249
1436
  if (!el.exps) {
1250
1437
  el.exps = []
1251
1438
  }
1252
- el.exps.push({ exp, isProps })
1439
+ el.exps.push({ exp, isProps, attrName })
1253
1440
  }
1254
1441
  }
1255
1442
 
@@ -1274,7 +1461,7 @@ function processIf (el) {
1274
1461
  }
1275
1462
  }
1276
1463
 
1277
- function processIfForWeb (el) {
1464
+ function processIfWeb (el) {
1278
1465
  let val = getAndRemoveAttr(el, config[mode].directive.if).val
1279
1466
  if (val) {
1280
1467
  el.if = {
@@ -1377,31 +1564,23 @@ function postProcessWxs (el, meta) {
1377
1564
  if (el.tag === config[mode].wxs.tag) {
1378
1565
  const module = el.attrsMap[config[mode].wxs.module]
1379
1566
  if (module) {
1380
- let src, content
1567
+ let src
1381
1568
  if (el.attrsMap[config[mode].wxs.src]) {
1382
1569
  src = el.attrsMap[config[mode].wxs.src]
1383
1570
  } else {
1384
- content = el.children.filter((child) => {
1571
+ const content = el.children.filter((child) => {
1385
1572
  return child.type === 3 && !child.isComment
1386
1573
  }).map(child => child.text).join('\n')
1574
+ addWxsContent(meta, module, content)
1387
1575
 
1388
1576
  const fakeRequest = filePath + config[mode].wxs.ext
1389
-
1390
1577
  src = addQuery(`~${fakeRequest}!=!${filePath}`, {
1391
1578
  wxsModule: module
1392
1579
  })
1393
-
1394
- addAttrs(el, [{
1395
- name: config[mode].wxs.src,
1396
- value: src
1397
- }])
1398
- el.children = []
1399
1580
  }
1400
- src && addWxsModule(meta, module, src)
1401
- content && addWxsContent(meta, module, content)
1402
1581
  // wxs hoist
1582
+ injectWxs(meta, module, src)
1403
1583
  removeNode(el, true)
1404
- injectNodes.push(el)
1405
1584
  }
1406
1585
  }
1407
1586
  }
@@ -1421,7 +1600,7 @@ function processAttrs (el, options) {
1421
1600
  if (isTemplateData) {
1422
1601
  result = result.replace(spreadREG, '$1')
1423
1602
  }
1424
- addExp(el, result, isProps)
1603
+ addExp(el, result, isProps, attr.name)
1425
1604
  if (parsed.replaced) {
1426
1605
  modifyAttr(el, attr.name, needWrap ? parsed.val.slice(1, -1) : parsed.val)
1427
1606
  }
@@ -1436,7 +1615,7 @@ function postProcessFor (el) {
1436
1615
  这个操作主要是因为百度小程序不支持这两个directive在同级使用
1437
1616
  */
1438
1617
  if (el.if && mode === 'swan') {
1439
- const block = createASTElement('block', [])
1618
+ const block = createASTElement('block')
1440
1619
  replaceNode(el, block, true)
1441
1620
  block.for = el.for
1442
1621
  delete el.for
@@ -1552,7 +1731,7 @@ function postProcessIf (el) {
1552
1731
  }
1553
1732
  }
1554
1733
 
1555
- function processText (el) {
1734
+ function processText (el, meta) {
1556
1735
  if (el.type !== 3 || el.isComment) {
1557
1736
  return
1558
1737
  }
@@ -1576,10 +1755,13 @@ function processText (el) {
1576
1755
  // }])
1577
1756
  // }
1578
1757
 
1579
- function injectWxs (meta, module, src) {
1758
+ function injectWxs (meta, module, src, options) {
1580
1759
  if (addWxsModule(meta, module, src)) {
1581
1760
  return
1582
1761
  }
1762
+ if (options && options.runtimeCompile) {
1763
+ return
1764
+ }
1583
1765
  const wxsNode = createASTElement(config[mode].wxs.tag, [
1584
1766
  {
1585
1767
  name: config[mode].wxs.module,
@@ -1683,13 +1865,13 @@ function processAliExternalClassesHack (el, options) {
1683
1865
  }
1684
1866
  })
1685
1867
 
1686
- if (options.hasScoped && isComponent) {
1868
+ if (hasScoped && isComponent) {
1687
1869
  options.externalClasses.forEach((className) => {
1688
1870
  const externalClass = getAndRemoveAttr(el, className).val
1689
1871
  if (externalClass) {
1690
1872
  addAttrs(el, [{
1691
1873
  name: className,
1692
- value: `${externalClass} ${options.moduleId}`
1874
+ value: `${externalClass} ${moduleId}`
1693
1875
  }])
1694
1876
  }
1695
1877
  })
@@ -1757,10 +1939,9 @@ function processWebExternalClassesHack (el, options) {
1757
1939
  }
1758
1940
  }
1759
1941
 
1760
- function processScoped (el, options) {
1761
- if (options.hasScoped && isRealNode(el)) {
1762
- const moduleId = options.moduleId
1763
- const rootModuleId = options.isComponent ? '' : MPX_APP_MODULE_ID // 处理app全局样式对页面的影响
1942
+ function processScoped (el) {
1943
+ if (hasScoped && isRealNode(el)) {
1944
+ const rootModuleId = ctorType === 'component' ? '' : MPX_APP_MODULE_ID // 处理app全局样式对页面的影响
1764
1945
  const staticClass = getAndRemoveAttr(el, 'class').val
1765
1946
  addAttrs(el, [{
1766
1947
  name: 'class',
@@ -1778,12 +1959,12 @@ function processBuiltInComponents (el, meta) {
1778
1959
  }
1779
1960
  const tag = el.tag
1780
1961
  if (!meta.builtInComponentsMap[tag]) {
1781
- meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/${mode}/${tag}.vue`
1962
+ meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/${mode}/${tag}`
1782
1963
  }
1783
1964
  }
1784
1965
  }
1785
1966
 
1786
- function processAliAddComponentRootView (el, options) {
1967
+ function postProcessAliComponentRootView (el, options, meta) {
1787
1968
  const processAttrsConditions = [
1788
1969
  { condition: /^(on|catch)Tap$/, action: 'clone' },
1789
1970
  { condition: /^(on|catch)TouchStart$/, action: 'clone' },
@@ -1797,25 +1978,25 @@ function processAliAddComponentRootView (el, options) {
1797
1978
  { condition: /^slot$/, action: 'move' }
1798
1979
  ]
1799
1980
  const processAppendAttrsRules = [
1800
- { name: 'class', value: `${MPX_ROOT_VIEW} host-${options.moduleId}` }
1981
+ { name: 'class', value: `${MPX_ROOT_VIEW} host-${moduleId}` }
1801
1982
  ]
1802
- const newElAttrs = []
1983
+ const newAttrs = []
1803
1984
  const allAttrs = cloneAttrsList(el.attrsList)
1804
1985
 
1805
1986
  function processClone (attr) {
1806
- newElAttrs.push(attr)
1987
+ newAttrs.push(attr)
1807
1988
  }
1808
1989
 
1809
1990
  function processMove (attr) {
1810
1991
  getAndRemoveAttr(el, attr.name)
1811
- newElAttrs.push(attr)
1992
+ newAttrs.push(attr)
1812
1993
  }
1813
1994
 
1814
1995
  function processAppendRules (el) {
1815
1996
  processAppendAttrsRules.forEach((rule) => {
1816
1997
  const getNeedAppendAttrValue = el.attrsMap[rule.name]
1817
1998
  const value = getNeedAppendAttrValue ? getNeedAppendAttrValue + ' ' + rule.value : rule.value
1818
- newElAttrs.push({
1999
+ newAttrs.push({
1819
2000
  name: rule.name,
1820
2001
  value
1821
2002
  })
@@ -1836,32 +2017,34 @@ function processAliAddComponentRootView (el, options) {
1836
2017
  })
1837
2018
 
1838
2019
  processAppendRules(el)
1839
- const componentWrapView = createASTElement('view', newElAttrs)
1840
- moveBaseDirective(componentWrapView, el)
1841
- if (el.is && el.components) {
1842
- el = postProcessComponentIs(el)
1843
- }
2020
+ const componentWrapView = createASTElement('view', newAttrs)
1844
2021
 
1845
2022
  replaceNode(el, componentWrapView, true)
1846
2023
  addChild(componentWrapView, el)
1847
- return componentWrapView
2024
+ processAttrs(componentWrapView, options)
2025
+ postMoveBaseDirective(componentWrapView, el, options)
2026
+
2027
+ if (options.runtimeCompile) {
2028
+ collectDynamicInfo(componentWrapView, options, meta)
2029
+ postProcessAttrsDynamic(componentWrapView, config[mode])
2030
+ }
1848
2031
  }
1849
2032
 
1850
2033
  // 有virtualHost情况wx组件注入virtualHost。无virtualHost阿里组件注入root-view。其他跳过。
1851
2034
  function getVirtualHostRoot (options, meta) {
1852
2035
  if (srcMode === 'wx') {
1853
- if (options.isComponent) {
1854
- if ((mode === 'wx') && options.hasVirtualHost) {
2036
+ if (ctorType === 'component') {
2037
+ if (mode === 'wx' && hasVirtualHost) {
1855
2038
  // wx组件注入virtualHost配置
1856
2039
  !meta.options && (meta.options = {})
1857
2040
  meta.options.virtualHost = true
1858
2041
  }
1859
- if ((mode === 'web') && !options.hasVirtualHost) {
2042
+ if (mode === 'web' && !hasVirtualHost) {
1860
2043
  // ali组件根节点实体化
1861
2044
  const rootView = createASTElement('view', [
1862
2045
  {
1863
2046
  name: 'class',
1864
- value: `${MPX_ROOT_VIEW} host-${options.moduleId}`
2047
+ value: `${MPX_ROOT_VIEW} host-${moduleId}`
1865
2048
  },
1866
2049
  {
1867
2050
  name: 'v-on',
@@ -1872,10 +2055,8 @@ function getVirtualHostRoot (options, meta) {
1872
2055
  return rootView
1873
2056
  }
1874
2057
  }
1875
- if (options.isPage) {
1876
- if (mode === 'web') {
1877
- return createASTElement('page', [])
1878
- }
2058
+ if (mode === 'web' && ctorType === 'page') {
2059
+ return createASTElement('page')
1879
2060
  }
1880
2061
  }
1881
2062
  return getTempNode()
@@ -1889,8 +2070,8 @@ function processShow (el, options, root) {
1889
2070
  if (has && show === undefined) {
1890
2071
  error$1(`Attrs ${config[mode].directive.show} should have a value `)
1891
2072
  }
1892
- if (options.hasVirtualHost) {
1893
- if (options.isComponent && el.parent === root && isRealNode(el)) {
2073
+ if (hasVirtualHost) {
2074
+ if (ctorType === 'component' && el.parent === root && isRealNode(el)) {
1894
2075
  if (show !== undefined) {
1895
2076
  show = `{{${parseMustacheWithContext(show).result}&&mpxShow}}`
1896
2077
  } else {
@@ -1906,22 +2087,30 @@ function processShow (el, options, root) {
1906
2087
  value: show
1907
2088
  }])
1908
2089
  } else {
1909
- processShowStyle()
2090
+ if (options.runtimeCompile) {
2091
+ processShowStyleDynamic(el, show)
2092
+ } else {
2093
+ processShowStyle(el, show)
2094
+ }
1910
2095
  }
1911
2096
  } else {
1912
- processShowStyle()
2097
+ if (options.runtimeCompile) {
2098
+ processShowStyleDynamic(el, show)
2099
+ } else {
2100
+ processShowStyle(el, show)
2101
+ }
1913
2102
  }
2103
+ }
1914
2104
 
1915
- function processShowStyle () {
1916
- if (show !== undefined) {
1917
- const showExp = parseMustacheWithContext(show).result
1918
- let oldStyle = getAndRemoveAttr(el, 'style').val
1919
- oldStyle = oldStyle ? oldStyle + ';' : ''
1920
- addAttrs(el, [{
1921
- name: 'style',
1922
- value: `${oldStyle}{{${showExp}?'':'display:none;'}}`
1923
- }])
1924
- }
2105
+ function processShowStyle (el, show) {
2106
+ if (show !== undefined) {
2107
+ const showExp = parseMustacheWithContext(show).result
2108
+ let oldStyle = getAndRemoveAttr(el, 'style').val
2109
+ oldStyle = oldStyle ? oldStyle + ';' : ''
2110
+ addAttrs(el, [{
2111
+ name: 'style',
2112
+ value: `${oldStyle}{{${showExp}?'':'display:none;'}}`
2113
+ }])
1925
2114
  }
1926
2115
  }
1927
2116
 
@@ -2044,11 +2233,11 @@ function processDuplicateAttrsList (el) {
2044
2233
  }
2045
2234
 
2046
2235
  // 处理wxs注入逻辑
2047
- function processInjectWxs (el, meta) {
2236
+ function processInjectWxs (el, meta, options) {
2048
2237
  if (el.injectWxsProps && el.injectWxsProps.length) {
2049
2238
  el.injectWxsProps.forEach((injectWxsProp) => {
2050
2239
  const { injectWxsPath, injectWxsModuleName } = injectWxsProp
2051
- injectWxs(meta, injectWxsModuleName, injectWxsPath)
2240
+ injectWxs(meta, injectWxsModuleName, injectWxsPath, options)
2052
2241
  })
2053
2242
  }
2054
2243
  }
@@ -2086,7 +2275,7 @@ function processElement (el, root, options, meta) {
2086
2275
 
2087
2276
  processMpxTagName(el)
2088
2277
 
2089
- processInjectWxs(el, meta)
2278
+ processInjectWxs(el, meta, options)
2090
2279
 
2091
2280
  const transAli = mode === 'ali' && srcMode === 'wx'
2092
2281
 
@@ -2094,9 +2283,9 @@ function processElement (el, root, options, meta) {
2094
2283
  // 收集内建组件
2095
2284
  processBuiltInComponents(el, meta)
2096
2285
  // 预处理代码维度条件编译
2097
- processIfForWeb(el)
2286
+ processIfWeb(el)
2098
2287
  processWebExternalClassesHack(el, options)
2099
- processComponentGenericsForWeb(el, options, meta)
2288
+ processComponentGenericsWeb(el, options, meta)
2100
2289
  return
2101
2290
  }
2102
2291
 
@@ -2104,7 +2293,7 @@ function processElement (el, root, options, meta) {
2104
2293
 
2105
2294
  // 仅ali平台需要scoped模拟样式隔离
2106
2295
  if (mode === 'ali') {
2107
- processScoped(el, options)
2296
+ processScoped(el)
2108
2297
  }
2109
2298
 
2110
2299
  if (transAli) {
@@ -2114,9 +2303,14 @@ function processElement (el, root, options, meta) {
2114
2303
  processIf(el)
2115
2304
  processFor(el)
2116
2305
  processRef(el, options, meta)
2117
- processClass(el, meta)
2118
- processStyle(el, meta)
2119
- processBindEvent(el, options)
2306
+ if (options.runtimeCompile) {
2307
+ processClassDynamic(el, meta)
2308
+ processStyleDynamic(el, meta)
2309
+ } else {
2310
+ processClass(el, meta)
2311
+ processStyle(el, meta)
2312
+ }
2313
+ processEvent(el, options)
2120
2314
 
2121
2315
  if (!pass) {
2122
2316
  processShow(el, options, root)
@@ -2128,6 +2322,8 @@ function processElement (el, root, options, meta) {
2128
2322
 
2129
2323
  function closeElement (el, meta, options) {
2130
2324
  postProcessAtMode(el)
2325
+ collectDynamicInfo(el, options, meta)
2326
+
2131
2327
  if (mode === 'web') {
2132
2328
  postProcessWxs(el, meta)
2133
2329
  // 处理代码维度条件编译移除死分支
@@ -2136,16 +2332,26 @@ function closeElement (el, meta, options) {
2136
2332
  }
2137
2333
  const pass = isNative || postProcessTemplate(el) || processingTemplate
2138
2334
  postProcessWxs(el, meta)
2139
-
2140
2335
  if (!pass) {
2141
- if (isComponentNode(el, options) && !options.hasVirtualHost && mode === 'ali') {
2142
- el = processAliAddComponentRootView(el, options)
2143
- } else {
2144
- el = postProcessComponentIs(el)
2336
+ if (isComponentNode(el, options) && !hasVirtualHost && mode === 'ali') {
2337
+ postProcessAliComponentRootView(el, options, meta)
2145
2338
  }
2339
+ postProcessComponentIs(el, options)
2146
2340
  }
2147
- postProcessFor(el)
2148
- postProcessIf(el)
2341
+
2342
+ if (options.runtimeCompile) {
2343
+ postProcessForDynamic(el, config[mode])
2344
+ postProcessIfDynamic(el, config[mode])
2345
+ postProcessAttrsDynamic(el, config[mode])
2346
+ } else {
2347
+ postProcessFor(el)
2348
+ postProcessIf(el)
2349
+ }
2350
+ }
2351
+
2352
+ // 运行时组件的模版节点收集,最终注入到 mpx-custom-element-*.wxml 中
2353
+ function collectDynamicInfo (el, options, meta) {
2354
+ setBaseWxml(el, { mode, isComponentNode, options }, meta)
2149
2355
  }
2150
2356
 
2151
2357
  function postProcessAtMode (el) {
@@ -2176,21 +2382,18 @@ function cloneAttrsList (attrsList) {
2176
2382
  })
2177
2383
  }
2178
2384
 
2179
- function postProcessComponentIs (el) {
2385
+ function postProcessComponentIs (el, options) {
2180
2386
  if (el.is && el.components) {
2181
2387
  let tempNode
2182
2388
  if (el.for || el.if || el.elseif || el.else) {
2183
- tempNode = createASTElement('block', [])
2184
- moveBaseDirective(tempNode, el)
2389
+ tempNode = createASTElement('block')
2185
2390
  } else {
2186
2391
  tempNode = getTempNode()
2187
2392
  }
2188
- let range = []
2189
- if (el.attrsMap.range) {
2190
- range = getAndRemoveAttr(el, 'range').val.split(',').map(item => item.trim())
2191
- }
2393
+ replaceNode(el, tempNode, true)
2394
+ postMoveBaseDirective(tempNode, el, options)
2395
+
2192
2396
  el.components.forEach(function (component) {
2193
- if (range.length > 0 && !range.includes(component)) return
2194
2397
  const newChild = createASTElement(component, cloneAttrsList(el.attrsList), tempNode)
2195
2398
  newChild.if = {
2196
2399
  raw: `{{${el.is} === ${stringify(component)}}}`,
@@ -2207,10 +2410,9 @@ function postProcessComponentIs (el) {
2207
2410
  if (!el.parent) {
2208
2411
  error$1('Dynamic component can not be the template root, considering wrapping it with <view> or <text> tag!')
2209
2412
  } else {
2210
- el = replaceNode(el, tempNode, true) || el
2413
+ replaceNode(el, tempNode, true)
2211
2414
  }
2212
2415
  }
2213
- return el
2214
2416
  }
2215
2417
 
2216
2418
  function stringifyAttr (val) {
@@ -2290,8 +2492,8 @@ function findPrevNode (node) {
2290
2492
  }
2291
2493
  }
2292
2494
 
2293
- function replaceNode (node, newNode, reserveNode) {
2294
- if (!reserveNode) deleteErrorInResultMap(node)
2495
+ function replaceNode (node, newNode, reserveError) {
2496
+ if (!reserveError) deleteErrorInResultMap(node)
2295
2497
  const parent = node.parent
2296
2498
  if (parent) {
2297
2499
  const index = parent.children.indexOf(node)
@@ -2303,8 +2505,8 @@ function replaceNode (node, newNode, reserveNode) {
2303
2505
  }
2304
2506
  }
2305
2507
 
2306
- function removeNode (node, reserveNode) {
2307
- if (!reserveNode) deleteErrorInResultMap(node)
2508
+ function removeNode (node, reserveError) {
2509
+ if (!reserveError) deleteErrorInResultMap(node)
2308
2510
  const parent = node.parent
2309
2511
  if (parent) {
2310
2512
  const index = parent.children.indexOf(node)
@@ -2399,167 +2601,148 @@ function genNode (node) {
2399
2601
  return exp
2400
2602
  }
2401
2603
 
2402
- /**
2403
- * 处理可选链用法
2404
- * @param str
2405
- * @returns
2406
- */
2407
- function parseOptionChain (str) {
2408
- const wxsName = `${optionalChainWxsName}.g`
2409
- let optionsRes
2410
- while (optionsRes = /\?\./.exec(str)) {
2411
- const strLength = str.length
2412
- const grammarMap = {
2413
- init () {
2414
- const initKey = [
2415
- {
2416
- mapKey: '[]',
2417
- mapValue: [
2418
- {
2419
- key: '[',
2420
- value: 1
2421
- },
2422
- {
2423
- key: ']',
2424
- value: -1
2425
- }
2426
- ]
2427
- },
2428
- {
2429
- mapKey: '()',
2430
- mapValue: [
2431
- {
2432
- key: '(',
2433
- value: 1
2434
- },
2435
- {
2436
- key: ')',
2437
- value: -1
2438
- }
2439
- ]
2440
- }
2441
- ]
2442
- this.count = {}
2443
- initKey.forEach(({ mapKey, mapValue }) => {
2444
- mapValue.forEach(({ key, value }) => {
2445
- this[key] = this.changeState(mapKey, value)
2446
- })
2447
- })
2448
- },
2449
- changeState (key, value) {
2450
- if (!this.count[key]) {
2451
- this.count[key] = 0
2452
- }
2453
- return () => {
2454
- this.count[key] = this.count[key] + value
2455
- return this.count[key]
2456
- }
2457
- },
2458
- checkState () {
2459
- return Object.values(this.count).find(i => i)
2460
- }
2461
- }
2462
- let leftIndex = optionsRes.index
2463
- let rightIndex = leftIndex + 2
2464
- let haveNotGetValue = true
2465
- let chainValue = ''
2466
- let chainKey = ''
2467
- let notCheck = false
2468
- grammarMap.init()
2469
- // ?. 左边值
2470
- while (haveNotGetValue && leftIndex > 0) {
2471
- const left = str[leftIndex - 1]
2472
- const grammar = grammarMap[left]
2473
- if (notCheck) {
2474
- // 处于表达式内
2475
- chainValue = left + chainValue
2476
- if (grammar) {
2477
- grammar()
2478
- if (!grammarMap.checkState()) {
2479
- // 表达式结束
2480
- notCheck = false
2481
- }
2482
- }
2483
- } else if (~[']', ')'].indexOf(left)) {
2484
- // 命中表达式,开始记录表达式
2485
- chainValue = left + chainValue
2486
- notCheck = true
2487
- grammar()
2488
- } else if (left !== ' ') {
2489
- if (!/[A-Za-z0-9_$.]/.test(left)) {
2490
- // 结束
2491
- haveNotGetValue = false
2492
- leftIndex++
2493
- } else {
2494
- // 正常语法
2495
- chainValue = left + chainValue
2604
+ function addIfConditionDynamic (el, condition) {
2605
+ if (!el.ifConditions) {
2606
+ el.ifConditions = []
2607
+ }
2608
+ el.ifConditions.push(condition)
2609
+ }
2610
+
2611
+ function processIfConditionsDynamic (el) {
2612
+ const prevNode = findPrevNode(el)
2613
+ if (prevNode && prevNode.if) {
2614
+ addIfConditionDynamic(prevNode, {
2615
+ ifExp: !!el.elseif,
2616
+ block: el,
2617
+ __exp: el.elseif ? parseExp(el.elseif.exp) : ''
2618
+ })
2619
+ removeNode(el)
2620
+ }
2621
+ }
2622
+
2623
+ function processClassDynamic (el, meta) {
2624
+ const type = 'class'
2625
+ const targetType = type
2626
+ const dynamicClass = getAndRemoveAttr(el, config[mode].directive.dynamicClass).val
2627
+ let staticClass = getAndRemoveAttr(el, type).val || ''
2628
+ staticClass = staticClass.replace(/\s+/g, ' ')
2629
+ if (dynamicClass) {
2630
+ const staticClassExp = parseMustacheWithContext(staticClass).result
2631
+ const dynamicClassExp = transDynamicClassExpr(parseMustacheWithContext(dynamicClass).result, {
2632
+ error: error$1
2633
+ })
2634
+ addAttrs(el, [{
2635
+ name: targetType,
2636
+ value: `{{[${staticClassExp},${dynamicClassExp}]}}`
2637
+ }])
2638
+ } else if (staticClass) {
2639
+ addAttrs(el, [{
2640
+ name: targetType,
2641
+ value: staticClass
2642
+ }])
2643
+ }
2644
+ }
2645
+
2646
+ function processStyleDynamic (el, meta) {
2647
+ const type = 'style'
2648
+ const targetType = type
2649
+ const dynamicStyle = getAndRemoveAttr(el, config[mode].directive.dynamicStyle).val
2650
+ let staticStyle = getAndRemoveAttr(el, type).val || ''
2651
+ staticStyle = staticStyle.replace(/\s+/g, ' ')
2652
+ if (dynamicStyle) {
2653
+ const staticStyleExp = parseMustacheWithContext(staticStyle).result
2654
+ const dynamicStyleExp = parseMustacheWithContext(dynamicStyle).result
2655
+ addAttrs(el, [{
2656
+ name: targetType,
2657
+ value: `{{[${staticStyleExp},${dynamicStyleExp}]}}`
2658
+ }])
2659
+ } else if (staticStyle) {
2660
+ addAttrs(el, [{
2661
+ name: targetType,
2662
+ value: staticStyle
2663
+ }])
2664
+ }
2665
+ }
2666
+
2667
+ function processTextDynamic (vnode) {
2668
+ if (vnode.type !== 3 || vnode.isComment) {
2669
+ return
2670
+ }
2671
+ const parsed = parseMustacheWithContext(vnode.text)
2672
+ if (parsed.hasBinding) {
2673
+ vnode.__exp = parseExp(parsed.result)
2674
+ delete vnode.text
2675
+ }
2676
+ }
2677
+
2678
+ function postProcessIfDynamic (vnode, config) {
2679
+ if (vnode.if) {
2680
+ const parsedExp = vnode.if.exp
2681
+ addIfConditionDynamic(vnode, {
2682
+ ifExp: true,
2683
+ block: 'self',
2684
+ __exp: parseExp(parsedExp)
2685
+ })
2686
+ getAndRemoveAttr(vnode, config.directive.if)
2687
+ vnode.if = true
2688
+ } else if (vnode.elseif || vnode.else) {
2689
+ const directive = vnode.elseif
2690
+ ? config.directive.elseif
2691
+ : config.directive.else
2692
+ getAndRemoveAttr(vnode, directive)
2693
+ processIfConditionsDynamic(vnode)
2694
+ delete vnode.elseif
2695
+ delete vnode.else
2696
+ }
2697
+ }
2698
+
2699
+ function postProcessForDynamic (vnode) {
2700
+ if (vnode.for) {
2701
+ vnode.for.__exp = parseExp(vnode.for.exp)
2702
+ delete vnode.for.raw
2703
+ delete vnode.for.exp
2704
+ popForScopes()
2705
+ }
2706
+ }
2707
+
2708
+ function postProcessAttrsDynamic (vnode, config) {
2709
+ const exps = vnode.exps?.filter(v => v.attrName) || []
2710
+ const expsMap = Object.fromEntries(exps.map(v => ([v.attrName, v])))
2711
+ const directives = Object.values(config.directive)
2712
+ if (vnode.attrsList && vnode.attrsList.length) {
2713
+ // 后序遍历,主要为了做剔除的操作
2714
+ for (let i = vnode.attrsList.length - 1; i >= 0; i--) {
2715
+ const attr = vnode.attrsList[i]
2716
+ if (config.event.parseEvent(attr.name) || directives.includes(attr.name)) {
2717
+ // 原本的事件代理直接剔除,主要是基础模版的事件直接走代理形式,事件绑定名直接写死的,优化 astJson 体积
2718
+ getAndRemoveAttr(vnode, attr.name)
2719
+ } else if (attr.value == null) {
2720
+ attr.__exp = parseExp('true')
2721
+ } else {
2722
+ const expInfo = expsMap[attr.name]
2723
+ if (expInfo && expInfo.exp) {
2724
+ attr.__exp = parseExp(expInfo.exp)
2496
2725
  }
2497
2726
  }
2498
- leftIndex--
2499
- }
2500
- if (grammarMap.checkState() && haveNotGetValue) {
2501
- // 值查找结束但是语法未闭合或者处理到边界还未结束,抛异常
2502
- throw new Error('[optionChain] option value illegal!!!')
2503
- }
2504
- haveNotGetValue = true
2505
- let keyValue = ''
2506
- // 查 ?. 右边key
2507
- while (haveNotGetValue && rightIndex < strLength) {
2508
- const right = str[rightIndex]
2509
- const grammar = grammarMap[right]
2510
- if (notCheck) {
2511
- // 处于表达式内
2512
- if (grammar) {
2513
- grammar()
2514
- if (grammarMap.checkState()) {
2515
- keyValue += right
2516
- } else {
2517
- // 表达式结束
2518
- notCheck = false
2519
- chainKey += `,${keyValue}`
2520
- keyValue = ''
2521
- }
2522
- } else {
2523
- keyValue += right
2524
- }
2525
- } else if (~['[', '('].indexOf(right)) {
2526
- // 命中表达式,开始记录表达式
2527
- grammar()
2528
- if (keyValue) {
2529
- chainKey += `,'${keyValue}'`
2530
- keyValue = ''
2531
- }
2532
- notCheck = true
2533
- } else if (!/[A-Za-z0-9_$.?]/.test(right)) {
2534
- // 结束
2535
- haveNotGetValue = false
2536
- rightIndex--
2537
- } else if (right !== '?') {
2538
- // 正常语法
2539
- if (right === '.') {
2540
- if (keyValue) {
2541
- chainKey += `,'${keyValue}'`
2542
- }
2543
- keyValue = ''
2544
- } else {
2545
- keyValue += right
2546
- }
2727
+ if (attr.__exp) {
2728
+ delete attr.value
2547
2729
  }
2548
- rightIndex++
2549
- }
2550
- if (grammarMap.checkState() && haveNotGetValue) {
2551
- // key值查找结束但是语法未闭合或者处理到边界还未结束,抛异常
2552
- throw new Error('[optionChain] option key illegal!!!')
2553
- }
2554
- if (keyValue) {
2555
- chainKey += `,'${keyValue}'`
2556
- }
2557
- str = str.slice(0, leftIndex) + `${wxsName}(${chainValue},[${chainKey.slice(1)}])` + str.slice(rightIndex)
2558
- if (!hasOptionalChain) {
2559
- hasOptionalChain = true
2560
2730
  }
2561
2731
  }
2562
- return str
2732
+ }
2733
+
2734
+ function processShowStyleDynamic (el, show) {
2735
+ if (show !== undefined) {
2736
+ const showExp = parseMustacheWithContext(show).result
2737
+ const oldStyle = getAndRemoveAttr(el, 'style').val
2738
+ const displayExp = `${showExp}? '' : "display:none;"`
2739
+ const isArray = oldStyle?.endsWith(']}}')
2740
+ const value = isArray ? oldStyle?.replace(']}}', `,${displayExp}]}}`) : `${oldStyle ? `${oldStyle};` : ''}{{${displayExp}}}`
2741
+ addAttrs(el, [{
2742
+ name: 'style',
2743
+ value: value
2744
+ }])
2745
+ }
2563
2746
  }
2564
2747
 
2565
2748
  module.exports = {
@@ -2572,5 +2755,10 @@ module.exports = {
2572
2755
  parseMustache,
2573
2756
  parseMustacheWithContext,
2574
2757
  stringifyWithResolveComputed,
2575
- addAttrs
2758
+ addAttrs,
2759
+ getAndRemoveAttr,
2760
+ findPrevNode,
2761
+ removeNode,
2762
+ replaceNode,
2763
+ createASTElement
2576
2764
  }