Author: johnh
Date: Wed May  4 23:08:45 2011
New Revision: 1099635

URL: http://svn.apache.org/viewvc?rev=1099635&view=rev
Log:
Alternate means of exporting key cross-JS/SWF boundary methods. This ensures 
that the methods can be accessed by the SWF irrespective the JS obfuscation 
model/mode.


Modified:
    shindig/trunk/content/xpc.swf
    shindig/trunk/features/src/main/flex/Main.as
    shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js

Modified: shindig/trunk/content/xpc.swf
URL: 
http://svn.apache.org/viewvc/shindig/trunk/content/xpc.swf?rev=1099635&r1=1099634&r2=1099635&view=diff
==============================================================================
Files shindig/trunk/content/xpc.swf (original) and 
shindig/trunk/content/xpc.swf Wed May  4 23:08:45 2011 differ

Modified: shindig/trunk/features/src/main/flex/Main.as
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/flex/Main.as?rev=1099635&r1=1099634&r2=1099635&view=diff
==============================================================================
--- shindig/trunk/features/src/main/flex/Main.as (original)
+++ shindig/trunk/features/src/main/flex/Main.as Wed May  4 23:08:45 2011
@@ -116,6 +116,17 @@ class Main {
       my_origin = _level0.origin;
     }
 
