;(function() {
|
if (window.WebViewJavascriptBridge) { return }
|
var messagingIframe
|
var sendMessageQueue = []
|
var receiveMessageQueue = []
|
var messageHandlers = {}
|
|
var MESSAGE_SEPARATOR = '__WVJB_MESSAGE_SEPERATOR__'
|
var CUSTOM_PROTOCOL_SCHEME = 'wvjbscheme'
|
var QUEUE_HAS_MESSAGE = '__WVJB_QUEUE_MESSAGE__'
|
|
var responseCallbacks = {}
|
var uniqueId = 1
|
|
function _createQueueReadyIframe(doc) {
|
messagingIframe = doc.createElement('iframe')
|
messagingIframe.style.display = 'none'
|
doc.documentElement.appendChild(messagingIframe)
|
}
|
|
function init(messageHandler) {
|
if (WebViewJavascriptBridge._messageHandler) { throw new Error('WebViewJavascriptBridge.init called twice') }
|
WebViewJavascriptBridge._messageHandler = messageHandler
|
var receivedMessages = receiveMessageQueue
|
receiveMessageQueue = null
|
for (var i=0; i<receivedMessages.length; i++) {
|
_dispatchMessageFromObjC(receivedMessages[i])
|
}
|
}
|
|
function send(data, responseCallback) {
|
_doSend({ data:data }, responseCallback)
|
}
|
|
function registerHandler(handlerName, handler) {
|
messageHandlers[handlerName] = handler
|
}
|
|
function callHandler(handlerName, data, responseCallback) {
|
_doSend({ data:data, handlerName:handlerName }, responseCallback)
|
}
|
|
function _doSend(message, responseCallback) {
|
if (responseCallback) {
|
var callbackId = 'js_cb_'+(uniqueId++)
|
responseCallbacks[callbackId] = responseCallback
|
message['callbackId'] = callbackId
|
}
|
sendMessageQueue.push(JSON.stringify(message))
|
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE
|
}
|
|
function _fetchQueue() {
|
var messageQueueString = sendMessageQueue.join(MESSAGE_SEPARATOR)
|
sendMessageQueue = []
|
return messageQueueString
|
}
|
|
function _dispatchMessageFromObjC(messageJSON) {
|
setTimeout(function _timeoutDispatchMessageFromObjC() {
|
var message = JSON.parse(messageJSON)
|
var messageHandler
|
if (message.responseId) {
|
var responseCallback = responseCallbacks[message.responseId]
|
|
responseCallback(message.error, message.responseData)
|
delete responseCallbacks[message.responseId]
|
} else {
|
var response
|
if (message.callbackId) {
|
var callbackResponseId = message.callbackId
|
response = {
|
respondWith: function(responseData) {
|
_doSend({ responseId:callbackResponseId, responseData:responseData })
|
},
|
respondWithError: function(error) {
|
_doSend({ responseId:callbackResponseId, error:error })
|
}
|
}
|
}
|
|
var handler = WebViewJavascriptBridge._messageHandler
|
|
if (message.handlerName) {
|
handler = messageHandlers[message.handlerName]
|
}
|
|
try {
|
handler(message.data, response)
|
} catch(exception) {
|
console.log("WebViewJavascriptBridge: WARNING: javascript handler threw.", message, exception)
|
}
|
}
|
})
|
}
|
|
function _handleMessageFromObjC(messageJSON) {
|
|
if (receiveMessageQueue) {
|
receiveMessageQueue.push(messageJSON)
|
} else {
|
_dispatchMessageFromObjC(messageJSON)
|
}
|
}
|
|
window.WebViewJavascriptBridge = {
|
init: init,
|
send: send,
|
registerHandler: registerHandler,
|
callHandler: callHandler,
|
_fetchQueue: _fetchQueue,
|
_handleMessageFromObjC: _handleMessageFromObjC
|
}
|
|
var doc = document
|
_createQueueReadyIframe(doc)
|
var readyEvent = doc.createEvent('Events')
|
readyEvent.initEvent('WebViewJavascriptBridgeReady')
|
readyEvent.bridge = WebViewJavascriptBridge
|
doc.dispatchEvent(readyEvent)
|
})();
|