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/09/15 03:40:15 UTC
svn commit: r997163 [36/37] - in
/shindig/trunk/features/src/main/javascript/features: caja/
com.google.gadgets.analytics/ container/ core.config/ core.io/ core.json/
core.legacy/ core.log/ core.prefs/ core.util/ dynamic-height.util/
dynamic-height/ fl...
Modified: shindig/trunk/features/src/main/javascript/features/rpc/rpc.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/rpc/rpc.js?rev=997163&r1=997162&r2=997163&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/rpc/rpc.js (original)
+++ shindig/trunk/features/src/main/javascript/features/rpc/rpc.js Wed Sep 15 01:39:49 2010
@@ -26,7 +26,7 @@
*
* All transports are stored in object gadgets.rpctx, and are provided
* to the core gadgets.rpc library by various build rules.
- *
+ *
* Transports used by core gadgets.rpc code to actually pass messages.
* each transport implements the same interface exposing hooks that
* the core library calls at strategic points to set up and use
@@ -54,101 +54,101 @@
if (!gadgets.rpc) { // make lib resilient to double-inclusion
-/**
+ /**
* @static
* @namespace Provides operations for making rpc calls.
* @name gadgets.rpc
*/
-gadgets.rpc = function() {
- /**
+ gadgets.rpc = function() {
+ /**
* @const
* @private
*/
- var CALLBACK_NAME = '__cb';
+ var CALLBACK_NAME = '__cb';
- /**
+ /**
* @const
* @private
*/
- var DEFAULT_NAME = '';
+ var DEFAULT_NAME = '';
- /** Exported constant, for use by transports only.
+ /** Exported constant, for use by transports only.
* @const
* @type {string}
* @member gadgets.rpc
*/
- var ACK = '__ack';
+ var ACK = '__ack';
- /**
+ /**
* Timeout and number of attempts made to setup a transport receiver.
* @const
* @private
*/
- var SETUP_FRAME_TIMEOUT = 500;
+ var SETUP_FRAME_TIMEOUT = 500;
- /**
+ /**
* @const
* @private
*/
- var SETUP_FRAME_MAX_TRIES = 10;
+ var SETUP_FRAME_MAX_TRIES = 10;
- var services = {};
- var relayUrl = {};
- var useLegacyProtocol = {};
- var authToken = {};
- var callId = 0;
- var callbacks = {};
- var setup = {};
- var sameDomain = {};
- var params = {};
- var receiverTx = {};
- var earlyRpcQueue = {};
-
- // isGadget =~ isChild for the purposes of rpc (used only in setup).
- var isChild = (window.top !== window.self);
-
- // Set the current rpc ID from window.name immediately, to prevent
- // shadowing of window.name by a "var name" declaration, or similar.
- var rpcId = window.name;
-
- var securityCallback = function() {};
- var LOAD_TIMEOUT = 0;
- var FRAME_PHISH = 1;
- var FORGED_MSG = 2;
-
- // Fallback transport is simply a dummy impl that emits no errors
- // and logs info on calls it receives, to avoid undesired side-effects
- // from falling back to IFPC or some other transport.
- var fallbackTransport = (function() {
- function logFn(name) {
- return function() {
- gadgets.log("gadgets.rpc." + name + "(" +
- gadgets.json.stringify(Array.prototype.slice.call(arguments)) +
- "): call ignored. [caller: " + document.location +
- ", isChild: " + isChild + "]");
+ var services = {};
+ var relayUrl = {};
+ var useLegacyProtocol = {};
+ var authToken = {};
+ var callId = 0;
+ var callbacks = {};
+ var setup = {};
+ var sameDomain = {};
+ var params = {};
+ var receiverTx = {};
+ var earlyRpcQueue = {};
+
+ // isGadget =~ isChild for the purposes of rpc (used only in setup).
+ var isChild = (window.top !== window.self);
+
+ // Set the current rpc ID from window.name immediately, to prevent
+ // shadowing of window.name by a "var name" declaration, or similar.
+ var rpcId = window.name;
+
+ var securityCallback = function() {};
+ var LOAD_TIMEOUT = 0;
+ var FRAME_PHISH = 1;
+ var FORGED_MSG = 2;
+
+ // Fallback transport is simply a dummy impl that emits no errors
+ // and logs info on calls it receives, to avoid undesired side-effects
+ // from falling back to IFPC or some other transport.
+ var fallbackTransport = (function() {
+ function logFn(name) {
+ return function() {
+ gadgets.log('gadgets.rpc.' + name + '(' +
+ gadgets.json.stringify(Array.prototype.slice.call(arguments)) +
+ '): call ignored. [caller: ' + document.location +
+ ', isChild: ' + isChild + ']');
+ };
+ }
+ return {
+ getCode: function() {
+ return 'noop';
+ },
+ isParentVerifiable: function() {
+ return true; // Not really, but prevents transport assignment to IFPC.
+ },
+ init: logFn('init'),
+ setup: logFn('setup'),
+ call: logFn('call')
};
- }
- return {
- getCode: function() {
- return "noop";
- },
- isParentVerifiable: function() {
- return true; // Not really, but prevents transport assignment to IFPC.
- },
- init: logFn("init"),
- setup: logFn("setup"),
- call: logFn("call")
- };
- })();
+ })();
- // Load the authentication token for speaking to the container
- // from the gadget's parameters, or default to '0' if not found.
- if (gadgets.util) {
- params = gadgets.util.getUrlParameters();
- }
+ // Load the authentication token for speaking to the container
+ // from the gadget's parameters, or default to '0' if not found.
+ if (gadgets.util) {
+ params = gadgets.util.getUrlParameters();
+ }
- /**
+ /**
* Return a transport representing the best available cross-domain
* message-passing mechanism available to the browser.
*
@@ -166,149 +166,149 @@ gadgets.rpc = function() {
* @return {Object}
* @member gadgets.rpc
*/
- function getTransport() {
- return typeof window.postMessage === 'function' ? gadgets.rpctx.wpm :
- typeof window.postMessage === 'object' ? gadgets.rpctx.wpm :
- window.ActiveXObject ? gadgets.rpctx.nix :
- navigator.userAgent.indexOf('WebKit') > 0 ? gadgets.rpctx.rmr :
- navigator.product === 'Gecko' ? gadgets.rpctx.frameElement :
- gadgets.rpctx.ifpc;
- }
+ function getTransport() {
+ return typeof window.postMessage === 'function' ? gadgets.rpctx.wpm :
+ typeof window.postMessage === 'object' ? gadgets.rpctx.wpm :
+ window.ActiveXObject ? gadgets.rpctx.nix :
+ navigator.userAgent.indexOf('WebKit') > 0 ? gadgets.rpctx.rmr :
+ navigator.product === 'Gecko' ? gadgets.rpctx.frameElement :
+ gadgets.rpctx.ifpc;
+ }
- /**
+ /**
* Function passed to, and called by, a transport indicating it's ready to
* send and receive messages.
*/
- function transportReady(receiverId, readySuccess) {
- var tx = transport;
- if (!readySuccess) {
- tx = fallbackTransport;
- }
- receiverTx[receiverId] = tx;
-
- // If there are any early-queued messages, send them now directly through
- // the needed transport.
- var earlyQueue = earlyRpcQueue[receiverId] || [];
- for (var i = 0; i < earlyQueue.length; ++i) {
- var rpc = earlyQueue[i];
- // There was no auth/rpc token set before, so set it now.
- rpc.t = getAuthToken(receiverId);
- tx.call(receiverId, rpc.f, rpc);
- }
-
- // Clear the queue so it won't be sent again.
- earlyRpcQueue[receiverId] = [];
- }
-
- // Track when this main page is closed or navigated to a different location
- // ("unload" event).
- // NOTE: The use of the "unload" handler here and for the relay iframe
- // prevents the use of the in-memory page cache in modern browsers.
- // See: https://developer.mozilla.org/en/using_firefox_1.5_caching
- // See: http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
- var mainPageUnloading = false,
- hookedUnload = false;
-
- function hookMainPageUnload() {
- if ( hookedUnload ) {
- return;
- }
- function onunload() {
- mainPageUnloading = true;
- }
- gadgets.util.attachBrowserEvent(window, 'unload', onunload, false);
- hookedUnload = true;
- }
-
- function relayOnload(targetId, sourceId, token, data, relayWindow) {
- // Validate auth token.
- if (!authToken[sourceId] || authToken[sourceId] !== token) {
- gadgets.error("Invalid auth token. " + authToken[sourceId] + " vs " + token);
- securityCallback(sourceId, FORGED_MSG);
- }
-
- relayWindow.onunload = function() {
- if (setup[sourceId] && !mainPageUnloading) {
- securityCallback(sourceId, FRAME_PHISH);
- gadgets.rpc.removeReceiver(sourceId);
+ function transportReady(receiverId, readySuccess) {
+ var tx = transport;
+ if (!readySuccess) {
+ tx = fallbackTransport;
+ }
+ receiverTx[receiverId] = tx;
+
+ // If there are any early-queued messages, send them now directly through
+ // the needed transport.
+ var earlyQueue = earlyRpcQueue[receiverId] || [];
+ for (var i = 0; i < earlyQueue.length; ++i) {
+ var rpc = earlyQueue[i];
+ // There was no auth/rpc token set before, so set it now.
+ rpc.t = getAuthToken(receiverId);
+ tx.call(receiverId, rpc.f, rpc);
+ }
+
+ // Clear the queue so it won't be sent again.
+ earlyRpcQueue[receiverId] = [];
+ }
+
+ // Track when this main page is closed or navigated to a different location
+ // ("unload" event).
+ // NOTE: The use of the "unload" handler here and for the relay iframe
+ // prevents the use of the in-memory page cache in modern browsers.
+ // See: https://developer.mozilla.org/en/using_firefox_1.5_caching
+ // See: http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
+ var mainPageUnloading = false,
+ hookedUnload = false;
+
+ function hookMainPageUnload() {
+ if (hookedUnload) {
+ return;
}
- };
- hookMainPageUnload();
-
- data = gadgets.json.parse(decodeURIComponent(data));
- transport.relayOnload(sourceId, data);
- }
+ function onunload() {
+ mainPageUnloading = true;
+ }
+ gadgets.util.attachBrowserEvent(window, 'unload', onunload, false);
+ hookedUnload = true;
+ }
- /**
+ function relayOnload(targetId, sourceId, token, data, relayWindow) {
+ // Validate auth token.
+ if (!authToken[sourceId] || authToken[sourceId] !== token) {
+ gadgets.error('Invalid auth token. ' + authToken[sourceId] + ' vs ' + token);
+ securityCallback(sourceId, FORGED_MSG);
+ }
+
+ relayWindow.onunload = function() {
+ if (setup[sourceId] && !mainPageUnloading) {
+ securityCallback(sourceId, FRAME_PHISH);
+ gadgets.rpc.removeReceiver(sourceId);
+ }
+ };
+ hookMainPageUnload();
+
+ data = gadgets.json.parse(decodeURIComponent(data));
+ transport.relayOnload(sourceId, data);
+ }
+
+ /**
* Helper function to process an RPC request
- * @param {Object} rpc RPC request object
+ * @param {Object} rpc RPC request object.
* @private
*/
- function process(rpc) {
- //
- // RPC object contents:
- // s: Service Name
- // f: From
- // c: The callback ID or 0 if none.
- // a: The arguments for this RPC call.
- // t: The authentication token.
- //
- if (rpc && typeof rpc.s === 'string' && typeof rpc.f === 'string' &&
- rpc.a instanceof Array) {
+ function process(rpc) {
+ //
+ // RPC object contents:
+ // s: Service Name
+ // f: From
+ // c: The callback ID or 0 if none.
+ // a: The arguments for this RPC call.
+ // t: The authentication token.
+ //
+ if (rpc && typeof rpc.s === 'string' && typeof rpc.f === 'string' &&
+ rpc.a instanceof Array) {
- // Validate auth token.
- if (authToken[rpc.f]) {
- // We don't do type coercion here because all entries in the authToken
- // object are strings, as are all url params. See setupReceiver(...).
- if (authToken[rpc.f] !== rpc.t) {
- gadgets.error("Invalid auth token. " + authToken[rpc.f] + " vs " + rpc.t);
- securityCallback(rpc.f, FORGED_MSG);
+ // Validate auth token.
+ if (authToken[rpc.f]) {
+ // We don't do type coercion here because all entries in the authToken
+ // object are strings, as are all url params. See setupReceiver(...).
+ if (authToken[rpc.f] !== rpc.t) {
+ gadgets.error('Invalid auth token. ' + authToken[rpc.f] + ' vs ' + rpc.t);
+ securityCallback(rpc.f, FORGED_MSG);
+ }
}
- }
- if (rpc.s === ACK) {
- // Acknowledgement API, used to indicate a receiver is ready.
- window.setTimeout(function() { transportReady(rpc.f, true); }, 0);
- return;
- }
+ if (rpc.s === ACK) {
+ // Acknowledgement API, used to indicate a receiver is ready.
+ window.setTimeout(function() { transportReady(rpc.f, true); }, 0);
+ return;
+ }
- // If there is a callback for this service, attach a callback function
- // to the rpc context object for asynchronous rpc services.
- //
- // Synchronous rpc request handlers should simply ignore it and return a
- // value as usual.
- // Asynchronous rpc request handlers, on the other hand, should pass its
- // result to this callback function and not return a value on exit.
- //
- // For example, the following rpc handler passes the first parameter back
- // to its rpc client with a one-second delay.
- //
- // function asyncRpcHandler(param) {
- // var me = this;
- // setTimeout(function() {
- // me.callback(param);
- // }, 1000);
- // }
- if (rpc.c) {
- rpc.callback = function(result) {
- gadgets.rpc.call(rpc.f, CALLBACK_NAME, null, rpc.c, result);
- };
- }
+ // If there is a callback for this service, attach a callback function
+ // to the rpc context object for asynchronous rpc services.
+ //
+ // Synchronous rpc request handlers should simply ignore it and return a
+ // value as usual.
+ // Asynchronous rpc request handlers, on the other hand, should pass its
+ // result to this callback function and not return a value on exit.
+ //
+ // For example, the following rpc handler passes the first parameter back
+ // to its rpc client with a one-second delay.
+ //
+ // function asyncRpcHandler(param) {
+ // var me = this;
+ // setTimeout(function() {
+ // me.callback(param);
+ // }, 1000);
+ // }
+ if (rpc.c) {
+ rpc.callback = function(result) {
+ gadgets.rpc.call(rpc.f, CALLBACK_NAME, null, rpc.c, result);
+ };
+ }
- // Call the requested RPC service.
- var result = (services[rpc.s] ||
- services[DEFAULT_NAME]).apply(rpc, rpc.a);
-
- // If the rpc request handler returns a value, immediately pass it back
- // to the callback. Otherwise, do nothing, assuming that the rpc handler
- // will make an asynchronous call later.
- if (rpc.c && typeof result !== 'undefined') {
- gadgets.rpc.call(rpc.f, CALLBACK_NAME, null, rpc.c, result);
+ // Call the requested RPC service.
+ var result = (services[rpc.s] ||
+ services[DEFAULT_NAME]).apply(rpc, rpc.a);
+
+ // If the rpc request handler returns a value, immediately pass it back
+ // to the callback. Otherwise, do nothing, assuming that the rpc handler
+ // will make an asynchronous call later.
+ if (rpc.c && typeof result !== 'undefined') {
+ gadgets.rpc.call(rpc.f, CALLBACK_NAME, null, rpc.c, result);
+ }
}
}
- }
- /**
+ /**
* Helper method returning a canonicalized protocol://host[:port] for
* a given input URL, provided as a string. Used to compute convenient
* relay URLs and to determine whether a call is coming from the same
@@ -319,164 +319,164 @@ gadgets.rpc = function() {
* @memberOf gadgets.rpc
*/
- function getOrigin(url) {
- if (!url) {
- return "";
- }
- url = url.toLowerCase();
- if (url.indexOf("//") == 0) {
- url = window.location.protocol + url;
- }
- if (url.indexOf("://") == -1) {
- // Assumed to be schemaless. Default to current protocol.
- url = window.location.protocol + "//" + url;
- }
- // At this point we guarantee that "://" is in the URL and defines
- // current protocol. Skip past this to search for host:port.
- var host = url.substring(url.indexOf("://") + 3);
-
- // Find the first slash char, delimiting the host:port.
- var slashPos = host.indexOf("/");
- if (slashPos != -1) {
- host = host.substring(0, slashPos);
- }
-
- var protocol = url.substring(0, url.indexOf("://"));
-
- // Use port only if it's not default for the protocol.
- var portStr = "";
- var portPos = host.indexOf(":");
- if (portPos != -1) {
- var port = host.substring(portPos + 1);
- host = host.substring(0, portPos);
- if ((protocol === "http" && port !== "80") ||
- (protocol === "https" && port !== "443")) {
- portStr = ":" + port;
- }
- }
-
- // Return <protocol>://<host>[<port>]
- return protocol + "://" + host + portStr;
- }
-
- function getTargetWin(id) {
- if (typeof id === "undefined" ||
- id === "..") {
- return window.parent;
- }
-
- // Cast to a String to avoid an index lookup.
- id = String(id);
-
- // Try window.frames first
- var target = window.frames[id];
- if (target) {
- return target;
- }
-
- // Fall back to getElementById()
- target = document.getElementById(id);
- if (target && target.contentWindow) {
- return target.contentWindow;
- }
-
- return null;
- }
-
- // Pick the most efficient RPC relay mechanism.
- var transport = getTransport();
-
- // Create the Default RPC handler.
- services[DEFAULT_NAME] = function() {
- gadgets.warn('Unknown RPC service: ' + this.s);
- };
-
- // Create a Special RPC handler for callbacks.
- services[CALLBACK_NAME] = function(callbackId, result) {
- var callback = callbacks[callbackId];
- if (callback) {
- delete callbacks[callbackId];
- callback(result);
+ function getOrigin(url) {
+ if (!url) {
+ return '';
+ }
+ url = url.toLowerCase();
+ if (url.indexOf('//') == 0) {
+ url = window.location.protocol + url;
+ }
+ if (url.indexOf('://') == -1) {
+ // Assumed to be schemaless. Default to current protocol.
+ url = window.location.protocol + '//' + url;
+ }
+ // At this point we guarantee that "://" is in the URL and defines
+ // current protocol. Skip past this to search for host:port.
+ var host = url.substring(url.indexOf('://') + 3);
+
+ // Find the first slash char, delimiting the host:port.
+ var slashPos = host.indexOf('/');
+ if (slashPos != -1) {
+ host = host.substring(0, slashPos);
+ }
+
+ var protocol = url.substring(0, url.indexOf('://'));
+
+ // Use port only if it's not default for the protocol.
+ var portStr = '';
+ var portPos = host.indexOf(':');
+ if (portPos != -1) {
+ var port = host.substring(portPos + 1);
+ host = host.substring(0, portPos);
+ if ((protocol === 'http' && port !== '80') ||
+ (protocol === 'https' && port !== '443')) {
+ portStr = ':' + port;
+ }
+ }
+
+ // Return <protocol>://<host>[<port>]
+ return protocol + '://' + host + portStr;
}
- };
- /**
+ function getTargetWin(id) {
+ if (typeof id === 'undefined' ||
+ id === '..') {
+ return window.parent;
+ }
+
+ // Cast to a String to avoid an index lookup.
+ id = String(id);
+
+ // Try window.frames first
+ var target = window.frames[id];
+ if (target) {
+ return target;
+ }
+
+ // Fall back to getElementById()
+ target = document.getElementById(id);
+ if (target && target.contentWindow) {
+ return target.contentWindow;
+ }
+
+ return null;
+ }
+
+ // Pick the most efficient RPC relay mechanism.
+ var transport = getTransport();
+
+ // Create the Default RPC handler.
+ services[DEFAULT_NAME] = function() {
+ gadgets.warn('Unknown RPC service: ' + this.s);
+ };
+
+ // Create a Special RPC handler for callbacks.
+ services[CALLBACK_NAME] = function(callbackId, result) {
+ var callback = callbacks[callbackId];
+ if (callback) {
+ delete callbacks[callbackId];
+ callback(result);
+ }
+ };
+
+ /**
* Conducts any frame-specific work necessary to setup
* the channel type chosen. This method is called when
* the container page first registers the gadget in the
* RPC mechanism. Gadgets, in turn, will complete the setup
* of the channel once they send their first messages.
*/
- function setupFrame(frameId, token, forcesecure) {
- if (setup[frameId] === true) {
- return;
- }
+ function setupFrame(frameId, token, forcesecure) {
+ if (setup[frameId] === true) {
+ return;
+ }
- if (typeof setup[frameId] === 'undefined') {
- setup[frameId] = 0;
- }
+ if (typeof setup[frameId] === 'undefined') {
+ setup[frameId] = 0;
+ }
- var tgtFrame = document.getElementById(frameId);
- if (frameId === '..' || tgtFrame != null) {
- if (transport.setup(frameId, token, forcesecure) === true) {
- setup[frameId] = true;
- return;
+ var tgtFrame = document.getElementById(frameId);
+ if (frameId === '..' || tgtFrame != null) {
+ if (transport.setup(frameId, token, forcesecure) === true) {
+ setup[frameId] = true;
+ return;
+ }
}
- }
- if (setup[frameId] !== true && setup[frameId]++ < SETUP_FRAME_MAX_TRIES) {
- // Try again in a bit, assuming that frame will soon exist.
- window.setTimeout(function() { setupFrame(frameId, token, forcesecure) },
+ if (setup[frameId] !== true && setup[frameId]++ < SETUP_FRAME_MAX_TRIES) {
+ // Try again in a bit, assuming that frame will soon exist.
+ window.setTimeout(function() { setupFrame(frameId, token, forcesecure) },
SETUP_FRAME_TIMEOUT);
- } else {
- // Fail: fall back for this gadget.
- receiverTx[frameId] = fallbackTransport;
- setup[frameId] = true;
+ } else {
+ // Fail: fall back for this gadget.
+ receiverTx[frameId] = fallbackTransport;
+ setup[frameId] = true;
+ }
}
- }
- /**
+ /**
* Attempts to make an rpc by calling the target's receive method directly.
* This works when gadgets are rendered on the same domain as their container,
* a potentially useful optimization for trusted content which keeps
* RPC behind a consistent interface.
*
- * @param {string} target Module id of the rpc service provider
- * @param {Object} rpc RPC data
+ * @param {string} target Module id of the rpc service provider.
+ * @param {Object} rpc RPC data.
* @return {boolean}
*/
- function callSameDomain(target, rpc) {
- if (typeof sameDomain[target] === 'undefined') {
- // Seed with a negative, typed value to avoid
- // hitting this code path repeatedly.
- sameDomain[target] = false;
- var targetRelay = gadgets.rpc.getRelayUrl(target);
- if (getOrigin(targetRelay) !== getOrigin(window.location.href)) {
- // Not worth trying -- avoid the error and just return.
- return false;
- }
-
- var targetEl = getTargetWin(target);
- try {
- // If this succeeds, then same-domain policy applied
- sameDomain[target] = targetEl.gadgets.rpc.receiveSameDomain;
- } catch (e) {
- // Shouldn't happen due to origin check. Caught to emit
- // more meaningful error to the caller.
- gadgets.error("Same domain call failed: parent= incorrectly set.");
+ function callSameDomain(target, rpc) {
+ if (typeof sameDomain[target] === 'undefined') {
+ // Seed with a negative, typed value to avoid
+ // hitting this code path repeatedly.
+ sameDomain[target] = false;
+ var targetRelay = gadgets.rpc.getRelayUrl(target);
+ if (getOrigin(targetRelay) !== getOrigin(window.location.href)) {
+ // Not worth trying -- avoid the error and just return.
+ return false;
+ }
+
+ var targetEl = getTargetWin(target);
+ try {
+ // If this succeeds, then same-domain policy applied
+ sameDomain[target] = targetEl.gadgets.rpc.receiveSameDomain;
+ } catch (e) {
+ // Shouldn't happen due to origin check. Caught to emit
+ // more meaningful error to the caller.
+ gadgets.error('Same domain call failed: parent= incorrectly set.');
+ }
}
- }
- if (typeof sameDomain[target] === 'function') {
- // Call target's receive method
- sameDomain[target](rpc);
- return true;
- }
+ if (typeof sameDomain[target] === 'function') {
+ // Call target's receive method
+ sameDomain[target](rpc);
+ return true;
+ }
- return false;
- }
+ return false;
+ }
- /**
+ /**
* Sets the relay URL of a target frame.
* @param {string} targetId Name of the target frame.
* @param {string} url Full relay URL of the target frame.
@@ -486,33 +486,33 @@ gadgets.rpc = function() {
* @member gadgets.rpc
* @deprecated
*/
- function setRelayUrl(targetId, url, opt_useLegacy) {
- // make URL absolute if necessary
- if (!/http(s)?:\/\/.+/.test(url)) {
- if (url.indexOf("//") == 0) {
- url = window.location.protocol + url;
- } else if (url.charAt(0) == '/') {
- url = window.location.protocol + "//" + window.location.host + url;
- } else if (url.indexOf("://") == -1) {
- // Assumed to be schemaless. Default to current protocol.
- url = window.location.protocol + "//" + url;
+ function setRelayUrl(targetId, url, opt_useLegacy) {
+ // make URL absolute if necessary
+ if (!/http(s)?:\/\/.+/.test(url)) {
+ if (url.indexOf('//') == 0) {
+ url = window.location.protocol + url;
+ } else if (url.charAt(0) == '/') {
+ url = window.location.protocol + '//' + window.location.host + url;
+ } else if (url.indexOf('://') == -1) {
+ // Assumed to be schemaless. Default to current protocol.
+ url = window.location.protocol + '//' + url;
+ }
}
+ relayUrl[targetId] = url;
+ useLegacyProtocol[targetId] = !!opt_useLegacy;
}
- relayUrl[targetId] = url;
- useLegacyProtocol[targetId] = !!opt_useLegacy;
- }
- /**
+ /**
* Helper method to retrieve the authToken for a given gadget.
* Not to be used directly.
* @member gadgets.rpc
* @return {string}
*/
- function getAuthToken(targetId) {
- return authToken[targetId];
- }
+ function getAuthToken(targetId) {
+ return authToken[targetId];
+ }
- /**
+ /**
* Sets the auth token of a target frame.
* @param {string} targetId Name of the target frame.
* @param {string} token The authentication token to use for all
@@ -521,103 +521,103 @@ gadgets.rpc = function() {
* @member gadgets.rpc
* @deprecated
*/
- function setAuthToken(targetId, token, forcesecure) {
- token = token || "";
+ function setAuthToken(targetId, token, forcesecure) {
+ token = token || '';
- // Coerce token to a String, ensuring that all authToken values
- // are strings. This ensures correct comparison with URL params
- // in the process(rpc) method.
- authToken[targetId] = String(token);
+ // Coerce token to a String, ensuring that all authToken values
+ // are strings. This ensures correct comparison with URL params
+ // in the process(rpc) method.
+ authToken[targetId] = String(token);
- setupFrame(targetId, token, forcesecure);
- }
+ setupFrame(targetId, token, forcesecure);
+ }
- function setupContainerGadgetContext(rpctoken, opt_forcesecure) {
- /**
+ function setupContainerGadgetContext(rpctoken, opt_forcesecure) {
+ /**
* Initializes gadget to container RPC params from the provided configuration.
*/
- function init(config) {
- var configRpc = config ? config.rpc : {};
- var parentRelayUrl = configRpc.parentRelayUrl;
-
- // Allow for wild card parent relay files as long as it's from a
- // white listed domain. This is enforced by the rendering servlet.
- if (parentRelayUrl.substring(0, 7) !== 'http://' &&
- parentRelayUrl.substring(0, 8) !== 'https://' &&
- parentRelayUrl.substring(0, 2) !== '//') {
- // Relative path: we append to the parent.
- // We're relying on the server validating the parent parameter in this
- // case. Because of this, parent may only be passed in the query, not fragment.
- if (typeof params.parent === "string" && params.parent !== "") {
- // Otherwise, relayUrl['..'] will be null, signaling transport
- // code to ignore rpc calls since they cannot work without a
- // relay URL with host qualification.
- if (parentRelayUrl.substring(0, 1) !== '/') {
- // Path-relative. Trust that parent is passed in appropriately.
- var lastSlash = params.parent.lastIndexOf('/');
- parentRelayUrl = params.parent.substring(0, lastSlash + 1) + parentRelayUrl;
- } else {
- // Host-relative.
- parentRelayUrl = getOrigin(params.parent) + parentRelayUrl;
+ function init(config) {
+ var configRpc = config ? config.rpc : {};
+ var parentRelayUrl = configRpc.parentRelayUrl;
+
+ // Allow for wild card parent relay files as long as it's from a
+ // white listed domain. This is enforced by the rendering servlet.
+ if (parentRelayUrl.substring(0, 7) !== 'http://' &&
+ parentRelayUrl.substring(0, 8) !== 'https://' &&
+ parentRelayUrl.substring(0, 2) !== '//') {
+ // Relative path: we append to the parent.
+ // We're relying on the server validating the parent parameter in this
+ // case. Because of this, parent may only be passed in the query, not fragment.
+ if (typeof params.parent === 'string' && params.parent !== '') {
+ // Otherwise, relayUrl['..'] will be null, signaling transport
+ // code to ignore rpc calls since they cannot work without a
+ // relay URL with host qualification.
+ if (parentRelayUrl.substring(0, 1) !== '/') {
+ // Path-relative. Trust that parent is passed in appropriately.
+ var lastSlash = params.parent.lastIndexOf('/');
+ parentRelayUrl = params.parent.substring(0, lastSlash + 1) + parentRelayUrl;
+ } else {
+ // Host-relative.
+ parentRelayUrl = getOrigin(params.parent) + parentRelayUrl;
+ }
}
}
- }
- var useLegacy = !!configRpc.useLegacyProtocol;
- setRelayUrl('..', parentRelayUrl, useLegacy);
+ var useLegacy = !!configRpc.useLegacyProtocol;
+ setRelayUrl('..', parentRelayUrl, useLegacy);
- if (useLegacy) {
- transport = gadgets.rpctx.ifpc;
- transport.init(process, transportReady);
+ if (useLegacy) {
+ transport = gadgets.rpctx.ifpc;
+ transport.init(process, transportReady);
+ }
+
+ // Sets the auth token and signals transport to setup connection to container.
+ var forceSecure = opt_forcesecure || params.forcesecure || false;
+ setAuthToken('..', rpctoken, forceSecure);
}
- // Sets the auth token and signals transport to setup connection to container.
- var forceSecure = opt_forcesecure || params.forcesecure || false;
- setAuthToken('..', rpctoken, forceSecure);
+ var requiredConfig = {
+ parentRelayUrl: gadgets.config.NonEmptyStringValidator
+ };
+ gadgets.config.register('rpc', requiredConfig, init);
}
- var requiredConfig = {
- parentRelayUrl : gadgets.config.NonEmptyStringValidator
- };
- gadgets.config.register("rpc", requiredConfig, init);
- }
+ function setupContainerGenericIframe(rpctoken, opt_parent, opt_forcesecure) {
+ // Generic child IFRAME setting up connection w/ its container.
+ // Use the opt_parent param if provided, or the "parent" query param
+ // if found -- otherwise, do nothing since this call might be initiated
+ // automatically at first, then actively later in IFRAME code.
+ var forcesecure = opt_forcesecure || params.forcesecure || false;
+ var parent = opt_parent || params.parent;
+ if (parent) {
+ setRelayUrl('..', parent);
+ setAuthToken('..', rpctoken, forcesecure);
+ }
+ }
- function setupContainerGenericIframe(rpctoken, opt_parent, opt_forcesecure) {
- // Generic child IFRAME setting up connection w/ its container.
- // Use the opt_parent param if provided, or the "parent" query param
- // if found -- otherwise, do nothing since this call might be initiated
- // automatically at first, then actively later in IFRAME code.
- var forcesecure = opt_forcesecure || params.forcesecure || false;
- var parent = opt_parent || params.parent;
- if (parent) {
- setRelayUrl('..', parent);
- setAuthToken('..', rpctoken, forcesecure);
- }
- }
-
- function setupChildIframe(gadgetId, opt_frameurl, opt_authtoken, opt_forcesecure) {
- if (!gadgets.util) {
- return;
- }
- var childIframe = document.getElementById(gadgetId);
- if (!childIframe) {
- throw new Error("Cannot set up gadgets.rpc receiver with ID: " + gadgetId +
- ", element not found.");
- }
-
- // The "relay URL" can either be explicitly specified or is set as
- // the child IFRAME URL verbatim.
- var relayUrl = opt_frameurl || childIframe.src;
- setRelayUrl(gadgetId, relayUrl);
-
- // The auth token is parsed from child params (rpctoken) or overridden.
- var childParams = gadgets.util.getUrlParameters(childIframe.src);
- var rpctoken = opt_authtoken || childParams.rpctoken;
- var forcesecure = opt_forcesecure || childParams.forcesecure;
- setAuthToken(gadgetId, rpctoken, forcesecure);
- }
+ function setupChildIframe(gadgetId, opt_frameurl, opt_authtoken, opt_forcesecure) {
+ if (!gadgets.util) {
+ return;
+ }
+ var childIframe = document.getElementById(gadgetId);
+ if (!childIframe) {
+ throw new Error('Cannot set up gadgets.rpc receiver with ID: ' + gadgetId +
+ ', element not found.');
+ }
+
+ // The "relay URL" can either be explicitly specified or is set as
+ // the child IFRAME URL verbatim.
+ var relayUrl = opt_frameurl || childIframe.src;
+ setRelayUrl(gadgetId, relayUrl);
+
+ // The auth token is parsed from child params (rpctoken) or overridden.
+ var childParams = gadgets.util.getUrlParameters(childIframe.src);
+ var rpctoken = opt_authtoken || childParams.rpctoken;
+ var forcesecure = opt_forcesecure || childParams.forcesecure;
+ setAuthToken(gadgetId, rpctoken, forcesecure);
+ }
- /**
+ /**
* Sets up the gadgets.rpc library to communicate with the receiver.
* <p>This method replaces setRelayUrl(...) and setAuthToken(...)
*
@@ -661,102 +661,102 @@ gadgets.rpc = function() {
* @param {string=} opt_authtoken
* @param {boolean=} opt_forcesecure
*/
- function setupReceiver(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure) {
- if (targetId === '..') {
- // Gadget/IFRAME to container.
- var rpctoken = opt_authtoken || params.rpctoken || params.ifpctok || "";
- if (window['__isgadget'] === true) {
- setupContainerGadgetContext(rpctoken, opt_forcesecure);
+ function setupReceiver(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure) {
+ if (targetId === '..') {
+ // Gadget/IFRAME to container.
+ var rpctoken = opt_authtoken || params.rpctoken || params.ifpctok || '';
+ if (window['__isgadget'] === true) {
+ setupContainerGadgetContext(rpctoken, opt_forcesecure);
+ } else {
+ setupContainerGenericIframe(rpctoken, opt_receiverurl, opt_forcesecure);
+ }
} else {
- setupContainerGenericIframe(rpctoken, opt_receiverurl, opt_forcesecure);
+ // Container to child.
+ setupChildIframe(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure);
}
- } else {
- // Container to child.
- setupChildIframe(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure);
}
- }
- return /** @scope gadgets.rpc */ {
- config: function(config) {
- if (typeof config.securityCallback === 'function') {
- securityCallback = config.securityCallback;
- }
- },
-
- /**
+ return /** @scope gadgets.rpc */ {
+ config: function(config) {
+ if (typeof config.securityCallback === 'function') {
+ securityCallback = config.securityCallback;
+ }
+ },
+
+ /**
* Registers an RPC service.
* @param {string} serviceName Service name to register.
* @param {function(Object,Object)} handler Service handler.
*
* @member gadgets.rpc
*/
- register: function(serviceName, handler) {
- if (serviceName === CALLBACK_NAME || serviceName === ACK) {
- throw new Error("Cannot overwrite callback/ack service");
- }
+ register: function(serviceName, handler) {
+ if (serviceName === CALLBACK_NAME || serviceName === ACK) {
+ throw new Error('Cannot overwrite callback/ack service');
+ }
- if (serviceName === DEFAULT_NAME) {
- throw new Error("Cannot overwrite default service:"
- + " use registerDefault");
- }
+ if (serviceName === DEFAULT_NAME) {
+ throw new Error('Cannot overwrite default service:'
+ + ' use registerDefault');
+ }
- services[serviceName] = handler;
- },
+ services[serviceName] = handler;
+ },
- /**
+ /**
* Unregisters an RPC service.
* @param {string} serviceName Service name to unregister.
*
* @member gadgets.rpc
*/
- unregister: function(serviceName) {
- if (serviceName === CALLBACK_NAME || serviceName === ACK) {
- throw new Error("Cannot delete callback/ack service");
- }
+ unregister: function(serviceName) {
+ if (serviceName === CALLBACK_NAME || serviceName === ACK) {
+ throw new Error('Cannot delete callback/ack service');
+ }
- if (serviceName === DEFAULT_NAME) {
- throw new Error("Cannot delete default service:"
- + " use unregisterDefault");
- }
+ if (serviceName === DEFAULT_NAME) {
+ throw new Error('Cannot delete default service:'
+ + ' use unregisterDefault');
+ }
- delete services[serviceName];
- },
+ delete services[serviceName];
+ },
- /**
+ /**
* Registers a default service handler to processes all unknown
* RPC calls which raise an exception by default.
* @param {function(Object,Object)} handler Service handler.
*
* @member gadgets.rpc
*/
- registerDefault: function(handler) {
- services[DEFAULT_NAME] = handler;
- },
+ registerDefault: function(handler) {
+ services[DEFAULT_NAME] = handler;
+ },
- /**
+ /**
* Unregisters the default service handler. Future unknown RPC
* calls will fail silently.
*
* @member gadgets.rpc
*/
- unregisterDefault: function() {
- delete services[DEFAULT_NAME];
- },
+ unregisterDefault: function() {
+ delete services[DEFAULT_NAME];
+ },
- /**
+ /**
* Forces all subsequent calls to be made by a transport
* method that allows the caller to verify the message receiver
* (by way of the parent parameter, through getRelayUrl(...)).
* At present this means IFPC or WPM.
* @member gadgets.rpc
*/
- forceParentVerifiable: function() {
- if (!transport.isParentVerifiable()) {
- transport = gadgets.rpctx.ifpc;
- }
- },
+ forceParentVerifiable: function() {
+ if (!transport.isParentVerifiable()) {
+ transport = gadgets.rpctx.ifpc;
+ }
+ },
- /**
+ /**
* Calls an RPC service.
* @param {string} targetId Module Id of the RPC service provider.
* Empty if calling the parent container.
@@ -767,116 +767,116 @@ gadgets.rpc = function() {
*
* @member gadgets.rpc
*/
- call: function(targetId, serviceName, callback, var_args) {
- targetId = targetId || '..';
- // Default to the container calling.
- var from = '..';
+ call: function(targetId, serviceName, callback, var_args) {
+ targetId = targetId || '..';
+ // Default to the container calling.
+ var from = '..';
- if (targetId === '..') {
- from = rpcId;
- }
+ if (targetId === '..') {
+ from = rpcId;
+ }
- ++callId;
- if (callback) {
- callbacks[callId] = callback;
- }
+ ++callId;
+ if (callback) {
+ callbacks[callId] = callback;
+ }
- var rpc = {
- s: serviceName,
- f: from,
- c: callback ? callId : 0,
- a: Array.prototype.slice.call(arguments, 3),
- t: authToken[targetId],
- l: useLegacyProtocol[targetId]
- };
+ var rpc = {
+ s: serviceName,
+ f: from,
+ c: callback ? callId : 0,
+ a: Array.prototype.slice.call(arguments, 3),
+ t: authToken[targetId],
+ l: useLegacyProtocol[targetId]
+ };
- if (targetId !== '..' && !document.getElementById(targetId)) {
- // The target has been removed from the DOM. Don't even try.
- gadgets.log("WARNING: attempted send to nonexistent frame: " + targetId);
- return;
- }
+ if (targetId !== '..' && !document.getElementById(targetId)) {
+ // The target has been removed from the DOM. Don't even try.
+ gadgets.log('WARNING: attempted send to nonexistent frame: ' + targetId);
+ return;
+ }
- // If target is on the same domain, call method directly
- if (callSameDomain(targetId, rpc)) {
- return;
- }
+ // If target is on the same domain, call method directly
+ if (callSameDomain(targetId, rpc)) {
+ return;
+ }
- // Attempt to make call via a cross-domain transport.
- // Retrieve the transport for the given target - if one
- // target is misconfigured, it won't affect the others.
- var channel = receiverTx[targetId];
-
- if (!channel) {
- // Not set up yet. Enqueue the rpc for such time as it is.
- if (!earlyRpcQueue[targetId]) {
- earlyRpcQueue[targetId] = [ rpc ];
- } else {
- earlyRpcQueue[targetId].push(rpc);
+ // Attempt to make call via a cross-domain transport.
+ // Retrieve the transport for the given target - if one
+ // target is misconfigured, it won't affect the others.
+ var channel = receiverTx[targetId];
+
+ if (!channel) {
+ // Not set up yet. Enqueue the rpc for such time as it is.
+ if (!earlyRpcQueue[targetId]) {
+ earlyRpcQueue[targetId] = [rpc];
+ } else {
+ earlyRpcQueue[targetId].push(rpc);
+ }
+ return;
}
- return;
- }
- // If we are told to use the legacy format, then we must
- // default to IFPC.
- if (useLegacyProtocol[targetId]) {
- channel = gadgets.rpctx.ifpc;
- }
+ // If we are told to use the legacy format, then we must
+ // default to IFPC.
+ if (useLegacyProtocol[targetId]) {
+ channel = gadgets.rpctx.ifpc;
+ }
- if (channel.call(targetId, from, rpc) === false) {
- // Fall back to IFPC. This behavior may be removed as IFPC is as well.
- receiverTx[targetId] = fallbackTransport;
- transport.call(targetId, from, rpc);
- }
- },
+ if (channel.call(targetId, from, rpc) === false) {
+ // Fall back to IFPC. This behavior may be removed as IFPC is as well.
+ receiverTx[targetId] = fallbackTransport;
+ transport.call(targetId, from, rpc);
+ }
+ },
- /**
+ /**
* Gets the relay URL of a target frame.
* @param {string} targetId Name of the target frame.
* @return {string|undefined} Relay URL of the target frame.
*
* @member gadgets.rpc
*/
- getRelayUrl: function(targetId) {
- var url = relayUrl[targetId];
- // Some RPC methods (wpm, for one) are unhappy with schemeless URLs.
- if (url && url.substring(0,1) === '/') {
- if (url.substring(1,2) === '/') { // starts with '//'
- url = document.location.protocol + url;
- } else { // relative URL, starts with '/'
- url = document.location.protocol + '//' + document.location.host + url;
- }
- }
-
- return url;
- },
-
- setRelayUrl: setRelayUrl,
- setAuthToken: setAuthToken,
- setupReceiver: setupReceiver,
- getAuthToken: getAuthToken,
-
- // Note: Does not delete iframe
- removeReceiver: function(receiverId) {
- delete relayUrl[receiverId];
- delete useLegacyProtocol[receiverId];
- delete authToken[receiverId];
- delete setup[receiverId];
- delete sameDomain[receiverId];
- delete receiverTx[receiverId];
- },
+ getRelayUrl: function(targetId) {
+ var url = relayUrl[targetId];
+ // Some RPC methods (wpm, for one) are unhappy with schemeless URLs.
+ if (url && url.substring(0, 1) === '/') {
+ if (url.substring(1, 2) === '/') { // starts with '//'
+ url = document.location.protocol + url;
+ } else { // relative URL, starts with '/'
+ url = document.location.protocol + '//' + document.location.host + url;
+ }
+ }
- /**
+ return url;
+ },
+
+ setRelayUrl: setRelayUrl,
+ setAuthToken: setAuthToken,
+ setupReceiver: setupReceiver,
+ getAuthToken: getAuthToken,
+
+ // Note: Does not delete iframe
+ removeReceiver: function(receiverId) {
+ delete relayUrl[receiverId];
+ delete useLegacyProtocol[receiverId];
+ delete authToken[receiverId];
+ delete setup[receiverId];
+ delete sameDomain[receiverId];
+ delete receiverTx[receiverId];
+ },
+
+ /**
* Gets the RPC relay mechanism.
* @return {string} RPC relay mechanism. See above for
* a list of supported types.
*
* @member gadgets.rpc
*/
- getRelayChannel: function() {
- return transport.getCode();
- },
+ getRelayChannel: function() {
+ return transport.getCode();
+ },
- /**
+ /**
* Receives and processes an RPC request. (Not to be used directly.)
* Only used by IFPC.
* @param {Array.<string>} fragment An RPC request fragment encoded as
@@ -887,115 +887,115 @@ gadgets.rpc = function() {
* @member gadgets.rpc
* @deprecated
*/
- receive: function(fragment, otherWindow) {
- if (fragment.length > 4) {
- process(gadgets.json.parse(
- decodeURIComponent(fragment[fragment.length - 1])));
- } else {
- relayOnload.apply(null, fragment.concat(otherWindow));
- }
- },
+ receive: function(fragment, otherWindow) {
+ if (fragment.length > 4) {
+ process(gadgets.json.parse(
+ decodeURIComponent(fragment[fragment.length - 1])));
+ } else {
+ relayOnload.apply(null, fragment.concat(otherWindow));
+ }
+ },
- /**
+ /**
* Receives and processes an RPC request sent via the same domain.
* (Not to be used directly). Converts the inbound rpc object's
* Array into a local Array to pass the process() Array test.
- * @param {Object} rpc RPC object containing all request params
+ * @param {Object} rpc RPC object containing all request params.
* @member gadgets.rpc
*/
- receiveSameDomain: function(rpc) {
- // Pass through to local process method but converting to a local Array
- rpc.a = Array.prototype.slice.call(rpc.a);
- window.setTimeout(function() { process(rpc); }, 0);
- },
-
- // Helper method to get the protocol://host:port of an input URL.
- // see docs above
- getOrigin: getOrigin,
-
- getReceiverOrigin: function(receiverId) {
- var channel = receiverTx[receiverId];
- if (!channel) {
- // not set up yet
- return null;
- }
- if (!channel.isParentVerifiable(receiverId)) {
- // given transport cannot verify receiver origin
- return null;
- }
- var origRelay = gadgets.rpc.getRelayUrl(receiverId) ||
- gadgets.util.getUrlParameters().parent;
- return gadgets.rpc.getOrigin(origRelay);
- },
+ receiveSameDomain: function(rpc) {
+ // Pass through to local process method but converting to a local Array
+ rpc.a = Array.prototype.slice.call(rpc.a);
+ window.setTimeout(function() { process(rpc); }, 0);
+ },
- /**
+ // Helper method to get the protocol://host:port of an input URL.
+ // see docs above
+ getOrigin: getOrigin,
+
+ getReceiverOrigin: function(receiverId) {
+ var channel = receiverTx[receiverId];
+ if (!channel) {
+ // not set up yet
+ return null;
+ }
+ if (!channel.isParentVerifiable(receiverId)) {
+ // given transport cannot verify receiver origin
+ return null;
+ }
+ var origRelay = gadgets.rpc.getRelayUrl(receiverId) ||
+ gadgets.util.getUrlParameters().parent;
+ return gadgets.rpc.getOrigin(origRelay);
+ },
+
+ /**
* Internal-only method used to initialize gadgets.rpc.
* @member gadgets.rpc
*/
- init: function() {
- // Conduct any global setup necessary for the chosen transport.
- // Do so after gadgets.rpc definition to allow transport to access
- // gadgets.rpc methods.
- if (transport.init(process, transportReady) === false) {
- transport = fallbackTransport;
- }
- if (isChild) {
- setupReceiver('..');
- }
- },
-
- /** Returns the window keyed by the ID. null/".." for parent, else child */
- _getTargetWin: getTargetWin,
-
- /** Create an iframe for loading the relay URL. Used by child only. */
- _createRelayIframe: function(token, data) {
- var relay = gadgets.rpc.getRelayUrl('..');
- if (!relay) {
- return null;
- }
-
- // Format: #targetId & sourceId & authToken & data
- var src = relay + '#..&' + rpcId + '&' + token + '&' +
- encodeURIComponent(gadgets.json.stringify(data));
-
- var iframe = document.createElement('iframe');
- iframe.style.border = iframe.style.width = iframe.style.height = '0px';
- iframe.style.visibility = 'hidden';
- iframe.style.position = 'absolute';
-
- function appendFn() {
- // Append the iframe.
- document.body.appendChild(iframe);
-
- // 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.
- iframe.src = 'javascript:"<html></html>"';
- iframe.src = src;
- }
-
- if (document.body) {
- appendFn();
- } else {
- gadgets.util.registerOnLoadHandler(function() { appendFn(); });
- }
-
- return iframe;
- },
-
- ACK: ACK,
-
- RPC_ID: rpcId,
-
- SEC_ERROR_LOAD_TIMEOUT: LOAD_TIMEOUT,
- SEC_ERROR_FRAME_PHISH: FRAME_PHISH,
- SEC_ERROR_FORGED_MSG : FORGED_MSG
- };
-}();
+ init: function() {
+ // Conduct any global setup necessary for the chosen transport.
+ // Do so after gadgets.rpc definition to allow transport to access
+ // gadgets.rpc methods.
+ if (transport.init(process, transportReady) === false) {
+ transport = fallbackTransport;
+ }
+ if (isChild) {
+ setupReceiver('..');
+ }
+ },
+
+ /** Returns the window keyed by the ID. null/".." for parent, else child */
+ _getTargetWin: getTargetWin,
+
+ /** Create an iframe for loading the relay URL. Used by child only. */
+ _createRelayIframe: function(token, data) {
+ var relay = gadgets.rpc.getRelayUrl('..');
+ if (!relay) {
+ return null;
+ }
+
+ // Format: #targetId & sourceId & authToken & data
+ var src = relay + '#..&' + rpcId + '&' + token + '&' +
+ encodeURIComponent(gadgets.json.stringify(data));
+
+ var iframe = document.createElement('iframe');
+ iframe.style.border = iframe.style.width = iframe.style.height = '0px';
+ iframe.style.visibility = 'hidden';
+ iframe.style.position = 'absolute';
+
+ function appendFn() {
+ // Append the iframe.
+ document.body.appendChild(iframe);
+
+ // 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.
+ iframe.src = 'javascript:"<html></html>"';
+ iframe.src = src;
+ }
+
+ if (document.body) {
+ appendFn();
+ } else {
+ gadgets.util.registerOnLoadHandler(function() { appendFn(); });
+ }
+
+ return iframe;
+ },
+
+ ACK: ACK,
+
+ RPC_ID: rpcId,
+
+ SEC_ERROR_LOAD_TIMEOUT: LOAD_TIMEOUT,
+ SEC_ERROR_FRAME_PHISH: FRAME_PHISH,
+ SEC_ERROR_FORGED_MSG: FORGED_MSG
+ };
+ }();
-// Initialize library/transport.
-gadgets.rpc.init();
+ // Initialize library/transport.
+ gadgets.rpc.init();
} // !end of double-inclusion guard
Modified: shindig/trunk/features/src/main/javascript/features/rpc/wpm.transport.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/rpc/wpm.transport.js?rev=997163&r1=997162&r2=997163&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/rpc/wpm.transport.js (original)
+++ shindig/trunk/features/src/main/javascript/features/rpc/wpm.transport.js Wed Sep 15 01:39:49 2010
@@ -43,132 +43,132 @@ gadgets.rpctx = gadgets.rpctx || {};
*/
if (!gadgets.rpctx.wpm) { // make lib resilient to double-inclusion
-gadgets.rpctx.wpm = function() {
- var process, ready;
- var postMessage;
- var pmSync = false;
- var pmEventDomain = false;
- var isForceSecure = false;
-
- // Some browsers (IE, Opera) have an implementation of postMessage that is
- // synchronous, although HTML5 specifies that it should be asynchronous. In
- // order to make all browsers behave consistently, we run a small test to detect
- // if postMessage is asynchronous or not. If not, we wrap calls to postMessage
- // in a setTimeout with a timeout of 0.
- // Also, Opera's "message" event does not have an "origin" property (at least,
- // it doesn't in version 9.64; presumably, it will in version 10). If
- // event.origin does not exist, use event.domain. The other difference is that
- // while event.origin looks like <scheme>://<hostname>:<port>, event.domain
- // consists only of <hostname>.
- //
- function testPostMessage() {
- var hit = false;
-
- function receiveMsg(event) {
- if (event.data == "postmessage.test") {
- hit = true;
- if (typeof event.origin === "undefined") {
- pmEventDomain = true;
+ gadgets.rpctx.wpm = function() {
+ var process, ready;
+ var postMessage;
+ var pmSync = false;
+ var pmEventDomain = false;
+ var isForceSecure = false;
+
+ // Some browsers (IE, Opera) have an implementation of postMessage that is
+ // synchronous, although HTML5 specifies that it should be asynchronous. In
+ // order to make all browsers behave consistently, we run a small test to detect
+ // if postMessage is asynchronous or not. If not, we wrap calls to postMessage
+ // in a setTimeout with a timeout of 0.
+ // Also, Opera's "message" event does not have an "origin" property (at least,
+ // it doesn't in version 9.64; presumably, it will in version 10). If
+ // event.origin does not exist, use event.domain. The other difference is that
+ // while event.origin looks like <scheme>://<hostname>:<port>, event.domain
+ // consists only of <hostname>.
+ //
+ function testPostMessage() {
+ var hit = false;
+
+ function receiveMsg(event) {
+ if (event.data == 'postmessage.test') {
+ hit = true;
+ if (typeof event.origin === 'undefined') {
+ pmEventDomain = true;
+ }
}
}
- }
-
- gadgets.util.attachBrowserEvent(window, "message", receiveMsg, false);
- window.postMessage("postmessage.test", "*");
-
- // if 'hit' is true here, then postMessage is synchronous
- if (hit) {
- pmSync = true;
- }
-
- gadgets.util.removeBrowserEvent(window, "message", receiveMsg, false);
- }
-
- function onmessage(packet) {
- var rpc = gadgets.json.parse(packet.data);
- if (isForceSecure) {
- if (!rpc || !rpc.f) {
- return;
+
+ gadgets.util.attachBrowserEvent(window, 'message', receiveMsg, false);
+ window.postMessage('postmessage.test', '*');
+
+ // if 'hit' is true here, then postMessage is synchronous
+ if (hit) {
+ pmSync = true;
}
-
- // for security, check origin against expected value
- var origRelay = gadgets.rpc.getRelayUrl(rpc.f) ||
- gadgets.util.getUrlParameters()["parent"];
- var origin = gadgets.rpc.getOrigin(origRelay);
- if (!pmEventDomain ? packet.origin !== origin :
- packet.domain !== /^.+:\/\/([^:]+).*/.exec( origin )[1]) {
- return;
+
+ gadgets.util.removeBrowserEvent(window, 'message', receiveMsg, false);
+ }
+
+ function onmessage(packet) {
+ var rpc = gadgets.json.parse(packet.data);
+ if (isForceSecure) {
+ if (!rpc || !rpc.f) {
+ return;
+ }
+
+ // for security, check origin against expected value
+ var origRelay = gadgets.rpc.getRelayUrl(rpc.f) ||
+ gadgets.util.getUrlParameters()['parent'];
+ var origin = gadgets.rpc.getOrigin(origRelay);
+ if (!pmEventDomain ? packet.origin !== origin :
+ packet.domain !== /^.+:\/\/([^:]+).*/.exec(origin)[1]) {
+ return;
+ }
}
+ process(rpc);
}
- process(rpc);
- }
- return {
- getCode: function() {
- return 'wpm';
- },
-
- isParentVerifiable: function() {
- return true;
- },
-
- init: function(processFn, readyFn) {
- process = processFn;
- ready = readyFn;
-
- testPostMessage();
- if (!pmSync) {
- postMessage = function(win, msg, origin) {
- win.postMessage(msg, origin);
- };
- } else {
- postMessage = function(win, msg, origin) {
- window.setTimeout( function() {
+ return {
+ getCode: function() {
+ return 'wpm';
+ },
+
+ isParentVerifiable: function() {
+ return true;
+ },
+
+ init: function(processFn, readyFn) {
+ process = processFn;
+ ready = readyFn;
+
+ testPostMessage();
+ if (!pmSync) {
+ postMessage = function(win, msg, origin) {
win.postMessage(msg, origin);
- }, 0);
- };
- }
-
- // Set up native postMessage handler.
- gadgets.util.attachBrowserEvent(window, 'message', onmessage, false);
-
- ready('..', true); // Immediately ready to send to parent.
- return true;
- },
-
- setup: function(receiverId, token, forceSecure) {
- isForceSecure = forceSecure;
- // If we're a gadget, send an ACK message to indicate to container
- // that we're ready to receive messages.
- if (receiverId === '..') {
- if (isForceSecure) {
- gadgets.rpc._createRelayIframe(token);
+ };
} else {
- gadgets.rpc.call(receiverId, gadgets.rpc.ACK);
+ postMessage = function(win, msg, origin) {
+ window.setTimeout(function() {
+ win.postMessage(msg, origin);
+ }, 0);
+ };
}
- }
- return true;
- },
- call: function(targetId, from, rpc) {
- var targetWin = gadgets.rpc._getTargetWin(targetId);
- // targetOrigin = canonicalized relay URL
- var origRelay = gadgets.rpc.getRelayUrl(targetId) ||
- gadgets.util.getUrlParameters()["parent"];
- var origin = gadgets.rpc.getOrigin(origRelay);
- if (origin) {
- postMessage(targetWin, gadgets.json.stringify(rpc), origin);
- } else {
- gadgets.error("No relay set (used as window.postMessage targetOrigin)" +
- ", cannot send cross-domain message");
- }
- return true;
- },
+ // Set up native postMessage handler.
+ gadgets.util.attachBrowserEvent(window, 'message', onmessage, false);
- relayOnload: function(receiverId, data) {
- ready(receiverId, true);
- }
- };
-}();
+ ready('..', true); // Immediately ready to send to parent.
+ return true;
+ },
+
+ setup: function(receiverId, token, forceSecure) {
+ isForceSecure = forceSecure;
+ // If we're a gadget, send an ACK message to indicate to container
+ // that we're ready to receive messages.
+ if (receiverId === '..') {
+ if (isForceSecure) {
+ gadgets.rpc._createRelayIframe(token);
+ } else {
+ gadgets.rpc.call(receiverId, gadgets.rpc.ACK);
+ }
+ }
+ return true;
+ },
+
+ call: function(targetId, from, rpc) {
+ var targetWin = gadgets.rpc._getTargetWin(targetId);
+ // targetOrigin = canonicalized relay URL
+ var origRelay = gadgets.rpc.getRelayUrl(targetId) ||
+ gadgets.util.getUrlParameters()['parent'];
+ var origin = gadgets.rpc.getOrigin(origRelay);
+ if (origin) {
+ postMessage(targetWin, gadgets.json.stringify(rpc), origin);
+ } else {
+ gadgets.error('No relay set (used as window.postMessage targetOrigin)' +
+ ', cannot send cross-domain message');
+ }
+ return true;
+ },
+
+ relayOnload: function(receiverId, data) {
+ ready(receiverId, true);
+ }
+ };
+ }();
} // !end of double-inclusion guard
Modified: shindig/trunk/features/src/main/javascript/features/setprefs/setprefs.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/setprefs/setprefs.js?rev=997163&r1=997162&r2=997163&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/setprefs/setprefs.js (original)
+++ shindig/trunk/features/src/main/javascript/features/setprefs/setprefs.js Wed Sep 15 01:39:49 2010
@@ -50,10 +50,10 @@ gadgets.Prefs.prototype.set = function(k
var args = [
null, // go to parent
- "set_pref", // service name
+ 'set_pref', // service name
null, // no callback
gadgets.util.getUrlParameters().ifpctok ||
- gadgets.util.getUrlParameters().rpctoken || 0 // Legacy IFPC "security".
+ gadgets.util.getUrlParameters().rpctoken || 0 // Legacy IFPC "security".
].concat(Array.prototype.slice.call(arguments));
gadgets.rpc.call.apply(gadgets.rpc, args);
@@ -69,8 +69,8 @@ gadgets.Prefs.prototype.setArray = funct
// We must escape pipe (|) characters to ensure that decoding in
// getArray actually works properly.
for (var i = 0, j = val.length; i < j; ++i) {
- if (typeof val[i] !== "number") {
- val[i] = val[i].replace(/\|/g, "%7C");
+ if (typeof val[i] !== 'number') {
+ val[i] = val[i].replace(/\|/g, '%7C');
}
}
this.set(key, val.join('|'));
Modified: shindig/trunk/features/src/main/javascript/features/settitle/settitle.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/settitle/settitle.js?rev=997163&r1=997162&r2=997163&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/settitle/settitle.js (original)
+++ shindig/trunk/features/src/main/javascript/features/settitle/settitle.js Wed Sep 15 01:39:49 2010
@@ -31,7 +31,7 @@ gadgets.window = gadgets.window || {};
* @scope gadgets.window
*/
gadgets.window.setTitle = function(title) {
- gadgets.rpc.call(null, "set_title", null, title);
+ gadgets.rpc.call(null, 'set_title', null, title);
};
// Alias for legacy code
Modified: shindig/trunk/features/src/main/javascript/features/settitle/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/settitle/taming.js?rev=997163&r1=997162&r2=997163&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/settitle/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/settitle/taming.js Wed Sep 15 01:39:49 2010
@@ -26,5 +26,5 @@ var tamings___ = tamings___ || [];
tamings___.push(function(imports) {
caja___.whitelistFuncs([
[gadgets.window, 'setTitle']
- ]);
+ ]);
});
Modified: shindig/trunk/features/src/main/javascript/features/shindig.auth/auth.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.auth/auth.js?rev=997163&r1=997162&r2=997163&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.auth/auth.js (original)
+++ shindig/trunk/features/src/main/javascript/features/shindig.auth/auth.js Wed Sep 15 01:39:49 2010
@@ -133,9 +133,9 @@ shindig.Auth = function() {
authToken = args.join('&');
}
- function init (configuration) {
+ function init(configuration) {
var urlParams = gadgets.util.getUrlParameters();
- var config = configuration["shindig.auth"] || {};
+ var config = configuration['shindig.auth'] || {};
// Auth token - might be injected into the gadget directly, or might
// be on the URL (hopefully on the fragment).
@@ -151,22 +151,22 @@ shindig.Auth = function() {
// Trusted JSON. We use eval directly because this was injected by the
// container server and json parsing is slow in IE.
if (config.trustedJson) {
- trusted = eval("(" + config.trustedJson + ")");
+ trusted = eval('(' + config.trustedJson + ')');
}
}
- gadgets.config.register("shindig.auth", null, init);
+ gadgets.config.register('shindig.auth', null, init);
return /** @scope shindig.auth */ {
/**
* Gets the auth token.
*
- * @return {string} the gadget authentication token
+ * @return {string} the gadget authentication token.
*
* @member shindig.auth
*/
- getSecurityToken : function() {
+ getSecurityToken: function() {
return authToken;
},
@@ -177,7 +177,7 @@ shindig.Auth = function() {
*
* @member shindig.auth
*/
- updateSecurityToken : function(newToken) {
+ updateSecurityToken: function(newToken) {
authToken = newToken;
},
@@ -186,7 +186,7 @@ shindig.Auth = function() {
* a trusted container server.
* @return {Object}
*/
- getTrustedData : function() {
+ getTrustedData: function() {
return trusted;
}
};
Modified: shindig/trunk/features/src/main/javascript/features/shindig.container/cookies.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.container/cookies.js?rev=997163&r1=997162&r2=997163&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.container/cookies.js (original)
+++ shindig/trunk/features/src/main/javascript/features/shindig.container/cookies.js Wed Sep 15 01:39:49 2010
@@ -17,7 +17,7 @@
*/
/**
- * @fileoverview Functions for setting, getting and deleting cookies
+ * @fileoverview Functions for setting, getting and deleting cookies.
*/
/**
@@ -102,14 +102,14 @@ shindig.cookies.set = function(name, val
/**
* Returns the value for the first cookie with the given name
- * @param {string} name The name of the cookie to get
+ * @param {string} name The name of the cookie to get.
* @param {string} opt_default If not found this is returned instead.
* @return {string|undefined} The value of the cookie. If no cookie is set this
* returns opt_default or undefined if opt_default is
* not provided.
*/
shindig.cookies.get = function(name, opt_default) {
- var nameEq = name + "=";
+ var nameEq = name + '=';
var cookie = String(document.cookie);
for (var pos = -1; (pos = cookie.indexOf(nameEq, pos + 1)) >= 0;) {
var i = pos;
@@ -157,7 +157,7 @@ shindig.cookies.remove = function(name,
/**
* Gets the names and values for all the cookies
* @private
- * @return {Object} An object with keys and values
+ * @return {Object} An object with keys and values.
*/
shindig.cookies.getKeyValues_ = function() {
var cookie = String(document.cookie);
@@ -180,7 +180,7 @@ shindig.cookies.getKeyValues_ = function
/**
* Gets the names for all the cookies
- * @return {Array} An array with the names of the cookies
+ * @return {Array} An array with the names of the cookies.
*/
shindig.cookies.getKeys = function() {
return shindig.cookies.getKeyValues_().keys;
@@ -189,7 +189,7 @@ shindig.cookies.getKeys = function() {
/**
* Gets the values for all the cookies
- * @return {Array} An array with the values of the cookies
+ * @return {Array} An array with the values of the cookies.
*/
shindig.cookies.getValues = function() {
return shindig.cookies.getKeyValues_().values;
@@ -221,7 +221,7 @@ shindig.cookies.getCount = function() {
/**
* Returns whether there is a cookie with the given name
- * @param {string} key The name of the cookie to test for
+ * @param {string} key The name of the cookie to test for.
* @return {boolean}
*/
shindig.cookies.containsKey = function(key) {
@@ -236,7 +236,7 @@ shindig.cookies.containsKey = function(k
/**
* Returns whether there is a cookie with the given value. (This is an O(n)
* operation.)
- * @param {string} value The value to check for
+ * @param {string} value The value to check for.
* @return {boolean}
*/
shindig.cookies.containsValue = function(value) {
@@ -266,6 +266,6 @@ shindig.cookies.clear = function() {
* to the size of a cookie. To make sure users can't break this limit, we
* should truncate long cookies at 3950 bytes, to be extra careful with dumb
* browsers/proxies that interpret 4K as 4000 rather than 4096
- * @type number
+ * @type {number}
*/
shindig.cookies.MAX_COOKIE_LENGTH = 3950;
Modified: shindig/trunk/features/src/main/javascript/features/shindig.container/osapi.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.container/osapi.js?rev=997163&r1=997162&r2=997163&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.container/osapi.js (original)
+++ shindig/trunk/features/src/main/javascript/features/shindig.container/osapi.js Wed Sep 15 01:39:49 2010
@@ -17,7 +17,7 @@
*/
/**
- * @fileoverview Base OSAPI binding
+ * @fileoverview Base OSAPI binding.
*/
/**
@@ -43,8 +43,8 @@ if (gadgets && gadgets.rpc) { //Only def
// Don't allow underscores in any part of the method name as a convention
// for restricted methods
var current = osapi;
- if (requests[i].method.indexOf("_") == -1) {
- var path = requests[i].method.split(".");
+ if (requests[i].method.indexOf('_') == -1) {
+ var path = requests[i].method.split('.');
for (var j = 0; j < path.length; j++) {
if (current.hasOwnProperty(path[j])) {
current = current[path[j]];
@@ -63,7 +63,7 @@ if (gadgets && gadgets.rpc) { //Only def
current(requests[i].params, function(i) {
return function(response) {
// Put back in json-rpc format
- responses[i] = { id : requests[i].id, data : response};
+ responses[i] = { id: requests[i].id, data: response};
callCount++;
if (callCount == requests.length) {
callback(responses);
@@ -80,9 +80,9 @@ if (gadgets && gadgets.rpc) { //Only def
* @param callback
*/
osapi.container = {};
- osapi.container["listMethods"] = function(request, callback) {
+ osapi.container['listMethods'] = function(request, callback) {
var names = [];
- recurseNames(osapi, "", 5, names)
+ recurseNames(osapi, '', 5, names);
callback(names);
};
@@ -92,17 +92,17 @@ if (gadgets && gadgets.rpc) { //Only def
function recurseNames(base, path, depth, accumulated) {
if (depth == 0) return;
for (var prop in base) if (base.hasOwnProperty(prop)) {
- if (prop.indexOf("_") == -1) {
+ if (prop.indexOf('_') == -1) {
var type = typeof(base[prop]);
- if (type == "function") {
+ if (type == 'function') {
accumulated.push(path + prop);
- } else if (type == "object") {
- recurseNames(base[prop], path + prop + ".", depth - 1, accumulated);
+ } else if (type == 'object') {
+ recurseNames(base[prop], path + prop + '.', depth - 1, accumulated);
}
}
}
}
// Register the osapi RPC dispatcher.
- gadgets.rpc.register("osapi._handleGadgetRpcMethod", osapi._handleGadgetRpcMethod);
+ gadgets.rpc.register('osapi._handleGadgetRpcMethod', osapi._handleGadgetRpcMethod);
}