@mpxjs/webpack-plugin 2.9.67 → 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 (48) hide show
  1. package/lib/index.js +13 -8
  2. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  3. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  4. package/lib/react/processStyles.js +14 -4
  5. package/lib/resolver/AddModePlugin.js +8 -8
  6. package/lib/runtime/components/react/context.ts +2 -0
  7. package/lib/runtime/components/react/dist/context.js +1 -0
  8. package/lib/runtime/components/react/dist/getInnerListeners.js +3 -12
  9. package/lib/runtime/components/react/dist/mpx-button.jsx +43 -8
  10. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  11. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  12. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  13. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  14. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  15. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  16. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  17. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +214 -0
  18. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  19. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +143 -84
  20. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +69 -113
  21. package/lib/runtime/components/react/dist/mpx-view.jsx +45 -26
  22. package/lib/runtime/components/react/dist/mpx-web-view.jsx +19 -5
  23. package/lib/runtime/components/react/dist/pickerFaces.js +75 -0
  24. package/lib/runtime/components/react/dist/pickerOverlay.jsx +21 -0
  25. package/lib/runtime/components/react/dist/utils.jsx +54 -3
  26. package/lib/runtime/components/react/getInnerListeners.ts +3 -17
  27. package/lib/runtime/components/react/mpx-button.tsx +41 -8
  28. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  29. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  30. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  31. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  32. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  33. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  34. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  35. package/lib/runtime/components/react/mpx-canvas/index.tsx +302 -0
  36. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  37. package/lib/runtime/components/react/mpx-picker-view-column.tsx +232 -103
  38. package/lib/runtime/components/react/mpx-picker-view.tsx +126 -122
  39. package/lib/runtime/components/react/mpx-view.tsx +57 -27
  40. package/lib/runtime/components/react/mpx-web-view.tsx +22 -5
  41. package/lib/runtime/components/react/pickerFaces.ts +104 -0
  42. package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
  43. package/lib/runtime/components/react/types/common.ts +2 -0
  44. package/lib/runtime/components/react/types/global.d.ts +2 -0
  45. package/lib/runtime/components/react/utils.tsx +78 -7
  46. package/lib/template-compiler/compiler.js +3 -2
  47. package/lib/template-compiler/gen-node-react.js +2 -2
  48. package/package.json +5 -4
