@mpxjs/core 2.10.17 → 2.10.18-beta.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.
- package/@types/global.d.ts +1 -1
- package/@types/index.d.ts +3 -3
- package/package.json +3 -3
- package/src/convertor/convertor.js +3 -1
- package/src/convertor/getConvertMode.js +2 -1
- package/src/convertor/wxToKs.js +21 -0
- package/src/convertor/wxToWeb.js +8 -1
- package/src/core/proxy.js +24 -3
- package/src/helper/MpxScroll/index.js +17 -5
- package/src/observer/array.js +1 -1
- package/src/observer/computed.js +2 -2
- package/src/observer/dep.js +25 -5
- package/src/observer/effect.js +46 -6
- package/src/observer/reactive.js +13 -7
- package/src/observer/watch.js +1 -1
- package/src/platform/builtInMixins/index.js +7 -3
- package/src/platform/builtInMixins/pageStatusMixin.js +14 -2
- package/src/platform/builtInMixins/refsMixin.js +47 -46
- package/src/platform/builtInMixins/renderHelperMixin.js +40 -38
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +98 -23
- package/src/platform/createApp.ios.js +8 -22
- package/src/platform/env/navigationHelper.ios.js +3 -2
- package/src/platform/patch/getDefaultOptions.ios.js +129 -63
- package/LICENSE +0 -433
- package/src/platform/patch/react/getDefaultOptions.ios.js +0 -0
|
@@ -3,25 +3,25 @@ import * as ReactNative from 'react-native'
|
|
|
3
3
|
import { ReactiveEffect } from '../../observer/effect'
|
|
4
4
|
import { watch } from '../../observer/watch'
|
|
5
5
|
import { del, reactive, set } from '../../observer/reactive'
|
|
6
|
-
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling, error, setFocusedNavigation } from '@mpxjs/utils'
|
|
6
|
+
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling, error, setFocusedNavigation, getDefaultValueByType } 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'
|
|
10
10
|
import { queueJob, hasPendingJob } from '../../observer/scheduler'
|
|
11
11
|
import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy'
|
|
12
|
-
import MpxKeyboardAvoidingView from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view'
|
|
13
12
|
import {
|
|
14
13
|
IntersectionObserverContext,
|
|
15
14
|
KeyboardAvoidContext,
|
|
16
15
|
ProviderContext,
|
|
17
16
|
RouteContext
|
|
18
17
|
} from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context'
|
|
19
|
-
import { PortalHost, useSafeAreaInsets } from '../env/navigationHelper'
|
|
18
|
+
import { PortalHost, useSafeAreaInsets, initialWindowMetrics } from '../env/navigationHelper'
|
|
20
19
|
import { useInnerHeaderHeight } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-nav'
|
|
20
|
+
import Mpx from '../../index'
|
|
21
21
|
|
|
22
22
|
function getSystemInfo () {
|
|
23
|
-
const windowDimensions =
|
|
24
|
-
const screenDimensions =
|
|
23
|
+
const windowDimensions = global.__mpxAppDimensionsInfo.window
|
|
24
|
+
const screenDimensions = global.__mpxAppDimensionsInfo.screen
|
|
25
25
|
return {
|
|
26
26
|
deviceOrientation: windowDimensions.width > windowDimensions.height ? 'landscape' : 'portrait',
|
|
27
27
|
size: {
|
|
@@ -33,12 +33,13 @@ function getSystemInfo () {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
function createEffect (proxy, componentsMap) {
|
|
36
|
+
function createEffect (proxy, componentsMap, rawOptions) {
|
|
37
37
|
const update = proxy.update = () => {
|
|
38
38
|
// react update props in child render(async), do not need exec pre render
|
|
39
39
|
// if (proxy.propsUpdatedFlag) {
|
|
40
40
|
// proxy.updatePreRender()
|
|
41
41
|
// }
|
|
42
|
+
// console.log(`[mpx] ${proxy.options?.mpxFileResource} 组件render响应时数据变更,开始修改stateVersion,驱动组件更新`)
|
|
42
43
|
if (proxy.isMounted()) {
|
|
43
44
|
proxy.callHook(BEFOREUPDATE)
|
|
44
45
|
proxy.pendingUpdatedFlag = true
|
|
@@ -61,11 +62,18 @@ function createEffect (proxy, componentsMap) {
|
|
|
61
62
|
return createElement(type, ...rest)
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
const debugConfig = typeof global.__getMpxRenderEffectDebugRules === 'function'
|
|
66
|
+
? global.__getMpxRenderEffectDebugRules(rawOptions.mpxFileResource)
|
|
67
|
+
: {
|
|
68
|
+
debug: 1,
|
|
69
|
+
name: `MpxRenderEffect-${rawOptions.mpxFileResource || 'unknown'}`
|
|
70
|
+
}
|
|
71
|
+
|
|
64
72
|
proxy.effect = new ReactiveEffect(() => {
|
|
65
73
|
// reset instance
|
|
66
74
|
proxy.target.__resetInstance()
|
|
67
75
|
return callWithErrorHandling(proxy.target.__injectedRender.bind(proxy.target), proxy, 'render function', [innerCreateElement, getComponent])
|
|
68
|
-
}, () => queueJob(update), proxy.scope)
|
|
76
|
+
}, () => { return queueJob(update) }, proxy.scope, debugConfig.debug, debugConfig.name)
|
|
69
77
|
// render effect允许自触发
|
|
70
78
|
proxy.toggleRecurse(true)
|
|
71
79
|
}
|
|
@@ -172,8 +180,8 @@ const instanceProto = {
|
|
|
172
180
|
type: field
|
|
173
181
|
}
|
|
174
182
|
}
|
|
175
|
-
// 处理props
|
|
176
|
-
propsData[key] = field.value
|
|
183
|
+
// 处理props默认值,没有显式设置value时根据type获取默认值,与微信小程序原生行为保持一致
|
|
184
|
+
propsData[key] = hasOwn(field, 'value') ? field.value : getDefaultValueByType(field.type)
|
|
177
185
|
}
|
|
178
186
|
}
|
|
179
187
|
})
|
|
@@ -295,13 +303,18 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
295
303
|
instance[key] = method.bind(instance)
|
|
296
304
|
})
|
|
297
305
|
}
|
|
298
|
-
|
|
306
|
+
const loadParams = {}
|
|
299
307
|
if (type === 'page') {
|
|
300
308
|
const props = propsRef.current
|
|
301
309
|
instance.route = props.route.name
|
|
302
310
|
global.__mpxPagesMap = global.__mpxPagesMap || {}
|
|
303
311
|
global.__mpxPagesMap[props.route.key] = [instance, props.navigation]
|
|
304
312
|
setFocusedNavigation(props.navigation)
|
|
313
|
+
|
|
314
|
+
if (!global.__mpxAppHotLaunched && global.__mpxInitialRunParams) {
|
|
315
|
+
Object.assign(loadParams, global.__mpxInitialRunParams)
|
|
316
|
+
}
|
|
317
|
+
set(global.__mpxPageSizeCountMap, pageId, global.__mpxSizeCount)
|
|
305
318
|
// App onLaunch 在 Page created 之前执行
|
|
306
319
|
if (!global.__mpxAppHotLaunched && global.__mpxAppOnLaunch) {
|
|
307
320
|
global.__mpxAppOnLaunch(props.navigation)
|
|
@@ -310,17 +323,16 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
310
323
|
|
|
311
324
|
const proxy = instance.__mpxProxy = new MpxProxy(rawOptions, instance)
|
|
312
325
|
proxy.created()
|
|
313
|
-
|
|
314
326
|
if (type === 'page') {
|
|
315
327
|
const props = propsRef.current
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
if (isObject(
|
|
319
|
-
for (const key in
|
|
320
|
-
|
|
328
|
+
const decodedQuery = {}
|
|
329
|
+
const rawQuery = Object.assign({}, loadParams, props.route.params || {})
|
|
330
|
+
if (isObject(rawQuery)) {
|
|
331
|
+
for (const key in rawQuery) {
|
|
332
|
+
decodedQuery[key] = decodeURIComponent(rawQuery[key])
|
|
321
333
|
}
|
|
322
334
|
}
|
|
323
|
-
proxy.callHook(ONLOAD, [
|
|
335
|
+
proxy.callHook(ONLOAD, [rawQuery, decodedQuery])
|
|
324
336
|
}
|
|
325
337
|
|
|
326
338
|
Object.assign(proxy, {
|
|
@@ -328,7 +340,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
328
340
|
stateVersion: Symbol(),
|
|
329
341
|
subscribe: (onStoreChange) => {
|
|
330
342
|
if (!proxy.effect) {
|
|
331
|
-
createEffect(proxy, componentsMap)
|
|
343
|
+
createEffect(proxy, componentsMap, rawOptions)
|
|
332
344
|
proxy.stateVersion = Symbol()
|
|
333
345
|
}
|
|
334
346
|
proxy.onStoreChange = onStoreChange
|
|
@@ -344,7 +356,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
344
356
|
})
|
|
345
357
|
// react数据响应组件更新管理器
|
|
346
358
|
if (!proxy.effect) {
|
|
347
|
-
createEffect(proxy, componentsMap)
|
|
359
|
+
createEffect(proxy, componentsMap, rawOptions)
|
|
348
360
|
}
|
|
349
361
|
|
|
350
362
|
return instance
|
|
@@ -375,9 +387,18 @@ const triggerPageStatusHook = (mpxProxy, event) => {
|
|
|
375
387
|
}
|
|
376
388
|
}
|
|
377
389
|
|
|
378
|
-
const triggerResizeEvent = (mpxProxy) => {
|
|
379
|
-
const
|
|
390
|
+
const triggerResizeEvent = (mpxProxy, sizeRef) => {
|
|
391
|
+
const oldSize = sizeRef.current.size
|
|
380
392
|
const systemInfo = getSystemInfo()
|
|
393
|
+
const newSize = systemInfo.size
|
|
394
|
+
|
|
395
|
+
if (oldSize && oldSize.windowWidth === newSize.windowWidth && oldSize.windowHeight === newSize.windowHeight) {
|
|
396
|
+
return
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
Object.assign(sizeRef.current, systemInfo)
|
|
400
|
+
|
|
401
|
+
const type = mpxProxy.options.__type__
|
|
381
402
|
const target = mpxProxy.target
|
|
382
403
|
mpxProxy.callHook(ONRESIZE, [systemInfo])
|
|
383
404
|
if (type === 'page') {
|
|
@@ -388,7 +409,9 @@ const triggerResizeEvent = (mpxProxy) => {
|
|
|
388
409
|
}
|
|
389
410
|
}
|
|
390
411
|
|
|
391
|
-
function usePageEffect (mpxProxy, pageId) {
|
|
412
|
+
function usePageEffect (mpxProxy, pageId, type) {
|
|
413
|
+
const sizeRef = useRef(getSystemInfo())
|
|
414
|
+
|
|
392
415
|
useEffect(() => {
|
|
393
416
|
let unWatch
|
|
394
417
|
const hasShowHook = hasPageHook(mpxProxy, [ONSHOW, 'show'])
|
|
@@ -399,21 +422,31 @@ function usePageEffect (mpxProxy, pageId) {
|
|
|
399
422
|
unWatch = watch(() => pageStatusMap[pageId], (newVal) => {
|
|
400
423
|
if (newVal === 'show' || newVal === 'hide') {
|
|
401
424
|
triggerPageStatusHook(mpxProxy, newVal)
|
|
425
|
+
// 仅在尺寸确实变化时才触发resize事件
|
|
426
|
+
triggerResizeEvent(mpxProxy, sizeRef)
|
|
427
|
+
|
|
428
|
+
// 如果当前全局size与pagesize不一致,在show之后触发一次resize事件
|
|
429
|
+
if (type === 'page' && newVal === 'show' && global.__mpxPageSizeCountMap[pageId] !== global.__mpxSizeCount) {
|
|
430
|
+
// 刷新__mpxPageSizeCountMap, 每个页面仅会执行一次,直接驱动render刷新
|
|
431
|
+
global.__mpxPageSizeCountMap[pageId] = global.__mpxSizeCount
|
|
432
|
+
}
|
|
402
433
|
} else if (/^resize/.test(newVal)) {
|
|
403
|
-
triggerResizeEvent(mpxProxy)
|
|
434
|
+
triggerResizeEvent(mpxProxy, sizeRef)
|
|
404
435
|
}
|
|
405
436
|
}, { sync: true })
|
|
406
437
|
}
|
|
407
438
|
}
|
|
408
439
|
return () => {
|
|
409
440
|
unWatch && unWatch()
|
|
441
|
+
if (type === 'page') {
|
|
442
|
+
del(global.__mpxPageSizeCountMap, pageId)
|
|
443
|
+
}
|
|
410
444
|
}
|
|
411
445
|
}, [])
|
|
412
446
|
}
|
|
413
447
|
|
|
414
448
|
let pageId = 0
|
|
415
449
|
const pageStatusMap = global.__mpxPageStatusMap = reactive({})
|
|
416
|
-
|
|
417
450
|
function usePageStatus (navigation, pageId) {
|
|
418
451
|
navigation.pageId = pageId
|
|
419
452
|
if (!hasOwn(pageStatusMap, pageId)) {
|
|
@@ -486,7 +519,17 @@ function getLayoutData (headerHeight) {
|
|
|
486
519
|
// 在横屏状态下 screen.height = window.height + bottomVirtualHeight
|
|
487
520
|
// 在正常状态 screen.height = window.height + bottomVirtualHeight + statusBarHeight
|
|
488
521
|
const isLandscape = screenDimensions.height < screenDimensions.width
|
|
489
|
-
|
|
522
|
+
let bottomVirtualHeight = 0
|
|
523
|
+
if (ReactNative.Platform.OS === 'android') {
|
|
524
|
+
if (isLandscape) {
|
|
525
|
+
bottomVirtualHeight = screenDimensions.height - windowDimensions.height
|
|
526
|
+
} else {
|
|
527
|
+
bottomVirtualHeight = initialWindowMetrics?.insets?.bottom || 0
|
|
528
|
+
if (typeof mpxGlobal.__mpx.config?.rnConfig?.getBottomVirtualHeight === 'function') {
|
|
529
|
+
bottomVirtualHeight = mpxGlobal.__mpx.config?.rnConfig?.getBottomVirtualHeight() || 0
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
490
533
|
return {
|
|
491
534
|
left: 0,
|
|
492
535
|
top: headerHeight,
|
|
@@ -519,7 +562,7 @@ export function PageWrapperHOC (WrappedComponent, pageConfig = {}) {
|
|
|
519
562
|
navigation.layout = getLayoutData(headerHeight)
|
|
520
563
|
|
|
521
564
|
useEffect(() => {
|
|
522
|
-
const dimensionListener = ReactNative.Dimensions.addEventListener('change', ({ screen }) => {
|
|
565
|
+
const dimensionListener = ReactNative.Dimensions.addEventListener('change', ({ window, screen }) => {
|
|
523
566
|
navigation.layout = getLayoutData(headerHeight)
|
|
524
567
|
})
|
|
525
568
|
return () => dimensionListener?.remove()
|
|
@@ -529,6 +572,8 @@ export function PageWrapperHOC (WrappedComponent, pageConfig = {}) {
|
|
|
529
572
|
usePageStatus(navigation, currentPageId)
|
|
530
573
|
|
|
531
574
|
const withKeyboardAvoidingView = (element) => {
|
|
575
|
+
if (currentPageConfig.disableKeyboardAvoiding) return element
|
|
576
|
+
const MpxKeyboardAvoidingView = require('@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view').default
|
|
532
577
|
return createElement(KeyboardAvoidContext.Provider,
|
|
533
578
|
{
|
|
534
579
|
value: keyboardAvoidRef
|
|
@@ -549,39 +594,53 @@ export function PageWrapperHOC (WrappedComponent, pageConfig = {}) {
|
|
|
549
594
|
// android存在第一次打开insets都返回为0情况,后续会触发第二次渲染后正确
|
|
550
595
|
navigation.insets = useSafeAreaInsets()
|
|
551
596
|
return withKeyboardAvoidingView(
|
|
552
|
-
|
|
597
|
+
createElement(ReactNative.View,
|
|
598
|
+
{
|
|
599
|
+
style: {
|
|
600
|
+
flex: 1,
|
|
601
|
+
// 页面容器背景色
|
|
602
|
+
backgroundColor: currentPageConfig?.backgroundColorContent || '#fff',
|
|
603
|
+
// 解决页面内有元素定位relative left为负值的时候,回退的时候还能看到对应元素问题
|
|
604
|
+
overflow: 'hidden'
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
createElement(RouteContext.Provider,
|
|
608
|
+
{
|
|
609
|
+
value: routeContextValRef.current
|
|
610
|
+
},
|
|
611
|
+
createElement(IntersectionObserverContext.Provider,
|
|
553
612
|
{
|
|
554
|
-
|
|
555
|
-
flex: 1,
|
|
556
|
-
// 页面容器背景色
|
|
557
|
-
backgroundColor: currentPageConfig?.backgroundColorContent || '#fff',
|
|
558
|
-
// 解决页面内有元素定位relative left为负值的时候,回退的时候还能看到对应元素问题
|
|
559
|
-
overflow: 'hidden'
|
|
560
|
-
}
|
|
613
|
+
value: intersectionObservers.current
|
|
561
614
|
},
|
|
562
|
-
createElement(
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
createElement(PortalHost,
|
|
571
|
-
null,
|
|
572
|
-
createElement(WrappedComponent, {
|
|
573
|
-
...props,
|
|
574
|
-
navigation,
|
|
575
|
-
route,
|
|
576
|
-
id: currentPageId
|
|
577
|
-
})
|
|
578
|
-
)
|
|
579
|
-
)
|
|
615
|
+
createElement(PortalHost,
|
|
616
|
+
null,
|
|
617
|
+
createElement(WrappedComponent, {
|
|
618
|
+
...props,
|
|
619
|
+
navigation,
|
|
620
|
+
route,
|
|
621
|
+
id: currentPageId
|
|
622
|
+
})
|
|
580
623
|
)
|
|
624
|
+
)
|
|
581
625
|
)
|
|
626
|
+
)
|
|
582
627
|
)
|
|
583
628
|
}
|
|
584
629
|
}
|
|
630
|
+
|
|
631
|
+
function updateProps (instance, props, validProps) {
|
|
632
|
+
Object.keys(validProps).forEach((key) => {
|
|
633
|
+
if (hasOwn(props, key)) {
|
|
634
|
+
instance[key] = props[key]
|
|
635
|
+
} else {
|
|
636
|
+
const altKey = hump2dash(key)
|
|
637
|
+
if (hasOwn(props, altKey)) {
|
|
638
|
+
instance[key] = props[altKey]
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
})
|
|
642
|
+
}
|
|
643
|
+
|
|
585
644
|
export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
586
645
|
rawOptions = mergeOptions(rawOptions, type, false)
|
|
587
646
|
const componentsMap = currentInject.componentsMap
|
|
@@ -634,16 +693,14 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
634
693
|
|
|
635
694
|
if (!isFirst) {
|
|
636
695
|
// 处理props更新
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
})
|
|
696
|
+
if (Mpx.config.forceFlushSync) {
|
|
697
|
+
// 避免开启forceFlushSync时react报错:Cannot update a component while rendering a different component
|
|
698
|
+
Promise.resolve().then(() => {
|
|
699
|
+
updateProps(instance, props, validProps)
|
|
700
|
+
})
|
|
701
|
+
} else {
|
|
702
|
+
updateProps(instance, props, validProps)
|
|
703
|
+
}
|
|
647
704
|
}
|
|
648
705
|
|
|
649
706
|
useEffect(() => {
|
|
@@ -653,7 +710,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
653
710
|
}
|
|
654
711
|
})
|
|
655
712
|
|
|
656
|
-
usePageEffect(proxy, pageId)
|
|
713
|
+
usePageEffect(proxy, pageId, type)
|
|
657
714
|
useEffect(() => {
|
|
658
715
|
proxy.mounted()
|
|
659
716
|
return () => {
|
|
@@ -676,6 +733,15 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
676
733
|
proxy.memoVersion = Symbol()
|
|
677
734
|
}
|
|
678
735
|
|
|
736
|
+
// if (rawOptions.mpxFileResource.includes('nav.mpx')) {
|
|
737
|
+
// const stateVersionChange = proxy.stateVersion === global.__mpxNavStateVersion
|
|
738
|
+
// const memoVersionChange = proxy.memoVersion === global.__mpxNavMemoVersion
|
|
739
|
+
// const propsChange = props === global.__mpxNavProps
|
|
740
|
+
// console.log(`[mpx] nav.mpx render, stateVersionChange: ${stateVersionChange}, memoVersionChange: ${memoVersionChange}, propsChange: ${propsChange}`)
|
|
741
|
+
// global.__mpxNavStateVersion = proxy.stateVersion
|
|
742
|
+
// global.__mpxNavMemoVersion = proxy.memoVersion
|
|
743
|
+
// global.__mpxNavProps = props
|
|
744
|
+
// }
|
|
679
745
|
const finalMemoVersion = useMemo(() => {
|
|
680
746
|
if (!hasPendingJob(proxy.update)) {
|
|
681
747
|
proxy.finalMemoVersion = Symbol()
|