You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2010/10/07 17:54:40 UTC
svn commit: r1005506 [40/45] - in /shindig/branches/2.0.x: ./
content/editor/ content/editor/CodeMirror-0.8/
content/editor/CodeMirror-0.8/css/ content/editor/CodeMirror-0.8/js/
content/samplecontainer/examples/media/ etc/ etc/checkstyle/ extras/src/ma...
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/rpc/nix.transport.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/rpc/nix.transport.js?rev=1005506&r1=1005505&r2=1005506&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/rpc/nix.transport.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/rpc/nix.transport.js Thu Oct 7 15:54:09 2010
@@ -64,222 +64,222 @@ gadgets.rpctx = gadgets.rpctx || {};
*/
if (!gadgets.rpctx.nix) { // make lib resilient to double-inclusion
-gadgets.rpctx.nix = function() {
- // Consts for NIX. VBScript doesn't
- // allow items to start with _ for some reason,
- // so we need to make these names quite unique, as
- // they will go into the global namespace.
- var NIX_WRAPPER = 'GRPC____NIXVBS_wrapper';
- var NIX_GET_WRAPPER = 'GRPC____NIXVBS_get_wrapper';
- var NIX_HANDLE_MESSAGE = 'GRPC____NIXVBS_handle_message';
- var NIX_CREATE_CHANNEL = 'GRPC____NIXVBS_create_channel';
- var MAX_NIX_SEARCHES = 10;
- var NIX_SEARCH_PERIOD = 500;
-
- // JavaScript reference to the NIX VBScript wrappers.
- // Gadgets will have but a single channel under
- // nix_channels['..'] while containers will have a channel
- // per gadget stored under the gadget's ID.
- var nix_channels = {};
- var isForceSecure = {};
-
- // Store the ready signal method for use on handshake complete.
- var ready;
- var numHandlerSearches = 0;
-
- // Search for NIX handler to parent. Tries MAX_NIX_SEARCHES times every
- // NIX_SEARCH_PERIOD milliseconds.
- function conductHandlerSearch() {
- // Call from gadget to the container.
- var handler = nix_channels['..'];
- if (handler) {
- return;
- }
-
- if (++numHandlerSearches > MAX_NIX_SEARCHES) {
- // Handshake failed. Will fall back.
- gadgets.warn('Nix transport setup failed, falling back...');
- ready('..', false);
- return;
- }
-
- // If the gadget has yet to retrieve a reference to
- // the NIX handler, try to do so now. We don't do a
- // typeof(window.opener.GetAuthToken) check here
- // because it means accessing that field on the COM object, which,
- // being an internal function reference, is not allowed.
- // "in" works because it merely checks for the prescence of
- // the key, rather than actually accessing the object's property.
- // This is just a sanity check, not a validity check.
- if (!handler && window.opener && "GetAuthToken" in window.opener) {
- handler = window.opener;
-
- // Create the channel to the parent/container.
- // First verify that it knows our auth token to ensure it's not
- // an impostor.
- if (handler.GetAuthToken() == gadgets.rpc.getAuthToken('..')) {
- // Auth match - pass it back along with our wrapper to finish.
- // own wrapper and our authentication token for co-verification.
- var token = gadgets.rpc.getAuthToken('..');
- handler.CreateChannel(window[NIX_GET_WRAPPER]('..', token),
- token);
- // Set channel handler
- nix_channels['..'] = handler;
- window.opener = null;
-
- // Signal success and readiness to send to parent.
- // Container-to-gadget bit flipped in CreateChannel.
- ready('..', true);
+ gadgets.rpctx.nix = function() {
+ // Consts for NIX. VBScript doesn't
+ // allow items to start with _ for some reason,
+ // so we need to make these names quite unique, as
+ // they will go into the global namespace.
+ var NIX_WRAPPER = 'GRPC____NIXVBS_wrapper';
+ var NIX_GET_WRAPPER = 'GRPC____NIXVBS_get_wrapper';
+ var NIX_HANDLE_MESSAGE = 'GRPC____NIXVBS_handle_message';
+ var NIX_CREATE_CHANNEL = 'GRPC____NIXVBS_create_channel';
+ var MAX_NIX_SEARCHES = 10;
+ var NIX_SEARCH_PERIOD = 500;
+
+ // JavaScript reference to the NIX VBScript wrappers.
+ // Gadgets will have but a single channel under
+ // nix_channels['..'] while containers will have a channel
+ // per gadget stored under the gadget's ID.
+ var nix_channels = {};
+ var isForceSecure = {};
+
+ // Store the ready signal method for use on handshake complete.
+ var ready;
+ var numHandlerSearches = 0;
+
+ // Search for NIX handler to parent. Tries MAX_NIX_SEARCHES times every
+ // NIX_SEARCH_PERIOD milliseconds.
+ function conductHandlerSearch() {
+ // Call from gadget to the container.
+ var handler = nix_channels['..'];
+ if (handler) {
return;
}
- }
- // Try again.
- window.setTimeout(function() { conductHandlerSearch(); },
- NIX_SEARCH_PERIOD);
- }
-
- // Returns current window location, without hash values
- function getLocationNoHash() {
- var loc = window.location.href;
- var idx = loc.indexOf('#');
- if (idx == -1) {
- return loc;
- }
- return loc.substring(0, idx);
- }
+ if (++numHandlerSearches > MAX_NIX_SEARCHES) {
+ // Handshake failed. Will fall back.
+ gadgets.warn('Nix transport setup failed, falling back...');
+ ready('..', false);
+ return;
+ }
- // When "forcesecure" is set to true, use the relay file and a simple variant of IFPC to first
- // authenticate the container and gadget with each other. Once that is done, then initialize
- // the NIX protocol.
- function setupSecureRelayToParent(rpctoken) {
- // To the parent, transmit the child's URL, the passed in auth
- // token, and another token generated by the child.
- var childToken = (0x7FFFFFFF * Math.random()) | 0; // TODO expose way to have child set this value
- var data = [
- getLocationNoHash(),
- childToken
- ];
- gadgets.rpc._createRelayIframe(rpctoken, data);
-
- // listen for response from parent
- var hash = window.location.href.split('#')[1] || '';
-
- function relayTimer() {
- var newHash = window.location.href.split('#')[1] || '';
- if (newHash !== hash) {
- clearInterval(relayTimerId);
- var params = gadgets.util.getUrlParameters(window.location.href);
- if (params.childtoken == childToken) {
- // parent has been authenticated; now init NIX
- conductHandlerSearch();
+ // If the gadget has yet to retrieve a reference to
+ // the NIX handler, try to do so now. We don't do a
+ // typeof(window.opener.GetAuthToken) check here
+ // because it means accessing that field on the COM object, which,
+ // being an internal function reference, is not allowed.
+ // "in" works because it merely checks for the prescence of
+ // the key, rather than actually accessing the object's property.
+ // This is just a sanity check, not a validity check.
+ if (!handler && window.opener && 'GetAuthToken' in window.opener) {
+ handler = window.opener;
+
+ // Create the channel to the parent/container.
+ // First verify that it knows our auth token to ensure it's not
+ // an impostor.
+ if (handler.GetAuthToken() == gadgets.rpc.getAuthToken('..')) {
+ // Auth match - pass it back along with our wrapper to finish.
+ // own wrapper and our authentication token for co-verification.
+ var token = gadgets.rpc.getAuthToken('..');
+ handler.CreateChannel(window[NIX_GET_WRAPPER]('..', token),
+ token);
+ // Set channel handler
+ nix_channels['..'] = handler;
+ window.opener = null;
+
+ // Signal success and readiness to send to parent.
+ // Container-to-gadget bit flipped in CreateChannel.
+ ready('..', true);
return;
}
- // security error -- token didn't match
- ready('..', false);
}
+
+ // Try again.
+ window.setTimeout(function() { conductHandlerSearch(); },
+ NIX_SEARCH_PERIOD);
}
- var relayTimerId = setInterval( relayTimer, 100 );
- }
- return {
- getCode: function() {
- return 'nix';
- },
-
- isParentVerifiable: function(opt_receiverId) {
- // NIX is only parent verifiable if a receiver was setup with "forcesecure" set to TRUE.
- if (opt_receiverId) {
- return isForceSecure[opt_receiverId];
+ // Returns current window location, without hash values
+ function getLocationNoHash() {
+ var loc = window.location.href;
+ var idx = loc.indexOf('#');
+ if (idx == -1) {
+ return loc;
}
- return false;
- },
-
- init: function(processFn, readyFn) {
- ready = readyFn;
+ return loc.substring(0, idx);
+ }
- // Ensure VBScript wrapper code is in the page and that the
- // global Javascript handlers have been set.
- // VBScript methods return a type of 'unknown' when
- // checked via the typeof operator in IE. Fortunately
- // for us, this only applies to COM objects, so we
- // won't see this for a real Javascript object.
- if (typeof window[NIX_GET_WRAPPER] !== 'unknown') {
- window[NIX_HANDLE_MESSAGE] = function(data) {
- window.setTimeout(
- function() { processFn(gadgets.json.parse(data)); }, 0);
- };
-
- window[NIX_CREATE_CHANNEL] = function(name, channel, token) {
- // Verify the authentication token of the gadget trying
- // to create a channel for us.
- if (gadgets.rpc.getAuthToken(name) === token) {
- nix_channels[name] = channel;
- ready(name, true);
+ // When "forcesecure" is set to true, use the relay file and a simple variant of IFPC to first
+ // authenticate the container and gadget with each other. Once that is done, then initialize
+ // the NIX protocol.
+ function setupSecureRelayToParent(rpctoken) {
+ // To the parent, transmit the child's URL, the passed in auth
+ // token, and another token generated by the child.
+ var childToken = (0x7FFFFFFF * Math.random()) | 0; // TODO expose way to have child set this value
+ var data = [
+ getLocationNoHash(),
+ childToken
+ ];
+ gadgets.rpc._createRelayIframe(rpctoken, data);
+
+ // listen for response from parent
+ var hash = window.location.href.split('#')[1] || '';
+
+ function relayTimer() {
+ var newHash = window.location.href.split('#')[1] || '';
+ if (newHash !== hash) {
+ clearInterval(relayTimerId);
+ var params = gadgets.util.getUrlParameters(window.location.href);
+ if (params.childtoken == childToken) {
+ // parent has been authenticated; now init NIX
+ conductHandlerSearch();
+ return;
}
- };
+ // security error -- token didn't match
+ ready('..', false);
+ }
+ }
+ var relayTimerId = setInterval(relayTimer, 100);
+ }
+
+ return {
+ getCode: function() {
+ return 'nix';
+ },
+
+ isParentVerifiable: function(opt_receiverId) {
+ // NIX is only parent verifiable if a receiver was setup with "forcesecure" set to TRUE.
+ if (opt_receiverId) {
+ return isForceSecure[opt_receiverId];
+ }
+ return false;
+ },
- // Inject the VBScript code needed.
- var vbscript =
- // We create a class to act as a wrapper for
- // a Javascript call, to prevent a break in of
- // the context.
- 'Class ' + NIX_WRAPPER + '\n '
-
- // An internal member for keeping track of the
- // name of the document (container or gadget)
- // for which this wrapper is intended. For
- // those wrappers created by gadgets, this is not
- // used (although it is set to "..")
+ init: function(processFn, readyFn) {
+ ready = readyFn;
+
+ // Ensure VBScript wrapper code is in the page and that the
+ // global Javascript handlers have been set.
+ // VBScript methods return a type of 'unknown' when
+ // checked via the typeof operator in IE. Fortunately
+ // for us, this only applies to COM objects, so we
+ // won't see this for a real Javascript object.
+ if (typeof window[NIX_GET_WRAPPER] !== 'unknown') {
+ window[NIX_HANDLE_MESSAGE] = function(data) {
+ window.setTimeout(
+ function() { processFn(gadgets.json.parse(data)); }, 0);
+ };
+
+ window[NIX_CREATE_CHANNEL] = function(name, channel, token) {
+ // Verify the authentication token of the gadget trying
+ // to create a channel for us.
+ if (gadgets.rpc.getAuthToken(name) === token) {
+ nix_channels[name] = channel;
+ ready(name, true);
+ }
+ };
+
+ // Inject the VBScript code needed.
+ var vbscript =
+ // We create a class to act as a wrapper for
+ // a Javascript call, to prevent a break in of
+ // the context.
+ 'Class ' + NIX_WRAPPER + '\n '
+
+ // An internal member for keeping track of the
+ // name of the document (container or gadget)
+ // for which this wrapper is intended. For
+ // those wrappers created by gadgets, this is not
+ // used (although it is set to "..")
+ 'Private m_Intended\n'
- // Stores the auth token used to communicate with
- // the gadget. The GetChannelCreator method returns
- // an object that returns this auth token. Upon matching
- // that with its own, the gadget uses the object
- // to actually establish the communication channel.
+ // Stores the auth token used to communicate with
+ // the gadget. The GetChannelCreator method returns
+ // an object that returns this auth token. Upon matching
+ // that with its own, the gadget uses the object
+ // to actually establish the communication channel.
+ 'Private m_Auth\n'
- // Method for internally setting the value
- // of the m_Intended property.
+ // Method for internally setting the value
+ // of the m_Intended property.
+ 'Public Sub SetIntendedName(name)\n '
+ 'If isEmpty(m_Intended) Then\n'
+ 'm_Intended = name\n'
+ 'End If\n'
+ 'End Sub\n'
- // Method for internally setting the value of the m_Auth property.
+ // Method for internally setting the value of the m_Auth property.
+ 'Public Sub SetAuth(auth)\n '
+ 'If isEmpty(m_Auth) Then\n'
+ 'm_Auth = auth\n'
+ 'End If\n'
+ 'End Sub\n'
- // A wrapper method which actually causes a
- // message to be sent to the other context.
+ // A wrapper method which actually causes a
+ // message to be sent to the other context.
+ 'Public Sub SendMessage(data)\n '
+ NIX_HANDLE_MESSAGE + '(data)\n'
+ 'End Sub\n'
- // Returns the auth token to the gadget, so it can
- // confirm a match before initiating the connection
+ // Returns the auth token to the gadget, so it can
+ // confirm a match before initiating the connection
+ 'Public Function GetAuthToken()\n '
+ 'GetAuthToken = m_Auth\n'
+ 'End Function\n'
- // Method for setting up the container->gadget
- // channel. Not strictly needed in the gadget's
- // wrapper, but no reason to get rid of it. Note here
- // that we pass the intended name to the NIX_CREATE_CHANNEL
- // method so that it can save the channel in the proper place
- // *and* verify the channel via the authentication token passed
- // here.
+ // Method for setting up the container->gadget
+ // channel. Not strictly needed in the gadget's
+ // wrapper, but no reason to get rid of it. Note here
+ // that we pass the intended name to the NIX_CREATE_CHANNEL
+ // method so that it can save the channel in the proper place
+ // *and* verify the channel via the authentication token passed
+ // here.
+ 'Public Sub CreateChannel(channel, auth)\n '
+ 'Call ' + NIX_CREATE_CHANNEL + '(m_Intended, channel, auth)\n'
+ 'End Sub\n'
+ 'End Class\n'
- // Function to get a reference to the wrapper.
+ // Function to get a reference to the wrapper.
+ 'Function ' + NIX_GET_WRAPPER + '(name, auth)\n'
+ 'Dim wrap\n'
+ 'Set wrap = New ' + NIX_WRAPPER + '\n'
@@ -288,55 +288,55 @@ gadgets.rpctx.nix = function() {
+ 'Set ' + NIX_GET_WRAPPER + ' = wrap\n'
+ 'End Function';
+ try {
+ window.execScript(vbscript, 'vbscript');
+ } catch (e) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ setup: function(receiverId, token, forcesecure) {
+ isForceSecure[receiverId] = !!forcesecure;
+ if (receiverId === '..') {
+ if (forcesecure) {
+ setupSecureRelayToParent(token);
+ } else {
+ conductHandlerSearch();
+ }
+ return true;
+ }
try {
- window.execScript(vbscript, 'vbscript');
+ var frame = document.getElementById(receiverId);
+ var wrapper = window[NIX_GET_WRAPPER](receiverId, token);
+ frame.contentWindow.opener = wrapper;
} catch (e) {
return false;
}
- }
- return true;
- },
+ return true;
+ },
- setup: function(receiverId, token, forcesecure) {
- isForceSecure[receiverId] = !!forcesecure;
- if (receiverId === '..') {
- if (forcesecure) {
- setupSecureRelayToParent(token);
- } else {
- conductHandlerSearch();
+ call: function(targetId, from, rpc) {
+ try {
+ // If we have a handler, call it.
+ if (nix_channels[targetId]) {
+ nix_channels[targetId].SendMessage(gadgets.json.stringify(rpc));
+ }
+ } catch (e) {
+ return false;
}
return true;
- }
- try {
- var frame = document.getElementById(receiverId);
- var wrapper = window[NIX_GET_WRAPPER](receiverId, token);
- frame.contentWindow.opener = wrapper;
- } catch (e) {
- return false;
- }
- return true;
- },
+ },
- call: function(targetId, from, rpc) {
- try {
- // If we have a handler, call it.
- if (nix_channels[targetId]) {
- nix_channels[targetId].SendMessage(gadgets.json.stringify(rpc));
- }
- } catch (e) {
- return false;
+ // data = [child URL, child auth token]
+ relayOnload: function(receiverId, data) {
+ // transmit childtoken back to child to complete authentication
+ var src = data[0] + '#childtoken=' + data[1];
+ var childIframe = document.getElementById(receiverId);
+ childIframe.src = src;
}
- return true;
- },
-
- // data = [child URL, child auth token]
- relayOnload: function(receiverId, data) {
- // transmit childtoken back to child to complete authentication
- var src = data[0] + '#childtoken=' + data[1];
- var childIframe = document.getElementById(receiverId);
- childIframe.src = src;
- }
- };
-}();
+ };
+ }();
} // !end of double-inclusion guard
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/rpc/rmr.transport.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/rpc/rmr.transport.js?rev=1005506&r1=1005505&r2=1005506&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/rpc/rmr.transport.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/rpc/rmr.transport.js Thu Oct 7 15:54:09 2010
@@ -42,22 +42,22 @@ gadgets.rpctx = gadgets.rpctx || {};
*/
if (!gadgets.rpctx.rmr) { // make lib resilient to double-inclusion
-gadgets.rpctx.rmr = function() {
- // Consts for RMR, including time in ms RMR uses to poll for
- // its relay frame to be created, and the max # of polls it does.
- var RMR_SEARCH_TIMEOUT = 500;
- var RMR_MAX_POLLS = 10;
-
- // JavaScript references to the channel objects used by RMR.
- // Gadgets will have but a single channel under
- // rmr_channels['..'] while containers will have a channel
- // per gadget stored under the gadget's ID.
- var rmr_channels = {};
-
- var process;
- var ready;
+ gadgets.rpctx.rmr = function() {
+ // Consts for RMR, including time in ms RMR uses to poll for
+ // its relay frame to be created, and the max # of polls it does.
+ var RMR_SEARCH_TIMEOUT = 500;
+ var RMR_MAX_POLLS = 10;
+
+ // JavaScript references to the channel objects used by RMR.
+ // Gadgets will have but a single channel under
+ // rmr_channels['..'] while containers will have a channel
+ // per gadget stored under the gadget's ID.
+ var rmr_channels = {};
- /**
+ var process;
+ var ready;
+
+ /**
* Append an RMR relay frame to the document. This allows the receiver
* to start receiving messages.
*
@@ -66,122 +66,122 @@ gadgets.rpctx.rmr = function() {
* @param {string} data to pass along to the frame.
* @param {string=} opt_frameId ID of frame for which relay is being appended (optional).
*/
- function appendRmrFrame(channelFrame, relayUri, data, opt_frameId) {
- var appendFn = function() {
- // Append the iframe.
- document.body.appendChild(channelFrame);
-
- // Set the src of the iframe to 'about:blank' first and then set it
- // to the relay URI. This prevents the iframe from maintaining a src
- // to the 'old' relay URI if the page is returned to from another.
- // In other words, this fixes the bfcache issue that causes the iframe's
- // src property to not be updated despite us assigning it a new value here.
- channelFrame.src = 'about:blank';
- if (opt_frameId) {
- // Process the initial sent payload (typically sent by container to
- // child/gadget) only when the relay frame has finished loading. We
- // do this to ensure that, in processRmrData(...), the ACK sent due
- // to processing can actually be sent. Before this time, the frame's
- // contentWindow is null, making it impossible to do so.
- channelFrame.onload = function() {
- processRmrData(opt_frameId);
- };
- }
- channelFrame.src = relayUri + '#' + data;
- };
+ function appendRmrFrame(channelFrame, relayUri, data, opt_frameId) {
+ var appendFn = function() {
+ // Append the iframe.
+ document.body.appendChild(channelFrame);
+
+ // Set the src of the iframe to 'about:blank' first and then set it
+ // to the relay URI. This prevents the iframe from maintaining a src
+ // to the 'old' relay URI if the page is returned to from another.
+ // In other words, this fixes the bfcache issue that causes the iframe's
+ // src property to not be updated despite us assigning it a new value here.
+ channelFrame.src = 'about:blank';
+ if (opt_frameId) {
+ // Process the initial sent payload (typically sent by container to
+ // child/gadget) only when the relay frame has finished loading. We
+ // do this to ensure that, in processRmrData(...), the ACK sent due
+ // to processing can actually be sent. Before this time, the frame's
+ // contentWindow is null, making it impossible to do so.
+ channelFrame.onload = function() {
+ processRmrData(opt_frameId);
+ };
+ }
+ channelFrame.src = relayUri + '#' + data;
+ };
- if (document.body) {
- appendFn();
- } else {
- // Common gadget case: attaching header during in-gadget handshake,
- // when we may still be in script in head. Attach onload.
- gadgets.util.registerOnLoadHandler(function() { appendFn(); });
+ if (document.body) {
+ appendFn();
+ } else {
+ // Common gadget case: attaching header during in-gadget handshake,
+ // when we may still be in script in head. Attach onload.
+ gadgets.util.registerOnLoadHandler(function() { appendFn(); });
+ }
}
- }
- /**
+ /**
* Sets up the RMR transport frame for the given frameId. For gadgets
* calling containers, the frameId should be '..'.
*
* @param {string} frameId The ID of the frame.
*/
- function setupRmr(frameId) {
- if (typeof rmr_channels[frameId] === "object") {
- // Sanity check. Already done.
- return;
- }
-
- var channelFrame = document.createElement('iframe');
- var frameStyle = channelFrame.style;
- frameStyle.position = 'absolute';
- frameStyle.top = '0px';
- frameStyle.border = '0';
- frameStyle.opacity = '0';
-
- // The width here is important as RMR
- // makes use of the resize handler for the frame.
- // Do not modify unless you test thoroughly!
- frameStyle.width = '10px';
- frameStyle.height = '1px';
- channelFrame.id = 'rmrtransport-' + frameId;
- channelFrame.name = channelFrame.id;
-
- // Use the explicitly set relay, if one exists. Otherwise,
- // Construct one using the parent parameter plus robots.txt
- // as a synthetic relay. This works since browsers using RMR
- // treat 404s as legitimate for the purposes of cross domain
- // communication.
- var relayUri = gadgets.rpc.getRelayUrl(frameId);
- if (!relayUri) {
- relayUri =
- gadgets.rpc.getOrigin(gadgets.util.getUrlParameters()["parent"]) +
- '/robots.txt';
- }
+ function setupRmr(frameId) {
+ if (typeof rmr_channels[frameId] === 'object') {
+ // Sanity check. Already done.
+ return;
+ }
- rmr_channels[frameId] = {
- frame: channelFrame,
- receiveWindow: null,
- relayUri: relayUri,
- searchCounter : 0,
- width: 10,
-
- // Waiting means "waiting for acknowledgement to be received."
- // Acknowledgement always comes as a special ACK
- // message having been received. This message is received
- // during handshake in different ways by the container and
- // gadget, and by normal RMR message passing once the handshake
- // is complete.
- waiting: true,
- queue: [],
-
- // Number of non-ACK messages that have been sent to the recipient
- // and have been acknowledged.
- sendId: 0,
-
- // Number of messages received and processed from the sender.
- // This is the number that accompanies every ACK to tell the
- // sender to clear its queue.
- recvId: 0
- };
+ var channelFrame = document.createElement('iframe');
+ var frameStyle = channelFrame.style;
+ frameStyle.position = 'absolute';
+ frameStyle.top = '0px';
+ frameStyle.border = '0';
+ frameStyle.opacity = '0';
+
+ // The width here is important as RMR
+ // makes use of the resize handler for the frame.
+ // Do not modify unless you test thoroughly!
+ frameStyle.width = '10px';
+ frameStyle.height = '1px';
+ channelFrame.id = 'rmrtransport-' + frameId;
+ channelFrame.name = channelFrame.id;
+
+ // Use the explicitly set relay, if one exists. Otherwise,
+ // Construct one using the parent parameter plus robots.txt
+ // as a synthetic relay. This works since browsers using RMR
+ // treat 404s as legitimate for the purposes of cross domain
+ // communication.
+ var relayUri = gadgets.rpc.getRelayUrl(frameId);
+ if (!relayUri) {
+ relayUri =
+ gadgets.rpc.getOrigin(gadgets.util.getUrlParameters()['parent']) +
+ '/robots.txt';
+ }
+
+ rmr_channels[frameId] = {
+ frame: channelFrame,
+ receiveWindow: null,
+ relayUri: relayUri,
+ searchCounter: 0,
+ width: 10,
+
+ // Waiting means "waiting for acknowledgement to be received."
+ // Acknowledgement always comes as a special ACK
+ // message having been received. This message is received
+ // during handshake in different ways by the container and
+ // gadget, and by normal RMR message passing once the handshake
+ // is complete.
+ waiting: true,
+ queue: [],
+
+ // Number of non-ACK messages that have been sent to the recipient
+ // and have been acknowledged.
+ sendId: 0,
+
+ // Number of messages received and processed from the sender.
+ // This is the number that accompanies every ACK to tell the
+ // sender to clear its queue.
+ recvId: 0
+ };
+
+ if (frameId !== '..') {
+ // Container always appends a relay to the gadget, before
+ // the gadget appends its own relay back to container. The
+ // gadget, in the meantime, refuses to attach the container
+ // relay until it finds this one. Thus, the container knows
+ // for certain that gadget to container communication is set
+ // up by the time it finds its own relay. In addition to
+ // establishing a reliable handshake protocol, this also
+ // makes it possible for the gadget to send an initial batch
+ // of messages to the container ASAP.
+ appendRmrFrame(channelFrame, relayUri, getRmrData(frameId));
+ }
- if (frameId !== '..') {
- // Container always appends a relay to the gadget, before
- // the gadget appends its own relay back to container. The
- // gadget, in the meantime, refuses to attach the container
- // relay until it finds this one. Thus, the container knows
- // for certain that gadget to container communication is set
- // up by the time it finds its own relay. In addition to
- // establishing a reliable handshake protocol, this also
- // makes it possible for the gadget to send an initial batch
- // of messages to the container ASAP.
- appendRmrFrame(channelFrame, relayUri, getRmrData(frameId));
+ // Start searching for our own frame on the other page.
+ conductRmrSearch(frameId);
}
-
- // Start searching for our own frame on the other page.
- conductRmrSearch(frameId);
- }
- /**
+ /**
* Searches for a relay frame, created by the sender referenced by
* frameId, with which this context receives messages. Once
* found with proper permissions, attaches a resize handler which
@@ -189,51 +189,51 @@ gadgets.rpctx.rmr = function() {
*
* @param {string} frameId Frame ID of the prospective sender.
*/
- function conductRmrSearch(frameId) {
- var channelWindow = null;
-
- // Increment the search counter.
- rmr_channels[frameId].searchCounter++;
-
- try {
- var targetWin = gadgets.rpc._getTargetWin(frameId);
- if (frameId === '..') {
- // We are a gadget.
- channelWindow = targetWin.frames['rmrtransport-' + gadgets.rpc.RPC_ID];
- } else {
- // We are a container.
- channelWindow = targetWin.frames['rmrtransport-..'];
- }
- } catch (e) {
- // Just in case; may happen when relay is set to about:blank or unset.
- // Catching exceptions here ensures that the timeout to continue the
- // search below continues to work.
- }
+ function conductRmrSearch(frameId) {
+ var channelWindow = null;
- var status = false;
+ // Increment the search counter.
+ rmr_channels[frameId].searchCounter++;
- if (channelWindow) {
- // We have a valid reference to "our" RMR transport frame.
- // Register the proper event handlers.
- status = registerRmrChannel(frameId, channelWindow);
- }
+ try {
+ var targetWin = gadgets.rpc._getTargetWin(frameId);
+ if (frameId === '..') {
+ // We are a gadget.
+ channelWindow = targetWin.frames['rmrtransport-' + gadgets.rpc.RPC_ID];
+ } else {
+ // We are a container.
+ channelWindow = targetWin.frames['rmrtransport-..'];
+ }
+ } catch (e) {
+ // Just in case; may happen when relay is set to about:blank or unset.
+ // Catching exceptions here ensures that the timeout to continue the
+ // search below continues to work.
+ }
+
+ var status = false;
+
+ if (channelWindow) {
+ // We have a valid reference to "our" RMR transport frame.
+ // Register the proper event handlers.
+ status = registerRmrChannel(frameId, channelWindow);
+ }
+
+ if (!status) {
+ // Not found yet. Continue searching, but only if the counter
+ // has not reached the threshold.
+ if (rmr_channels[frameId].searchCounter > RMR_MAX_POLLS) {
+ // If we reach this point, then RMR has failed and we
+ // fall back to IFPC.
+ return;
+ }
- if (!status) {
- // Not found yet. Continue searching, but only if the counter
- // has not reached the threshold.
- if (rmr_channels[frameId].searchCounter > RMR_MAX_POLLS) {
- // If we reach this point, then RMR has failed and we
- // fall back to IFPC.
- return;
+ window.setTimeout(function() {
+ conductRmrSearch(frameId);
+ }, RMR_SEARCH_TIMEOUT);
}
-
- window.setTimeout(function() {
- conductRmrSearch(frameId);
- }, RMR_SEARCH_TIMEOUT);
}
- }
- /**
+ /**
* Attempts to conduct an RPC call to the specified
* target with the specified data via the RMR
* method. If this method fails, the system attempts again
@@ -244,147 +244,147 @@ gadgets.rpctx.rmr = function() {
* @param {string} from Module Id of the calling provider.
* @param {Object} rpc The RPC data for this call.
*/
- function callRmr(targetId, serviceName, from, rpc) {
- var handler = null;
+ function callRmr(targetId, serviceName, from, rpc) {
+ var handler = null;
- if (from !== '..') {
- // Call from gadget to the container.
- handler = rmr_channels['..'];
- } else {
- // Call from container to the gadget.
- handler = rmr_channels[targetId];
- }
-
- if (handler) {
- // Queue the current message if not ACK.
- // ACK is always sent through getRmrData(...).
- if (serviceName !== gadgets.rpc.ACK) {
- handler.queue.push(rpc);
- }
-
- if (handler.waiting ||
- (handler.queue.length === 0 &&
- !(serviceName === gadgets.rpc.ACK && rpc && rpc.ackAlone === true))) {
- // If we are awaiting a response from any previously-sent messages,
- // or if we don't have anything new to send, just return.
- // Note that we don't short-return if we're ACKing just-received
- // messages.
- return true;
+ if (from !== '..') {
+ // Call from gadget to the container.
+ handler = rmr_channels['..'];
+ } else {
+ // Call from container to the gadget.
+ handler = rmr_channels[targetId];
}
- if (handler.queue.length > 0) {
- handler.waiting = true;
- }
+ if (handler) {
+ // Queue the current message if not ACK.
+ // ACK is always sent through getRmrData(...).
+ if (serviceName !== gadgets.rpc.ACK) {
+ handler.queue.push(rpc);
+ }
- var url = handler.relayUri + "#" + getRmrData(targetId);
+ if (handler.waiting ||
+ (handler.queue.length === 0 &&
+ !(serviceName === gadgets.rpc.ACK && rpc && rpc.ackAlone === true))) {
+ // If we are awaiting a response from any previously-sent messages,
+ // or if we don't have anything new to send, just return.
+ // Note that we don't short-return if we're ACKing just-received
+ // messages.
+ return true;
+ }
- try {
- // Update the URL with the message.
- handler.frame.contentWindow.location = url;
+ if (handler.queue.length > 0) {
+ handler.waiting = true;
+ }
- // Resize the frame.
- var newWidth = handler.width == 10 ? 20 : 10;
- handler.frame.style.width = newWidth + 'px';
- handler.width = newWidth;
+ var url = handler.relayUri + '#' + getRmrData(targetId);
- // Done!
- } catch (e) {
- // Something about location-setting or resizing failed.
- // This should never happen, but if it does, fall back to
- // the default transport.
- return false;
+ try {
+ // Update the URL with the message.
+ handler.frame.contentWindow.location = url;
+
+ // Resize the frame.
+ var newWidth = handler.width == 10 ? 20 : 10;
+ handler.frame.style.width = newWidth + 'px';
+ handler.width = newWidth;
+
+ // Done!
+ } catch (e) {
+ // Something about location-setting or resizing failed.
+ // This should never happen, but if it does, fall back to
+ // the default transport.
+ return false;
+ }
}
- }
- return true;
- }
+ return true;
+ }
- /**
+ /**
* Returns as a string the data to be appended to an RMR relay frame,
* constructed from the current request queue plus an ACK message indicating
* the currently latest-processed message ID.
*
* @param {string} toFrameId Frame whose sendable queued data to retrieve.
*/
- function getRmrData(toFrameId) {
- var channel = rmr_channels[toFrameId];
- var rmrData = {id: channel.sendId};
- if (channel) {
- rmrData.d = Array.prototype.slice.call(channel.queue, 0);
- rmrData.d.push({s:gadgets.rpc.ACK, id:channel.recvId});
+ function getRmrData(toFrameId) {
+ var channel = rmr_channels[toFrameId];
+ var rmrData = {id: channel.sendId};
+ if (channel) {
+ rmrData.d = Array.prototype.slice.call(channel.queue, 0);
+ rmrData.d.push({s: gadgets.rpc.ACK, id: channel.recvId});
+ }
+ return gadgets.json.stringify(rmrData);
}
- return gadgets.json.stringify(rmrData);
- }
- /**
+ /**
* Retrieve data from the channel keyed by the given frameId,
* processing it as a batch. All processed data is assumed to have been
* generated by getRmrData(...), pairing that method with this.
*
* @param {string} fromFrameId Frame from which data is being retrieved.
*/
- function processRmrData(fromFrameId) {
- var channel = rmr_channels[fromFrameId];
- var data = channel.receiveWindow.location.hash.substring(1);
-
- // Decode the RPC object array.
- var rpcObj = gadgets.json.parse(decodeURIComponent(data)) || {};
- var rpcArray = rpcObj.d || [];
-
- var nonAckReceived = false;
- var noLongerWaiting = false;
-
- var numBypassed = 0;
- var numToBypass = (channel.recvId - rpcObj.id);
- for (var i = 0; i < rpcArray.length; ++i) {
- var rpc = rpcArray[i];
-
- // If we receive an ACK message, then mark the current
- // handler as no longer waiting and send out the next
- // queued message.
- if (rpc.s === gadgets.rpc.ACK) {
- // ACK received - whether this came from a handshake or
- // an active call, in either case it indicates readiness to
- // send messages to the from frame.
- ready(fromFrameId, true);
+ function processRmrData(fromFrameId) {
+ var channel = rmr_channels[fromFrameId];
+ var data = channel.receiveWindow.location.hash.substring(1);
+
+ // Decode the RPC object array.
+ var rpcObj = gadgets.json.parse(decodeURIComponent(data)) || {};
+ var rpcArray = rpcObj.d || [];
+
+ var nonAckReceived = false;
+ var noLongerWaiting = false;
+
+ var numBypassed = 0;
+ var numToBypass = (channel.recvId - rpcObj.id);
+ for (var i = 0; i < rpcArray.length; ++i) {
+ var rpc = rpcArray[i];
+
+ // If we receive an ACK message, then mark the current
+ // handler as no longer waiting and send out the next
+ // queued message.
+ if (rpc.s === gadgets.rpc.ACK) {
+ // ACK received - whether this came from a handshake or
+ // an active call, in either case it indicates readiness to
+ // send messages to the from frame.
+ ready(fromFrameId, true);
+
+ if (channel.waiting) {
+ noLongerWaiting = true;
+ }
+
+ channel.waiting = false;
+ var newlyAcked = Math.max(0, rpc.id - channel.sendId);
+ channel.queue.splice(0, newlyAcked);
+ channel.sendId = Math.max(channel.sendId, rpc.id || 0);
+ continue;
+ }
- if (channel.waiting) {
- noLongerWaiting = true;
+ // If we get here, we've received > 0 non-ACK messages to
+ // process. Indicate this bit for later.
+ nonAckReceived = true;
+
+ // Bypass any messages already received.
+ if (++numBypassed <= numToBypass) {
+ continue;
}
- channel.waiting = false;
- var newlyAcked = Math.max(0, rpc.id - channel.sendId);
- channel.queue.splice(0, newlyAcked);
- channel.sendId = Math.max(channel.sendId, rpc.id || 0);
- continue;
+ ++channel.recvId;
+ process(rpc); // actually dispatch the message
}
- // If we get here, we've received > 0 non-ACK messages to
- // process. Indicate this bit for later.
- nonAckReceived = true;
-
- // Bypass any messages already received.
- if (++numBypassed <= numToBypass) {
- continue;
+ // Send an ACK indicating that we got/processed the message(s).
+ // Do so if we've received a message to process or if we were waiting
+ // before but a received ACK has cleared our waiting bit, and we have
+ // more messages to send. Performing this operation causes additional
+ // messages to be sent.
+ if (nonAckReceived ||
+ (noLongerWaiting && channel.queue.length > 0)) {
+ var from = (fromFrameId === '..') ? gadgets.rpc.RPC_ID : '..';
+ callRmr(fromFrameId, gadgets.rpc.ACK, from, {ackAlone: nonAckReceived});
}
-
- ++channel.recvId;
- process(rpc); // actually dispatch the message
- }
-
- // Send an ACK indicating that we got/processed the message(s).
- // Do so if we've received a message to process or if we were waiting
- // before but a received ACK has cleared our waiting bit, and we have
- // more messages to send. Performing this operation causes additional
- // messages to be sent.
- if (nonAckReceived ||
- (noLongerWaiting && channel.queue.length > 0)) {
- var from = (fromFrameId === '..') ? gadgets.rpc.RPC_ID : '..';
- callRmr(fromFrameId, gadgets.rpc.ACK, from, {ackAlone: nonAckReceived});
}
- }
- /**
+ /**
* Registers the RMR channel handler for the given frameId and associated
* channel window.
*
@@ -396,121 +396,121 @@ gadgets.rpctx.rmr = function() {
* @return {boolean} True if the frame was setup successfully, false
* otherwise.
*/
- function registerRmrChannel(frameId, channelWindow) {
- var channel = rmr_channels[frameId];
+ function registerRmrChannel(frameId, channelWindow) {
+ var channel = rmr_channels[frameId];
- // Verify that the channel is ready for receiving.
- try {
- var canAccess = false;
-
- // Check to see if the document is in the window. For Chrome, this
- // will return 'false' if the channelWindow is inaccessible by this
- // piece of JavaScript code, meaning that the URL of the channelWindow's
- // parent iframe has not yet changed from 'about:blank'. We do this
- // check this way because any true *access* on the channelWindow object
- // will raise a security exception, which, despite the try-catch, still
- // gets reported to the debugger (it does not break execution, the try
- // handles that problem, but it is still reported, which is bad form).
- // This check always succeeds in Safari 3.1 regardless of the state of
- // the window.
- canAccess = 'document' in channelWindow;
+ // Verify that the channel is ready for receiving.
+ try {
+ var canAccess = false;
- if (!canAccess) {
- return false;
- }
+ // Check to see if the document is in the window. For Chrome, this
+ // will return 'false' if the channelWindow is inaccessible by this
+ // piece of JavaScript code, meaning that the URL of the channelWindow's
+ // parent iframe has not yet changed from 'about:blank'. We do this
+ // check this way because any true *access* on the channelWindow object
+ // will raise a security exception, which, despite the try-catch, still
+ // gets reported to the debugger (it does not break execution, the try
+ // handles that problem, but it is still reported, which is bad form).
+ // This check always succeeds in Safari 3.1 regardless of the state of
+ // the window.
+ canAccess = 'document' in channelWindow;
- // Check to see if the document is an object. For Safari 3.1, this will
- // return undefined if the page is still inaccessible. Unfortunately, this
- // *will* raise a security issue in the debugger.
- // TODO Find a way around this problem.
- canAccess = typeof channelWindow['document'] == 'object';
+ if (!canAccess) {
+ return false;
+ }
- if (!canAccess) {
- return false;
- }
+ // Check to see if the document is an object. For Safari 3.1, this will
+ // return undefined if the page is still inaccessible. Unfortunately, this
+ // *will* raise a security issue in the debugger.
+ // TODO Find a way around this problem.
+ canAccess = typeof channelWindow['document'] == 'object';
- // Once we get here, we know we can access the document (and anything else)
- // on the window object. Therefore, we check to see if the location is
- // still about:blank (this takes care of the Safari 3.2 case).
- var loc = channelWindow.location.href;
+ if (!canAccess) {
+ return false;
+ }
- // Check if this is about:blank for Safari.
- if (loc === 'about:blank') {
+ // Once we get here, we know we can access the document (and anything else)
+ // on the window object. Therefore, we check to see if the location is
+ // still about:blank (this takes care of the Safari 3.2 case).
+ var loc = channelWindow.location.href;
+
+ // Check if this is about:blank for Safari.
+ if (loc === 'about:blank') {
+ return false;
+ }
+ } catch (ex) {
+ // For some reason, the iframe still points to about:blank. We try
+ // again in a bit.
return false;
}
- } catch (ex) {
- // For some reason, the iframe still points to about:blank. We try
- // again in a bit.
- return false;
- }
- // Save a reference to the receive window.
- channel.receiveWindow = channelWindow;
+ // Save a reference to the receive window.
+ channel.receiveWindow = channelWindow;
- // Register the onresize handler.
- function onresize() {
- processRmrData(frameId);
- };
+ // Register the onresize handler.
+ function onresize() {
+ processRmrData(frameId);
+ };
- if (typeof channelWindow.attachEvent === "undefined") {
- channelWindow.onresize = onresize;
- } else {
- channelWindow.attachEvent("onresize", onresize);
- }
+ if (typeof channelWindow.attachEvent === 'undefined') {
+ channelWindow.onresize = onresize;
+ } else {
+ channelWindow.attachEvent('onresize', onresize);
+ }
- if (frameId === '..') {
- // Gadget to container. Signal to the container that the gadget
- // is ready to receive messages by attaching the g -> c relay.
- // As a nice optimization, pass along any gadget to container
- // queued messages that have backed up since then. ACK is enqueued in
- // getRmrData to ensure that the container's waiting flag is set to false
- // (this happens in the below code run on the container side).
- appendRmrFrame(channel.frame, channel.relayUri, getRmrData(frameId), frameId);
- } else {
- // Process messages that the gadget sent in its initial relay payload.
- // We can do this immediately because the container has already appended
- // and loaded a relay frame that can be used to ACK the messages the gadget
- // sent. In the preceding if-block, however, the processRmrData(...) call
- // must wait. That's because appendRmrFrame may not actually append the
- // frame - in the context of a gadget, this code may be running in the
- // head element, so it cannot be appended to body. As a result, the
- // gadget cannot ACK the container for messages it received.
- processRmrData(frameId);
+ if (frameId === '..') {
+ // Gadget to container. Signal to the container that the gadget
+ // is ready to receive messages by attaching the g -> c relay.
+ // As a nice optimization, pass along any gadget to container
+ // queued messages that have backed up since then. ACK is enqueued in
+ // getRmrData to ensure that the container's waiting flag is set to false
+ // (this happens in the below code run on the container side).
+ appendRmrFrame(channel.frame, channel.relayUri, getRmrData(frameId), frameId);
+ } else {
+ // Process messages that the gadget sent in its initial relay payload.
+ // We can do this immediately because the container has already appended
+ // and loaded a relay frame that can be used to ACK the messages the gadget
+ // sent. In the preceding if-block, however, the processRmrData(...) call
+ // must wait. That's because appendRmrFrame may not actually append the
+ // frame - in the context of a gadget, this code may be running in the
+ // head element, so it cannot be appended to body. As a result, the
+ // gadget cannot ACK the container for messages it received.
+ processRmrData(frameId);
+ }
+
+ return true;
}
- return true;
- }
+ return {
+ getCode: function() {
+ return 'rmr';
+ },
- return {
- getCode: function() {
- return 'rmr';
- },
+ isParentVerifiable: function() {
+ return true;
+ },
- isParentVerifiable: function() {
- return true;
- },
+ init: function(processFn, readyFn) {
+ // No global setup.
+ process = processFn;
+ ready = readyFn;
+ return true;
+ },
- init: function(processFn, readyFn) {
- // No global setup.
- process = processFn;
- ready = readyFn;
- return true;
- },
+ setup: function(receiverId, token) {
+ try {
+ setupRmr(receiverId);
+ } catch (e) {
+ gadgets.warn('Caught exception setting up RMR: ' + e);
+ return false;
+ }
+ return true;
+ },
- setup: function(receiverId, token) {
- try {
- setupRmr(receiverId);
- } catch (e) {
- gadgets.warn('Caught exception setting up RMR: ' + e);
- return false;
+ call: function(targetId, from, rpc) {
+ return callRmr(targetId, rpc.s, from, rpc);
}
- return true;
- },
-
- call: function(targetId, from, rpc) {
- return callRmr(targetId, rpc.s, from, rpc);
- }
- };
-}();
+ };
+ }();
} // !end of double-inclusion guard