@mpxjs/webpack-plugin 2.8.40-beta.0 → 2.8.40-test.2

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.
Files changed (63) hide show
  1. package/lib/dependencies/CommonJsExtractDependency.js +51 -0
  2. package/lib/dependencies/DynamicEntryDependency.js +10 -16
  3. package/lib/dependencies/ResolveDependency.js +11 -20
  4. package/lib/extractor.js +1 -0
  5. package/lib/helpers.js +9 -1
  6. package/lib/index.js +239 -134
  7. package/lib/json-compiler/helper.js +27 -17
  8. package/lib/json-compiler/index.js +82 -31
  9. package/lib/loader.js +31 -37
  10. package/lib/native-loader.js +21 -14
  11. package/lib/parser.js +0 -1
  12. package/lib/platform/index.js +15 -4
  13. package/lib/platform/json/wx/index.js +63 -2
  14. package/lib/platform/run-rules.js +1 -1
  15. package/lib/platform/template/normalize-component-rules.js +42 -41
  16. package/lib/platform/template/wx/component-config/README.md +1 -1
  17. package/lib/platform/template/wx/component-config/component.js +1 -2
  18. package/lib/platform/template/wx/component-config/fix-component-name.js +21 -0
  19. package/lib/platform/template/wx/component-config/hypen-tag-name.js +2 -6
  20. package/lib/platform/template/wx/component-config/index.js +6 -4
  21. package/lib/platform/template/wx/component-config/view.js +0 -11
  22. package/lib/platform/template/wx/index.js +84 -32
  23. package/lib/runtime/base.styl +9 -6
  24. package/lib/runtime/components/web/filterTag.js +9 -30
  25. package/lib/runtime/components/web/getInnerListeners.js +3 -16
  26. package/lib/runtime/components/web/mpx-image.vue +13 -10
  27. package/lib/runtime/components/web/mpx-keep-alive.vue +10 -17
  28. package/lib/runtime/components/web/mpx-movable-view.vue +105 -23
  29. package/lib/runtime/components/web/mpx-picker-view-column.vue +10 -2
  30. package/lib/runtime/components/web/mpx-picker-view.vue +1 -1
  31. package/lib/runtime/components/web/mpx-picker.vue +9 -1
  32. package/lib/runtime/components/web/mpx-scroll-view.vue +69 -23
  33. package/lib/runtime/components/web/mpx-swiper.vue +152 -62
  34. package/lib/runtime/components/web/mpx-video.vue +123 -89
  35. package/lib/runtime/components/web/mpx-web-view.vue +120 -81
  36. package/lib/runtime/components/web/promisify.js +19 -0
  37. package/lib/runtime/components/wx/default-page.mpx +27 -0
  38. package/lib/runtime/optionProcessor.js +321 -270
  39. package/lib/runtime/stringify.wxs +44 -8
  40. package/lib/style-compiler/index.js +6 -3
  41. package/lib/template-compiler/bind-this.js +280 -49
  42. package/lib/template-compiler/compiler.js +122 -108
  43. package/lib/template-compiler/index.js +35 -23
  44. package/lib/utils/check-core-version-match.js +18 -14
  45. package/lib/utils/dom-tag-config.js +115 -0
  46. package/lib/utils/make-map.js +12 -0
  47. package/lib/utils/string.js +7 -1
  48. package/lib/utils/ts-loader-watch-run-loader-filter.js +4 -5
  49. package/lib/web/processJSON.js +39 -3
  50. package/lib/web/processMainScript.js +84 -0
  51. package/lib/web/processScript.js +21 -201
  52. package/lib/web/processTemplate.js +11 -35
  53. package/lib/web/script-helper.js +202 -0
  54. package/package.json +7 -6
  55. package/lib/json-compiler/default-page.mpx +0 -3
  56. package/lib/style-compiler/plugins/trim.js +0 -15
  57. package/lib/template-compiler/preprocessor.js +0 -29
  58. package/lib/wxss/compile-exports.js +0 -52
  59. package/lib/wxss/createResolver.js +0 -36
  60. package/lib/wxss/css-base.js +0 -79
  61. package/lib/wxss/getLocalIdent.js +0 -25
  62. package/lib/wxss/localsLoader.js +0 -44
  63. package/lib/wxss/processCss.js +0 -274
