You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2012/08/17 18:40:07 UTC

js commit: Add logic to toggle between different exec() techniques on iOS.

Updated Branches:
  refs/heads/master 993c3aec5 -> d5a72028f


Add logic to toggle between different exec() techniques on iOS.


Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/commit/d5a72028
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/d5a72028
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/d5a72028

Branch: refs/heads/master
Commit: d5a72028f2375c9ba587e37a3e6f099765b50b03
Parents: 993c3ae
Author: Andrew Grieve <ag...@chromium.org>
Authored: Wed Aug 8 22:39:48 2012 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Fri Aug 17 12:39:36 2012 -0400

----------------------------------------------------------------------
 lib/ios/exec.js |   77 ++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 63 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/d5a72028/lib/ios/exec.js
----------------------------------------------------------------------
diff --git a/lib/ios/exec.js b/lib/ios/exec.js
index bf0e1dd..ffe8710 100644
--- a/lib/ios/exec.js
+++ b/lib/ios/exec.js
@@ -5,20 +5,42 @@
      * @private
      */
 var cordova = require('cordova'),
+    channel = require('cordova/channel'),
+    nativecomm = require('cordova/plugin/ios/nativecomm'),
     utils = require('cordova/utils'),
-    gapBridge,
-    createGapBridge = function() {
-
-        gapBridge = document.createElement("iframe");
-        gapBridge.setAttribute("style", "display:none;");
-        gapBridge.setAttribute("height","0px");
-        gapBridge.setAttribute("width","0px");
-        gapBridge.setAttribute("frameborder","0");
-        document.documentElement.appendChild(gapBridge);
+    jsToNativeModes = {
+        IFRAME_NAV: 0,
+        XHR_NO_PAYLOAD: 1,
+        XHR_WITH_PAYLOAD: 2,
+        XHR_OPTIONAL_PAYLOAD: 3
     },
-    channel = require('cordova/channel');
+    bridgeMode = jsToNativeModes.IFRAME_NAV,
+    execIframe,
+    execXhr;
+
+function createExecIframe() {
+    var iframe = document.createElement("iframe");
+    iframe.style.display = 'none';
+    document.body.appendChild(iframe);
+    return iframe;
+}
+
+function shouldBundleCommandJson() {
+    if (bridgeMode == 2) {
+        return true;
+    }
+    if (bridgeMode == 3) {
+        var payloadLength = 0;
+        for (var i = 0; i < cordova.commandQueue.length; ++i) {
+            payloadLength += cordova.commandQueue[i].length;
+        }
+        // The value here was determined using the benchmark within CordovaLibApp on an iPad 3.
+        return payloadLength < 4500;
+    }
+    return false;
+}
 
-module.exports = function() {
+function iOSExec() {
     if (!channel.onCordovaReady.fired) {
         utils.alert("ERROR: Attempting to call cordova.exec()" +
               " before 'deviceready'. Ignoring.");
@@ -68,9 +90,36 @@ module.exports = function() {
     // commands to execute, unless the queue is currently being flushed, in
     // which case the command will be picked up without notification.
     if (cordova.commandQueue.length == 1 && !cordova.commandQueueFlushing) {
-        if (!gapBridge) {
-            createGapBridge();
+        if (bridgeMode) {
+            execXhr = execXhr || new XMLHttpRequest();
+            execXhr.open('HEAD', "file:///!gap_exec", true);
+            execXhr.setRequestHeader('vc', cordova.iOSVCAddr);
+            if (shouldBundleCommandJson()) {
+                execXhr.setRequestHeader('cmds', nativecomm());
+            }
+            execXhr.send(null);
+        } else {
+            execIframe = execIframe || createExecIframe();
+            execIframe.src = "gap://ready";
         }
-        gapBridge.src = "gap://ready";
     }
+}
+
+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) {
+        execIframe.parentNode.removeChild(execIframe);
+        execIframe = null;
+    }
+    if (mode && !cordova.iOSVCAddr) {
+        alert('ViewController not correctly initialized for XHR mode.');
+        mode = 0;
+    }
+    bridgeMode = mode;
 };
+
+module.exports = iOSExec;


Re: js commit: Add logic to toggle between different exec() techniques on iOS.

Posted by Shazron <sh...@gmail.com>.
Andrew, I'll add a doc issue for this, although I don't know where the
doc will go yet exactly. Also perhaps a mobile-spec issue. I'll update
the ios repo with the new js in the interim.

On Fri, Aug 17, 2012 at 9:40 AM,  <ag...@apache.org> wrote:
> Updated Branches:
>   refs/heads/master 993c3aec5 -> d5a72028f
>
>
> Add logic to toggle between different exec() techniques on iOS.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/repo
> Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/commit/d5a72028
> Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/d5a72028
> Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/d5a72028
>
> Branch: refs/heads/master
> Commit: d5a72028f2375c9ba587e37a3e6f099765b50b03
> Parents: 993c3ae
> Author: Andrew Grieve <ag...@chromium.org>
> Authored: Wed Aug 8 22:39:48 2012 -0400
> Committer: Andrew Grieve <ag...@chromium.org>
> Committed: Fri Aug 17 12:39:36 2012 -0400
>
> ----------------------------------------------------------------------
>  lib/ios/exec.js |   77 ++++++++++++++++++++++++++++++++++++++++---------
>  1 files changed, 63 insertions(+), 14 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/d5a72028/lib/ios/exec.js
> ----------------------------------------------------------------------
> diff --git a/lib/ios/exec.js b/lib/ios/exec.js
> index bf0e1dd..ffe8710 100644
> --- a/lib/ios/exec.js
> +++ b/lib/ios/exec.js
> @@ -5,20 +5,42 @@
>       * @private
>       */
>  var cordova = require('cordova'),
> +    channel = require('cordova/channel'),
> +    nativecomm = require('cordova/plugin/ios/nativecomm'),
>      utils = require('cordova/utils'),
> -    gapBridge,
> -    createGapBridge = function() {
> -
> -        gapBridge = document.createElement("iframe");
> -        gapBridge.setAttribute("style", "display:none;");
> -        gapBridge.setAttribute("height","0px");
> -        gapBridge.setAttribute("width","0px");
> -        gapBridge.setAttribute("frameborder","0");
> -        document.documentElement.appendChild(gapBridge);
> +    jsToNativeModes = {
> +        IFRAME_NAV: 0,
> +        XHR_NO_PAYLOAD: 1,
> +        XHR_WITH_PAYLOAD: 2,
> +        XHR_OPTIONAL_PAYLOAD: 3
>      },
> -    channel = require('cordova/channel');
> +    bridgeMode = jsToNativeModes.IFRAME_NAV,
> +    execIframe,
> +    execXhr;
> +
> +function createExecIframe() {
> +    var iframe = document.createElement("iframe");
> +    iframe.style.display = 'none';
> +    document.body.appendChild(iframe);
> +    return iframe;
> +}
> +
> +function shouldBundleCommandJson() {
> +    if (bridgeMode == 2) {
> +        return true;
> +    }
> +    if (bridgeMode == 3) {
> +        var payloadLength = 0;
> +        for (var i = 0; i < cordova.commandQueue.length; ++i) {
> +            payloadLength += cordova.commandQueue[i].length;
> +        }
> +        // The value here was determined using the benchmark within CordovaLibApp on an iPad 3.
> +        return payloadLength < 4500;
> +    }
> +    return false;
> +}
>
> -module.exports = function() {
> +function iOSExec() {
>      if (!channel.onCordovaReady.fired) {
>          utils.alert("ERROR: Attempting to call cordova.exec()" +
>                " before 'deviceready'. Ignoring.");
> @@ -68,9 +90,36 @@ module.exports = function() {
>      // commands to execute, unless the queue is currently being flushed, in
>      // which case the command will be picked up without notification.
>      if (cordova.commandQueue.length == 1 && !cordova.commandQueueFlushing) {
> -        if (!gapBridge) {
> -            createGapBridge();
> +        if (bridgeMode) {
> +            execXhr = execXhr || new XMLHttpRequest();
> +            execXhr.open('HEAD', "file:///!gap_exec", true);
> +            execXhr.setRequestHeader('vc', cordova.iOSVCAddr);
> +            if (shouldBundleCommandJson()) {
> +                execXhr.setRequestHeader('cmds', nativecomm());
> +            }
> +            execXhr.send(null);
> +        } else {
> +            execIframe = execIframe || createExecIframe();
> +            execIframe.src = "gap://ready";
>          }
> -        gapBridge.src = "gap://ready";
>      }
> +}
> +
> +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) {
> +        execIframe.parentNode.removeChild(execIframe);
> +        execIframe = null;
> +    }
> +    if (mode && !cordova.iOSVCAddr) {
> +        alert('ViewController not correctly initialized for XHR mode.');
> +        mode = 0;
> +    }
> +    bridgeMode = mode;
>  };
> +
> +module.exports = iOSExec;
>