+    var ready_method:String = "gadgets.rpctx.flash._ready";
+    var recv_method:String = "gadgets.rpctx.flash._receiveMessage";
+    var setup_done_method:String = "gadgets.rpctx.flash._setupDone";
+
+    if (_level0.jsl == "1") {
+      // Use 'safe-exported' methods.
+      ready_method = "___jsl._fm.ready";
+      recv_method = "___jsl._fm.receiveMessage";
+      setup_done_method = "___jsl._fm.setupDone";
+    }
+
     // Flash doesn't accept/honor ports, so we strip one if present
     // for canonicalization.
     var domain:String = stripPortIfPresent(
@@ -132,8 +143,7 @@ class Main {
     }
 
     // Install global communication channel setup method.
-    ExternalInterface.addCallback("setup", { },
-        function(rpc_key:String, channel_id:String, role:String) {
+    ExternalInterface.addCallback("setup", { }, function(rpc_key:String, 
channel_id:String, role:String) {
       var other_role:String;
 
       if (role == "INNER") {
@@ -148,8 +158,7 @@ class Main {
       receiving_lc.receiveMessage =
           function(to_origin:String, from_origin:String, in_rpc_key:String, 
message:String) {
         if ((to_origin === "*" || to_origin === my_origin) && (in_rpc_key == 
rpc_key)) {
-          ExternalInterface.call("gadgets.rpctx.flash._receiveMessage",
-              escFn(message), escFn(from_origin), escFn(to_origin));
+          ExternalInterface.call(recv_method, escFn(message), 
escFn(from_origin), escFn(to_origin));
         }
       };
 
@@ -168,11 +177,11 @@ class Main {
         // This in turn initiates a child-to-parent polling procedure to 
complete a bidirectional
         // communication handshake, since otherwise meaningful messages could 
be passed and dropped
         // before the receiving end was ready.
-        ExternalInterface.call("gadgets.rpctx.flash._setupDone");
+        ExternalInterface.call(setup_done_method);
       }
     });
 
     // Signal completion of the setup callback to calling-context JS for 
proper ordering.
-    ExternalInterface.call("gadgets.rpctx.flash._ready");
+    ExternalInterface.call(ready_method);
   }
 }

Modified: 
shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js?rev=1099635&r1=1099634&r2=1099635&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js 
(original)
+++ shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js 
Wed May  4 23:08:45 2011
@@ -35,8 +35,8 @@ if (!gadgets.rpctx.flash) {  // make lib
     var swfId = "___xpcswf";
     var swfUrl = null;
     var usingFlash = false;
-    var process = null;
-    var ready = null;
+    var processFn = null;
+    var readyFn = null;
     var secureReceivers = {};
     var relayHandle = null;
 
@@ -54,6 +54,27 @@ if (!gadgets.rpctx.flash) {  // make lib
     var readyMsgs = {};
 
     var myLoc = window.location.protocol + "//" + window.location.host;
+    var JSL_NS = '___jsl';
+    var METHODS_NS = '_fm';
+    var bucketNs;
+
+    function setupMethodBucket() {
+      window[JSL_NS] = window[JSL_NS] || {};
+      var container = window[JSL_NS];
+      var bucket = container[METHODS_NS] = {};
+      bucketNs = JSL_NS + "." + METHODS_NS;
+      return bucket;
+    }
+
+    var methodBucket = setupMethodBucket();
+
+    function exportMethod(method, requestedName) {
+      var exported = function() {
+        method.apply({}, arguments);
+      };
+      methodBucket[requestedName] = methodBucket[requestedName] || exported;
+      return bucketNs + "." + requestedName;
+    }
 
     function getChannelId(receiverId) {
       return receiverId === ".." ? gadgets.rpc.RPC_ID : receiverId;
@@ -72,7 +93,7 @@ if (!gadgets.rpctx.flash) {  // make lib
 
     function relayLoader() {
       if (relayHandle === null && document.body && swfUrl) {
-        var theSwf = swfUrl + '?cb=' + Math.random() + '&origin=' + myLoc;
+        var theSwf = swfUrl + '?cb=' + Math.random() + '&origin=' + myLoc + 
'&jsl=1';
 
         var containerDiv = document.createElement('div');
         containerDiv.style.height = '1px';
@@ -130,6 +151,25 @@ if (!gadgets.rpctx.flash) {  // make lib
       }
     }
 
+    function ready() {
+      flushHandshakes();
+      if (setupHandle !== null) {
+        window.clearTimeout(setupHandle);
+      }
+      setupHandle = null;
+    }
+    exportMethod(ready, 'ready');
+
+    function setupDone() {
+      // Called by SWF only for role_id = "INNER" ie when initializing to 
parent.
+      // Instantiates a polling handshake mechanism which ensures that any 
enqueued
+      // messages remain so until each side is ready to send.
+      if (!readyMsgs[".."] && readyHandle === null) {
+        readyHandle = window.setTimeout(childReadyPoller, READY_TIMEOUT_MS);
+      }
+    }
+    exportMethod(setupDone, 'setupDone');
+
     function call(targetId, from, rpc) {
       var targetOrigin = gadgets.rpc.getTargetOrigin(targetId);
       var rpcKey = gadgets.rpc.getAuthToken(targetId);
@@ -139,6 +179,28 @@ if (!gadgets.rpctx.flash) {  // make lib
       return true;
     }
 
+    function receiveMessage(message, fromOrigin, toOrigin) {
+      var jsonMsg = gadgets.json.parse(message);
+      var channelReady = jsonMsg[SWF_CHANNEL_READY];
+      if (channelReady) {
+        // Special message indicating that a ready message has been received, 
indicating
+        // the sender is now prepared to receive messages. This type of 
message is instigated
+        // by child context in polling fashion, and is responded-to by parent 
context(s).
+        // If readyHandle is non-null, then it should first be cleared.
+        // This method is OK to call twice, if it occurs in a race.
+        readyFn(channelReady, true);
+        readyMsgs[channelReady] = true;
+        if (channelReady !== "..") {
+          // Child-to-parent: immediately signal that parent is ready.
+          // Now that we know that child can receive messages, it's enough to 
send once.
+          sendChannelReady(channelReady);
+        }
+        return;
+      }
+      window.setTimeout(function() { processFn(jsonMsg, fromOrigin); }, 0);
+    }
+    exportMethod(receiveMessage, 'receiveMessage');
+
     function sendChannelReady(receiverId) {
       var myId = gadgets.rpc.RPC_ID;
       var readyAck = {};
@@ -156,9 +218,9 @@ if (!gadgets.rpctx.flash) {  // make lib
         return true;
       },
 
-      init: function(processFn, readyFn) {
-        process = processFn;
-        ready = readyFn;
+      init: function(processIn, readyIn) {
+        processFn = processIn;
+        readyFn = readyIn;
         usingFlash = true;
         return true;
       },
@@ -183,43 +245,9 @@ if (!gadgets.rpctx.flash) {  // make lib
       call: call,
 
       // Methods called by relay SWF. Should be considered private.
-      _receiveMessage: function(message, fromOrigin, toOrigin) {
-        var jsonMsg = gadgets.json.parse(message);
-        var channelReady = jsonMsg[SWF_CHANNEL_READY];
-        if (channelReady) {
-          // Special message indicating that a ready message has been 
received, indicating
-          // the sender is now prepared to receive messages. This type of 
message is instigated
-          // by child context in polling fashion, and is responded-to by 
parent context(s).
-          // If readyHandle is non-null, then it should first be cleared.
-          // This method is OK to call twice, if it occurs in a race.
-          ready(channelReady, true);
-          readyMsgs[channelReady] = true;
-          if (channelReady !== "..") {
-            // Child-to-parent: immediately signal that parent is ready.
-            // Now that we know that child can receive messages, it's enough 
to send once.
-            sendChannelReady(channelReady);
-          }
-          return;
-        }
-        window.setTimeout(function() { process(jsonMsg, fromOrigin); }, 0);
-      },
-
-      _ready: function() {
-        flushHandshakes();
-        if (setupHandle !== null) {
-          window.clearTimeout(setupHandle);
-        }
-        setupHandle = null;
-      },
-
-      _setupDone: function() {
-        // Called by SWF only for role_id = "INNER" ie when initializing to 
parent.
-        // Instantiates a polling handshake mechanism which ensures that any 
enqueued
-        // messages remain so until each side is ready to send.
-        if (!readyMsgs[".."] && readyHandle === null) {
-          readyHandle = window.setTimeout(childReadyPoller, READY_TIMEOUT_MS);
-        }
-      }
+      _receiveMessage: receiveMessage,
+      _ready: ready,
+      _setupDone: setupDone
     };
   }();
 


Reply via email to