You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2011/07/21 20:02:27 UTC
svn commit: r1149287 [1/2] - in /shindig/trunk:
content/samplecontainer/examples/commoncontainer/
content/samplecontainer/examples/embeddedexperiences/
content/samplecontainer/examples/media-openGadgets/ features/
features/src/main/javascript/features/...
Author: lindner
Date: Thu Jul 21 18:02:23 2011
New Revision: 1149287
URL: http://svn.apache.org/viewvc?rev=1149287&view=rev
Log:
Patch from Jason Chiang | View Enhancements To Open Gadgets and URLs
Added:
shindig/trunk/content/samplecontainer/examples/commoncontainer/cconviews.js
shindig/trunk/content/samplecontainer/examples/media-openGadgets/
shindig/trunk/content/samplecontainer/examples/media-openGadgets/Media.xml
shindig/trunk/content/samplecontainer/examples/media-openGadgets/MediaUIOpenGadgets.js
shindig/trunk/content/samplecontainer/examples/media-openGadgets/Social.js
shindig/trunk/content/samplecontainer/examples/media-openGadgets/styles.css
shindig/trunk/features/src/main/javascript/features/open-views/
shindig/trunk/features/src/main/javascript/features/open-views/feature.xml
shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements-container.js
shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements.js
shindig/trunk/features/src/test/javascript/features/open-views/
shindig/trunk/features/src/test/javascript/features/open-views/viewEnhancements-test.js
Modified:
shindig/trunk/content/samplecontainer/examples/commoncontainer/gadgetCollections.json
shindig/trunk/content/samplecontainer/examples/commoncontainer/index.html
shindig/trunk/content/samplecontainer/examples/embeddedexperiences/AlbumViewer.xml
shindig/trunk/content/samplecontainer/examples/embeddedexperiences/PhotoList.xml
shindig/trunk/content/samplecontainer/examples/embeddedexperiences/index.html
shindig/trunk/features/pom.xml
shindig/trunk/features/src/main/javascript/features/features.txt
Added: shindig/trunk/content/samplecontainer/examples/commoncontainer/cconviews.js
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/commoncontainer/cconviews.js?rev=1149287&view=auto
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/commoncontainer/cconviews.js (added)
+++ shindig/trunk/content/samplecontainer/examples/commoncontainer/cconviews.js Thu Jul 21 18:02:23 2011
@@ -0,0 +1,358 @@
+/*
+ * 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.
+ */
+
+/**
+ * overview Container implementation of view enhancement.
+ */
+
+CommonContainer['views'] = CommonContainer['views'] || {};
+
+/**
+ * Method will be called to create the DOM element to place the Gadget Site in.
+ *
+ * @param {object} gadgetMetadata
+ * gadget meta data for the gadget being opened in
+ * this GadgetSite.
+ * @param {string=} opt_view
+ * Optional parameter, the view that indicates the type of
+ * GadgetSite.
+ * @param {string=} opt_viewTarget
+ * Optional parameter, the view target indicates where
+ * to open the gadget.
+ * @return {object} The DOM element to place the GadgetSite in.
+ */
+
+CommonContainer.views.createElementForGadget = function(gadgetMetadata,
+ opt_view, opt_viewTarget) {
+ var surfaceView = 'default';
+ var viewTarget = 'default';
+
+ if (opt_view !== undefined) {
+ surfaceView = opt_view;
+ }
+ if (opt_viewTarget !== undefined) {
+ viewTarget = opt_viewTarget;
+ }
+
+ switch (viewTarget) {
+ case 'tab':
+ return openInNewTab(gadgetMetadata);
+ break;
+ case 'dialog':
+ return openInDialog(false, surfaceView, true, gadgetMetadata);
+ break;
+ case 'modalDialog':
+ return openInDialog(true, surfaceView, true, gadgetMetadata);
+ break;
+ default:
+ return openInDialog(false, surfaceView, true, gadgetMetadata);
+ }
+};
+
+
+/**
+ * Method will be called to create the DOM element to place the UrlSite in.
+ *
+ * @param {string=} opt_viewTarget
+ * Optional parameter, the view target to open. If not
+ * included the container should use its default view.
+ * @return {Object} The DOM element to place the UrlSite object in.
+ */
+CommonContainer.views.createElementForUrl = function(opt_viewTarget) {
+ var viewTarget = 'dialog';
+
+ if (opt_viewTarget !== undefined) {
+ viewTarget = opt_viewTarget;
+ }
+
+ switch (viewTarget) {
+ case 'tab':
+ return openInNewTab();
+ break;
+ case 'dialog':
+ return openInDialog(false, 'canvas', false);
+ break;
+ case 'modalDialog':
+ return openInDialog(true, 'canvas', false);
+ break;
+ default:
+ return openInDialog(false, 'canvas', false);
+ }
+};
+
+
+/**
+ * Method will be called when a gadget wants to close itself or the parent
+ * gadget wants to close a gadget or url site it has opened.
+ *
+ * @param {object=} site
+ * The id of the site to close.
+ */
+CommonContainer.views.destroyElement = function(site) {
+ closeDialog(site);
+};
+
+var dialog_counter = 0;
+var tab_counter = 2;
+var newTabId;
+var $tabs;
+
+
+/**
+ * private method will be called to create the dialog DOM element.
+ * @private
+ * @param {boolean} modaldialog
+ * true for modal dialog.
+ * @param {string} view
+ * view type.
+ * @param {boolean} isGadget
+ * true for gadget, false for url.
+ * @param {string} opt_gadgetMetadata
+ * gadget metadate.
+ * @return {Object} The DOM element to place the gadget or url site object in.
+ */
+function openInDialog(modaldialog, view, isGadget, opt_gadgetMetadata) {
+
+ var dialog_width = 450; // default width
+ if (view == 'canvas') {
+ dialog_width = 675; // width for canvas
+ }
+
+ dialog_counter++;
+ var dialog = document.createElement('div');
+ dialog.id = 'dialog_' + dialog_counter;
+
+ if (opt_gadgetMetadata !== undefined) {
+ // open gadget, get the title from gadgetMetadata
+ dialog.title = opt_gadgetMetadata['modulePrefs'].title;
+ }
+
+ document.getElementById('content').appendChild(dialog);
+ if (isGadget) {
+ // use jquery to create the dialog
+ $('#dialog_' + dialog_counter).dialog({
+ resizable: false,
+ width: dialog_width, // height will be auto
+ modal: modaldialog, // set modal: true or false
+ close: function(ev, ui) {
+ var iframeid = document.getElementById('dialog_' + dialog_counter).
+ getElementsByTagName('iframe')[0].id;
+ var site = CommonContainer.getGadgetSiteByIframeId_(iframeid);
+ CommonContainer.closeGadget(site);
+ $(this).remove();
+ }
+ });
+ return dialog;
+ } else {
+ var dialog_height = 350; // default height
+ if (view == 'canvas') {
+ dialog_height = 530; // height for canvas
+ }
+ $('#dialog_' + dialog_counter).dialog({
+ resizable: false,
+ width: dialog_width,
+ height: dialog_height,
+ modal: modaldialog, // set modal: true or false
+ close: function(ev, ui) {
+ $(this).remove();
+ }
+ });
+ // Maybe an issue in jquery, we need to create another div, otherwise it
+ // will show vertical scroll bar
+ var dialog_content = document.createElement('div');
+ dialog_content.style.height = '100%';
+ dialog_content.style.width = '100%';
+ dialog.appendChild(dialog_content);
+ return dialog_content;
+ }
+}
+
+
+/**
+ * private method will be called to create the tab DOM element.
+ * @private
+ * @param {string} gadgetMetadata
+ * gadget metadate.
+ * @return {Object} The DOM element to place the gadget or url site object in.
+ */
+function openInNewTab(gadgetMetadata) {
+
+ var tabsNode;
+
+ if (!document.getElementById('tabs')) {
+ // add the new tab the first time, will create the default tab for the
+ // current content, and add a new tab
+ var controlPanelNode = document.getElementById('controlPanel');
+ var testAreaNode = document.getElementById('testArea');
+ var contentNode = document.getElementById('content');
+
+ contentNode.removeChild(controlPanelNode);
+ contentNode.removeChild(testAreaNode);
+
+ tabsNode = document.createElement('div');
+ tabsNode.id = 'tabs';
+
+ tabsNode.innerHTML = "<ul><li><a href='#tabs-1'>Default</a></li></ul>";
+
+ var tabs_1_Node = document.createElement('div');
+ tabs_1_Node.id = 'tabs-1';
+
+ // put the default content into the tabs-1
+ tabs_1_Node.appendChild(controlPanelNode);
+ tabs_1_Node.appendChild(testAreaNode);
+
+ tabsNode.appendChild(tabs_1_Node);
+ contentNode.appendChild(tabsNode);
+ newTabId = 'tabs-2';
+
+ // use jquery to create new tab
+ $tabs = $('#tabs')
+ .tabs(
+ {
+ tabTemplate: "<li><a href='#{href}'>#{label}</a>" +
+ "<span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
+ add: function(event, ui) {
+ var tab_content_id = 'tab_content' + tab_counter;
+ var tab_content = document.createElement('div');
+ tab_content.id = tab_content_id;
+ // tab_content.className = "column";
+
+ tab_content.style.height = '1000px';
+ tab_content.style.width = '100%';
+
+ $(ui.panel).append(tab_content);
+
+ // set the focus to the new tab
+ $('#tabs').tabs('select', '#' + newTabId);
+ },
+
+ remove: function(event, ui) {
+ // If there is gadget inside, close the gadget
+ var iframes = $(this).parent().get(0)
+ .getElementsByTagName('iframe');
+ if (iframes.lenth > 0 && iframes[0].id !== undefined) {
+ var site = CommonContainer
+ .getGadgetSiteByIframeId_(iframes[0].id);
+ CommonContainer.closeGadget(site);
+ }
+ }
+ });
+
+ // close icon: removing the tab on click
+ // note: closable tabs gonna be an option in the future - see
+ // http://dev.jqueryui.com/ticket/3924
+ $('#tabs span.ui-icon-close').live('click', function() {
+ var index = $('li', $tabs).index($(this).parent());
+
+ $tabs.tabs('remove', index);
+ if ($tabs.tabs('length') < 2) {
+
+ controlPanelNode = document.getElementById('controlPanel');
+ testAreaNode = document.getElementById('testArea');
+ contentNode = document.getElementById('content');
+ tabsNode = document.getElementById('tabs');
+
+ tabs_1_Node = document.getElementById('tabs-1');
+
+ tabs_1_Node.removeChild(controlPanelNode);
+ tabs_1_Node.removeChild(testAreaNode);
+
+ contentNode.removeChild(tabsNode);
+
+ tab_counter = 2;
+ newTabId = null;
+ $tabs = null;
+
+ contentNode.appendChild(controlPanelNode);
+ contentNode.appendChild(testAreaNode);
+
+ }
+
+ });
+ }
+
+ newTabId = 'tabs-' + tab_counter;
+ var tab_content_id = 'tab_content' + tab_counter;
+
+ // add new tab with new id and new title
+ var tab_title = 'new tab ';
+ if (gadgetMetadata !== undefined &&
+ gadgetMetadata['modulePrefs'].title !== undefined) {
+ // open gadget, get the title from gadgetMetadata
+ tab_title = gadgetMetadata['modulePrefs'].title;
+ if (tab_title.length > 7) {
+ tab_title = tab_title.substring(0, 6) + '...';
+ }
+ }
+ $tabs.tabs('add', '#tabs-' + tab_counter, tab_title);
+
+ if (gadgetMetadata !== undefined) {
+ // rendering gadget's header
+ var gadgetSiteId = 'gadget-site-' + newTabId;
+ var gadgetTemplate = '<div class="portlet">' +
+ '<div class="portlet-header">sample to replace</div>' +
+ '<div id=' + gadgetSiteId +
+ ' class="portlet-content"></div>' + '</div>';
+
+ $(gadgetTemplate).appendTo($('#' + tab_content_id)).addClass(
+ 'ui-widget ui-widget-content ui-helper-clearfix ui-corner-all')
+ .find('.portlet-header')
+ .addClass('ui-widget-header ui-corner-all')
+ .text(gadgetMetadata['modulePrefs'].title)
+ .append('<span id="remove" class="ui-icon ui-icon-closethick"></span>');
+ }
+
+ tab_counter++;
+
+ // return the div
+ if (gadgetMetadata !== undefined) {
+ return document.getElementById('gadget-site-' + newTabId);
+ } else {
+ return document.getElementById(tab_content_id);
+ }
+}
+
+
+/**
+ * private method will be called to destroy dialog object.
+ * @private
+ * @param {object} site
+ * gadget site.
+ */
+function closeDialog(site) {
+ // this is the site id, we also need to find the dojo dialog widget id
+ var iframeId;
+ var widgetId = 'dialog_' + dialog_counter; //default
+
+ if (site && site.getActiveGadgetHolder()) {
+ // get iframe id
+ iframeId = site.getActiveGadgetHolder().getIframeId();
+ if (iframeId !== undefined) {
+ var iframeNode = document.getElementById(iframeId);
+ // get dialog widget id
+ widgetId = iframeNode.parentNode.id;
+ }
+ }
+ // close the gadget
+ CommonContainer.closeGadget(site);
+
+ // close the widget
+ $('#' + widgetId).dialog('close');
+
+}
Modified: shindig/trunk/content/samplecontainer/examples/commoncontainer/gadgetCollections.json
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/commoncontainer/gadgetCollections.json?rev=1149287&r1=1149286&r2=1149287&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/commoncontainer/gadgetCollections.json (original)
+++ shindig/trunk/content/samplecontainer/examples/commoncontainer/gadgetCollections.json Thu Jul 21 18:02:23 2011
@@ -31,6 +31,13 @@
]
},
{
+ "name": "Sample Media Items Gadget with openGadget API",
+ "Description": "Sample gadget used in the view enhancements sample",
+ "apps" : [
+ {"name": "publisher", "url": "/samplecontainer/examples/media-openGadgets/Media.xml"}
+ ]
+ },
+ {
"name": "OpenSearch Demo",
"Description": "Sample gadgets used for opensearch",
"apps" : [
Modified: shindig/trunk/content/samplecontainer/examples/commoncontainer/index.html
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/commoncontainer/index.html?rev=1149287&r1=1149286&r2=1149287&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/commoncontainer/index.html (original)
+++ shindig/trunk/content/samplecontainer/examples/commoncontainer/index.html Thu Jul 21 18:02:23 2011
@@ -23,7 +23,7 @@
<!-- My OpenSocial Beginnings -->
<link rel="stylesheet" href="../../../container/gadgets.css">
<script type="text/javascript"
- src="../../../gadgets/js/container:views:opensearch:rpc:pubsub-2.js?c=1&debug=1&container=default""></script>
+ src="../../../gadgets/js/container:open-views:opensearch:rpc:pubsub-2.js?c=1&debug=1&container=default""></script>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script
@@ -165,7 +165,7 @@ Enter the event payload
<div id="results"></div>
</div>
</div>
-</div>
+
<span class="ui-icon ui-icon-grip-dotted-horizontal"
style="margin: 2px auto;"></span></div>
@@ -183,6 +183,6 @@ Enter the event payload
<span class="ui-icon ui-icon-grip-dotted-horizontal"
style="margin: 2px auto;"></span></div>
</div>
-
+</div>
</body>
</html>
Modified: shindig/trunk/content/samplecontainer/examples/embeddedexperiences/AlbumViewer.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/embeddedexperiences/AlbumViewer.xml?rev=1149287&r1=1149286&r2=1149287&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/embeddedexperiences/AlbumViewer.xml (original)
+++ shindig/trunk/content/samplecontainer/examples/embeddedexperiences/AlbumViewer.xml Thu Jul 21 18:02:23 2011
@@ -21,7 +21,7 @@
<ModulePrefs title="Photo Album Viewer" description="View Photos From An Album" height="400" width="650">
<Require feature="embedded-experiences"></Require>
<Require feature="dynamic-height"></Require>
- <Require feature="views"></Require>
+ <Require feature="open-views"></Require>
</ModulePrefs>
<Content type="html" view="embedded, default">
<![CDATA[
@@ -50,8 +50,8 @@
clear: both;
}
</style>
-
-
+
+
<script type="text/javascript">
function initAlbum(){
opensocial.data.getDataContext().registerListener('org.opensocial.ee.context', function(key){
@@ -72,7 +72,7 @@
gadgets.util.registerOnLoadHandler(initAlbum);
</script>
-
+
<div id="wrapper">
<div id="header"></div>
<div id="album"></div>
Modified: shindig/trunk/content/samplecontainer/examples/embeddedexperiences/PhotoList.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/embeddedexperiences/PhotoList.xml?rev=1149287&r1=1149286&r2=1149287&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/embeddedexperiences/PhotoList.xml (original)
+++ shindig/trunk/content/samplecontainer/examples/embeddedexperiences/PhotoList.xml Thu Jul 21 18:02:23 2011
@@ -20,7 +20,7 @@
<Module>
<ModulePrefs title="Photo List" description="View Photos From An Album" height="400" width="650">
<Require feature="embedded-experiences"></Require>
- <Require feature="views"></Require>
+ <Require feature="open-views"></Require>
</ModulePrefs>
<Content type="html" view="embedded, default">
<![CDATA[
@@ -34,25 +34,27 @@
padding: 2px 2px 2px 2px;
border: 1px solid black;
}
-
+
#wrapper{
border: 1px solid black;
}
-
+
#header{
font-size: 120%;
padding: 10px 10px 10px 10px;
color: #0F67A1;
- }
-
+ }
+
.clear{
clear: both;
- }
+ }
</style>
-
- <script type="text/javascript">
-
+
+
+ <script type="text/javascript">
+
var currentSite;
+
function initAlbum(){
opensocial.data.getDataContext().registerListener('org.opensocial.ee.context', function(key){
createAlbumHTML(opensocial.data.getDataContext().getDataSet(key));
@@ -70,24 +72,24 @@
document.getElementById('header').innerHTML = context.albumName;
document.getElementById("album").innerHTML = result;
};
-
+
gadgets.util.registerOnLoadHandler(initAlbum);
-
+
function showPreviewPhoto(index) {
-
+
var eeDataModel = {
'gadget' : 'http://localhost:8080/samplecontainer/examples/embeddedexperiences/AlbumViewer.xml',
- 'context' : {
- "albumName": context.albumName,
+ 'context' : {
+ "albumName": context.albumName,
"photoUrls": [context.photoUrls[index]]
}
};
-
- var navigateCallback = function(site, metadata){currentSite = site; console.log("Nagivate callback");};
+
+ var navigateCallback = function(site, metadata){currentSite = site; console.log("Nagivate callback");};
var returnCallback = function(returnValue){console.log("Return Value: " + returnValue);};
gadgets.views.openEmbeddedExperience(returnCallback, navigateCallback, eeDataModel, {'viewTarget' : 'preview'});
};
-
+
function closePreview(){
if(currentSite != null){
gadgets.views.close(currentSite);
@@ -95,7 +97,7 @@
return false;
};
</script>
-
+
<div id="wrapper">
<div id="header"></div>
<div id="album"></div>
Modified: shindig/trunk/content/samplecontainer/examples/embeddedexperiences/index.html
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/embeddedexperiences/index.html?rev=1149287&r1=1149286&r2=1149287&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/embeddedexperiences/index.html (original)
+++ shindig/trunk/content/samplecontainer/examples/embeddedexperiences/index.html Thu Jul 21 18:02:23 2011
@@ -45,7 +45,7 @@
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
- <script type="text/javascript" src="/gadgets/js/core:container:rpc:views.js?c=1&debug=1&container=default"></script>
+ <script type="text/javascript" src="/gadgets/js/core:container:rpc:open-views.js?c=1&debug=1&container=default"></script>
<script type="text/javascript" src="EEContainer.js"></script>
</head>
<body style="font-size:62.5%;">
Added: shindig/trunk/content/samplecontainer/examples/media-openGadgets/Media.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/media-openGadgets/Media.xml?rev=1149287&view=auto
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/media-openGadgets/Media.xml (added)
+++ shindig/trunk/content/samplecontainer/examples/media-openGadgets/Media.xml Thu Jul 21 18:02:23 2011
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- * 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. -->
+<Module>
+ <ModulePrefs title="Albums and MediaItems">
+ <Require feature="osapi" />
+ <Require feature="dynamic-height" />
+ <Require feature="open-views" />
+ </ModulePrefs>
+
+ <Content type="html" view="default"><![CDATA[
+ <html>
+ <head>
+ <!-- Source imports --><script src='http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js' type='text/javascript' djConfig='parseOnLoad:true, isDebug:true'></script>
+ <script src='Social.js' type='text/javascript'></script>
+ <script src='MediaUIOpenGadgets.js' type='text/javascript'></script>
+
+ <!-- Styling -->
+ <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/tundra/tundra.css"></link>
+ <link rel="stylesheet" type="text/css" href="styles.css">
+
+ <!-- DOJO requires -->
+ <script type='text/javascript'>
+ dojo.require('dijit.form.Button');
+ dojo.require('dijit.form.Form');
+ dojo.require('dijit.form.TextBox');
+ dojo.require('dijit.form.ValidationTextBox');
+ dojo.require('dijit.Dialog');
+ dojo.require('dijit.form.Textarea');
+ dojo.require('dijit.layout.ContentPane');
+ dojo.require('dijit.layout.TabContainer');
+ </script>
+
+ <!-- JavaScript -->
+ <script type="text/javascript">
+ <!-- Entry point to the gadget -->
+ function init() {
+ new MediaUI(new SocialWrapper()).init();
+ }
+
+ <!-- Register entry point -->
+ gadgets.util.registerOnLoadHandler(function() {
+ dojo.addOnLoad(init);
+ });
+ </script>
+ </head><body class="tundra"></body>
+ </html>
+ ]]></Content>
+
+ <Content type="html" view="albumFullView"><![CDATA[
+ <html>
+ <head>
+ <!-- Source imports -->
+ <script src='http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js' type='text/javascript' djConfig='parseOnLoad:true, isDebug:true'></script>
+ <script src='Social.js' type='text/javascript'></script>
+ <script src='MediaUIOpenGadgets.js' type='text/javascript'></script>
+
+ <!-- Styling -->
+ <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/tundra/tundra.css"></link>
+ <link rel="stylesheet" type="text/css" href="styles.css">
+
+ <!-- DOJO requires -->
+ <script type='text/javascript'>
+ dojo.require('dijit.form.Button');
+ dojo.require('dijit.form.Form');
+ dojo.require('dijit.form.TextBox');
+ dojo.require('dijit.form.ValidationTextBox');
+ dojo.require('dijit.Dialog');
+ dojo.require('dijit.form.Textarea');
+ dojo.require('dijit.layout.ContentPane');
+ dojo.require('dijit.layout.TabContainer');
+ </script>
+
+ <!-- JavaScript -->
+ <script type="text/javascript">
+ <!-- Entry point to the gadget -->
+ function init() {
+ var params = gadgets.views.getParams();
+ var m = new MediaUI(new SocialWrapper());
+ m.openAlbum(params['viewerId'],params['data']);
+ }
+
+ <!-- Register entry point -->
+ gadgets.util.registerOnLoadHandler(function() {
+ dojo.addOnLoad(init);
+ });
+ </script>
+ </head><body class="tundra"></body>
+ </html>
+ ]]></Content>
+
+ <Content type="html" view="editAlbum"><![CDATA[
+ <html>
+ <head>
+ <!-- Source imports -->
+ <script src='http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js' type='text/javascript' djConfig='parseOnLoad:true, isDebug:true'></script>
+ <script src='Social.js' type='text/javascript'></script>
+ <script src='MediaUIOpenGadgets.js' type='text/javascript'></script>
+
+ <!-- Styling -->
+ <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/tundra/tundra.css"></link>
+ <link rel="stylesheet" type="text/css" href="styles.css">
+
+ <!-- DOJO requires -->
+ <script type='text/javascript'>
+ dojo.require('dijit.form.Button');
+ dojo.require('dijit.form.Form');
+ dojo.require('dijit.form.TextBox');
+ dojo.require('dijit.form.ValidationTextBox');
+ dojo.require('dijit.Dialog');
+ dojo.require('dijit.form.Textarea');
+ dojo.require('dijit.layout.ContentPane');
+ dojo.require('dijit.layout.TabContainer');
+ </script>
+
+ <!-- JavaScript -->
+ <script type="text/javascript">
+ <!-- Entry point to the gadget -->
+ function init() {
+ var params = gadgets.views.getParams();
+ var data = params['data'];
+ new MediaUI(new SocialWrapper()).editAlbum(data);
+ }
+
+ <!-- Register entry point -->
+ gadgets.util.registerOnLoadHandler(function() {
+ dojo.addOnLoad(init);
+ });
+ </script>
+ </head><body class="tundra"></body>
+ </html>
+ ]]></Content>
+
+ <Content type="html" view="editMediaItem"><![CDATA[
+ <html>
+ <head>
+ <!-- Source imports -->
+ <script src='http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js' type='text/javascript' djConfig='parseOnLoad:true, isDebug:true'></script>
+ <script src='Social.js' type='text/javascript'></script>
+ <script src='MediaUIOpenGadgets.js' type='text/javascript'></script>
+
+ <!-- Styling -->
+ <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/tundra/tundra.css"></link>
+ <link rel="stylesheet" type="text/css" href="styles.css">
+
+ <!-- DOJO requires -->
+ <script type='text/javascript'>
+ dojo.require('dijit.form.Button');
+ dojo.require('dijit.form.Form');
+ dojo.require('dijit.form.TextBox');
+ dojo.require('dijit.form.ValidationTextBox');
+ dojo.require('dijit.Dialog');
+ dojo.require('dijit.form.Textarea');
+ dojo.require('dijit.layout.ContentPane');
+ dojo.require('dijit.layout.TabContainer');
+ </script>
+
+ <!-- JavaScript -->
+ <script type="text/javascript">
+ <!-- Entry point to the gadget -->
+ function init() {
+ var params = gadgets.views.getParams();
+ new MediaUI(new SocialWrapper()).editMediaItem(params['data'].album,params['data'].mediaItem);
+ }
+
+ <!-- Register entry point -->
+ gadgets.util.registerOnLoadHandler(function() {
+ dojo.addOnLoad(init);
+ });
+ </script>
+ </head><body class="tundra"></body>
+ </html>
+ ]]></Content>
+
+</Module>
\ No newline at end of file
Added: shindig/trunk/content/samplecontainer/examples/media-openGadgets/MediaUIOpenGadgets.js
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/media-openGadgets/MediaUIOpenGadgets.js?rev=1149287&view=auto
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/media-openGadgets/MediaUIOpenGadgets.js (added)
+++ shindig/trunk/content/samplecontainer/examples/media-openGadgets/MediaUIOpenGadgets.js Thu Jul 21 18:02:23 2011
@@ -0,0 +1,645 @@
+/*
+ * 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.
+ */
+
+/*
+ * The User Interface for the Albums & MediaItems gadget.
+ *
+ * SHINDIG TODOS set ownerId automatically? delete children mediaitems when
+ * album deleted? update only updates given fields? update album mediaitem
+ * count when inserting/removing mediaitem?
+ *
+ * GADGET TODOS album info such as how many albums are contained fix auto
+ * height for edit album popup thumnail pictures
+ */
+function MediaUI(social) {
+ var viewer = null;
+ var divManager = null;
+
+ var folderUrl = 'http://www.clker.com/cliparts/2/b/b/3/' +
+ '1194983972976950993blue_folder_seth_yastrov_01.svg.med.png';
+ var docUrl = 'http://www.plastyc.com/images/document-icon.png';
+
+ /*
+ * Pre-load data for gadget.
+ */
+ function loadData(callback) {
+ social.getViewer(function(data) {
+ viewer = data;
+ callback();
+ });
+ }
+
+ /*
+ * Manages the gadgets main DIV elements.
+ */
+ function DivManager() {
+ var divs = [];
+
+ this.init = function() {
+ addDiv('albumsDiv');
+ addDiv('mediaItemsDiv');
+ addDiv('mediaItemDiv');
+ hideAll();
+ }
+
+ this.showAlbums = function() {
+ hideAll();
+ divs['albumsDiv'].style.display = 'block';
+ this.refreshWindow();
+ }
+
+ this.showMediaItems = function() {
+ hideAll();
+ divs['mediaItemsDiv'].style.display = 'block';
+ this.refreshWindow();
+ }
+
+ this.showMediaItem = function() {
+ hideAll();
+ divs['mediaItemDiv'].style.display = 'block';
+ this.refreshWindow();
+ }
+
+ this.refreshWindow = function() {
+ gadgets.window.adjustHeight(350);
+ }
+
+ function hideAll() {
+ for (key in divs) { divs[key].style.display = 'none'; }
+ }
+
+ function addDiv(id) { divs[id] = dojo.create('div', {id: id}, dojo.body());}
+ }
+
+ /*
+ * Renders a list of the given albums.
+ */
+ function renderAlbums(albums) {
+
+ dojo.empty('albumsDiv');
+ var albumsDiv = dojo.byId('albumsDiv');
+
+ var albumsBanner = dojo.create('div', null, albumsDiv);
+ var table = dojo.create('table', null, albumsBanner);
+ var tbody = dojo.create('tbody', null, table);
+ var tr = dojo.create('tr', null, tbody);
+ dojo.create('td', {innerHTML: viewer.name.formatted + "'s Albums",
+ className: 'albumsTitle'}, tr);
+ dojo.create('td', null, tr).appendChild(new dijit.form.Button(
+ {label: '+ New Album', onClick: dojo.hitch(
+ this, editAlbumPopup, null)}).domNode);
+
+ var albumsList = dojo.create('div', null, albumsDiv);
+ if (albums.length > 0) {
+ var table = dojo.create('table', {className: 'albumsTable'}, albumsList);
+ var tbody = dojo.create('tbody', null, table);
+ for (i = 0; i < albums.length; i++) {
+ var albumRow = dojo.create('tr', null, tbody);
+ var albumLeft = dojo.create('td', {className: 'albumListThumbnail'},
+ albumRow);
+ var imgLink = dojo.create('a', {href: 'javascript:;',
+ onclick: dojo.hitch(this, onClickAlbum, viewer.id, albums[i])},
+ albumLeft);
+ dojo.create('img', {src: albums[i].thumbnailUrl,
+ onerror: "this.src='" + folderUrl + "';", width: '100%'}, imgLink);
+ var albumRight = dojo.create('td', {className: 'albumListRight'},
+ albumRow);
+ var albumTitleRow = dojo.create('tr', null, albumRight);
+ var titleTd = dojo.create('td', {className: 'albumListTitle'},
+ albumTitleRow);
+ dojo.create('a', {innerHTML: albums[i].title, href: 'javascript:;',
+ onclick: dojo.hitch(this, onClickAlbum, viewer.id, albums[i])},
+ titleTd);
+ var editTd = dojo.create('td', {className: 'actionLinks',
+ style: 'text-align: right'}, albumTitleRow);
+ dojo.create('a', {innerHTML: 'edit', href: 'javascript:;',
+ onclick: dojo.hitch(this, editAlbumPopup, albums[i])}, editTd);
+ editTd.appendChild(dojo.doc.createTextNode(' | '));
+ dojo.create('a', {innerHTML: 'delete', href: 'javascript:;',
+ onclick: dojo.hitch(this, deleteAlbumPopup, albums[i])}, editTd);
+
+ var openTabButton = new dijit.form.Button({label: 'Open in New Tab',
+ onClick: dojo.hitch(this, openAlbumNewTab, albums[i], null)});
+ editTd.appendChild(openTabButton.domNode);
+
+ if (albums[i].description) {
+ var albumDescription = dojo.create('tr', null, albumRight);
+ dojo.create('td', {innerHTML: albums[i].description,
+ className: 'albumListDescription', colspan: '2'}, albumDescription);
+ }
+ }
+ } else {
+ albumsDiv.appendChild(dojo.doc.createTextNode('No albums found.'));
+ }
+ divManager.refreshWindow();
+
+ // Handles when user clicks an album
+ function onClickAlbum(userId, album) {
+ social.getMediaItemsByAlbum(userId, album.id, function(response) {
+ renderMediaItems(album, response.list);
+ divManager.showMediaItems();
+ });
+ }
+ }
+
+ /*
+ * Convenience function to retrieve albums and render.
+ */
+ function renderAlbumsByUser(userId, callback) {
+ social.getAlbumsByUser(userId, function(response) {
+ renderAlbums(response.list);
+ divManager.showAlbums();
+ if (callback !== null) callback();
+ });
+ }
+
+ /*
+ * Renders a grid of the given MediaItems.
+ *
+ */
+ function renderMediaItems(album, mediaItems) {
+ dojo.empty('mediaItemsDiv');
+ var mediaItemsDiv = dojo.byId('mediaItemsDiv');
+ var numCols = 5;
+
+ // Div to display navation bar and Create button
+ var topDiv = dojo.create('div', null, mediaItemsDiv);
+ var table = dojo.create('table', null, topDiv);
+ var tbody = dojo.create('tbody', null, table);
+ var tr = dojo.create('tr', null, tbody);
+ var td = dojo.create('td', {style: 'width:100%'}, tr);
+ dojo.create('a', {innerHTML: 'Albums', href: 'javascript:;',
+ onclick: dojo.hitch(this, renderAlbumsByUser, viewer.id, null)}, td);
+ td.appendChild(dojo.doc.createTextNode(' > ' + album.title));
+ td = dojo.create('td', {style: 'width:100%'}, tr);
+ var createButton = new dijit.form.Button({label: '+ New MediaItem',
+ onClick: dojo.hitch(this, editMediaItemPopupInGadget, album, null)});
+ td.appendChild(createButton.domNode);
+
+ // Div to display MediaItems in a grid
+ var gridDiv = dojo.create('div', null, mediaItemsDiv);
+ if (mediaItems.length > 0) {
+ var table = dojo.create('table', null, gridDiv);
+ var tbody = dojo.create('tbody', null, table);
+ var tr = null;
+ for (i = 0; i < mediaItems.length; i++) {
+ if (i % numCols == 0) {
+ tr = dojo.create('tr', null, tbody);
+ }
+ var td = dojo.create('td', {className: 'mediaItemBox'}, tr);
+ var imageTd = dojo.create('tr', null, td).appendChild(dojo.create('td',
+ {className: 'mediaItemThumbnail'}));
+ if (mediaItems[i].url) {
+ var imageLink = dojo.create('a', {href: 'javascript:;',
+ onclick: dojo.hitch(this, renderMediaItemInDialog, album,
+ mediaItems[i])}, imageTd);
+ imageLink.appendChild(dojo.create('img',
+ {src: mediaItems[i].thumbnailUrl,
+ onerror: "this.src='" + docUrl + "';",
+ style: 'height:100px;'}));
+ } else {
+ dojo.create('img', {src: mediaItems[i].thumbnailUrl,
+ onerror: "this.src='" + docUrl + "';",
+ style: 'height:100px;'}, imageTd);
+ }
+ var titleTd = dojo.create('tr', null, td).appendChild(
+ dojo.create('td', {
+ style: 'text-align:center;' +
+ "font-family:'comic sans ms';white-space:nowrap;"}));
+ titleTd.appendChild(dojo.doc.createTextNode(mediaItems[i].title));
+ var actionsTd = dojo.create('tr', null, td).appendChild(
+ dojo.create('td', {className: 'actionLinks',
+ style: 'text-align: center;'}));
+ dojo.create('a', {innerHTML: 'edit', href: 'javascript:;',
+ onclick: dojo.hitch(this, editMediaItemPopupInGadget,
+ album, mediaItems[i])}, actionsTd);
+ actionsTd.appendChild(dojo.doc.createTextNode(' | '));
+ dojo.create('a', {innerHTML: 'delete', href: 'javascript:;',
+ onclick: dojo.hitch(this, deleteMediaItemPopup, album,
+ mediaItems[i])}, actionsTd);
+ }
+ } else {
+ gridDiv.appendChild(dojo.doc.createTextNode('Album is empty'));
+ }
+ divManager.refreshWindow();
+ }
+
+ /*
+ * Convenience function to retriev & render MediaItems by Album.
+ */
+ function retrieveAndRenderMediaItems(album) {
+ social.getMediaItemsByAlbum(viewer.id, album.id, function(response) {
+ divManager.showMediaItems();
+ renderMediaItems(album, response.list);
+ });
+ }
+
+ /*
+ * Renders the view for a single MediaItem.
+ */
+ function renderMediaItem(album, mediaItem) {
+ dojo.empty('mediaItemDiv');
+ var mediaItemDiv = dojo.byId('mediaItemDiv');
+
+ // Div to display navation bar and Create button
+ var topDiv = dojo.create('div', null, mediaItemDiv);
+ var table = dojo.create('table', null, topDiv);
+ var tbody = dojo.create('tbody', null, table);
+ var tr = dojo.create('tr', null, tbody);
+ var td = dojo.create('td', {style: 'width:100%'}, tr);
+ dojo.create('a', {innerHTML: 'Albums', href: 'javascript:;',
+ onclick: dojo.hitch(this, renderAlbumsByUser, viewer.id, null)}, td);
+ td.appendChild(dojo.doc.createTextNode(' > '));
+ dojo.create('a', {innerHTML: album.title, href: 'javascript:;',
+ onclick: dojo.hitch(this, retrieveAndRenderMediaItems, album)}, td);
+ td.appendChild(dojo.doc.createTextNode(' > ' + mediaItem.title));
+
+ // Div to show MediaItem
+ var itemDiv = dojo.create('div', null, mediaItemDiv);
+ var table = dojo.create('table', null, itemDiv);
+ var tbody = dojo.create('tbody', null, table);
+ var tr = dojo.create('tr', null, tbody);
+ var td = dojo.create('td', null, tr);
+ dojo.create('img', {src: mediaItem.url}, td);
+ if (mediaItem.description) {
+ tr = dojo.create('tr', null, tbody);
+ td = dojo.create('td', null, tr);
+ td.appendChild(dojo.doc.createTextNode(mediaItem.description));
+ }
+
+ divManager.showMediaItem();
+ }
+
+
+
+ function renderMediaItemInDialog(album, mediaItem) {
+
+ var url = mediaItem.url;
+ var viewTarget = 'dialog';
+
+ function navigateCallback(site) {
+ console.log('navigateCallback ');
+ }
+ gadgets.views.openUrl(url, navigateCallback, viewTarget);
+
+ }
+
+ /*
+ * Render album gadget in new tab
+ */
+ function openAlbumNewTab(album) {
+
+ function callback(album) {}
+ function navigateCallback(site, metadata) {}
+
+ var viewParams = {'viewerId': viewer.id, 'data': album};
+
+ var opt_params = {};
+ opt_params.view = 'albumFullView';
+ opt_params.viewTarget = 'tab';
+ opt_params.viewParams = viewParams;
+ gadgets.views.openGadget(callback, navigateCallback, opt_params);
+
+ }
+
+ /*
+ * Popup to edit album.
+ */
+ function editAlbumPopup(album) {
+ var opt_view = 'default.modalDialog';
+
+ function callback(album) {
+ social.updateAlbum(viewer.id, album.id, album, function(response) {
+ renderAlbumsByUser(viewer.id);
+ });
+ }
+
+ function navigateCallback(site, metadata) {
+ console.log('navigateCallback');
+ }
+
+ var viewParams = {'data': album};
+
+ var opt_params = {};
+ opt_params.view = 'editAlbum';
+ opt_params.viewTarget = 'modalDialog';
+ opt_params.viewParams = viewParams;
+ gadgets.views.openGadget(callback, navigateCallback, opt_params);
+
+ };
+
+ /*
+ * Popup to edit MediaItem.
+ */
+ function editMediaItemPopupInGadget(album, mediaItem) {
+
+ function callback(newMediaItem) {
+ var albumId = mediaItem == null ? album.id : mediaItem.albumId;
+
+ social.updateMediaItem(viewer.id, albumId, mediaItem.id, newMediaItem,
+ function(response) {
+ // publish("org.apache.shindig.mediaItem.updated", newMediaItem);
+ social.getMediaItemsByAlbum(viewer.id, album.id,
+ function(response) {
+ renderMediaItems(album, response.list);
+ });
+ });
+ }
+
+ function navigateCallback(site, metadata) {
+ console.log('navigateCallback');
+ }
+
+ var viewParams = {'data': {'album': album, 'mediaItem': mediaItem}};
+ var opt_params = {};
+ opt_params.view = 'editMediaItem';
+ opt_params.viewTarget = 'modalDialog';
+ opt_params.viewParams = viewParams;
+ gadgets.views.openGadget(callback, navigateCallback, opt_params);
+
+ }
+
+
+ /*
+ * Popup to confirm that the user wants to delete album.
+ */
+ function deleteAlbumPopup(album) {
+ if (confirm("Delete '" + album.title + "'?")) {
+ social.deleteAlbum(viewer.id, album.id, function(response) {
+ publish('org.apache.shindig.album.deleted', album);
+ console.log('delete album response: ' + JSON.stringify(response));
+ renderAlbumsByUser(viewer.id);
+ });
+ }
+ }
+
+ /*
+ * Popup to confirm user wants to delete MediaItem.
+ */
+ function deleteMediaItemPopup(album, mediaItem) {
+ var albumId = mediaItem.albumId;
+ if (confirm("Delete '" + mediaItem.title + "'?")) {
+ social.deleteMediaItem(viewer.id, albumId, mediaItem.id,
+ function(response) {
+ publish('org.apache.shindig.mediaItem.deleted', mediaItem);
+ console.log('delete mediaItem response: ' +
+ JSON.stringify(response));
+ social.getMediaItemsByAlbum(viewer.id, albumId, function(response) {
+ renderMediaItems(album, response.list);
+ });
+ });
+ }
+ }
+
+ /*
+ * Publishers.
+ */
+ function publish(topic, payload) {
+ gadgets.Hub.publish(topic, payload);
+ }
+
+
+ return {
+
+ /*
+ * Initializes the gadget.
+ */
+ init: function() {
+
+ // Manages high-level divs
+ divManager = new DivManager();
+ divManager.init();
+
+ // Load data and render
+ loadData(function() {
+ social.getAlbumsByUser(viewer.id, function(response) {
+ renderAlbums(response.list);
+ divManager.showAlbums();
+ });
+ });
+ },
+
+ openAlbum: function(userId, album) {
+
+ // Manages high-level divs
+ divManager = new DivManager();
+ divManager.init();
+
+ loadData(function() {
+ social.getMediaItemsByAlbum(userId, album.id, function(response) {
+ renderMediaItems(album, response.list);
+ divManager.showMediaItems();
+ });
+ });
+
+ },
+
+ editAlbum: function(album) {
+
+ if (dojo.query('editAlbumFormDiv')) {
+ dojo.destroy('editAlbumFormDiv');
+ }
+
+ var formDiv = dojo.create('div', {id: 'editAlbumFormDiv'});
+
+ var form = new dijit.form.Form({id: 'editAlbumForm'});
+ formDiv.appendChild(form.domNode);
+
+ var table = dojo.create('table', null, form.domNode);
+ var tbody = dojo.create('tbody', null, table);
+
+ var tr = dojo.create('tr', null, tbody);
+ dojo.create('td', null, tr).appendChild(dojo.create('label',
+ {innerHTML: 'Title', for: 'title'}));
+ dojo.create('td', null, tr).appendChild(
+ new dijit.form.ValidationTextBox({
+ name: 'title',
+ value: album == null ? '' : album.title
+ }).domNode
+ );
+
+ tr = dojo.create('tr', null, tbody);
+ dojo.create('td', null, tr).appendChild(dojo.create('label',
+ {innerHTML: 'Thumnail URL', for: 'thumbnail'}));
+ dojo.create('td', null, tr).appendChild(
+ new dijit.form.ValidationTextBox({
+ name: 'thumbnail',
+ value: album == null ? '' : album.thumbnailUrl
+ }).domNode
+ );
+
+ tr = dojo.create('tr', null, tbody);
+ dojo.create('td', null, tr).appendChild(dojo.create('label',
+ {innerHTML: 'Description', for: 'description'}));
+ dojo.create('td', null, tr).appendChild(
+ new dijit.form.Textarea({
+ name: 'description',
+ value: album == null ? '' : album.description
+ }).domNode
+ );
+
+ tr = dojo.create('tr', null, tbody);
+ var buttonTd = dojo.create('td', {colspan: '2', align: 'center'}, tr);
+ buttonTd.appendChild(new dijit.form.Button({
+ label: 'Save',
+ onClick: saveForm
+ }).domNode
+ );
+
+ buttonTd.appendChild(new dijit.form.Button({
+ label: 'Cancel',
+ onClick: destroyDialog
+ }).domNode
+ );
+
+ dojo.body().appendChild(formDiv);
+ gadgets.window.adjustHeight();
+
+ function saveForm() {
+ var values = form.get('value');
+
+ album.title = values.title;
+ album.thumbnailUrl = values.thumbnail;
+ album.description = values.description;
+
+ gadgets.views.setReturnValue(album);
+ destroyDialog();
+ }
+
+ function destroyDialog() {
+ gadgets.views.close('');
+ }
+ },
+
+ editMediaItem: function(album, mediaItem) {
+
+ var albumId = mediaItem == null ? album.id : mediaItem.albumId;
+ var title = (mediaItem == null ? 'Create' : 'Edit') + ' MediaItem';
+
+ if (dojo.query('editMediaItemDialogDiv')) {
+ dojo.destroy('editMediaItemDialogDiv');
+ }
+ // Form div
+ var formDiv = dojo.create('div', {id: 'editMediaItemFormDiv'});
+ var form = new dijit.form.Form({id: 'editMediaItemForm'});
+ formDiv.appendChild(form.domNode);
+ var table = dojo.create('table', null, form.domNode);
+ var tbody = dojo.create('tbody', null, table);
+ var tr = dojo.create('tr', null, tbody);
+ dojo.create('td', null, tr).appendChild(dojo.create('label',
+ {innerHTML: 'Title', for: 'title'}));
+ dojo.create('td', null, tr).appendChild(
+ new dijit.form.ValidationTextBox({
+ name: 'title',
+ value: mediaItem == null ? '' : mediaItem.title
+ }).domNode
+ );
+ tr = dojo.create('tr', null, tbody);
+ dojo.create('td', null, tr).appendChild(dojo.create('label',
+ {innerHTML: 'Description', for: 'description'}));
+ dojo.create('td', null, tr).appendChild(
+ new dijit.form.Textarea({
+ name: 'description',
+ value: mediaItem == null ? '' : mediaItem.description
+ }).domNode
+ );
+ tr = dojo.create('tr', null, tbody);
+ dojo.create('td', null, tr).appendChild(dojo.create('label',
+ {innerHTML: 'Type', for: 'type'}));
+ dojo.create('td', null, tr).appendChild(
+ new dijit.form.ValidationTextBox({
+ name: 'type',
+ value: mediaItem == null ? '' : mediaItem.type
+ }).domNode
+ );
+ tr = dojo.create('tr', null, tbody);
+ dojo.create('td', null, tr).appendChild(dojo.create('label',
+ {innerHTML: 'Thumnail URL', for: 'thumbnailUrl'}));
+ dojo.create('td', null, tr).appendChild(
+ new dijit.form.ValidationTextBox({
+ name: 'thumbnailUrl',
+ value: mediaItem == null ? '' : mediaItem.thumbnailUrl
+ }).domNode
+ );
+ tr = dojo.create('tr', null, tbody);
+ dojo.create('td', null, tr).appendChild(dojo.create('label',
+ {innerHTML: 'URL', for: 'url'}));
+ dojo.create('td', null, tr).appendChild(
+ new dijit.form.ValidationTextBox({
+ name: 'url',
+ value: mediaItem == null ? '' : mediaItem.url
+ }).domNode
+ );
+ tr = dojo.create('tr', null, tbody);
+ var buttonTd = dojo.create('td', {colspan: '2', align: 'center'}, tr);
+ buttonTd.appendChild(new dijit.form.Button({
+ label: 'Save',
+ onClick: saveForm
+ }).domNode
+ );
+ buttonTd.appendChild(new dijit.form.Button({
+ label: 'Cancel',
+ onClick: destroyDialog
+ }).domNode
+ );
+
+ // Textarea div for JSON
+ var textAreaDiv = dojo.create('div',
+ {style: 'width:100%; height:100%;', id: 'textAreaDiv'});
+ var textArea = new dijit.form.Textarea({value: JSON.stringify(mediaItem),
+ rows: '20'});
+ textAreaDiv.appendChild(textArea.domNode);
+
+ // Put divs together
+ var tabContainer = new dijit.layout.TabContainer(
+ {style: 'width:400px; height:275px;'});
+ var formContentPane = new dijit.layout.ContentPane(
+ {title: 'Form', content: formDiv});
+ tabContainer.addChild(formContentPane);
+ var textAreaContentPane = new dijit.layout.ContentPane(
+ {title: 'JSON', content: textAreaDiv});
+ tabContainer.addChild(textAreaContentPane);
+ tabContainer.startup();
+ var dialogDiv = dojo.create('div', {id: 'editMediaItemDialogDiv'});
+ dialogDiv.appendChild(tabContainer.domNode);
+
+ dojo.body().appendChild(dialogDiv);
+ gadgets.window.adjustHeight();
+
+ function saveForm() {
+ var values = form.get('value');
+
+ var newMediaItem = {
+ title: values.title,
+ description: values.description,
+ type: values.type,
+ thumbnailUrl: values.thumbnailUrl,
+ url: values.url
+ };
+
+ gadgets.views.setReturnValue(newMediaItem);
+ destroyDialog();
+ }
+
+ function destroyDialog() {
+ gadgets.views.close('');
+ }
+ }
+ };
+}
Added: shindig/trunk/content/samplecontainer/examples/media-openGadgets/Social.js
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/media-openGadgets/Social.js?rev=1149287&view=auto
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/media-openGadgets/Social.js (added)
+++ shindig/trunk/content/samplecontainer/examples/media-openGadgets/Social.js Thu Jul 21 18:02:23 2011
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+
+/*
+ * Defines high level functionality to interact with the OpenSocial API.
+ */
+function SocialWrapper() {
+
+ /*
+ * Retrieves the current viewer.
+ */
+ this.getViewer = function(callback) {
+ osapi.people.getViewer().execute(callback);
+ }
+
+ /*
+ * Retrieves the current owner.
+ */
+ this.getOwner = function(callback) {
+ osapi.people.getOwner().execute(callback);
+ }
+
+ // ------------------------ ALBUMS ----------------------
+ /*
+ * Retrieves albums by ID(s).
+ */
+ this.getAlbumsById = function(userId, albumId, callback) {
+ var params = {userId: userId, albumId: albumId};
+ osapi.albums.get(params).execute(callback);
+ }
+
+ /*
+ * Retrieves albums by user.
+ */
+ this.getAlbumsByUser = function(userId, callback) {
+ osapi.albums.get({userId: userId}).execute(callback);
+ }
+
+ /*
+ * Retrieves albums by group.
+ */
+ this.getAlbumsByGroup = function(userId, groupId, callback) {
+ osapi.albums.get({userId: userId, groupId: groupId}).execute(callback);
+ }
+
+ /*
+ * Creates an album for the given user.
+ */
+ this.createAlbum = function(userId, album, callback) {
+ var params = {
+ userId: userId,
+ album: album
+ };
+ osapi.albums.create(params).execute(callback);
+ }
+
+ /*
+ * Updates an album by ID.
+ */
+ this.updateAlbum = function(userId, albumId, album, callback) {
+ var params = {
+ userId: userId,
+ albumId: albumId,
+ album: album
+ };
+ osapi.albums.update(params).execute(callback);
+ }
+
+ /*
+ * Deletes an album by ID.
+ */
+ this.deleteAlbum = function(userId, albumId, callback) {
+ var params = {userId: userId, albumId: albumId};
+ osapi.albums.delete(params).execute(callback);
+ }
+
+ // ------------------------------- MEDIAITEMS ----------------------------
+ /*
+ * Creates a MediaItem.
+ */
+ this.createMediaItem = function(userId, albumId, mediaItem, callback) {
+ var params = {
+ userId: userId,
+ albumId: albumId,
+ mediaItem: mediaItem
+ };
+ osapi.mediaItems.create(params).execute(callback);
+ }
+
+ /*
+ * Updates a MediaItem by ID.
+ */
+ this.updateMediaItem = function(userId, albumId, mediaItemId, mediaItem,
+ callback) {
+ var params = {
+ userId: userId,
+ albumId: albumId,
+ mediaItemId: mediaItemId,
+ mediaItem: mediaItem
+ };
+ console.log('PARAMS: ' + JSON.stringify(params));
+ osapi.mediaItems.update(params).execute(callback);
+ }
+
+ /*
+ * Retrieves MediaItems by ID(s).
+ */
+ this.getMediaItemsById = function(userId, albumId, mediaItemId, callback) {
+ var params = {
+ userId: userId,
+ albumId: albumId,
+ mediaItemId: mediaItemId
+ };
+ osapi.mediaItems.get(params).execute(callback);
+ }
+
+ /*
+ * Retrieves MediaItems by album.
+ */
+ this.getMediaItemsByAlbum = function(userId, albumId, callback) {
+ osapi.mediaItems.get({userId: userId, albumId: albumId}).execute(callback);
+ }
+
+ /*
+ * Retrieves MediaItems by user and group.
+ */
+ this.getMediaItemsByUser = function(userId, groupId, callback) {
+ osapi.mediaItems.get({userId: userId, groupId: groupId}).execute(callback);
+ }
+
+ /*
+ * Deletes a MediaItem by ID.
+ */
+ this.deleteMediaItem = function(userId, albumId, mediaItemId, callback) {
+ var params = {
+ userId: userId,
+ albumId: albumId,
+ mediaItemId: mediaItemId
+ };
+ osapi.mediaItems.delete(params).execute(callback);
+ }
+}
Added: shindig/trunk/content/samplecontainer/examples/media-openGadgets/styles.css
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/media-openGadgets/styles.css?rev=1149287&view=auto
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/media-openGadgets/styles.css (added)
+++ shindig/trunk/content/samplecontainer/examples/media-openGadgets/styles.css Thu Jul 21 18:02:23 2011
@@ -0,0 +1,109 @@
+/**
+ * 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.
+ */
+/* ============ ROUND 2 ============== */
+td.albumsTitle {
+ font-family: 'comic sans ms';
+ width: 100%;
+ font-size: 24px;
+}
+
+td.albumListThumbnail {
+ width: 10%;
+ height: 75px;
+}
+
+td.albumListRight {
+ width: 90%;
+}
+
+td.actionLinks {
+ width: 100%;
+ font-size: 12px;
+}
+
+td.albumListTitle {
+ font-size: 24px;
+ white-space: nowrap;
+ font-family: 'comic sans ms';
+}
+
+td.albumListDescription {
+ font-family: 'comic sans ms';
+}
+
+.albumsTable {
+ width: 100%;
+ border-style: solid;
+ background-color: #b0c4de;
+}
+
+td.mediaItemThumbnail {
+ height: 100%;
+}
+
+td.mediaItemBox {
+ width: 150px;
+ height: 100px;
+}
+
+.mediaItemControls {
+
+}
+
+/* ============ ROUND 1 ============== */
+.temp1 {
+ background-color: #6495ed;
+}
+
+.temp2 {
+ background-color: #e0ffff;
+}
+
+.temp3 {
+ background-color: #b0c4de;
+ background-image: url("img_flwr.png");
+ background-repeat: no-repeat;
+ background-position: top right;
+}
+
+td2 {
+ border-style: solid;
+}
+
+td.albumLeft {
+ width: 10%;
+}
+
+td.albumRight {
+ width: 90%;
+}
+
+td.albumEdit {
+ width: 100%;
+ text-align: right;
+ vertical-align: middle;
+ font-size: 12px;
+}
+
+.albumTitleStyle {
+ color: blue;
+}
+
+.albumElement {
+ background-color: #b0c4de;
+}
\ No newline at end of file
Modified: shindig/trunk/features/pom.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/pom.xml?rev=1149287&r1=1149286&r2=1149287&view=diff
==============================================================================
--- shindig/trunk/features/pom.xml (original)
+++ shindig/trunk/features/pom.xml Thu Jul 21 18:02:23 2011
@@ -184,6 +184,8 @@
<source>opensearch/opensearch.js</source>
<source>embeddedexperiences/constant.js</source>
<source>embeddedexperiences/embedded_experiences_container.js</source>
+ <source>open-views/viewenhancements-container.js</source>
+ <source>open-views/viewenhancements.js</source>
</sources>
<testSourceDirectory>${basedir}/src/test/javascript/features</testSourceDirectory>
<testSuites>
Modified: shindig/trunk/features/src/main/javascript/features/features.txt
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/features.txt?rev=1149287&r1=1149286&r2=1149287&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/features.txt (original)
+++ shindig/trunk/features/src/main/javascript/features/features.txt Thu Jul 21 18:02:23 2011
@@ -73,6 +73,7 @@ features/opensocial-data/feature.xml
features/opensocial-jsonrpc/feature.xml
features/opensocial-reference/feature.xml
features/opensocial-templates/feature.xml
+features/open-views/feature.xml
features/osapi.base/feature.xml
features/osapi/feature.xml
features/osml/feature.xml
Added: shindig/trunk/features/src/main/javascript/features/open-views/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/open-views/feature.xml?rev=1149287&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/open-views/feature.xml (added)
+++ shindig/trunk/features/src/main/javascript/features/open-views/feature.xml Thu Jul 21 18:02:23 2011
@@ -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>
+<!--
+Required configuration:
+A map of view names to view attributes. Examples:
+
+
+-->
+ <name>open-views</name>
+ <dependency>globals</dependency>
+ <dependency>rpc</dependency>
+ <dependency>container.url</dependency>
+ <dependency>views</dependency>
+ <dependency>embedded-experiences</dependency>
+ <gadget>
+ <script src="viewenhancements.js"/>
+ <api>
+ <exports type="js">gadgets.views.openEmbeddedExperience</exports>
+ <exports type="js">gadgets.views.openGadget</exports>
+ <exports type="js">gadgets.views.openUrl</exports>
+ <exports type="js">gadgets.views.close</exports>
+ <exports type="js">gadgets.views.setReturnValue</exports>
+ <exports type="js">gadgets.window.getContainerDimensions</exports>
+ </api>
+ </gadget>
+ <container>
+ <script src="viewenhancements-container.js"/>
+ </container>
+</feature>
Added: shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements-container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements-container.js?rev=1149287&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements-container.js (added)
+++ shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements-container.js Thu Jul 21 18:02:23 2011
@@ -0,0 +1,417 @@
+/*
+ * 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 Container-side view enhancements.
+ */
+
+(function() {
+
+ var context;
+
+ // Mapping between id and callback function
+ var resultCallbackMap;
+
+ // Mapping between id and return value
+ var returnValueMap;
+
+ // mapping between iframe id and site
+ var iframeSiteMap;
+
+ function init(container) {
+
+ context = container;
+
+ gadgets.rpc.register('gadgets.views.openGadget', openGadget);
+
+ gadgets.rpc.register('gadgets.views.openEmbeddedExperience', openEE);
+
+ gadgets.rpc.register('gadgets.views.openUrl', openUrl);
+
+ gadgets.rpc.register('gadgets.views.close', close);
+
+ gadgets.rpc.register('gadgets.views.setReturnValue', setReturnValue);
+
+ gadgets.rpc.register('gadgets.window.getContainerDimensions',
+ getContainerDimensions);
+
+ resultCallbackMap = {};
+
+ returnValueMap = {};
+
+ iframeSiteMap = {};
+ };
+ /**
+ * Opens a gadget in the container UI. The location of the gadget site in the
+ * container will be determined by the view target passed in. The container
+ * would open the view in a dialog, if view target is dialog or the gadgets
+ * view in a tab for view target is tab.
+ *
+ * @param {function}
+ * resultCallback: Callback function to be called when the gadget
+ * closes. The function will be called with the return value as a
+ * parameter.
+ * @param {function}
+ * navigateCallback: Callback function to be called with the the
+ * Site which has been opened and metadata.
+ * @param {Object.<string, string|Object>=}
+ * opt_params: These are optional parameters which can be used to
+ * open gadgets. The following parameters may be included in this
+ * object. {string} view: The view to render. Should be one of the
+ * views returned by calling gadgets.views.getSupportedViews. If the
+ * view is not included the default view will be rendered. {string}
+ * viewTarget: The view that indicates where to open the gadget. For
+ * example, tab, dialog or modaldialog {Object} viewParams: View
+ * parameters for the view being rendered.
+ */
+ function openGadget(resultCallback, navigateCallback, opt_params) {
+
+ var gadgetUrl = '';
+
+ var orig_site = context.getGadgetSiteByIframeId_(this.f);
+
+ if (orig_site !== undefined &&
+ orig_site.getActiveGadgetHolder() !== undefined) {
+ // get url through gadget holder
+ gadgetUrl = orig_site.getActiveGadgetHolder().getUrl();
+ }
+
+ var view = '';
+ var viewTarget = '';
+ var viewParams = {};
+ if (opt_params !== undefined) {
+ if (opt_params.view !== undefined)
+ view = opt_params.view;
+ if (opt_params.viewTarget !== undefined)
+ viewTarget = opt_params.viewTarget;
+ if (opt_params.viewParams !== undefined)
+ viewParams = opt_params.viewParams;
+ }
+ context.preloadGadget(gadgetUrl, function(result) {
+ /*
+ * result[gadgetUrl] : metadata
+ */
+ var metadata = {};
+ if (result !== undefined && result[gadgetUrl] !== undefined) {
+ if (result[gadgetUrl].error) {
+ gadgets.error('Failed to preload gadget : ' + gadgetUrl);
+ if (navigateCallback != null) {
+ navigateCallback(null, result[gadgetUrl]);
+ }
+ return;
+ }else {
+ metadata = result[gadgetUrl];
+ }
+ }
+ var content_div = context.views.createElementForGadget(metadata, view,
+ viewTarget);
+ var site = context.newGadgetSite(content_div);
+
+ var renderParams = {};
+
+ if (view !== undefined && view !== '') {
+ renderParams[osapi.container.RenderParam.VIEW] = view;
+ }
+ renderParams[osapi.container.RenderParam.WIDTH] = '100%';
+ renderParams[osapi.container.RenderParam.HEIGHT] = '100%';
+
+ context.navigateGadget(site, gadgetUrl, viewParams, renderParams,
+ function(metadata) {
+ if (metadata != null) {
+ processSiteAndCallbackInfo(site, resultCallback);
+ }
+ if (navigateCallback != null) {
+ navigateCallback(site, metadata);
+ }
+ });
+
+ });
+ }
+
+ /**
+ * Processes the site and callback information and stores it in global maps.
+ * @param {osapi.container.GadgetSite | osapi.container.UrlSite} site the site
+ * that was created for the gadget.
+ * @param {Function} resultCallback called with any result the gadget chooses
+ * to set.
+ */
+ function processSiteAndCallbackInfo(site, resultCallback) {
+ var iframeId;
+ if (site && site.getActiveGadgetHolder()) {
+ iframeId = site.getActiveGadgetHolder().getIframeId();
+ }
+
+ iframeSiteMap[iframeId] = site;
+
+ // use the site id as key
+ if (typeof site.getId() !== 'undefined' && resultCallback != null) {
+ resultCallbackMap[site.getId()] = resultCallback;
+ }
+ }
+
+ /**
+ * Opens an embedded experience in the container UI. The location of the site
+ * in the container will be determined by the view target passed in. The
+ * container would open the embedded experience in a dialog, if view target is
+ * dialog or the embedded experience view in a tab for view target is tab.
+ *
+ * @param {Function}
+ * resultCallback: Callback function to be called when the embedded
+ * experience closes. The function will be called with the return
+ * value as a parameter.
+ * @param {Function}
+ * navigateCallback: Callback function to be called with the embedded
+ * experience has rendered.
+ * @param {Object}
+ * opt_params: These are optional parameters which can be used to
+ * open gadgets. The following parameters may be included in this
+ * object. {string} viewTarget: The view that indicates where to open
+ * the gadget. For example, tab, dialog or modaldialog {Object}
+ * viewParams: View parameters for the view being rendered.
+ */
+ function openEE(resultCallback, navigateCallback, dataModel, opt_params) {
+ var gadgetUrl = dataModel.gadget;
+ if (gadgetUrl) {
+ //Check to make sure we can actually reach the gadget we are going to try
+ //to render before we do anything else
+ context.preloadGadget(gadgetUrl, function(result) {
+ if (result[gadgetUrl] == null ||
+ (result[gadgetUrl] != null && result[gadgetUrl].error)) {
+ //There was an error, check to see if there is still the option to
+ //render the url, else just call the navigateCallback
+ if (!dataModel.url) {
+ if (navigateCallback != null) {
+ navigateCallback(null, result[gadgetUrl]);
+ }
+ return;
+ }
+ }
+
+ var viewTarget = '';
+ var viewParams = {};
+ if (opt_params != undefined) {
+ if (opt_params.viewTarget != undefined)
+ viewTarget = opt_params.viewTarget;
+ if (opt_params.viewParams != undefined)
+ viewParams = opt_params.viewParams;
+ }
+
+ var element = context.views.createElementForEmbeddedExperience(
+ viewTarget);
+
+ var gadgetRenderParams = {};
+ gadgetRenderParams[osapi.container.RenderParam.VIEW] =
+ osapi.container.ee.RenderParams.EMBEDDED;
+ gadgetRenderParams[osapi.container.RenderParam.WIDTH] = '100%';
+ gadgetRenderParams[osapi.container.RenderParam.HEIGHT] = '100%';
+
+ var urlRenderParams = {};
+ urlRenderParams[osapi.container.RenderParam.WIDTH] = '100%';
+ urlRenderParams[osapi.container.RenderParam.HEIGHT] = '100%';
+
+ var eeRenderParams = {};
+ eeRenderParams[osapi.container.ee.RenderParams.GADGET_RENDER_PARAMS] =
+ gadgetRenderParams;
+ eeRenderParams[osapi.container.ee.RenderParams.URL_RENDER_PARAMS] =
+ urlRenderParams;
+ eeRenderParams[osapi.container.ee.RenderParams.GADGET_VIEW_PARAMS] =
+ viewParams;
+
+ context.ee.navigate(element, dataModel, eeRenderParams, function(site,
+ metadata) {
+ if (metadata != null) {
+ processSiteAndCallbackInfo(site, resultCallback);
+ }
+ if (navigateCallback != null) {
+ navigateCallback(site, metadata);
+ }
+ });
+ });
+ }
+ }
+
+
+ /**
+ * Opens a URL in the container UI. The location of the URL site will be
+ * determined by the container based on the target view. The container would
+ * open the view in a dialog, if opt_viewTarget=dialog or the gadgets view in
+ * a tab for opt_viewTarget=tab
+ *
+ * @param {string}
+ * url: URL to a web page to open in a URL site in the container.
+ * (Note this should not be a URL to a gadget definition.).
+ * @param {function}
+ * navigateCallback: Callback function to be called with the site
+ * which has been opened.
+ * @param {string=}
+ * opt_viewTarget: Optional parameter,the view that indicates where
+ * to open the URL.
+ */
+ function openUrl(url, navigateCallback, opt_viewTarget) {
+ var content_div = context.views.createElementForUrl(opt_viewTarget);
+
+ var site = context.newUrlSite(content_div);
+
+ var renderParams = {}; // (height, width, class,userPrefsObject)
+ renderParams[osapi.container.RenderParam.WIDTH] = '100%';
+ renderParams[osapi.container.RenderParam.HEIGHT] = '100%';
+
+ context.navigateUrl(site, url, renderParams);
+
+ if (navigateCallback !== undefined) {
+ navigateCallback(site);
+ }
+ }
+
+ /**
+ * Closes an opened site. If the opt_id parameter is null the container will
+ * close the calling site.
+ *
+ * @param {object=}
+ * opt_site: Optional parameter which specifies what site to close.
+ * If null it will close the current gadget site.
+ */
+ function close(opt_site) {
+ // this.f is the frame id
+ var iframeId = this.f;
+ var site;
+
+ if (opt_site == undefined || opt_site == '') {
+ site = iframeSiteMap[iframeId];
+ }
+ else {
+ site = opt_site;
+ }
+
+ if (site != null) {
+ var siteId = site.getId();
+
+ if (siteId !== undefined && resultCallbackMap[siteId] !== undefined &&
+ returnValueMap[siteId] !== undefined) {
+ var returnValue = returnValueMap[siteId];
+ // execute the result callback function with return value as parameter
+ resultCallbackMap[siteId](returnValue);
+ }
+ }
+
+ context.views.destroyElement(site);
+ }
+
+ /**
+ * Sets the return value for the current window. This method should only be
+ * called inside those secondary view types defined in gadgets.views.ViewType.
+ * For example, DIALOG or MODALDIALOG
+ *
+ * @param {object}
+ * returnValue: Return value for this window.
+ */
+ function setReturnValue(returnValue) {
+ if (returnValue !== undefined && iframeSiteMap[this.f] !== undefined) {
+ var siteId = iframeSiteMap[this.f].getId();
+ // use the site id as key
+ if (siteId !== undefined) {
+ returnValueMap[siteId] = returnValue;
+ }
+ }
+ }
+
+ /**
+ * Gets the dimensions of the container displaying the gadget.
+ */
+ function getContainerDimensions() {
+ var el = document.documentElement; // Container
+ // element
+ if (el !== undefined)
+ // return client width and client height
+ return {
+ 'width' : el.clientWidth,
+ 'height' : el.clientHeight
+ };
+ else
+ return {
+ 'width' : -1,
+ 'height' : -1
+ };
+ }
+
+ osapi.container.Container.addMixin('views', function(container) {
+
+ init(container);
+
+ return { // this is a map of the public API in the namespace
+ /**
+ * Method will be called to create the DOM element to place the Gadget
+ * Site in.
+ *
+ * @param {Object}
+ * metadata: Gadget meta data for the gadget being opened in
+ * this GadgetSite.
+ * @param {string=}
+ * opt_view: Optional parameter, the view that indicates the
+ * type of GadgetSite.
+ * @param {string=}
+ * opt_viewTarget: Optional parameter, the view target indicates
+ * where to open the gadget.
+ * @return {Object} The DOM element to place the GadgetSite in.
+ */
+ 'createElementForGadget' : function(metadata, opt_view, opt_viewTarget) {
+ console.log('container need to define createElementForGadget function');
+ },
+
+ /**
+ * Method will be called to create the DOM element to place the embedded
+ * experience in.
+ *
+ * @param {string=}
+ * opt_viewTarget: Optional parameter, the view target indicates
+ * where to open.
+ * @return {Object} The DOM element to place the embedded experience in.
+ */
+
+ 'createElementForEmbeddedExperience' : function(opt_viewTarget) {
+ console.log('container need to define ' +
+ 'createElementForEmbeddedExperience function');
+ },
+
+ /**
+ * Method will be called to create the DOM element to place the UrlSite
+ * in.
+ *
+ * @param {string=}
+ * opt_view: Optional parameter, the view to open. If not
+ * included the container should use its default view.
+ * @return {Object} The DOM element to place the UrlSite object in.
+ */
+
+ 'createElementForUrl' : function(opt_viewTarget) {
+ console.log('container need to define createElementForUrl function');
+ },
+
+ /**
+ * Method will be called when a gadget wants to close itself or the
+ * parent gadget wants to close a gadget or url site it has opened.
+ *
+ * @param {Object}
+ * site: The site to close.
+ */
+ 'destroyElement' : function(site) {
+ console.log('container need to define destroyElement function');
+ }
+ };
+ }); //end addMixin
+}());
Added: shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements.js?rev=1149287&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements.js (added)
+++ shindig/trunk/features/src/main/javascript/features/open-views/viewenhancements.js Thu Jul 21 18:02:23 2011
@@ -0,0 +1,144 @@
+/*
+ * 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 view enhancement library for gadgets.
+ */
+
+gadgets['window'] = gadgets['window'] || {};
+
+(function() {
+
+ /**
+ * Opens a gadget in the container UI. The location of the gadget site in the
+ * container will be determined by the view target passed in. The container
+ * would open the view in a dialog, if view target is dialog or the gadgets
+ * view in a tab for view target is tab
+ *
+ * @param {function}
+ * resultCallback: Callback function to be called when the gadget
+ * closes. The function will be called with the return value as a
+ * parameter.
+ * @param {function}
+ * idCallback: Callback function to be called with the id of the
+ * Site which has been opened.
+ * @param {Object}
+ * opt_params: These are optional parameters which can be used to
+ * open gadgets. The following parameters may be included in this
+ * object. {string} view: The view to render. Should be one of the
+ * views returned by calling gadgets.views.getSupportedViews. If the
+ * view is not included the default view will be rendered. {string}
+ * viewTarget: The view that indicates where to open the gadget. For
+ * example, tab, dialog or modaldialog {Object} viewParams: View
+ * parameters for the view being rendered.
+ */
+
+ gadgets.views.openGadget = function(resultCallback, idCallback, opt_params) {
+ gadgets.rpc.call('..', 'gadgets.views.openGadget', null, resultCallback,
+ idCallback, opt_params);
+ };
+
+ /**
+ * Opens an embedded experience in the container UI. The location of the
+ * gadget site in the container will be determined by the view target passed
+ * in. The container would open the view in a dialog, if view target is dialog
+ * or the gadgets view in a tab for view target is tab.
+ *
+ * @param {function}
+ * resultCallback: Callback function to be called when the gadget
+ * closes. The function will be called with the return value as a
+ * parameter.
+ * @param {function}
+ * navigateCallback: Callback function to be called with the site and
+ * gadget metadata.
+ * @param {function}
+ * dataModel: The embedded experiences data model.
+ * @param {Object}
+ * opt_params: These are optional parameters which can be used to
+ * open gadgets. The following parameters may be included in this
+ * object. {string} viewTarget: The view that indicates where to open
+ * the gadget. For example, tab, dialog or modaldialog {Object}
+ * viewParams: View parameters for the view being rendered.
+ */
+ gadgets.views.openEmbeddedExperience = function(resultCallback,
+ navigateCallback, dataModel, opt_params) {
+ gadgets.rpc
+ .call('..', 'gadgets.views.openEmbeddedExperience', null, resultCallback,
+ navigateCallback, dataModel, opt_params);
+ };
+
+ /**
+ * Opens a URL in the container UI. The location of the URL site will be
+ * determined by the container based on the target view. The container would
+ * open the view in a dialog, if opt_viewTarget=dialog or the gadgets view in
+ * a tab for opt_viewTarget=tab
+ *
+ * @param {string}
+ * url: URL to a web page to open in a URL site in the container.
+ * (Note this should not be a URL to a gadget definition.).
+ * @param {function}
+ * idCallback: Callback function to be called with the id of the
+ * site which has been opened.
+ * @param {string=}
+ * opt_viewTarget: Optional parameter,the view that indicates where
+ * to open the URL.
+ */
+ gadgets.views.openUrl = function(url, idCallback, opt_viewTarget) {
+ gadgets.rpc.call('..', 'gadgets.views.openUrl', null, url, idCallback,
+ opt_viewTarget);
+ }
+
+ /**
+ * Closes an opened site. If the opt_id parameter is null the container will
+ * close the calling site.
+ *
+ * @param {string}
+ * opt_id: Optional parameter which specifies what site to close.
+ * If null it will close the current gadget site.
+ */
+ gadgets.views.close = function(id) {
+ gadgets.rpc.call('..', 'gadgets.views.close', null, id);
+ };
+
+ /**
+ * Sets the return value for the current window. This method should only be
+ * called inside those secondary view types defined in gadgets.views.ViewType.
+ * For example, DIALOG or MODALDIALOG
+ *
+ * @param {object}
+ * returnValue: Return value for this window.
+ */
+ gadgets.views.setReturnValue = function(returnValue) {
+ gadgets.rpc.call('..', 'gadgets.views.setReturnValue', null, returnValue);
+ };
+
+ /**
+ * Gets the dimensions of the container displaying this gadget through
+ * callback function which will be called with the return value as a
+ * parameter.
+ *
+ * @param {function}
+ * resultCallback: Callback function will be called with the return
+ * value as a parameter.
+ */
+ gadgets.window.getContainerDimensions = function(resultCallback) {
+ gadgets.rpc.call('..', 'gadgets.window.getContainerDimensions',
+ resultCallback, null);
+ }
+
+}());