@mpxjs/webpack-plugin 2.9.66 → 2.9.69

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 (112) hide show
  1. package/lib/dependencies/RecordGlobalComponentsDependency.js +11 -12
  2. package/lib/dependencies/RecordRuntimeInfoDependency.js +1 -1
  3. package/lib/index.js +29 -8
  4. package/lib/json-compiler/index.js +2 -11
  5. package/lib/loader.js +24 -45
  6. package/lib/native-loader.js +49 -64
  7. package/lib/platform/json/wx/index.js +3 -10
  8. package/lib/platform/style/wx/index.js +15 -10
  9. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  10. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  11. package/lib/react/index.js +4 -3
  12. package/lib/react/processJSON.js +5 -13
  13. package/lib/react/processMainScript.js +7 -3
  14. package/lib/react/processScript.js +3 -4
  15. package/lib/react/processStyles.js +14 -4
  16. package/lib/react/processTemplate.js +2 -2
  17. package/lib/resolver/AddModePlugin.js +20 -7
  18. package/lib/runtime/components/react/context.ts +2 -0
  19. package/lib/runtime/components/react/dist/context.js +1 -0
  20. package/lib/runtime/components/react/dist/getInnerListeners.js +3 -12
  21. package/lib/runtime/components/react/dist/mpx-button.jsx +44 -9
  22. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  23. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  24. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  25. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  26. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  27. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  28. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  29. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +214 -0
  30. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  31. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +30 -17
  32. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +1 -1
  33. package/lib/runtime/components/react/dist/mpx-form.jsx +33 -24
  34. package/lib/runtime/components/react/dist/mpx-icon.jsx +1 -1
  35. package/lib/runtime/components/react/dist/mpx-image/index.jsx +1 -1
  36. package/lib/runtime/components/react/dist/mpx-input.jsx +44 -38
  37. package/lib/runtime/components/react/dist/mpx-label.jsx +10 -7
  38. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -17
  39. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +378 -294
  40. package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
  41. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +143 -84
  42. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +69 -113
  43. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +30 -17
  44. package/lib/runtime/components/react/dist/mpx-radio.jsx +1 -1
  45. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
  46. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +49 -29
  47. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +1 -1
  48. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +1 -1
  49. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +1 -1
  50. package/lib/runtime/components/react/dist/mpx-switch.jsx +8 -1
  51. package/lib/runtime/components/react/dist/mpx-text.jsx +1 -1
  52. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
  53. package/lib/runtime/components/react/dist/mpx-view.jsx +46 -27
  54. package/lib/runtime/components/react/dist/mpx-web-view.jsx +20 -6
  55. package/lib/runtime/components/react/dist/pickerFaces.js +75 -0
  56. package/lib/runtime/components/react/dist/pickerOverlay.jsx +21 -0
  57. package/lib/runtime/components/react/dist/useAnimationHooks.js +96 -8
  58. package/lib/runtime/components/react/dist/utils.jsx +66 -6
  59. package/lib/runtime/components/react/getInnerListeners.ts +3 -16
  60. package/lib/runtime/components/react/mpx-button.tsx +42 -9
  61. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  62. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  63. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  64. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  65. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  66. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  67. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  68. package/lib/runtime/components/react/mpx-canvas/index.tsx +302 -0
  69. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  70. package/lib/runtime/components/react/mpx-checkbox-group.tsx +52 -29
  71. package/lib/runtime/components/react/mpx-checkbox.tsx +1 -1
  72. package/lib/runtime/components/react/mpx-form.tsx +42 -34
  73. package/lib/runtime/components/react/mpx-icon.tsx +1 -1
  74. package/lib/runtime/components/react/mpx-image/index.tsx +2 -3
  75. package/lib/runtime/components/react/mpx-input.tsx +68 -66
  76. package/lib/runtime/components/react/mpx-label.tsx +11 -8
  77. package/lib/runtime/components/react/mpx-movable-area.tsx +11 -19
  78. package/lib/runtime/components/react/mpx-movable-view.tsx +456 -334
  79. package/lib/runtime/components/react/mpx-navigator.tsx +1 -1
  80. package/lib/runtime/components/react/mpx-picker-view-column.tsx +232 -103
  81. package/lib/runtime/components/react/mpx-picker-view.tsx +126 -122
  82. package/lib/runtime/components/react/mpx-radio-group.tsx +55 -29
  83. package/lib/runtime/components/react/mpx-radio.tsx +1 -1
  84. package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
  85. package/lib/runtime/components/react/mpx-scroll-view.tsx +81 -36
  86. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +2 -2
  87. package/lib/runtime/components/react/mpx-swiper/index.tsx +2 -1
  88. package/lib/runtime/components/react/mpx-swiper-item.tsx +1 -1
  89. package/lib/runtime/components/react/mpx-switch.tsx +10 -2
  90. package/lib/runtime/components/react/mpx-text.tsx +1 -1
  91. package/lib/runtime/components/react/mpx-textarea.tsx +1 -1
  92. package/lib/runtime/components/react/mpx-view.tsx +58 -28
  93. package/lib/runtime/components/react/mpx-web-view.tsx +23 -6
  94. package/lib/runtime/components/react/pickerFaces.ts +104 -0
  95. package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
  96. package/lib/runtime/components/react/types/common.ts +2 -0
  97. package/lib/runtime/components/react/types/global.d.ts +2 -0
  98. package/lib/runtime/components/react/useAnimationHooks.ts +97 -13
  99. package/lib/runtime/components/react/useNodesRef.ts +1 -0
  100. package/lib/runtime/components/react/utils.tsx +94 -8
  101. package/lib/runtime/optionProcessorReact.js +0 -15
  102. package/lib/runtime/swanHelper.wxs +1 -1
  103. package/lib/style-compiler/index.js +1 -1
  104. package/lib/style-compiler/plugins/scope-id.js +1 -0
  105. package/lib/template-compiler/compiler.js +47 -16
  106. package/lib/template-compiler/gen-node-react.js +2 -2
  107. package/lib/template-compiler/index.js +4 -4
  108. package/lib/utils/pre-process-json.js +113 -0
  109. package/lib/web/index.js +5 -4
  110. package/lib/web/processJSON.js +5 -13
  111. package/lib/web/processTemplate.js +2 -2
  112. package/package.json +5 -4
