can3p (can3p) wrote in changelog,
can3p
can3p
changelog

[livejournal] r20448: OPSC-397: Implement LJ JS API osapi.peop...

Committer: dpetrov
OPSC-397: Implement LJ JS API osapi.people service functions
A   trunk/htdocs/js/apps/livejournal/
A   trunk/htdocs/js/apps/livejournal/container/
A   trunk/htdocs/js/apps/livejournal/container/container.js
A   trunk/htdocs/js/apps/livejournal/container/feature.xml
A   trunk/htdocs/js/apps/livejournal/container/init.js
A   trunk/htdocs/js/apps/livejournal/container/service.js
A   trunk/htdocs/js/apps/livejournal/osapi/
A   trunk/htdocs/js/apps/livejournal/osapi/feature.xml
A   trunk/htdocs/js/apps/livejournal/osapi/gadgetsrpctransport.js
A   trunk/htdocs/js/apps/livejournal/osapi/jsonrpctransport.js
A   trunk/htdocs/js/apps/livejournal/osapi/peoplehelpers.js
A   trunk/htdocs/js/apps/livejournal/osapi/taming.js
A   trunk/htdocs/js/apps/livejournal/osapi.base/
A   trunk/htdocs/js/apps/livejournal/osapi.base/batch.js
A   trunk/htdocs/js/apps/livejournal/osapi.base/feature.xml
A   trunk/htdocs/js/apps/livejournal/osapi.base/osapi.js
A   trunk/htdocs/js/apps/livejournal/osapi.base/taming.js
A   trunk/htdocs/js/apps/shindig/container.util/
A   trunk/htdocs/js/apps/shindig/container.util/constant.js
A   trunk/htdocs/js/apps/shindig/container.util/feature.xml
A   trunk/htdocs/js/apps/shindig/container.util/util.js
A   trunk/htdocs/js/apps/shindig/core.io/
A   trunk/htdocs/js/apps/shindig/core.io/feature.xml
A   trunk/htdocs/js/apps/shindig/core.io/io.js
A   trunk/htdocs/js/apps/shindig/core.io/taming.js
Added: trunk/htdocs/js/apps/livejournal/container/container.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/container/container.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/container/container.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,93 @@
+/*
+ * 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 This represents the container for the current window or create
+ * the container if none already exists.
+ */
+
+/** @TODO: most of functionality was cut from this container, because it's duplicated
+ * in the shindig.container object. In order to unify all the code we should implement
+ * GadgetSite and GadgetHolder classes and migrate all the functionality to them from
+ * LJGadget, LJContainer, LJIframeService.
+ */
+
+
+/**
+ * @param {Object=} opt_config Configuration JSON.
+ * @constructor
+ */
+osapi.container.Container = function(opt_config) {
+  var config = this.config_ = opt_config || {};
+
+  /**
+   * @type {osapi.container.Service}
+   * @private
+   */
+  this.service_ = new osapi.container.Service(config);
+
+  this.initializeMixins_();
+
+  this.onConstructed(config);
+};
+
+
+/**
+ * Callback that occurs after instantiation/construction of this. Override to
+ * provide your specific functionalities.
+ * @param {Object=} opt_config Configuration JSON.
+ */
+osapi.container.Container.prototype.onConstructed = function(opt_config) {};
+
+
+/**
+ * Adds a new namespace to the Container object.  The namespace
+ * will contain the result of calling the function passed in.
+ *
+ * @param {string} namespace the namespace to add.
+ * @param {function} func to call when creating the namespace.
+ */
+osapi.container.Container.addMixin = function(namespace, func) {
+   osapi.container.Container.prototype.mixins_[namespace] = func;
+};
+
+
+// -----------------------------------------------------------------------------
+// Private variables and methods.
+// -----------------------------------------------------------------------------
+
+
+/**
+ * Adds the ability for features to extend the container with
+ * their own functionality that may be specific to that feature.
+ * @type {Object<string,function>}
+ * @private
+ */
+osapi.container.Container.prototype.mixins_ = {};
+
+
+/**
+ * Called from the constructor to add any namespace extensions.
+ * @private
+ */
+osapi.container.Container.prototype.initializeMixins_ = function() {
+  for (var i in this.mixins_) {
+    this[i] = new this.mixins_[i](this);
+  }
+};

