@mpxjs/webpack-plugin 2.8.22 → 2.8.23-alpha

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 (38) hide show
  1. package/README.md +1 -1
  2. package/lib/config.js +14 -0
  3. package/lib/dependencies/AddEntryDependency.js +24 -0
  4. package/lib/dependencies/ResolveDependency.js +4 -0
  5. package/lib/index.js +35 -5
  6. package/lib/loader.js +40 -0
  7. package/lib/platform/template/wx/component-config/button.js +14 -2
  8. package/lib/platform/template/wx/component-config/image.js +4 -0
  9. package/lib/platform/template/wx/component-config/input.js +4 -0
  10. package/lib/platform/template/wx/component-config/rich-text.js +4 -0
  11. package/lib/platform/template/wx/component-config/scroll-view.js +4 -0
  12. package/lib/platform/template/wx/component-config/switch.js +4 -0
  13. package/lib/platform/template/wx/component-config/text.js +4 -0
  14. package/lib/platform/template/wx/component-config/textarea.js +5 -0
  15. package/lib/platform/template/wx/component-config/view.js +4 -0
  16. package/lib/platform/template/wx/index.js +121 -1
  17. package/lib/resolve-loader.js +4 -1
  18. package/lib/runtime/components/tenon/getInnerListeners.js +314 -0
  19. package/lib/runtime/components/tenon/tenon-button.vue +305 -0
  20. package/lib/runtime/components/tenon/tenon-image.vue +61 -0
  21. package/lib/runtime/components/tenon/tenon-input.vue +104 -0
  22. package/lib/runtime/components/tenon/tenon-rich-text.vue +21 -0
  23. package/lib/runtime/components/tenon/tenon-scroll-view.vue +124 -0
  24. package/lib/runtime/components/tenon/tenon-switch.vue +91 -0
  25. package/lib/runtime/components/tenon/tenon-text-area.vue +77 -0
  26. package/lib/runtime/components/tenon/tenon-text.vue +64 -0
  27. package/lib/runtime/components/tenon/tenon-view.vue +93 -0
  28. package/lib/runtime/optionProcessor.tenon.js +388 -0
  29. package/lib/style-compiler/index.js +1 -1
  30. package/lib/style-compiler/plugins/hm.js +20 -0
  31. package/lib/template-compiler/compiler.js +11 -2
  32. package/lib/tenon/index.js +104 -0
  33. package/lib/tenon/processJSON.js +356 -0
  34. package/lib/tenon/processScript.js +262 -0
  35. package/lib/tenon/processStyles.js +21 -0
  36. package/lib/tenon/processTemplate.js +133 -0
  37. package/lib/utils/get-relative-path.js +25 -0
  38. package/package.json +5 -2
