Author: zhen
Date: Tue Apr 8 17:55:50 2008
New Revision: 646161
URL: http://svn.apache.org/viewvc?rev=646161&view=rev
Log:
Take advantage of Gecko's non-standard frameElement feature to greatly reduce
the cross-domain messaging latency in FireFox 2.
This optimization does not affect non-Gecko-based browsers.
Modified:
incubator/shindig/trunk/features/rpc/rpc.js
Modified: incubator/shindig/trunk/features/rpc/rpc.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/rpc/rpc.js?rev=646161&r1=646160&r2=646161&view=diff
==============================================================================
--- incubator/shindig/trunk/features/rpc/rpc.js (original)
+++ incubator/shindig/trunk/features/rpc/rpc.js Tue Apr 8 17:55:50 2008
@@ -95,6 +95,37 @@
throw new Error("Invalid auth token.");
}
}
+
+ // The Gecko engine used by FireFox etc. allows an IFrame to directly
call
+ // methods on the frameElement property added by the container page even
+ // if their domains don't match.
+ // Here we try to set up a relay channel using the frameElement technique
+ // to greatly reduce the latency of cross-domain calls if the postMessage
+ // method is not supported.
+ if (relayChannel === 'ifpc') {
+ if (rpc.f === '..') {
+ // Container-to-gadget call
+ try {
+ var fel = window.frameElement;
+ if (typeof fel.__g2c_rpc === 'function' &&
+ typeof fel.__g2c_rpc.__c2g_rpc != 'function') {
+ fel.__g2c_rpc.__c2g_rpc = function(args) {
+ process(gadgets.json.parse(args));
+ };
+ }
+ } catch (e) {
+ }
+ } else {
+ // Gadget-to-container call
+ var iframe = document.getElementById(rpc.f);
+ if (iframe && typeof iframe.__g2c_rpc != 'function') {
+ iframe.__g2c_rpc = function(args) {
+ process(gadgets.json.parse(args));
+ };
+ }
+ }
+ }
+
var result = (services[rpc.s] || services['']).apply(rpc, rpc.a);
if (rpc.c) {
gadgets.rpc.call(rpc.f, '__cb', null, rpc.c, result);
@@ -267,6 +298,25 @@
targetWin.postMessage(rpcData);
break;
default: // use 'ifpc' as a fallback mechanism
+ // Try the frameElement channel if available
+ try {
+ if (from === '..') {
+ // Container-to-gadget
+ var iframe = document.getElementById(targetId);
+ if (typeof iframe.__g2c_rpc.__c2g_rpc === 'function') {
+ iframe.__g2c_rpc.__c2g_rpc(rpcData);
+ return;
+ }
+ } else {
+ // Gadget-to-container
+ if (typeof window.frameElement.__g2c_rpc === 'function') {
+ window.frameElement.__g2c_rpc(rpcData);
+ return;
+ }
+ }
+ } catch (e) {
+ }
+
var relay = gadgets.rpc.getRelayUrl(targetId);
// TODO split message if too long