@@ -45,19 +45,79 @@ const InitialValue = Object.assign({
45
45
  transformOrigin: ['50%', '50%', 0]
46
46
  }, TransformInitial);
47
47
  const TransformOrigin = 'transformOrigin';
48
- // deg 角度
49
- // const isDeg = (key: RuleKey) => ['rotateX', 'rotateY', 'rotateZ', 'rotate', 'skewX', 'skewY'].includes(key)
50
- // 背景色
51
- // const isBg = (key: RuleKey) => key === 'backgroundColor'
52
48
  // transform
53
49
  const isTransform = (key) => Object.keys(TransformInitial).includes(key);
50
+ // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
51
+ const parseTransform = (transformStr) => {
52
+ const values = transformStr.trim().split(/\s+/);
53
+ const transform = [];
54
+ values.forEach(item => {
55
+ const match = item.match(/([/\w]+)\(([^)]+)\)/);
56
+ if (match && match.length >= 3) {
57
+ let key = match[1];
58
+ const val = match[2];
59
+ switch (key) {
60
+ case 'translateX':
61
+ case 'translateY':
62
+ case 'scaleX':
63
+ case 'scaleY':
64
+ case 'rotateX':
65
+ case 'rotateY':
66
+ case 'rotateZ':
67
+ case 'rotate':
68
+ case 'skewX':
69
+ case 'skewY':
70
+ case 'perspective':
71
+ // 单个值处理
72
+ transform.push({ [key]: global.__formatValue(val) });
73
+ break;
74
+ case 'matrix':
75
+ case 'matrix3d':
76
+ transform.push({ [key]: val.split(',').map(val => +val) });
77
+ break;
78
+ case 'translate':
79
+ case 'scale':
80
+ case 'skew':
81
+ case 'rotate3d': // x y z angle
82
+ case 'translate3d': // x y 支持 z不支持
83
+ case 'scale3d': // x y 支持 z不支持
84
+ {
85
+ // 2 个以上的值处理
86
+ key = key.replace('3d', '');
87
+ const vals = val.split(',', key === 'rotate' ? 4 : 3);
88
+ // scale(.5) === scaleX(.5) scaleY(.5) 这里处理一下
89
+ if (vals.length === 1 && key === 'scale') {
90
+ vals.push(vals[0]);
91
+ }
92
+ const xyz = ['X', 'Y', 'Z'];
93
+ transform.push(...vals.map((v, index) => {
94
+ return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
95
+ }));
96
+ break;
97
+ }
98
+ }
99
+ }
100
+ });
101
+ return transform;
102
+ };
103
+ // format style
104
+ const formatStyle = (style) => {
105
+ if (!style.transform || Array.isArray(style.transform))
106
+ return style;
107
+ return Object.assign({}, style, {
108
+ transform: parseTransform(style.transform)
109
+ });
110
+ };
54
111
  export default function useAnimationHooks(props) {
55
- const { style: originalStyle = {}, animation } = props;
112
+ const { style = {}, animation } = props;
113
+ const originalStyle = formatStyle(style);
56
114
  // id 标识
57
115
  const id = animation?.id || -1;
58
116
  // 有动画样式的 style key
59
117
  const animatedStyleKeys = useSharedValue([]);
118
+ // 记录动画key的style样式值 没有的话设置为false
60
119
  const animatedKeys = useRef({});
120
+ // const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
61
121
  // ** 全量 style prop sharedValue
62
122
  // 不能做增量的原因:
63
123
  // 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
@@ -80,6 +140,16 @@ export default function useAnimationHooks(props) {
80
140
  // 驱动动画
81
141
  createAnimation(keys);
82
142
  }, [id]);
