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
};
}();