Files
react-native-webview-bridge/scripts/WebViewBridgeRPC.js
T

104 lines
2.4 KiB
JavaScript
Raw Normal View History

(function () {
'use strict'
var ids = 0
2016-09-27 14:01:32 -04:00
var invokers = {}
var responseCallbacks = {}
2016-09-27 14:01:32 -04:00
//invoker has accept 2 arguments
//fn(args, result). result is a function which accept an argument.
//that argument is being used to send to caller as a result value.
//by using this function, we can support both sync and async operation
2016-09-27 20:53:03 -04:00
function register(sender, name, fn) {
2016-09-27 14:01:32 -04:00
invokers[name] = function (id, args) {
fn(args, function (result) {
2016-09-27 20:53:03 -04:00
sender({
2016-09-27 14:01:32 -04:00
id: id,
type: 'response',
result: result
})
})
}
}
2016-09-27 20:53:03 -04:00
function invoke(sender, name, args, callback) {
2016-09-27 14:01:32 -04:00
var id = ++ids
responseCallbacks[id] = callback
2016-09-27 20:53:03 -04:00
sender({
2016-09-27 14:01:32 -04:00
id: id,
type: 'invoke',
name: name,
args: args
})
}
2016-09-27 14:01:32 -04:00
function onInvoke(payload) {
var invoker = invokers[payload.name]
if (invoker) {
setTimeout(function () {
invoker(payload.id, payload.args)
}, 15)
}
}
function onResponse(payload) {
var callback = responseCallbacks[payload.id]
if (callback) {
delete responseCallbacks[payload.id]
setTimeout(function () {
callback(payload.result)
}, 15)
}
}
function onMessage(payload) {
if (typeof payload === 'string') {
return
}
//there are two types of payload
// invoke: { type: 'payload', id, name, args }
// response: { type: 'response', id, result }
switch(payload.type) {
case 'invoke':
onInvoke(payload)
break
case 'response':
onResponse(payload)
break
default:
//ignore
}
}
//init this method register and attaches rpc to WebViewBridge.
//you can either check whether WebViewBridge.rpc is availebe or
//simply register to `webviewbridge:rpc` event.
function init(WebViewBridge) {
2016-09-27 20:53:03 -04:00
var rpc = {}
var sender = window.WebViewBridge.send
2016-09-27 20:53:03 -04:00
window.removeEventListener('webviewbridge:init', init)
WebViewBridge.addMessageListener(onMessage)
rpc.register = function (name, fn) {
register(sender, name, fn)
}
2016-09-27 20:53:03 -04:00
rpc.invoke = function (name, args, callback) {
invoke(sender, name, args, callback)
}
2016-09-27 14:01:32 -04:00
WebViewBridge.rpc = rpc
WebViewBridge.__dispatch__('webviewbridge:rpc', rpc)
}
if (window.WebViewBridge) {
init(window.WebViewBridge)
} else {
window.addEventListener('webviewbridge:init', init)
}
}())