@mpxjs/core 2.9.70-alpha.2 → 2.9.70-alpha.3
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/package.json +5 -5
- package/src/convertor/wxToReact.js +1 -1
- package/src/core/mergeOptions.js +3 -6
- package/src/core/proxy.js +27 -21
- package/src/index.js +3 -10
- package/src/observer/reactive.js +4 -3
- package/src/platform/builtInMixins/directiveHelperMixin.ios.js +4 -1
- package/src/platform/builtInMixins/index.js +2 -1
- package/src/platform/builtInMixins/proxyEventMixin.web.js +53 -5
- package/src/platform/builtInMixins/relationsMixin.ios.js +67 -0
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +1 -1
- package/src/platform/createApp.ios.js +55 -54
- package/src/platform/createApp.js +25 -29
- package/src/platform/env/event.js +105 -0
- package/src/platform/env/index.ios.js +61 -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 +10 -4
- package/src/platform/export/index.js +1 -1
- package/src/platform/export/{apiInject.js → inject.js} +16 -26
- package/src/platform/patch/getDefaultOptions.ios.js +115 -38
- package/src/platform/patch/getDefaultOptions.js +0 -2
- package/src/external/vue.js +0 -1
- package/src/external/vue.web.js +0 -6
- /package/src/{external → platform/env}/vue.tenon.js +0 -0
- /package/src/platform/export/{apiInject.web.js → inject.web.js} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, useMemo, useState, useCallback, createElement, memo, forwardRef, useImperativeHandle, useContext, Fragment, cloneElement } from 'react'
|
|
1
|
+
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, useMemo, useState, useCallback, createElement, memo, forwardRef, useImperativeHandle, useContext, Fragment, cloneElement, createContext } from 'react'
|
|
2
2
|
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'
|
|
@@ -11,6 +11,8 @@ import { queueJob, hasPendingJob } from '../../observer/scheduler'
|
|
|
11
11
|
import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy'
|
|
12
12
|
import { IntersectionObserverContext, RouteContext, KeyboardAvoidContext } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context'
|
|
13
13
|
|
|
14
|
+
const ProviderContext = createContext(null)
|
|
15
|
+
|
|
14
16
|
function getSystemInfo () {
|
|
15
17
|
const window = ReactNative.Dimensions.get('window')
|
|
16
18
|
const screen = ReactNative.Dimensions.get('screen')
|
|
@@ -42,7 +44,8 @@ function createEffect (proxy, components) {
|
|
|
42
44
|
const getComponent = (tagName) => {
|
|
43
45
|
if (!tagName) return null
|
|
44
46
|
if (tagName === 'block') return Fragment
|
|
45
|
-
|
|
47
|
+
const appComponents = global.__getAppComponents?.() || {}
|
|
48
|
+
return components[tagName] || appComponents[tagName] || getByPath(ReactNative, tagName)
|
|
46
49
|
}
|
|
47
50
|
const innerCreateElement = (type, ...rest) => {
|
|
48
51
|
if (!type) return null
|
|
@@ -52,20 +55,18 @@ function createEffect (proxy, components) {
|
|
|
52
55
|
proxy.effect = new ReactiveEffect(() => {
|
|
53
56
|
// reset instance
|
|
54
57
|
proxy.target.__resetInstance()
|
|
55
|
-
return proxy.target.__injectedRender(innerCreateElement, getComponent)
|
|
58
|
+
return callWithErrorHandling(proxy.target.__injectedRender.bind(proxy.target), proxy, 'render function', [innerCreateElement, getComponent])
|
|
56
59
|
}, () => queueJob(update), proxy.scope)
|
|
57
60
|
// render effect允许自触发
|
|
58
61
|
proxy.toggleRecurse(true)
|
|
59
62
|
}
|
|
60
63
|
|
|
61
|
-
function getRootProps (props) {
|
|
64
|
+
function getRootProps (props, validProps) {
|
|
62
65
|
const rootProps = {}
|
|
63
66
|
for (const key in props) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
rootProps[key] = props[key]
|
|
68
|
-
}
|
|
67
|
+
const altKey = dash2hump(key)
|
|
68
|
+
if (!hasOwn(validProps, key) && !hasOwn(validProps, altKey) && key !== 'children') {
|
|
69
|
+
rootProps[key] = props[key]
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
return rootProps
|
|
@@ -195,7 +196,7 @@ const instanceProto = {
|
|
|
195
196
|
}
|
|
196
197
|
}
|
|
197
198
|
|
|
198
|
-
function createInstance ({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx }) {
|
|
199
|
+
function createInstance ({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx, relation, parentProvides }) {
|
|
199
200
|
const instance = Object.create(instanceProto, {
|
|
200
201
|
dataset: {
|
|
201
202
|
get () {
|
|
@@ -246,9 +247,33 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
246
247
|
return currentInject.getRefsData || noop
|
|
247
248
|
},
|
|
248
249
|
enumerable: false
|
|
250
|
+
},
|
|
251
|
+
__parentProvides: {
|
|
252
|
+
get () {
|
|
253
|
+
return parentProvides || null
|
|
254
|
+
},
|
|
255
|
+
enumerable: false
|
|
249
256
|
}
|
|
250
257
|
})
|
|
251
258
|
|
|
259
|
+
if (type === 'component') {
|
|
260
|
+
Object.defineProperty(instance, '__componentPath', {
|
|
261
|
+
get () {
|
|
262
|
+
return currentInject.componentPath || ''
|
|
263
|
+
},
|
|
264
|
+
enumerable: false
|
|
265
|
+
})
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (relation) {
|
|
269
|
+
Object.defineProperty(instance, '__relation', {
|
|
270
|
+
get () {
|
|
271
|
+
return relation
|
|
272
|
+
},
|
|
273
|
+
enumerable: false
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
|
|
252
277
|
// bind this & assign methods
|
|
253
278
|
if (rawOptions.methods) {
|
|
254
279
|
Object.entries(rawOptions.methods).forEach(([key, method]) => {
|
|
@@ -367,34 +392,68 @@ function usePageStatus (navigation, pageId) {
|
|
|
367
392
|
const blurSubscription = navigation.addListener('blur', () => {
|
|
368
393
|
pageStatusMap[pageId] = 'hide'
|
|
369
394
|
})
|
|
370
|
-
const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => {
|
|
371
|
-
pageStatusMap[pageId] = value
|
|
372
|
-
})
|
|
373
395
|
|
|
374
396
|
return () => {
|
|
375
397
|
focusSubscription()
|
|
376
398
|
blurSubscription()
|
|
377
|
-
unWatchAppFocusedState()
|
|
378
399
|
del(pageStatusMap, pageId)
|
|
379
400
|
}
|
|
380
401
|
}, [navigation])
|
|
381
402
|
}
|
|
382
403
|
|
|
404
|
+
const RelationsContext = createContext(null)
|
|
405
|
+
|
|
406
|
+
const checkRelation = (options) => {
|
|
407
|
+
const relations = options.relations || {}
|
|
408
|
+
let hasDescendantRelation = false
|
|
409
|
+
let hasAncestorRelation = false
|
|
410
|
+
Object.keys(relations).forEach((path) => {
|
|
411
|
+
const relation = relations[path]
|
|
412
|
+
const type = relation.type
|
|
413
|
+
if (['child', 'descendant'].includes(type)) {
|
|
414
|
+
hasDescendantRelation = true
|
|
415
|
+
} else if (['parent', 'ancestor'].includes(type)) {
|
|
416
|
+
hasAncestorRelation = true
|
|
417
|
+
}
|
|
418
|
+
})
|
|
419
|
+
return {
|
|
420
|
+
hasDescendantRelation,
|
|
421
|
+
hasAncestorRelation
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const provideRelation = (instance, relation) => {
|
|
426
|
+
const componentPath = instance.__componentPath
|
|
427
|
+
if (relation) {
|
|
428
|
+
return Object.assign({}, relation, { [componentPath]: instance })
|
|
429
|
+
} else {
|
|
430
|
+
return {
|
|
431
|
+
[componentPath]: instance
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
383
436
|
export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
384
437
|
rawOptions = mergeOptions(rawOptions, type, false)
|
|
385
438
|
const components = Object.assign({}, rawOptions.components, currentInject.getComponents())
|
|
386
439
|
const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
|
|
440
|
+
const { hasDescendantRelation, hasAncestorRelation } = checkRelation(rawOptions)
|
|
387
441
|
if (rawOptions.methods) rawOptions.methods = wrapMethodsWithErrorHandling(rawOptions.methods)
|
|
388
442
|
const defaultOptions = memo(forwardRef((props, ref) => {
|
|
389
443
|
const instanceRef = useRef(null)
|
|
390
444
|
const propsRef = useRef(null)
|
|
391
445
|
const intersectionCtx = useContext(IntersectionObserverContext)
|
|
392
446
|
const pageId = useContext(RouteContext)
|
|
447
|
+
const parentProvides = useContext(ProviderContext)
|
|
448
|
+
let relation = null
|
|
449
|
+
if (hasDescendantRelation || hasAncestorRelation) {
|
|
450
|
+
relation = useContext(RelationsContext)
|
|
451
|
+
}
|
|
393
452
|
propsRef.current = props
|
|
394
453
|
let isFirst = false
|
|
395
454
|
if (!instanceRef.current) {
|
|
396
455
|
isFirst = true
|
|
397
|
-
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx })
|
|
456
|
+
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx, relation, parentProvides })
|
|
398
457
|
}
|
|
399
458
|
const instance = instanceRef.current
|
|
400
459
|
useImperativeHandle(ref, () => {
|
|
@@ -444,10 +503,17 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
444
503
|
|
|
445
504
|
useEffect(() => {
|
|
446
505
|
if (type === 'page') {
|
|
447
|
-
if (!global.
|
|
506
|
+
if (!global.__mpxAppHotLaunched && global.__mpxAppOnLaunch) {
|
|
448
507
|
global.__mpxAppOnLaunch(props.navigation)
|
|
449
508
|
}
|
|
450
|
-
|
|
509
|
+
const loadParams = {}
|
|
510
|
+
// 此处拿到的props.route.params内属性的value被进行过了一次decode, 不符合预期,此处额外进行一次encode来与微信对齐
|
|
511
|
+
if (isObject(props.route.params)) {
|
|
512
|
+
for (const key in props.route.params) {
|
|
513
|
+
loadParams[key] = encodeURIComponent(props.route.params[key])
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
proxy.callHook(ONLOAD, [loadParams])
|
|
451
517
|
}
|
|
452
518
|
proxy.mounted()
|
|
453
519
|
return () => {
|
|
@@ -472,14 +538,28 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
472
538
|
return proxy.finalMemoVersion
|
|
473
539
|
}, [proxy.stateVersion, proxy.memoVersion])
|
|
474
540
|
|
|
475
|
-
|
|
541
|
+
let root = useMemo(() => proxy.effect.run(), [finalMemoVersion])
|
|
476
542
|
if (root && root.props.ishost) {
|
|
477
|
-
|
|
543
|
+
// 对于组件未注册的属性继承到host节点上,如事件、样式和其他属性等
|
|
544
|
+
const rootProps = getRootProps(props, validProps)
|
|
478
545
|
rootProps.style = Object.assign({}, root.props.style, rootProps.style)
|
|
479
546
|
// update root props
|
|
480
|
-
|
|
547
|
+
root = cloneElement(root, rootProps)
|
|
481
548
|
}
|
|
482
|
-
|
|
549
|
+
|
|
550
|
+
const provides = proxy.provides
|
|
551
|
+
if (provides) {
|
|
552
|
+
root = createElement(ProviderContext.Provider, { value: provides }, root)
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return hasDescendantRelation
|
|
556
|
+
? createElement(RelationsContext.Provider,
|
|
557
|
+
{
|
|
558
|
+
value: provideRelation(instance, relation)
|
|
559
|
+
},
|
|
560
|
+
root
|
|
561
|
+
)
|
|
562
|
+
: root
|
|
483
563
|
}))
|
|
484
564
|
|
|
485
565
|
if (rawOptions.options?.isCustomText) {
|
|
@@ -487,30 +567,25 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
487
567
|
}
|
|
488
568
|
|
|
489
569
|
if (type === 'page') {
|
|
490
|
-
const { Provider, useSafeAreaInsets, GestureHandlerRootView } = global.__navigationHelper
|
|
570
|
+
const { Provider, useSafeAreaInsets, GestureHandlerRootView, useHeaderHeight } = global.__navigationHelper
|
|
491
571
|
const pageConfig = Object.assign({}, global.__mpxPageConfig, currentInject.pageConfig)
|
|
492
572
|
const Page = ({ navigation, route }) => {
|
|
493
|
-
const [enabled, setEnabled] = useState(
|
|
573
|
+
const [enabled, setEnabled] = useState(false)
|
|
494
574
|
const currentPageId = useMemo(() => ++pageId, [])
|
|
495
575
|
const intersectionObservers = useRef({})
|
|
496
576
|
usePageStatus(navigation, currentPageId)
|
|
497
577
|
|
|
498
578
|
useLayoutEffect(() => {
|
|
499
579
|
const isCustom = pageConfig.navigationStyle === 'custom'
|
|
500
|
-
navigation.setOptions({
|
|
580
|
+
navigation.setOptions(Object.assign({
|
|
501
581
|
headerShown: !isCustom,
|
|
502
582
|
title: pageConfig.navigationBarTitleText || '',
|
|
503
583
|
headerStyle: {
|
|
504
584
|
backgroundColor: pageConfig.navigationBarBackgroundColor || '#000000'
|
|
505
585
|
},
|
|
506
|
-
headerTintColor: pageConfig.navigationBarTextStyle || 'white'
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
ReactNative.StatusBar.setBarStyle(pageConfig.barStyle || 'dark-content')
|
|
510
|
-
ReactNative.StatusBar.setTranslucent(isCustom) // 控制statusbar是否占位
|
|
511
|
-
const color = isCustom ? 'transparent' : pageConfig.statusBarColor
|
|
512
|
-
color && ReactNative.StatusBar.setBackgroundColor(color)
|
|
513
|
-
}
|
|
586
|
+
headerTintColor: pageConfig.navigationBarTextStyle || 'white',
|
|
587
|
+
statusBarTranslucent: true
|
|
588
|
+
}, __mpx_mode__ === 'android' ? { statusBarStyle: pageConfig.statusBarStyle || 'light' } : {}))
|
|
514
589
|
}, [])
|
|
515
590
|
|
|
516
591
|
const rootRef = useRef(null)
|
|
@@ -548,7 +623,12 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
548
623
|
|
|
549
624
|
return createElement(GestureHandlerRootView,
|
|
550
625
|
{
|
|
551
|
-
|
|
626
|
+
// https://github.com/software-mansion/react-native-reanimated/issues/6639 因存在此问题,iOS在页面上进行定宽来暂时规避
|
|
627
|
+
style: __mpx_mode__ === 'ios' && pageConfig.navigationStyle !== 'custom'
|
|
628
|
+
? {
|
|
629
|
+
height: ReactNative.Dimensions.get('screen').height - useHeaderHeight()
|
|
630
|
+
}
|
|
631
|
+
: {
|
|
552
632
|
flex: 1
|
|
553
633
|
}
|
|
554
634
|
},
|
|
@@ -560,10 +640,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
560
640
|
backgroundColor: pageConfig.backgroundColor || '#ffffff'
|
|
561
641
|
},
|
|
562
642
|
ref: rootRef,
|
|
563
|
-
onLayout
|
|
564
|
-
onTouchStart: () => {
|
|
565
|
-
ReactNative.Keyboard.isVisible() && ReactNative.Keyboard.dismiss()
|
|
566
|
-
}
|
|
643
|
+
onLayout
|
|
567
644
|
},
|
|
568
645
|
createElement(RouteContext.Provider,
|
|
569
646
|
{
|
|
@@ -23,13 +23,11 @@ function transformProperties (properties) {
|
|
|
23
23
|
} else {
|
|
24
24
|
newFiled = Object.assign({}, rawFiled)
|
|
25
25
|
}
|
|
26
|
-
const rawObserver = rawFiled?.observer
|
|
27
26
|
newFiled.observer = function (value, oldValue) {
|
|
28
27
|
if (this.__mpxProxy) {
|
|
29
28
|
this[key] = value
|
|
30
29
|
this.__mpxProxy.propsUpdated()
|
|
31
30
|
}
|
|
32
|
-
rawObserver && rawObserver.call(this, value, oldValue)
|
|
33
31
|
}
|
|
34
32
|
newProps[key] = newFiled
|
|
35
33
|
})
|
package/src/external/vue.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default {}
|
package/src/external/vue.web.js
DELETED
|
File without changes
|
|
File without changes
|