@@ -3,6 +3,7 @@ const normalizeTest = require('../normalize-test')
3
3
  const changeKey = require('../change-key')
4
4
  const normalize = require('../../../utils/normalize')
5
5
  const { capitalToHyphen } = require('../../../utils/string')
6
+ const { isOriginTag, isBuildInTag } = require('../../../utils/dom-tag-config')
6
7
 
7
8
  const mpxViewPath = normalize.lib('runtime/components/ali/mpx-view.mpx')
8
9
  const mpxTextPath = normalize.lib('runtime/components/ali/mpx-text.mpx')
@@ -70,6 +71,26 @@ module.exports = function getSpec ({ warn, error }) {
70
71
  return input
71
72
  }
72
73
 
74
+ // 校验输出支付宝 componentGenerics 配置的正确性
75
+ function aliComponentGenericsValidate (input) {
76
+ const componentGenerics = input.componentGenerics
77
+ if (componentGenerics && typeof componentGenerics === 'object') {
78
+ Object.keys(componentGenerics).forEach(key => {
79
+ if (!componentGenerics[key].default) {
80
+ error(`Ali environment componentGenerics need to specify a default custom component! please check the configuration of component ${key}`)
81
+ }
82
+ })
83
+ }
84
+ return input
85
+ }
86
+
87
+ function fillGlobalComponents (input, { globalComponents }) {
88
+ if (globalComponents) {
89
+ Object.assign(globalComponents, input.usingComponents)
90
+ }
91
+ return input
92
+ }
93
+
73
94
  // 处理 ali swan 的组件名大写字母转连字符:WordExample/wordExample -> word-example
