@mpxjs/core 2.9.70-alpha.0 → 2.9.70
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.
- package/@types/global.d.ts +1 -1
- package/LICENSE +433 -0
- package/package.json +9 -6
- package/src/convertor/convertor.js +0 -2
- package/src/convertor/getConvertMode.js +0 -1
- package/src/core/proxy.js +8 -9
- package/src/index.js +3 -14
- package/src/observer/reactive.js +4 -3
- package/src/platform/builtInMixins/directiveHelperMixin.ios.js +4 -1
- package/src/platform/builtInMixins/index.js +0 -5
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +1 -1
- package/src/platform/createApp.ios.js +24 -23
- package/src/platform/createApp.js +5 -14
- package/src/platform/env/event.js +108 -0
- package/src/platform/env/index.ios.js +51 -0
- package/src/platform/env/index.js +8 -0
- package/src/platform/env/index.web.js +48 -0
- package/src/{external → platform/env}/vuePlugin.js +1 -1
- package/src/platform/export/index.js +1 -1
- package/src/platform/patch/builtInKeysMap.js +1 -1
- package/src/platform/patch/getDefaultOptions.ios.js +9 -13
- package/src/platform/patch/index.js +3 -3
- package/src/convertor/wxToTenon.js +0 -86
- package/src/external/vue.js +0 -1
- package/src/external/vue.tenon.js +0 -13
- package/src/external/vue.web.js +0 -6
- package/src/platform/builtInMixins/pageStatusMixin.tenon.js +0 -40
- package/src/platform/builtInMixins/proxyEventMixin.tenon.js +0 -46
- package/src/platform/export/apiInject.tenon.js +0 -1
- package/src/platform/export/index.tenon.js +0 -78
- package/src/platform/patch/getDefaultOptions.tenon.js +0 -99
- package/src/platform/patch/lifecycle/index.tenon.js +0 -52
- /package/src/platform/export/{apiInject.js → inject.js} +0 -0
- /package/src/platform/export/{apiInject.web.js → inject.web.js} +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import transferOptions from '../core/transferOptions'
|
|
2
2
|
import builtInKeysMap from './patch/builtInKeysMap'
|
|
3
|
-
import { makeMap, spreadProp,
|
|
3
|
+
import { makeMap, spreadProp, getFocusedNavigation, hasOwn, extend } from '@mpxjs/utils'
|
|
4
4
|
import { mergeLifecycle } from '../convertor/mergeLifecycle'
|
|
5
5
|
import { LIFECYCLE } from '../platform/patch/lifecycle/index'
|
|
6
6
|
import Mpx from '../index'
|
|
7
7
|
import { createElement, memo, useRef, useEffect } from 'react'
|
|
8
8
|
import * as ReactNative from 'react-native'
|
|
9
|
+
import { Image } from 'react-native'
|
|
9
10
|
import { ref } from '../observer/ref'
|
|
10
11
|
|
|
11
12
|
const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
|
|
@@ -80,12 +81,6 @@ export default function createApp (option, config = {}) {
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
global.__mpxAppCbs = global.__mpxAppCbs || {
|
|
84
|
-
show: [],
|
|
85
|
-
hide: [],
|
|
86
|
-
error: []
|
|
87
|
-
}
|
|
88
|
-
|
|
89
84
|
global.__mpxAppLaunched = false
|
|
90
85
|
|
|
91
86
|
global.__mpxAppFocusedState = ref('show')
|
|
@@ -101,14 +96,10 @@ export default function createApp (option, config = {}) {
|
|
|
101
96
|
})
|
|
102
97
|
|
|
103
98
|
if (!global.__mpxAppLaunched) {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
initialRouteName: path.startsWith('/') ? path.slice(1) : path,
|
|
109
|
-
initialParams: queryObj
|
|
110
|
-
})
|
|
111
|
-
}
|
|
99
|
+
const { initialRouteName, initialParams } = Mpx.config.rnConfig.parseAppProps?.(props) || {}
|
|
100
|
+
initialRouteRef.current.initialRouteName = initialRouteName || initialRouteRef.current.initialRouteName
|
|
101
|
+
initialRouteRef.current.initialParams = initialParams || initialRouteRef.current.initialParams
|
|
102
|
+
|
|
112
103
|
global.__mpxAppOnLaunch = (navigation) => {
|
|
113
104
|
global.__mpxAppLaunched = true
|
|
114
105
|
const state = navigation.getState()
|
|
@@ -136,6 +127,9 @@ export default function createApp (option, config = {}) {
|
|
|
136
127
|
if (defaultOptions.onError) {
|
|
137
128
|
global.__mpxAppCbs.error.push(defaultOptions.onError.bind(instance))
|
|
138
129
|
}
|
|
130
|
+
if (defaultOptions.onUnhandledRejection) {
|
|
131
|
+
global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(instance))
|
|
132
|
+
}
|
|
139
133
|
|
|
140
134
|
const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => {
|
|
141
135
|
if (currentState === 'active') {
|
|
@@ -158,7 +152,7 @@ export default function createApp (option, config = {}) {
|
|
|
158
152
|
if (navigation && hasOwn(global.__mpxPageStatusMap, navigation.pageId)) {
|
|
159
153
|
global.__mpxPageStatusMap[navigation.pageId] = 'show'
|
|
160
154
|
}
|
|
161
|
-
} else if (currentState === 'inactive') {
|
|
155
|
+
} else if (currentState === 'inactive' || currentState === 'background') {
|
|
162
156
|
global.__mpxAppCbs.hide.forEach((cb) => {
|
|
163
157
|
cb()
|
|
164
158
|
})
|
|
@@ -187,6 +181,19 @@ export default function createApp (option, config = {}) {
|
|
|
187
181
|
}, [])
|
|
188
182
|
|
|
189
183
|
const { initialRouteName, initialParams } = initialRouteRef.current
|
|
184
|
+
const headerBackImageProps = Mpx.config.rnConfig.headerBackImageProps || null
|
|
185
|
+
const navScreenOpts = {
|
|
186
|
+
// 7.x替换headerBackTitleVisible
|
|
187
|
+
// headerBackButtonDisplayMode: 'minimal',
|
|
188
|
+
headerBackTitleVisible: false,
|
|
189
|
+
// 安卓上会出现初始化时闪现导航条的问题
|
|
190
|
+
headerShown: false
|
|
191
|
+
}
|
|
192
|
+
if (headerBackImageProps) {
|
|
193
|
+
navScreenOpts.headerBackImage = () => {
|
|
194
|
+
return createElement(Image, headerBackImageProps)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
190
197
|
return createElement(SafeAreaProvider,
|
|
191
198
|
null,
|
|
192
199
|
createElement(NavigationContainer,
|
|
@@ -197,13 +204,7 @@ export default function createApp (option, config = {}) {
|
|
|
197
204
|
createElement(Stack.Navigator,
|
|
198
205
|
{
|
|
199
206
|
initialRouteName,
|
|
200
|
-
screenOptions:
|
|
201
|
-
gestureEnabled: true,
|
|
202
|
-
// 7.x替换headerBackTitleVisible
|
|
203
|
-
// headerBackButtonDisplayMode: 'minimal',
|
|
204
|
-
headerBackTitleVisible: false,
|
|
205
|
-
headerMode: 'float'
|
|
206
|
-
}
|
|
207
|
+
screenOptions: navScreenOpts
|
|
207
208
|
},
|
|
208
209
|
...getPageScreens(initialRouteName, initialParams)
|
|
209
210
|
)
|
|
@@ -5,7 +5,7 @@ import { makeMap, spreadProp, isBrowser } from '@mpxjs/utils'
|
|
|
5
5
|
import { mergeLifecycle } from '../convertor/mergeLifecycle'
|
|
6
6
|
import { LIFECYCLE } from '../platform/patch/lifecycle/index'
|
|
7
7
|
import Mpx from '../index'
|
|
8
|
-
import { initAppProvides } from './export/
|
|
8
|
+
import { initAppProvides } from './export/inject'
|
|
9
9
|
|
|
10
10
|
const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
|
|
11
11
|
|
|
@@ -47,11 +47,6 @@ export default function createApp (option, config = {}) {
|
|
|
47
47
|
}
|
|
48
48
|
global.__mpxEnterOptions = options
|
|
49
49
|
this.$options.onLaunch && this.$options.onLaunch.call(this, options)
|
|
50
|
-
global.__mpxAppCbs = global.__mpxAppCbs || {
|
|
51
|
-
show: [],
|
|
52
|
-
hide: [],
|
|
53
|
-
error: []
|
|
54
|
-
}
|
|
55
50
|
if (isBrowser) {
|
|
56
51
|
if (this.$options.onShow) {
|
|
57
52
|
this.$options.onShow.call(this, options)
|
|
@@ -63,16 +58,12 @@ export default function createApp (option, config = {}) {
|
|
|
63
58
|
if (this.$options.onError) {
|
|
64
59
|
global.__mpxAppCbs.error.push(this.$options.onError.bind(this))
|
|
65
60
|
}
|
|
61
|
+
if (this.$options.onUnhandledRejection) {
|
|
62
|
+
global.__mpxAppCbs.rejection.push(this.$options.onUnhandledRejection.bind(this))
|
|
63
|
+
}
|
|
66
64
|
}
|
|
67
65
|
}
|
|
68
66
|
})
|
|
69
|
-
} else if (__mpx_mode__ === 'tenon') {
|
|
70
|
-
// todo add tenon mixins
|
|
71
|
-
builtInMixins.push({
|
|
72
|
-
onLaunch () {
|
|
73
|
-
// console.log('tenon mixins')
|
|
74
|
-
}
|
|
75
|
-
})
|
|
76
67
|
} else {
|
|
77
68
|
builtInMixins.push({
|
|
78
69
|
onLaunch () {
|
|
@@ -85,7 +76,7 @@ export default function createApp (option, config = {}) {
|
|
|
85
76
|
rawOptions.mixins = builtInMixins
|
|
86
77
|
const defaultOptions = filterOptions(spreadProp(mergeOptions(rawOptions, 'app', false), 'methods'), appData)
|
|
87
78
|
|
|
88
|
-
if (__mpx_mode__ === 'web'
|
|
79
|
+
if (__mpx_mode__ === 'web') {
|
|
89
80
|
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
|
|
90
81
|
global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
|
|
91
82
|
global.getApp = function () {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { isBrowser } from '@mpxjs/utils'
|
|
2
|
+
|
|
3
|
+
function extendEvent (e, extendObj = {}) {
|
|
4
|
+
Object.keys(extendObj).forEach((key) => {
|
|
5
|
+
Object.defineProperty(e, key, {
|
|
6
|
+
value: extendObj[key],
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true
|
|
10
|
+
})
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function MpxEvent (layer) {
|
|
15
|
+
this.targetElement = null
|
|
16
|
+
this.touches = []
|
|
17
|
+
this.touchStartX = 0
|
|
18
|
+
this.touchStartY = 0
|
|
19
|
+
this.startTimer = null
|
|
20
|
+
this.needTap = true
|
|
21
|
+
this.isTouchDevice = document && ('ontouchstart' in document.documentElement)
|
|
22
|
+
|
|
23
|
+
this.onTouchStart = (event) => {
|
|
24
|
+
if (event.targetTouches?.length > 1) {
|
|
25
|
+
return true
|
|
26
|
+
}
|
|
27
|
+
this.touches = event.targetTouches
|
|
28
|
+
this.targetElement = event.target
|
|
29
|
+
this.needTap = true
|
|
30
|
+
this.startTimer = null
|
|
31
|
+
this.touchStartX = this.touches[0].pageX
|
|
32
|
+
this.touchStartY = this.touches[0].pageY
|
|
33
|
+
this.startTimer = setTimeout(() => {
|
|
34
|
+
this.needTap = false
|
|
35
|
+
this.sendEvent(this.targetElement, 'longpress', event)
|
|
36
|
+
this.sendEvent(this.targetElement, 'longtap', event)
|
|
37
|
+
}, 350)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.onTouchMove = (event) => {
|
|
41
|
+
const touch = event.changedTouches[0]
|
|
42
|
+
if (Math.abs(touch.pageX - this.touchStartX) > 1 || Math.abs(touch.pageY - this.touchStartY) > 1) {
|
|
43
|
+
this.needTap = false
|
|
44
|
+
this.startTimer && clearTimeout(this.startTimer)
|
|
45
|
+
this.startTimer = null
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.onTouchEnd = (event) => {
|
|
50
|
+
if (event.targetTouches?.length > 1) {
|
|
51
|
+
return true
|
|
52
|
+
}
|
|
53
|
+
this.startTimer && clearTimeout(this.startTimer)
|
|
54
|
+
this.startTimer = null
|
|
55
|
+
if (this.needTap) {
|
|
56
|
+
this.sendEvent(this.targetElement, 'tap', event)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.onClick = (event) => {
|
|
61
|
+
this.targetElement = event.target
|
|
62
|
+
this.sendEvent(this.targetElement, 'tap', event)
|
|
63
|
+
}
|
|
64
|
+
this.sendEvent = (targetElement, type, event) => {
|
|
65
|
+
const touchEvent = new CustomEvent(type, {
|
|
66
|
+
bubbles: true,
|
|
67
|
+
cancelable: true
|
|
68
|
+
})
|
|
69
|
+
const changedTouches = event.changedTouches || []
|
|
70
|
+
extendEvent(touchEvent, {
|
|
71
|
+
timeStamp: event.timeStamp,
|
|
72
|
+
changedTouches,
|
|
73
|
+
touches: changedTouches,
|
|
74
|
+
detail: {
|
|
75
|
+
// pc端点击事件可能没有changedTouches,所以直接从 event中取
|
|
76
|
+
x: changedTouches[0]?.pageX || event.pageX || 0,
|
|
77
|
+
y: changedTouches[0]?.pageY || event.pageY || 0
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
targetElement && targetElement.dispatchEvent(touchEvent)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.addListener = () => {
|
|
84
|
+
if (this.isTouchDevice) {
|
|
85
|
+
layer.addEventListener('touchstart', this.onTouchStart, true)
|
|
86
|
+
layer.addEventListener('touchmove', this.onTouchMove, true)
|
|
87
|
+
layer.addEventListener('touchend', this.onTouchEnd, true)
|
|
88
|
+
} else {
|
|
89
|
+
layer.addEventListener('click', this.onClick, true)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
this.addListener()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function initEvent () {
|
|
96
|
+
if (isBrowser && !global.__mpxCreatedEvent) {
|
|
97
|
+
global.__mpxCreatedEvent = true
|
|
98
|
+
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
|
99
|
+
// eslint-disable-next-line no-new
|
|
100
|
+
new MpxEvent(document.body)
|
|
101
|
+
} else {
|
|
102
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
103
|
+
// eslint-disable-next-line no-new
|
|
104
|
+
new MpxEvent(document.body)
|
|
105
|
+
}, false)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createI18n } from '../builtInMixins/i18nMixin'
|
|
2
|
+
|
|
3
|
+
export function init (Mpx) {
|
|
4
|
+
global.__mpx = Mpx
|
|
5
|
+
global.__mpxAppCbs = global.__mpxAppCbs || {
|
|
6
|
+
show: [],
|
|
7
|
+
hide: [],
|
|
8
|
+
error: [],
|
|
9
|
+
rejection: []
|
|
10
|
+
}
|
|
11
|
+
if (global.i18n) {
|
|
12
|
+
Mpx.i18n = createI18n(global.i18n)
|
|
13
|
+
}
|
|
14
|
+
initGlobalErrorHandling()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function initGlobalErrorHandling () {
|
|
18
|
+
if (global.ErrorUtils) {
|
|
19
|
+
const defaultHandler = global.ErrorUtils.getGlobalHandler()
|
|
20
|
+
global.ErrorUtils.setGlobalHandler((error, isFatal) => {
|
|
21
|
+
if (global.__mpxAppCbs && global.__mpxAppCbs.error && global.__mpxAppCbs.error.length) {
|
|
22
|
+
global.__mpxAppCbs.error.forEach((cb) => {
|
|
23
|
+
cb(error)
|
|
24
|
+
})
|
|
25
|
+
} else if (defaultHandler) {
|
|
26
|
+
defaultHandler(error, isFatal)
|
|
27
|
+
} else {
|
|
28
|
+
console.error(`${error.name}: ${error.message}\n`)
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const rejectionTrackingOptions = {
|
|
34
|
+
allRejections: true,
|
|
35
|
+
onUnhandled (id, error) {
|
|
36
|
+
if (global.__mpxAppCbs && global.__mpxAppCbs.rejection && global.__mpxAppCbs.rejection.length) {
|
|
37
|
+
global.__mpxAppCbs.rejection.forEach((cb) => {
|
|
38
|
+
cb(error, id)
|
|
39
|
+
})
|
|
40
|
+
} else {
|
|
41
|
+
console.warn(`UNHANDLED PROMISE REJECTION (id: ${id}): ${error}\n`)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (global?.HermesInternal?.hasPromise?.()) {
|
|
47
|
+
global.HermesInternal?.enablePromiseRejectionTracker?.(rejectionTrackingOptions)
|
|
48
|
+
} else {
|
|
49
|
+
require('promise/setimmediate/rejection-tracking').enable(rejectionTrackingOptions)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Vue from 'vue'
|
|
2
|
+
import install from './vuePlugin'
|
|
3
|
+
import { isBrowser, error, warn } from '@mpxjs/utils'
|
|
4
|
+
import { initEvent } from './event'
|
|
5
|
+
|
|
6
|
+
export function init (Mpx) {
|
|
7
|
+
global.__mpx = Mpx
|
|
8
|
+
global.__mpxAppCbs = global.__mpxAppCbs || {
|
|
9
|
+
show: [],
|
|
10
|
+
hide: [],
|
|
11
|
+
error: [],
|
|
12
|
+
rejection: []
|
|
13
|
+
}
|
|
14
|
+
Mpx.__vue = Vue
|
|
15
|
+
Vue.use(install)
|
|
16
|
+
initEvent()
|
|
17
|
+
initGlobalErrorHandling()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function initGlobalErrorHandling () {
|
|
21
|
+
Vue.config.errorHandler = (e, vm, info) => {
|
|
22
|
+
error(`Unhandled error occurs${info ? ` during execution of [${info}]` : ''}!`, vm?.__mpxProxy?.options.mpxFileResource, e)
|
|
23
|
+
}
|
|
24
|
+
Vue.config.warnHandler = (msg, vm, trace) => {
|
|
25
|
+
warn(msg, vm?.__mpxProxy?.options.mpxFileResource, trace)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (isBrowser) {
|
|
29
|
+
window.addEventListener('error', (event) => {
|
|
30
|
+
if (global.__mpxAppCbs && global.__mpxAppCbs.error && global.__mpxAppCbs.error.length) {
|
|
31
|
+
global.__mpxAppCbs.error.forEach((cb) => {
|
|
32
|
+
cb(event.error)
|
|
33
|
+
})
|
|
34
|
+
} else {
|
|
35
|
+
console.error(`${event.type}: ${event.message}\n`)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
window.addEventListener('unhandledrejection', (event) => {
|
|
39
|
+
if (global.__mpxAppCbs && global.__mpxAppCbs.rejection && global.__mpxAppCbs.rejection.length) {
|
|
40
|
+
global.__mpxAppCbs.rejection.forEach((cb) => {
|
|
41
|
+
cb(event.reason, event.promise)
|
|
42
|
+
})
|
|
43
|
+
} else {
|
|
44
|
+
console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}\n`)
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { walkChildren, parseSelector, error, hasOwn, collectDataset } from '@mpxjs/utils'
|
|
2
2
|
import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy'
|
|
3
3
|
import { EffectScope } from 'vue'
|
|
4
|
-
import { PausedState } from '
|
|
4
|
+
import { PausedState } from '../../helper/const'
|
|
5
5
|
|
|
6
6
|
const hackEffectScope = () => {
|
|
7
7
|
EffectScope.prototype.pause = function () {
|
|
@@ -3,7 +3,7 @@ import * as ReactNative from 'react-native'
|
|
|
3
3
|
import { ReactiveEffect } from '../../observer/effect'
|
|
4
4
|
import { watch } from '../../observer/watch'
|
|
5
5
|
import { reactive, set, del } from '../../observer/reactive'
|
|
6
|
-
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, wrapMethodsWithErrorHandling } from '@mpxjs/utils'
|
|
6
|
+
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling } from '@mpxjs/utils'
|
|
7
7
|
import MpxProxy from '../../core/proxy'
|
|
8
8
|
import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE, REACTHOOKSEXEC } from '../../core/innerLifecycle'
|
|
9
9
|
import mergeOptions from '../../core/mergeOptions'
|
|
@@ -52,20 +52,18 @@ function createEffect (proxy, components) {
|
|
|
52
52
|
proxy.effect = new ReactiveEffect(() => {
|
|
53
53
|
// reset instance
|
|
54
54
|
proxy.target.__resetInstance()
|
|
55
|
-
return proxy.target.__injectedRender(innerCreateElement, getComponent)
|
|
55
|
+
return callWithErrorHandling(proxy.target.__injectedRender.bind(proxy.target), proxy, 'render function', [innerCreateElement, getComponent])
|
|
56
56
|
}, () => queueJob(update), proxy.scope)
|
|
57
57
|
// render effect允许自触发
|
|
58
58
|
proxy.toggleRecurse(true)
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
function getRootProps (props) {
|
|
61
|
+
function getRootProps (props, validProps) {
|
|
62
62
|
const rootProps = {}
|
|
63
63
|
for (const key in props) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
rootProps[key] = props[key]
|
|
68
|
-
}
|
|
64
|
+
const altKey = dash2hump(key)
|
|
65
|
+
if (!hasOwn(validProps, key) && !hasOwn(validProps, altKey) && key !== 'children') {
|
|
66
|
+
rootProps[key] = props[key]
|
|
69
67
|
}
|
|
70
68
|
}
|
|
71
69
|
return rootProps
|
|
@@ -474,7 +472,8 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
474
472
|
|
|
475
473
|
const root = useMemo(() => proxy.effect.run(), [finalMemoVersion])
|
|
476
474
|
if (root && root.props.ishost) {
|
|
477
|
-
|
|
475
|
+
// 对于组件未注册的属性继承到host节点上,如事件、样式和其他属性等
|
|
476
|
+
const rootProps = getRootProps(props, validProps)
|
|
478
477
|
rootProps.style = Object.assign({}, root.props.style, rootProps.style)
|
|
479
478
|
// update root props
|
|
480
479
|
return cloneElement(root, rootProps)
|
|
@@ -560,10 +559,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
560
559
|
backgroundColor: pageConfig.backgroundColor || '#ffffff'
|
|
561
560
|
},
|
|
562
561
|
ref: rootRef,
|
|
563
|
-
onLayout
|
|
564
|
-
onTouchStart: () => {
|
|
565
|
-
ReactNative.Keyboard.isVisible() && ReactNative.Keyboard.dismiss()
|
|
566
|
-
}
|
|
562
|
+
onLayout
|
|
567
563
|
},
|
|
568
564
|
createElement(RouteContext.Provider,
|
|
569
565
|
{
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import transferOptions from '../../core/transferOptions'
|
|
2
2
|
import getBuiltInMixins from '../builtInMixins/index'
|
|
3
3
|
import { getDefaultOptions } from './getDefaultOptions'
|
|
4
|
-
import { error, isReact, isWeb
|
|
4
|
+
import { error, isReact, isWeb } from '@mpxjs/utils'
|
|
5
5
|
|
|
6
6
|
export default function createFactory (type) {
|
|
7
7
|
return (options = {}, { isNative, customCtor, customCtorType } = {}) => {
|
|
8
8
|
options.__nativeRender__ = !!isNative
|
|
9
9
|
options.__type__ = type
|
|
10
10
|
let ctor
|
|
11
|
-
if (!isWeb && !isReact
|
|
11
|
+
if (!isWeb && !isReact) {
|
|
12
12
|
if (customCtor) {
|
|
13
13
|
ctor = customCtor
|
|
14
14
|
customCtorType = customCtorType || type
|
|
@@ -43,7 +43,7 @@ export default function createFactory (type) {
|
|
|
43
43
|
// 将合并后的用户定义的rawOptions传入获取当前应该注入的内建mixins
|
|
44
44
|
rawOptions.mixins = getBuiltInMixins({ type, rawOptions, currentInject })
|
|
45
45
|
const defaultOptions = getDefaultOptions({ type, rawOptions, currentInject })
|
|
46
|
-
if (isWeb || isReact
|
|
46
|
+
if (isWeb || isReact) {
|
|
47
47
|
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
|
|
48
48
|
global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
|
|
49
49
|
} else if (ctor) {
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import * as wxLifecycle from '../platform/patch/lifecycle/index.wx'
|
|
2
|
-
import * as tenonLifecycle from '../platform/patch/lifecycle/index.tenon'
|
|
3
|
-
import { mergeLifecycle } from './mergeLifecycle'
|
|
4
|
-
import { error, isObject, diffAndCloneA, hasOwn } from '@mpxjs/utils'
|
|
5
|
-
import { implemented } from '../core/implement'
|
|
6
|
-
import { CREATED, UNMOUNTED } from '../core/innerLifecycle'
|
|
7
|
-
|
|
8
|
-
// 暂不支持的wx选项,后期需要各种花式支持
|
|
9
|
-
const unsupported = [
|
|
10
|
-
'moved',
|
|
11
|
-
'definitionFilter',
|
|
12
|
-
'onShareAppMessage',
|
|
13
|
-
'activated',
|
|
14
|
-
'deactivated',
|
|
15
|
-
'pageShow',
|
|
16
|
-
'pageHide',
|
|
17
|
-
'onPullDownRefresh',
|
|
18
|
-
'onReachBottom',
|
|
19
|
-
'onPageScroll',
|
|
20
|
-
'onTabItemTap',
|
|
21
|
-
'onResize',
|
|
22
|
-
'onUnhandledRejection',
|
|
23
|
-
'onThemeChange'
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
function convertErrorDesc (key) {
|
|
27
|
-
error(`Options.${key} is not supported in runtime conversion from wx to tenon.`, global.currentResource)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function notSupportTip (options) {
|
|
31
|
-
unsupported.forEach(key => {
|
|
32
|
-
if (options[key]) {
|
|
33
|
-
if (!implemented[key]) {
|
|
34
|
-
process.env.NODE_ENV !== 'production' && convertErrorDesc(key)
|
|
35
|
-
delete options[key]
|
|
36
|
-
} else if (implemented[key].remove) {
|
|
37
|
-
delete options[key]
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default {
|
|
44
|
-
lifecycle: mergeLifecycle(wxLifecycle.LIFECYCLE),
|
|
45
|
-
lifecycle2: mergeLifecycle(tenonLifecycle.LIFECYCLE),
|
|
46
|
-
pageMode: 'blend',
|
|
47
|
-
// support传递为true以将methods外层的方法函数合入methods中
|
|
48
|
-
support: true,
|
|
49
|
-
// wx输出tenon时额外将onLoad代理到CREATED
|
|
50
|
-
lifecycleProxyMap: Object.assign({}, wxLifecycle.lifecycleProxyMap, {
|
|
51
|
-
[CREATED]: ['created', 'attached', 'onLoad'],
|
|
52
|
-
[UNMOUNTED]: ['destroyed', 'detached', 'onUnload', 'unmounted']
|
|
53
|
-
}),
|
|
54
|
-
convert (options) {
|
|
55
|
-
const props = Object.assign({}, options.properties, options.props)
|
|
56
|
-
if (props) {
|
|
57
|
-
Object.keys(props).forEach(key => {
|
|
58
|
-
const prop = props[key]
|
|
59
|
-
if (prop) {
|
|
60
|
-
if (hasOwn(prop, 'type')) {
|
|
61
|
-
const newProp = {}
|
|
62
|
-
if (hasOwn(prop, 'optionalTypes')) {
|
|
63
|
-
newProp.type = [prop.type, ...prop.optionalTypes]
|
|
64
|
-
} else {
|
|
65
|
-
newProp.type = prop.type
|
|
66
|
-
}
|
|
67
|
-
if (hasOwn(prop, 'value')) {
|
|
68
|
-
// vue中对于引用类型数据需要使用函数返回
|
|
69
|
-
newProp.default = isObject(prop.value)
|
|
70
|
-
? function propFn () {
|
|
71
|
-
return diffAndCloneA(prop.value).clone
|
|
72
|
-
}
|
|
73
|
-
: prop.value
|
|
74
|
-
}
|
|
75
|
-
props[key] = newProp
|
|
76
|
-
} else {
|
|
77
|
-
props[key] = prop
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
options.props = props
|
|
82
|
-
delete options.properties
|
|
83
|
-
}
|
|
84
|
-
notSupportTip(options)
|
|
85
|
-
}
|
|
86
|
-
}
|
package/src/external/vue.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default {}
|
package/src/external/vue.web.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { CREATED, ONSHOW, ONHIDE } from '../../core/innerLifecycle'
|
|
2
|
-
|
|
3
|
-
export default function pageStatusMixin (mixinType) {
|
|
4
|
-
if (mixinType === 'page') {
|
|
5
|
-
return {
|
|
6
|
-
data: {
|
|
7
|
-
mpxPageStatus: 'show'
|
|
8
|
-
},
|
|
9
|
-
onShow () {
|
|
10
|
-
this.mpxPageStatus = 'show'
|
|
11
|
-
this.__mpxProxy.callHook(ONSHOW)
|
|
12
|
-
},
|
|
13
|
-
onHide () {
|
|
14
|
-
this.mpxPageStatus = 'hide'
|
|
15
|
-
this.__mpxProxy.callHook(ONHIDE)
|
|
16
|
-
},
|
|
17
|
-
onBack () {
|
|
18
|
-
return this.onBack && this.onBack()
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
// components
|
|
23
|
-
return {
|
|
24
|
-
[CREATED] () {
|
|
25
|
-
const pageInstance = global.__currentPageInstance
|
|
26
|
-
if (!pageInstance) return
|
|
27
|
-
this.$watch(
|
|
28
|
-
() => pageInstance.mpxPageStatus,
|
|
29
|
-
status => {
|
|
30
|
-
if (!status) return
|
|
31
|
-
const pageLifetimes = (this.$rawOptions && this.$rawOptions.pageLifetimes) || {}
|
|
32
|
-
// show & hide
|
|
33
|
-
if (status in pageLifetimes && typeof pageLifetimes[status] === 'function') {
|
|
34
|
-
pageLifetimes[status].call(this)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { setByPath } from '@mpxjs/utils'
|
|
2
|
-
|
|
3
|
-
export default function proxyEventMixin () {
|
|
4
|
-
const methods = {
|
|
5
|
-
triggerEvent (eventName, eventDetail) {
|
|
6
|
-
return this.$emit(eventName, {
|
|
7
|
-
type: eventName,
|
|
8
|
-
detail: eventDetail
|
|
9
|
-
})
|
|
10
|
-
},
|
|
11
|
-
__model (expr, $event, valuePath = ['value'], filterMethod) {
|
|
12
|
-
const innerFilter = {
|
|
13
|
-
trim: val => typeof val === 'string' && val.trim()
|
|
14
|
-
}
|
|
15
|
-
const originValue = valuePath.reduce((acc, cur) => acc[cur], $event.detail)
|
|
16
|
-
const value = filterMethod ? (innerFilter[filterMethod] ? innerFilter[filterMethod](originValue) : typeof this[filterMethod] === 'function' && this[filterMethod]) : originValue
|
|
17
|
-
setByPath(this, expr, value)
|
|
18
|
-
},
|
|
19
|
-
getOpenerEventChannel () {
|
|
20
|
-
const router = global.__mpxRouter
|
|
21
|
-
const eventChannel = router && router.__mpxAction && router.__mpxAction.eventChannel
|
|
22
|
-
return eventChannel
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
beforeCreate () {
|
|
28
|
-
const modelEvent = this.$attrs.mpxModelEvent
|
|
29
|
-
const modelEventId = this.$attrs.mpxModelEventId
|
|
30
|
-
if (modelEvent && modelEventId) {
|
|
31
|
-
Hummer.notifyCenter.addEventListener(modelEventId, (e) => {
|
|
32
|
-
this.$emit('mpxModel', e)
|
|
33
|
-
})
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
beforeDestroy () {
|
|
37
|
-
const modelEvent = this.$attrs.mpxModelEvent
|
|
38
|
-
const modelEventId = this.$attrs.mpxModelEventId
|
|
39
|
-
if (modelEvent && modelEventId) {
|
|
40
|
-
Hummer.notifyCenter.removeEventListener(modelEventId)
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
methods
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { provide, inject } from '@hummer/tenon-vue'
|