diff options
Diffstat (limited to 'StoneIsland/platforms/ios/www/cordova-js-src/exec.js')
| -rw-r--r-- | StoneIsland/platforms/ios/www/cordova-js-src/exec.js | 187 |
1 files changed, 42 insertions, 145 deletions
diff --git a/StoneIsland/platforms/ios/www/cordova-js-src/exec.js b/StoneIsland/platforms/ios/www/cordova-js-src/exec.js index 3fb7fa19..466220d8 100644 --- a/StoneIsland/platforms/ios/www/cordova-js-src/exec.js +++ b/StoneIsland/platforms/ios/www/cordova-js-src/exec.js @@ -19,30 +19,24 @@ * */ -/*global require, module, atob, document */ - /** - * Creates a gap bridge iframe used to notify the native code about queued + * Creates the exec bridge used to notify the native code of * commands. */ -var cordova = require('cordova'), - utils = require('cordova/utils'), - base64 = require('cordova/base64'), - execIframe, - commandQueue = [], // Contains pending JS->Native messages. - isInContextOfEvalJs = 0, - failSafeTimerId = 0; +var cordova = require('cordova'); +var utils = require('cordova/utils'); +var base64 = require('cordova/base64'); -function massageArgsJsToNative(args) { - if (!args || utils.typeName(args) != 'Array') { +function massageArgsJsToNative (args) { + if (!args || utils.typeName(args) !== 'Array') { return args; } var ret = []; - args.forEach(function(arg, i) { - if (utils.typeName(arg) == 'ArrayBuffer') { + args.forEach(function (arg, i) { + if (utils.typeName(arg) === 'ArrayBuffer') { ret.push({ - 'CDVType': 'ArrayBuffer', - 'data': base64.fromArrayBuffer(arg) + CDVType: 'ArrayBuffer', + data: base64.fromArrayBuffer(arg) }); } else { ret.push(arg); @@ -51,29 +45,29 @@ function massageArgsJsToNative(args) { return ret; } -function massageMessageNativeToJs(message) { - if (message.CDVType == 'ArrayBuffer') { - var stringToArrayBuffer = function(str) { +function massageMessageNativeToJs (message) { + if (message.CDVType === 'ArrayBuffer') { + var stringToArrayBuffer = function (str) { var ret = new Uint8Array(str.length); for (var i = 0; i < str.length; i++) { ret[i] = str.charCodeAt(i); } return ret.buffer; }; - var base64ToArrayBuffer = function(b64) { - return stringToArrayBuffer(atob(b64)); + var base64ToArrayBuffer = function (b64) { + return stringToArrayBuffer(atob(b64)); // eslint-disable-line no-undef }; message = base64ToArrayBuffer(message.data); } return message; } -function convertMessageToArgsNativeToJs(message) { +function convertMessageToArgsNativeToJs (message) { var args = []; - if (!message || !message.hasOwnProperty('CDVType')) { + if (!message || !Object.prototype.hasOwnProperty.call(message, 'CDVType')) { args.push(message); - } else if (message.CDVType == 'MultiPart') { - message.messages.forEach(function(e) { + } else if (message.CDVType === 'MultiPart') { + message.messages.forEach(function (e) { args.push(massageMessageNativeToJs(e)); }); } else { @@ -82,8 +76,7 @@ function convertMessageToArgsNativeToJs(message) { return args; } -function iOSExec() { - +var iOSExec = function () { var successCallback, failCallback, service, action, actionArgs; var callbackId = null; if (typeof arguments[0] !== 'string') { @@ -100,9 +93,8 @@ function iOSExec() { // an invalid callbackId and passes it even if no callbacks were given. callbackId = 'INVALID'; } else { - throw new Error('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' + - 'cordova.exec(null, null, \'Service\', \'action\', [ arg1, arg2 ]);' - ); + throw new Error('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' + // eslint-disable-line + 'cordova.exec(null, null, \'Service\', \'action\', [ arg1, arg2 ]);'); } // If actionArgs is not provided, default to an empty array @@ -113,149 +105,54 @@ function iOSExec() { if (successCallback || failCallback) { callbackId = service + cordova.callbackId++; cordova.callbacks[callbackId] = - {success:successCallback, fail:failCallback}; + { success: successCallback, fail: failCallback }; } actionArgs = massageArgsJsToNative(actionArgs); - var command = [callbackId, service, action, actionArgs]; - - // Stringify and queue the command. We stringify to command now to - // effectively clone the command arguments in case they are mutated before - // the command is executed. - commandQueue.push(JSON.stringify(command)); - - // If we're in the context of a stringByEvaluatingJavaScriptFromString call, - // then the queue will be flushed when it returns; no need for a poke. - // Also, if there is already a command in the queue, then we've already - // poked the native side, so there is no reason to do so again. - if (!isInContextOfEvalJs && commandQueue.length == 1) { - pokeNative(); - } -} - -// CB-10530 -function proxyChanged() { - var cexec = cordovaExec(); - - return (execProxy !== cexec && // proxy objects are different - iOSExec !== cexec // proxy object is not the current iOSExec - ); -} - -// CB-10106 -function handleBridgeChange() { - if (proxyChanged()) { - var commandString = commandQueue.shift(); - while(commandString) { - var command = JSON.parse(commandString); - var callbackId = command[0]; - var service = command[1]; - var action = command[2]; - var actionArgs = command[3]; - var callbacks = cordova.callbacks[callbackId] || {}; - - execProxy(callbacks.success, callbacks.fail, service, action, actionArgs); - - commandString = commandQueue.shift(); - }; - return true; - } - - return false; -} - -function pokeNative() { - // CB-5488 - Don't attempt to create iframe before document.body is available. - if (!document.body) { - setTimeout(pokeNative); - return; - } - - // Check if they've removed it from the DOM, and put it back if so. - if (execIframe && execIframe.contentWindow) { - execIframe.contentWindow.location = 'gap://ready'; - } else { - execIframe = document.createElement('iframe'); - execIframe.style.display = 'none'; - execIframe.src = 'gap://ready'; - document.body.appendChild(execIframe); - } - // Use a timer to protect against iframe being unloaded during the poke (CB-7735). - // This makes the bridge ~ 7% slower, but works around the poke getting lost - // when the iframe is removed from the DOM. - // An onunload listener could be used in the case where the iframe has just been - // created, but since unload events fire only once, it doesn't work in the normal - // case of iframe reuse (where unload will have already fired due to the attempted - // navigation of the page). - failSafeTimerId = setTimeout(function() { - if (commandQueue.length) { - // CB-10106 - flush the queue on bridge change - if (!handleBridgeChange()) { - pokeNative(); - } - } - }, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn't fire). -} - -iOSExec.nativeFetchMessages = function() { - // Stop listing for window detatch once native side confirms poke. - if (failSafeTimerId) { - clearTimeout(failSafeTimerId); - failSafeTimerId = 0; - } - // Each entry in commandQueue is a JSON string already. - if (!commandQueue.length) { - return ''; - } - var json = '[' + commandQueue.join(',') + ']'; - commandQueue.length = 0; - return json; + // CB-10133 DataClone DOM Exception 25 guard (fast function remover) + var command = [callbackId, service, action, JSON.parse(JSON.stringify(actionArgs))]; + window.webkit.messageHandlers.cordova.postMessage(command); }; -iOSExec.nativeCallback = function(callbackId, status, message, keepCallback, debug) { - return iOSExec.nativeEvalAndFetch(function() { - var success = status === 0 || status === 1; - var args = convertMessageToArgsNativeToJs(message); - function nc2() { - cordova.callbackFromNative(callbackId, success, status, args, keepCallback); - } - setTimeout(nc2, 0); +iOSExec.nativeCallback = function (callbackId, status, message, keepCallback, debug) { + var success = status === 0 || status === 1; + var args = convertMessageToArgsNativeToJs(message); + Promise.resolve().then(function () { + cordova.callbackFromNative(callbackId, success, status, args, keepCallback); // eslint-disable-line }); }; -iOSExec.nativeEvalAndFetch = function(func) { - // This shouldn't be nested, but better to be safe. - isInContextOfEvalJs++; +// for backwards compatibility +iOSExec.nativeEvalAndFetch = function (func) { try { func(); - return iOSExec.nativeFetchMessages(); - } finally { - isInContextOfEvalJs--; + } catch (e) { + console.log(e); } }; // Proxy the exec for bridge changes. See CB-10106 -function cordovaExec() { +function cordovaExec () { var cexec = require('cordova/exec'); var cexec_valid = (typeof cexec.nativeFetchMessages === 'function') && (typeof cexec.nativeEvalAndFetch === 'function') && (typeof cexec.nativeCallback === 'function'); - return (cexec_valid && execProxy !== cexec)? cexec : iOSExec; + return (cexec_valid && execProxy !== cexec) ? cexec : iOSExec; } -function execProxy() { +function execProxy () { cordovaExec().apply(null, arguments); -}; +} -execProxy.nativeFetchMessages = function() { +execProxy.nativeFetchMessages = function () { return cordovaExec().nativeFetchMessages.apply(null, arguments); }; -execProxy.nativeEvalAndFetch = function() { +execProxy.nativeEvalAndFetch = function () { return cordovaExec().nativeEvalAndFetch.apply(null, arguments); }; -execProxy.nativeCallback = function() { +execProxy.nativeCallback = function () { return cordovaExec().nativeCallback.apply(null, arguments); }; |