74
95
  function componentNameCapitalToHyphen (type) {
75
96
  return function (input) {
@@ -105,10 +126,28 @@ module.exports = function getSpec ({ warn, error }) {
105
126
  }
106
127
  }
107
128
 
129
+ /**
130
+ * 将小程序代码中使用的与原生 HTML tag 或 内建组件 同名的组件进行转化,以解决与原生tag命名冲突问题。
131
+ */
132
+ function fixComponentName (type) {
133
+ return function (input) {
134
+ const usingComponents = input[type]
135
+ if (usingComponents) {
136
+ Object.keys(usingComponents).forEach(tag => {
137
+ if (isOriginTag(tag) || isBuildInTag(tag)) {
138
+ usingComponents[`mpx-com-${tag}`] = usingComponents[tag]
139
+ delete usingComponents[tag]
140
+ }
141
+ })
142
+ }
143
+ return input
144
+ }
145
+ }
146
+
108
147
  const componentRules = [
109
148
  {
110
149
  test: 'componentGenerics',
111
- ali: deletePath(true)
150
+ ali: aliComponentGenericsValidate
112
151
  },
113
152
  {
114
153
  test: 'componentPlaceholder',
@@ -117,6 +156,10 @@ module.exports = function getSpec ({ warn, error }) {
117
156
  tt: deletePath(),
118
157
  jd: deletePath()
119
158
  },
159
+ {
160
+ test: 'usingComponents',
161
+ web: fixComponentName('usingComponents')
162
+ },
120
163
  {
121
164
  test: 'usingComponents',
122
165
  ali: componentNameCapitalToHyphen('usingComponents'),
@@ -217,7 +260,7 @@ module.exports = function getSpec ({ warn, error }) {
217
260
  }
218
261
 
219
262
  const spec = {
220
- supportedModes: ['ali', 'swan', 'qq', 'tt', 'jd', 'qa', 'dd'],
263
+ supportedModes: ['ali', 'swan', 'qq', 'tt', 'jd', 'qa', 'dd', 'web'],
221
264
  normalizeTest,
222
265
  page: [
223
266
  ...windowRules,
@@ -318,6 +361,24 @@ module.exports = function getSpec ({ warn, error }) {
318
361
  tt: deletePath(),
319
362
  jd: deletePath(true)
320
363
  },
364
+ {
365
+ test: 'usingComponents',
366
+ web: fixComponentName('usingComponents')
367
+ },
368
+ {
369
+ test: 'usingComponents',
370
+ ali: componentNameCapitalToHyphen('usingComponents'),
371
+ swan: componentNameCapitalToHyphen('usingComponents')
372
+ },
373
+ {
374
+ test: 'usingComponents',
375
+ // todo ali 2.0已支持全局组件,待移除
376
+ ali: fillGlobalComponents,
377
+ qq: fillGlobalComponents,
378
+ swan: fillGlobalComponents,
379
+ tt: fillGlobalComponents,
380
+ jd: fillGlobalComponents
381
+ },
321
382
  {
322
383
  test: 'usingComponents',
323
384
  // todo ali 2.0已支持全局组件,待移除
@@ -32,7 +32,7 @@ module.exports = function runRules (rules = [], input, options = {}) {
32
32
  if (result !== undefined) {
33
33
  input = result
34
34
  }
35
- if (!waterfall) break
35
+ if (!(rule.waterfall || waterfall)) break
36
36
  }
37
37
  }
38
38
  return input
@@ -8,56 +8,57 @@ const runRules = require('../run-rules')
8
8
  module.exports = function normalizeComponentRules (cfgs, spec) {
9
9
  return cfgs.map((cfg) => {
10
10
  const result = {}
11
- if (cfg.test) {
12
- result.test = cfg.test
13
- }
11
+ if (cfg.test) result.test = cfg.test
12
+ if (cfg.waterfall) result.waterfall = cfg.waterfall
14
13
  const supportedModes = cfg.supportedModes || spec.supportedModes
15
14
  // 合并component-config中组件的event 与index中公共的event规则
16
15
  const eventRules = (cfg.event || []).concat(spec.event.rules)
17
16
  supportedModes.forEach((mode) => {
18
- result[mode] = function (el, data) {
19
- data = Object.assign({}, data, { el, eventRules })
20
- const testKey = 'name'
21
- let rAttrsList = []
22
- const options = {
23
- mode,
24
- testKey,
25
- data
26
- }
27
- el.attrsList.forEach((attr) => {
28
- const meta = {}
29
- let rAttr = runRules(spec.directive, attr, {
30
- ...options,
31
- meta
32
- })
33
- // 指令未匹配到时说明为props,因为目前所有的指令都需要转换
34
- if (!meta.processed) {
35
- rAttr = runRules(spec.preProps, rAttr, options)
36
- rAttr = runRules(cfg.props, rAttr, options)
17
+ result[mode] = cfg.skipNormalize
18
+ ? cfg[mode]
19
+ : function (el, data) {
20
+ data = Object.assign({}, data, { el, eventRules })
21
+ const testKey = 'name'
22
+ let rAttrsList = []
23
+ const options = {
24
+ mode,
25
+ testKey,
26
+ data
27
+ }
28
+ el.attrsList.forEach((attr) => {
29
+ const meta = {}
30
+ let rAttr = runRules(spec.directive, attr, {
31
+ ...options,
32
+ meta
33
+ })
34
+ // 指令未匹配到时说明为props,因为目前所有的指令都需要转换
35
+ if (!meta.processed) {
36
+ rAttr = runRules(spec.preProps, rAttr, options)
37
+ rAttr = runRules(cfg.props, rAttr, options)
38
+ if (Array.isArray(rAttr)) {
39
+ rAttr = rAttr.map((attr) => {
40
+ return runRules(spec.postProps, attr, options)
41
+ })
42
+ } else if (rAttr !== false) {
43
+ rAttr = runRules(spec.postProps, rAttr, options)
44
+ }
45
+ }
46
+ // 生成目标attrsList
37
47
  if (Array.isArray(rAttr)) {
38
- rAttr = rAttr.map((attr) => {
39
- return runRules(spec.postProps, attr, options)
40
- })
48
+ rAttrsList = rAttrsList.concat(rAttr)
41
49
  } else if (rAttr !== false) {
42
- rAttr = runRules(spec.postProps, rAttr, options)
50
+ rAttrsList.push(rAttr)
43
51
  }
52
+ })
53
+ el.attrsList = rAttrsList
54
+ el.attrsMap = require('../../template-compiler/compiler').makeAttrsMap(rAttrsList)
55
+ // 前置处理attrs,便于携带信息用于tag的处理
56
+ const rTag = cfg[mode] && cfg[mode].call(this, el.tag, data)
57
+ if (rTag) {
58
+ el.tag = rTag
44
59
  }
45
- // 生成目标attrsList
46
- if (Array.isArray(rAttr)) {
47
- rAttrsList = rAttrsList.concat(rAttr)
48
- } else if (rAttr !== false) {
49
- rAttrsList.push(rAttr)
50
- }
51
- })
52
- el.attrsList = rAttrsList
53
- el.attrsMap = require('../../template-compiler/compiler').makeAttrsMap(rAttrsList)
54
- // 前置处理attrs,便于携带信息用于tag的处理
55
- const rTag = cfg[mode] && cfg[mode].call(this, el.tag, data)
56
- if (rTag) {
57
- el.tag = rTag
60
+ return el
58
61
  }
59
- return el
60
- }
61
62
  })
62
63
  return result
63
64
  })
@@ -14,7 +14,7 @@ web的额外逻辑,因为小程序组件和web存在差异,比如事件相
14
14
 
15
15
  Mpx的转换一个重要原则是转不了的东西通过控制台打印提示用户,要求用户提供一份符合对应平台的代码通过条件编译支持。因此错误输出格式保持一致是有必要的。
16
16
 
17
- 在 index.js 中,会汇总每个组件的转换规则函数,为了使错误信息标准化,一致化,错误打印函数的生成函数实现在index.js里。
17
+ 在 index.web.js 中,会汇总每个组件的转换规则函数,为了使错误信息标准化,一致化,错误打印函数的生成函数实现在index.js里。
18
18
 
19
19
  每个组件文件是一个方法,接受错误打印生成方法,根据组件名生成对应的错误打印方法。
20
20
 
@@ -1,5 +1,4 @@
1
- const templateCompiler = require('../../../../template-compiler/compiler')
2
- const parseMustache = templateCompiler.parseMustache
1
+ const { parseMustache } = require('../../../../template-compiler/compiler')
3
2
  const normalize = require('../../../../utils/normalize')
4
3
  const TAG_NAME = 'component'
5
4
 
@@ -0,0 +1,21 @@
1
+ const { isOriginTag, isBuildInTag } = require('../../../../utils/dom-tag-config')
2
+
3
+ module.exports = function () {
4
+ return {
5
+ waterfall: true,
6
+ skipNormalize: true,
7
+ supportedModes: ['web'],
8
+ test: (input) => isOriginTag(input) || isBuildInTag(input),
9
+ // 输出web时对组件名进行转义避免与原生tag和内建tag冲突
10
+ web (el, data) {
11
+ const newTag = `mpx-com-${el.tag}`
12
+ const usingComponents = data.usingComponents || []
13
+ // 当前组件名与原生tag或内建tag同名,对组件名进行转义
14
+ // json转义见:platform/json/wx/index.js fixComponentName
15
+ if (usingComponents.includes(newTag)) {
16
+ el.tag = newTag
17
+ }
18
+ return el
19
+ }
20
+ }
21
+ }
@@ -1,14 +1,10 @@
1
1
  const { capitalToHyphen } = require('../../../../utils/string')
2
2
 
3
3
  module.exports = function () {
4
- function convertTagName (name) {
5
- return capitalToHyphen(name)
6
- }
7
-
8
4
  return {
9
5
  // tag name contains capital letters
10
6
  test: /[A-Z]/,
11
- ali: convertTagName,
12
- swan: convertTagName
7
+ ali: capitalToHyphen,
8
+ swan: capitalToHyphen
13
9
  }
14
10
  }
@@ -8,7 +8,7 @@ const checkbox = require('./checkbox')
8
8
  const coverImage = require('./cover-image')
9
9
  const coverView = require('./cover-view')
10
10
  const form = require('./form')
11
- const HyphenTagName = require('./hypen-tag-name')
11
+ const hyphenTagName = require('./hypen-tag-name')
12
12
  const icon = require('./icon')
13
13
  const image = require('./image')
14
14
  const input = require('./input')
@@ -33,12 +33,13 @@ const switchComponent = require('./switch')
33
33
  const template = require('./template')
34
34
  const text = require('./text')
35
35
  const textarea = require('./textarea')
36
- const Nonsupport = require('./unsupported')
36
+ const unsupported = require('./unsupported')
37
37
  const video = require('./video')
38
38
  const view = require('./view')
39
39
  const webView = require('./web-view')
40
40
  const wxs = require('./wxs')
41
41
  const component = require('./component')
42
+ const fixComponentName = require('./fix-component-name')
42
43
 
43
44
  module.exports = function getComponentConfigs ({ warn, error }) {
44
45
  /**
@@ -79,7 +80,8 @@ module.exports = function getComponentConfigs ({ warn, error }) {
79
80
 
80
81
  // 转换规则只需以微信为基准配置微信和支付宝的差异部分,比如微信和支付宝都支持但是写法不一致,或者微信支持而支付宝不支持的部分(抛出错误或警告)
81
82
  return [
82
- ...Nonsupport({ print }),
83
+ ...unsupported({ print }),
84
+ fixComponentName({ print }),
83
85
  ad({ print }),
84
86
  view({ print }),
85
87
  scrollView({ print }),
@@ -118,7 +120,7 @@ module.exports = function getComponentConfigs ({ warn, error }) {
118
120
  camera({ print }),
119
121
  livePlayer({ print }),
120
122
  livePusher({ print }),
121
- HyphenTagName({ print }),
123
+ hyphenTagName({ print }),
122
124
  component()
123
125
  ]
124
126
  }
@@ -41,18 +41,7 @@ module.exports = function ({ print }) {
41
41
  // 快应用通用事件有touchstart|touchmove|touchend|touchcancel|longpress|click|focus|blur
42
42
  event: [
43
43
  {
44
- // 支付宝中的view组件额外支持了transitionEnd|animationStart|animationIteration|animationEnd,故在此声明了组件事件转换逻辑
45
44
  test: /^(transitionend|animationstart|animationiteration|animationend)$/,
46
- //
47
- ali (eventName) {
48
- const eventMap = {
49
- transitionend: 'transitionEnd',
50
- animationstart: 'animationStart',
51
- animationiteration: 'animationIteration',
52
- animationend: 'animationEnd'
53
- }
54
- return eventMap[eventName]
55
- },
56
45
  qa: qaEventLogError
57
46
  }
58
47
  ]
@@ -3,9 +3,7 @@ const JSON5 = require('json5')
3
3
  const getComponentConfigs = require('./component-config')
4
4
  const normalizeComponentRules = require('../normalize-component-rules')
5
5
  const isValidIdentifierStr = require('../../../utils/is-valid-identifier-str')
6
- const templateCompiler = require('../../../template-compiler/compiler')
7
- const parseMustache = templateCompiler.parseMustache
8
- const stringifyWithResolveComputed = templateCompiler.stringifyWithResolveComputed
6
+ const { parseMustacheWithContext, stringifyWithResolveComputed } = require('../../../template-compiler/compiler')
9
7
  const normalize = require('../../../utils/normalize')
10
8
 
11
9
  module.exports = function getSpec ({ warn, error }) {
@@ -17,10 +15,10 @@ module.exports = function getSpec ({ warn, error }) {
17
15
  postProps: [
18
16
  {
19
17
  web ({ name, value }) {
20
- const parsed = parseMustache(value)
18
+ const parsed = parseMustacheWithContext(value)
21
19
  if (parsed.hasBinding) {
22
20
  return {
23
- name: name === 'animation' ? 'v-' + name : ':' + name,
21
+ name: name === 'animation' ? 'v-animation' : ':' + name,
24
22
  value: parsed.result
25
23
  }
26
24
  }
@@ -34,7 +32,7 @@ module.exports = function getSpec ({ warn, error }) {
34
32
  test: 'wx:for',
35
33
  swan (obj, data) {
36
34
  const attrsMap = data.el.attrsMap
37
- const parsed = parseMustache(obj.value)
35
+ const parsed = parseMustacheWithContext(obj.value)
38
36
  let listName = parsed.result
39
37
  const el = data.el
40
38
 
@@ -48,7 +46,7 @@ module.exports = function getSpec ({ warn, error }) {
48
46
  }
49
47
 
50
48
  if (keyName) {
51
- const parsed = parseMustache(keyName)
49
+ const parsed = parseMustacheWithContext(keyName)
52
50
  if (parsed.hasBinding) {
53
51
  // keyStr = ` trackBy ${parsed.result.slice(1, -1)}`
54
52
  } else if (keyName === '*this') {
@@ -78,7 +76,7 @@ module.exports = function getSpec ({ warn, error }) {
78
76
  }
79
77
  },
80
78
  web ({ value }, { el }) {
81
- const parsed = parseMustache(value)
79
+ const parsed = parseMustacheWithContext(value)
82
80
  const attrsMap = el.attrsMap
83
81
  const itemName = attrsMap['wx:for-item'] || 'item'
84
82
  const indexName = attrsMap['wx:for-index'] || 'index'
@@ -190,17 +188,9 @@ module.exports = function getSpec ({ warn, error }) {
190
188
  }
191
189
  const styleBinding = []
192
190
  el.isStyleParsed = true
193
- el.attrsList.forEach((item) => {
194
- const parsed = parseMustache(item.value)
195
- if (item.name === 'style') {
196
- if (parsed.hasBinding || parsed.result.indexOf('rpx') > -1) {
197
- styleBinding.push(parseMustache(item.value).result)
198
- } else {
199
- styleBinding.push(JSON.stringify(item.value))
200
- }
201
- } else if (item.name === 'wx:style') {
202
- styleBinding.push(parseMustache(item.value).result)
203
- }
191
+ el.attrsList.filter(item => this.test.test(item.name)).forEach((item) => {
192
+ const parsed = parseMustacheWithContext(item.value)
193
+ styleBinding.push(parsed.result)
204
194
  })
205
195
  return {
206
196
  name: ':style',
@@ -210,12 +200,20 @@ module.exports = function getSpec ({ warn, error }) {
210
200
  },
211
201
  {
212
202
  // 样式类名绑定
213
- test: /^wx:(class)$/,
214
- web ({ value }) {
215
- const parsed = parseMustache(value)
203
+ test: /^(class|wx:class)$/,
204
+ web ({ value }, { el }) {
205
+ if (el.isClassParsed) {
206
+ return false
207
+ }
208
+ const classBinding = []
209
+ el.isClassParsed = true
210
+ el.attrsList.filter(item => this.test.test(item.name)).forEach((item) => {
211
+ const parsed = parseMustacheWithContext(item.value)
212
+ classBinding.push(parsed.result)
213
+ })
216
214
  return {
217
215
  name: ':class',
218
- value: parsed.result
216
+ value: `[${classBinding}]`
219
217
  }
220
218
  }
221
219
  },
@@ -266,7 +264,7 @@ module.exports = function getSpec ({ warn, error }) {
266
264
  },
267
265
  web ({ name, value }) {
268
266
  let dir = this.test.exec(name)[1]
269
- const parsed = parseMustache(value)
267
+ const parsed = parseMustacheWithContext(value)
270
268
  if (dir === 'elif') {
271
269
  dir = 'else-if'
272
270
  }
@@ -295,18 +293,39 @@ module.exports = function getSpec ({ warn, error }) {
295
293
  },
296
294
  swan ({ name, value }, { eventRules }) {
297
295
  const match = this.test.exec(name)
296
+ const prefix = match[1]
298
297
  const eventName = match[2]
299
- runRules(eventRules, eventName, { mode: 'swan' })
298
+ const modifierStr = match[3] || ''
299
+ const rPrefix = runRules(spec.event.prefix, prefix, { mode: 'swan' })
300
+ const rEventName = runRules(eventRules, eventName, { mode: 'swan' })
301
+ return {
302
+ name: rPrefix + rEventName + modifierStr,
303
+ value
304
+ }
300
305
  },
301
306
  qq ({ name, value }, { eventRules }) {
302
307
  const match = this.test.exec(name)
308
+ const prefix = match[1]
303
309
  const eventName = match[2]
304
- runRules(eventRules, eventName, { mode: 'qq' })
310
+ const modifierStr = match[3] || ''
311
+ const rPrefix = runRules(spec.event.prefix, prefix, { mode: 'qq' })
312
+ const rEventName = runRules(eventRules, eventName, { mode: 'qq' })
313
+ return {
314
+ name: rPrefix + rEventName + modifierStr,
315
+ value
316
+ }
305
317
  },
306
318
  jd ({ name, value }, { eventRules }) {
307
319
  const match = this.test.exec(name)
320
+ const prefix = match[1]
308
321
  const eventName = match[2]
309
- runRules(eventRules, eventName, { mode: 'jd' })
322
+ const modifierStr = match[3] || ''
323
+ const rPrefix = runRules(spec.event.prefix, prefix, { mode: 'jd' })
324
+ const rEventName = runRules(eventRules, eventName, { mode: 'jd' })
325
+ return {
326
+ name: rPrefix + rEventName + modifierStr,
327
+ value
328
+ }
310
329
  },
311
330
  // tt ({ name, value }, { eventRules }) {
312
331
  // const match = this.test.exec(name)
@@ -322,15 +341,33 @@ module.exports = function getSpec ({ warn, error }) {
322
341
  // },
323
342
  tt ({ name, value }, { eventRules }) {
324
343
  const match = this.test.exec(name)
344
+ const prefix = match[1]
325
345
  const eventName = match[2]
326
- runRules(eventRules, eventName, { mode: 'tt' })
346
+ const modifierStr = match[3] || ''
347
+ const rPrefix = runRules(spec.event.prefix, prefix, { mode: 'tt' })
348
+ const rEventName = runRules(eventRules, eventName, { mode: 'tt' })
349
+ return {
350
+ name: rPrefix + rEventName + modifierStr,
351
+ value
352
+ }
327
353
  },
328
354
  dd ({ name, value }, { eventRules }) {
329
355
  const match = this.test.exec(name)
356
+ const prefix = match[1]
330
357
  const eventName = match[2]
331
- runRules(eventRules, eventName, { mode: 'dd' })
358
+ const modifierStr = match[3] || ''
359
+ const rPrefix = runRules(spec.event.prefix, prefix, { mode: 'dd' })
360
+ const rEventName = runRules(eventRules, eventName, { mode: 'dd' })
361
+ return {
362
+ name: rPrefix + rEventName + modifierStr,
363
+ value
364
+ }
332
365
  },
333
- web ({ name, value }, { eventRules, el }) {
366
+ web ({ name, value }, { eventRules, el, usingComponents }) {
367
+ if (parseMustacheWithContext(value).hasBinding) {
368
+ error('Web environment does not support mustache binding in event props!')
369
+ return
370
+ }
334
371
  const match = this.test.exec(name)
335
372
  const prefix = match[1]
336
373
  const eventName = match[2]
@@ -338,10 +375,11 @@ module.exports = function getSpec ({ warn, error }) {
338
375
  const meta = {
339
376
  modifierStr
340
377
  }
378
+ const isComponent = usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component'
341
379
  // 记录event监听信息用于后续判断是否需要使用内置基础组件
342
380
  el.hasEvent = true
343
381
  const rPrefix = runRules(spec.event.prefix, prefix, { mode: 'web', meta })
344
- const rEventName = runRules(eventRules, eventName, { mode: 'web' })
382
+ const rEventName = runRules(eventRules, eventName, { mode: 'web', data: { isComponent } })
345
383
  return {
346
384
  name: rPrefix + rEventName + meta.modifierStr,
347
385
  value
@@ -411,7 +449,11 @@ module.exports = function getSpec ({ warn, error }) {
411
449
  touchcancel: 'touchCancel',
412
450
  tap: 'tap',
413
451
  longtap: 'longTap',
414
- longpress: 'longTap'
452
+ longpress: 'longTap',
453
+ transitionend: 'transitionEnd',
454
+ animationstart: 'animationStart',
455
+ animationiteration: 'animationIteration',
456
+ animationend: 'animationEnd'
415
457
  }
416
458
  if (eventMap[eventName]) {
417
459
  return eventMap[eventName]
@@ -424,6 +466,16 @@ module.exports = function getSpec ({ warn, error }) {
424
466
  error(`Web environment does not support [${eventName}] event!`)
425
467
  }
426
468
  }
469
+ },
470
+ // 特殊web事件
471
+ {
472
+ test: /^click$/,
473
+ web (eventName, data) {
474
+ // 自定义组件根节点
475
+ if (data.isComponent) {
476
+ return '_' + eventName
477
+ }
478
+ }
427
479
  }
428
480
  ]
429
481
  }
@@ -48,11 +48,19 @@ span {
48
48
  white-space: pre-line;
49
49
  }
50
50
 
51
- html, body, .app {
51
+ html, body, #app {
52
+ display: block;
52
53
  width: 100%;
53
54
  height: 100%;
54
55
  }
55
56
 
57
+ page {
58
+ display: block;
59
+ width: 100%;
60
+ height: 100%;
61
+ background-color: #fff;
62
+ }
63
+
56
64
  .pull-down-loading {
57
65
  position: absolute;
58
66
  width: 100%;
@@ -120,8 +128,3 @@ html, body, .app {
120
128
  font-family "weui"
121
129
  src url('data:application/octet-stream;base64,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') format('truetype')
122
130
  }
123
-
124
- .mpx-root-view {
125
- display: inline
126
- line-height: normal
127
- }
@@ -1,3 +1,12 @@
1
+ const {
2
+ isRichTextTag,
3
+ isUnaryTag,
4
+ isSpace,
5
+ isContWidth,
6
+ isContHeight,
7
+ isContConRow
8
+ } = require('../../../utils/dom-tag-config')
9
+
1
10
  // eslint-disable-next-line
2
11
  const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/ // useless escape
3
12
  const ncname = '[a-zA-Z_][\\w\\-\\.]*'
@@ -11,36 +20,6 @@ const comment = /^<!\--/
11
20
  const invalidAttributeRE = /[\s"'<>\/=]/
12
21
  let currentParent
13
22
 
14
- function makeMap (str, expectsLowerCase) {
15
- const map = Object.create(null)
16
- const list = str.split(',')
17
- for (let i = 0; i < list.length; i++) {
18
- map[list[i]] = true
19
- }
20
- return expectsLowerCase
21
- ? val => map[val.toLowerCase()]
22
- : val => map[val]
23
- }
24
-
25
- const isRichTextTag = makeMap(
26
- 'a,abbr,address,article,aside,b,bdi,bdo,big,blockquote,br,caption,' +
27
- 'center,cite,code,col,colgroup,dd,del,div,dl,dt,em,fieldset,' +
28
- 'font,footer,h1,h2,h3,h4,h5,h6,header,hr,i,img,ins,label,legend,' +
29
- 'li,mark,nav,ol,p,pre,q,rt,ruby,s,section,small,span,strong,sub,sup,' +
30
- 'table,tbody,td,tfoot,th,thead,tr,tt,u,ul'
31
- )
32
- const isUnaryTag = makeMap(
33
- 'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
34
- 'link,meta,param,source,track,wbr'
35
- )
36
- const isSpace = makeMap('ensp,emsp,nbsp')
37
-
38
- const isContWidth = makeMap('col,colgroup,img,table,td,th,tr')
39
-
40
- const isContHeight = makeMap('img,td,th,tr')
41
-
42
- const isContConRow = makeMap('td,th,tr')
43
-
44
23
  function makeAttrsMap (attrs) {
45
24
  const map = {}
46
25
  for (let i = 0, l = attrs.length; i < l; i++) {