Added: trunk/htdocs/js/apps/livejournal/container/feature.xml
===================================================================
--- trunk/htdocs/js/apps/livejournal/container/feature.xml	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/container/feature.xml	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<feature>
+  <name>container</name>
+  <dependency>globals</dependency>
+  <dependency>core.log</dependency>
+  <dependency>shindig.auth</dependency>
+  <dependency>shindig.uri.ext</dependency>
+  <dependency>osapi</dependency>
+  <dependency>rpc</dependency>
+  <dependency>container.util</dependency>
+  <dependency>container.gadget</dependency>
+  <dependency>container.url</dependency>
+  <container>
+    <script src="service.js"/>
+    <script src="container.js"/>
+    <script src="init.js"/>
+    <api>
+      <exports type="js">osapi.container.Container</exports>
+      <exports type="js">osapi.container.Container.prototype.newGadgetSite</exports>
+      <exports type="js">osapi.container.Container.prototype.navigateGadget</exports>
+      <exports type="js">osapi.container.Container.prototype.closeGadget</exports>
+      <exports type="js">osapi.container.Container.prototype.preloadGadget</exports>
+      <exports type="js">osapi.container.Container.prototype.preloadGadgets</exports>
+      <exports type="js">osapi.container.Container.prototype.preloadCaches</exports>
+      <exports type="js">osapi.container.Container.prototype.unloadGadget</exports>
+      <exports type="js">osapi.container.Container.prototype.unloadGadgets</exports>
+      <exports type="js">osapi.container.Container.prototype.getGadgetMetadata</exports>
+      <exports type="js">osapi.container.Container.prototype.rpcRegister</exports>
+      <exports type="js">osapi.container.Container.prototype.onConstructed</exports>
+      <exports type="js">osapi.container.ContainerConfig.ALLOW_DEFAULT_VIEW</exports>
+      <exports type="js">osapi.container.ContainerConfig.RENDER_CAJOLE</exports>
+      <exports type="js">osapi.container.ContainerConfig.RENDER_DEBUG</exports>
+      <exports type="js">osapi.container.ContainerConfig.RENDER_DEBUG_PARAM</exports>
+      <exports type="js">osapi.container.ContainerConfig.RENDER_TEST</exports>
+      <exports type="js">osapi.container.ContainerConfig.TOKEN_REFRESH_INTERVAL</exports>
+      <exports type="js">osapi.container.ContainerConfig.NAVIGATE_CALLBACK</exports>
+      <exports type="js">osapi.container.ContainerConfig.PRELOAD_REF_TIME</exports>
+      <exports type="js">osapi.container.ContainerConfig.PRELOAD_METADATAS</exports>
+      <exports type="js">osapi.container.ContainerConfig.PRELOAD_TOKENS</exports>
+      <exports type="rpc">resize_iframe</exports>
+      <exports type="rpc">resize_iframe_width</exports>
+      <exports type="rpc">set_pref</exports>
+      <uses type="rpc">update_security_token</uses>
+    </api>
+  </container>
+</feature>

Added: trunk/htdocs/js/apps/livejournal/container/init.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/container/init.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/container/init.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,68 @@
+/*
+ * 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 Initial configuration/boot-strapping work for common container
+ * to operate. This includes setting up gadgets config and global environment
+ * variables.
+ */
+(function() {
+
+  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%'
+      }
+    });
+  }
+
+  function initializeGlobalVars() {
+    window.__CONTAINER_URI = shindig.uri(window.location.href);
+
+    window.__API_URI = null;
+    var scriptEl = null;
+    if (window.__CONTAINER_SCRIPT_ID) {
+      scriptEl = document.getElementById(window.__CONTAINER_SCRIPT_ID);
+    } else {
+      var scriptEls = document.getElementsByTagName('script');
+      if (scriptEls.length > 0) {
+        scriptEl = scriptEls[scriptEls.length - 1];
+      }
+    }
+
+    if (scriptEl) {
+      window.__API_URI = shindig.uri(scriptEl.src);
+      // In case script URI is relative, resolve (make absolute) with container.
+      window.__API_URI.resolve(window.__CONTAINER_URI);
+    }
+
+    window.__CONTAINER = window.__API_URI ?
+        window.__API_URI.getQP('container') : 'default';
+  }
+
+  initializeConfig();
+  initializeGlobalVars();
+})();

Added: trunk/htdocs/js/apps/livejournal/container/service.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/container/service.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/container/service.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,61 @@
+/*
+ * 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 This represents the service layer that talks to OSAPI
+ * endpoints. All RPC requests should go into this class.
+ */
+
+
+/**
+ * @param {Object=} opt_config Configuration JSON.
+ * @constructor
+ */
+osapi.container.Service = function(opt_config) {
+	var config = this.config_ = opt_config || {};
+
+	this.registerOsapiServices();
+
+	this.onConstructed(config);
+};
+
+
+/**
+ * Callback that occurs after instantiation/construction of this. Override to
+ * provide your specific functionalities.
+ * @param {Object=} opt_config Configuration JSON.
+ */
+osapi.container.Service.prototype.onConstructed = function(opt_config) {};
+
+
+/**
+ * Initialize OSAPI endpoint methods/interfaces.
+ */
+osapi.container.Service.prototype.registerOsapiServices = function() {
+	gadgets.config.init({
+		rpc: {
+			parentRelayUrl: ''
+		},
+		views: gadgets.config.views,
+		'osapi.services': {
+			'http://%host%/__api_endpoint/os/1.0/rpc': ['people.get', 'people.getViewer',
+				'people.getViewerFriends', 'people.getOwner', 'people.getOwnerFriends']
+		}
+	});
+};

Added: trunk/htdocs/js/apps/livejournal/osapi/feature.xml
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi/feature.xml	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi/feature.xml	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<feature>
+  <name>osapi</name>
+  <dependency>globals</dependency>
+  <dependency>taming</dependency>
+  <dependency>shindig.auth</dependency>
+  <dependency>core.config</dependency>
+  <dependency>core.io</dependency>
+  <dependency>core.json</dependency>
+  <dependency>core.util</dependency>
+  <dependency>osapi.base</dependency>
+  <dependency>rpc</dependency>
+  <dependency>security-token</dependency>
+  <container>
+    <script src="jsonrpctransport.js"></script>
+    <script src="peoplehelpers.js"></script>
+    <script src="taming.js" caja="1"></script>    
+  </container>
+  <gadget>
+    <script src="jsonrpctransport.js"></script>
+    <script src="gadgetsrpctransport.js"></script>
+    <script src="peoplehelpers.js"></script>    
+    <script src="taming.js" caja="1"></script>
+    <api>
+      <uses type="rpc">osapi._handleGadgetRpcMethod</uses>
+    </api>
+  </gadget>
+</feature>

