You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ka...@apache.org on 2014/11/12 17:49:43 UTC
[3/9] js commit: CB-7735 Fix iOS bridge race condition when using
innerHTML on
CB-7735 Fix iOS bridge race condition when using innerHTML on <body>
Project: http://git-wip-us.apache.org/repos/asf/cordova-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-js/commit/94291706
Tree: http://git-wip-us.apache.org/repos/asf/cordova-js/tree/94291706
Diff: http://git-wip-us.apache.org/repos/asf/cordova-js/diff/94291706
Branch: refs/heads/3.7.x
Commit: 94291706945c42fd47fa632ed30f5eb811080e95
Parents: d9e2a1c
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Oct 14 16:39:06 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 14 16:39:48 2014 -0400
----------------------------------------------------------------------
src/ios/exec.js | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/94291706/src/ios/exec.js
----------------------------------------------------------------------
diff --git a/src/ios/exec.js b/src/ios/exec.js
index e3e8b32..5c7cc98 100644
--- a/src/ios/exec.js
+++ b/src/ios/exec.js
@@ -52,15 +52,20 @@ var cordova = require('cordova'),
commandQueue = [], // Contains pending JS->Native messages.
isInContextOfEvalJs = 0;
-function createExecIframe() {
+function createExecIframe(src, unloadListener) {
var iframe = document.createElement("iframe");
iframe.style.display = 'none';
+ // Both the unload listener and the src must be set before adding the iframe
+ // to the document in order to avoid race conditions. Callbacks from native
+ // can happen within the appendChild() call!
+ iframe.onunload = unloadListener;
+ iframe.src = src;
document.body.appendChild(iframe);
return iframe;
}
function createHashIframe() {
- var ret = createExecIframe();
+ var ret = createExecIframe('about:blank');
// Hash changes don't work on about:blank, so switch it to file:///.
ret.contentWindow.history.replaceState(null, null, 'file:///#');
return ret;
@@ -233,6 +238,11 @@ function pokeNativeViaXhr() {
execXhr.send(null);
}
+function onIframeUnload() {
+ execIframe = null;
+ setTimeout(pokeNativeViaIframe, 0);
+}
+
function pokeNativeViaIframe() {
// CB-5488 - Don't attempt to create iframe before document.body is available.
if (!document.body) {
@@ -240,6 +250,7 @@ function pokeNativeViaIframe() {
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)
execHashIframe = execHashIframe || createHashIframe();
// Check if they've removed it from the DOM, and put it back if so.
if (!execHashIframe.contentWindow) {
@@ -253,12 +264,15 @@ function pokeNativeViaIframe() {
}
execHashIframe.contentWindow.location.hash = hashValue;
} else {
- execIframe = execIframe || createExecIframe();
// Check if they've removed it from the DOM, and put it back if so.
- if (!execIframe.contentWindow) {
- execIframe = createExecIframe();
+ if (execIframe && execIframe.contentWindow) {
+ // Listen for unload, since it can happen (CB-7735) that the iframe gets
+ // removed from the DOM before it gets a chance to poke the native side.
+ execIframe.contentWindow.onunload = onIframeUnload;
+ execIframe.src = 'gap://ready';
+ } else {
+ execIframe = createExecIframe('gap://ready', onIframeUnload);
}
- execIframe.src = "gap://ready";
}
}
@@ -276,6 +290,10 @@ iOSExec.setJsToNativeBridgeMode = function(mode) {
};
iOSExec.nativeFetchMessages = function() {
+ // Stop listing for window detatch once native side confirms poke.
+ if (execIframe && execIframe.contentWindow) {
+ execIframe.contentWindow.onunload = null;
+ }
// Each entry in commandQueue is a JSON string already.
if (!commandQueue.length) {
return '';
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org