143
+ // 同步style更新
144
+ // useEffect(() => {
145
+ // Object.keys(animatedKeys.current).forEach(key => {
146
+ // const originVal = getOriginalStyleVal(key, isTransform(key))
147
+ // if (originVal && animatedKeys.current[key] !== originVal) {
148
+ // animatedKeys.current[key] = originVal
149
+ // shareValMap[key].value = originVal
150
+ // }
151
+ // })
152
+ // }, [style])
83
153
  // ** 清空动画
84
154
  useEffect(() => {
85
155
  return () => {
@@ -115,7 +185,7 @@ export default function useAnimationHooks(props) {
115
185
  animatedKeys.forEach(key => {
116
186
  let toVal = (rules.get(key) || transform.get(key));
117
187
  // key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
118
- if (!toVal) {
188
+ if (toVal === undefined) {
119
189
  toVal = index > 0 ? lastValueMap[key] : shareValMap[key].value;
120
190
  }
121
191
  const animation = getAnimation({ key, value: toVal }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined);
@@ -143,9 +213,8 @@ export default function useAnimationHooks(props) {
143
213
  : withTiming(value, { duration, easing });
144
214
  return delay ? withDelay(delay, animation) : animation;
145
215
  }
146
- // 获取初始值(prop style or 默认值)
147
216
  function getInitialVal(key, isTransform = false) {
148
- if (isTransform && originalStyle.transform?.length) {
217
+ if (isTransform && Array.isArray(originalStyle.transform)) {
149
218
  let initialVal = InitialValue[key];
150
219
  // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
151
220
  originalStyle.transform.forEach(item => {
@@ -156,12 +225,31 @@ export default function useAnimationHooks(props) {
156
225
  }
157
226
  return originalStyle[key] === undefined ? InitialValue[key] : originalStyle[key];
158
227
  }
228
+ // 从 prop style 中获取样式初始值 没有为undefined
229
+ // function getOriginalStyleVal (key: keyof ExtendedViewStyle, isTransform = false) {
230
+ // if (isTransform && Array.isArray(originalStyle.transform)) {
231
+ // let initialVal = undefined // InitialValue[key]
232
+ // // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
233
+ // originalStyle.transform.forEach(item => {
234
+ // if (item[key] !== undefined) initialVal = item[key]
235
+ // })
236
+ // return initialVal
237
+ // }
238
+ // return originalStyle[key] // === undefined ? InitialValue[key] : originalStyle[key]
239
+ // }
240
+ // 获取动画shareVal初始值(prop style or 默认值)
241
+ // function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
242
+ // const originalVal = getOriginalStyleVal(key, isTransform)
243
+ // return originalVal === undefined ? InitialValue[key] : originalStyle[key]
244
+ // }
159
245
  // 循环 animation actions 获取所有有动画的 style prop name
160
246
  function getAnimatedStyleKeys() {
161
247
  return (animation?.actions || []).reduce((keyMap, action) => {
162
248
  const { rules, transform } = action;
163
249
  const ruleArr = [...rules.keys(), ...transform.keys()];
164
250
  ruleArr.forEach(key => {
251
+ // const originalVal = getOriginalStyleVal(key, isTransform(key))
252
+ // if (!keyMap[key]) keyMap[key] = originalVal === undefined ? false : originalVal
165
253
  if (!keyMap[key])
166
254
  keyMap[key] = true;
167
255
  });
@@ -1,15 +1,17 @@
1
- import { useEffect, useRef, isValidElement, useContext, useState, Children, cloneElement } from 'react';
2
- import { isObject, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils';
1
+ import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, Children, cloneElement } from 'react';
2
+ import { Image } from 'react-native';
3
+ import { isObject, isFunction, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils';
3
4
  import { VarContext } from './context';
4
5
  import { ExpressionParser, parseFunc, ReplaceSource } from './parser';
5
6
  import { initialWindowMetrics } from 'react-native-safe-area-context';
7
+ import FastImage from '@d11/react-native-fast-image';
6
8
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/;
7
9
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/;
8
10
  export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/;
9
11
  export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/;
10
12
  export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/;
11
13
  export const DEFAULT_FONT_SIZE = 16;
12
- export const DEFAULT_UNLAY_STYLE = {
14
+ export const HIDDEN_STYLE = {
13
15
  opacity: 0
14
16
  };
15
17
  const varDecRegExp = /^--.*/;
@@ -69,7 +71,7 @@ export const parseInlineStyle = (inlineStyle = '') => {
69
71
  if (rest.length || !v || !k)
70
72
  return styleObj;
71
73
  const key = k.trim().replace(/-./g, c => c.substring(1).toUpperCase());
72
- return Object.assign(styleObj, { [key]: v.trim() });
74
+ return Object.assign(styleObj, { [key]: global.__formatValue(v.trim()) });
73
75
  }, {});
74
76
  };
75
77
  export const parseUrl = (cssUrl = '') => {
@@ -88,7 +90,7 @@ export function isText(ele) {
88
90
  if (isValidElement(ele)) {
89
91
  const displayName = ele.type?.displayName;
90
92
  const isCustomText = ele.type?.isCustomText;
91
- return displayName === 'mpx-text' || displayName === 'Text' || !!isCustomText;
93
+ return displayName === 'MpxText' || displayName === 'Text' || !!isCustomText;
92
94
  }
93
95
  return false;
94
96
  }
@@ -402,7 +404,7 @@ export function splitProps(props) {
402
404
  export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }) => {
403
405
  const layoutRef = useRef({});
404
406
  const hasLayoutRef = useRef(false);
405
- const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? DEFAULT_UNLAY_STYLE : {};
407
+ const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {};
406
408
  const layoutProps = {};
407
409
  const enableOffset = props['enable-offset'];
408
410
  if (hasSelfPercent || onLayout || enableOffset) {
@@ -444,3 +446,61 @@ export function wrapChildren(props = {}, { hasVarDec, varContext, textStyle, tex
444
446
  }
445
447
  return children;
446
448
  }
449
+ export const debounce = (func, delay) => {
450
+ let timer;
451
+ const wrapper = (...args) => {
452
+ clearTimeout(timer);
453
+ timer = setTimeout(() => {
454
+ func(...args);
455
+ }, delay);
456
+ };
457
+ wrapper.clear = () => {
458
+ clearTimeout(timer);
459
+ };
460
+ return wrapper;
461
+ };
462
+ export const useDebounceCallback = (func, delay) => {
463
+ const debounced = useMemo(() => debounce(func, delay), [func]);
464
+ return debounced;
465
+ };
466
+ export const useStableCallback = (callback) => {
467
+ const ref = useRef(callback);
468
+ ref.current = callback;
469
+ return useCallback((...args) => ref.current?.(...args), []);
470
+ };
471
+ export const usePrevious = (value) => {
472
+ const ref = useRef(undefined);
473
+ const prev = ref.current;
474
+ ref.current = value;
475
+ return prev;
476
+ };
477
+ export function flatGesture(gestures = []) {
478
+ return (gestures && gestures.flatMap((gesture) => {
479
+ if (gesture && gesture.nodeRefs) {
480
+ return gesture.nodeRefs
481
+ .map((item) => item.getNodeInstance()?.instance?.gestureRef || {});
482
+ }
483
+ return gesture?.current ? [gesture] : [];
484
+ })) || [];
485
+ }
486
+ export function extendObject(...args) {
487
+ return Object.assign({}, ...args);
488
+ }
489
+ export function getCurrentPage(pageId) {
490
+ if (!global.getCurrentPages)
491
+ return;
492
+ const pages = global.getCurrentPages();
493
+ return pages.find((page) => isFunction(page.getPageId) && page.getPageId() === pageId);
494
+ }
495
+ export function renderImage(imageProps, enableFastImage = false) {
496
+ const Component = enableFastImage ? FastImage : Image;
497
+ return <Component {...imageProps}/>;
498
+ }
499
+ export function pickStyle(styleObj = {}, pickedKeys, callback) {
500
+ return pickedKeys.reduce((acc, key) => {
501
+ if (key in styleObj) {
502
+ acc[key] = callback ? callback(key, styleObj[key]) : styleObj[key];
503
+ }
504
+ return acc;
505
+ }, {});
506
+ }
@@ -1,4 +1,5 @@
1
1
  import { useRef } from 'react'
2
+ import { collectDataset } from '@mpxjs/utils'
2
3
  import { omit } from './utils'
3
4
  import eventConfigMap from './event.config'
4
5
  import {
@@ -8,7 +9,6 @@ import {
8
9
  UseInnerPropsConfig,
9
10
  InnerRef,
10
11
  SetTimeoutReturnType,
11
- DataSetType,
12
12
  LayoutRef,
13
13
  NativeTouchEvent
14
14
  } from './types/getInnerListeners'
@@ -36,7 +36,7 @@ const getTouchEvent = (
36
36
  currentTarget: {
37
37
  ...(event.currentTarget || {}),
38
38
  id: id || '',
39
- dataset: getDataSet(props),
39
+ dataset: collectDataset(props),
40
40
  offsetLeft: layoutRef?.current?.offsetLeft || 0,
41
41
  offsetTop: layoutRef?.current?.offsetTop || 0
42
42
  },
@@ -68,19 +68,6 @@ const getTouchEvent = (
68
68
  }
69
69
  }
70
70
 
71
- export const getDataSet = (props: Record<string, any>) => {
72
- const result: DataSetType = {}
73
-
74
- for (const key in props) {
75
- if (key.indexOf('data-') === 0) {
76
- const newKey = key.substr(5)
77
- result[newKey] = props[key]
78
- }
79
- }
80
-
81
- return result
82
- }
83
-
84
71
  export const getCustomEvent = (
85
72
  type = '',
86
73
  oe: any = {},
@@ -94,7 +81,7 @@ export const getCustomEvent = (
94
81
  target: {
95
82
  ...(oe.target || {}),
96
83
  id: props.id || '',
97
- dataset: getDataSet(props),
84
+ dataset: collectDataset(props),
98
85
  offsetLeft: layoutRef?.current?.offsetLeft || 0,
99
86
  offsetTop: layoutRef?.current?.offsetTop || 0
100
87
  },
@@ -45,10 +45,10 @@ import {
45
45
  NativeSyntheticEvent
46
46
  } from 'react-native'
47
47
  import { warn } from '@mpxjs/utils'
48
- import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren } from './utils'
48
+ import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren } from './utils'
49
49
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
50
50
  import useNodesRef, { HandlerRef } from './useNodesRef'
51
- import { FormContext } from './context'
51
+ import { RouteContext, FormContext } from './context'
52
52
 
53
53
  export type Type = 'default' | 'primary' | 'warn'
54
54
 
@@ -128,7 +128,8 @@ const styles = StyleSheet.create({
128
128
  }
129
129
  })
130
130
 
131
- const getOpenTypeEvent = (openType: OpenType) => {
131
+ const getOpenTypeEvent = (openType?: OpenType) => {
132
+ if (!openType) return
132
133
  if (!global.__mpx?.config?.rnConfig) {
133
134
  warn('Environment not supported')
134
135
  return
@@ -148,6 +149,12 @@ const getOpenTypeEvent = (openType: OpenType) => {
148
149
  return event
149
150
  }
150
151
 
152
+ const timer = (data: any, time = 3000) => new Promise((resolve) => {
153
+ setTimeout(() => {
154
+ resolve(data)
155
+ }, time)
156
+ })
157
+
151
158
  const Loading = ({ alone = false }: { alone: boolean }): JSX.Element => {
152
159
  const image = useRef(new Animated.Value(0)).current
153
160
 
@@ -211,6 +218,8 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
211
218
  bindtouchend
212
219
  } = props
213
220
 
221
+ const pageId = useContext(RouteContext)
222
+
214
223
  const formContext = useContext(FormContext)
215
224
 
216
225
  let submitFn: () => void | undefined
@@ -310,17 +319,41 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
310
319
  }
311
320
 
312
321
  const handleOpenTypeEvent = (evt: NativeSyntheticEvent<TouchEvent>) => {
313
- if (!openType) return
314
322
  const handleEvent = getOpenTypeEvent(openType)
323
+ if (!handleEvent) return
315
324
 
316
325
  if (openType === 'share') {
317
- handleEvent && handleEvent({
326
+ const currentPage = getCurrentPage(pageId)
327
+ const event = {
318
328
  from: 'button',
319
- target: getCustomEvent('tap', evt, { layoutRef }, props).target
320
- })
329
+ target: getCustomEvent('tap', evt, { layoutRef }, props).target,
330
+ webViewUrl: currentPage?.__webViewUrl
331
+ }
332
+ if (currentPage) {
333
+ const defaultMessage = {
334
+ title: global.__mpx.config.rnConfig.projectName || 'AwesomeProject',
335
+ path: currentPage.route || ''
336
+ }
337
+ if (currentPage.onShareAppMessage) {
338
+ const { promise, ...message } = currentPage.onShareAppMessage(event) || {}
339
+ if (promise) {
340
+ Promise.race([Promise.resolve(promise), timer(message)])
341
+ .then((msg) => {
342
+ handleEvent(Object.assign({}, defaultMessage, msg))
343
+ })
344
+ } else {
345
+ handleEvent(Object.assign({}, defaultMessage, message))
346
+ }
347
+ } else {
348
+ handleEvent(defaultMessage)
349
+ }
350
+ } else {
351
+ warn('Current page not found')
352
+ // Todo handleEvent(event)
353
+ }
321
354
  }
322
355
 
323
- if (openType === 'getUserInfo' && handleEvent && bindgetuserinfo) {
356
+ if (openType === 'getUserInfo' && bindgetuserinfo) {
324
357
  Promise.resolve(handleEvent)
325
358
  .then((userInfo) => {
326
359
  if (typeof userInfo === 'object') {
@@ -408,6 +441,6 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
408
441
  )
409
442
  })
410
443
 
411
- Button.displayName = 'mpx-button'
444
+ Button.displayName = 'MpxButton'
412
445
 
413
446
  export default Button
@@ -0,0 +1,70 @@
1
+ import { warn } from '@mpxjs/utils'
2
+ interface Message {
3
+ id?: string
4
+ type: string
5
+ payload?: any
6
+ }
7
+ export default class Bus {
8
+ _paused: Boolean = false;
9
+ _messageListeners: { [key: string]: (message: Message) => void } = {}
10
+ _queue: Message[] = []
11
+ _send: (message: Message | Message[]) => void
12
+ _timeoutId: NodeJS.Timeout | null = null
13
+ constructor (send: (message: Message | Message[]) => void) {
14
+ this._send = send
15
+ }
16
+
17
+ post (message: Message): Promise<any> {
18
+ return new Promise((resolve) => {
19
+ if (message.type !== 'set' && message.id) {
20
+ this._messageListeners[message.id] = resolve
21
+ }
22
+
23
+ if (!this._paused) {
24
+ this._queue.push(message)
25
+ this.startBatching()
26
+ } else {
27
+ this._queue.push(message)
28
+ }
29
+ })
30
+ }
31
+
32
+ handle (message: Message): void {
33
+ if (!message.id) return
34
+ const handler = this._messageListeners[message.id]
35
+ delete this._messageListeners[message.id]
36
+
37
+ if (handler) {
38
+ handler(message)
39
+ } else {
40
+ warn(`Received unexpected message: ${message}`)
41
+ }
42
+ }
43
+
44
+ pause (): void {
45
+ this._paused = true
46
+ }
47
+
48
+ resume (): void {
49
+ this._paused = false
50
+ this._send(this._queue)
51
+ this._queue = []
52
+ }
53
+
54
+ startBatching (): void {
55
+ if (this._timeoutId) return
56
+
57
+ this._timeoutId = setTimeout(() => {
58
+ this._send(this._queue)
59
+ this._queue = []
60
+ this._timeoutId = null
61
+ }, 16)
62
+ }
63
+
64
+ clearBatchingTimeout (): void {
65
+ if (this._timeoutId) {
66
+ clearTimeout(this._timeoutId)
67
+ this._timeoutId = null
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,18 @@
1
+ import { WebviewMessage, CanvasInstance, registerWebviewMethods } from './utils'
2
+
3
+ const METHODS = ['addColorStop']
4
+ export default class CanvasGradient {
5
+ private canvas: CanvasInstance;
6
+ [key: string]: any;
7
+ constructor (canvas: CanvasInstance, noOnConstruction = false) {
8
+ this.canvas = canvas
9
+ registerWebviewMethods(this, METHODS)
10
+ if (this.onConstruction && !noOnConstruction) {
11
+ this.onConstruction()
12
+ }
13
+ }
14
+
15
+ postMessage (message: WebviewMessage) {
16
+ return this.canvas.postMessage(message)
17
+ }
18
+ }
@@ -0,0 +1,87 @@
1
+ import { CanvasInstance, WebviewMessage, registerWebviewProperties, registerWebviewMethods, registerWebviewTarget } from './utils'
2
+
3
+ const PROPERTIES = {
4
+ direction: 'inherit',
5
+ fillStyle: '#000',
6
+ filter: 'none',
7
+ font: '10px sans-serif',
8
+ fontKerning: 'auto',
9
+ fontStretch: 'auto',
10
+ fontVariantCaps: 'normal',
11
+ globalAlpha: 1.0,
12
+ globalCompositeOperation: 'source-over',
13
+ imageSmoothingEnabled: 'true',
14
+ imageSmoothingQuality: 'low',
15
+ letterSpacing: '0px',
16
+ lineCap: 'butt',
17
+ lineDashOffset: 0.0,
18
+ lineJoin: 'miter',
19
+ lineWidth: 1.0,
20
+ miterLimit: 10.0,
21
+ shadowBlur: 0,
22
+ shadowColor: 'rgba(0,0,0,0)',
23
+ shadowOffsetX: 0,
24
+ shadowOffsetY: 0,
25
+ strokeStyle: '#000',
26
+ textAlign: 'start',
27
+ textBaseline: 'alphabetic',
28
+ textRendering: 'auto',
29
+ wordSpacing: '0px'
30
+ }
31
+
32
+ const METHODS = [
33
+ 'arc',
34
+ 'arcTo',
35
+ 'beginPath',
36
+ 'bezierCurveTo',
37
+ 'clearRect',
38
+ 'clip',
39
+ 'closePath',
40
+ 'createConicGradient',
41
+ 'createImageData',
42
+ 'createLinearGradient',
43
+ 'createPattern',
44
+ 'createRadialGradient',
45
+ 'drawFocusIfNeeded',
46
+ 'drawImage',
47
+ 'ellipse',
48
+ 'fill',
49
+ 'fillRect',
50
+ 'fillText',
51
+ 'getImageData',
52
+ 'getLineDash',
53
+ 'getTransform',
54
+ 'lineTo',
55
+ 'measureText',
56
+ 'moveTo',
57
+ 'putImageData',
58
+ 'quadraticCurveTo',
59
+ 'rect',
60
+ 'reset',
61
+ 'resetTransform',
62
+ 'restore',
63
+ 'rotate',
64
+ 'roundRect',
65
+ 'save',
66
+ 'scale',
67
+ 'setLineDash',
68
+ 'setTransform',
69
+ 'stroke',
70
+ 'strokeRect',
71
+ 'strokeText',
72
+ 'transform',
73
+ 'translate'
74
+ ]
75
+ export default class CanvasRenderingContext2D {
76
+ canvas: CanvasInstance
77
+ constructor (canvas: CanvasInstance) {
78
+ this.canvas = canvas
79
+ registerWebviewTarget(this, 'context2D')
80
+ registerWebviewProperties(this, PROPERTIES)
81
+ registerWebviewMethods(this, METHODS)
82
+ }
83
+
84
+ postMessage (message: WebviewMessage) {
85
+ return this.canvas.postMessage(message)
86
+ }
87
+ }
@@ -0,0 +1,102 @@
1
+ import { WebviewMessage, WEBVIEW_TARGET, registerWebviewProperties, CanvasInstance } from './utils'
2
+
3
+ const PROPERTIES = {
4
+ crossOrigin: undefined,
5
+ height: undefined,
6
+ src: undefined,
7
+ width: undefined
8
+ }
9
+
10
+ export class Image {
11
+ [WEBVIEW_TARGET]: string;
12
+ canvas: any;
13
+ width: number;
14
+ height: number;
15
+ private _loadListener: any;
16
+ private _errorListener: any;
17
+ private _onload: ((...args: any[]) => void);
18
+ private _onerror: ((...args: any[]) => void);
19
+ [key: string]: any;
20
+
21
+ constructor (canvas: CanvasInstance, width?: number, height?: number, noOnConstruction = false) {
22
+ this.canvas = canvas
23
+ registerWebviewProperties(this, PROPERTIES)
24
+
25
+ if (width) {
26
+ this.width = width
27
+ }
28
+ if (height) {
29
+ this.height = height
30
+ }
31
+
32
+ if (this.onConstruction && !noOnConstruction) {
33
+ this.onConstruction()
34
+ this.postMessage({
35
+ type: 'listen',
36
+ payload: {
37
+ types: ['error', 'load'],
38
+ target: this[WEBVIEW_TARGET]
39
+ }
40
+ })
41
+ }
42
+ }
43
+
44
+ postMessage (message: WebviewMessage) {
45
+ return this.canvas.postMessage(message)
46
+ }
47
+
48
+ addEventListener (type: 'load' | 'error', callbackFn: Function) {
49
+ return this.canvas.addMessageListener((message: WebviewMessage) => {
50
+ const target = message?.payload?.target as { [key: string]: any } || {}
51
+ if (
52
+ message &&
53
+ message.type === 'event' &&
54
+ target[WEBVIEW_TARGET] === this[WEBVIEW_TARGET] &&
55
+ message.payload.type === type
56
+ ) {
57
+ for (const key in target) {
58
+ const value = target[key]
59
+ if (key in this && this[key] !== value) {
60
+ this[key] = value
61
+ }
62
+ }
63
+ callbackFn({
64
+ ...message.payload,
65
+ target: this
66
+ })
67
+ }
68
+ })
69
+ }
70
+
71
+ set onload (callback: ((...args: any[]) => void)) {
72
+ this._onload = callback
73
+ if (this._loadListener) {
74
+ this.canvas.removeMessageListener(this._loadListener)
75
+ }
76
+ if (callback) {
77
+ this._loadListener = this.addEventListener('load', callback)
78
+ }
79
+ }
80
+
81
+ get onload (): ((...args: any[]) => void) {
82
+ return this._onload
83
+ }
84
+
85
+ set onerror (callback: ((...args: any[]) => void)) {
86
+ this._onerror = callback
87
+ if (this._errorListener) {
88
+ this.canvas.removeMessageListener(this._errorListener)
89
+ }
90
+ if (callback) {
91
+ this._errorListener = this.addEventListener('error', callback)
92
+ }
93
+ }
94
+
95
+ get onerror () : ((...args: any[]) => void) {
96
+ return this._onerror
97
+ }
98
+ }
99
+
100
+ export function createImage (canvas: CanvasInstance, width?: number, height?: number) {
101
+ return new Image(canvas, width, height)
102
+ }