Reviewers: mhermanto1,
Message:
Mike, not sure if you saw this, so just wanted to make sure. This is the
code change to go along with this update to the container spec:
http://code.google.com/p/opensocial-resources/issues/detail?id=1185
Description:
Allows container components to register themselves and react to
preload/navigate/close/unload gadget events.
Allows features that rely on feature parameters(e.g. opensearch,
actions) to find out when gadgets are added, and react to their
contributions.
Please review this at http://codereview.appspot.com/4536097/
Affected files:
features/src/main/javascript/features/container/container.js
Index: features/src/main/javascript/features/container/container.js
===================================================================
--- features/src/main/javascript/features/container/container.js (revision
1130245)
+++ features/src/main/javascript/features/container/container.js (working
copy)
@@ -29,8 +29,14 @@
*/
osapi.container.Container = function(opt_config) {
var config = opt_config || {};
-
+
/**
+ * A list of object to be notified when gadgets are preloaded, navigated
to or closed.
+ * @type {Array} array of callback objects, all of which have
an "preloaded", "navigated", "closed" and "unloaded" methods.
+ * @private
+ */
+ this.gadgetLifecycleCallbacks_ = [];
+ /**
* A JSON list of preloaded gadget URLs.
* @type {Object}
* @private
@@ -173,6 +179,7 @@
this.refreshService_();
var self = this;
+ var selfSite=site;
// TODO: Lifecycle, add ability for current gadget to cancel nav.
site.navigateTo(gadgetUrl, viewParams, renderParams,
function(gadgetInfo) {
// TODO: Navigate to error screen on primary gadget load failure
@@ -184,6 +191,8 @@
} else if
(gadgetInfo[osapi.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) {
self.scheduleRefreshTokens_();
}
+
+ self.applyLifecycleCallbacks_("navigated", selfSite);
callback(gadgetInfo);
});
};
@@ -198,10 +207,31 @@
site.close();
delete this.sites_[id];
this.unscheduleRefreshTokens_();
+ this.applyLifecycleCallbacks_("closed", site);
};
/**
+ * Add a callback to be called when one or more gadgets are preloaded,
navigated to or closed.
+ * @param {Object} callback object to call back when a gadget is
preloaded, navigated to or closed. called via preloaded, navigated and
closed methods
+ */
+osapi.container.Container.prototype.addGadgetLifecycleCallback =
function(lifeCycleCallback) {
+ this.gadgetLifecycleCallbacks_.push(lifeCycleCallback);
+};
+
+/**
+ * remove a lifecycle callback previously registered with the container
+ * @param {Object} callback object to be removed
+ */
+osapi.container.Container.prototype.removeGadgetLifecycleCallback =
function(lifeCycleCallback) {
+ for (index in this.gadgetLifecycleCallbacks_) {
+ if(this.gadgetLifecycleCallbacks_[index]==lifeCycleCallback) {
+ this.gadgetLifecycleCallbacks_.splice(index,1);
+ }
+ }
+};
+
+/**
* Pre-load one gadget metadata information. More details on
preloadGadgets().
* @param {string} gadgetUrl gadget URI to preload.
* @param {function(Object)=} opt_callback function to call upon data
receive.
@@ -226,7 +256,9 @@
this.refreshService_();
this.service_.getGadgetMetadata(request, function(response) {
self.addPreloadGadgets_(response);
+ self.applyLifecycleCallbacks_("preloaded", response);
callback(response);
+
});
};
@@ -248,6 +280,7 @@
for (var i = 0; i < gadgetUrls.length; i++) {
var url = gadgetUrls[i];
delete this.preloadedGadgetUrls_[url];
+ this.applyLifecycleCallbacks_("unloaded", url);
}
};
@@ -624,3 +657,19 @@
}
});
};
+
+
+/**
+ * invokes methods on the gadget lifecycle callback registered with the
container.
+ * @param {methodName} name of the callback method to be called.
+ * @param {data} data to be passed to the callback method
+ * @private
+ */
+
+osapi.container.Container.prototype.applyLifecycleCallbacks_=function(methodName,
data)
{
+ for (index in this.gadgetLifecycleCallbacks_) {
+ if (this.gadgetLifecycleCallbacks_[index][methodName]!=null) {
+ this.gadgetLifecycleCallbacks_[index][methodName](data);
+ }
+ }
+};