@@ -0,0 +1,314 @@
1
+ import { isEmptyObject } from '../../utils'
2
+
3
+ const tapEvents = [
4
+ 'onTouchstart',
5
+ 'onTouchmove',
6
+ 'onTouchcancel',
7
+ 'onTouchend',
8
+ 'onLongtap'
9
+ ]
10
+
11
+ function createTouch (context, hasLongTap, __mpxTapInfo) {
12
+ return ({
13
+ onTouch (e) {
14
+ // 用touch模拟longtap
15
+ switch (e.state) {
16
+ case 1:
17
+ context.$emit('touchstart', e)
18
+ __mpxTapInfo.detail = {
19
+ x: e.position.x,
20
+ y: e.position.y
21
+ }
22
+ __mpxTapInfo.startTimer = null
23
+
24
+ if (hasLongTap) {
25
+ __mpxTapInfo.startTimer = setTimeout(() => {
26
+ if (hasLongTap) {
27
+ const re = inheritEvent(
28
+ 'longtap',
29
+ e,
30
+ __mpxTapInfo.detail
31
+ )
32
+ context.$emit('longtap', re)
33
+ __mpxTapInfo.startTimer = null
34
+ }
35
+ }, 350)
36
+ }
37
+
38
+ break
39
+ case 2:
40
+ context.$emit('touchmove', e)
41
+ if (
42
+ Math.abs(e.position.x - __mpxTapInfo.detail.x) > 1 ||
43
+ Math.abs(e.position.y - __mpxTapInfo.detail.y) > 1
44
+ ) {
45
+ __mpxTapInfo.startTimer &&
46
+ clearTimeout(__mpxTapInfo.startTimer)
47
+ __mpxTapInfo.startTimer = null
48
+ }
49
+ break
50
+ case 3:
51
+ context.$emit('touchend', e)
52
+ __mpxTapInfo.startTimer &&
53
+ clearTimeout(__mpxTapInfo.startTimer)
54
+ __mpxTapInfo.startTimer = null
55
+ break
56
+ case 4:
57
+ context.$emit('touchcancel', e)
58
+ break
59
+ }
60
+ }
61
+ })
62
+ }
63
+
64
+ function processOriginEvent (listeners) {
65
+ // 给event添加_originEvent属性
66
+ const ignoreEvents = ['onTap', 'onFocus', 'onChange', 'onBlur', 'onConfirm']
67
+ Object.keys(listeners).forEach((key) => {
68
+ if (!ignoreEvents.includes(key)) {
69
+ const listener = listeners[key]
70
+ listeners[key] = function (e) {
71
+ if (e) {
72
+ e._originEvent = { ...e }
73
+ }
74
+ listener.call(this, e)
75
+ }
76
+ }
77
+ })
78
+ }
79
+
80
+ function processModel (listeners, context) {
81
+ // 该函数只有wx:model的情况下才调用,而且默认e.detail.value有值
82
+ // 该函数必须在产生merge前执行
83
+ // todo 此处对于$attrs的访问会导致父组件更新时子组件必然更新,暂时用短路效应避免影响,待优化
84
+ // todo 访问$listeners也会导致上述现象,但是为了事件代理还必须访问$listeners,待后续思考处理
85
+
86
+ const modelEvent = context.$attrs.mpxModelEvent
87
+ const modelEventId = context.$attrs.mpxModelEventId
88
+ if (modelEvent && modelEventId) {
89
+ // 对于modelEvent,内部获得时间后向外部转发,触发外部listener的同时转发为mpxModel事件
90
+
91
+ const listener = listeners.onInput
92
+
93
+ listeners.onInput = function (e) {
94
+ Hummer.notifyCenter.triggerEvent(modelEventId, {
95
+ detail: e
96
+ })
97
+ context.$emit('mpxModel', {
98
+ detail: e
99
+ })
100
+ listener && listener.call(this, e)
101
+ }
102
+ // 内部listener不需要mpxModel
103
+ delete listeners.mpxModel
104
+ }
105
+ }
106
+
107
+ function mergeListeners (listeners, otherListeners, options = {}, context, __mpxTapInfo) {
108
+ if (!otherListeners) {
109
+ return
110
+ }
111
+ // "onTouchstart",
112
+ // "onTouchmove",
113
+ // "onTouchcancel",
114
+ // "onTouchend",
115
+ // "onLongtap",
116
+
117
+ // 都依赖touch事件 如果listener没有touch事件 如果是force需要强行添加一个touch事件 longTap需要根据context
118
+ // 特殊处理
119
+ const listenerMap = {}
120
+ tapEvents.forEach((eventName) => {
121
+ if (listeners[eventName]) {
122
+ listenerMap[eventName] = true
123
+ delete listeners[eventName]
124
+ }
125
+ })
126
+ // const otherListenerKeys = Object.keys(otherListeners)
127
+ // for (let key of otherListenerKeys) {
128
+
129
+ // }
130
+
131
+ Object.keys(otherListeners).forEach((key) => {
132
+ const listener = otherListeners[key]
133
+ let rawListener
134
+ if (tapEvents.includes(key)) {
135
+ // 判断onTouch是否存在 若存在 则直接处理
136
+ rawListener = listeners.onTouch
137
+
138
+ if (!rawListener && !options.force) {
139
+ return
140
+ } else if (!rawListener && options.force) {
141
+ // 创建一个touh事件 并赋值
142
+ listeners.onTouch = createTouch(context, listenerMap.onLongtap, __mpxTapInfo).onTouch
143
+ rawListener = listeners.onTouch
144
+ }
145
+ // 事件处理 onTouchstart 1 onTouchmove 2 onTouchend 3 onTouchcancel 4
146
+ listeners.onTouch = function (e) {
147
+ // const thatKey = key
148
+ let timer = null
149
+ if (key === 'onLongtap') {
150
+ if (e.state === 1) {
151
+ // start
152
+ timer = setTimeout(
153
+ () => {
154
+ listener.call(this, e)
155
+ },
156
+ options.before ? 340 : 360
157
+ )
158
+ } else if (e.state === 3) {
159
+ timer && clearTimeout(timer)
160
+ timer = null
161
+ }
162
+ } else {
163
+ if (options.before) {
164
+ if (key === 'onTouchstart' && e.state === 1) {
165
+ listener.call(this, e)
166
+ } else if (key === 'onTouchmove' && e.state === 2) {
167
+ listener.call(this, e)
168
+ } else if (key === 'onTouchend' && e.state === 3) {
169
+ listener.call(this, e)
170
+ } else if (key === 'onTouchcancel' && e.state === 4) {
171
+ listener.call(this, e)
172
+ }
173
+ rawListener.call(this, e)
174
+ } else {
175
+ rawListener.call(this, e)
176
+ if (key === 'onTouchstart' && e.state === 1) {
177
+ listener.call(this, e)
178
+ } else if (key === 'onTouchmove' && e.state === 2) {
179
+ listener.call(this, e)
180
+ } else if (key === 'onTouchend' && e.state === 3) {
181
+ listener.call(this, e)
182
+ } else if (key === 'onTouchcancel' && e.state === 4) {
183
+ listener.call(this, e)
184
+ }
185
+ }
186
+ }
187
+ }
188
+ } else {
189
+ rawListener = listeners[key]
190
+ if (!rawListener) {
191
+ if (options.force) {
192
+ listeners[key] = listener
193
+ }
194
+ } else {
195
+ listeners[key] = function (e) {
196
+ if (options.before) {
197
+ listener.call(this, e)
198
+ rawListener.call(this, e)
199
+ } else {
200
+ rawListener.call(this, e)
201
+ listener.call(this, e)
202
+ }
203
+ }
204
+ }
205
+ }
206
+ })
207
+ }
208
+ // 没有tap 用touch模拟 touchstart touchmove touchcancel touchend tap longpress langtap
209
+ function processTouchAndLtap (listeners, context, __mpxTapInfo) {
210
+ const listenerMap = {}
211
+ tapEvents.forEach((eventName) => {
212
+ if (listeners[eventName]) {
213
+ listenerMap[eventName] = true
214
+ delete listeners[eventName]
215
+ }
216
+ })
217
+ if (isEmptyObject(listenerMap)) return
218
+ const events = createTouch(context, listenerMap.onLongtap, __mpxTapInfo)
219
+ mergeListeners(
220
+ listeners,
221
+ events,
222
+ {
223
+ force: true
224
+ },
225
+ context,
226
+ __mpxTapInfo
227
+ )
228
+ }
229
+
230
+ export function extendEvent (e, extendObj = {}) {
231
+ Object.keys(extendObj).forEach((key) => {
232
+ Object.defineProperty(e, key, {
233
+ value: extendObj[key],
234
+ enumerable: true,
235
+ configurable: true,
236
+ writable: true
237
+ })
238
+ })
239
+ }
240
+
241
+ export function inheritEvent (type, oe, detail = {}) {
242
+ detail = Object.assign({}, oe.detail, detail)
243
+ const ne = getCustomEvent(type, detail)
244
+ extendEvent(ne, {
245
+ timeStamp: oe.timeStamp,
246
+ target: oe.target,
247
+ currentTarget: oe.currentTarget,
248
+ stopPropagation: oe.stopPropagation.bind(oe),
249
+ preventDefault: oe.preventDefault.bind(oe)
250
+ })
251
+ return ne
252
+ }
253
+
254
+ export function getCustomEvent (type, detail = {}, target = null) {
255
+ return {
256
+ type,
257
+ detail,
258
+ target,
259
+ timeStamp: new Date().valueOf()
260
+ }
261
+ }
262
+
263
+ function noop () {}
264
+
265
+ function getListeners (context) {
266
+ const attrs = context.$attrs
267
+ const listeners = {}
268
+ Object.keys(attrs).forEach((v) => {
269
+ if (/^on[A-Z]/.test(v)) {
270
+ listeners[v] = attrs[v]
271
+ }
272
+ })
273
+ return listeners
274
+ }
275
+
276
+ export default function getInnerListeners (context, options = {}) {
277
+ let {
278
+ mergeBefore = {},
279
+ mergeAfter = {},
280
+ defaultListeners = [],
281
+ ignoredListeners = []
282
+ } = options
283
+ const __mpxTapInfo = {}
284
+ // 从attrs里面拿到以on开头的所有绑定的事件
285
+ const listeners = Object.assign({}, getListeners(context))
286
+ defaultListeners.forEach((key) => {
287
+ if (!listeners[key]) listeners[key] = noop
288
+ })
289
+ const mergeBeforeOptions = {
290
+ before: true
291
+ }
292
+ const mergeAfterOptions = {
293
+ before: false
294
+ }
295
+
296
+ if (mergeBefore.listeners) {
297
+ mergeBeforeOptions.force = mergeBefore.force
298
+ mergeBefore = mergeBefore.listeners
299
+ }
300
+
301
+ if (mergeAfter.listeners) {
302
+ mergeAfterOptions.force = mergeAfter.force
303
+ mergeAfter = mergeAfter.listeners
304
+ }
305
+ processOriginEvent(listeners)
306
+ processModel(listeners, context)
307
+ processTouchAndLtap(listeners, context, __mpxTapInfo)
308
+ mergeListeners(listeners, mergeBefore, mergeBeforeOptions, context, __mpxTapInfo)
309
+ mergeListeners(listeners, mergeAfter, mergeAfterOptions, context, __mpxTapInfo)
310
+ ignoredListeners.forEach((key) => {
311
+ delete listeners[key]
312
+ })
313
+ return listeners
314
+ }
@@ -0,0 +1,305 @@
1
+ <script>
2
+ import { h } from "@hummer/tenon-vue";
3
+ import getInnerListeners from "./getInnerListeners";
4
+
5
+ // 获取当前小程序样式版本配置
6
+ const styleVersion = global.__style || "";
7
+ const sizeClassMap = {
8
+ default: "",
9
+ mini: "mpx-button-size-mini",
10
+ };
11
+ const typeClassMap = {
12
+ primary: "mpx-button-type-primary",
13
+ warn: "mpx-button-type-warn",
14
+ };
15
+ const plainClassMap = {
16
+ false: "",
17
+ true: "mpx-button-plain",
18
+ };
19
+ const disabledClassMap = {
20
+ false: "",
21
+ true: "mpx-button-disabled",
22
+ };
23
+ const clickDisabledClassMap = {
24
+ false: "",
25
+ true: "mpx-button-click-disabled",
26
+ };
27
+ export default (function(){
28
+ return {
29
+ name: "mpx-button",
30
+ data() {
31
+ return {
32
+ hover: false,
33
+ };
34
+ },
35
+ props: {
36
+ name: String,
37
+ size: {
38
+ type: String,
39
+ default: "default",
40
+ },
41
+ type: {
42
+ type: String,
43
+ default: "default",
44
+ },
45
+ plain: Boolean,
46
+ disabled: Boolean,
47
+ loading: Boolean,
48
+ formType: String,
49
+ hoverClass: {
50
+ type: String,
51
+ default: "button-hover",
52
+ },
53
+ hoverStopPropagation: {
54
+ type: Boolean,
55
+ default: false,
56
+ },
57
+ hoverStartTime: {
58
+ type: Number,
59
+ default: 20,
60
+ },
61
+ hoverStayTime: {
62
+ type: Number,
63
+ default: 70,
64
+ },
65
+ },
66
+ computed: {
67
+ className() {
68
+ if (this.hoverClass && this.hoverClass !== "none" && this.hover) {
69
+ return this.hoverClass;
70
+ }
71
+ return "";
72
+ },
73
+ classNameList() {
74
+ let classArr = [];
75
+ if (this.hoverClass && this.hoverClass !== "none" && this.hover) {
76
+ classArr.push(this.hoverClass);
77
+ }
78
+ if (styleVersion === "v2") {
79
+ classArr.push(`${sizeClassMap[this.size]}${styleVersion}`);
80
+ classArr.push(`${typeClassMap[this.type]}${styleVersion}`);
81
+ classArr.push(`mpx-button-version${styleVersion}`);
82
+ } else {
83
+ classArr.push(sizeClassMap[this.size]);
84
+ classArr.push(typeClassMap[this.type]);
85
+ classArr.push(`mpx-button-version`);
86
+ }
87
+ classArr.push(plainClassMap[this.plain]);
88
+ classArr.push(disabledClassMap["" + !!this.disabled]);
89
+ // 禁用click
90
+ classArr.push(clickDisabledClassMap["" + !!this.disabled]);
91
+ return classArr;
92
+ },
93
+ },
94
+ render() {
95
+ let mergeAfter;
96
+ if (this.hoverClass && this.hoverClass !== "none") {
97
+ mergeAfter = {
98
+ listeners: {
99
+ onTouchstart: this.handleTouchstart,
100
+ onTouchend: this.handleTouchend,
101
+ },
102
+ force: true,
103
+ };
104
+ }
105
+ const domProps = {
106
+ disabled: this.disabled,
107
+ plain: this.plain,
108
+ type: this.type,
109
+ };
110
+ const data = {
111
+ class: ["mpx-button", ...this.classNameList],
112
+ ...domProps,
113
+ ...getInnerListeners(this, {
114
+ mergeAfter,
115
+ // 由于当前机制下tap事件只有存在tap监听才会触发,为了确保该组件能够触发tap,传递一个包含tap的defaultListeners用于模拟存在tap监听
116
+ defaultListeners: ["onTap"],
117
+ }),
118
+ };
119
+
120
+ let text = "";
121
+ const nodes = this.$slots.default();
122
+ nodes.forEach((item) => {
123
+ if (item.shapeFlag === 8 && item.children) {
124
+ text += item.children;
125
+ }
126
+ });
127
+ return h("button", data, text);
128
+ },
129
+ methods: {
130
+ handleTouchstart(e) {
131
+ if (e.__hoverStopPropagation) {
132
+ return;
133
+ }
134
+ e.__hoverStopPropagation = this.hoverStopPropagation;
135
+ clearTimeout(this.startTimer);
136
+ this.startTimer = setTimeout(() => {
137
+ this.hover = true;
138
+ }, this.hoverStartTime);
139
+ },
140
+ handleTouchend() {
141
+ clearTimeout(this.endTimer);
142
+ this.endTimer = setTimeout(() => {
143
+ this.hover = false;
144
+ }, this.hoverStayTime);
145
+ },
146
+ },
147
+ }
148
+ })()
149
+ </script>
150
+
151
+
152
+
153
+ <style lang="stylus" scoped>
154
+ .mpx-button-versionv2
155
+ width: 184px
156
+ line-height 1.41176471
157
+ font-weight: 700;
158
+ padding-top 8px
159
+ padding-bottom 8px
160
+ .mpx-button-version
161
+ width: 100%
162
+ line-height 2.55555556
163
+ cursor: pointer
164
+ &:after
165
+ border 1px solid rgba(0,0,0,.2)
166
+
167
+ .mpx-button
168
+ padding-left: 14px
169
+ padding-right: 14px
170
+ border none
171
+ outline: none
172
+ position relative
173
+ display block
174
+ margin-left auto
175
+ margin-right auto
176
+ margin-bottom 10px
177
+ box-sizing border-box
178
+ font-size 18px
179
+ text-align center
180
+ text-decoration none
181
+ border-radius 5px
182
+ -webkit-tap-highlight-color transparent
183
+ overflow hidden
184
+ color #000
185
+ background-color #f8f8f8
186
+ &:after
187
+ content " "
188
+ width 200%
189
+ height 200%
190
+ position absolute
191
+ top 0
192
+ left 0
193
+ -webkit-transform scale(.5)
194
+ transform scale(.5)
195
+ -webkit-transform-origin 0 0
196
+ transform-origin 0 0
197
+ box-sizing border-box
198
+ border-radius 10px
199
+
200
+ &.button-hover
201
+ background-color #dedede
202
+
203
+ /* 默认版本 size=mini style */
204
+ &.mpx-button-size-mini
205
+ display inline-block
206
+ line-height 2.3
207
+ font-size 13px
208
+ padding 0 1.34em
209
+ width auto
210
+ /* v2 size=mini style */
211
+ &.mpx-button-size-miniv2
212
+ width auto
213
+ padding 0 0.75em
214
+ line-height 2
215
+ font-size 16px
216
+ display inline-block
217
+ &.mpx-button-plain
218
+ color #353535
219
+ border 1px solid #353535
220
+ background-color transparent
221
+ &.mpx-button-plain.button-hover
222
+ background-color rgba(0, 0, 0, 0)
223
+ color #828282
224
+ border 1px solid #828282
225
+
226
+ /* 默认版本 type=primary style */
227
+ &.mpx-button-type-primary
228
+ background-color #1aad19
229
+ color #fff
230
+ &.mpx-button-type-primary.mpx-button-plain
231
+ color #1aad19
232
+ border-color #1aad19
233
+ background-color #fff
234
+ /* v2 type=primary style */
235
+ &.mpx-button-type-primaryv2
236
+ background-color #07c160
237
+ color #fff
238
+ &.mpx-button-type-primaryv2.button-hover
239
+ color #fff
240
+ background-color #06ad56
241
+ &.mpx-button-type-primaryv2.mpx-button-plain
242
+ color #06ae56
243
+ border-color #179c16
244
+ background-color #fff
245
+ &.mpx-button-type-primaryv2.button-hover.mpx-button-plain
246
+ color #06ae56
247
+ background-color rgba(0, 0, 0, .1)
248
+
249
+ /* 默认版本 type=warn style */
250
+ &.mpx-button-type-warn
251
+ color #fff
252
+ background-color #e64340
253
+ &.mpx-button-type-warn.mpx-button-plain
254
+ color #e64340
255
+ background-color transparent
256
+ border 1px solid #e64340
257
+ /* v2 type=warn style */
258
+ &.mpx-button-type-warnv2
259
+ color #fa5151
260
+ background-color #f2f2f2
261
+ &.mpx-button-type-warnv2.button-hover
262
+ background-color #d9d9d9
263
+ &.mpx-button-type-warnv2.mpx-button-plain
264
+ color #fa5151
265
+ background-color #fff
266
+ border 1px solid #e64340
267
+ &.mpx-button-type-warnv2.button-hover.mpx-button-plain
268
+ color: #f58c8d
269
+ border 1px solid #f58a8b
270
+ background-color #fff
271
+
272
+ &.mpx-button-disabled
273
+ color rgba(0, 0, 0, 0.18) !important
274
+ background-color #fafafa !important
275
+ border 1px solid rgba(0, 0, 0, .2) !important
276
+ &.mpx-button-click-disabled
277
+ pointer-events none
278
+ &.mpx-button-loading
279
+ &.mpx-button-type-warn
280
+ color rgba(255,255,255,.6)
281
+ background-color #ce3c39
282
+ &.mpx-button-type-warnv2
283
+ background-color #d9d9d9
284
+ color #fa5151
285
+ &.mpx-button-type-primary
286
+ color: rgba(255,255,255,.6);
287
+ background-color: #179b16;
288
+ &:before
289
+ content: " "
290
+ display: inline-block
291
+ width: 18px
292
+ height: 18px
293
+ vertical-align: middle
294
+ -webkit-animation: mpxButton 1s steps(12,end) infinite
295
+ animation: mpxButton 1s steps(12,end) infinite
296
+ background transparent url('data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iciIgd2lkdGg9JzEyMHB4JyBoZWlnaHQ9JzEyMHB4JyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICAgIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJub25lIiBjbGFzcz0iYmsiPjwvcmVjdD4KICAgIDxyZWN0IHg9JzQ2LjUnIHk9JzQwJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgcng9JzUnIHJ5PSc1JyBmaWxsPScjRTlFOUU5JwogICAgICAgICAgdHJhbnNmb3JtPSdyb3RhdGUoMCA1MCA1MCkgdHJhbnNsYXRlKDAgLTMwKSc+CiAgICA8L3JlY3Q+CiAgICA8cmVjdCB4PSc0Ni41JyB5PSc0MCcgd2lkdGg9JzcnIGhlaWdodD0nMjAnIHJ4PSc1JyByeT0nNScgZmlsbD0nIzk4OTY5NycKICAgICAgICAgIHRyYW5zZm9ybT0ncm90YXRlKDMwIDUwIDUwKSB0cmFuc2xhdGUoMCAtMzApJz4KICAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0naW5kZWZpbml0ZScvPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyM5Qjk5OUEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSg2MCA1MCA1MCkgdHJhbnNsYXRlKDAgLTMwKSc+CiAgICAgICAgICAgICAgICAgcmVwZWF0Q291bnQ9J2luZGVmaW5pdGUnLz4KICAgIDwvcmVjdD4KICAgIDxyZWN0IHg9JzQ2LjUnIHk9JzQwJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgcng9JzUnIHJ5PSc1JyBmaWxsPScjQTNBMUEyJwogICAgICAgICAgdHJhbnNmb3JtPSdyb3RhdGUoOTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNBQkE5QUEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxMjAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNCMkIyQjInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxNTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNCQUI4QjknCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxODAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNDMkMwQzEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyMTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNDQkNCQ0InCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyNDAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNEMkQyRDInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyNzAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNEQURBREEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgzMDAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNFMkUyRTInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgzMzAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0Pgo8L3N2Zz4=') no-repeat
297
+ background-size: 100%
298
+ margin -0.2em 0.34em 0 0
299
+
300
+ @keyframes mpxButton
301
+ 0%
302
+ transform: rotate3d(0, 0, 1, 0deg)
303
+ 100%
304
+ transform: rotate3d(0, 0, 1, 360deg)
305
+ </style>
@@ -0,0 +1,61 @@
1
+ <script>
2
+ import { h } from "@hummer/tenon-vue";
3
+ import getInnerListeners from "./getInnerListeners";
4
+
5
+ export default {
6
+ name: "mpx-image",
7
+ props: {
8
+ src: {
9
+ type: String,
10
+ },
11
+ mode: {
12
+ type: String,
13
+ default: "scaleToFill",
14
+ },
15
+ lazyLoad: {
16
+ type: Boolean,
17
+ default: false,
18
+ },
19
+ showMenuByLongpress: {
20
+ type: Boolean,
21
+ default: false,
22
+ },
23
+ },
24
+ render() {
25
+ let resize = "";
26
+ switch (this.mode) {
27
+ case "scaleToFill":
28
+ resize = "stretch";
29
+ break;
30
+ case "aspectFit":
31
+ resize = "contain";
32
+ break;
33
+ case "aspectFill":
34
+ resize = "cover";
35
+ break;
36
+ default:
37
+ resize = "stretch";
38
+ }
39
+ return h("image", {
40
+ class: "mpx-image",
41
+ src: this.src,
42
+ resize,
43
+ ...getInnerListeners(this)
44
+ });
45
+ },
46
+ data() {
47
+ return {};
48
+ },
49
+ pageConfig: {
50
+ canScroll: false,
51
+ },
52
+ methods: {
53
+ },
54
+ };
55
+ </script>
56
+ <style lang="stylus" scoped>
57
+ .mpx-image
58
+ width 300px
59
+ height 225px
60
+ display inline-block
61
+ </style>