Added: trunk/htdocs/js/apps/livejournal/osapi/gadgetsrpctransport.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi/gadgetsrpctransport.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi/gadgetsrpctransport.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+/**
+ * A transport for osapi based on gadgets.rpc. Allows osapi to expose APIs requiring container
+ * and user UI mediation in addition to allowing data oriented APIs to be implemented using
+ * gadgets.rpc instead of XHR/JSON-RPC/REST etc..
+ */
+if (gadgets && gadgets.rpc) { //Dont bind if gadgets.rpc not defined
+  (function() {
+
+    /**
+     * Execute the JSON-RPC batch of gadgets.rpc. The container is expected to implement
+     * the method osapi._handleGadgetRpcMethod(<JSON-RPC batch>)
+     *
+     * @param {Object} requests the opensocial JSON-RPC request batch.
+     * @param {function(Object)} callback to the osapi batch with either an error response or
+     * a JSON-RPC batch result.
+     * @private
+     */
+    function execute(requests, callback) {
+      var rpcCallback = function(response) {
+        if (!response) {
+          callback({ 'code': 500, 'message': 'Container refused the request' });
+        } else if (response['error']) {
+          callback(response);
+        } else {
+          var responseMap = {};
+          for (var i = 0; i < response.length; i++) {
+            responseMap[response[i]['id']] = response[i];
+          }
+          callback(responseMap);
+        }
+      };
+      //we add here our security token because all json-rpc requests are made
+      //on the container side now
+      gadgets.rpc.call('..', 'osapi._handleGadgetRpcMethod', rpcCallback, requests,
+              livejournal.getSecurityToken().getToken());
+      // TODO - Timeout handling if rpc silently fails?
+    }
+
+    function init(config) {
+      var transport = { 'name': 'gadgets.rpc', 'execute' : execute };
+      var services = config['osapi.services'];
+      if (services) {
+        // Iterate over the defined services, extract the gadget.rpc endpoint and
+        // bind to it
+        for (var endpointName in services) {
+          if (services.hasOwnProperty(endpointName)) {
+            if (endpointName === 'gadgets.rpc') {
+              var methods = services[endpointName];
+              for (var i = 0; i < methods.length; i++) {
+                osapi._registerMethod(methods[i], transport);
+              }
+            }
+          }
+        }
+      }
+
+      // Check if the container.listMethods is bound? If it is then use it to
+      // introspect the container services for available methods and bind them
+      // Because the call is asynchronous we delay the execution of the gadget onLoad
+      // handler until the callback has completed. Containers wishing to avoid this
+      // behavior should not specify a binding for container.listMethods in their
+      // container config but rather list out all the container methods they want to
+      // expose directly which is the preferred option for production environments
+      if (osapi.container && osapi.container.listMethods) {
+
+        // Intercept the onload handler so that it is not called until
+        // - gadgets.util.runOnLoadHandlers called at end of gadget,
+        //   and either
+        //   - callback from container.listMethods
+        //   - callback from window.setTimeout
+        var originalRunOnLoadHandlers = gadgets.util.runOnLoadHandlers;
+        var gadgetFlag = false;
+        var listMethodsFlag = false;
+        var triggered = false;
+        var trigger = function() {
+          if (!triggered && gadgetFlag && listMethodsFlag) {
+            triggered = true;
+            originalRunOnLoadHandlers();
+          }
+        };
+        gadgets.util.runOnLoadHandlers = function() {
+          gadgetFlag = true;
+          trigger();
+        };
+
+        // Call for the container methods and bind them to osapi.
+        osapi.container.listMethods({}).execute(function(response) {
+          if (!response['error']) {
+            for (var i = 0; i < response.length; i++) {
+              // do not rebind container.listMethods implementation
+              if (response[i] != 'container.listMethods') {
+                osapi._registerMethod(response[i], transport);
+              }
+            }
+          }
+          listMethodsFlag = true;
+          trigger();
+        });
+
+        // Wait 500ms for the rpc. This should be a reasonable upper bound
+        // even for slow transports while still allowing for reasonable testing
+        // in a development environment
+        window.setTimeout(function() {
+          listMethodsFlag = true;
+          trigger();
+        }, 500);
+      }
+    }
+
+    // Do not run this in container mode.
+    if (gadgets.config) {
+      gadgets.config.register('osapi.services', null, init);
+    }
+  })();
+}

