@mpxjs/core 2.9.38 → 2.9.41-react.0

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 (44) hide show
  1. package/package.json +37 -3
  2. package/src/convertor/convertor.js +4 -1
  3. package/src/convertor/getConvertMode.js +3 -1
  4. package/src/convertor/wxToReact.js +31 -0
  5. package/src/core/proxy.js +75 -7
  6. package/src/core/transferOptions.js +9 -1
  7. package/src/dynamic/astCache.js +25 -0
  8. package/src/dynamic/dynamicRenderMixin.js +77 -0
  9. package/src/dynamic/vnode/context.js +17 -0
  10. package/src/dynamic/vnode/css-select/cssauron.js +445 -0
  11. package/src/dynamic/vnode/css-select/index.js +116 -0
  12. package/src/dynamic/vnode/css-select/through.js +19 -0
  13. package/src/dynamic/vnode/css-select/tokenizer.js +371 -0
  14. package/src/dynamic/vnode/interpreter.js +449 -0
  15. package/src/dynamic/vnode/render.js +289 -0
  16. package/src/{vuePlugin.js → external/vuePlugin.js} +1 -1
  17. package/src/index.js +8 -2
  18. package/src/platform/builtInMixins/directiveHelperMixin.android.js +2 -0
  19. package/src/platform/builtInMixins/directiveHelperMixin.ios.js +15 -0
  20. package/src/platform/builtInMixins/directiveHelperMixin.js +3 -0
  21. package/src/platform/builtInMixins/index.js +20 -2
  22. package/src/platform/builtInMixins/proxyEventMixin.android.js +2 -0
  23. package/src/platform/builtInMixins/proxyEventMixin.ios.js +49 -0
  24. package/src/platform/builtInMixins/proxyEventMixin.js +12 -14
  25. package/src/platform/builtInMixins/refsMixin.android.js +2 -0
  26. package/src/platform/builtInMixins/refsMixin.ios.js +311 -0
  27. package/src/platform/builtInMixins/renderHelperMixin.js +2 -2
  28. package/src/platform/builtInMixins/styleHelperMixin.android.js +2 -0
  29. package/src/platform/builtInMixins/styleHelperMixin.ios.js +141 -0
  30. package/src/platform/builtInMixins/styleHelperMixin.js +3 -0
  31. package/src/platform/createApp.android.js +2 -0
  32. package/src/platform/createApp.ios.js +103 -0
  33. package/src/platform/createApp.js +3 -5
  34. package/src/platform/export/api.web.js +1 -1
  35. package/src/platform/patch/ali/getDefaultOptions.js +24 -4
  36. package/src/platform/patch/index.js +9 -6
  37. package/src/platform/patch/react/getDefaultOptions.android.js +1 -0
  38. package/src/platform/patch/react/getDefaultOptions.ios.js +270 -0
  39. package/src/platform/patch/react/getDefaultOptions.js +1 -0
  40. package/src/platform/patch/swan/getDefaultOptions.js +1 -1
  41. package/src/platform/patch/web/getDefaultOptions.js +13 -3
  42. package/src/platform/patch/wx/getDefaultOptions.js +21 -1
  43. /package/src/{vue.js → external/vue.js} +0 -0
  44. /package/src/{vue.web.js → external/vue.web.js} +0 -0
@@ -4,14 +4,15 @@ import { getDefaultOptions as getWxDefaultOptions } from './wx/getDefaultOptions
4
4
  import { getDefaultOptions as getAliDefaultOptions } from './ali/getDefaultOptions'
5
5
  import { getDefaultOptions as getSwanDefaultOptions } from './swan/getDefaultOptions'
6
6
  import { getDefaultOptions as getWebDefaultOptions } from './web/getDefaultOptions'
7
- import { error } from '@mpxjs/utils'
7
+ import { getDefaultOptions as getReactDefaultOptions } from './react/getDefaultOptions'
8
+ import { error, isReact } from '@mpxjs/utils'
8
9
 
