@mpxjs/webpack-plugin 2.9.38 → 2.9.40

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,14 @@ 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 range = getAndRemoveAttr(el, 'range').val
968
+ const isInRange = makeMap(range || '')
969
+ el.components = (options.usingComponents || []).filter(i => {
970
+ if (!range) return true
971
+ return isInRange(i)
972
+ })
973
+ if (!el.components.length) {
974
+ warn$1('Component in which <component> tag is used must have a non blank usingComponents field')
951
975
  }
952
976
 
953
977
  const is = getAndRemoveAttr(el, 'is').val
@@ -960,7 +984,7 @@ function processComponentIs (el, options) {
960
984
 
961
985
  const eventIdentifier = '__mpx_event__'
962
986
 
963
- function parseFuncStr2 (str) {
987
+ function parseFuncStr (str, extraStr = '') {
964
988
  const funcRE = /^([^()]+)(\((.*)\))?/
965
989
  const match = funcRE.exec(str)
966
990
  if (match) {
@@ -978,7 +1002,7 @@ function parseFuncStr2 (str) {
978
1002
  }
979
1003
  return {
980
1004
  hasArgs,
981
- expStr: `[${funcName + args}]`
1005
+ expStr: `[${funcName + args + extraStr}]`
982
1006
  }
983
1007
  }
984
1008
  }
@@ -1023,23 +1047,25 @@ function stringifyWithResolveComputed (modelValue) {
1023
1047
  return result.join('+')
1024
1048
  }
1025
1049
 
1026
- function processBindEvent (el, options) {
1050
+ function processEvent (el, options) {
1027
1051
  const eventConfigMap = {}
1028
- el.attrsList.forEach(function (attr) {
1029
- const parsedEvent = config[mode].event.parseEvent(attr.name)
1052
+ el.attrsList.forEach(function ({ name, value }) {
1053
+ const parsedEvent = config[mode].event.parseEvent(name)
1030
1054
 
1031
1055
  if (parsedEvent) {
1032
1056
  const type = parsedEvent.eventName
1033
1057
  const modifiers = (parsedEvent.modifier || '').split('.')
1034
- const parsedFunc = parseFuncStr2(attr.value)
1058
+ const prefix = parsedEvent.prefix
1059
+ // catch 场景下,下发的 eventconfig 里面包含特殊字符,用以运行时的判断
1060
+ const extraStr = options.runtimeCompile && prefix === 'catch' ? `, "__mpx_${prefix}"` : ''
1061
+ const parsedFunc = parseFuncStr(value, extraStr)
1035
1062
  if (parsedFunc) {
1036
1063
  if (!eventConfigMap[type]) {
1037
1064
  eventConfigMap[type] = {
1038
- rawName: attr.name,
1039
1065
  configs: []
1040
1066
  }
1041
1067
  }
1042
- eventConfigMap[type].configs.push(parsedFunc)
1068
+ eventConfigMap[type].configs.push(Object.assign({ name }, parsedFunc))
1043
1069
  if (modifiers.indexOf('proxy') > -1 || options.forceProxyEvent) {
1044
1070
  eventConfigMap[type].proxy = true
1045
1071
  }
@@ -1098,7 +1124,7 @@ function processBindEvent (el, options) {
1098
1124
 
1099
1125
  for (const type in eventConfigMap) {
1100
1126
  let needBind = false
1101
- let { configs, rawName, proxy } = eventConfigMap[type]
1127
+ const { configs, proxy } = eventConfigMap[type]
1102
1128
  delete eventConfigMap[type]
1103
1129
  if (proxy) {
1104
1130
  needBind = true
@@ -1116,19 +1142,25 @@ function processBindEvent (el, options) {
1116
1142
  }
1117
1143
 
1118
1144
  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
- }
1145
+ let resultName
1146
+ configs.forEach(({ name }) => {
1147
+ if (name) {
1148
+ // 清空原始事件绑定
1149
+ let has
1150
+ do {
1151
+ has = getAndRemoveAttr(el, name).has
1152
+ } while (has)
1153
+
1154
+ if (!resultName) {
1155
+ // 清除修饰符
1156
+ resultName = name.replace(/\..*/, '')
1157
+ }
1158
+ }
1159
+ })
1128
1160
 
1129
1161
  addAttrs(el, [
1130
1162
  {
1131
- name: rawName || config[mode].event.getEvent(type),
1163
+ name: resultName || config[mode].event.getEvent(type),
1132
1164
  value: '__invoke'
1133
1165
  }
1134
1166
  ])
@@ -1141,7 +1173,7 @@ function processBindEvent (el, options) {
1141
1173
  if (!isEmptyObject(eventConfigMap)) {
1142
1174
  addAttrs(el, [{
1143
1175
  name: 'data-eventconfigs',
1144
- value: `{{${config[mode].event.shallowStringify(eventConfigMap)}}}`
1176
+ value: `{{${shallowStringify(eventConfigMap, true)}}}`
1145
1177
  }])
1146
1178
  }
1147
1179
  }
@@ -1150,6 +1182,164 @@ function wrapMustache (val) {
1150
1182
  return val && !tagRE.test(val) ? `{{${val}}}` : val
1151
1183
  }
1152
1184
 
1185
+ function parseOptionalChaining (str) {
1186
+ const wxsName = `${optionalChainWxsName}.g`
1187
+ let optionsRes
1188
+ while (optionsRes = /\?\./.exec(str)) {
1189
+ const strLength = str.length
1190
+ const grammarMap = {
1191
+ init () {
1192
+ const initKey = [
1193
+ {
1194
+ mapKey: '[]',
1195
+ mapValue: [
1196
+ {
1197
+ key: '[',
1198
+ value: 1
1199
+ },
1200
+ {
1201
+ key: ']',
1202
+ value: -1
1203
+ }
1204
+ ]
1205
+ },
1206
+ {
1207
+ mapKey: '()',
1208
+ mapValue: [
1209
+ {
1210
+ key: '(',
1211
+ value: 1
1212
+ },
1213
+ {
1214
+ key: ')',
1215
+ value: -1
1216
+ }
1217
+ ]
1218
+ }
1219
+ ]
1220
+ this.count = {}
1221
+ initKey.forEach(({ mapKey, mapValue }) => {
1222
+ mapValue.forEach(({ key, value }) => {
1223
+ this[key] = this.changeState(mapKey, value)
1224
+ })
1225
+ })
1226
+ },
1227
+ changeState (key, value) {
1228
+ if (!this.count[key]) {
1229
+ this.count[key] = 0
1230
+ }
1231
+ return () => {
1232
+ this.count[key] = this.count[key] + value
1233
+ return this.count[key]
1234
+ }
1235
+ },
1236
+ checkState () {
1237
+ return Object.values(this.count).find(i => i)
1238
+ }
1239
+ }
1240
+ let leftIndex = optionsRes.index
1241
+ let rightIndex = leftIndex + 2
1242
+ let haveNotGetValue = true
1243
+ let chainValue = ''
1244
+ let chainKey = ''
1245
+ let notCheck = false
1246
+ grammarMap.init()
1247
+ // 查 ?. 左边值
1248
+ while (haveNotGetValue && leftIndex > 0) {
1249
+ const left = str[leftIndex - 1]
1250
+ const grammar = grammarMap[left]
1251
+ if (notCheck) {
1252
+ // 处于表达式内
1253
+ chainValue = left + chainValue
1254
+ if (grammar) {
1255
+ grammar()
1256
+ if (!grammarMap.checkState()) {
1257
+ // 表达式结束
1258
+ notCheck = false
1259
+ }
1260
+ }
1261
+ } else if (~[']', ')'].indexOf(left)) {
1262
+ // 命中表达式,开始记录表达式
1263
+ chainValue = left + chainValue
1264
+ notCheck = true
1265
+ grammar()
1266
+ } else if (left !== ' ') {
1267
+ if (!/[A-Za-z0-9_$.]/.test(left)) {
1268
+ // 结束
1269
+ haveNotGetValue = false
1270
+ leftIndex++
1271
+ } else {
1272
+ // 正常语法
1273
+ chainValue = left + chainValue
1274
+ }
1275
+ }
1276
+ leftIndex--
1277
+ }
1278
+ if (grammarMap.checkState() && haveNotGetValue) {
1279
+ // 值查找结束但是语法未闭合或者处理到边界还未结束,抛异常
1280
+ throw new Error('[optionChain] option value illegal!!!')
1281
+ }
1282
+ haveNotGetValue = true
1283
+ let keyValue = ''
1284
+ // 查 ?. 右边key
1285
+ while (haveNotGetValue && rightIndex < strLength) {
1286
+ const right = str[rightIndex]
1287
+ const grammar = grammarMap[right]
1288
+ if (notCheck) {
1289
+ // 处于表达式内
1290
+ if (grammar) {
1291
+ grammar()
1292
+ if (grammarMap.checkState()) {
1293
+ keyValue += right
1294
+ } else {
1295
+ // 表达式结束
1296
+ notCheck = false
1297
+ chainKey += `,${keyValue}`
1298
+ keyValue = ''
1299
+ }
1300
+ } else {
1301
+ keyValue += right
1302
+ }
1303
+ } else if (~['[', '('].indexOf(right)) {
1304
+ // 命中表达式,开始记录表达式
1305
+ grammar()
1306
+ if (keyValue) {
1307
+ chainKey += `,'${keyValue}'`
1308
+ keyValue = ''
1309
+ }
1310
+ notCheck = true
1311
+ } else if (!/[A-Za-z0-9_$.?]/.test(right)) {
1312
+ // 结束
1313
+ haveNotGetValue = false
1314
+ rightIndex--
1315
+ } else if (right !== '?') {
1316
+ // 正常语法
1317
+ if (right === '.') {
1318
+ if (keyValue) {
1319
+ chainKey += `,'${keyValue}'`
1320
+ }
1321
+ keyValue = ''
1322
+ } else {
1323
+ keyValue += right
1324
+ }
1325
+ }
1326
+ rightIndex++
1327
+ }
1328
+ if (grammarMap.checkState() && haveNotGetValue) {
1329
+ // key值查找结束但是语法未闭合或者处理到边界还未结束,抛异常
1330
+ throw new Error('[optionChain] option key illegal!!!')
1331
+ }
1332
+ if (keyValue) {
1333
+ chainKey += `,'${keyValue}'`
1334
+ }
1335
+ str = str.slice(0, leftIndex) + `${wxsName}(${chainValue},[${chainKey.slice(1)}])` + str.slice(rightIndex)
1336
+ if (!hasOptionalChaining) {
1337
+ hasOptionalChaining = true
1338
+ }
1339
+ }
1340
+ return str
1341
+ }
1342
+
1153
1343
  function parseMustacheWithContext (raw = '') {
1154
1344
  return parseMustache(raw, (exp) => {
1155
1345
  if (defs) {
@@ -1163,8 +1353,9 @@ function parseMustacheWithContext (raw = '') {
1163
1353
  }
1164
1354
  })
1165
1355
  }
1356
+ // 处理可选链表达式
1357
+ exp = parseOptionalChaining(exp)
1166
1358
 
1167
- exp = parseOptionChain(exp)
1168
1359
  if (i18n) {
1169
1360
  for (const i18nFuncName of i18nFuncNames) {
1170
1361
  const funcNameRE = new RegExp(`(?<![A-Za-z0-9_$.])${i18nFuncName}\\(`)
@@ -1244,12 +1435,12 @@ function parseMustache (raw = '', expHandler = exp => exp, strHandler = str => s
1244
1435
  }
1245
1436
  }
1246
1437
 
1247
- function addExp (el, exp, isProps) {
1438
+ function addExp (el, exp, isProps, attrName) {
1248
1439
  if (exp) {
1249
1440
  if (!el.exps) {
1250
1441
  el.exps = []
1251
1442
  }
1252
- el.exps.push({ exp, isProps })
1443
+ el.exps.push({ exp, isProps, attrName })
1253
1444
  }
1254
1445
  }
1255
1446
 
@@ -1274,7 +1465,7 @@ function processIf (el) {
1274
1465
  }
1275
1466
  }
1276
1467
 
1277
- function processIfForWeb (el) {
1468
+ function processIfWeb (el) {
1278
1469
  let val = getAndRemoveAttr(el, config[mode].directive.if).val
1279
1470
  if (val) {
1280
1471
  el.if = {
@@ -1377,31 +1568,23 @@ function postProcessWxs (el, meta) {
1377
1568
  if (el.tag === config[mode].wxs.tag) {
1378
1569
  const module = el.attrsMap[config[mode].wxs.module]
1379
1570
  if (module) {
1380
- let src, content
1571
+ let src
1381
1572
  if (el.attrsMap[config[mode].wxs.src]) {
1382
1573
  src = el.attrsMap[config[mode].wxs.src]
1383
1574
  } else {
1384
- content = el.children.filter((child) => {
1575
+ const content = el.children.filter((child) => {
1385
1576
  return child.type === 3 && !child.isComment
1386
1577
  }).map(child => child.text).join('\n')
1578
+ addWxsContent(meta, module, content)
1387
1579
 
1388
1580
  const fakeRequest = filePath + config[mode].wxs.ext
1389
-
1390
1581
  src = addQuery(`~${fakeRequest}!=!${filePath}`, {
1391
1582
  wxsModule: module
1392
1583
  })
1393
-
1394
- addAttrs(el, [{
1395
- name: config[mode].wxs.src,
1396
- value: src
1397
- }])
1398
- el.children = []
1399
1584
  }
1400
- src && addWxsModule(meta, module, src)
1401
- content && addWxsContent(meta, module, content)
1402
1585
  // wxs hoist
1586
+ injectWxs(meta, module, src)
1403
1587
  removeNode(el, true)
1404
- injectNodes.push(el)
1405
1588
  }
1406
1589
  }
1407
1590
  }
@@ -1421,7 +1604,7 @@ function processAttrs (el, options) {
1421
1604
  if (isTemplateData) {
1422
1605
  result = result.replace(spreadREG, '$1')
1423
1606
  }
1424
- addExp(el, result, isProps)
1607
+ addExp(el, result, isProps, attr.name)
1425
1608
  if (parsed.replaced) {
1426
1609
  modifyAttr(el, attr.name, needWrap ? parsed.val.slice(1, -1) : parsed.val)
1427
1610
  }
@@ -1436,7 +1619,7 @@ function postProcessFor (el) {
1436
1619
  这个操作主要是因为百度小程序不支持这两个directive在同级使用
1437
1620
  */
1438
1621
  if (el.if && mode === 'swan') {
1439
- const block = createASTElement('block', [])
1622
+ const block = createASTElement('block')
1440
1623
  replaceNode(el, block, true)
1441
1624
  block.for = el.for
1442
1625
  delete el.for
@@ -1552,7 +1735,7 @@ function postProcessIf (el) {
1552
1735
  }
1553
1736
  }
1554
1737
 
1555
- function processText (el) {
1738
+ function processText (el, meta) {
1556
1739
  if (el.type !== 3 || el.isComment) {
1557
1740
  return
1558
1741
  }
@@ -1576,10 +1759,13 @@ function processText (el) {
1576
1759
  // }])
1577
1760
  // }
1578
1761
 
1579
- function injectWxs (meta, module, src) {
1762
+ function injectWxs (meta, module, src, options) {
1580
1763
  if (addWxsModule(meta, module, src)) {
1581
1764
  return
1582
1765
  }
1766
+ if (options && options.runtimeCompile) {
1767
+ return
1768
+ }
1583
1769
  const wxsNode = createASTElement(config[mode].wxs.tag, [
1584
1770
  {
1585
1771
  name: config[mode].wxs.module,
@@ -1683,13 +1869,13 @@ function processAliExternalClassesHack (el, options) {
1683
1869
  }
1684
1870
  })
1685
1871
 
1686
- if (options.hasScoped && isComponent) {
1872
+ if (hasScoped && isComponent) {
1687
1873
  options.externalClasses.forEach((className) => {
1688
1874
  const externalClass = getAndRemoveAttr(el, className).val
1689
1875
  if (externalClass) {
1690
1876
  addAttrs(el, [{
1691
1877
  name: className,
1692
- value: `${externalClass} ${options.moduleId}`
1878
+ value: `${externalClass} ${moduleId}`
1693
1879
  }])
1694
1880
  }
1695
1881
  })
@@ -1757,10 +1943,9 @@ function processWebExternalClassesHack (el, options) {
1757
1943
  }
1758
1944
  }
1759
1945
 
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全局样式对页面的影响
1946
+ function processScoped (el) {
1947
+ if (hasScoped && isRealNode(el)) {
1948
+ const rootModuleId = ctorType === 'component' ? '' : MPX_APP_MODULE_ID // 处理app全局样式对页面的影响
1764
1949
  const staticClass = getAndRemoveAttr(el, 'class').val
1765
1950
  addAttrs(el, [{
1766
1951
  name: 'class',
@@ -1778,12 +1963,12 @@ function processBuiltInComponents (el, meta) {
1778
1963
  }
1779
1964
  const tag = el.tag
1780
1965
  if (!meta.builtInComponentsMap[tag]) {
1781
- meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/${mode}/${tag}.vue`
1966
+ meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/${mode}/${tag}`
1782
1967
  }
1783
1968
  }
1784
1969
  }
1785
1970
 
1786
- function processAliAddComponentRootView (el, options) {
1971
+ function postProcessAliComponentRootView (el, options, meta) {
1787
1972
  const processAttrsConditions = [
1788
1973
  { condition: /^(on|catch)Tap$/, action: 'clone' },
1789
1974
  { condition: /^(on|catch)TouchStart$/, action: 'clone' },
@@ -1797,25 +1982,25 @@ function processAliAddComponentRootView (el, options) {
1797
1982
  { condition: /^slot$/, action: 'move' }
1798
1983
  ]
1799
1984
  const processAppendAttrsRules = [
1800
- { name: 'class', value: `${MPX_ROOT_VIEW} host-${options.moduleId}` }
1985
+ { name: 'class', value: `${MPX_ROOT_VIEW} host-${moduleId}` }
1801
1986
  ]
1802
- const newElAttrs = []
1987
+ const newAttrs = []
1803
1988
  const allAttrs = cloneAttrsList(el.attrsList)
1804
1989
 
1805
1990
  function processClone (attr) {
1806
- newElAttrs.push(attr)
1991
+ newAttrs.push(attr)
1807
1992
  }
1808
1993
 
1809
1994
  function processMove (attr) {
1810
1995
  getAndRemoveAttr(el, attr.name)
1811
- newElAttrs.push(attr)
1996
+ newAttrs.push(attr)
1812
1997
  }
1813
1998
 
1814
1999
  function processAppendRules (el) {
1815
2000
  processAppendAttrsRules.forEach((rule) => {
1816
2001
  const getNeedAppendAttrValue = el.attrsMap[rule.name]
1817
2002
  const value = getNeedAppendAttrValue ? getNeedAppendAttrValue + ' ' + rule.value : rule.value
1818
- newElAttrs.push({
2003
+ newAttrs.push({
1819
2004
  name: rule.name,
1820
2005
  value
1821
2006
  })
@@ -1836,32 +2021,34 @@ function processAliAddComponentRootView (el, options) {
1836
2021
  })
1837
2022
 
1838
2023
  processAppendRules(el)
1839
- const componentWrapView = createASTElement('view', newElAttrs)
1840
- moveBaseDirective(componentWrapView, el)
1841
- if (el.is && el.components) {
1842
- el = postProcessComponentIs(el)
1843
- }
2024
+ const componentWrapView = createASTElement('view', newAttrs)
1844
2025
 
1845
2026
  replaceNode(el, componentWrapView, true)
1846
2027
  addChild(componentWrapView, el)
1847
- return componentWrapView
2028
+ processAttrs(componentWrapView, options)
2029
+ postMoveBaseDirective(componentWrapView, el, options)
2030
+
2031
+ if (options.runtimeCompile) {
2032
+ collectDynamicInfo(componentWrapView, options, meta)
2033
+ postProcessAttrsDynamic(componentWrapView, config[mode])
2034
+ }
1848
2035
  }
1849
2036
 
1850
2037
  // 有virtualHost情况wx组件注入virtualHost。无virtualHost阿里组件注入root-view。其他跳过。
1851
2038
  function getVirtualHostRoot (options, meta) {
1852
2039
  if (srcMode === 'wx') {
1853
- if (options.isComponent) {
1854
- if ((mode === 'wx') && options.hasVirtualHost) {
2040
+ if (ctorType === 'component') {
2041
+ if (mode === 'wx' && hasVirtualHost) {
1855
2042
  // wx组件注入virtualHost配置
1856
2043
  !meta.options && (meta.options = {})
1857
2044
  meta.options.virtualHost = true
1858
2045
  }
1859
- if ((mode === 'web') && !options.hasVirtualHost) {
2046
+ if (mode === 'web' && !hasVirtualHost) {
1860
2047
  // ali组件根节点实体化
1861
2048
  const rootView = createASTElement('view', [
1862
2049
  {
1863
2050
  name: 'class',
1864
- value: `${MPX_ROOT_VIEW} host-${options.moduleId}`
2051
+ value: `${MPX_ROOT_VIEW} host-${moduleId}`
1865
2052
  },
1866
2053
  {
1867
2054
  name: 'v-on',
@@ -1872,10 +2059,8 @@ function getVirtualHostRoot (options, meta) {
1872
2059
  return rootView
1873
2060
  }
1874
2061
  }
1875
- if (options.isPage) {
1876
- if (mode === 'web') {
1877
- return createASTElement('page', [])
1878
- }
2062
+ if (mode === 'web' && ctorType === 'page') {
2063
+ return createASTElement('page')
1879
2064
  }
1880
2065
  }
1881
2066
  return getTempNode()
@@ -1889,8 +2074,8 @@ function processShow (el, options, root) {
1889
2074
  if (has && show === undefined) {
1890
2075
  error$1(`Attrs ${config[mode].directive.show} should have a value `)
1891
2076
  }
1892
- if (options.hasVirtualHost) {
1893
- if (options.isComponent && el.parent === root && isRealNode(el)) {
2077
+ if (hasVirtualHost) {
2078
+ if (ctorType === 'component' && el.parent === root && isRealNode(el)) {
1894
2079
  if (show !== undefined) {
1895
2080
  show = `{{${parseMustacheWithContext(show).result}&&mpxShow}}`
1896
2081
  } else {
@@ -1906,22 +2091,30 @@ function processShow (el, options, root) {
1906
2091
  value: show
1907
2092
  }])
1908
2093
  } else {
1909
- processShowStyle()
2094
+ if (options.runtimeCompile) {
2095
+ processShowStyleDynamic(el, show)
2096
+ } else {
2097
+ processShowStyle(el, show)
2098
+ }
1910
2099
  }
1911
2100
  } else {
1912
- processShowStyle()
2101
+ if (options.runtimeCompile) {
2102
+ processShowStyleDynamic(el, show)
2103
+ } else {
2104
+ processShowStyle(el, show)
2105
+ }
1913
2106
  }
2107
+ }
1914
2108
 
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
- }
2109
+ function processShowStyle (el, show) {
2110
+ if (show !== undefined) {
2111
+ const showExp = parseMustacheWithContext(show).result
2112
+ let oldStyle = getAndRemoveAttr(el, 'style').val
2113
+ oldStyle = oldStyle ? oldStyle + ';' : ''
2114
+ addAttrs(el, [{
2115
+ name: 'style',
2116
+ value: `${oldStyle}{{${showExp}?'':'display:none;'}}`
2117
+ }])
1925
2118
  }
1926
2119
  }
1927
2120
 
@@ -2044,11 +2237,11 @@ function processDuplicateAttrsList (el) {
2044
2237
  }
2045
2238
 
2046
2239
  // 处理wxs注入逻辑
2047
- function processInjectWxs (el, meta) {
2240
+ function processInjectWxs (el, meta, options) {
2048
2241
  if (el.injectWxsProps && el.injectWxsProps.length) {
2049
2242
  el.injectWxsProps.forEach((injectWxsProp) => {
2050
2243
  const { injectWxsPath, injectWxsModuleName } = injectWxsProp
2051
- injectWxs(meta, injectWxsModuleName, injectWxsPath)
2244
+ injectWxs(meta, injectWxsModuleName, injectWxsPath, options)
2052
2245
  })
2053
2246
  }
2054
2247
  }
@@ -2086,7 +2279,7 @@ function processElement (el, root, options, meta) {
2086
2279
 
2087
2280
  processMpxTagName(el)
2088
2281
 
2089
- processInjectWxs(el, meta)
2282
+ processInjectWxs(el, meta, options)
2090
2283
 
2091
2284
  const transAli = mode === 'ali' && srcMode === 'wx'
2092
2285
 
@@ -2094,9 +2287,9 @@ function processElement (el, root, options, meta) {
2094
2287
  // 收集内建组件
2095
2288
  processBuiltInComponents(el, meta)
2096
2289
  // 预处理代码维度条件编译
2097
- processIfForWeb(el)
2290
+ processIfWeb(el)
2098
2291
  processWebExternalClassesHack(el, options)
2099
- processComponentGenericsForWeb(el, options, meta)
2292
+ processComponentGenericsWeb(el, options, meta)
2100
2293
  return
2101
2294
  }
2102
2295
 
@@ -2104,7 +2297,7 @@ function processElement (el, root, options, meta) {
2104
2297
 
2105
2298
  // 仅ali平台需要scoped模拟样式隔离
2106
2299
  if (mode === 'ali') {
2107
- processScoped(el, options)
2300
+ processScoped(el)
2108
2301
  }
2109
2302
 
2110
2303
  if (transAli) {
@@ -2114,9 +2307,14 @@ function processElement (el, root, options, meta) {
2114
2307
  processIf(el)
2115
2308
  processFor(el)
2116
2309
  processRef(el, options, meta)
2117
- processClass(el, meta)
2118
- processStyle(el, meta)
2119
- processBindEvent(el, options)
2310
+ if (options.runtimeCompile) {
2311
+ processClassDynamic(el, meta)
2312
+ processStyleDynamic(el, meta)
2313
+ } else {
2314
+ processClass(el, meta)
2315
+ processStyle(el, meta)
2316
+ }
2317
+ processEvent(el, options)
2120
2318
 
2121
2319
  if (!pass) {
2122
2320
  processShow(el, options, root)
@@ -2128,6 +2326,8 @@ function processElement (el, root, options, meta) {
2128
2326
 
2129
2327
  function closeElement (el, meta, options) {
2130
2328
  postProcessAtMode(el)
2329
+ collectDynamicInfo(el, options, meta)
2330
+
2131
2331
  if (mode === 'web') {
2132
2332
  postProcessWxs(el, meta)
2133
2333
  // 处理代码维度条件编译移除死分支
@@ -2136,16 +2336,26 @@ function closeElement (el, meta, options) {
2136
2336
  }
2137
2337
  const pass = isNative || postProcessTemplate(el) || processingTemplate
2138
2338
  postProcessWxs(el, meta)
2139
-
2140
2339
  if (!pass) {
2141
- if (isComponentNode(el, options) && !options.hasVirtualHost && mode === 'ali') {
2142
- el = processAliAddComponentRootView(el, options)
2143
- } else {
2144
- el = postProcessComponentIs(el)
2340
+ if (isComponentNode(el, options) && !hasVirtualHost && mode === 'ali') {
2341
+ postProcessAliComponentRootView(el, options, meta)
2145
2342
  }
2343
+ postProcessComponentIs(el, options)
2146
2344
  }
2147
- postProcessFor(el)
2148
- postProcessIf(el)
2345
+
2346
+ if (options.runtimeCompile) {
2347
+ postProcessForDynamic(el, config[mode])
2348
+ postProcessIfDynamic(el, config[mode])
2349
+ postProcessAttrsDynamic(el, config[mode])
2350
+ } else {
2351
+ postProcessFor(el)
2352
+ postProcessIf(el)
2353
+ }
2354
+ }
2355
+
2356
+ // 运行时组件的模版节点收集,最终注入到 mpx-custom-element-*.wxml 中
2357
+ function collectDynamicInfo (el, options, meta) {
2358
+ setBaseWxml(el, { mode, isComponentNode, options }, meta)
2149
2359
  }
2150
2360
 
2151
2361
  function postProcessAtMode (el) {
@@ -2176,21 +2386,18 @@ function cloneAttrsList (attrsList) {
2176
2386
  })
2177
2387
  }
2178
2388
 
2179
- function postProcessComponentIs (el) {
2389
+ function postProcessComponentIs (el, options) {
2180
2390
  if (el.is && el.components) {
2181
2391
  let tempNode
2182
2392
  if (el.for || el.if || el.elseif || el.else) {
2183
- tempNode = createASTElement('block', [])
2184
- moveBaseDirective(tempNode, el)
2393
+ tempNode = createASTElement('block')
2185
2394
  } else {
2186
2395
  tempNode = getTempNode()
2187
2396
  }
2188
- let range = []
2189
- if (el.attrsMap.range) {
2190
- range = getAndRemoveAttr(el, 'range').val.split(',').map(item => item.trim())
2191
- }
2397
+ replaceNode(el, tempNode, true)
2398
+ postMoveBaseDirective(tempNode, el, options)
2399
+
2192
2400
  el.components.forEach(function (component) {
2193
- if (range.length > 0 && !range.includes(component)) return
2194
2401
  const newChild = createASTElement(component, cloneAttrsList(el.attrsList), tempNode)
2195
2402
  newChild.if = {
2196
2403
  raw: `{{${el.is} === ${stringify(component)}}}`,
@@ -2207,10 +2414,9 @@ function postProcessComponentIs (el) {
2207
2414
  if (!el.parent) {
2208
2415
  error$1('Dynamic component can not be the template root, considering wrapping it with <view> or <text> tag!')
2209
2416
  } else {
2210
- el = replaceNode(el, tempNode, true) || el
2417
+ replaceNode(el, tempNode, true)
2211
2418
  }
2212
2419
  }
2213
- return el
2214
2420
  }
2215
2421
 
2216
2422
  function stringifyAttr (val) {
@@ -2290,8 +2496,8 @@ function findPrevNode (node) {
2290
2496
  }
2291
2497
  }
2292
2498
 
2293
- function replaceNode (node, newNode, reserveNode) {
2294
- if (!reserveNode) deleteErrorInResultMap(node)
2499
+ function replaceNode (node, newNode, reserveError) {
2500
+ if (!reserveError) deleteErrorInResultMap(node)
2295
2501
  const parent = node.parent
2296
2502
  if (parent) {
2297
2503
  const index = parent.children.indexOf(node)
@@ -2303,8 +2509,8 @@ function replaceNode (node, newNode, reserveNode) {
2303
2509
  }
2304
2510
  }
2305
2511
 
2306
- function removeNode (node, reserveNode) {
2307
- if (!reserveNode) deleteErrorInResultMap(node)
2512
+ function removeNode (node, reserveError) {
2513
+ if (!reserveError) deleteErrorInResultMap(node)
2308
2514
  const parent = node.parent
2309
2515
  if (parent) {
2310
2516
  const index = parent.children.indexOf(node)
@@ -2399,167 +2605,148 @@ function genNode (node) {
2399
2605
  return exp
2400
2606
  }
2401
2607
 
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
2608
+ function addIfConditionDynamic (el, condition) {
2609
+ if (!el.ifConditions) {
2610
+ el.ifConditions = []
2611
+ }
2612
+ el.ifConditions.push(condition)
2613
+ }
2614
+
2615
+ function processIfConditionsDynamic (el) {
2616
+ const prevNode = findPrevNode(el)
2617
+ if (prevNode && prevNode.if) {
2618
+ addIfConditionDynamic(prevNode, {
2619
+ ifExp: !!el.elseif,
2620
+ block: el,
2621
+ __exp: el.elseif ? parseExp(el.elseif.exp) : ''
2622
+ })
2623
+ removeNode(el)
2624
+ }
2625
+ }
2626
+
2627
+ function processClassDynamic (el, meta) {
2628
+ const type = 'class'
2629
+ const targetType = type
2630
+ const dynamicClass = getAndRemoveAttr(el, config[mode].directive.dynamicClass).val
2631
+ let staticClass = getAndRemoveAttr(el, type).val || ''
2632
+ staticClass = staticClass.replace(/\s+/g, ' ')
2633
+ if (dynamicClass) {
2634
+ const staticClassExp = parseMustacheWithContext(staticClass).result
2635
+ const dynamicClassExp = transDynamicClassExpr(parseMustacheWithContext(dynamicClass).result, {
2636
+ error: error$1
2637
+ })
2638
+ addAttrs(el, [{
2639
+ name: targetType,
2640
+ value: `{{[${staticClassExp},${dynamicClassExp}]}}`
2641
+ }])
2642
+ } else if (staticClass) {
2643
+ addAttrs(el, [{
2644
+ name: targetType,
2645
+ value: staticClass
2646
+ }])
2647
+ }
2648
+ }
2649
+
2650
+ function processStyleDynamic (el, meta) {
2651
+ const type = 'style'
2652
+ const targetType = type
2653
+ const dynamicStyle = getAndRemoveAttr(el, config[mode].directive.dynamicStyle).val
2654
+ let staticStyle = getAndRemoveAttr(el, type).val || ''
2655
+ staticStyle = staticStyle.replace(/\s+/g, ' ')
2656
+ if (dynamicStyle) {
2657
+ const staticStyleExp = parseMustacheWithContext(staticStyle).result
2658
+ const dynamicStyleExp = parseMustacheWithContext(dynamicStyle).result
2659
+ addAttrs(el, [{
2660
+ name: targetType,
2661
+ value: `{{[${staticStyleExp},${dynamicStyleExp}]}}`
2662
+ }])
2663
+ } else if (staticStyle) {
2664
+ addAttrs(el, [{
2665
+ name: targetType,
2666
+ value: staticStyle
2667
+ }])
2668
+ }
2669
+ }
2670
+
2671
+ function processTextDynamic (vnode) {
2672
+ if (vnode.type !== 3 || vnode.isComment) {
2673
+ return
2674
+ }
2675
+ const parsed = parseMustacheWithContext(vnode.text)
2676
+ if (parsed.hasBinding) {
2677
+ vnode.__exp = parseExp(parsed.result)
2678
+ delete vnode.text
2679
+ }
2680
+ }
2681
+
2682
+ function postProcessIfDynamic (vnode, config) {
2683
+ if (vnode.if) {
2684
+ const parsedExp = vnode.if.exp
2685
+ addIfConditionDynamic(vnode, {
2686
+ ifExp: true,
2687
+ block: 'self',
2688
+ __exp: parseExp(parsedExp)
2689
+ })
2690
+ getAndRemoveAttr(vnode, config.directive.if)
2691
+ vnode.if = true
2692
+ } else if (vnode.elseif || vnode.else) {
2693
+ const directive = vnode.elseif
2694
+ ? config.directive.elseif
2695
+ : config.directive.else
2696
+ getAndRemoveAttr(vnode, directive)
2697
+ processIfConditionsDynamic(vnode)
2698
+ delete vnode.elseif
2699
+ delete vnode.else
2700
+ }
2701
+ }
2702
+
2703
+ function postProcessForDynamic (vnode) {
2704
+ if (vnode.for) {
2705
+ vnode.for.__exp = parseExp(vnode.for.exp)
2706
+ delete vnode.for.raw
2707
+ delete vnode.for.exp
2708
+ popForScopes()
2709
+ }
2710
+ }
2711
+
2712
+ function postProcessAttrsDynamic (vnode, config) {
2713
+ const exps = vnode.exps?.filter(v => v.attrName) || []
2714
+ const expsMap = Object.fromEntries(exps.map(v => ([v.attrName, v])))
2715
+ const directives = Object.values(config.directive)
2716
+ if (vnode.attrsList && vnode.attrsList.length) {
2717
+ // 后序遍历,主要为了做剔除的操作
2718
+ for (let i = vnode.attrsList.length - 1; i >= 0; i--) {
2719
+ const attr = vnode.attrsList[i]
2720
+ if (config.event.parseEvent(attr.name) || directives.includes(attr.name)) {
2721
+ // 原本的事件代理直接剔除,主要是基础模版的事件直接走代理形式,事件绑定名直接写死的,优化 astJson 体积
2722
+ getAndRemoveAttr(vnode, attr.name)
2723
+ } else if (attr.value == null) {
2724
+ attr.__exp = parseExp('true')
2725
+ } else {
2726
+ const expInfo = expsMap[attr.name]
2727
+ if (expInfo && expInfo.exp) {
2728
+ attr.__exp = parseExp(expInfo.exp)
2496
2729
  }
2497
2730
  }
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
- }
2731
+ if (attr.__exp) {
2732
+ delete attr.value
2547
2733
  }
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
2734
  }
2561
2735
  }
2562
- return str
2736
+ }
2737
+
2738
+ function processShowStyleDynamic (el, show) {
2739
+ if (show !== undefined) {
2740
+ const showExp = parseMustacheWithContext(show).result
2741
+ const oldStyle = getAndRemoveAttr(el, 'style').val
2742
+ const displayExp = `${showExp}? '' : "display:none;"`
2743
+ const isArray = oldStyle?.endsWith(']}}')
2744
+ const value = isArray ? oldStyle?.replace(']}}', `,${displayExp}]}}`) : `${oldStyle ? `${oldStyle};` : ''}{{${displayExp}}}`
2745
+ addAttrs(el, [{
2746
+ name: 'style',
2747
+ value: value
2748
+ }])
2749
+ }
2563
2750
  }
2564
2751
 
2565
2752
  module.exports = {
@@ -2572,5 +2759,10 @@ module.exports = {
2572
2759
  parseMustache,
2573
2760
  parseMustacheWithContext,
2574
2761
  stringifyWithResolveComputed,
2575
- addAttrs
2762
+ addAttrs,
2763
+ getAndRemoveAttr,
2764
+ findPrevNode,
2765
+ removeNode,
2766
+ replaceNode,
2767
+ createASTElement
2576
2768
  }