Added: trunk/htdocs/js/apps/livejournal/osapi/jsonrpctransport.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi/jsonrpctransport.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi/jsonrpctransport.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provide a transport of osapi requests over JSON-RPC. Exposed JSON-RPC endpoints and
+ * their associated methods are available from config in the "osapi.services" field.
+ */
+(function() {
+
+  var useOAuth2;
+
+  /**
+   * Called by a batch to execute all requests
+   * @param {Object} requests
+   * @param {function(Object)} callback
+   */
+  function execute(requests, callback, st) {
+    function processResponse(response) {
+      // Convert an XHR failure to a JSON-RPC error
+      if (response['errors'][0]) {
+        callback({
+          error: {
+            'code': response['rc'],
+            'message': response['text']
+          }
+        });
+      } else {
+        var jsonResponse = response['result'] || response['data'];
+        if (jsonResponse['error']) {
+          callback(jsonResponse);
+        } else {
+          var responseMap = {};
+          for (var i = 0; i < jsonResponse.length; i++) {
+            responseMap[jsonResponse[i]['id']] = jsonResponse[i];
+          }
+          callback(responseMap);
+        }
+      }
+    }
+
+    var request = {
+      'POST_DATA' : gadgets.json.stringify(requests),
+      'CONTENT_TYPE' : 'JSON',
+      'METHOD' : 'POST',
+      'AUTHORIZATION' : 'SIGNED'
+    };
+    var headers = {'Content-Type': 'application/json'};
+
+    var url = this.name;
+    var token = st;
+    if (token) {
+      if (useOAuth2) {
+        headers['Authorization'] = 'OAuth2 ' + token;
+      } else {
+        url += '?st=';
+        url += encodeURIComponent(token);
+      }
+    }
+    gadgets.io.makeNonProxiedRequest(url, processResponse, request, headers);
+  }
+
+  function init(config) {
+    var services = config['osapi.services'];
+    useOAuth2 = config['osapi.useOAuth2'];
+    if (services) {
+      // Iterate over the defined services, extract the http endpoints and
+      // create a transport per-endpoint
+      for (var endpointName in services) {
+        if (services.hasOwnProperty(endpointName)) {
+          if (endpointName.indexOf('http') == 0 ||
+              endpointName.indexOf('//') == 0) {
+            // Expand the host & append the security token
+            var endpointUrl = endpointName.replace('%host%', document.location.host);
+            var transport = { 'name' : endpointUrl, 'execute' : execute };
+            var methods = services[endpointName];
+            for (var i = 0; i < methods.length; i++) {
+              osapi._registerMethod(methods[i], transport);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // We do run this in the container mode in the new common container
+  if (gadgets.config) {
+    gadgets.config.register('osapi.services', null, init);
+  }
+
+})();

Added: trunk/htdocs/js/apps/livejournal/osapi/peoplehelpers.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi/peoplehelpers.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi/peoplehelpers.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+/**
+ * Service to retrieve People via JSON RPC opensocial calls.
+ * Called in onLoad handler as osapi.people.get could be defined by
+ * the container over the gadgets.rpc transport.
+ */
+gadgets.util.registerOnLoadHandler(function() {
+
+  // No point defining these if osapi.people.get doesn't exist
+  if (osapi && osapi.people && osapi.people.get) {
+    /**
+    * Helper functions to get People.
+    * Options specifies parameters to the call as outlined in the
+    * JSON RPC Opensocial Spec
+    * http://www.opensocial.org/Technical-Resources/opensocial-spec-v081/rpc-protocol
+    * @param {object.<JSON>} The JSON object of parameters for the specific request.
+    */
+    /**
+      * Function to get Viewer profile.
+      * Options specifies parameters to the call as outlined in the
+      * JSON RPC Opensocial Spec
+      * http://www.opensocial.org/Technical-Resources/opensocial-spec-v081/rpc-protocol
+      * @param {object.<JSON>} The JSON object of parameters for the specific request.
+      */
+    osapi.people.getViewer = function(options) {
+      options = options || {};
+      options.userId = '@viewer';
+      options.groupId = '@self';
+      return osapi.people.get(options);
+    };
+
+    /**
+      * Function to get Viewer's friends'  profiles.
+      * Options specifies parameters to the call as outlined in the
+      * JSON RPC Opensocial Spec
+      * http://www.opensocial.org/Technical-Resources/opensocial-spec-v081/rpc-protocol
+      * @param {object.<JSON>} The JSON object of parameters for the specific request.
+      */
+    osapi.people.getViewerFriends = function(options) {
+      options = options || {};
+      options.userId = '@viewer';
+      options.groupId = '@friends';
+      return osapi.people.get(options);
+    };
+
+    /**
+      * Function to get Owner profile.
+      * Options specifies parameters to the call as outlined in the
+      * JSON RPC Opensocial Spec
+      * http://www.opensocial.org/Technical-Resources/opensocial-spec-v081/rpc-protocol
+      * @param {object.<JSON>} The JSON object of parameters for the specific request.
+      */
+    osapi.people.getOwner = function(options) {
+      options = options || {};
+      options.userId = '@owner';
+      options.groupId = '@self';
+      return osapi.people.get(options);
+    };
+
+    /**
+      * Function to get Owner's friends' profiles.
+      * Options specifies parameters to the call as outlined in the
+      * JSON RPC Opensocial Spec
+      * http://www.opensocial.org/Technical-Resources/opensocial-spec-v081/rpc-protocol
+      * @param {object.<JSON>} The JSON object of parameters for the specific request.
+      */
+    osapi.people.getOwnerFriends = function(options) {
+      options = options || {};
+      options.userId = '@owner';
+      options.groupId = '@friends';
+      return osapi.people.get(options);
+    };
+  }
+});

Added: trunk/htdocs/js/apps/livejournal/osapi/taming.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi/taming.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi/taming.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * @class
+ * Tame and expose people osapi.* API to cajoled gadgets
+ */
+tamings___.push(function(imports) {
+
+  // Forced to tame in an onload handler because peoplehelpers does
+  // not define some functions till runOnLoadHandlers runs
+  var savedImports = imports;
+  gadgets.util.registerOnLoadHandler(function() {
+    if (osapi && osapi.people && osapi.people.get) {
+      caja___.whitelistFuncs([
+        [osapi.people, 'getViewer'],
+        [osapi.people, 'getViewerFriends'],
+        [osapi.people, 'getOwner'],
+        [osapi.people, 'getOwnerFriends']
+      ]);
+    }
+  });
+});

Added: trunk/htdocs/js/apps/livejournal/osapi.base/batch.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi.base/batch.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi.base/batch.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+(function() {
+
+  /**
+   * It is common to batch requests together to make them more efficient.
+   *
+   * Note: the container config specified endpoints at which services are to be
+   * found. When creating a batch, the calls are split out into separate
+   * requests based on the transport, as it may get sent to a different server
+   * on the backend.
+   */
+  var newBatch = function(st) {
+    var that = {};
+
+    // An array of requests where each request is
+    // { key : <key>
+    //   request : {
+    //     method : <service-method>
+    //     rpc  : <request params>
+    //     transport : <rpc dispatcher>
+    //  }
+    // }
+
+    /** @type {Array.<Object>} */
+    var keyedRequests = [];
+    var token = st || null;
+
+    /**
+     * Create a new request in the batch
+     * @param {string} key id for the request.
+     * @param {Object} request the opensocial request object which is of the form
+     * { method : <service-method>
+     *   rpc  : <request>
+     *   transport : <rpc dispatcher>
+     * }.
+     */
+    var add = function(key, request) {
+      if (request && key) {
+        keyedRequests.push({'key' : key, 'request' : request});
+      }
+      return that;
+    };
+
+    /**
+     * Convert our internal request format into a JSON-RPC
+     * @param {Object} request
+     */
+    var toJsonRpc = function(request) {
+      var jsonRpc = { 'method': request['request']['method'], 'id': request['key'] };
+      if (request['request']['rpc']) {
+        jsonRpc['params'] = request['request']['rpc'];
+      }
+      return jsonRpc;
+    };
+
+    /**
+     * Call to make a batch execute its requests. Batch will distribute calls over their
+     * bound transports and then merge them before calling the userCallback. If the result
+     * of an rpc is another rpc request then it will be chained and executed.
+     *
+     * @param {function(Object)} userCallback the callback to the gadget where results are passed.
+     */
+    var execute = function(userCallback) {
+      var batchResult = {};
+
+      var perTransportBatch = {};
+
+      // Break requests into their per-transport batches in call order
+      /** @type {number} */
+      var latchCount = 0;
+      var transports = [];
+      for (var i = 0; i < keyedRequests.length; i++) {
+        // Batch requests per-transport
+        var transport = keyedRequests[i]['request']['transport'];
+        if (!perTransportBatch[transport['name']]) {
+          transports.push(transport);
+          latchCount++;
+        }
+        perTransportBatch[transport['name']] = perTransportBatch[transport['name']] || [];
+
+        // Transform the request into JSON-RPC form before sending to the transport
+        perTransportBatch[transport['name']].push(toJsonRpc(keyedRequests[i]));
+      }
+
+      // Define callback for transports
+      var transportCallback = function(transportBatchResult) {
+        if (transportBatchResult['error']) {
+          batchResult['error'] = transportBatchResult['error'];
+        }
+        // Merge transport results into overall result and hoist data.
+        // All transport results are required to be of the format
+        // { <key> : <JSON-RPC response>, ...}
+        for (var i = 0; i < keyedRequests.length; i++) {
+          var key = keyedRequests[i]['key'];
+          var response = transportBatchResult[key];
+          if (response) {
+            if (response['error']) {
+              // No need to hoist error responses
+              batchResult[key] = response;
+            } else {
+              // Handle both compliant and non-compliant JSON-RPC data responses.
+              batchResult[key] = response['data'] || response['result'];
+            }
+          }
+        }
+
+        // Latch on no. of transports before calling user callback
+        latchCount--;
+        if (latchCount === 0) {
+          userCallback(batchResult);
+        }
+      };
+
+      // For each transport execute its local batch of requests
+      for (var j = 0; j < transports.length; j++) {
+        transports[j].execute(perTransportBatch[transports[j]['name']], transportCallback, token);
+      }
+
+      // Force the callback to occur asynchronously even if there were no actual calls
+      if (latchCount == 0) {
+        window.setTimeout(function() {userCallback(batchResult)}, 0);
+      }
+    };
+
+    that.execute = execute;
+    that.add = add;
+    return that;
+  };
+
+  osapi.newBatch = newBatch;
+})();

Added: trunk/htdocs/js/apps/livejournal/osapi.base/feature.xml
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi.base/feature.xml	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi.base/feature.xml	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<feature>
+  <name>osapi.base</name>
+  <dependency>globals</dependency>
+  <dependency>core.log</dependency>
+  <dependency>taming</dependency>
+  <all>
+    <script src="batch.js"></script>
+    <script src="osapi.js"></script>
+    <script src="taming.js" caja="1"></script>    
+    <api>
+      <exports type="js">osapi.newBatch.add</exports>
+      <exports type="js">osapi.newBatch.execute</exports>
+      <exports type="js">osapi._registerMethod</exports>
+      <exports type="js">osapi._BoundCall</exports>
+      <exports type="js">osapi._BoundCall.prototype.execute</exports>
+    </api>
+  </all>
+</feature>

Added: trunk/htdocs/js/apps/livejournal/osapi.base/osapi.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi.base/osapi.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi.base/osapi.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+/**
+ * Called by the transports for each service method that they expose
+ * @param {string} method  The method to expose e.g. "people.get".
+ * @param {Object.<string,Object>} transport The transport used to
+ *    execute a call for the method.
+ */
+osapi._registerMethod = function(method, transport) {
+  // Skip registration of local newBatch implementation.
+  if (method === 'newBatch') {
+    return;
+  }
+
+  // Lookup last method value.
+  var parts = method.split('.');
+  var last = osapi;
+  for (var i = 0; i < parts.length - 1; i++) {
+    last[parts[i]] = last[parts[i]] || {};
+    last = last[parts[i]];
+  }
+  var basename = parts[parts.length - 1], old;
+
+  // registered methods are now 'last one in wins'.  See tamings__ below.
+  if (last[basename]) {
+    old = last[basename];
+  }
+
+  last[basename] = function(rpc, callback, st) {
+    // TODO: This shouldn't really be necessary. The spec should be clear
+    // enough about defaults that we dont have to populate this.
+    rpc = rpc || {};
+    rpc['userId'] = rpc['userId'] || '@viewer';
+    rpc['groupId'] = rpc['groupId'] || '@self';
+    if (osapi.container) {
+        //ugly hack to allow to call JSON-RPC from the container side
+        var boundCall = new osapi._BoundCall(method, transport, rpc, st);
+        boundCall.execute(callback);
+    } else {
+        var boundCall = new osapi._BoundCall(method, transport, rpc);
+        return boundCall;
+    }
+  };
+
+  if (typeof tamings___ !== 'undefined') {
+    var newTaming = function() {
+      caja___.markTameAsFunction(last[basename], method);
+    };
+
+    // Remove the old taming if we are replacing it, no sense in growing the array
+    // needlessly. This function (_registerMethod) gets called a lot.
+    if (old && old.__taming_index) {
+      last[basename].__taming_index = old.__taming_index;
+      tamings___[old.__taming_index] = newTaming;
+    }
+    else {
+      last[basename].__taming_index = tamings___.length;
+      tamings___.push(newTaming);
+    }
+  }
+};
+
+// This was formerly an anonymous ad-hoc object, but that triggers a caja
+// bug: http://code.google.com/p/google-caja/issues/detail?id=1355
+// Workaround is to make it a class.
+osapi._BoundCall = function(method, transport, rpc, st) {
+  this['method'] = method;
+  this['transport'] = transport;
+  this['rpc'] = rpc;
+  this['token'] = st;
+};
+
+osapi._BoundCall.prototype.execute = function(callback) {
+  var cajaReady = (typeof caja___ !== 'undefined'
+                   && caja___.getUseless
+                   && caja___.getUseless());
+  var that = cajaReady ? caja___.getUseless() : this;
+  var feralCallback = cajaReady ? caja___.untame(callback) : callback;
+  var batch = osapi.newBatch(this.token);
+  batch.add(this.method, this);
+  batch.execute(function(batchResult) {
+    if (batchResult.error) {
+      feralCallback.call(that, batchResult.error);
+    } else {
+      feralCallback.call(that, batchResult[that.method]);
+    }
+  });
+};
+

Added: trunk/htdocs/js/apps/livejournal/osapi.base/taming.js
===================================================================
--- trunk/htdocs/js/apps/livejournal/osapi.base/taming.js	                        (rev 0)
+++ trunk/htdocs/js/apps/livejournal/osapi.base/taming.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * @class
+ * Tame and expose core osapi.* API to cajoled gadgets
+ */
+tamings___.push(function(imports) {
+  function newBatch() {
+    var batch = osapi.newBatch();
+    caja___.whitelistFuncs([
+      [batch, 'add'],
+      [batch, 'execute']
+    ]);
+    return caja___.tame(batch);
+  }
+  caja___.markTameAsFunction(newBatch, 'newBatch');
+  caja___.tamesTo(osapi.newBatch, newBatch);
+  caja___.whitelistCtors([
+    [osapi, '_BoundCall', Object]
+  ]);
+  caja___.whitelistMeths([
+    [osapi._BoundCall, 'execute']
+  ]);
+});

Added: trunk/htdocs/js/apps/shindig/container.util/constant.js
===================================================================
--- trunk/htdocs/js/apps/shindig/container.util/constant.js	                        (rev 0)
+++ trunk/htdocs/js/apps/shindig/container.util/constant.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,153 @@
+/*
+ * 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}
+ */
+osapi.container = {};
+
+
+/**
+ * Constants to key into gadget metadata state.
+ * @const
+ * @enum {string}
+ */
+osapi.container.MetadataParam = {
+    LOCAL_EXPIRE_TIME: 'localExpireTimeMs',
+    URL: 'url'
+};
+
+
+/**
+ * Constants to key into gadget metadata response JSON.
+ * @enum {string}
+ */
+
+osapi.container.MetadataResponse = {
+  IFRAME_URL: 'iframeUrl',
+  NEEDS_TOKEN_REFRESH: 'needsTokenRefresh',
+  VIEWS: 'views',
+  EXPIRE_TIME_MS: 'expireTimeMs',
+  FEATURES: 'features',
+  HEIGHT: 'height',
+  MODULE_PREFS: 'modulePrefs',
+  PREFERRED_HEIGHT: 'preferredHeight',
+  PREFERRED_WIDTH: 'preferredWidth',
+  RESPONSE_TIME_MS: 'responseTimeMs',
+  WIDTH: 'width'
+};
+
+
+/**
+ * Constants to key into gadget token response JSON.
+ * @enum {string}
+ */
+osapi.container.TokenResponse = {
+  TOKEN: 'token'
+};
+
+
+/**
+ * Constants to key into timing response JSON.
+ * @enum {string}
+ */
+osapi.container.NavigateTiming = {
+  /** The gadget URL reporting this timing information. */
+  URL: 'url',
+  /** The gadget site ID reporting this timing information. */
+  ID: 'id',
+  /** Absolute time (ms) when gadget navigation is requested. */
+  START: 'start',
+  /** Time (ms) to receive XHR response time. In CC, for metadata and token. */
+  XRT: 'xrt',
+  /** Time (ms) to receive first byte. Typically timed at start of page. */
+  SRT: 'srt',
+  /** Time (ms) to load the DOM. Typically timed at end of page. */
+  DL: 'dl',
+  /** Time (ms) when body onload is called. */
+  OL: 'ol',
+  /** Time (ms) when page is ready for use. Typically happen after data XHR (ex:
+   * calendar, email) is received/presented to users. Overridable by user.
+   */
+  PRT: 'prt'
+};
+
+
+/**
+ * Constants to key into request renderParam JSON.
+ * @enum {string}
+ * @const
+ */
+osapi.container.RenderParam = {
+    /** Allow gadgets to render in unspecified view. */
+    ALLOW_DEFAULT_VIEW: 'allowDefaultView',
+
+    /** Whether to enable cajole mode. */
+    CAJOLE: 'cajole',
+
+    /** Style class to associate to iframe. */
+    CLASS: 'class',
+
+    /** Whether to enable debugging mode. */
+    DEBUG: 'debug',
+
+    /** The starting gadget iframe height (in pixels). */
+    HEIGHT: 'height',
+
+    /** Whether to disable cache. */
+    NO_CACHE: 'nocache',
+
+    /** Whether to enable test mode. */
+    TEST_MODE: 'testmode',
+
+    /** The gadget user prefs to render with. */
+    USER_PREFS: 'userPrefs',
+
+    /** The view of gadget to render. */
+    VIEW: 'view',
+
+    /** The starting gadget iframe width (in pixels). */
+    WIDTH: 'width'
+};
+
+/**
+ * Constants to key into request viewParam JSON.
+ * @enum {string}
+ */
+osapi.container.ViewParam = {
+  VIEW: 'view'
+};
+
+/**
+ * Constants to define lifecycle callback
+ * @enum {string}
+ */
+osapi.container.CallbackType = {
+    ON_PRELOADED: 'onPreloaded',
+    ON_NAVIGATED: 'onNavigated',
+    ON_CLOSED: 'onClosed',
+    ON_UNLOADED: 'onUnloaded',
+    ON_RENDER: 'onRender'
+};

Added: trunk/htdocs/js/apps/shindig/container.util/feature.xml
===================================================================
--- trunk/htdocs/js/apps/shindig/container.util/feature.xml	                        (rev 0)
+++ trunk/htdocs/js/apps/shindig/container.util/feature.xml	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<feature>
+  <name>container.util</name>
+  <dependency>globals</dependency>
+  <dependency>core.log</dependency>
+  <dependency>shindig.auth</dependency>
+  <dependency>shindig.uri.ext</dependency>
+  <dependency>core.util</dependency>
+  <dependency>osapi</dependency>
+  <dependency>rpc</dependency>
+  <container>
+    <script src="constant.js"/>
+    <script src="util.js"/>
+    <api>
+      <exports type="js">osapi.container.RenderParam.ALLOW_DEFAULT_VIEW</exports>
+      <exports type="js">osapi.container.RenderParam.CAJOLE</exports>
+      <exports type="js">osapi.container.RenderParam.CLASS</exports>
+      <exports type="js">osapi.container.RenderParam.DEBUG</exports>
+      <exports type="js">osapi.container.RenderParam.HEIGHT</exports>
+      <exports type="js">osapi.container.RenderParam.NO_CACHE</exports>
+      <exports type="js">osapi.container.RenderParam.TEST_MODE</exports>
+      <exports type="js">osapi.container.RenderParam.USER_PREFS</exports>
+      <exports type="js">osapi.container.RenderParam.VIEW</exports>
+      <exports type="js">osapi.container.RenderParam.WIDTH</exports>
+    </api>
+  </container>
+</feature>
\ No newline at end of file

Added: trunk/htdocs/js/apps/shindig/container.util/util.js
===================================================================
--- trunk/htdocs/js/apps/shindig/container.util/util.js	                        (rev 0)
+++ trunk/htdocs/js/apps/shindig/container.util/util.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,188 @@
+/*
+ * 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 Utility methods for common container.
+ */
+
+
+/**
+ * @type {Object}
+ */
+osapi.container.util = {};
+
+
+/**
+ * @param {Object} json The JSON to look up key param from.
+ * @param {string} key Key in config.
+ * @param {*=} defaultValue The default value to return.
+ * @return {*} value of json at key, if valid. Otherwise, return defaultValue.
+ */
+osapi.container.util.getSafeJsonValue = function(json, key, defaultValue) {
+  return (json[key] != undefined && json[key] != null) ?
+      json[key] : defaultValue;
+};
+
+
+/**
+ * Merge two JSON together. Keys in json2 will replace than in json1.
+ * @param {Object} json1 JSON to start merge with.
+ * @param {Object} json2 JSON to append/replace json1.
+ * @return {Object} the resulting JSON.
+ */
+osapi.container.util.mergeJsons = function(json1, json2) {
+  var result = {};
+  for (var key in json1) {
+    result[key] = json1[key];
+  }
+  for (var key in json2) {
+    result[key] = json2[key];
+  }
+  return result;
+};
+
+
+/**
+ * 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} gadgetUrls An array of gadget URLs.
+ * @return {Object} the resulting JSON.
+ */
+osapi.container.util.newMetadataRequest = function(gadgetUrls) {
+  if (!osapi.container.util.isArray(gadgetUrls)) {
+    gadgetUrls = [gadgetUrls];
+  }
+  return {
+    'container': window.__CONTAINER,
+    'ids': gadgetUrls,
+    'fields': [
+      'iframeUrl',
+      'modulePrefs.*',
+      'needsTokenRefresh',
+      'userPrefs.*',
+      'views.preferredHeight',
+      'views.preferredWidth',
+      'expireTimeMs',
+      'responseTimeMs',
+      'rpcServiceIds'
+    ]
+  };
+};
+
+
+/**
+ * Construct a JSON request to get gadget token.
+ * @param {Array} gadgetUrls A list of gadget URLs.
+ * @return {Object} the resulting JSON.
+ */
+osapi.container.util.newTokenRequest = function(gadgetUrls) {
+  if (!osapi.container.util.isArray(gadgetUrls)) {
+    gadgetUrls = [gadgetUrls];
+  }
+  return {
+    'container': window.__CONTAINER,
+    'ids': gadgetUrls,
+    'fields': [
+      'token'
+    ]
+  };
+};
+
+
+/**
+ * Extract keys from a JSON to an array.
+ * @param {Object} json to extract keys from.
+ * @return {Array.<string>} keys in the json.
+ */
+osapi.container.util.toArrayOfJsonKeys = function(json) {
+  var result = [];
+  for (var key in json) {
+    result.push(key);
+  }
+  return result;
+};
+
+
+/**
+ * Tests an object to see if it is an array or not.
+ * @param {object} obj Object to test.
+ * @return {boolean} If obj is an array.
+ */
+osapi.container.util.isArray = function(obj) {
+  return Object.prototype.toString.call(obj) == '[object Array]';
+};
+
+
+/**
+ * @param {Object} json to check.
+ * @return {Boolean} true if json is empty.
+ */
+osapi.container.util.isEmptyJson = function(json) {
+  for (var key in json) {
+    return false;
+  }
+  return true;
+};
+
+
+/**
+ * Put up a warning message to console.
+ * @param {String} message to warn with.
+ */
+osapi.container.util.warn = function(message) {
+  if (console && console.warn) {
+    console.warn(message);
+  }
+};
+
+
+/**
+ * @return {number} current time in ms.
+ */
+osapi.container.util.getCurrentTimeMs = function() {
+  return new Date().getTime();
+};
+
+/**
+ * Crates the HTML for the iFrame
+ * @param {Object.<string,string>} iframeParams iframe Params.
+ * @return {string} the HTML for the iFrame.
+ */
+osapi.container.util.createIframeHtml = function(iframeParams) {
+
+  // Do not use DOM API (createElement(), setAttribute()), since it is slower,
+  // requires more code, and creating an element with it results in a click
+  // sound in IE (unconfirmed), setAttribute('class') may need browser-specific
+  // variants.
+  var out = [];
+  out.push('<iframe ');
+  for (var key in iframeParams) {
+      var value = iframeParams[key];
+      if (value) {
+          out.push(key);
+          out.push('="');
+          out.push(value);
+          out.push('" ');
+      }
+  }
+  out.push('></iframe>');
+
+  return out.join('');
+};

Added: trunk/htdocs/js/apps/shindig/core.io/feature.xml
===================================================================
--- trunk/htdocs/js/apps/shindig/core.io/feature.xml	                        (rev 0)
+++ trunk/htdocs/js/apps/shindig/core.io/feature.xml	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<feature>
+<!--
+  Required configuration:
+
+  proxyUrl: A url template containing the placeholder "%url%", which will be
+      used for all calls to gadgets.io.getProxyUrl(string), with the value
+      passed in being used as the replacement.
+  jsonProxyUrl: A url pointing to the JSON proxy endpoint, used by
+      gadgets.io.makeRequest. All data passed to this end point will be
+      encoded inside of the POST body.
+-->
+  <name>core.io</name>
+  <dependency>globals</dependency>
+  <dependency>taming</dependency>
+  <dependency>shindig.auth</dependency>
+  <dependency>core.config.base</dependency>
+  <dependency>core.json</dependency>
+  <dependency>core.util.base</dependency>
+  <dependency>core.util.urlparams</dependency>
+  <all>
+    <script src="io.js"/>
+    <script src="taming.js" caja="1"/>
+    <api>
+      <exports type="js">gadgets.io.makeRequest</exports>
+      <exports type="js">gadgets.io.makeNonProxiedRequest</exports>
+      <exports type="js">gadgets.io.clearOAuthState</exports>
+      <exports type="js">gadgets.io.encodeValues</exports>
+      <exports type="js">gadgets.io.getProxyUrl</exports>
+      <exports type="js">gadgets.io.RequestParameters</exports>
+      <exports type="js">gadgets.io.MethodType</exports>
+      <exports type="js">gadgets.io.ContentType</exports>
+      <exports type="js">gadgets.io.AuthorizationType</exports>
+    </api>
+  </all>
+</feature>

Added: trunk/htdocs/js/apps/shindig/core.io/io.js
===================================================================
--- trunk/htdocs/js/apps/shindig/core.io/io.js	                        (rev 0)
+++ trunk/htdocs/js/apps/shindig/core.io/io.js	2011-10-31 07:19:19 UTC (rev 20448)
@@ -0,0 +1,588 @@
+/*
+ * 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.
+ */
+
+/*global ActiveXObject, DOMParser */
+/*global shindig */
+
+/**
+ * @fileoverview Provides remote content retrieval facilities.
+ *     Available to every gadget.
+ */
+
+/**
+ * @class Provides...
 (truncated)
Tags: can3p, dpetrov, js, livejournal, xml
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments