Author: lindner
Date: Mon Jun 21 23:43:49 2010
New Revision: 956739
URL: http://svn.apache.org/viewvc?rev=956739&view=rev
Log:
SHINDIG-1369 | gadget and container framework part 2
Modified:
shindig/trunk/features/src/main/javascript/features/container/container.js
shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js
shindig/trunk/features/src/main/javascript/features/container/gadget_site.js
shindig/trunk/features/src/main/javascript/features/container/init.js
shindig/trunk/features/src/main/javascript/features/container/service.js
shindig/trunk/features/src/main/javascript/features/container/util.js
Modified:
shindig/trunk/features/src/main/javascript/features/container/container.js
URL:
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/container.js?rev=956739&r1=956738&r2=956739&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/container.js
(original)
+++ shindig/trunk/features/src/main/javascript/features/container/container.js
Mon Jun 21 23:43:49 2010
@@ -16,11 +16,13 @@
* specific language governing permissions and limitations under the License.
*/
+
/**
* @fileoverview This represents the container for the current window or create
* the container if none already exists.
*/
+
/**
* @param {Object=} opt_config Configuration JSON.
* @constructor
@@ -52,17 +54,11 @@ shindig.container.Container = function(o
shindig.container.ContainerConfig.RENDER_TEST, false));
/**
- * @type {boolean}
- */
- this.sameDomain_ = Boolean(shindig.container.util.getSafeJsonValue(config,
- shindig.container.ContainerConfig.SAME_DOMAIN, true));
-
- /**
* Security token refresh interval (in ms) for debugging.
* @type {number}
*/
- this.tokenRefreshInterval_ =
Number(shindig.container.util.getSafeJsonValue(config,
- shindig.container.ContainerConfig.TOKEN_REFRESH_INTERVAL,
+ this.tokenRefreshInterval_ = Number(shindig.container.util.getSafeJsonValue(
+ config, shindig.container.ContainerConfig.TOKEN_REFRESH_INTERVAL,
30 * 60 * 1000));
/**
@@ -75,7 +71,7 @@ shindig.container.Container = function(o
* @type {number|null}
*/
this.tokenRefreshTimer_ = null;
-
+
this.registerRpcServices_();
this.onConstructed(config);
@@ -86,7 +82,7 @@ shindig.container.Container = function(o
* Create a new gadget site.
* @param {Element} gadgetEl HTML element into which to render
* @param {Element=} opt_bufferEl Optional HTML element for double buffering.
- * @return {shindig.container.GadgetSite} site created for application to hold
to.
+ * @return {shindig.container.GadgetSite} site created for client to hold to.
*/
shindig.container.Container.prototype.newGadgetSite = function(
gadgetEl, opt_bufferEl) {
@@ -99,7 +95,7 @@ shindig.container.Container.prototype.ne
/**
* @param {string} id Iframe ID of gadget site to get.
- * @return {shindig.container.GadgetSite} The gadget site with given holder's
iframeId.
+ * @return {shindig.container.GadgetSite} The gadget site with the given id.
*/
shindig.container.Container.prototype.getGadgetSite = function(id) {
// TODO: Support getting only the loading/active gadget in 2x buffers.
@@ -130,14 +126,15 @@ shindig.container.Container.prototype.ge
/**
* Called when gadget is navigated.
*
- * @param {shindig.container.GadgetSite} site the site where navigation is
ocurring
- * @param {string} gadgetUrl The URI of the gadget
- * @param {Object} gadgetParams view params for the gadget
- * @param {Object} renderParams render parameters, including the view
- * @param {function(Object)=} opt_callback Callback that occurs after gadget
is loaded
+ * @param {shindig.container.GadgetSite} site destination gadget to navigate
to.
+ * @param {string} gadgetUrl The URI of the gadget.
+ * @param {Object} gadgetParams view params for the gadget.
+ * @param {Object} renderParams render parameters, including the view.
+ * @param {function(Object)=} opt_callback Callback after gadget is loaded.
*/
shindig.container.Container.prototype.navigateGadget = function(
site, gadgetUrl, gadgetParams, renderParams, opt_callback) {
+ var callback = opt_callback || function() {};
if (this.renderDebug_) {
renderParams['nocache'] = true;
renderParams['debug'] = true;
@@ -145,26 +142,24 @@ shindig.container.Container.prototype.na
if (this.renderTest_) {
renderParams['testmode'] = true;
}
+
var self = this;
- var callback = function(response) {
+ // TODO: Lifecycle, add ability for current gadget to cancel nav.
+ site.navigateTo(gadgetUrl, gadgetParams, renderParams, function(response) {
// TODO: Navigate to error screen on primary gadget load failure
// TODO: Should display error without doing a standard navigate.
// TODO: Bad if the error gadget fails to load.
if (!response.error) {
self.scheduleRefreshTokens_();
}
- if (opt_callback) {
- opt_callback(response);
- }
- };
- // TODO: Lifecycle, add ability for current gadget to cancel nav.
- site.navigateTo(gadgetUrl, gadgetParams, renderParams, callback);
+ callback(response);
+ });
};
/**
* Called when gadget is closed. This may stop refreshing of tokens.
- * @param {shindig.container.GadgetSite} site the site where navigation
occurred.
+ * @param {shindig.container.GadgetSite} site navigate gadget to close.
*/
shindig.container.Container.prototype.closeGadget = function(site) {
var id = site.getId();
@@ -192,10 +187,8 @@ shindig.container.Container.prototype.pr
var self = this;
this.service_.getGadgetMetadata(metadataRequest, function(response) {
if (!response.error) {
- var data = response.data;
- var ids = shindig.container.util.toArrayOfJsonKeys(data);
- for (var i = 0; i < ids.length; i++) {
- self.addPreloadedGadgetUrl_(ids[i]);
+ for (var id in response) {
+ self.addPreloadedGadgetUrl_(id);
}
self.scheduleRefreshTokens_();
}
@@ -226,10 +219,9 @@ shindig.container.ContainerConfig = {};
shindig.container.ContainerConfig.RENDER_DEBUG = 'renderDebug';
// Whether test mode is turned on.
shindig.container.ContainerConfig.RENDER_TEST = 'renderTest';
-// Toggle to render gadgets in the same domain.
-shindig.container.ContainerConfig.SAME_DOMAIN = 'sameDomain';
// Security token refresh interval (in ms) for debugging.
-shindig.container.ContainerConfig.TOKEN_REFRESH_INTERVAL =
'tokenRefreshInterval';
+shindig.container.ContainerConfig.TOKEN_REFRESH_INTERVAL =
+ 'tokenRefreshInterval';
/**
@@ -312,7 +304,8 @@ shindig.container.Container.prototype.re
* @param {string} gadgetUrl URL of preloaded gadget.
* @private
*/
-shindig.container.Container.prototype.addPreloadedGadgetUrl_ =
function(gadgetUrl) {
+shindig.container.Container.prototype.addPreloadedGadgetUrl_ = function(
+ gadgetUrl) {
this.preloadedGadgetUrls_[gadgetUrl] = null;
};
@@ -323,7 +316,8 @@ shindig.container.Container.prototype.ad
* @return {Array} An array of URLs of gadgets.
* @private
*/
-shindig.container.Container.prototype.getTokenRefreshableGadgetUrls_ =
function() {
+shindig.container.Container.prototype.getTokenRefreshableGadgetUrls_ =
+ function() {
// Uses a JSON to ensure uniqueness. Collect all preloaded gadget URLs.
var result = shindig.container.util.mergeJsons({},
this.preloadedGadgetUrls_);
@@ -352,16 +346,15 @@ shindig.container.Container.prototype.re
};
var self = this;
- osapi.gadgets.getToken(request, function(response) {
+ this.service_.getGadgetToken(request, function(response) {
if (!response.error) {
// Update current (visible) gadgets with new tokens (already stored in
// cache). Do not need to update pre-loaded gadgets, since new tokens
will
// take effect when they are navigated to.
- var data = response.data;
for (var key in self.sites_) {
var holder = self.sites_[key].getActiveGadget();
if (holder) {
- var token = data[holder.getUrl()]['token'];
+ var token = response[holder.getUrl()]['token'];
gadgets.rpc.call(holder.getIframeId(), 'update_security_token', null,
token);
}
Modified:
shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js
URL:
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js?rev=956739&r1=956738&r2=956739&view=diff
==============================================================================
---
shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js
(original)
+++
shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js
Mon Jun 21 23:43:49 2010
@@ -16,10 +16,12 @@
* specific language governing permissions and limitations under the License.
*/
+
/**
* @fileoverview This represents an HTML element and the associated gadget.
*/
+
/**
* @param {number} siteId The id of site containing this holder.
* @param {Element} el The element to render gadgets in.
@@ -179,10 +181,13 @@ shindig.container.GadgetHolder.prototype
* Render a gadget into the element.
* @param {Object} gadgetInfo the JSON gadget description.
* @param {Object} gadgetParams View parameters for the gadget.
- * @param {Object} renderParams Render parameters for the gadget, including:
view, width, height.
+ * @param {Object} renderParams Render parameters for the gadget, including:
+ * view, width, height.
*/
-shindig.container.GadgetHolder.prototype.render = function(gadgetInfo,
gadgetParams, renderParams) {
- this.iframeId_ = shindig.container.GadgetHolder.IFRAME_ID_PREFIX_ +
this.siteId_;
+shindig.container.GadgetHolder.prototype.render = function(
+ gadgetInfo, gadgetParams, renderParams) {
+ this.iframeId_ = shindig.container.GadgetHolder.IFRAME_ID_PREFIX_
+ + this.siteId_;
this.gadgetInfo_ = gadgetInfo;
this.gadgetParams_ = gadgetParams;
this.hasGadgetParams_ = false;
@@ -306,7 +311,8 @@ shindig.container.GadgetHolder.prototype
* @return {string} The URL with param append to.
* @private
*/
-shindig.container.GadgetHolder.prototype.updateBooleanParam_ = function(uri,
param) {
+shindig.container.GadgetHolder.prototype.updateBooleanParam_
+ = function(uri, param) {
if (this.renderParams_[param]) {
uri = this.addQueryParam_(uri, param, "1");
}
@@ -362,7 +368,8 @@ shindig.container.GadgetHolder.prototype
* @return {string} The new URI.
* @private
*/
-shindig.container.GadgetHolder.prototype.addHashParam_ = function(uri, key,
value) {
+shindig.container.GadgetHolder.prototype.addHashParam_ = function(
+ uri, key, value) {
return uri + ((uri.indexOf('#') == -1) ? '#' : '&') + key + '=' + value;
};
@@ -375,7 +382,8 @@ shindig.container.GadgetHolder.prototype
* @return {string} The new URI.
* @private
*/
-shindig.container.GadgetHolder.prototype.addQueryParam_ = function(uri, key,
value) {
+shindig.container.GadgetHolder.prototype.addQueryParam_ = function(
+ uri, key, value) {
var hasQuery = uri.indexOf('?') != -1;
var insertPos = (uri.indexOf('#') != -1) ? uri.indexOf('#') : uri.length;
return uri.substring(0, insertPos) + (hasQuery ? '&' : '?') +
Modified:
shindig/trunk/features/src/main/javascript/features/container/gadget_site.js
URL:
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/gadget_site.js?rev=956739&r1=956738&r2=956739&view=diff
==============================================================================
---
shindig/trunk/features/src/main/javascript/features/container/gadget_site.js
(original)
+++
shindig/trunk/features/src/main/javascript/features/container/gadget_site.js
Mon Jun 21 23:43:49 2010
@@ -16,6 +16,7 @@
* specific language governing permissions and limitations under the License.
*/
+
/**
* @fileoverview This manages rendering of gadgets in a place holder, within an
* HTML element in the container. The API for this is low-level. Use the
@@ -198,12 +199,12 @@ shindig.container.GadgetSite.prototype.g
* @param {function(Object)=} opt_callback Function called with gadget info
after
* navigation has occurred.
*/
-shindig.container.GadgetSite.prototype.navigateTo = function(gadgetUrl,
gadgetParams,
- renderParams, opt_callback) {
+shindig.container.GadgetSite.prototype.navigateTo = function(
+ gadgetUrl, gadgetParams, renderParams, opt_callback) {
var callback = opt_callback || function() {};
- var gadgetInfo = osapi.gadgets.getCachedMetadataInfo(gadgetUrl);
-
+
// If metadata has been loaded/cached.
+ var gadgetInfo = this.service_.getCachedGadgetMetadata(gadgetUrl);
if (gadgetInfo) {
this.render(gadgetInfo, gadgetParams, renderParams);
callback(gadgetInfo);
@@ -217,9 +218,10 @@ shindig.container.GadgetSite.prototype.n
var self = this;
this.service_.getGadgetMetadata(request, function(response) {
if (!response.error) {
- var data = response.data;
- var gadgetInfo = data[gadgetUrl];
+ var gadgetInfo = response[gadgetUrl];
self.render(gadgetInfo, gadgetParams, renderParams);
+ callback(gadgetInfo);
+ } else {
callback(response);
}
});
@@ -234,8 +236,8 @@ shindig.container.GadgetSite.prototype.n
* @param {Object} renderParams. Render parameters for the gadget, including:
* view, width, height.
*/
-shindig.container.GadgetSite.prototype.render = function(gadgetInfo,
gadgetParams,
- renderParams) {
+shindig.container.GadgetSite.prototype.render = function(
+ gadgetInfo, gadgetParams, renderParams) {
var curUrl = this.curGadget_ ? this.curGadget_.getUrl() : null;
var previousView = null;
@@ -290,7 +292,8 @@ shindig.container.GadgetSite.prototype.r
* @param {function(Object)} callback Function to call upon RPC completion.
* @param {...number} var_args payload to pass to the recipient.
*/
-shindig.container.GadgetSite.prototype.rpcCall = function(serviceName,
callback, var_args) {
+shindig.container.GadgetSite.prototype.rpcCall = function(
+ serviceName, callback, var_args) {
if (this.curGadget_) {
gadgets.rpc.call(this.curGadget_.getIframeId(), serviceName, callback,
var_args);
}
@@ -306,7 +309,7 @@ shindig.container.GadgetSite.prototype.r
*/
shindig.container.GadgetSite.prototype.updateSecurityToken_
= function(gadgetInfo, renderParams) {
- var tokenInfo = osapi.gadgets.getCachedTokenInfo(gadgetInfo['url']);
+ var tokenInfo = this.service_.getCachedGadgetToken(gadgetInfo['url']);
if (tokenInfo) {
var token = tokenInfo['token'];
this.loadingGadget_.setSecurityToken(token);
Modified: shindig/trunk/features/src/main/javascript/features/container/init.js
URL:
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/init.js?rev=956739&r1=956738&r2=956739&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/init.js
(original)
+++ shindig/trunk/features/src/main/javascript/features/container/init.js Mon
Jun 21 23:43:49 2010
@@ -16,6 +16,7 @@
* specific language governing permissions and limitations under the License.
*/
+
/**
* @fileoverview Initial configuration/boot-strapping work for common container
* to operate. This includes setting up gadgets config and global environment
@@ -23,15 +24,18 @@
*/
(function() {
- function initializeGadgetsConfig() {
+ function initializeConfig() {
gadgets.config.init({
- 'rpc': {
- parentRelayUrl: ''
- },
- 'core.io': {
- jsonProxyUrl: 'http://%host%/gadgets/makeRequest',
- proxyUrl:
'http://%host%/gadgets/proxy?refresh=%refresh%&container=%container%%rewriteMime%&gadget=%gadget%/%rawurl%'
- }
+ 'rpc': {
+ parentRelayUrl: ''
+ },
+ 'core.io': {
+ jsonProxyUrl: 'http://%host%/gadgets/makeRequest',
+ proxyUrl: 'http://%host%/gadgets/proxy' +
+ '?refresh=%refresh%' +
+ '&container=%container%%rewriteMime%' +
+ '&gadget=%gadget%/%rawurl%'
+ }
});
}
@@ -55,6 +59,6 @@
: null;
}
- initializeGadgetsConfig();
+ initializeConfig();
initializeGlobalVars();
})();
Modified:
shindig/trunk/features/src/main/javascript/features/container/service.js
URL:
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/service.js?rev=956739&r1=956738&r2=956739&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/service.js
(original)
+++ shindig/trunk/features/src/main/javascript/features/container/service.js
Mon Jun 21 23:43:49 2010
@@ -16,6 +16,7 @@
* specific language governing permissions and limitations under the License.
*/
+
/**
* @fileoverview This represents the service layer that talks to OSAPI
* endpoints. All RPC requests should go into this class.
@@ -23,17 +24,50 @@
/**
- * @param {Object=} opt_config. Configuration JSON.
+ * @param {Object=} opt_config Configuration JSON.
* @constructor
*/
shindig.container.Service = function(opt_config) {
var config = opt_config || {};
/**
+ * @type {string}
+ */
+ this.apiHost_ = String(google.container.util.getSafeJsonValue(config,
+ shindig.container.ServiceConfig.API_HOST, window.__API_HOST));
+
+ /**
+ * @type {string}
+ */
+ this.apiPrefixPath_ = String(google.container.util.getSafeJsonValue(config,
+ shindig.container.ServiceConfig.API_PREFIX_PATH,
+ window.__API_PREFIX_PATH));
+
+ /**
+ * @type {string}
+ */
+ this.apiPath_ = String(google.container.util.getSafeJsonValue(config,
+ shindig.container.ServiceConfig.API_PATH, '/api/rpc/cs'));
+
+ /**
* @type {boolean}
*/
this.sameDomain_ = Boolean(shindig.container.util.getSafeJsonValue(config,
- shindig.container.ServiceConfig.SAME_DOMAIN, true));
+ shindig.container.ServiceConfig.SAME_DOMAIN, false));
+
+ /**
+ * Map of gadget URLs to cached gadgetInfo response.
+ * @type {Object}
+ */
+ this.cachedMetadatas_ = {};
+
+ /**
+ * Map of gadget URLs to cached tokenInfo response.
+ * @type {Object}
+ */
+ this.cachedTokens_ = {};
+
+ this.initializeOsapi_();
this.onConstructed(config);
};
@@ -57,21 +91,45 @@ shindig.container.Service.prototype.onCo
*/
shindig.container.Service.prototype.getGadgetMetadata = function(
request, opt_callback) {
- var callback = opt_callback || function(a) {};
+ var callback = opt_callback || function() {};
var self = this;
- osapi.gadgets.getMetadata(request, function(response) {
+ osapi.gadgets.metadata.get(request).execute(function(response) {
if (response.error) {
- // This hides internal server error.
+ // Hides internal server error.
callback({
- error : 'Failed to retrieve gadget.',
+ error : 'Failed to retrieve gadget metadata.',
errorCode : 'NOLOAD'
});
} else {
- var data = response.data;
- var gadgetUrls = shindig.container.util.toArrayOfJsonKeys(data);
- for (var i = 0; i < gadgetUrls.length; i++) {
- var gadgetInfo = data[gadgetUrls[i]];
+ for (var id in response) {
+ var gadgetInfo = response[id];
self.processSameDomain_(gadgetInfo);
+ self.cachedMetadatas_[id] = gadgetInfo;
+ }
+ callback(response);
+ }
+ });
+};
+
+
+/**
+ * @param {Object} request JSON object representing the request.
+ * @param {function(Object)=} opt_callback function to call upon data receive.
+ */
+shindig.container.Service.prototype.getGadgetToken = function(
+ request, opt_callback) {
+ var callback = opt_callback || function() {};
+ var self = this;
+ osapi.gadgets.token.get(request).execute(function(response) {
+ if (response.error) {
+ // Hides internal server error.
+ callback({
+ error : 'Failed to retrieve gadget token.',
+ errorCode : 'NOLOAD'
+ });
+ } else {
+ for (var id in response) {
+ self.cachedTokens_[id] = response[id];
}
callback(response);
}
@@ -80,11 +138,55 @@ shindig.container.Service.prototype.getG
/**
+ * @param {string} url gadget URL to use as key to get cached metadata.
+ * @return {string} the gadgetInfo referenced by this URL.
+ */
+shindig.container.Service.prototype.getCachedGadgetMetadata = function(url) {
+ return this.cachedMetadatas_[url];
+};
+
+
+/**
+ * @param {string} url gadget URL to use as key to get cached token.
+ * @return {string} the tokenInfo referenced by this URL.
+ */
+shindig.container.Service.prototype.getCachedGadgetToken = function(url) {
+ return this.cachedTokens_[url];
+};
+
+
+/**
* @param {Object} gadgetInfo
* @private
*/
shindig.container.Service.prototype.processSameDomain_ = function(gadgetInfo) {
- gadgetInfo['sameDomain'] = this.sameDomain_;
+ if (this.sameDomain_ && gadgetInfo['sameDomain']) {
+ var views = gadgetInfo['views'] || {};
+ for (var view in views) {
+ views[view]['iframeHost'] = this.apiHost_;
+ }
+ }
+};
+
+
+/**
+ * Initialize OSAPI endpoint methods/interfaces.
+ * @private
+ */
+shindig.container.Service.prototype.initializeOsapi_ = function() {
+ var endPoint = this.apiHost_ + this.apiPrefixPath_ + this.apiPath_;
+
+ var osapiServicesConfig = {};
+ osapiServicesConfig['gadgets.rpc'] = [ 'container.listMethods' ];
+ osapiServicesConfig[endPoint] = [
+ 'gadgets.metadata.get',
+ 'gadgets.token.get'
+ ];
+
+ gadgets.config.init({
+ 'osapi': { 'endPoints': [ endPoint ] },
+ 'osapi.services': osapiServicesConfig
+ });
};
@@ -92,13 +194,18 @@ shindig.container.Service.prototype.proc
// Configuration
//
-----------------------------------------------------------------------------
+
/**
* Enumeration of configuration keys for this service. This is specified in
* JSON to provide extensible configuration.
* @enum {string}
*/
shindig.container.ServiceConfig = {};
-
-//Toggle to render gadgets in the same domain.
-/** @type {string} */
+//Host to fetch gadget information, via XHR.
+shindig.container.ServiceConfig.API_HOST = 'apiHost';
+// Prefix to path to fetch gadget information, via XHR.
+shindig.container.ServiceConfig.API_PREFIX_PATH = 'apiPrefixPath';
+// Path (appears after API_PREFIX_PATH) to fetch gadget information, via XHR.
+shindig.container.ServiceConfig.API_PATH = 'apiPath';
+// Toggle to render gadgets in the same domain.
shindig.container.ServiceConfig.SAME_DOMAIN = 'sameDomain';
Modified: shindig/trunk/features/src/main/javascript/features/container/util.js
URL:
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/util.js?rev=956739&r1=956738&r2=956739&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/util.js
(original)
+++ shindig/trunk/features/src/main/javascript/features/container/util.js Mon
Jun 21 23:43:49 2010
@@ -16,15 +16,18 @@
* specific language governing permissions and limitations under the License.
*/
+
/**
- * @fileoverview Utility methods common container.
+ * @fileoverview Utility methods for common container.
*/
+
/**
* @type {Object}
*/
shindig.container = {};
+
/**
* @type {Object}
*/
@@ -61,6 +64,7 @@ shindig.container.util.parsePrefixPath =
return path;
};
+
/**
* Extract path of a URL.
* @param {string} uri The URL to extract path from.
@@ -127,20 +131,3 @@ shindig.container.util.toArrayOfJsonKeys
}
return result;
};
-
-
-// TODO unused?
-/**
- * Count the number of own/self properties in json.
- * @param {Object} json the JSON to act on.
- * @return {number} Number of elements in json.
- */
-shindig.container.util.countProperties = function(json) {
- var count = 0;
- for (var key in json) {
- if (json.hasOwnProperty(key)) {
- count++;
- }
- }
- return count;
-};