9
10
  export default function createFactory (type) {
10
11
  return (options = {}, { isNative, customCtor, customCtorType } = {}) => {
11
12
  options.__nativeRender__ = !!isNative
12
13
  options.__type__ = type
13
14
  let ctor
14
- if (__mpx_mode__ !== 'web') {
15
+ if (__mpx_mode__ !== 'web' && !isReact) {
15
16
  if (customCtor) {
16
17
  ctor = customCtor
17
18
  customCtorType = customCtorType || type
@@ -39,7 +40,9 @@ export default function createFactory (type) {
39
40
  }
40
41
 
41
42
  let getDefaultOptions
42
- if (__mpx_mode__ === 'web') {
43
+ if (isReact) {
44
+ getDefaultOptions = getReactDefaultOptions
45
+ } else if (__mpx_mode__ === 'web') {
43
46
  getDefaultOptions = getWebDefaultOptions
44
47
  } else if (__mpx_mode__ === 'ali') {
45
48
  getDefaultOptions = getAliDefaultOptions
@@ -56,10 +59,10 @@ export default function createFactory (type) {
56
59
  // 注入内建的mixins, 内建mixin是按原始平台编写的,所以合并规则和rootMixins保持一致
57
60
  // 将合并后的用户定义的rawOptions传入获取当前应该注入的内建mixins
58
61
  rawOptions.mixins = getBuiltInMixins(rawOptions, type)
59
- const defaultOptions = getDefaultOptions(type, { rawOptions, currentInject })
60
- if (__mpx_mode__ === 'web') {
62
+ const defaultOptions = getDefaultOptions({ type, rawOptions, currentInject })
63
+ if (__mpx_mode__ === 'web' || isReact) {
61
64
  global.__mpxOptionsMap = global.__mpxOptionsMap || {}
62
- global.__mpxOptionsMap[global.currentModuleId] = defaultOptions
65
+ global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
63
66
  } else if (ctor) {
64
67
  return ctor(defaultOptions)
65
68
  }
@@ -0,0 +1 @@
1
+ export { getDefaultOptions } from './getDefaultOptions.ios'
@@ -0,0 +1,270 @@
1
+ import { useEffect, useSyncExternalStore, useRef, createElement, memo, forwardRef, useImperativeHandle } from 'react'
2
+ import * as ReactNative from 'react-native'
3
+ import { ReactiveEffect } from '../../../observer/effect'
4
+ import { hasOwn, isFunction, noop, isObject, error, getByPath, collectDataset } from '@mpxjs/utils'
5
+ import MpxProxy from '../../../core/proxy'
6
+ import { BEFOREUPDATE, UPDATED } from '../../../core/innerLifecycle'
7
+ import mergeOptions from '../../../core/mergeOptions'
8
+ import { queueJob } from '../../../observer/scheduler'
9
+
10
+ function getNativeComponent (tagName) {
11
+ return getByPath(ReactNative, tagName)
12
+ }
13
+
14
+ function getRootProps (props) {
15
+ const rootProps = {}
16
+ for (const key in props) {
17
+ if (hasOwn(props, key)) {
18
+ const match = /^(bind|catch|capture-bind|capture-catch|style):?(.*?)(?:\.(.*))?$/.exec(key)
19
+ if (match) {
20
+ rootProps[key] = props[key]
21
+ }
22
+ }
23
+ }
24
+ return rootProps
25
+ }
26
+
27
+ function createEffect (proxy, components, props) {
28
+ const update = proxy.update = () => {
29
+ // pre render for props update
30
+ if (proxy.propsUpdatedFlag) {
31
+ proxy.updatePreRender()
32
+ }
33
+ if (proxy.isMounted()) {
34
+ proxy.callHook(BEFOREUPDATE)
35
+ proxy.pendingUpdatedFlag = true
36
+ }
37
+ // eslint-disable-next-line symbol-description
38
+ proxy.stateVersion = Symbol()
39
+ proxy.onStoreChange && proxy.onStoreChange()
40
+ }
41
+ update.id = proxy.uid
42
+ proxy.effect = new ReactiveEffect(() => {
43
+ return proxy.target.__injectedRender(createElement, components, getNativeComponent, getRootProps(props))
44
+ }, () => queueJob(update), proxy.scope)
45
+ }
46
+
47
+ function createInstance ({ propsRef, ref, type, rawOptions, currentInject, validProps, components }) {
48
+ const instance = Object.create({
49
+ setData (data, callback) {
50
+ return this.__mpxProxy.forceUpdate(data, { sync: true }, callback)
51
+ },
52
+ __getProps () {
53
+ const propsData = {}
54
+ const props = propsRef.current
55
+ if (props) {
56
+ Object.keys(props).forEach((key) => {
57
+ if (hasOwn(validProps, key) && !isFunction(props[key])) {
58
+ propsData[key] = props[key]
59
+ }
60
+ })
61
+ }
62
+ return propsData
63
+ },
64
+ __getSlot (name) {
65
+ const { children } = propsRef.current || {}
66
+ if (children) {
67
+ const result = []
68
+ if (Array.isArray(children)) {
69
+ children.forEach(child => {
70
+ if (child && child.props && child.props.slot === name) {
71
+ result.push(child)
72
+ }
73
+ })
74
+ } else {
75
+ if (children && children.props && children.props.slot === name) {
76
+ result.push(children)
77
+ }
78
+ }
79
+ return result.filter(item => {
80
+ if (this.__dispatchedSlotSet.has(item)) {
81
+ return false
82
+ } else {
83
+ this.__dispatchedSlotSet.add(item)
84
+ return true
85
+ }
86
+ })
87
+ }
88
+ return null
89
+ },
90
+ __injectedRender: currentInject.render || noop,
91
+ __getRefsData: currentInject.getRefsData || noop,
92
+ // render helper
93
+ _i (val, fn) {
94
+ let i, l, keys, key
95
+ const result = []
96
+ if (Array.isArray(val) || typeof val === 'string') {
97
+ for (i = 0, l = val.length; i < l; i++) {
98
+ result.push(fn.call(this, val[i], i))
99
+ }
100
+ } else if (typeof val === 'number') {
101
+ for (i = 0; i < val; i++) {
102
+ result.push(fn.call(this, i + 1, i))
103
+ }
104
+ } else if (isObject(val)) {
105
+ keys = Object.keys(val)
106
+ for (i = 0, l = keys.length; i < l; i++) {
107
+ key = keys[i]
108
+ result.push(fn.call(this, val[key], key, i))
109
+ }
110
+ }
111
+ return result
112
+ },
113
+ triggerEvent (eventName, eventDetail) {
114
+ const props = propsRef.current
115
+ const handlerName = eventName.replace(/^./, matched => matched.toUpperCase()).replace(/-([a-z])/g, (match, p1) => p1.toUpperCase())
116
+ const handler = props && (props['bind' + handlerName] || props['catch' + handlerName] || props['capture-bind' + handlerName] || props['capture-catch' + handlerName])
117
+ if (handler && typeof handler === 'function') {
118
+ const timeStamp = +new Date()
119
+ const dataset = collectDataset(props)
120
+ const id = props.id || ''
121
+ const eventObj = {
122
+ type: eventName,
123
+ timeStamp,
124
+ target: {
125
+ id,
126
+ dataset,
127
+ targetDataset: dataset
128
+ },
129
+ currentTarget: {
130
+ id,
131
+ dataset
132
+ },
133
+ detail: eventDetail
134
+ }
135
+ handler.call(this, eventObj)
136
+ }
137
+ },
138
+ selectComponent () {
139
+ error('selectComponent is not supported in react native, please use ref instead')
140
+ },
141
+ selectAllComponents () {
142
+ error('selectAllComponents is not supported in react native, please use ref instead')
143
+ },
144
+ createSelectorQuery () {
145
+ error('createSelectorQuery is not supported in react native, please use ref instead')
146
+ },
147
+ createIntersectionObserver () {
148
+ error('createIntersectionObserver is not supported in react native, please use ref instead')
149
+ },
150
+ ...rawOptions.methods
151
+ }, {
152
+ dataset: {
153
+ get () {
154
+ const props = propsRef.current
155
+ return collectDataset(props)
156
+ },
157
+ enumerable: true
158
+ },
159
+ id: {
160
+ get () {
161
+ const props = propsRef.current
162
+ return props.id
163
+ },
164
+ enumerable: true
165
+ }
166
+ })
167
+
168
+ const proxy = instance.__mpxProxy = new MpxProxy(rawOptions, instance)
169
+ proxy.created()
170
+ Object.assign(proxy, {
171
+ onStoreChange: null,
172
+ // eslint-disable-next-line symbol-description
173
+ stateVersion: Symbol(),
174
+ subscribe: (onStoreChange) => {
175
+ if (!proxy.effect) {
176
+ createEffect(proxy, components, propsRef.current)
177
+ // eslint-disable-next-line symbol-description
178
+ proxy.stateVersion = Symbol()
179
+ }
180
+ proxy.onStoreChange = onStoreChange
181
+ return () => {
182
+ proxy.effect && proxy.effect.stop()
183
+ proxy.effect = null
184
+ proxy.onStoreChange = null
185
+ }
186
+ },
187
+ getSnapshot: () => {
188
+ return proxy.stateVersion
189
+ }
190
+ })
191
+ // react数据响应组件更新管理器
192
+ if (!proxy.effect) {
193
+ createEffect(proxy, components, propsRef.current)
194
+ }
195
+
196
+ return instance
197
+ }
198
+
199
+ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
200
+ rawOptions = mergeOptions(rawOptions, type, false)
201
+ const { RootSiblingParent } = global.__navigationHelper
202
+ const components = currentInject.getComponents() || {}
203
+ const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
204
+ const defaultOptions = memo(forwardRef((props, ref) => {
205
+ const instanceRef = useRef(null)
206
+ const propsRef = useRef(props)
207
+ let isFirst = false
208
+ if (!instanceRef.current) {
209
+ isFirst = true
210
+ instanceRef.current = createInstance({ propsRef, ref, type, rawOptions, currentInject, validProps, components })
211
+ }
212
+ const instance = instanceRef.current
213
+ // reset instance
214
+ instance.__refs = {}
215
+ instance.__dispatchedSlotSet = new WeakSet()
216
+ useImperativeHandle(ref, () => {
217
+ return instance
218
+ })
219
+ const proxy = instance.__mpxProxy
220
+
221
+ if (!isFirst) {
222
+ // 处理props更新
223
+ propsRef.current = props
224
+ Object.keys(props).forEach(key => {
225
+ if (hasOwn(validProps, key) && !isFunction(props[key])) {
226
+ instance[key] = props[key]
227
+ }
228
+ })
229
+ proxy.propsUpdated()
230
+ }
231
+
232
+ useEffect(() => {
233
+ if (proxy.pendingUpdatedFlag) {
234
+ proxy.pendingUpdatedFlag = false
235
+ proxy.callHook(UPDATED)
236
+ }
237
+ })
238
+
239
+ useEffect(() => {
240
+ proxy.mounted()
241
+ return () => {
242
+ proxy.unmounted()
243
+ }
244
+ }, [])
245
+
246
+ useSyncExternalStore(proxy.subscribe, proxy.getSnapshot)
247
+
248
+ return proxy.effect.run()
249
+ }))
250
+
251
+ if (type === 'page') {
252
+ const Page = () => {
253
+ return createElement(RootSiblingParent,
254
+ null,
255
+ createElement(ReactNative.ScrollView,
256
+ {
257
+ style: {
258
+ ...ReactNative.StyleSheet.absoluteFillObject
259
+ },
260
+ showsVerticalScrollIndicator: false
261
+ },
262
+ createElement(defaultOptions)
263
+ )
264
+ )
265
+ }
266
+ return Page
267
+ }
268
+
269
+ return defaultOptions
270
+ }
@@ -0,0 +1 @@
1
+ export function getDefaultOptions () {}
@@ -1,7 +1,7 @@
1
1
  import mergeOptions from '../../../core/mergeOptions'
2
2
  import { initProxy, filterOptions } from '../wx/getDefaultOptions'
3
3
 
4
- export function getDefaultOptions (type, { rawOptions = {}, currentInject }) {
4
+ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
5
5
  let hookNames = ['attached', 'ready', 'detached']
6
6
  // 当用户传入page作为构造器构造页面时,修改所有关键hooks
7
7
  if (rawOptions.__pageCtor__) {
@@ -3,7 +3,14 @@ import mergeOptions from '../../../core/mergeOptions'
3
3
  import { diffAndCloneA, hasOwn } from '@mpxjs/utils'
4
4
  import { getCurrentInstance as getCurrentVueInstance } from '../../export/index'
5
5
  import MpxProxy, { setCurrentInstance, unsetCurrentInstance } from '../../../core/proxy'
6
- import { BEFORECREATE, BEFOREUPDATE, UPDATED, BEFOREUNMOUNT, UNMOUNTED, SERVERPREFETCH } from '../../../core/innerLifecycle'
6
+ import {
7
+ BEFORECREATE,
8
+ BEFOREUPDATE,
9
+ UPDATED,
10
+ BEFOREUNMOUNT,
11
+ UNMOUNTED,
12
+ SERVERPREFETCH
13
+ } from '../../../core/innerLifecycle'
7
14
 
8
15
  function filterOptions (options) {
9
16
  const newOptions = {}
@@ -37,7 +44,7 @@ function initProxy (context, rawOptions) {
37
44
  }
38
45
  }
39
46
 
40
- export function getDefaultOptions (type, { rawOptions = {} }) {
47
+ export function getDefaultOptions ({ type, rawOptions = {} }) {
41
48
  const rawSetup = rawOptions.setup
42
49
  if (rawSetup) {
43
50
  rawOptions.setup = (props) => {
@@ -78,7 +85,10 @@ export function getDefaultOptions (type, { rawOptions = {} }) {
78
85
  if (this.__mpxProxy) this.__mpxProxy.callHook(BEFOREUNMOUNT)
79
86
  },
80
87
  destroyed () {
81
- if (this.__mpxProxy) this.__mpxProxy.callHook(UNMOUNTED)
88
+ if (this.__mpxProxy) {
89
+ this.__mpxProxy.state = UNMOUNTED
90
+ this.__mpxProxy.callHook(UNMOUNTED)
91
+ }
82
92
  },
83
93
  serverPrefetch () {
84
94
  if (this.__mpxProxy) return this.__mpxProxy.callHook(SERVERPREFETCH)
@@ -101,6 +101,26 @@ function transformApiForProxy (context, currentInject) {
101
101
  }
102
102
  })
103
103
  }
104
+ if (currentInject.moduleId) {
105
+ Object.defineProperties(context, {
106
+ __moduleId: {
107
+ get () {
108
+ return currentInject.moduleId
109
+ },
110
+ configurable: false
111
+ }
112
+ })
113
+ }
114
+ if (currentInject.dynamic) {
115
+ Object.defineProperties(context, {
116
+ __dynamic: {
117
+ get () {
118
+ return currentInject.dynamic
119
+ },
120
+ configurable: false
121
+ }
122
+ })
123
+ }
104
124
  }
105
125
  }
106
126
 
@@ -141,7 +161,7 @@ export function initProxy (context, rawOptions, currentInject) {
141
161
  }
142
162
  }
143
163
 
144
- export function getDefaultOptions (type, { rawOptions = {}, currentInject }) {
164
+ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
145
165
  let hookNames = ['attached', 'ready', 'detached']
146
166
  // 当用户传入page作为构造器构造页面时,修改所有关键hooks
147
167
  if (rawOptions.__pageCtor__) {
File without changes
File without changes