Author: mhermanto Date: Mon Sep 13 19:58:45 2010 New Revision: 996670 URL: http://svn.apache.org/viewvc?rev=996670&view=rev Log: Common container updates -- - Reduce the response size, by filtering the fields needed. - Prioritize initial iframe size to: requested size, view-specified size, moduleprefs-specified size, default. - Allow disabling of security token update by setting it to -1. - gadgets.rpc.call to update_security_token now only work if there is 1+ gadgets receiving it. This avoids warning of rpc service not found. - Make most (not all yet) JSON keys constants.
http://codereview.appspot.com/2130041/ Added: shindig/trunk/features/src/main/javascript/features/container/constant.js Modified: shindig/trunk/features/src/main/javascript/features/container/container.js shindig/trunk/features/src/main/javascript/features/container/feature.xml 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/service.js shindig/trunk/features/src/main/javascript/features/container/util.js shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java Added: shindig/trunk/features/src/main/javascript/features/container/constant.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/constant.js?rev=996670&view=auto ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/constant.js (added) +++ shindig/trunk/features/src/main/javascript/features/container/constant.js Mon Sep 13 19:58:45 2010 @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + + +/** + * @fileoverview Constants used throughout common container. + */ + + +/** + * Set up namespace. + * @type {Object} + */ +shindig.container = {}; + + +/** + * Constants to key into gadget metadata response JSON. + * @enum {string} + */ +shindig.container.MetadataResponse = {}; +shindig.container.MetadataResponse.IFRAME_URL = 'iframeUrl'; +shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH = 'needsTokenRefresh'; +shindig.container.MetadataResponse.VIEWS = 'views'; +shindig.container.MetadataResponse.FEATURES = 'features'; +shindig.container.MetadataResponse.HEIGHT = 'height'; +shindig.container.MetadataResponse.MODULE_PREFS = 'modulePrefs'; +shindig.container.MetadataResponse.PREFERRED_HEIGHT = 'preferredHeight'; +shindig.container.MetadataResponse.PREFERRED_WIDTH = 'preferredWidth'; +shindig.container.MetadataResponse.WIDTH = 'width'; + + +/** + * Constants to key into gadget token response JSON. + * @enum {string} + */ +shindig.container.TokenResponse = {}; +shindig.container.TokenResponse.TOKEN = 'token'; + + +/** + * Constants to key into request renderParam JSON. + * @enum {string} + */ +shindig.container.RenderParam = {}; +shindig.container.RenderParam.CLASS = 'class'; +shindig.container.RenderParam.DEBUG = 'debug'; +shindig.container.RenderParam.HEIGHT = 'height'; +shindig.container.RenderParam.NO_CACHE = 'nocache'; +shindig.container.RenderParam.TEST_MODE = 'testmode'; +shindig.container.RenderParam.USER_PREFS = 'userPrefs'; +shindig.container.RenderParam.VIEW = 'view'; +shindig.container.RenderParam.WIDTH = 'width'; + +/** + * Constants to key into request viewParam JSON. + * @enum {string} + */ +shindig.container.ViewParam = {}; +shindig.container.ViewParam.VIEW = 'view'; 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=996670&r1=996669&r2=996670&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/container.js (original) +++ shindig/trunk/features/src/main/javascript/features/container/container.js Mon Sep 13 19:58:45 2010 @@ -138,12 +138,12 @@ shindig.container.Container.prototype.ge * * @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} viewParams 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) { + site, gadgetUrl, viewParams, renderParams, opt_callback) { var callback = opt_callback || function() {}; if (this.renderDebug_) { renderParams['nocache'] = true; @@ -155,14 +155,14 @@ shindig.container.Container.prototype.na var self = this; // TODO: Lifecycle, add ability for current gadget to cancel nav. - site.navigateTo(gadgetUrl, gadgetParams, renderParams, function(response) { + site.navigateTo(gadgetUrl, viewParams, renderParams, function(gadgetInfo) { // 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) { + if (gadgetInfo[shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) { self.scheduleRefreshTokens_(); } - callback(response); + callback(gadgetInfo); }); }; @@ -195,17 +195,17 @@ shindig.container.Container.prototype.pr * @param {Array} gadgetUrls gadgets URIs to preload. */ shindig.container.Container.prototype.preloadGadgets = function(gadgetUrls) { - var request = { - 'container' : window.__CONTAINER, - 'ids' : gadgetUrls - }; + var request = shindig.container.util.newMetadataRequest(gadgetUrls); var self = this; this.service_.getGadgetMetadata(request, function(response) { if (!response.error) { for (var id in response) { self.addPreloadedGadgetUrl_(id); + if (response[id][shindig.container.MetadatResponse.NEEDS_TOKEN_REFRESH]) { + // Safe to re-schedule many times. + self.scheduleRefreshTokens_(); + } } - self.scheduleRefreshTokens_(); } }); }; @@ -218,10 +218,7 @@ shindig.container.Container.prototype.pr */ shindig.container.Container.prototype.getGadgetMetadata = function( gadgetUrl, callback) { - var request = { - 'container' : window.__CONTAINER, - 'ids' : [ gadgetUrl ] - }; + var request = shindig.container.util.newMetadataRequest([gadgetUrl]); this.service_.getGadgetMetadata(request, callback); }; @@ -293,7 +290,7 @@ shindig.container.Container.prototype.sc // token in all preloaded- and navigated-to- gadgets. This should be obtained // from the server. For now, constant on 50% of long-lived tokens (1 hour), // which is 30 minutes. - if (!this.tokenRefreshTimer_) { + if (this.isRefreshTokensEnabled_() && !this.tokenRefreshTimer_) { var self = this; this.tokenRefreshTimer_ = window.setInterval(function() { self.refreshTokens_(); @@ -318,6 +315,19 @@ shindig.container.Container.prototype.un /** + * Provides a manual override to disable token refresh to avoid gadgets.rpc + * warning of service not found. We can do better to detect if token refresh is + * even necessary, by inspecting the gadget transitively depend on + * feature=security-token. + * @return {Boolean} if token refresh interval is of valid value. + * @private + */ +shindig.container.Container.prototype.isRefreshTokensEnabled_ = function() { + return this.tokenRefreshInterval_ > 0; +}; + + +/** * Register standard RPC services * @private */ @@ -351,14 +361,23 @@ shindig.container.Container.prototype.ad */ 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_); + var result = {}; + + // Collect preloaded gadget urls. + for (var url in this.preloadedGadgetUrls_) { + var metadata = this.service_.getCachedGadgetMetadata(url); + if (metadata[shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) { + result[url] = null; + } + } - // Collect all current gadget URLs. + // Collect active gadget urls. for (var siteIndex in this.sites_) { - var holder = this.sites_[siteIndex].getActiveGadget(); - if (holder) { - result[holder.getUrl()] = null; + var holder = this.sites_[siteIndex].getActiveGadgetHolder(); + var url = holder.getUrl(); + var metadata = this.service_.getCachedGadgetMetadata(url); + if (metadata[shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) { + result[url] = null; } } @@ -366,6 +385,7 @@ shindig.container.Container.prototype.ge }; + /** * Refresh security tokens immediately. This will fetch gadget metadata, along * with its token and have the token cache updated. @@ -373,23 +393,20 @@ shindig.container.Container.prototype.ge */ shindig.container.Container.prototype.refreshTokens_ = function() { var ids = this.getTokenRefreshableGadgetUrls_(); - var request = { - 'container' : window.__CONTAINER, - 'ids' : ids - }; + var request = shindig.container.util.newTokenRequest(ids); var self = this; 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. + // Update active token-requiring gadgets with new tokens. Do not need to + // update pre-loaded gadgets, since new tokens will take effect when they + // are navigated to, from cache. for (var key in self.sites_) { - var holder = self.sites_[key].getActiveGadget(); - if (holder) { - var token = response[holder.getUrl()]['token']; + var holder = self.sites_[key].getActiveGadgetHolder(); + var gadgetInfo = self.service_.getCachedGadgetMetadata(holder.getUrl()); + if (gadgetInfo[shindig.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) { gadgets.rpc.call(holder.getIframeId(), 'update_security_token', null, - token); + response[holder.getUrl()][shindig.container.TokenResponse.TOKEN]); } } } Modified: shindig/trunk/features/src/main/javascript/features/container/feature.xml URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/feature.xml?rev=996670&r1=996669&r2=996670&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/feature.xml (original) +++ shindig/trunk/features/src/main/javascript/features/container/feature.xml Mon Sep 13 19:58:45 2010 @@ -27,6 +27,7 @@ under the License. <dependency>osapi</dependency> <dependency>rpc</dependency> <container> + <script src="constant.js"/> <script src="util.js"/> <script src="service.js"/> <script src="gadget_holder.js"/> 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=996670&r1=996669&r2=996670&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 Sep 13 19:58:45 2010 @@ -54,14 +54,7 @@ shindig.container.GadgetHolder = functio * @type {Object?} * @private */ - this.gadgetParams_ = null; - - /** - * Whether there are any view parameters. - * @type {boolean} - * @private - */ - this.hasGadgetParams_ = false; + this.viewParams_ = null; /** * Gadget rendering parameters @@ -78,13 +71,6 @@ shindig.container.GadgetHolder = functio this.iframeId_ = null; /** - * Name of current view being rendered. - * @type {string?} - * @private - */ - this.view_ = null; - - /** * A dynamically set social/security token. * Social tokens are sent with original view URLs but may need * to be refreshed for long lived gadgets. @@ -148,7 +134,7 @@ shindig.container.GadgetHolder.prototype * @return {string|null} The view of current gadget. */ shindig.container.GadgetHolder.prototype.getView = function() { - return this.view_; + return this.renderParams_[shindig.container.RenderParam.VIEW]; }; @@ -173,24 +159,18 @@ 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} viewParams View parameters for the gadget. * @param {Object} renderParams Render parameters for the gadget, including: * view, width, height. */ shindig.container.GadgetHolder.prototype.render = function( - gadgetInfo, gadgetParams, renderParams) { + gadgetInfo, viewParams, renderParams) { this.iframeId_ = shindig.container.GadgetHolder.IFRAME_ID_PREFIX_ + this.siteId_; this.gadgetInfo_ = gadgetInfo; - this.gadgetParams_ = gadgetParams; - this.hasGadgetParams_ = false; - for (var key in this.gadgetParams_) { - this.hasGadgetParams_ = true; - break; - } + this.viewParams_ = viewParams; this.renderParams_ = renderParams; - this.view_ = renderParams['view']; - if (!this.gadgetInfo_['views'][this.view_]) { + if (!this.gadgetInfo_[shindig.container.MetadataResponse.VIEWS][this.getView()]) { throw 'View ' + this.view_ + ' unsupported in ' + this.gadgetInfo_['url']; } @@ -198,7 +178,8 @@ shindig.container.GadgetHolder.prototype // Set up RPC channel. RPC relay url is on gmodules, relative to base of the // container. Assumes container has set up forwarding to gmodules at /gadgets. - var iframeUri = shindig.uri(this.gadgetInfo_['iframeUrl']); + var iframeUri = shindig.uri( + this.gadgetInfo_[shindig.container.MetadataResponse.IFRAME_URL]); var relayUri = shindig.uri() .setSchema(iframeUri.getSchema()) .setAuthority(iframeUri.getAuthority()) @@ -237,9 +218,9 @@ shindig.container.GadgetHolder.prototype 'frameborder': '0', 'vspace': '0', 'hspace': '0', - 'class': this.renderParams_['class'], - 'height': this.renderParams_['height'], - 'width': this.renderParams_['width'] + 'class': this.renderParams_[shindig.container.RenderParam.CLASS], + 'height': this.renderParams_[shindig.container.RenderParam.HEIGHT], + 'width': this.renderParams_[shindig.container.RenderParam.WIDTH] }; // Do not use DOM API (createElement(), setAttribute()), since it is slower, @@ -265,11 +246,11 @@ shindig.container.GadgetHolder.prototype * @private */ shindig.container.GadgetHolder.prototype.getIframeUrl_ = function() { - var uri = shindig.uri(this.gadgetInfo_['iframeUrl']); - uri.setQP('debug', this.renderParams_['debug'] ? '1' : '0'); - uri.setQP('nocache', this.renderParams_['nocache'] ? '1' : '0'); - uri.setQP('testmode', this.renderParams_['testmode'] ? '1' : '0'); - uri.setQP('view', this.view_); + var uri = shindig.uri(this.gadgetInfo_[shindig.container.MetadataResponse.IFRAME_URL]); + uri.setQP('debug', this.renderParams_[shindig.container.RenderParam.DEBUG] ? '1' : '0'); + uri.setQP('nocache', this.renderParams_[shindig.container.RenderParam.NO_CACHE] ? '1' : '0'); + uri.setQP('testmode', this.renderParams_[shindig.container.RenderParam.TEST_MODE] ? '1' : '0'); + uri.setQP('view', this.getView()); this.updateUserPrefParams_(uri); // TODO: Share this base container logic @@ -284,8 +265,8 @@ shindig.container.GadgetHolder.prototype uri.setFP('mid', String(this.siteId_)); - if (this.hasGadgetParams_) { - var gadgetParamText = gadgets.json.stringify(this.gadgetParams_); + if (this.hasViewParams_()) { + var gadgetParamText = gadgets.json.stringify(this.viewParams_); uri.setFP('view-params', gadgetParamText); } @@ -303,7 +284,7 @@ shindig.container.GadgetHolder.prototype * @private */ shindig.container.GadgetHolder.prototype.updateUserPrefParams_ = function(uri) { - var userPrefs = this.renderParams_['userPrefs']; + var userPrefs = this.renderParams_[shindig.container.RenderParam.USER_PREFS]; if (userPrefs) { for (var up in userPrefs) { var upKey = 'up_' + up; @@ -315,3 +296,16 @@ shindig.container.GadgetHolder.prototype } } }; + + +/** + * Return true if this has view parameters. + * @private + * @return {Boolean} + */ +shindig.container.GadgetHolder.prototype.hasViewParams_ = function() { + for (var key in this.viewParams_) { + return true; + } + return false; +}; 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=996670&r1=996669&r2=996670&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 Sep 13 19:58:45 2010 @@ -43,7 +43,7 @@ shindig.container.GadgetSite = function( * @type {Element} * @private */ - this.curGadgetEl_ = gadgetEl; + this.currentGadgetEl_ = gadgetEl; /** * Element holding the loading gadget for 2x buffering. @@ -71,14 +71,14 @@ shindig.container.GadgetSite = function( * @type {shindig.container.GadgetHolder?} * @private */ - this.curGadget_ = null; + this.currentGadgetHolder_ = null; /** * Information about the currently loading gadget. * @type {shindig.container.GadgetHolder?} * @private */ - this.loadingGadget_ = null; + this.loadingGadgetHolder_ = null; this.onConstructed(); }; @@ -97,9 +97,9 @@ shindig.container.GadgetSite.prototype.o * @return {shindig.container.GadgetSite} This instance. */ shindig.container.GadgetSite.prototype.setHeight = function(value) { - var activeGadget = this.getActiveGadget(); - if (activeGadget) { - var iframeEl = activeGadget.getIframeElement(); + var holder = this.getActiveGadgetHolder(); + if (holder) { + var iframeEl = holder.getIframeElement(); if (iframeEl) { iframeEl.style.height = value + 'px'; } @@ -114,9 +114,9 @@ shindig.container.GadgetSite.prototype.s * @return {shindig.container.GadgetSite} This instance. */ shindig.container.GadgetSite.prototype.setWidth = function(value) { - var activeGadget = this.getActiveGadget(); - if (activeGadget) { - var iframeEl = activeGadget.getIframeElement(); + var holder = this.getActiveGadgetHolder(); + if (holder) { + var iframeEl = holder.getIframeElement(); if (iframeEl) { iframeEl.style.width = value + 'px'; } @@ -148,8 +148,8 @@ shindig.container.GadgetSite.prototype.g * loading, or the currently visible gadget. * @return {shindig.container.GadgetHolder} The gadget holder. */ -shindig.container.GadgetSite.prototype.getActiveGadget = function() { - return this.loadingGadget_ || this.curGadget_; +shindig.container.GadgetSite.prototype.getActiveGadgetHolder = function() { + return this.loadingGadgetHolder_ || this.currentGadgetHolder_; }; @@ -161,8 +161,9 @@ shindig.container.GadgetSite.prototype.g * @return {Object} JSON representing the feature. */ shindig.container.GadgetSite.prototype.getFeature = function(name, opt_gadgetInfo) { - var gadgetInfo = opt_gadgetInfo || this.getActiveGadget().getGadgetInfo(); - return gadgetInfo['features'] && gadgetInfo['features'][name]; + var gadgetInfo = opt_gadgetInfo || this.getActiveGadgetHolder().getGadgetInfo(); + return gadgetInfo[shindig.container.MetadataResponse.FEATURES] && + gadgetInfo[shindig.container.MetadataResponse.FEATURES][name]; }; @@ -172,11 +173,11 @@ shindig.container.GadgetSite.prototype.g * @return {shindig.container.GadgetHolder?} The gadget. Null, if not exist. */ shindig.container.GadgetSite.prototype.getGadgetHolder = function(id) { - if (this.curGadget_ && this.curGadget_.getIframeId() == id) { - return this.curGadget_; + if (this.currentGadgetHolder_ && this.currentGadgetHolder_.getIframeId() == id) { + return this.currentGadgetHolder_; } - if (this.loadingGadget_ && this.loadingGadget_.getIframeId() == id) { - return this.loadingGadget_; + if (this.loadingGadgetHolder_ && this.loadingGadgetHolder_.getIframeId() == id) { + return this.loadingGadgetHolder_; } return null; }; @@ -193,33 +194,30 @@ shindig.container.GadgetSite.prototype.g /** * Render a gadget in the site, by URI of the gadget XML. * @param {string} gadgetUrl The absolute URL to gadget. - * @param {Object} gadgetParams View parameters for the gadget. + * @param {Object} viewParams View parameters for the gadget. * @param {Object} renderParams. Render parameters for the gadget, including: * view, width, height. * @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) { + gadgetUrl, viewParams, renderParams, opt_callback) { var callback = opt_callback || function() {}; // If metadata has been loaded/cached. var gadgetInfo = this.service_.getCachedGadgetMetadata(gadgetUrl); if (gadgetInfo) { - this.render(gadgetInfo, gadgetParams, renderParams); + this.render(gadgetInfo, viewParams, renderParams); callback(gadgetInfo); // Otherwise, fetch gadget metadata. } else { - var request = { - 'container': window.__CONTAINER, - 'ids': [ gadgetUrl ] - }; + var request = shindig.container.util.newMetadataRequest([gadgetUrl]); var self = this; this.service_.getGadgetMetadata(request, function(response) { if (!response.error) { var gadgetInfo = response[gadgetUrl]; - self.render(gadgetInfo, gadgetParams, renderParams); + self.render(gadgetInfo, viewParams, renderParams); callback(gadgetInfo); } else { callback(response); @@ -232,26 +230,28 @@ shindig.container.GadgetSite.prototype.n /** * Render a gadget in this site, using a JSON gadget description. * @param {Object} gadgetInfo the JSON gadget description. - * @param {Object} gadgetParams View parameters for the gadget. + * @param {Object} viewParams View parameters for the gadget. * @param {Object} renderParams. Render parameters for the gadget, including: * view, width, height. */ shindig.container.GadgetSite.prototype.render = function( - gadgetInfo, gadgetParams, renderParams) { - var curUrl = this.curGadget_ ? this.curGadget_.getUrl() : null; + gadgetInfo, viewParams, renderParams) { + var curUrl = this.currentGadgetHolder_ ? this.currentGadgetHolder_.getUrl() : null; var previousView = null; if (curUrl == gadgetInfo['url']) { - previousView = this.curGadget_.getView(); + previousView = this.currentGadgetHolder_.getView(); } // Load into the double-buffer if there is one - var el = this.loadingGadgetEl_ || this.curGadgetEl_; - this.loadingGadget_ = new shindig.container.GadgetHolder(this.id_, el); + var el = this.loadingGadgetEl_ || this.currentGadgetEl_; + this.loadingGadgetHolder_ = new shindig.container.GadgetHolder(this.id_, el); - var view = renderParams['view'] || gadgetParams['view'] || previousView + var view = renderParams[shindig.container.RenderParam.VIEW] + || viewParams[shindig.container.ViewParam.VIEW] + || previousView || 'default'; - var viewInfo = gadgetInfo['views'][view]; + var viewInfo = gadgetInfo[shindig.container.MetadataResponse.VIEWS][view]; var delayLoad = this.getFeature('loadstate', gadgetInfo) || this.getFeature('shell', gadgetInfo); @@ -263,17 +263,23 @@ shindig.container.GadgetSite.prototype.r // Delay load for now means we autosize. if (delayLoad) { - localRenderParams['height'] = '0'; + localRenderParams[shindig.container.RenderParam.HEIGHT] = '0'; } - localRenderParams['view'] = view; - localRenderParams['width'] = localRenderParams['width'] || - viewInfo['preferredWidth'] || null; - localRenderParams['height'] = localRenderParams['height'] || - viewInfo['preferredHeight'] || '150'; + localRenderParams[shindig.container.RenderParam.VIEW] = view; + localRenderParams[shindig.container.RenderParam.HEIGHT] + = renderParams[shindig.container.RenderParam.HEIGHT] + || viewInfo[shindig.container.MetadataResponse.PREFERRED_HEIGHT] + || gadgetInfo[shindig.container.MetadataResponse.MODULE_PREFS][shindig.container.MetadataResponse.HEIGHT] + || String(shindig.container.GadgetSite.DEFAULT_HEIGHT_); + localRenderParams[shindig.container.RenderParam.WIDTH] + = renderParams[shindig.container.RenderParam.WIDTH] + || viewInfo[shindig.container.MetadataResponse.PREFERRED_WIDTH] + || gadgetInfo[shindig.container.MetadataResponse.MODULE_PREFS][shindig.container.MetadataResponse.WIDTH] + || String(shindig.container.GadgetSite.DEFAULT_WIDTH_); this.updateSecurityToken_(gadgetInfo, localRenderParams); - this.loadingGadget_.render(gadgetInfo, gadgetParams, localRenderParams); + this.loadingGadgetHolder_.render(gadgetInfo, viewParams, localRenderParams); this.loaded_ = false; @@ -294,8 +300,9 @@ shindig.container.GadgetSite.prototype.r */ shindig.container.GadgetSite.prototype.rpcCall = function( serviceName, callback, var_args) { - if (this.curGadget_) { - gadgets.rpc.call(this.curGadget_.getIframeId(), serviceName, callback, var_args); + if (this.currentGadgetHolder_) { + gadgets.rpc.call(this.currentGadgetHolder_.getIframeId(), + serviceName, callback, var_args); } }; @@ -311,8 +318,8 @@ shindig.container.GadgetSite.prototype.u = function(gadgetInfo, renderParams) { var tokenInfo = this.service_.getCachedGadgetToken(gadgetInfo['url']); if (tokenInfo) { - var token = tokenInfo['token']; - this.loadingGadget_.setSecurityToken(token); + var token = tokenInfo[shindig.container.TokenResponse.TOKEN]; + this.loadingGadgetHolder_.setSecurityToken(token); } }; @@ -323,18 +330,17 @@ shindig.container.GadgetSite.prototype.u * for removal. */ shindig.container.GadgetSite.prototype.close = function() { - // Only remove the element (iframe) created by this, not by the container. - if (this.loadingGadgetEl_) { + if (this.loadingGadgetEl_ && this.loadingGadgetEl_.firstChild) { this.loadingGadgetEl_.removeChild(this.loadingGadgetEl_.firstChild); } - if (this.curGadgetEl_) { - this.curGadgetEl_.removeChild(this.curGadgetEl_.firstChild); + if (this.currentGadgetEl_ && this.currentGadgetEl_.firstChild) { + this.currentGadgetEl_.removeChild(this.currentGadgetEl_.firstChild); } - if (this.loadingGadget_) { - this.loadingGadget_.dispose(); + if (this.loadingGadgetHolder_) { + this.loadingGadgetHolder_.dispose(); } - if (this.curGadget_) { - this.curGadget_.dispose(); + if (this.currentGadgetHolder_) { + this.currentGadgetHolder_.dispose(); } }; @@ -366,7 +372,7 @@ shindig.container.GadgetSite.prototype.s shindig.container.GadgetSite.prototype.onload_ = function() { this.loaded_ = true; try { - gadgets.rpc.call(this.loadingGadget_.getIframeId(), 'onLoad', null); + gadgets.rpc.call(this.loadingGadgetHolder_.getIframeId(), 'onLoad', null); if (this.resizeOnLoad_) { // TODO need a value for setHeight this.setHeight(); @@ -378,12 +384,12 @@ shindig.container.GadgetSite.prototype.o this.swapBuffers_(); - if (this.curGadget_) { - this.curGadget_.dispose(); + if (this.currentGadgetHolder_) { + this.currentGadgetHolder_.dispose(); } - this.curGadget_ = this.loadingGadget_; - this.loadingGadget_ = null; + this.currentGadgetHolder_ = this.loadingGadgetHolder_; + this.loadingGadgetHolder_ = null; }; @@ -395,12 +401,30 @@ shindig.container.GadgetSite.prototype.s if (this.loadingGadgetEl_) { this.loadingGadgetEl_.style.left = ''; this.loadingGadgetEl_.style.position = ''; - this.curGadgetEl_.style.position = 'absolute'; - this.curGadgetEl_.style.left = '-2000px'; + this.currentGadgetEl_.style.position = 'absolute'; + this.currentGadgetEl_.style.left = '-2000px'; // Swap references; cur_ will now again be what's visible - var oldCur = this.curGadgetEl_; - this.curGadgetEl_ = this.loadingGadgetEl_; + var oldCur = this.currentGadgetEl_; + this.currentGadgetEl_ = this.loadingGadgetEl_; this.loadingGadgetEl_ = oldCur; } }; + + +/** + * Default height of gadget. Refer to -- + * http://code.google.com/apis/gadgets/docs/legacy/reference.html. + * @type {number} + * @private + */ +shindig.container.GadgetSite.DEFAULT_HEIGHT_ = 200; + + +/** + * Default width of gadget. Refer to -- + * http://code.google.com/apis/gadgets/docs/legacy/reference.html. + * @type {number} + * @private + */ +shindig.container.GadgetSite.DEFAULT_WIDTH_ = 320; 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=996670&r1=996669&r2=996670&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/service.js (original) +++ shindig/trunk/features/src/main/javascript/features/container/service.js Mon Sep 13 19:58:45 2010 @@ -43,12 +43,6 @@ shindig.container.Service = function(opt shindig.container.ServiceConfig.API_PATH, '/api/rpc/cs')); /** - * @type {boolean} - */ - this.sameDomain_ = Boolean(shindig.container.util.getSafeJsonValue(config, - shindig.container.ServiceConfig.SAME_DOMAIN, false)); - - /** * Map of gadget URLs to cached gadgetInfo response. * @type {Object} */ @@ -76,9 +70,8 @@ shindig.container.Service.prototype.onCo /** * Do an immediate fetch of gadgets metadata for gadgets in request.ids, for - * container request.container, with its results mutated by - * request.sameDomain and request.aspDomain. The appropriate optional - * callback opt_callback will be called, after a response is received. + * container request.container. The optional callback opt_callback will be + * called, after a response is received. * @param {Object} request JSON object representing the request. * @param {function(Object)=} opt_callback function to call upon data receive. */ @@ -96,7 +89,6 @@ shindig.container.Service.prototype.getG } else { for (var id in response) { var gadgetInfo = response[id]; - self.processSameDomain_(gadgetInfo); self.cachedMetadatas_[id] = gadgetInfo; } callback(response); @@ -149,20 +141,6 @@ shindig.container.Service.prototype.getC /** - * @param {Object} gadgetInfo - * @private - */ -shindig.container.Service.prototype.processSameDomain_ = function(gadgetInfo) { - 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 */ @@ -198,5 +176,3 @@ shindig.container.ServiceConfig = {}; shindig.container.ServiceConfig.API_HOST = 'apiHost'; // 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=996670&r1=996669&r2=996670&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/util.js (original) +++ shindig/trunk/features/src/main/javascript/features/container/util.js Mon Sep 13 19:58:45 2010 @@ -25,12 +25,6 @@ /** * @type {Object} */ -shindig.container = {}; - - -/** - * @type {Object} - */ shindig.container.util = {}; @@ -65,6 +59,47 @@ shindig.container.util.mergeJsons = func }; +shindig.container.util.cloneJson = function(json) { + +}; + +/** + * Construct a JSON request to get gadget metadata. For now, this will request + * a super-set of data needed for all CC APIs requiring gadget metadata, since + * the caching of response is not additive. + * @param {Array} A list of gadget URLs. + * @return {Object} the resulting JSON. + */ +shindig.container.util.newMetadataRequest = function(gadgetUrls) { + return { + 'container': window.__CONTAINER, + 'ids': gadgetUrls, + 'fields': [ + 'iframeUrl', + 'modulePrefs.*', + 'needsTokenRefresh', + 'userPrefs.*', + 'views.preferredHeight', + 'views.preferredWidth' + ] + }; +}; + + +/** + * Construct a JSON request to get gadget token. + * @param {Array} A list of gadget URLs. + * @return {Object} the resulting JSON. + */ +shindig.container.util.newTokenRequest = function(gadgetUrls) { + return { + 'container': window.__CONTAINER, + 'ids': gadgetUrls, + 'fields': [ 'token' ] + }; +}; + + /** * Extract keys from a JSON to an array. * @param {Object} json to extract keys from. Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java?rev=996670&r1=996669&r2=996670&view=diff ============================================================================== --- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java (original) +++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java Mon Sep 13 19:58:45 2010 @@ -72,6 +72,7 @@ public class GadgetsHandlerApi { public ModulePrefs getModulePrefs(); public Map<String, UserPref> getUserPrefs(); public Map<String, View> getViews(); + public Boolean getNeedsTokenRefresh(); } public enum ViewContentType { Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java?rev=996670&r1=996669&r2=996670&view=diff ============================================================================== --- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java (original) +++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java Mon Sep 13 19:58:45 2010 @@ -126,7 +126,11 @@ public class GadgetsHandlerService { String iframeUrl = (fields.contains("iframeurl") || fields.contains(BeanFilter.ALL_FIELDS)) ? iframeUriManager.makeRenderingUri(gadget).toString() : null; - return createMetadataResponse(context.getUrl(), gadget.getSpec(), iframeUrl, fields); + Boolean needsTokenRefresh = + (fields.contains("needstokenrefresh") || fields.contains(BeanFilter.ALL_FIELDS)) ? + gadget.getAllFeatures().contains("auth-refresh") : null; + return createMetadataResponse(context.getUrl(), gadget.getSpec(), iframeUrl, + needsTokenRefresh, fields); } /** @@ -230,12 +234,15 @@ public class GadgetsHandlerService { } private GadgetsHandlerApi.MetadataResponse createMetadataResponse( - Uri url, GadgetSpec spec, String iframeUrl, Set<String> fields) { + Uri url, GadgetSpec spec, String iframeUrl, Boolean needsTokenRefresh, + Set<String> fields) { return (GadgetsHandlerApi.MetadataResponse) beanFilter.createFilteredBean( beanDelegator.createDelegator(spec, GadgetsHandlerApi.MetadataResponse.class, ImmutableMap.<String, Object>of( - "url", url, "error", BeanDelegator.NULL, - "iframeurl", BeanDelegator.nullable(iframeUrl))), + "url", url, + "error", BeanDelegator.NULL, + "iframeurl", BeanDelegator.nullable(iframeUrl), + "needstokenrefresh", BeanDelegator.nullable(needsTokenRefresh))), fields); } Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java?rev=996670&r1=996669&r2=996670&view=diff ============================================================================== --- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java (original) +++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java Mon Sep 13 19:58:45 2010 @@ -23,6 +23,7 @@ import org.apache.shindig.common.uri.Uri import org.apache.shindig.gadgets.Gadget; import org.apache.shindig.gadgets.GadgetContext; import org.apache.shindig.gadgets.GadgetException; +import org.apache.shindig.gadgets.features.FeatureRegistry; import org.apache.shindig.gadgets.process.ProcessingException; import org.apache.shindig.gadgets.process.Processor; import org.apache.shindig.gadgets.spec.GadgetSpec; @@ -64,10 +65,17 @@ public class FakeProcessor extends Proce "<Content type=\"html\">Hello, world</Content>" + "</Module>"; + private final FeatureRegistry featureRegistry; + public FakeProcessor() { + this(null); + } + + public FakeProcessor(FeatureRegistry featureRegistry) { super(null, null, null, null, null); this.gadgets.put(FakeProcessor.SPEC_URL, FakeProcessor.SPEC_XML); this.gadgets.put(FakeProcessor.SPEC_URL2, FakeProcessor.SPEC_XML2); + this.featureRegistry = featureRegistry; } @Override @@ -84,7 +92,8 @@ public class FakeProcessor extends Proce return new Gadget() .setContext(context) .setSpec(spec) - .setCurrentView(view); + .setCurrentView(view) + .setGadgetFeatureRegistry(featureRegistry); } catch (GadgetException e) { throw new RuntimeException(e); } Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java?rev=996670&r1=996669&r2=996670&view=diff ============================================================================== --- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java (original) +++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetHandlerServiceTest.java Mon Sep 13 19:58:45 2010 @@ -19,12 +19,14 @@ package org.apache.shindig.gadgets.servlet; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import org.apache.shindig.auth.SecurityToken; import org.apache.shindig.auth.SecurityTokenCodec; import org.apache.shindig.auth.SecurityTokenException; import org.apache.shindig.common.EasyMockTestCase; import org.apache.shindig.common.uri.Uri; +import org.apache.shindig.gadgets.features.FeatureRegistry; import org.apache.shindig.gadgets.process.ProcessingException; import org.apache.shindig.protocol.conversion.BeanDelegator; import org.apache.shindig.protocol.conversion.BeanFilter; @@ -45,7 +47,8 @@ public class GadgetHandlerServiceTest ex private final BeanDelegator delegator = new BeanDelegator( GadgetsHandlerService.apiClasses, GadgetsHandlerService.enumConversionMap); - private final FakeProcessor processor = new FakeProcessor(); + private final FeatureRegistry mockRegistry = mock(FeatureRegistry.class); + private final FakeProcessor processor = new FakeProcessor(mockRegistry); private final FakeIframeUriManager urlGenerator = new FakeIframeUriManager(); private FakeSecurityTokenCodec tokenCodec; @@ -73,9 +76,12 @@ public class GadgetHandlerServiceTest ex GadgetsHandlerApi.MetadataRequest request = createMetadataRequest( FakeProcessor.SPEC_URL, CONTAINER, "view", createTokenData(null, null), ImmutableList.of("*")); + EasyMock.expect(mockRegistry.getFeatures(EasyMock.isA(List.class))) + .andReturn(Lists.newArrayList("auth-refresh")); replay(); GadgetsHandlerApi.MetadataResponse response = gadgetHandler.getMetadata(request); assertEquals(FakeIframeUriManager.DEFAULT_IFRAME_URI.toString(), response.getIframeUrl()); + assertTrue(response.getNeedsTokenRefresh()); assertEquals(1, response.getViews().size()); assertTrue(response.getViews().get("default").getContent().contains("Hello, world" )); assertEquals(FakeProcessor.SPEC_TITLE, response.getModulePrefs().getTitle()); @@ -105,7 +111,6 @@ public class GadgetHandlerServiceTest ex verify(); } - @Test(expected = ProcessingException.class) public void testGetMetadataNoContainer() throws Exception { GadgetsHandlerApi.MetadataRequest request = createMetadataRequest( @@ -115,7 +120,6 @@ public class GadgetHandlerServiceTest ex GadgetsHandlerApi.MetadataResponse response = gadgetHandler.getMetadata(request); } - @Test(expected = ProcessingException.class) public void testGetMetadataNoUrl() throws Exception { GadgetsHandlerApi.MetadataRequest request = createMetadataRequest( @@ -147,6 +151,8 @@ public class GadgetHandlerServiceTest ex public void testGetMetadataNoToken() throws Exception { GadgetsHandlerApi.MetadataRequest request = createMetadataRequest( FakeProcessor.SPEC_URL, CONTAINER, "view", null, ImmutableList.of("*")); + EasyMock.expect(mockRegistry.getFeatures(EasyMock.isA(List.class))) + .andReturn(Lists.newArrayList("auth-refresh")); replay(); GadgetsHandlerApi.MetadataResponse response = gadgetHandler.getMetadata(request); assertEquals(FakeIframeUriManager.DEFAULT_IFRAME_URI.toString(), response.getIframeUrl());
