Author: mfranklin
Date: Fri Sep 13 18:40:15 2013
New Revision: 1523056

URL: http://svn.apache.org/r1523056
Log:
Added basic infrastructure for container actions (RAVE-1056)

Added:
    rave/trunk/rave-demo-gadgets/src/main/webapp/actions_contributions.xml
      - copied, changed from r1522894, 
rave/trunk/rave-demo-gadgets/src/main/webapp/my_experience.xml
    
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_action_manager.js
    
rave/trunk/rave-portal-resources/src/test/javascript/core/rave_action_manager.spec
      - copied, changed from r1522894, 
rave/trunk/rave-portal-resources/src/test/javascript/core/rave_view_manager.spec
Modified:
    rave/trunk/rave-portal-resources/src/main/resources/db/initial-data.json
    rave/trunk/rave-portal-resources/src/main/resources/portal.properties
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/main.js
    
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js
    rave/trunk/rave-portal-resources/src/test/dependencies/osapi.js

Copied: rave/trunk/rave-demo-gadgets/src/main/webapp/actions_contributions.xml 
(from r1522894, rave/trunk/rave-demo-gadgets/src/main/webapp/my_experience.xml)
URL: 
http://svn.apache.org/viewvc/rave/trunk/rave-demo-gadgets/src/main/webapp/actions_contributions.xml?p2=rave/trunk/rave-demo-gadgets/src/main/webapp/actions_contributions.xml&p1=rave/trunk/rave-demo-gadgets/src/main/webapp/my_experience.xml&r1=1522894&r2=1523056&rev=1523056&view=diff
==============================================================================
--- rave/trunk/rave-demo-gadgets/src/main/webapp/my_experience.xml (original)
+++ rave/trunk/rave-demo-gadgets/src/main/webapp/actions_contributions.xml Fri 
Sep 13 18:40:15 2013
@@ -20,42 +20,68 @@
   $Id:$
 -->
 <Module>
-    <ModulePrefs title="My Experience" author="" author_email="" height="" 
description="Static widget of experience for demoing on the Person Profile 
page">
+    <ModulePrefs title="Actions Contributions Example" author="Rave Project" 
author_email="[email protected]" height="" description="Simple example of 
how to leverage container actions">
         <Require feature="dynamic-height" />
