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);
+    }
+  }
+};


Reply via email to