Skip to content

Commit

Permalink
Merge branch 'master' into fix-actionsheet-1217
Browse files Browse the repository at this point in the history
  • Loading branch information
hiyuki authored Dec 19, 2024
2 parents 6bbeb02 + a013670 commit 537defb
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 244 deletions.
4 changes: 2 additions & 2 deletions examples/mpx-webview/H5/webviewbridge.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const getCustomEvent = (
{
detail = {},
layoutRef
}: { detail?: Record<string, unknown>; layoutRef: LayoutRef },
}: { detail?: Record<string, unknown>; layoutRef?: LayoutRef },
props: Props = {}
) => {
const targetInfo = extendObject({}, oe.target, {
Expand Down
135 changes: 86 additions & 49 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { forwardRef, JSX, useEffect, useRef, useContext, useMemo, createElement } from 'react'
import { noop, warn } from '@mpxjs/utils'
import { View } from 'react-native'
import { forwardRef, JSX, useRef, useContext, useMemo, createElement } from 'react'
import { warn, getFocusedNavigation, isFunction } from '@mpxjs/utils'
import { Portal } from '@ant-design/react-native'
import { getCustomEvent } from './getInnerListeners'
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
Expand Down Expand Up @@ -31,26 +30,25 @@ interface WebViewProps {
}

interface PayloadData {
data?: Record<string, any>
[x: string]: any
}

type MessageData = {
payload?: PayloadData,
args?: Array<any>,
type?: string,
callbackId?: number
}

const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element => {
const { src, bindmessage = noop, bindload = noop, binderror = noop } = props
if (!src) {
return (<View></View>)
}
const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element | null => {
const { src, bindmessage, bindload, binderror } = props
const mpx = global.__mpx
if (props.style) {
warn('The web-view component does not support the style prop.')
}
const pageId = useContext(RouteContext)
const currentPage = useMemo(() => getCurrentPage(pageId), [pageId])

const webViewRef = useRef<WebView>(null)
const defaultWebViewStyle = {
position: 'absolute' as 'absolute' | 'relative' | 'static',
left: 0 as number,
Expand All @@ -59,34 +57,14 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
bottom: 0 as number
}

const webViewRef = useRef<WebView>(null)
useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
style: defaultWebViewStyle
})

const _messageList = useRef<any[]>([])
const handleUnload = () => {
// 这里是 WebView 销毁前执行的逻辑
bindmessage(getCustomEvent('messsage', {}, {
detail: {
data: _messageList.current
},
layoutRef: webViewRef
}))
if (!src) {
return null
}

useEffect(() => {
if (currentPage) {
currentPage.__webViewUrl = src
}
}, [src, currentPage])

useEffect(() => {
// 组件卸载时执行
return () => {
handleUnload()
}
}, [])
const _load = function (res: WebViewNavigationEvent) {
const result = {
type: 'load',
Expand All @@ -107,8 +85,33 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
}
binderror(result)
}
const injectedJavaScript = `
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
var _documentTitle = document.title;
window.ReactNativeWebView.postMessage(JSON.stringify({
type: 'setTitle',
payload: {
_documentTitle: _documentTitle
}
}))
Object.defineProperty(document, 'title', {
set (val) {
_documentTitle = val
window.ReactNativeWebView.postMessage(JSON.stringify({
type: 'setTitle',
payload: {
_documentTitle: _documentTitle
}
}))
},
get () {
return _documentTitle
}
});
}
`
const _changeUrl = function (navState: WebViewNavigation) {
if (currentPage) {
if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
currentPage.__webViewUrl = navState.url
}
}
Expand All @@ -121,43 +124,79 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
if (typeof nativeEventData === 'string') {
data = JSON.parse(nativeEventData)
}
} catch (e) {
data = {}
}
} catch (e) {}
const args = data.args
const postData: PayloadData = data.payload || {}
switch (data.type) {
const params = Array.isArray(args) ? args : [postData]
const type = data.type
switch (type) {
case 'setTitle':
{ // case下不允许直接声明,包个块解决该问题
const title = postData._documentTitle
if (title) {
const navigation = getFocusedNavigation()
navigation && navigation.setOptions({ title })
}
}
break
case 'postMessage':
_messageList.current.push(postData.data)
bindmessage && bindmessage(getCustomEvent('messsage', {}, { // RN组件销毁顺序与小程序不一致,所以改成和支付宝消息一致
detail: {
data: params[0]?.data
}
}))
asyncCallback = Promise.resolve({
errMsg: 'invokeWebappApi:ok'
})
break
case 'navigateTo':
asyncCallback = navObj.navigateTo(postData)
asyncCallback = navObj.navigateTo(...params)
break
case 'navigateBack':
asyncCallback = navObj.navigateBack(postData)
asyncCallback = navObj.navigateBack(...params)
break
case 'redirectTo':
asyncCallback = navObj.redirectTo(postData)
asyncCallback = navObj.redirectTo(...params)
break
case 'switchTab':
asyncCallback = navObj.switchTab(postData)
asyncCallback = navObj.switchTab(...params)
break
case 'reLaunch':
asyncCallback = navObj.reLaunch(postData)
asyncCallback = navObj.reLaunch(...params)
break
default:
if (type) {
const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type]
if (isFunction(implement)) {
asyncCallback = Promise.resolve(implement(...params))
} else {
/* eslint-disable prefer-promise-reject-errors */
asyncCallback = Promise.reject({
errMsg: `未在apiImplementations中配置${type}方法`
})
}
}
break
}

asyncCallback && asyncCallback.then((res: any) => {
if (webViewRef.current?.postMessage) {
const test = JSON.stringify({
type: data.type,
type,
callbackId: data.callbackId,
result: res
})
webViewRef.current.postMessage(test)
}
}).catch((error: any) => {
if (webViewRef.current?.postMessage) {
const test = JSON.stringify({
type,
callbackId: data.callbackId,
error
})
webViewRef.current.postMessage(test)
}
})
}
const events = {}
Expand All @@ -172,11 +211,9 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
onError: _error
})
}
if (bindmessage) {
extendObject(events, {
onMessage: _message
})
}
extendObject(events, {
onMessage: _message
})

return createElement(Portal, null, createElement(WebView, extendObject({
style: defaultWebViewStyle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ declare module '@mpxjs/utils' {
bottom: number
left: number
right: number
}
},
setOptions: (params: Record<string, any>) => void
} | undefined
}

Expand Down
Loading

0 comments on commit 537defb

Please sign in to comment.