@@ -0,0 +1,23 @@
1
+ import {
2
+ WebviewMessage,
3
+ CanvasInstance
4
+ } from './utils'
5
+
6
+ export default class ImageData {
7
+ canvas: CanvasInstance;
8
+ [key: string]: any;
9
+ constructor (canvas: CanvasInstance, dataArray: number[], width: number, height: number, noOnConstruction?: boolean) {
10
+ this.canvas = canvas
11
+ if (this.onConstruction && !noOnConstruction) {
12
+ this.onConstruction(dataArray, width, height)
13
+ }
14
+ }
15
+
16
+ postMessage = (message: WebviewMessage) => {
17
+ return this.canvas.postMessage(message)
18
+ };
19
+ }
20
+
21
+ export function createImageData (canvas: CanvasInstance, dataArray: number[], width: number, height: number) {
22
+ return new ImageData(canvas, dataArray, width, height)
23
+ }
@@ -0,0 +1,38 @@
1
+ import { Image } from './Image'
2
+ import CanvasGradient from './CanvasGradient'
3
+ import ImageData from './ImageData'
4
+ import { WebviewConstructor } from './utils'
5
+
6
+ export enum ConstructorType {
7
+ Image = 'Image',
8
+ CanvasGradient = 'CanvasGradient',
9
+ ImageData = 'ImageData'
10
+ }
11
+
12
+ interface Constructor {
13
+ type: ConstructorType
14
+ instance: WebviewConstructor
15
+ }
16
+
17
+ const constructors: Constructor[] = [
18
+ { type: ConstructorType.Image, instance: Image },
19
+ { type: ConstructorType.CanvasGradient, instance: CanvasGradient },
20
+ { type: ConstructorType.ImageData, instance: ImageData }
21
+ ]
22
+
23
+ export function useConstructorsRegistry () {
24
+ const register = (registerWebviewConstructor: Function): void => {
25
+ constructors.forEach(({ type, instance }) => {
26
+ registerWebviewConstructor(instance, type)
27
+ })
28
+ }
29
+
30
+ const getConstructor = (type: ConstructorType): WebviewConstructor | undefined => {
31
+ return constructors.find(c => c.type === type)?.instance
32
+ }
33
+
34
+ return {
35
+ register,
36
+ getConstructor
37
+ }
38
+ }
@@ -0,0 +1,343 @@
1
+ export default `<html><head>
2
+ <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scaleable=no" name="viewport">
3
+ <style>
4
+ html {
5
+ -ms-content-zooming: none;
6
+ -ms-touch-action: pan-x pan-y;
7
+ }
8
+ body {
9
+ position: fixed;
10
+ top: 0;
11
+ right: 0;
12
+ bottom: 0;
13
+ left: 0;
14
+ margin: 0;
15
+ padding: 0;
16
+ overflow: hidden;
17
+ }
18
+ * {
19
+ user-select: none;
20
+ -ms-user-select: none;
21
+ -moz-user-select: none;
22
+ -webkit-user-select: none;
23
+ }
24
+ </style>
25
+ </head>
26
+ <body>
27
+ <script>
28
+ var scale = function (ratio) {
29
+ return function (item) {
30
+ if (typeof item === "number") {
31
+ return item * ratio;
32
+ }
33
+ return item;
34
+ };
35
+ };
36
+ function autoScaleCanvas(canvas) {
37
+ var ctx = canvas.getContext("2d");
38
+ var ratio = window.devicePixelRatio || 1;
39
+ if (ratio !== 1) {
40
+ canvas.width *= ratio;
41
+ canvas.height *= ratio;
42
+ ctx.scale(ratio, ratio);
43
+ ctx.isPointInPath = function () {
44
+ var args = [];
45
+ for (var _i = 0; _i < arguments.length; _i++) {
46
+ args[_i] = arguments[_i];
47
+ }
48
+ return CanvasRenderingContext2D.prototype.isPointInPath.apply(ctx, args.map(scale(ratio)));
49
+ };
50
+ }
51
+ return canvas;
52
+ }
53
+ window.autoScaleCanvas = autoScaleCanvas;
54
+ </script>
55
+ <script>
56
+
57
+ var WEBVIEW_TARGET = '@@WEBVIEW_TARGET';
58
+
59
+ var ID = function () {
60
+ return Math.random().toString(32).slice(2);
61
+ };
62
+
63
+ var flattenObjectCopyValue = function (flatObj, srcObj, key) {
64
+ var value = srcObj[key];
65
+ if (typeof value === 'function') {
66
+ return;
67
+ }
68
+ if (typeof value === 'object' && value instanceof Node) {
69
+ return;
70
+ }
71
+ flatObj[key] = flattenObject(value);
72
+ };
73
+
74
+ var flattenObject = function (object) {
75
+ if (typeof object !== 'object' || object === null) {
76
+ return object;
77
+ }
78
+ // Handle TypedArray
79
+ if (object instanceof Uint8ClampedArray) {
80
+ return Array.from(object);
81
+ }
82
+ var flatObject = {};
83
+ for (var key in object) {
84
+ flattenObjectCopyValue(flatObject, object, key);
85
+ }
86
+ for (var key in Object.getOwnPropertyNames(object)) {
87
+ flattenObjectCopyValue(flatObject, object, key);
88
+ }
89
+ return flatObject;
90
+ };
91
+
92
+ var AutoScaledCanvas = function (element) {
93
+ this.element = element;
94
+ };
95
+
96
+ AutoScaledCanvas.prototype.toDataURL = function () {
97
+ return this.element.toDataURL.apply(this.element, arguments);
98
+ };
99
+
100
+ AutoScaledCanvas.prototype.autoScale = function () {
101
+ if (this.savedHeight !== undefined) {
102
+ this.element.height = this.savedHeight;
103
+ }
104
+ if (this.savedWidth !== undefined) {
105
+ this.element.width = this.savedWidth;
106
+ }
107
+ window.autoScaleCanvas(this.element);
108
+ };
109
+
110
+ Object.defineProperty(AutoScaledCanvas.prototype, 'width', {
111
+ get: function () {
112
+ return this.element.width;
113
+ },
114
+ set: function (value) {
115
+ this.savedWidth = value;
116
+ this.autoScale();
117
+ return value;
118
+ },
119
+ });
120
+
121
+ Object.defineProperty(AutoScaledCanvas.prototype, 'height', {
122
+ get: function () {
123
+ return this.element.height;
124
+ },
125
+ set: function (value) {
126
+ this.savedHeight = value;
127
+ this.autoScale();
128
+ return value;
129
+ },
130
+ });
131
+ var toMessage = function (result) {
132
+ if (result instanceof Blob) {
133
+ return {
134
+ type: 'blob',
135
+ payload: btoa(result),
136
+ meta: {},
137
+ };
138
+ }
139
+ if (result instanceof Object) {
140
+ if (!result[WEBVIEW_TARGET]) {
141
+ var id = ID();
142
+ result[WEBVIEW_TARGET] = id;
143
+ targets[id] = result;
144
+ }
145
+ return {
146
+ type: 'json',
147
+ payload: flattenObject(result),
148
+ args: toArgs(flattenObject(result)),
149
+ meta: {
150
+ target: result[WEBVIEW_TARGET],
151
+ constructor: result.__constructorName__ || result.constructor.name,
152
+ },
153
+ };
154
+ }
155
+ return {
156
+ type: 'json',
157
+ payload: typeof result === 'string' ? result : JSON.stringify(result),
158
+ meta: {},
159
+ };
160
+ };
161
+ var toArgs = function (result) {
162
+ var args = [];
163
+ for (var key in result) {
164
+ if (result[key] !== undefined && key !== '@@WEBVIEW_TARGET') {
165
+ args.push(result[key]);
166
+ }
167
+ }
168
+ return args;
169
+ };
170
+
171
+ var createObjectsFromArgs = function (args) {
172
+ for (var index = 0; index < args.length; index += 1) {
173
+ var currentArg = args[index];
174
+ if (currentArg && currentArg.className !== undefined) {
175
+ var className = currentArg.className, classArgs = currentArg.classArgs;
176
+ // new ImageData,第一个参数需要是 Uint8ClampedArray
177
+ var object = new (Function.prototype.bind.apply(constructors[className], [null].concat(classArgs)))();
178
+ args[index] = object;
179
+ }
180
+ }
181
+ return args;
182
+ };
183
+
184
+ var canvas = document.createElement('canvas');
185
+ canvas.style.width = '100%';
186
+ canvas.style.height = '100%';
187
+ var autoScaledCanvas = new AutoScaledCanvas(canvas);
188
+
189
+ var targets = {
190
+ canvas: autoScaledCanvas,
191
+ context2D: canvas.getContext('2d'),
192
+ };
193
+
194
+ var constructors = {
195
+ CanvasGradient: CanvasGradient,
196
+ Image: Image,
197
+ ImageData: ImageData,
198
+ Uint8ClampedArray: Uint8ClampedArray,
199
+ };
200
+
201
+ Image.bind =
202
+ Image.bind ||
203
+ function () {
204
+ return Image;
205
+ };
206
+
207
+ ImageData.bind =
208
+ ImageData.bind ||
209
+ function () {
210
+ return ImageData;
211
+ };
212
+ Uint8ClampedArray.bind =
213
+ Uint8ClampedArray.bind ||
214
+ function () {
215
+ return Uint8ClampedArray;
216
+ };
217
+
218
+ var populateRefs = function (arg) {
219
+ if (arg && arg.__ref__) {
220
+ return targets[arg.__ref__];
221
+ }
222
+ return arg;
223
+ };
224
+ document.body.appendChild(canvas);
225
+
226
+ var mergeObjects = function (target, source) {
227
+ for (var key in source) {
228
+ if (source.hasOwnProperty(key)) {
229
+ target[key] = source[key];
230
+ }
231
+ }
232
+ return target;
233
+ };
234
+
235
+ function handleMessage(message) {
236
+ var id = message.id,
237
+ type = message.type,
238
+ payload = message.payload;
239
+
240
+ switch (type) {
241
+ case 'exec': {
242
+ var target = payload.target,
243
+ method = payload.method,
244
+ args = payload.args;
245
+ var result = targets[target][method].apply(targets[target], args.map(populateRefs));
246
+ var msg = toMessage(result);
247
+
248
+ if (typeof result === 'object' && !msg.meta.constructor) {
249
+ for (var constructorName in constructors) {
250
+ if (result instanceof constructors[constructorName]) {
251
+ msg.meta.constructor = constructorName;
252
+ }
253
+ }
254
+ }
255
+ window.ReactNativeWebView.postMessage(JSON.stringify(mergeObjects({ id: id }, msg)));
256
+ break;
257
+ }
258
+ case 'set': {
259
+ var target = payload.target,
260
+ key = payload.key,
261
+ value = payload.value;
262
+ targets[target][key] = populateRefs(value);
263
+ break;
264
+ }
265
+ case 'construct': {
266
+ var constructor = payload.constructor,
267
+ target = payload.id,
268
+ args = payload.args || [];
269
+ var newArgs = createObjectsFromArgs(args);
270
+ var object;
271
+ try {
272
+ object = new (Function.prototype.bind.apply(constructors[constructor], [null].concat(newArgs)))();
273
+ }
274
+ catch (error) {
275
+ throw new Error('Error while constructing '.concat(constructor, ' ').concat(error.message));
276
+ }
277
+ object.__constructorName__ = constructor;
278
+ var msg = toMessage({});
279
+ targets[target] = object;
280
+ window.ReactNativeWebView.postMessage(JSON.stringify(mergeObjects({ id: id }, msg)));
281
+ break;
282
+ }
283
+ case 'listen': {
284
+ var types = payload.types,
285
+ target = payload.target;
286
+ for (var i = 0; i < types.length; i++) {
287
+ var eventType = types[i];
288
+ targets[target].addEventListener(eventType, function (e) {
289
+ const message = toMessage({
290
+ type: 'event',
291
+ payload: {
292
+ type: e.type,
293
+ target: mergeObjects(flattenObject(targets[target]), {
294
+ [WEBVIEW_TARGET]: target,
295
+ }),
296
+ },
297
+ });
298
+ window.ReactNativeWebView.postMessage(
299
+ JSON.stringify(mergeObjects({ id: id }, message))
300
+ );
301
+ });
302
+ }
303
+ break;
304
+ }
305
+ }
306
+ }
307
+ var handleError = function (err, message) {
308
+ window.ReactNativeWebView.postMessage(JSON.stringify({
309
+ id: message.id,
310
+ type: 'error',
311
+ payload: {
312
+ message: err.message,
313
+ stack: err.stack,
314
+ },
315
+ }));
316
+ document.removeEventListener('message', handleIncomingMessage);
317
+ };
318
+
319
+ function handleIncomingMessage(e) {
320
+ var data = JSON.parse(e.data);
321
+ if (Array.isArray(data)) {
322
+ for (var i = 0; i < data.length; i++) {
323
+ try {
324
+ handleMessage(data[i]);
325
+ } catch (err) {
326
+ handleError(err, data[i]);
327
+ }
328
+ }
329
+ } else {
330
+ try {
331
+ handleMessage(data);
332
+ } catch (err) {
333
+ handleError(err, data);
334
+ }
335
+ }
336
+ }
337
+
338
+ window.addEventListener('message', handleIncomingMessage);
339
+ document.addEventListener('message', handleIncomingMessage);
340
+ </script>
341
+
342
+
343
+ </body></html>`
@@ -0,0 +1,302 @@
1
+ /**
2
+ * ✘ type
3
+ * ✘ canvas-id
4
+ * ✘ disable-scroll
5
+ * ✔ bindtouchstart
6
+ * ✔ bindtouchmove
7
+ * ✔ bindtouchend
8
+ * ✔ bindtouchcancel
9
+ * ✔ bindlongtap
10
+ * ✔ binderror
11
+ */
12
+ import React, { useRef, useState, useCallback, useEffect, forwardRef, JSX, TouchEvent, MutableRefObject } from 'react'
13
+ import { View, Platform, StyleSheet, NativeSyntheticEvent } from 'react-native'
14
+ import { WebView } from 'react-native-webview'
15
+ import useNodesRef, { HandlerRef } from '../useNodesRef'
16
+ import { useLayout, useTransformStyle, extendObject } from '../utils'
17
+ import useInnerProps, { getCustomEvent } from '../getInnerListeners'
18
+ import Bus from './Bus'
19
+ import {
20
+ useWebviewBinding,
21
+ constructors,
22
+ WEBVIEW_TARGET,
23
+ WebviewMessage,
24
+ ID,
25
+ CanvasInstance,
26
+ registerWebviewConstructor
27
+ } from './utils'
28
+ import CanvasRenderingContext2D from './CanvasRenderingContext2D'
29
+ import html from './html'
30
+ import './CanvasGradient'
31
+ import { createImage as canvasCreateImage } from './Image'
32
+ import { createImageData as canvasCreateImageData } from './ImageData'
33
+ import { useConstructorsRegistry } from './constructorsRegistry'
34
+
35
+ const stylesheet = StyleSheet.create({
36
+ container: { overflow: 'hidden', flex: 0 },
37
+ webview: {
38
+ overflow: 'hidden',
39
+ backgroundColor: 'transparent',
40
+ flex: 0
41
+ },
42
+ webviewAndroid9: {
43
+ overflow: 'hidden',
44
+ backgroundColor: 'transparent',
45
+ flex: 0,
46
+ opacity: 0.99
47
+ }
48
+ })
49
+
50
+ interface CanvasProps {
51
+ style?: Record<string, any>;
52
+ originWhitelist?: Array<string>;
53
+ 'enable-var'?: boolean
54
+ 'parent-font-size'?: number
55
+ 'parent-width'?: number
56
+ 'parent-height'?: number
57
+ 'external-var-context'?: Record<string, any>
58
+ bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent>) => void;
59
+ bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
60
+ bindtouchend?: (event: NativeSyntheticEvent<TouchEvent>) => void;
61
+ bindtouchcancel?: (event: NativeSyntheticEvent<TouchEvent>) => void;
62
+ bindlongtap?: (event: NativeSyntheticEvent<TouchEvent>) => void;
63
+ binderror?: (event: NativeSyntheticEvent<ErrorEvent>) => void;
64
+ }
65
+
66
+ const _Canvas = forwardRef<HandlerRef<CanvasProps & View, CanvasProps>, CanvasProps>((props: CanvasProps = {}, ref): JSX.Element => {
67
+ const { style = {}, originWhitelist = ['*'], 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props
68
+ const [isLoaded, setIsLoaded] = useState(false)
69
+ const nodeRef = useRef(null)
70
+
71
+ const {
72
+ normalStyle,
73
+ hasSelfPercent,
74
+ setWidth,
75
+ setHeight
76
+ } = useTransformStyle(extendObject(style, stylesheet.container), {
77
+ enableVar,
78
+ externalVarContext,
79
+ parentFontSize,
80
+ parentWidth,
81
+ parentHeight
82
+ })
83
+
84
+ const { width, height } = normalStyle
85
+ const canvasRef = useWebviewBinding({
86
+ targetName: 'canvas',
87
+ properties: { width, height },
88
+ methods: ['toDataURL']
89
+ }) as MutableRefObject<CanvasInstance>
90
+
91
+ const { register } = useConstructorsRegistry()
92
+
93
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
94
+ const innerProps = useInnerProps(props, {
95
+ ref: nodeRef,
96
+ style: extendObject(normalStyle, layoutStyle, { opacity: isLoaded ? 1 : 0 }),
97
+ ...layoutProps
98
+ }, [], {
99
+ layoutRef
100
+ })
101
+
102
+ const context2D = new CanvasRenderingContext2D(canvasRef.current) as any
103
+
104
+ register(registerWebviewConstructor)
105
+ // 初始化bus和context2D
106
+ useEffect(() => {
107
+ const webviewPostMessage = (message: WebviewMessage) => {
108
+ if (canvasRef.current.webview) {
109
+ canvasRef.current.webview.postMessage(JSON.stringify(message))
110
+ }
111
+ }
112
+
113
+ // 设置bus
114
+ canvasRef.current.bus = new Bus(webviewPostMessage)
115
+ canvasRef.current.bus.pause()
116
+
117
+ // 设置 context 2D
118
+ canvasRef.current.context2D = context2D
119
+
120
+ // 设置 getContext 方法
121
+ canvasRef.current.getContext = getContext
122
+
123
+ // 设置 createImage 方法
124
+ canvasRef.current.createImage = createImage
125
+
126
+ // 设置 postMessage 方法
127
+ canvasRef.current.postMessage = postMessage
128
+
129
+ // 设置 listeners
130
+ canvasRef.current.listeners = []
131
+
132
+ canvasRef.current.addMessageListener = addMessageListener
133
+
134
+ canvasRef.current.removeMessageListener = removeMessageListener
135
+
136
+ canvasRef.current.createImageData = createImageData
137
+ return () => {
138
+ canvasRef.current.bus?.clearBatchingTimeout()
139
+ }
140
+ }, [])
141
+
142
+ const createImageData = (dataArray: Array<number>, width: number, height: number) => {
143
+ return canvasCreateImageData(canvasRef.current, dataArray, width, height)
144
+ }
145
+ const createImage = (width?: number, height?: number) => {
146
+ return canvasCreateImage(canvasRef.current, width, height)
147
+ }
148
+ const getContext = useCallback((contextType: string) => {
149
+ if (contextType === '2d') {
150
+ return context2D
151
+ }
152
+ return null
153
+ }, [])
154
+
155
+ const postMessage = useCallback(async (message: WebviewMessage) => {
156
+ if (!canvasRef.current?.bus) return
157
+ const { type, payload } = await canvasRef.current.bus.post({
158
+ id: ID(),
159
+ ...message
160
+ })
161
+
162
+ switch (type) {
163
+ case 'error': {
164
+ const { binderror } = props
165
+ binderror &&
166
+ binderror(
167
+ getCustomEvent('error', {}, {
168
+ detail: {
169
+ errMsg: payload.message
170
+ },
171
+ layoutRef
172
+ }, props)
173
+ )
174
+ break
175
+ }
176
+ case 'json': {
177
+ return payload
178
+ }
179
+ case 'blob': {
180
+ return atob(payload)
181
+ }
182
+ }
183
+ }, [])
184
+
185
+ const addMessageListener = (listener: any) => {
186
+ canvasRef.current.listeners.push(listener)
187
+ return () => canvasRef.current.removeMessageListener(listener)
188
+ }
189
+
190
+ const removeMessageListener = (listener: any) => {
191
+ canvasRef.current.listeners.splice(canvasRef.current.listeners.indexOf(listener), 1)
192
+ }
193
+
194
+ const onMessage = useCallback((e: { nativeEvent: { data: string } }) => {
195
+ let data = JSON.parse(e.nativeEvent.data)
196
+ switch (data.type) {
197
+ case 'error': {
198
+ const { binderror } = props
199
+ binderror &&
200
+ binderror(
201
+ getCustomEvent('error', e, {
202
+ detail: {
203
+ errMsg: data.payload.message
204
+ },
205
+ layoutRef
206
+ }, props)
207
+ )
208
+ break
209
+ }
210
+ default: {
211
+ if (data.payload) {
212
+ // createLinearGradient 方法调用需要在 constructors 中需要注册 CanvasGradient
213
+ const constructor = constructors[data.meta.constructor]
214
+ if (constructor) {
215
+ const { args, payload } = data
216
+ // RN 端同步生成一个 CanvasGradient 的实例
217
+ const object = constructor.constructLocally(canvasRef.current, ...args)
218
+ Object.assign(object, payload, {
219
+ [WEBVIEW_TARGET]: data.meta.target
220
+ })
221
+ data = {
222
+ ...data,
223
+ payload: object
224
+ }
225
+ }
226
+ for (const listener of canvasRef.current.listeners) {
227
+ listener(data.payload)
228
+ }
229
+ }
230
+ if (canvasRef.current.bus) {
231
+ canvasRef.current.bus.handle(data)
232
+ }
233
+ }
234
+ }
235
+ }, [])
236
+
237
+ const onLoad = useCallback(() => {
238
+ setIsLoaded(true)
239
+ if (canvasRef.current?.bus) {
240
+ canvasRef.current.bus.resume()
241
+ }
242
+ }, [])
243
+
244
+ useNodesRef(props, ref, nodeRef, {
245
+ style: normalStyle,
246
+ node: canvasRef.current,
247
+ context: context2D
248
+ })
249
+
250
+ if (Platform.OS === 'android') {
251
+ const isAndroid9 = Platform.Version >= 28
252
+ return (
253
+ <View {...innerProps}>
254
+ <WebView
255
+ ref={(element) => {
256
+ if (canvasRef.current) {
257
+ canvasRef.current.webview = element
258
+ }
259
+ }}
260
+ style={[
261
+ isAndroid9 ? stylesheet.webviewAndroid9 : stylesheet.webview,
262
+ { height, width }
263
+ ]}
264
+ source={{ html }}
265
+ originWhitelist={originWhitelist}
266
+ onMessage={onMessage}
267
+ onLoad={onLoad}
268
+ overScrollMode="never"
269
+ mixedContentMode="always"
270
+ scalesPageToFit={false}
271
+ javaScriptEnabled
272
+ domStorageEnabled
273
+ thirdPartyCookiesEnabled
274
+ allowUniversalAccessFromFileURLs
275
+ />
276
+ </View>
277
+ )
278
+ }
279
+
280
+ return (
281
+ <View
282
+ {...innerProps}
283
+ >
284
+ <WebView
285
+ ref={(element) => {
286
+ if (canvasRef.current) {
287
+ canvasRef.current.webview = element
288
+ }
289
+ }}
290
+ style={[stylesheet.webview, { height, width }]}
291
+ source={{ html }}
292
+ originWhitelist={originWhitelist}
293
+ onMessage={onMessage}
294
+ onLoad={onLoad}
295
+ scrollEnabled={false}
296
+ />
297
+ </View>
298
+ )
299
+ })
300
+ _Canvas.displayName = 'mpxCanvas'
301
+
302
+ export default _Canvas