summaryrefslogtreecommitdiff
path: root/StoneIsland/platforms/ios/CordovaLib/cordova.js
diff options
context:
space:
mode:
Diffstat (limited to 'StoneIsland/platforms/ios/CordovaLib/cordova.js')
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/CordovaLib/cordova.js324
1 files changed, 145 insertions, 179 deletions
diff --git a/StoneIsland/platforms/ios/CordovaLib/cordova.js b/StoneIsland/platforms/ios/CordovaLib/cordova.js
index 46ab90b7..9dce1f9f 100755..100644
--- a/StoneIsland/platforms/ios/CordovaLib/cordova.js
+++ b/StoneIsland/platforms/ios/CordovaLib/cordova.js
@@ -1,5 +1,5 @@
// Platform: ios
-// 49a8db57fa070d20ea7b304a53ffec3d7250c5af
+// f28234fbc27c578b9a335f1dabfa2d1b96bfc03d
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,7 +19,7 @@
under the License.
*/
;(function() {
-var PLATFORM_VERSION_BUILD_LABEL = '3.9.2';
+var PLATFORM_VERSION_BUILD_LABEL = '4.3.0';
// file: src/scripts/require.js
/*jshint -W079 */
@@ -697,8 +697,13 @@ var Channel = function(type, sticky) {
}
};
-function forceFunction(f) {
- if (typeof f != 'function') throw "Function required as first argument!";
+function checkSubscriptionArgument(argument) {
+ if (typeof argument !== "function" && typeof argument.handleEvent !== "function") {
+ throw new Error(
+ "Must provide a function or an EventListener object " +
+ "implementing the handleEvent interface."
+ );
+ }
}
/**
@@ -708,28 +713,39 @@ function forceFunction(f) {
* and a guid that can be used to stop subscribing to the channel.
* Returns the guid.
*/
-Channel.prototype.subscribe = function(f, c) {
- // need a function to call
- forceFunction(f);
+Channel.prototype.subscribe = function(eventListenerOrFunction, eventListener) {
+ checkSubscriptionArgument(eventListenerOrFunction);
+ var handleEvent, guid;
+
+ if (eventListenerOrFunction && typeof eventListenerOrFunction === "object") {
+ // Received an EventListener object implementing the handleEvent interface
+ handleEvent = eventListenerOrFunction.handleEvent;
+ eventListener = eventListenerOrFunction;
+ } else {
+ // Received a function to handle event
+ handleEvent = eventListenerOrFunction;
+ }
+
if (this.state == 2) {
- f.apply(c || this, this.fireArgs);
+ handleEvent.apply(eventListener || this, this.fireArgs);
return;
}
- var func = f,
- guid = f.observer_guid;
- if (typeof c == "object") { func = utils.close(c, f); }
+ guid = eventListenerOrFunction.observer_guid;
+ if (typeof eventListener === "object") {
+ handleEvent = utils.close(eventListener, handleEvent);
+ }
if (!guid) {
- // first time any channel has seen this subscriber
+ // First time any channel has seen this subscriber
guid = '' + nextGuid++;
}
- func.observer_guid = guid;
- f.observer_guid = guid;
+ handleEvent.observer_guid = guid;
+ eventListenerOrFunction.observer_guid = guid;
// Don't add the same handler more than once.
if (!this.handlers[guid]) {
- this.handlers[guid] = func;
+ this.handlers[guid] = handleEvent;
this.numHandlers++;
if (this.numHandlers == 1) {
this.onHasSubscribersChange && this.onHasSubscribersChange();
@@ -740,12 +756,20 @@ Channel.prototype.subscribe = function(f, c) {
/**
* Unsubscribes the function with the given guid from the channel.
*/
-Channel.prototype.unsubscribe = function(f) {
- // need a function to unsubscribe
- forceFunction(f);
+Channel.prototype.unsubscribe = function(eventListenerOrFunction) {
+ checkSubscriptionArgument(eventListenerOrFunction);
+ var handleEvent, guid, handler;
+
+ if (eventListenerOrFunction && typeof eventListenerOrFunction === "object") {
+ // Received an EventListener object implementing the handleEvent interface
+ handleEvent = eventListenerOrFunction.handleEvent;
+ } else {
+ // Received a function to handle event
+ handleEvent = eventListenerOrFunction;
+ }
- var guid = f.observer_guid,
- handler = this.handlers[guid];
+ guid = handleEvent.observer_guid;
+ handler = this.handlers[guid];
if (handler) {
delete this.handlers[guid];
this.numHandlers--;
@@ -817,58 +841,23 @@ module.exports = channel;
});
-// file: e:/cordova/cordova-ios/cordova-js-src/exec.js
+// file: /Users/shazron/Documents/git/apache/cordova-ios/cordova-js-src/exec.js
define("cordova/exec", function(require, exports, module) {
+/*global require, module, atob, document */
+
/**
* Creates a gap bridge iframe used to notify the native code about queued
* commands.
*/
var cordova = require('cordova'),
- channel = require('cordova/channel'),
utils = require('cordova/utils'),
base64 = require('cordova/base64'),
- // XHR mode does not work on iOS 4.2.
- // XHR mode's main advantage is working around a bug in -webkit-scroll, which
- // doesn't exist only on iOS 5.x devices.
- // IFRAME_NAV is the fastest.
- // IFRAME_HASH could be made to enable synchronous bridge calls if we wanted this feature.
- jsToNativeModes = {
- IFRAME_NAV: 0, // Default. Uses a new iframe for each poke.
- // XHR bridge appears to be flaky sometimes: CB-3900, CB-3359, CB-5457, CB-4970, CB-4998, CB-5134
- XHR_NO_PAYLOAD: 1, // About the same speed as IFRAME_NAV. Performance not about the same as IFRAME_NAV, but more variable.
- XHR_WITH_PAYLOAD: 2, // Flakey, and not as performant
- XHR_OPTIONAL_PAYLOAD: 3, // Flakey, and not as performant
- IFRAME_HASH_NO_PAYLOAD: 4, // Not fully baked. A bit faster than IFRAME_NAV, but risks jank since poke happens synchronously.
- IFRAME_HASH_WITH_PAYLOAD: 5, // Slower than no payload. Maybe since it has to be URI encoded / decoded.
- WK_WEBVIEW_BINDING: 6 // Only way that works for WKWebView :)
- },
- bridgeMode,
execIframe,
- execHashIframe,
- hashToggle = 1,
- execXhr,
- requestCount = 0,
- vcHeaderValue = null,
commandQueue = [], // Contains pending JS->Native messages.
isInContextOfEvalJs = 0,
failSafeTimerId = 0;
-function shouldBundleCommandJson() {
- if (bridgeMode === jsToNativeModes.XHR_WITH_PAYLOAD) {
- return true;
- }
- if (bridgeMode === jsToNativeModes.XHR_OPTIONAL_PAYLOAD) {
- var payloadLength = 0;
- for (var i = 0; i < commandQueue.length; ++i) {
- payloadLength += commandQueue[i].length;
- }
- // The value here was determined using the benchmark within CordovaLibApp on an iPad 3.
- return payloadLength < 4500;
- }
- return false;
-}
-
function massageArgsJsToNative(args) {
if (!args || utils.typeName(args) != 'Array') {
return args;
@@ -919,17 +908,10 @@ function convertMessageToArgsNativeToJs(message) {
}
function iOSExec() {
- if (bridgeMode === undefined) {
- bridgeMode = jsToNativeModes.IFRAME_NAV;
- }
-
- if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.cordova && window.webkit.messageHandlers.cordova.postMessage) {
- bridgeMode = jsToNativeModes.WK_WEBVIEW_BINDING;
- }
- var successCallback, failCallback, service, action, actionArgs, splitCommand;
+ var successCallback, failCallback, service, action, actionArgs;
var callbackId = null;
- if (typeof arguments[0] !== "string") {
+ if (typeof arguments[0] !== 'string') {
// FORMAT ONE
successCallback = arguments[0];
failCallback = arguments[1];
@@ -943,18 +925,9 @@ function iOSExec() {
// an invalid callbackId and passes it even if no callbacks were given.
callbackId = 'INVALID';
} else {
- // FORMAT TWO, REMOVED
- try {
- splitCommand = arguments[0].split(".");
- action = splitCommand.pop();
- service = splitCommand.join(".");
- actionArgs = Array.prototype.splice.call(arguments, 1);
-
- console.log('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' +
- "cordova.exec(null, null, \"" + service + "\", \"" + action + "\"," + JSON.stringify(actionArgs) + ");"
- );
- return;
- } catch (e) {}
+ 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 ]);'
+ );
}
// If actionArgs is not provided, default to an empty array
@@ -976,116 +949,79 @@ function iOSExec() {
// effectively clone the command arguments in case they are mutated before
// the command is executed.
commandQueue.push(JSON.stringify(command));
-
- if (bridgeMode === jsToNativeModes.WK_WEBVIEW_BINDING) {
- window.webkit.messageHandlers.cordova.postMessage(command);
- } else {
- // 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();
- }
+
+ // 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();
}
}
-function pokeNative() {
- switch (bridgeMode) {
- case jsToNativeModes.XHR_NO_PAYLOAD:
- case jsToNativeModes.XHR_WITH_PAYLOAD:
- case jsToNativeModes.XHR_OPTIONAL_PAYLOAD:
- pokeNativeViaXhr();
- break;
- default: // iframe-based.
- pokeNativeViaIframe();
- }
+// CB-10530
+function proxyChanged() {
+ var cexec = cordovaExec();
+
+ return (execProxy !== cexec && // proxy objects are different
+ iOSExec !== cexec // proxy object is not the current iOSExec
+ );
}
-function pokeNativeViaXhr() {
- // This prevents sending an XHR when there is already one being sent.
- // This should happen only in rare circumstances (refer to unit tests).
- if (execXhr && execXhr.readyState != 4) {
- execXhr = null;
- }
- // Re-using the XHR improves exec() performance by about 10%.
- execXhr = execXhr || new XMLHttpRequest();
- // Changing this to a GET will make the XHR reach the URIProtocol on 4.2.
- // For some reason it still doesn't work though...
- // Add a timestamp to the query param to prevent caching.
- execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true);
- if (!vcHeaderValue) {
- vcHeaderValue = /.*\((.*)\)$/.exec(navigator.userAgent)[1];
- }
- execXhr.setRequestHeader('vc', vcHeaderValue);
- execXhr.setRequestHeader('rc', ++requestCount);
- if (shouldBundleCommandJson()) {
- execXhr.setRequestHeader('cmds', iOSExec.nativeFetchMessages());
+// 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;
}
- execXhr.send(null);
+
+ return false;
}
-function pokeNativeViaIframe() {
+function pokeNative() {
// CB-5488 - Don't attempt to create iframe before document.body is available.
if (!document.body) {
- setTimeout(pokeNativeViaIframe);
+ setTimeout(pokeNative);
return;
}
- if (bridgeMode === jsToNativeModes.IFRAME_HASH_NO_PAYLOAD || bridgeMode === jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD) {
- // TODO: This bridge mode doesn't properly support being removed from the DOM (CB-7735)
- if (!execHashIframe) {
- execHashIframe = document.createElement('iframe');
- execHashIframe.style.display = 'none';
- document.body.appendChild(execHashIframe);
- // Hash changes don't work on about:blank, so switch it to file:///.
- execHashIframe.contentWindow.history.replaceState(null, null, 'file:///#');
- }
- // The delegate method is called only when the hash changes, so toggle it back and forth.
- hashToggle = hashToggle ^ 3;
- var hashValue = '%0' + hashToggle;
- if (bridgeMode === jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD) {
- hashValue += iOSExec.nativeFetchMessages();
- }
- execHashIframe.contentWindow.location.hash = hashValue;
+
+ // 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 {
- // 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) {
- pokeNative();
- }
- }, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn't fire).
+ execIframe = document.createElement('iframe');
+ execIframe.style.display = 'none';
+ execIframe.src = 'gap://ready';
+ document.body.appendChild(execIframe);
}
-}
-
-iOSExec.jsToNativeModes = jsToNativeModes;
-
-iOSExec.setJsToNativeBridgeMode = function(mode) {
- // Remove the iFrame since it may be no longer required, and its existence
- // can trigger browser bugs.
- // https://issues.apache.org/jira/browse/CB-593
- if (execIframe) {
- if (execIframe.parentNode) {
- execIframe.parentNode.removeChild(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();
+ }
}
- execIframe = null;
- }
- bridgeMode = mode;
-};
+ }, 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.
@@ -1102,11 +1038,14 @@ iOSExec.nativeFetchMessages = function() {
return json;
};
-iOSExec.nativeCallback = function(callbackId, status, message, keepCallback) {
+iOSExec.nativeCallback = function(callbackId, status, message, keepCallback, debug) {
return iOSExec.nativeEvalAndFetch(function() {
var success = status === 0 || status === 1;
var args = convertMessageToArgsNativeToJs(message);
- cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
+ function nc2() {
+ cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
+ }
+ setTimeout(nc2, 0);
});
};
@@ -1121,7 +1060,31 @@ iOSExec.nativeEvalAndFetch = function(func) {
}
};
-module.exports = iOSExec;
+// Proxy the exec for bridge changes. See CB-10106
+
+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;
+}
+
+function execProxy() {
+ cordovaExec().apply(null, arguments);
+};
+
+execProxy.nativeFetchMessages = function() {
+ return cordovaExec().nativeFetchMessages.apply(null, arguments);
+};
+
+execProxy.nativeEvalAndFetch = function() {
+ return cordovaExec().nativeEvalAndFetch.apply(null, arguments);
+};
+
+execProxy.nativeCallback = function() {
+ return cordovaExec().nativeCallback.apply(null, arguments);
+};
+
+module.exports = execProxy;
});
@@ -1606,7 +1569,7 @@ exports.reset();
});
-// file: e:/cordova/cordova-ios/cordova-js-src/platform.js
+// file: /Users/shazron/Documents/git/apache/cordova-ios/cordova-js-src/platform.js
define("cordova/platform", function(require, exports, module) {
module.exports = {
@@ -1888,7 +1851,10 @@ utils.clone = function(obj) {
retVal = {};
for(i in obj){
- if(!(i in retVal) || retVal[i] != obj[i]) {
+ // https://issues.apache.org/jira/browse/CB-11522 'unknown' type may be returned in
+ // custom protocol activation case on Windows Phone 8.1 causing "No such interface supported" exception
+ // on cloning.
+ if((!(i in retVal) || retVal[i] != obj[i]) && typeof obj[i] != 'undefined' && typeof obj[i] != 'unknown') {
retVal[i] = utils.clone(obj[i]);
}
}