+        <Require feature="actions" />
+        <Require feature="setprefs" />
     </ModulePrefs>
 
     <Content type="html" view="home">
        <![CDATA[
-          <div class="header">Work Experience</div>
-          <ul>
-            <li>2011-Present: Apache Rave Developer
-            <li>2008-2011: Database Administrator
-            <li>2006-2008: JSF Developer
-            <li>2002-2006: Struts Developer
-            <li>2001-2002: ASP Developer
-            <li>1997-2001: JavaScript Developer
-          </ul>
-          <div class="header">School Experience</div>
-          <ul>
-            <li>1993-1997: University of Somewhere
-          </ul>
-          <div class="header">Skill Experience:</div>
-          <ul>
-               <li>Java
-               <li>JavaScript
-               <li>HTML
-               <li>RDBMS
-          </ul>
-          <style>
-            .header {
-               border-bottom: 1px solid #CCCCCC;
-               color: #228800;
-            }
-            li {
-                font-size: 10pt;
-            }
-          </style>
+          <link rel="stylesheet" 
href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css"
 />
+          <script 
src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0/handlebars.min.js"></script>
+          <script type="text/x-handlebars-template" id="template">
+            {{#each_entry this}}
+                <h3>{{key}}</h3>
+                <ul>
+                {{#each 
value}}<li><b>{{id}}:</b><span>{{description}}</span></li>{{/each}}
+                </ul>
+            {{/each_entry}}
+          </script>
+          <div id="render"></div>
           <script>
+              Handlebars.registerHelper("each_entry", function(obj, options) {
+                var buffer = "", key;
+                for (key in obj) { if (obj.hasOwnProperty(key)) buffer += 
options.fn({key: key, value: obj[key]}); }
+                return buffer;
+              });
+              var template = 
Handlebars.compile(document.getElementById("template").innerHTML);
+              var elem = document.getElementById("render");
+
+              function actionCallback(args) {
+                alert("Action called: " + args);
+              }
+
+              var moduleId = (new gadgets.Prefs()).getModuleId();
+
+              var actions = {};
+
+              var warning = {
+                    id: "org.apache.rave.gadget." + moduleId + 
".toolbarAction.warning",
+                    tooltip: "This is a warning",
+                    label: "Take Warning",
+                    icon: "css:icon-warning-sign",
+                    callback: actionCallback,
+                    path: "/gadget/toolbar",
+                    moduleId: moduleId,
+                    description: "Toolbar action as an image that when clicked 
fires the action"
+                };
+              actions[warning.path] = [warning];
+              gadgets.actions.addAction(warning);
+
+              var open = {
+                    id: "org.apache.rave.gadget." + moduleId + 
".toolbarAction.open",
+                    tooltip: "This is a folder open",
+                    label: "Open File",
+                    icon: "css:icon-folder-open",
+                    callback: actionCallback,
+                    path: "/gadget/toolbar",
+                    moduleId: moduleId,
+                    description: "Toolbar action as an image that when clicked 
fires the action"
+                };
+              actions[open.path].push(open);
+              gadgets.actions.addAction(open);
+              elem.innerHTML = template(actions);
               gadgets.util.registerOnLoadHandler(gadgets.window.adjustHeight);
           </script>
        ]]>

Modified: 
rave/trunk/rave-portal-resources/src/main/resources/db/initial-data.json
URL: 
http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/resources/db/initial-data.json?rev=1523056&r1=1523055&r2=1523056&view=diff
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/resources/db/initial-data.json 
(original)
+++ rave/trunk/rave-portal-resources/src/main/resources/db/initial-data.json 
Fri Sep 13 18:40:15 2013
@@ -1236,6 +1236,17 @@
             "disableRendering": false,
             "featured": false,
             "widgetStatus": "PUBLISHED"
+        },
+        {
+            "id": 31,
+            "title": "Actions Example",
+            "url": 
"http://localhost:8080/demogadgets/actions_contributions.xml";,
+            "type": "OpenSocial",
+            "author": "Rave Project",
+            "description": "Actions contributions examples",
+            "disableRendering": false,
+            "featured": false,
+            "widgetStatus": "PUBLISHED"
         }
     ],
     "authorities": [

Modified: rave/trunk/rave-portal-resources/src/main/resources/portal.properties
URL: 
http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/resources/portal.properties?rev=1523056&r1=1523055&r2=1523056&view=diff
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/resources/portal.properties 
(original)
+++ rave/trunk/rave-portal-resources/src/main/resources/portal.properties Fri 
Sep 13 18:40:15 2013
@@ -27,7 +27,7 @@ portal.version=${project.version}
 portal.opensocial_engine.protocol=http
 portal.opensocial_engine.root=localhost:8080
 portal.opensocial_engine.gadget_path=/gadgets
-portal.opensocial_engine.container_features=container:pubsub-2:open-views
+portal.opensocial_engine.container_features=container:pubsub-2:open-views:actions
 
 
portal.opensocial_security.encryptionkey=classpath:security_token_encryption_key.txt
 portal.opensocial_security.container=default

Modified: 
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/main.js
URL: 
http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/main.js?rev=1523056&r1=1523055&r2=1523056&view=diff
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/main.js 
(original)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/main.js 
Fri Sep 13 18:40:15 2013
@@ -41,8 +41,8 @@
  * });
  */
 define(['underscore', 'core/rave_widget_manager', 'core/rave_api', 
'core/rave_widget', 'core/rave_log',
-    'core/rave_event_manager', 'core/rave_view_manager', 
'core/rave_state_manager', 'core/rave_openajax_hub'],
-    function (_, widgetManager, api, RegionWidget, log, eventManager, 
viewManager, stateManager, managedHub) {
+    'core/rave_event_manager', 'core/rave_view_manager', 
'core/rave_state_manager', 'core/rave_openajax_hub', 
'core/rave_action_manager'],
+    function (_, widgetManager, api, RegionWidget, log, eventManager, 
viewManager, stateManager, managedHub, actionManager) {
 
         var exports = {};
 
@@ -70,6 +70,7 @@ define(['underscore', 'core/rave_widget_
         _.extend(exports, viewManager);
         _.extend(exports, widgetManager);
         _.extend(exports, stateManager);
+        _.extend(exports, actionManager);
 
         return exports;
     }

Added: 
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_action_manager.js
URL: 
http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_action_manager.js?rev=1523056&view=auto
==============================================================================
--- 
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_action_manager.js
 (added)
+++ 
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_action_manager.js
 Fri Sep 13 18:40:15 2013
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * Manages rave the registering and rendering of menu and toolbar actions.
+ * @module rave_action_manager
+ */
+define(['underscore'], function(_){
+    /**
+     * @typedef RegionWidget
+     * @see module:rave_widget
+     */
+    var actionHandlers = [];
+    var exports = {};
+
+    /**
+     * Registers a new action with the action_manager and calls all 
actionHandlers' create function
+     * @param path {string} path to the action /gadget/toolbar, /gadget/menu, 
/container/menu, etc
+     * @param widgetId {string} the id of the widget contributing the action
+     * @param fnAction function to call when the action is selected
+     */
+    exports.createAction = function(path, widgetId, fnAction) {
+        _.invoke(actionHandlers, 'create', [path, widgetId, fnAction]);
+    }
+
+    /**
+     * Removes an action by calling all actionHandlers remove function
+     * @param {string} path to the action /gadget/toolbar, /gadget/menu, 
/container/menu, etc
+     * @param widgetId {string} the id of the widget contributing the action
+     */
+    exports.removeAction = function(path, widgetId) {
+        _.invoke(actionHandlers, 'remove', [path, widgetId]);
+    }
+
+    /**
+     * Registers a UI manager for rendering and hiding UI elements for actions 
contributed by widgets
+     * @param {object} manager structure: { createAction : function(path, 
widget), removeAction: function(path, widget)}
+     */
+    exports.registerActionHandler = function(manager) {
+        actionHandlers.push(manager);
+    }
+    return exports;
+})
\ No newline at end of file

Modified: 
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js
URL: 
http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js?rev=1523056&r1=1523055&r2=1523056&view=diff
==============================================================================
--- 
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js
 (original)
+++ 
rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js
 Fri Sep 13 18:40:15 2013
@@ -26,8 +26,8 @@
  * @requires rave_log
  * @requires rave_state_manager
  */
-define(['underscore', 'core/rave_view_manager', 'core/rave_api', 
'core/rave_openajax_hub', 'core/rave_log', 'core/rave_state_manager', 'osapi'],
-    function (_, viewManager, api, managedHub, log, stateManager) {
+define(['underscore', 'core/rave_view_manager', 'core/rave_api', 
'core/rave_openajax_hub', 'core/rave_log', 'core/rave_state_manager', 
'core/rave_action_manager', 'osapi'],
+    function (_, viewManager, api, managedHub, log, stateManager, 
actionManager) {
         var exports = {};
 
         var container;
@@ -43,6 +43,7 @@ define(['underscore', 'core/rave_view_ma
 
         rpcRegister();
         implementViews();
+        implementActions();
 
 
         function rpcRegister() {
@@ -113,6 +114,22 @@ define(['underscore', 'core/rave_view_ma
             };
         }
 
+        function implementActions() {
+            container.actions.registerShowActionsHandler(function(actions) {
+                _.each(actions, function(action){
+                    actionManager.createAction(action.path, action.moduleId, 
function() {
+                        container.actions.runAction(action.id);
+                    })
+                })
+            });
+
+            container.actions.registerHideActionsHandler(function (actions){
+                _.each(actions, function(action){
+                    actionManager.removeAction(action.path, action.moduleId);
+                })
+            });
+        }
+
         function requestNavigateTo(args, viewName, opt_params, opt_ownerId) {
             var widget = args.gs._widget,
                 viewSurface = viewName.split('.')[0],
@@ -195,6 +212,7 @@ define(['underscore', 'core/rave_view_ma
             opts = opts || {};
             var site = container.newGadgetSite(el);
             site._widget = widget;
+            site.moduleId_ = widget.regionWidgetId;
             widget._site = site;
 
             var renderParams = {};
@@ -206,6 +224,7 @@ define(['underscore', 'core/rave_view_ma
             renderParams[osapi.container.RenderParam.TEST_MODE] = 
opts.testMode || stateManager.getDebugMode();
             renderParams[osapi.container.RenderParam.WIDTH ] = 
getWidthFromParams(opts);
             renderParams[osapi.container.RenderParam.USER_PREFS] = 
getCompleteUserPrefSet(widget.userPrefs, widget.metadata.userPrefs);
+            renderParams[osapi.container.RenderParam.MODULE_ID] = 
widget.regionWidgetId;
             container.navigateGadget(site, widget.widgetUrl, opts.view_params, 
renderParams, opts.callback);
         }
 
@@ -233,7 +252,10 @@ define(['underscore', 'core/rave_view_ma
             commonContainerTokenData[osapi.container.TokenResponse.TOKEN] = 
gadget.securityToken;
             
commonContainerTokenData[osapi.container.MetadataResponse.RESPONSE_TIME_MS] = 
new Date().getTime();
             var commonContainerTokenWrapper = {};
+            //Shindig will look for the specific moduleId security token.  
Since that is the same as the default in our case
+            //set them both to the same value.
             commonContainerTokenWrapper[gadget.widgetUrl] = 
commonContainerTokenData;
+            commonContainerTokenWrapper[gadget.widgetUrl + "#moduleId=" + 
gadget.regionWidgetId] = commonContainerTokenData;
 
             //Setup the preloadConfig data with all our preload data
             var preloadConfig = {};

Modified: rave/trunk/rave-portal-resources/src/test/dependencies/osapi.js
URL: 
http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/test/dependencies/osapi.js?rev=1523056&r1=1523055&r2=1523056&view=diff
==============================================================================
--- rave/trunk/rave-portal-resources/src/test/dependencies/osapi.js (original)
+++ rave/trunk/rave-portal-resources/src/test/dependencies/osapi.js Fri Sep 13 
18:40:15 2013
@@ -17,13 +17,12 @@
  * under the License.
  */
 
-
 window.___jsl=window.___jsl||{};
 
(window.___jsl.ci=window.___jsl.ci||[]).push({opensocial:{invalidatePath:"http://%host%/rpc",path:"http://%host%/rpc",domain:"shindig",supportedFields:{person:["id",{name:["familyName","givenName","unstructured"]},"thumbnailUrl","profileUrl"],mediaItem:"album_id
 created description duration file_size id language last_updated location 
mime_type num_comments num_views num_votes rating start_time tagged_people tags 
thumbnail_url title type url".split(" "),album:"id thumbnailUrl title 
description location ownerId".split(" "),group:["id",
-    "title","description"],activity:"appId body bodyId externalId id 
mediaItems postedTime priority streamFaviconUrl streamSourceUrl streamTitle 
streamUrl templateParams title url userId".split(" "),activityEntry:"actor 
content generator icon id object published provider target title updated url 
verb openSocial extensions".split(" 
")},enableCaja:!1},rpc:{commSwf:"/xpc.swf",passReferrer:"c2p:query",parentRelayUrl:"/container/rpc_relay.html",useLegacyProtocol:!1},"shindig.auth":{},views:{"default":{isOnlyVisible:!1,
-    
urlTemplate:"http://localhost/gadgets/default?{var}",aliases:["home","profile","canvas"]},canvas:{isOnlyVisible:!0,urlTemplate:"http://localhost/gadgets/canvas?{var}",aliases:["FULL_PAGE"]},profile:{isOnlyVisible:!1,urlTemplate:"http://localhost/gadgets/profile?{var}",aliases:["DASHBOARD","default"]}},container:{jsPath:"/gadgets/js",relayPath:"/gadgets/files/container/rpc_relay.html",enableRpcArbitration:!1},osapi:{endPoints:["//%host%/rpc"]},"osapi.services":{"gadgets.rpc":["container.listMethods";],
+    "title","description"],activity:"appId body bodyId externalId id 
mediaItems postedTime priority streamFaviconUrl streamSourceUrl streamTitle 
streamUrl templateParams title url userId".split(" "),activityEntry:"actor 
content generator icon id object published provider target title updated url 
verb openSocial extensions".split(" 
")},enableCaja:!1},rpc:{commSwf:"/xpc.swf",passReferrer:"c2p:query",parentRelayUrl:"/container/rpc_relay.html",useLegacyProtocol:!1},"shindig.auth":{},container:{jsPath:"/gadgets/js",
+    
relayPath:"/gadgets/files/container/rpc_relay.html",enableRpcArbitration:!1},views:{"default":{isOnlyVisible:!1,urlTemplate:"http://localhost/gadgets/default?{var}",aliases:["home","profile","canvas"]},canvas:{isOnlyVisible:!0,urlTemplate:"http://localhost/gadgets/canvas?{var}",aliases:["FULL_PAGE"]},profile:{isOnlyVisible:!1,urlTemplate:"http://localhost/gadgets/profile?{var}",aliases:["DASHBOARD","default"]}},osapi:{endPoints:["//%host%/rpc"]},"osapi.services":{"gadgets.rpc":["container.listMethods";],
     "//%host%/rpc":"samplecontainer.update activities.supportedFields 
gadgets.metadata albums.supportedFields gadgets.proxySupportedFields albums.get 
mediaItems.create http.put system.listMethods gadgets.proxy gadgets.cajole 
http.head messages.create albums.delete mediaItems.update messages.delete 
appdata.update gadgets.js http.post gadgets.tokenSupportedFields 
samplecontainer.create http.get appdata.delete appdata.create 
gadgets.supportedFields mediaItems.get activities.update activities.delete 
albums.update activities.get messages.modify activitystreams.create appdata.get 
messages.get cache.invalidate samplecontainer.get people.supportedFields 
groups.get http.delete gadgets.jsSupportedFields people.get activitystreams.get 
mediaItems.supportedFields mediaItems.delete activitystreams.update 
gadgets.cajaSupportedFields activities.create albums.create people.update 
gadgets.token activitystreams.delete activitystreams.supportedFields".split(" 
")},
-    "core.io":{unparseableCruft:"throw 1; < don't be evil' 
>",jsonProxyUrl:"//%host%/gadgets/makeRequest",jsPath:"/gadgets/js",proxyUrl:"//%host%/gadgets/proxy%filename%?container=%container%&refresh=%refresh%&url=%url%%authz%%rewriteMime%",xhrPollIntervalMs:50}});window.___jsl=window.___jsl||{};window['___jsl']['f']
 = 
['auth-refresh','container','container.site','container.site.gadget','container.site.url','container.util','core','core.config','core.config.base','core.io','core.json','core.legacy','core.log','core.prefs','core.util','core.util.base','core.util.dom','core.util.event','core.util.onload','core.util.string','core.util.urlparams','embedded-experiences','gadgets.json.ext','globals','locked-domain','open-views','open-views.common','open-views.ee','open-views.gadget','open-views.results','open-views.url','opensocial','opensocial-base','opensocial-data-context','opensocial-jsonrpc','opensocial-reference','org.openajax.hub-2.0.7','osapi','osapi.base','presence','pubsub-2','r
 
pc','security-token','shindig.auth','shindig.uri','shindig.uri.ext','taming','views','xmlutil'];gadgets=window.gadgets||{};shindig=window.shindig||{};osapi=window.osapi||{};var
 
safeJSON=window.safeJSON,tamings___=window.tamings___||[],bridge___,caja___=window.caja___,___=window.___;window.gadgets.config||(gadgets.config=function(){function
 j(a,b){for(var e in b)b.hasOwnProperty(e)&&("object"===typeof 
a[e]&&"object"===typeof b[e]?j(a[e],b[e]):a[e]=b[e])}function n(a){var 
b="";if(3==a.nodeType||4==a.nodeType)b=a.nodeValue;else 
if(a.innerText)b=a.innerText;else if(a.innerHTML)b=a.innerHTML;else 
if(a.firstChild){b=[];for(a=a.firstChild;a;a=a.nextSibling)b.push(n(a));b=b.join("")}return
 b}function o(a){var 
b=(f["core.io"]||{}).jsPath||null,e=[],d=0,c=document.scripts||document.getElementsByTagName("script");
+    "core.io":{unparseableCruft:"throw 1; < don't be evil' 
>",jsonProxyUrl:"//%host%/gadgets/makeRequest",jsPath:"/gadgets/js",proxyUrl:"//%host%/gadgets/proxy%filename%?container=%container%&refresh=%refresh%&url=%url%%authz%%rewriteMime%",xhrPollIntervalMs:50}});window.___jsl=window.___jsl||{};window['___jsl']['f']
 = 
['actions','auth-refresh','container','container.site','container.site.gadget','container.site.url','container.util','core.config','core.config.base','core.io','core.json','core.log','core.prefs','core.util','core.util.base','core.util.dom','core.util.event','core.util.onload','core.util.string','core.util.urlparams','embedded-experiences','gadgets.json.ext','globals','locked-domain','open-views','open-views.common','open-views.ee','open-views.gadget','open-views.results','open-views.url','opensocial','opensocial-base','opensocial-data-context','opensocial-jsonrpc','opensocial-reference','org.openajax.hub-2.0.7','osapi','osapi.base','pubsub-2','rpc','security-token','
 
shindig.auth','shindig.uri','shindig.uri.ext','taming','views','xmlutil'];gadgets=window.gadgets||{};shindig=window.shindig||{};osapi=window.osapi||{};var
 
safeJSON=window.safeJSON,tamings___=window.tamings___||[],bridge___,caja___=window.caja___,___=window.___;window.gadgets.config||(gadgets.config=function(){function
 j(a,b){for(var e in b)b.hasOwnProperty(e)&&("object"===typeof 
a[e]&&"object"===typeof b[e]?j(a[e],b[e]):a[e]=b[e])}function n(a){var 
b="";if(3==a.nodeType||4==a.nodeType)b=a.nodeValue;else 
if(a.innerText)b=a.innerText;else if(a.innerHTML)b=a.innerHTML;else 
if(a.firstChild){b=[];for(a=a.firstChild;a;a=a.nextSibling)b.push(n(a));b=b.join("")}return
 b}function o(a){var 
b=(f["core.io"]||{}).jsPath||null,e=[],d=0,c=document.scripts||document.getElementsByTagName("script");
     if(c&&0!=c.length){for(var h=0;h<c.length;++h){var 
g=c[h].src,i=null!=b&&g&&g.indexOf(b)||-1;-1!=i&&/.*[.]js.*[?&]c=[01](#|&|$).*/.test(g.substring(i+b.length))&&(e[d++]=c[h])}e.length||(b=c[c.length-1],b.src&&(e[0]=b))}if(e.length)for(b=0;b<e.length;b++){d=n(e[b]);c=void
 0;try{c=(new Function("return ("+d+"\n)"))()}catch(l){}if("object"===typeof 
c)d=c;else{try{c=(new Function("return 
({"+d+"\n})"))()}catch(m){}d="object"===typeof 
c?c:{}}k.f&&1==k.f.length&&!d[k.f[0]]&&(c={},c[k.f[0]]=d,d=c);j(a,
         d);(d=window.___cfg)&&j(a,d)}}function m(a){for(var b in 
i)if(i.hasOwnProperty(b))for(var e=i[b],d=0,c=e.length;d<c;++d)a(b,e[d])}var 
k,i={},f={},l=!1;return{register:function(a,b,e,d){var 
c=i[a];c||(c=[],i[a]=c);c.push({validators:b||{},callback:e,callOnUpdate:d});l&&e&&e(f)},get:function(a){return
 
a?f[a]||{}:f},init:function(a,b){k=window.___jsl||{};j(f,a);o(f);j(f,window.___config||{});m(function(a,d){var
 c=f[a];if(c&&!b){var h=d.validators,g;for(g in 
h)if(h.hasOwnProperty(g)&&!h[g](c[g]))throw Error('Invalid config value "'+
     c[g]+'" for parameter "'+g+'" in component 
"'+a+'"');}d.callback&&d.callback(f)});l=!0},update:function(a,b){var 
e=[];m(function(c,d){(a.hasOwnProperty(c)||b&&f&&f[c])&&d.callback&&d.callOnUpdate&&e.push(d.callback)});f=b?{}:f||{};j(f,a);for(var
 d=0,c=e.length;d<c;++d)e[d](f)},clear:function(){gadgets.warn("This method is 
for testing.");k=void 0;f={};l=!1}}}());gadgets.log=function(){function 
d(a,c){"undefined"===typeof 
b&&(b=window.console?window.console:window.opera?window.opera.postError:null);!(a<e)&&b&&(2===a&&b.warn?b.warn(c):3===a&&b.error?b.error(c):b.log&&b.log(c))}var
 
c=function(a){d(1,a)};gadgets.warn=function(a){d(2,a)};gadgets.error=function(a){d(3,a)};gadgets.setLogLevel=function(a){e=a};c.INFO=1;c.WARNING=2;c.NONE=4;var
 e=1,b;return c}();(function(){gadgets.config.EnumValidator=function(a){var 
c=[];if(1<arguments.length)for(var b=0,d;d=arguments[b];++b)c.push(d);else 
c=a;return function(a){for(var 
b=0;c[b];++b)if(a===c[b])return!0;return!1}};gadgets.config.RegExVa
 lidator=function(a){return function(c){return 
a.test(c)}};gadgets.config.ExistsValidator=function(a){return"undefined"!==typeof
 a};gadgets.config.NonEmptyStringValidator=function(a){return"string"===typeof 
a&&0<a.length};gadgets.config.BooleanValidator=function(a){return"boolean"===
@@ -186,21 +185,7 @@ opensocial.xmlutil.prepareXML=function(b
     (f=c.viewParams),c.coordinates))d=c.coordinates;var 
l=h.getGadgetSiteByIframeId_(k),o=l.getActiveSiteHolder().getIframeElement(),n=j.getContainerAssociatedContext(b,g);(g=j.createElementForEmbeddedExperience(o,g,a,d,l,e))&&e(g)};e?h.preloadGadget(e,function(a){(!a[e]||a[e].error)&&!b.url?null!=i&&i([null,a[e]||{error:a}]):d(a[e])}):d()});this.createElementForEmbeddedExperience=function(){console.log("container
 needs to define createElementForEmbeddedExperience 
function")};this.getContainerAssociatedContext=
     function(){return 
null}});osapi.container.Container.addMixin("views",function(e){var 
i=this;e.rpcRegister("gadgets.views.openGadget",function(d,n,a){var 
g=d.callback,o=d.f,c="",b=e.getGadgetSiteByIframeId_(d.f);"undefined"!=typeof 
b&&"undefined"!=typeof 
b.getActiveSiteHolder()&&(c=b.getActiveSiteHolder().getUrl());var 
f="",j="",k={},l;if(a&&(a.view&&(f=a.view),a.viewTarget&&(j=a.viewTarget),a.viewParams&&(k=a.viewParams),a.coordinates))l=a.coordinates;var
 p=e.getGadgetSiteByIframeId_(d.f).getActiveSiteHolder().getIframeElement();
     e.preloadGadget(c,function(a){function d(a){var 
b={},h=e.newGadgetSite(a);h.ownerId_=o;"undefined"!=typeof 
f&&""!==f&&(b[osapi.container.RenderParam.VIEW]=f);b[osapi.container.RenderParam.WIDTH]="100%";b[osapi.container.RenderParam.HEIGHT]="100%";e.navigateGadget(h,c,k,b,function(a){a&&(i.resultCallbacks_[h.getId()]=n);g&&g([h.getId(),a])})}var
 m={};if("undefined"!=typeof a&&"undefined"!=typeof 
a[c]){if(a[c].error){gadgets.error("Failed to preload gadget : 
"+c);null!=g&&g([null,a[c]]);return}m=a[c]}(a=
-        
i.createElementForGadget(m,p,f,j,l,b,d))&&d(a)})});this.createElementForGadget=function(){console.log("container
 needs to define createElementForGadget 
function")}});osapi.container.Container.addMixin("views",function(c){var 
g=this;c.rpcRegister("gadgets.views.openUrl",function(d,h,a,i){function 
e(b){var 
b=c.newUrlSite(b),a={};a[osapi.container.RenderParam.WIDTH]="100%";a[osapi.container.RenderParam.HEIGHT]="100%";c.navigateUrl(b,h,a);b.ownerId_=d.f;d.callback([b.getId()])}var
 
f=c.getGadgetSiteByIframeId_(d.f),j=f.getActiveSiteHolder().getIframeElement();(a=g.createElementForUrl(j,a,i,f,e))&&e(a)});this.createElementForUrl=function(){console.log("container
 needs to define createElementForUrl function")}});var 
PresenceControlbrowseris=new 
PresenceControlBrowseris,PresenceControlObject=null,bPresenceControlInited=!1,PresenceControlURIDictionaryObj=null,PresenceControlStatesDictionaryObj=null,PresenceControlOrigScrollFunc=null,bPresenceControlInScrollFunc=!1;
-function 
EnsurePresenceControl(){if(!bPresenceControlInited){if(PresenceControlbrowseris.ie5up&&PresenceControlbrowseris.win32)try{PresenceControlObject=new
 
ActiveXObject("Name.NameCtrl.1")}catch(a){console.log(a.message)}bPresenceControlInited=!0;PresenceControlObject&&(PresenceControlObject.OnStatusChange=PresenceControlOnStatusChange)}return
 PresenceControlObject}
-function 
PresenceControlOnStatusChange(a,d,b){PresenceControlStatesDictionaryObj&&(a=PresenceControlGetStatusImage(d,PresenceControlStatesDictionaryObj[b]),PresenceControlStatesDictionaryObj[b]!=d&&(PresenceControlUpdateImage(b,a),PresenceControlStatesDictionaryObj[b]=d))}function
 PresenceControlShowOOUIMouse(){PresenceControlShowOOUI(0)}function 
PresenceControlShowOOUIFocus(){PresenceControlShowOOUI(1)}
-function 
PresenceControlShowOOUI(a){if(PresenceControlbrowseris.ie5up&&PresenceControlbrowseris.win32){var
 
d=window.event.srcElement,b=d,c=d,e=0,f=0;EnsurePresenceControl()&&PresenceControlURIDictionaryObj&&(f=PresenceControlGetOOUILocation(d,!1),b=f.objSpan,c=f.objOOUI,e=f.oouiX,f=f.oouiY,c=PresenceControlURIDictionaryObj[c.id],b&&(b.onkeydown=PresenceControlHandleAccelerator),PresenceControlObject.ShowOOUI(c,a,e,f))}}function
 PresenceControlHideOOUI(){PresenceControlObject.HideOOUI()}
-function PresenceControlGetStatusImage(a,d){var 
b="presence-unknown.png";switch(a){case 0:b="presence-online.png";break;case 
1:b="presence-off.png";break;case 2:b="presence-away.png";break;case 
3:b=3!=d?"presence-busy.png":"presence-idle-busy.png";break;case 
4:b="presence-away.png";break;case 5:b="presence-away.png";break;case 
6:b="presence-away.png";break;case 7:if(7!=d){b="presence-busy.png";break}else 
b="presence-idle-busy.png";break;case 9:b="presence-dnd.png";break;case 
16:b="presence-idle-online.png"}return b}
-function PresenceControlUpdateImage(a,d){var b=document.images(a);if(b){var 
c=b.src,e=c.lastIndexOf("/"),e=c.slice(0,e+1),e=e+d;c!=e&&(b.src=e);b.altbase&&(b.alt=b.altbase)}}function
 
PresenceControlScroll(){bPresenceControlInScrollFunc||(bPresenceControlInScrollFunc=!0,PresenceControlHideOOUI());bPresenceControlInScrollFunc=!1;return
 PresenceControlOrigScrollFunc?PresenceControlOrigScrollFunc():!0}
-function PresenceControl(a,d,b){if(null==a||""==a)$(d).parent().html("");else 
if(PresenceControlbrowseris.ie5up&&PresenceControlbrowseris.win32){var 
c=d,c=d.id,e=!1;PresenceControlStatesDictionaryObj||(PresenceControlStatesDictionaryObj={},PresenceControlURIDictionaryObj={},PresenceControlOrigScrollFunc||(PresenceControlOrigScrollFunc=window.onscroll,window.onscroll=PresenceControlScroll));if(PresenceControlStatesDictionaryObj){if(!PresenceControlURIDictionaryObj[c]||b)PresenceControlURIDictionaryObj[c]=
-    a,e=!0;"undefined"==typeof 
PresenceControlStatesDictionaryObj[c]&&(PresenceControlStatesDictionaryObj[c]=1);e&&(EnsurePresenceControl()&&PresenceControlObject.PresenceEnabled)&&(b=1,b=PresenceControlObject.GetStatus(a,c),a=PresenceControlGetStatusImage(b,PresenceControlStatesDictionaryObj[c]),PresenceControlUpdateImage(c,a),PresenceControlStatesDictionaryObj[c]=b)}if(e&&(c=PresenceControlGetOOUILocation(d,!1).objSpan))c.onmouseover=PresenceControlShowOOUIMouse,c.onfocusin=PresenceControlShowOOUIFocus,
-    
c.onmouseout=PresenceControlHideOOUI,c.onfocusout=PresenceControlHideOOUI}else 
$(d).parent().html("")}function 
PresenceControlHandleAccelerator(){PresenceControlObject&&event.altKey&&(event.shiftKey&&121==event.keyCode)&&PresenceControlObject.DoAccelerator()}
-function PresenceControlGetOOUILocation(a,d){for(var 
b={},c=a,e=a,f=0,g=0,i=0,k="rtl"==document.dir;c&&"SPAN"!=c.tagName&&"TABLE"!=c.tagName;)c=c.parentNode;if(c){var
 
j="TABLE"==c.tagName?c.rows(0).cells(0).childNodes:c.childNodes,h;for(h=0;h<j.length;++h)if("IMG"==j.item(h).tagName&&j.item(h).id){e=j.item(h);break}}for(a=e;a;)k?(i=a.scrollWidth>=a.clientWidth+a.scrollLeft?a.scrollWidth-a.clientWidth-a.scrollLeft:a.clientWidth+a.scrollLeft-a.scrollWidth,f+=a.offsetLeft+i):f+=a.offsetLeft-a.scrollLeft,
-    
g+=a.offsetTop-a.scrollTop,d&&alert(a.scrollTop),a=a.offsetParent;try{for(a=window.frameElement;a;)k?(i=a.scrollWidth>=a.clientWidth+a.scrollLeft?a.scrollWidth-a.clientWidth-a.scrollLeft:a.clientWidth+a.scrollLeft-a.scrollWidth,f+=a.offsetLeft+i):f+=a.offsetLeft-a.scrollLeft,g+=a.offsetTop-a.scrollTop,d&&alert(a.scrollTop),a=a.offsetParent}catch(l){}b.objSpan=c;b.objOOUI=e;b.oouiX=f;b.oouiY=g;k&&(b.oouiX+=e.offsetWidth);d&&alert(g);return
 b}
-function PresenceControlBrowseris(){var 
a=navigator.userAgent.toLowerCase();this.osver=1;if(a){var 
d=a.substring(a.indexOf("windows 
")+11);this.osver=parseFloat(d)}this.major=parseInt(navigator.appVersion);this.nav2=(this.nav=-1!=a.indexOf("mozilla")&&-1==a.indexOf("spoofer")&&-1==a.indexOf("compatible"))&&2==this.major;this.nav3=this.nav&&3==this.major;this.nav4=this.nav&&4==this.major;this.nav6=this.nav&&5==this.major;this.nav6up=this.nav&&5<=this.major;this.nav7up=!1;this.nav6up&&(d=a.indexOf("netscape/"),
-    
0<=d&&(this.nav7up=7<=parseInt(a.substring(d+9))));this.aol=(this.ie=-1!=a.indexOf("msie"))&&-1!=a.indexOf("
 aol ");this.ie?(d=a.substring(a.indexOf("msie 
")+5),this.iever=parseInt(d),this.verIEFull=parseFloat(d)):this.iever=0;this.ie3=this.ie&&2==this.major;this.ie4=this.ie&&4==this.major;this.ie4up=this.ie&&4<=this.major;this.ie5up=this.ie&&5<=this.iever;this.ie55up=this.ie&&5.5<=this.verIEFull;this.ie6up=this.ie&&6<=this.iever;this.win16=-1!=a.indexOf("win16")||-1!=a.indexOf("16bit")||-1!=a.indexOf("windows
 3.1")||
-    -1!=a.indexOf("windows 16-bit");this.win31=-1!=a.indexOf("windows 
3.1")||-1!=a.indexOf("win16")||-1!=a.indexOf("windows 
16-bit");this.win98=-1!=a.indexOf("win98")||-1!=a.indexOf("windows 
98");this.win95=-1!=a.indexOf("win95")||-1!=a.indexOf("windows 
95");this.winnt=-1!=a.indexOf("winnt")||-1!=a.indexOf("windows 
nt");this.win64=-1!=a.indexOf("win64")||-1!=a.indexOf("x64");this.win32=!this.win64&&(this.win95||this.winnt||this.win98||4<=this.major&&"Win32"==navigator.platform||-1!=a.indexOf("win32")||
-    
-1!=a.indexOf("32bit"));this.os2=-1!=a.indexOf("os/2")||-1!=navigator.appVersion.indexOf("OS/2")||-1!=a.indexOf("ibm-webexplorer");this.mac68k=(this.mac=-1!=a.indexOf("mac"))&&(-1!=a.indexOf("68k")||-1!=a.indexOf("68000"));this.macppc=this.mac&&(-1!=a.indexOf("ppc")||-1!=a.indexOf("powerpc"));this.w3c=this.nav6up};var
 OpenAjax=OpenAjax||{};
+        
i.createElementForGadget(m,p,f,j,l,b,d))&&d(a)})});this.createElementForGadget=function(){console.log("container
 needs to define createElementForGadget 
function")}});osapi.container.Container.addMixin("views",function(c){var 
g=this;c.rpcRegister("gadgets.views.openUrl",function(d,h,a,i){function 
e(b){var 
b=c.newUrlSite(b),a={};a[osapi.container.RenderParam.WIDTH]="100%";a[osapi.container.RenderParam.HEIGHT]="100%";c.navigateUrl(b,h,a);b.ownerId_=d.f;d.callback([b.getId()])}var
 
f=c.getGadgetSiteByIframeId_(d.f),j=f.getActiveSiteHolder().getIframeElement();(a=g.createElementForUrl(j,a,i,f,e))&&e(a)});this.createElementForUrl=function(){console.log("container
 needs to define createElementForUrl function")}});var OpenAjax=OpenAjax||{};
 OpenAjax.hub||(OpenAjax.hub=function(){var 
a={};return{implementer:"http://openajax.org",implVersion:"2.0.7",specVersion:"2.0",implExtraData:{},libraries:a,registerLibrary:function(b,c,d,e){a[b]={prefix:b,namespaceURI:c,version:d,extraData:e};this.publish("org.openajax.hub.registerLibrary",a[b])},unregisterLibrary:function(b){this.publish("org.openajax.hub.unregisterLibrary",a[b]);delete
 
a[b]}}}(),OpenAjax.hub.Error={BadParameters:"OpenAjax.hub.Error.BadParameters",Disconnected:"OpenAjax.hub.Error.Disconnected",Duplicate:"OpenAjax.hub.Error.Duplicate",
     
NoContainer:"OpenAjax.hub.Error.NoContainer",NoSubscription:"OpenAjax.hub.Error.NoSubscription",NotAllowed:"OpenAjax.hub.Error.NotAllowed",WrongProtocol:"OpenAjax.hub.Error.WrongProtocol",IncompatBrowser:"OpenAjax.hub.Error.IncompatBrowser"},OpenAjax.hub.SecurityAlert={LoadTimeout:"OpenAjax.hub.SecurityAlert.LoadTimeout",FramePhish:"OpenAjax.hub.SecurityAlert.FramePhish",ForgedMsg:"OpenAjax.hub.SecurityAlert.ForgedMsg"},OpenAjax.hub._debugger=function(){},OpenAjax.hub.ManagedHub=function(a){if(!a||
     !a.onPublish||!a.onSubscribe)throw 
Error(OpenAjax.hub.Error.BadParameters);this._p=a;this._onUnsubscribe=a.onUnsubscribe?a.onUnsubscribe:null;this._scope=a.scope||window;if(a.log){var
 b=this;this._log=function(c){try{a.log.call(b._scope,"ManagedHub: 
"+c)}catch(d){OpenAjax.hub._debugger()}}}else 
this._log=function(){};this._subscriptions={c:{},s:null};this._containers={};this._seq=0;this._active=!0;this._isPublishing=!1;this._pubQ=[]},OpenAjax.hub.ManagedHub.prototype.subscribeForClient=function(a,
@@ -248,8 +233,19 @@ OpenAjax.hub.InlineHubClient=function(a)
 OpenAjax._smash.crypto={strToWA:function(a,b){for(var 
f=[],c=(1<<b)-1,d=0;d<a.length*b;d=d+b)f[d>>5]=f[d>>5]|(a.charCodeAt(d/b)&c)<<32-b-d%32;return
 f},hmac_sha1:function(a,b,f){for(var 
c=Array(16),d=Array(16),g=0;g<16;g++){c[g]=a[g]^909522486;d[g]=a[g]^1549556828}a=this.sha1(c.concat(this.strToWA(b,f)),512+b.length*f);return
 this.sha1(d.concat(a),672)},newPRNG:function(a){function b(a){for(var 
a=f.hmac_sha1(c,a,8),b=0;b<5;b++)d[b]=d[b]^a[b]}var f=this;(typeof 
a!="string"||a.length<12)&&alert("WARNING: Seed length too short ...");
     var 
c=[43417,15926,18182,33130,9585,30800,49772,40144,47678,55453,4659,38181,65340,6787,54417,65301],d=[],g=0;b(a);return{addSeed:function(a){b(a)},nextRandomOctets:function(a){for(var
 b=[];a>0;){g=g+1;var 
c=f.hmac_sha1(d,g.toString(16),8);for(i=0;i<20&a>0;i++,a--)b.push((c[i>>2]>>i%4)%256)}return
 b},nextRandomB64Str:function(a){for(var 
b=this.nextRandomOctets(a),c="",d=0;d<a;d++)c=c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt(b[d]&63);return
 c}}},sha1:function(){var a=
     function(a,f){var 
c=(a&65535)+(f&65535);return(a>>16)+(f>>16)+(c>>16)<<16|c&65535};return 
function(b,f){b[f>>5]=b[f>>5]|128<<24-f%32;b[(f+64>>9<<4)+15]=f;for(var 
c=Array(80),d=1732584193,g=-271733879,m=-1732584194,n=271733878,o=-1009589776,p=0;p<b.length;p=p+16){for(var
 
l=d,h=g,j=m,k=n,q=o,e=0;e<80;e++){c[e]=e<16?b[p+e]:(c[e-3]^c[e-8]^c[e-14]^c[e-16])<<1|(c[e-3]^c[e-8]^c[e-14]^c[e-16])>>>31;var
 
r=l<<5|l>>>27,s;s=e<20?h&j|~h&k:e<40?h^j^k:e<60?h&j|h&k|j&k:h^j^k;r=a(a(r,s),a(a(q,c[e]),e<20?1518500249:
-    
e<40?1859775393:e<60?-1894007588:-899497514));q=k;k=j;j=h<<30|h>>>2;h=l;l=r}d=a(l,d);g=a(h,g);m=a(j,m);n=a(k,n);o=a(q,o)}return[d,g,m,n,o]}}()};gadgets.pubsub2router=function(){return{init:function(a){this.hub=a.hub?a.hub:new
 
OpenAjax.hub.ManagedHub({onPublish:a.onPublish,onSubscribe:a.onSubscribe,onUnsubscribe:a.onUnsubscribe})}}}();gadgets.config.init({opensocial:{invalidatePath:"http://%host%/rpc",path:"http://%host%/rpc",domain:"shindig",supportedFields:{person:["id",{name:["familyName","givenName","unstructured"]},"thumbnailUrl","profileUrl"],mediaItem:"album_id
 created description duration file_size id language last_updated location 
mime_type num_comments num_views num_votes rating start_time tagged_people tags 
thumbnail_url title type url".split(" "),album:"id thumbnailUrl title 
description location ownerId".split(" "),
-    group:["id","title","description"],activity:"appId body bodyId externalId 
id mediaItems postedTime priority streamFaviconUrl streamSourceUrl streamTitle 
streamUrl templateParams title url userId".split(" "),activityEntry:"actor 
content generator icon id object published provider target title updated url 
verb openSocial extensions".split(" 
")},enableCaja:!1},rpc:{commSwf:"/xpc.swf",passReferrer:"c2p:query",parentRelayUrl:"/container/rpc_relay.html",useLegacyProtocol:!1},"shindig.auth":{},views:{"default":{isOnlyVisible:!1,
-    
urlTemplate:"http://localhost/gadgets/default?{var}",aliases:["home","profile","canvas"]},canvas:{isOnlyVisible:!0,urlTemplate:"http://localhost/gadgets/canvas?{var}",aliases:["FULL_PAGE"]},profile:{isOnlyVisible:!1,urlTemplate:"http://localhost/gadgets/profile?{var}",aliases:["DASHBOARD","default"]}},container:{jsPath:"/gadgets/js",relayPath:"/gadgets/files/container/rpc_relay.html",enableRpcArbitration:!1},osapi:{endPoints:["//%host%/rpc"]},"osapi.services":{"gadgets.rpc":["container.listMethods";],
+    
e<40?1859775393:e<60?-1894007588:-899497514));q=k;k=j;j=h<<30|h>>>2;h=l;l=r}d=a(l,d);g=a(h,g);m=a(j,m);n=a(k,n);o=a(q,o)}return[d,g,m,n,o]}}()};gadgets.pubsub2router=function(){return{init:function(a){this.hub=a.hub?a.hub:new
 
OpenAjax.hub.ManagedHub({onPublish:a.onPublish,onSubscribe:a.onSubscribe,onUnsubscribe:a.onUnsubscribe})}}}();osapi.container.actions={};osapi.container.actions.OptParam={};osapi.container.actions.OptParam.VIEW="view";osapi.container.actions.OptParam.VIEW_TARGET="viewTarget";(function(){function
 o(a){var b=!0;if(a){var c=a.path,d=a.dataType;if(!a.id||!c&&!d)b=!1}else 
b=!1;return b}function p(a,b){if(o(a)){g.addAction(a,b);q([a]);for(var c in 
i)i.hasOwnProperty(c)&&(f.getGadgetSiteByIframeId_(c)?gadgets.rpc.call(c,"actions.onActionShow",null,[a]):delete
 i[c])}}function r(a){var b=g.getItemById(a);g.removeAction(a);s([b]);for(var c 
in 
j)j.hasOwnProperty(c)&&(f.getGadgetSiteByIframeId_(c)?gadgets.rpc.call(c,"actions.onActionHide",null,[b]):delete
 j[c])}functio
 n t(a,b){!b&&
+    (f&&f.selection)&&(b=f.selection.getSelection());var 
c=k[a],d;if(c)for(d=0;d<c.length;d++){var 
e=c[d];e.call(null,a,b)}for(d=0;d<l.length;d++)e=l[d],e.call(null,a,b);if(c=g.getGadgetSites(a))for(d=0;d<c.length;d++)(e=c[d].getActiveSiteHolder())&&gadgets.rpc.call(e.getIframeId(),"actions.runAction",null,a,b)}var
 
k={},l=[],h={};h[osapi.container.CallbackType.ON_PRELOADED]=function(a){for(var 
b in a)if(a.hasOwnProperty(b)){var 
c=a[b];if(!c.error&&c.modulePrefs&&(c=(c=c.modulePrefs.features.actions)&&
+    c.params?c.params["action-contributions"]:null)){"string"!==typeof 
c&&(c=c.toString());c=c.replace(/\n/g,"");c=c.replace(/\s+</g,"<");c=c.replace(/>\s+/g,">");-1===c.indexOf("<actions>")&&(c="<actions>"+c+"</actions>");var
 
d;try{d=opensocial.xmlutil.parseXML(c)}catch(e){}if(d&&(c=gadgets.json.xml.convertXmlToJson(d).actions))for(var
 c=[].concat(c.action),f=0;f<c.length;f++){var m=c[f],h={},i;for(i in 
m)m.hasOwnProperty(i)&&(h[i.substring(1)]=m[i]);g.getItemById(h.id)?gadgets.warn(["Duplicated
 gadget action [",
+    h.id,"] detected, make sure the gadget actions have unique 
ids."].join("")):p(h,b)}}}};h[osapi.container.CallbackType.ON_NAVIGATED]=function(a){var
 
b=a.getActiveSiteHolder();b&&(b=b.getUrl(),g.addGadgetSite(b,a))};h[osapi.container.CallbackType.ON_BEFORE_CLOSE]=function(a){a=a.getId();g.removeGadgetSite(a)};h[osapi.container.CallbackType.ON_UNLOADED]=function(a){for(var
 a=g.getActionsByUrl(a),b=0;b<a.length;b++)r(a[b].id)};var 
q=function(){},i={},s=function(){},j={},u=function(){},g=new 
function(){this.registryById=
+{};this.registryByPath={};this.registryByDataType={};this.registryByUrl={};this.urlToSite={};this.actionToUrl={};this.addAction=function(a,b){if(o(a)){var
 c=a.id,d=a.path,e=a.dataType;if(d){for(var 
e=d.split("/"),d=this.registryByPath,f=0;f<e.length;f++){var 
g=e[f];d[g]||(d[g]={});d=d[g]}e=d["@actions"];d["@actions"]=e?e.concat(a):[a]}else
 
e&&(this.registryByDataType[e]=this.registryByDataType[e]?this.registryByDataType[e].concat(a):[a]);this.registryById[c]=a;b&&(this.actionToUrl[c]=b,this.registryByUrl[b]=
+    
this.registryByUrl[b]?this.registryByUrl[b].concat(a):[a])}};this.removeAction=function(a){var
 b=this.registryById[a];delete this.registryById[a];var c=b.path;if(c){var 
c=this.getActionsByPath(c),d=c.indexOf(b);-1!=d&&c.splice(d,1)}else{var 
d=b.dataType,e=this.registryByDataType[d],c=e.indexOf(b);e.splice(c,1);0==e.length&&delete
 this.registryByDataType[d]}if(d=this.actionToUrl[a])delete 
this.actionToUrl[a],a=this.registryByUrl[d],c=a.indexOf(b),a.splice(c,1),0==a.length&&delete
 this.registryByUrl[d]};
+    
this.getItemById=function(a){return(this.registryById?this.registryById:{})[a]};this.getAllActions=function(){var
 a=[];for(actionId in 
this.registryById)this.registryById.hasOwnProperty(actionId)&&(a=a.concat(this.registryById[actionId]));return
 a};this.getActionsByPath=function(a){for(var 
b=[],a=a.split("/"),c=this.registryByPath?this.registryByPath:{},d=0;d<a.length;d++){var
 e=a[d];if(c[e])c=c[e];else return b}c&&(b=c["@actions"]);return 
b};this.getActionsByDataType=function(a){var b=[];this.registryByDataType[a]&&
+    (b=this.registryByDataType[a]);return 
b};this.getActionsByUrl=function(a){var 
b=[];this.registryByUrl[a]&&(b=b.concat(this.registryByUrl[a]));return 
b};this.addGadgetSite=function(a,b){var 
c=this.urlToSite[a];this.urlToSite[a]=c?c.concat(b):[b]};this.removeGadgetSite=function(a){for(var
 b in this.urlToSite)if(this.urlToSite.hasOwnProperty(b)){var 
c=this.urlToSite[b];if(c)for(var d=0;d<c.length;d++){var 
e=c[d];e&&e.getId()==a&&(c.splice(d,1),0==c.length&&delete 
this.urlToSite[b])}}};this.getGadgetSites=
+        function(a){var 
b=this.getItemById(a),c=[];if(a=this.urlToSite[this.actionToUrl[a]])for(var 
d=0;d<a.length;d++){var 
e=a[d],f=e.getActiveSiteHolder();(!b.view||f&&f.getView()===b.view)&&c.push(e)}return
 c};this.getUrl=function(a){return 
this.actionToUrl[a]}},n={},f=null;osapi.container.Container.addMixin("actions",function(a){f=a;f.rpcRegister("actions.registerHideCallback",function(b){j[b.f]=1});f.rpcRegister("actions.registerShowCallback",function(b){i[b.f]=1});f.rpcRegister("actions.bindAction",
+    function(b,c){var a=c.id;if(g.getItemById(a)){var 
e=n[a];e&&(t(a,e.selection),delete n[a])}else 
p(c)});f.rpcRegister("actions.get_actions_by_type",function(b,c){return[].concat(g.getActionsByDataType(c))});f.rpcRegister("actions.get_actions_by_path",function(b,c){return[].concat(g.getActionsByPath(c))});f.rpcRegister("actions.removeAction",function(b,c){return
 
r(c)});f.rpcRegister("actions.runAction",function(b,c,a){f.actions.runAction(c,a)});f.addGadgetLifecycleCallback&&f.addGadgetLifecycleCallback("actions",
+    h);return{registerShowActionsHandler:function(b){"function"===typeof 
b&&(q=b)},registerHideActionsHandler:function(b){"function"===typeof 
b&&(s=b)},registerNavigateGadgetHandler:function(b){"function"===typeof 
b&&(u=b)},runAction:function(b,a){var d=g.getItemById(b);if(d){var 
e=g.getGadgetSites(b);if(!e||0===e.length){e=g.getUrl(b);n[b]={selection:a||f.selection.getSelection()};var
 
h={};d.view&&(h[osapi.container.actions.OptParam.VIEW]=d.view);d.viewTarget&&(h[osapi.container.actions.OptParam.VIEW_TARGET]=
+    d.viewTarget);u(e,h)}else t(b,a)}},getAction:function(b){return 
g.getItemById(b)},getAllActions:function(){return 
g.getAllActions()},getActionsByPath:function(b){return 
g.getActionsByPath(b)},getActionsByDataType:function(b){return 
g.getActionsByDataType(b)},addListener:function(b,a){if(b&&"function"!=typeof 
b)throw Error("listener param must be a 
function");a?(k[a]=k[a]||[]).push(b):l.push(b)},removeListener:function(a){a=listeners.indexOf(a);-1!=a&&listeners.splice(a,1)}}})})();gadgets.config.init({opensocial:{invalidatePath:"http://%host%/rpc",path:"http://%host%/rpc",domain:"shindig",supportedFields:{person:["id",{name:["familyName","givenName","unstructured"]},"thumbnailUrl","profileUrl"],mediaItem:"album_id
 created description duration file_size id language last_updated location 
mime_type num_comments num_views num_votes rating start_time tagged_people tags 
thumbnail_url title type url".split(" "),album:"id thumbnailUrl title 
description location ownerId".split(" "),
+    group:["id","title","description"],activity:"appId body bodyId externalId 
id mediaItems postedTime priority streamFaviconUrl streamSourceUrl streamTitle 
streamUrl templateParams title url userId".split(" "),activityEntry:"actor 
content generator icon id object published provider target title updated url 
verb openSocial extensions".split(" 
")},enableCaja:!1},rpc:{commSwf:"/xpc.swf",passReferrer:"c2p:query",parentRelayUrl:"/container/rpc_relay.html",useLegacyProtocol:!1},"shindig.auth":{},container:{jsPath:"/gadgets/js",
+    
relayPath:"/gadgets/files/container/rpc_relay.html",enableRpcArbitration:!1},views:{"default":{isOnlyVisible:!1,urlTemplate:"http://localhost/gadgets/default?{var}",aliases:["home","profile","canvas"]},canvas:{isOnlyVisible:!0,urlTemplate:"http://localhost/gadgets/canvas?{var}",aliases:["FULL_PAGE"]},profile:{isOnlyVisible:!1,urlTemplate:"http://localhost/gadgets/profile?{var}",aliases:["DASHBOARD","default"]}},osapi:{endPoints:["//%host%/rpc"]},"osapi.services":{"gadgets.rpc":["container.listMethods";],
     "//%host%/rpc":"samplecontainer.update activities.supportedFields 
gadgets.metadata albums.supportedFields gadgets.proxySupportedFields albums.get 
mediaItems.create http.put system.listMethods gadgets.proxy gadgets.cajole 
http.head messages.create albums.delete mediaItems.update messages.delete 
appdata.update gadgets.js http.post gadgets.tokenSupportedFields 
samplecontainer.create http.get appdata.delete appdata.create 
gadgets.supportedFields mediaItems.get activities.update activities.delete 
albums.update activities.get messages.modify activitystreams.create appdata.get 
messages.get cache.invalidate samplecontainer.get people.supportedFields 
groups.get http.delete gadgets.jsSupportedFields people.get activitystreams.get 
mediaItems.supportedFields mediaItems.delete activitystreams.update 
gadgets.cajaSupportedFields activities.create albums.create people.update 
gadgets.token activitystreams.delete activitystreams.supportedFields".split(" 
")},
-    "core.io":{unparseableCruft:"throw 1; < don't be evil' 
>",jsonProxyUrl:"//%host%/gadgets/makeRequest",jsPath:"/gadgets/js",proxyUrl:"//%host%/gadgets/proxy%filename%?container=%container%&refresh=%refresh%&url=%url%%authz%%rewriteMime%",xhrPollIntervalMs:50}});window['___jsl']['l']
 = (window['___jsl']['l'] || 
[]).concat(['container','open-views','presence','pubsub-2']);
+    "core.io":{unparseableCruft:"throw 1; < don't be evil' 
>",jsonProxyUrl:"//%host%/gadgets/makeRequest",jsPath:"/gadgets/js",proxyUrl:"//%host%/gadgets/proxy%filename%?container=%container%&refresh=%refresh%&url=%url%%authz%%rewriteMime%",xhrPollIntervalMs:50}});window['___jsl']['l']
 = (window['___jsl']['l'] || 
[]).concat(['actions','container','open-views','pubsub-2']);
\ No newline at end of file

Copied: 
rave/trunk/rave-portal-resources/src/test/javascript/core/rave_action_manager.spec
 (from r1522894, 
rave/trunk/rave-portal-resources/src/test/javascript/core/rave_view_manager.spec)
URL: 
http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/test/javascript/core/rave_action_manager.spec?p2=rave/trunk/rave-portal-resources/src/test/javascript/core/rave_action_manager.spec&p1=rave/trunk/rave-portal-resources/src/test/javascript/core/rave_view_manager.spec&r1=1522894&r2=1523056&rev=1523056&view=diff
==============================================================================
--- 
rave/trunk/rave-portal-resources/src/test/javascript/core/rave_view_manager.spec
 (original)
+++ 
rave/trunk/rave-portal-resources/src/test/javascript/core/rave_action_manager.spec
 Fri Sep 13 18:40:15 2013
@@ -17,149 +17,10 @@
  */
 
 
-describe('rave_view_manager', function () {
-    var viewName = 'modal',
-        viewObject,
-        testScope = {};
+describe('rave_action_manager', function () {
+     beforeEach(function () {
+         actionManager = testr('core/rave_action_manager');
 
-    beforeEach(function(){
-        ViewManager = testr('core/rave_view_manager');
+     });
 
-        viewObject = {
-            render: function () {
-            },
-            getWidgetSite: function () {
-            },
-            destroy: function () {
-            }
-        }
-
-        _.each(viewObject, function (fn, key) {
-            spyOn(viewObject, key);
-        });
-
-        testScope.ViewConstructor = function () {
-            this.render = function () {
-            };
-            this.getWidgetSite = function () {
-            };
-            this.destroy = function () {
-            };
-
-            spyOn(this, 'render');
-            spyOn(this, 'getWidgetSite');
-            spyOn(this, 'destroy');
-        }
-        spyOn(testScope, 'ViewConstructor').andCallThrough();
-
-
-    })
-
-    afterEach(function () {
-        ViewManager.reset();
-    });
-
-    describe('registerView / getView', function () {
-        it('registers and retrieves views and is case insensitive', function 
() {
-            expect(ViewManager.getView(viewName)).toBeUndefined();
-            ViewManager.registerView(viewName, viewObject);
-            expect(ViewManager.getView(viewName)).toBe(viewObject);
-            
expect(ViewManager.getView(viewName.toUpperCase())).toBe(viewObject);
-        });
-    });
-
-    describe('renderView', function () {
-        it('throws an error if you render an unregistered view', function () {
-            expect(function () {
-                ViewManager.renderView('asdf')
-            }).toThrow();
-        });
-
-        it('invokes render on a view object', function () {
-            ViewManager.registerView(viewName, viewObject);
-            ViewManager.renderView(viewName);
-
-            expect(viewObject.render).toHaveBeenCalled();
-        });
-
-        it('returns the view object', function () {
-            ViewManager.registerView(viewName, viewObject);
-            expect(ViewManager.renderView(viewName)).toBe(viewObject);
-        });
-
-        it('instantiates a view constructor and calls its render', function () 
{
-            ViewManager.registerView(viewName, testScope.ViewConstructor);
-            var viewInstance = ViewManager.renderView(viewName);
-
-            expect(testScope.ViewConstructor).toHaveBeenCalled();
-            expect(viewInstance.render).toHaveBeenCalled();
-            expect(viewInstance.destroy).not.toHaveBeenCalled();
-        });
-
-        it('passes through any arbitrary arguments to the render function', 
function () {
-            //with view object
-            ViewManager.registerView(viewName, viewObject);
-            ViewManager.renderView(viewName, 1, 'bird', {hello: 'world'});
-            expect(viewObject.render).toHaveBeenCalledWith(1, 'bird', {hello: 
'world'});
-
-            //or view constructor
-            ViewManager.registerView(viewName, viewObject);
-            var viewInstance = ViewManager.renderView(viewName);
-            expect(viewInstance.render).toHaveBeenCalledWith(1, 'bird', 
{hello: 'world'});
-        });
-
-        it('assigns a uid to a rendered view', function () {
-            ViewManager.registerView(viewName, viewObject);
-            var viewInstance = ViewManager.renderView(viewName);
-
-            expect(viewInstance._uid).toBeDefined();
-        });
-    });
-
-    describe('getRenderedView', function () {
-        it('retrieves views that have been rendered', function () {
-            ViewManager.registerView(viewName, viewObject);
-            var viewInstance1 = ViewManager.renderView(viewName);
-            var viewInstance2 = ViewManager.renderView(viewName);
-
-            
expect(ViewManager.getRenderedView(viewInstance1._uid)).toBe(viewInstance1);
-            
expect(ViewManager.getRenderedView(viewInstance2._uid)).toBe(viewInstance2);
-            expect(ViewManager.getRenderedView('asdfasdf')).toBeUndefined();
-        });
-    });
-
-    describe('destroyView', function () {
-        it('invokes destroy on a view object', function () {
-            ViewManager.registerView(viewName, viewObject);
-            ViewManager.renderView(viewName);
-            ViewManager.destroyView(viewObject);
-
-            expect(viewObject.destroy).toHaveBeenCalled();
-        });
-
-        it('invokes destroy on a view instance', function () {
-            ViewManager.registerView(viewName, viewObject);
-            var viewInstance = ViewManager.renderView(viewName);
-            ViewManager.destroyView(viewInstance);
-
-            expect(viewInstance.destroy).toHaveBeenCalled();
-        });
-
-        it('invokes destroy on a view identified by uid', function () {
-            ViewManager.registerView(viewName, viewObject);
-            var viewInstance = ViewManager.renderView(viewName);
-            ViewManager.destroyView(viewInstance._uid);
-
-            expect(viewInstance.destroy).toHaveBeenCalled();
-        });
-
-        it('removes view from renderedViews registry', function () {
-            ViewManager.registerView(viewName, viewObject);
-            var viewInstance = ViewManager.renderView(viewName);
-            
expect(ViewManager.getRenderedView(viewInstance._uid)).toBe(viewInstance);
-
-            ViewManager.destroyView(viewInstance._uid);
-            
expect(ViewManager.getRenderedView(viewInstance._uid)).toBeUndefined();
-        });
-    });
 });


Reply via email to