You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by zh...@apache.org on 2011/04/01 02:29:38 UTC

svn commit: r1087520 [22/35] - in /incubator/rave/donations/ogce-gadget-container: ./ config/ config/shindig-1.1-BETA5/ config/shindig-2.0.0/ db-cleaner/ examples/ examples/src/ examples/src/main/ examples/src/main/java/ examples/src/main/java/cgl/ exa...

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadget-layout-data-structure.js
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadget-layout-data-structure.js?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadget-layout-data-structure.js (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadget-layout-data-structure.js Fri Apr  1 00:29:22 2011
@@ -0,0 +1,1136 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+/*****************************************************************************
+ *      Following code is related to underlying data structure for           *
+ *      layout representation and manipulation.                              *
+ *  Note: UI component manipulation is not handled here.                     *
+ *****************************************************************************/
+
+Ext.namespace("cgl.shindig.ui.layout");
+
+cgl.shindig.ui.layout.layoutSuiteclass  = getLayoutSuiteClass();
+cgl.shindig.ui.layout.layoutclass       = getLayoutClass();
+cgl.shindig.ui.layout.tabclass          = getTabClass();
+cgl.shindig.ui.layout.columnclass       = getColumnClass();
+cgl.shindig.ui.layout.gadgetclass       = getGadgetClass();
+
+/** this function generates a new object represents the layout based on the
+ * input json object or string */
+cgl.shindig.ui.layout.generateLayoutObj = getLayoutObject();
+
+function getLayoutObject() {
+  return function(jsonstr_or_obj){
+    var obj = jsonstr_or_obj;
+    if( typeof jsonstr_or_obj == 'string' )
+        obj = eval(jsonstr_or_obj);
+    return new cgl.shindig.ui.layout.layoutclass(obj);
+  }
+}
+
+
+function getLayoutSuiteClass () {
+}
+
+function getLayoutClass() {
+  /**
+   * This class manages data of the whole layout.
+   * @param jonobj an JSON object which includes the layout data.
+   */
+  return function(jsonobj){
+
+    // theme option
+    this.ThemeOptionProp= 'theme';
+    
+    // sync option
+    this.SyncOptionProp = 'sync';
+    this.AutoSync       = 'auto';
+    this.ManualSync     = 'manual';
+
+    this.layoutDataProp = 'layoutdata';
+
+    this.USERNAMEKEY = 'username';
+    this.LAYOUTKEY = 'layout';
+    this.LAYOUTTYPEKEY = 'layouttype';
+    this.LAYOUTDATAKEY = 'layoutdata';
+    this.PROPERTIESKEY = 'properties';
+    this.ACTIVETABIDXKEY = 'activetabidx';
+
+    /** Note the parameter is an object so it is passed as reference.
+     *  I don't make a deep copy of the passed-in object. 
+     */
+    this.username = jsonobj[this.USERNAMEKEY];
+    this.jsonobj = jsonobj[this.LAYOUTKEY];
+
+    this.useNewFormat = true;
+
+    if (this.useNewFormat) {
+        if (this.jsonobj["layouts"] != null) { //new data format
+            this.jsonobj = this.jsonobj["layouts"][0];
+        }
+    }
+
+    this.activeTabIdx = (this.jsonobj[this.ACTIVETABIDXKEY]== null ? -1 : this.jsonobj[this.ACTIVETABIDXKEY]);
+
+    this.properties = this.jsonobj[this.PROPERTIESKEY];
+    if (this.properties == null || typeof this.properties != 'object')
+        this.properties = {};
+
+    this.tabobj = [];
+
+    if (this.jsonobj[this.layoutDataProp] != null) {
+        for(var i = 0; i < this.jsonobj[this.layoutDataProp].length; ++i){
+            var tabobj2 = this.jsonobj[this.layoutDataProp][i];
+            var tabidx = parseInt(tabobj2.tabid.substr("_tab_".length));
+            var tab = new cgl.shindig.ui.layout.tabclass(this.jsonobj.layoutdata[i], tabidx);
+            // this.tabobj.push();
+            this.tabobj[tabidx] = tab;
+        }
+    }
+    
+    if (this.activeTabIdx >= this.tabobj.length)
+        this.activeTabIdx = -1;
+
+    // this.clone = function() {
+    //     var newobj = {};
+    //     newobj 
+    // }
+
+    this.dirty = false;
+
+    this.markClean = function() {
+        this.dirty = false;
+    };
+    this.markDirty = function() {
+        this.dirty = true;
+    }
+    this.isDirty = function() {
+        return this.dirty;
+    }
+
+    this.layoutJs = {
+        type: "text/javascript",
+        defaultLayout: "js-tab-layout",
+        js: [{
+            name:   "tree",
+            id:     "js-tree-layout",
+            description:    "tree layout. On the left is a navigation tree. " +
+                            "On the right is the main gadget panel",
+            file:   "tree-layout.js"
+        }, {
+            name:   "tab",
+            id:     "js-tab-layout",
+            description:    "tab layout. On top is a tab bar. " +
+                            "The main panel is in the middle. " +
+                            "By clicking a tab label in tab bar, the main panel is switched",
+            file:   "tab-layout.js"
+        }],
+        // currentLayout: "tab",
+        /**
+         * First the layout with the specified id.
+         */
+        findLayout: function(id) {
+            for (var i = 0; i < this.js.length; ++i) {
+                var jsobj = this.js[i];
+                if (id == jsobj.id)
+                    return jsobj;
+            }
+            if (id != this.defaultLayout) {
+                return this.findLayout(this.defaultLayout);
+            } else {
+                return null;
+            }
+        },
+        /**
+         * return supported layouts.
+         * The returned value looks like:
+         *  [[id1, name1], [id2, name2]]
+         */
+        getLayoutNameIdList: function() {
+            var result = [];
+            for (var i = 0; i < this.js.length; ++i) {
+                var jsobj = this.js[i];
+                result.push([jsobj.id, jsobj.name]);
+            }
+            return result;
+        }
+
+        // switchLayout: function (to) {
+        //     var toObj = findLayout(to);
+        //     if (toObj == null) {
+        //         return;
+        //     }
+        // }
+    }
+
+    this.initProperties = function() {
+    }
+
+    this.getActiveTabIdx = function() {
+        return this.activeTabIdx;
+    };
+    this.setActiveTabIdx = function(newidx) {
+        this.activeTabIdx = newidx;
+    };
+
+    this.layoutType = this.jsonobj.layouttype;
+    if (this.layoutType == null || this.layoutType == '')
+        this.layoutType = this.layoutJs.defaultLayout;
+
+    this.getCurrentLayout = function() {
+        return this.layoutType;
+    }
+
+    this.setCurrentLayout = function(newLayout) {
+        this.layoutType = newLayout;
+    }
+
+    this.getLayoutNameIdList = function() {
+        return this.layoutJs.getLayoutNameIdList();
+    }
+
+    /**
+     * get layout type object of current layout.
+     */
+    this.getCurrentLayoutJsObj = function() {
+        var layoutJsObj = this.layoutJs.findLayout(this.getCurrentLayout());
+        return layoutJsObj;
+    }
+    this.getProperty = function (property) {
+        if (this.properties == null)
+            return null;
+        return this.properties[property];
+    }
+    this.setProperty = function (property, value) {
+        if (this.properties == null) {
+            this.properties = {};
+        }
+        this.properties[property] = value;
+    }
+
+    /**
+     * Because of addition and deletion of tabs, gadgets, the indices may not
+     * reflect positions of gadgets. This function adjusts indices.
+     * Note: only content of internal data structure is adjusted. If other
+     * parts rely on indices, they must be adjusted by users independently.
+     */
+    this.adjustIdx = function() {
+        var tabidx = -1;
+        for( var i = 0, j = 0 ; i < this.tabobj.length ; ++i, ++j){
+            if (j == this.getActiveTabIdx()) {
+                this.setActiveTabIdx(i);
+            }
+
+            if (this.tabobj[i] != null) {
+                this.tabobj[i].adjustIdx(i);
+            } else {
+                this.tabobj.splice(i, 1);
+                --i;
+            }
+        }
+        if (i != j)
+            this.markDirty();
+    };
+
+    /** return value is like: 
+     * [[tabid1, tabname1], [tabid2, tabname2]]
+     */
+    this.getTabNameIdList = function(){
+        var result = [];
+        for( var i = 0 ; i < this.tabobj.length ; ++i ){
+            if (this.tabobj[i] != null)
+                result.push( [this.tabobj[i].getTabId(), this.tabobj[i].getTabName()] );
+        }
+        return result;
+    };
+    
+    /** 
+     * ger tab count.
+     * NOTE!!! this includes those removed tabs who corresponding value in the
+     * array is null.
+     */
+    this.getTabCount = function(){
+        return this.tabobj.length;
+    };
+
+    /** 
+     * ger effective tab count.
+     * NOTE!!! this does not include those removed tabs who corresponding
+     * value in the array is null.
+     */
+    this.getEffectiveTabCount = function(){
+        var count = 0;
+        for (var i = 0; i < this.tabobj.length; ++i) {
+           if (this.tabobj[i] != null)
+             ++count;
+        }
+        return count;
+    };
+
+    this.getTabColumnCount = function(tabindex){
+        return this.tabobj[tabindex].getColumnCount();
+    };
+    this.getTabColumnGadgetCount = function(tabindex, columnindex){
+        return this.tabobj[tabindex].getColumnByIndex(columnindex).getGadgetCount();
+    };
+    this.getTabByIndex = function(tabindex){
+        return this.tabobj[tabindex];
+    };
+    this.getTabById = function(tabid, result){
+        for( var i = 0 ; i < this.getTabCount(); ++i ){
+            var tabobj = this.getTabByIndex(i);
+            if (tabobj == null) continue;
+            if (tabobj.getTabId() == tabid) {
+                if (arguments.length == 2 && result != null)
+                    result.tabidx = i
+                return tabobj;
+            }
+        }
+    };
+    this.getColumnByIndex = function(tabindex, columnindex){
+        return this.tabobj[tabindex].getColumnByIndex(columnindex);
+    };
+    this.getGadgetByIndex = function(tabindex, columnindex, gadgetindex){
+        return this.tabobj[tabindex].getColumnByIndex(columnindex).getGadgetByIndex(gadgetindex);
+    };
+   
+    // this.gadgetMap = {};
+
+    this.getGadgetIdxById = function(gadgetid) {
+        var idx = [];
+        for( var i = 0 ; i < this.getTabCount(); ++i ){
+            var tabobj = this.getTabByIndex(i);
+            if (tabobj == null) continue;
+            var r = tabobj.getGadgetIdxById(gadgetid);
+            if( r != null ) {
+                idx.push([i, tabobj]);
+                idx = idx.concat(r);
+                return idx;
+            }
+        }
+        return null;
+    }
+
+    this.getColumnIdxById = function(columnid) {
+        var idx = [];
+        for( var i = 0 ; i < this.getTabCount(); ++i ){
+            var tabobj = this.getTabByIndex(i);
+            if (tabobj == null) continue;
+            var r = tabobj.getColumnIdxById(columnid);
+            if( r != null ) {
+                idx.push([i, tabobj]);
+                idx = idx.concat(r);
+                return idx;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * get gadget object according to the specified gadget id.
+     * This operation traverses all gadgets to find a gadget with the specified id.
+     * So in the future, I may improve the performance.  
+     * @param gid gadget id
+     * @return a gadget object. Or null if no gadget has that id.
+     */
+    this.getGadgetById = function (gadgetid) {
+        for( var i = 0 ; i < this.getTabCount(); ++i ){
+            var tabobj = this.getTabByIndex(i);
+            if (tabobj == null) continue;
+            var r = tabobj.getGadgetByID(gadgetid);
+            if( r != null )
+                return r;
+        }
+        return null;
+    }
+    
+    /** 
+     * Get name of the gadget with the specified gadget id.
+     * @param gid gadget id
+     * @return name of the corresponding gadget. Or null if no gadget has that
+     * id.
+     */
+    this.getGadgetNameByID = function(gid){
+        var gadget = this.getGadgetById(gid);
+        if (gadget != null)
+            return gadget.getGadgetName();
+        else
+            return null;
+    };
+
+    /**
+     * get gadget name of the gadget with the specified id and belonging to
+     * the tab with specified tab index.
+     * @param gid gadget id
+     * @param tabidx index of the tab in which the search is done.
+     * @return gadget name
+     */
+    this.getGadgetNameByIDInTab = function(gid, tabidx){
+        var r = this.getTabByIndex(tabidx).getGadgetNameByID(gid);
+        if( r != null )
+            return r;
+        return null;
+    };
+
+    /**
+     * Add a new tab.
+     * @param tabname name of the newly added tab.
+     * @param tabid id of the tab.
+     * @return newly added tab object.
+     */
+    this.addNewTab = function(tabname, tabid, tabidx){
+        var newtabobj = {};
+        newtabobj.tabname = tabname;
+        newtabobj.tabid = tabid;//Ext.id();
+        newtabobj.column = 3;
+        newtabobj.content = null;
+        newtabobj =  new cgl.shindig.ui.layout.tabclass(newtabobj, tabidx);
+        this.tabobj.push(newtabobj);
+        return newtabobj;
+    };
+
+    /**
+     * Remove a tab.
+     * Note:  the corresponding element is cleared but not deleted from the
+     * array. The value becomes 'null'. This is essential so that application
+     * can access element of the array correctly.
+     * @param tabid id of the tab to be removed.
+     * @return removed tab object
+     */
+    this.removeTabById = function(tabid){
+        var result = [];
+        for( var i = 0 ; i < this.tabobj.length ; ++i ){
+            if (this.tabobj[i] == null)
+                continue;
+            if(tabid == this.tabobj[i].getTabId()){
+                var tabobj = this.tabobj[i];
+                this.tabobj[i] = null;
+                return tabobj;
+            }
+        }
+    };
+        
+    
+    /**
+     * Add a new gadget.
+     * @param gname name of the gadget
+     * @param gspecsrc specification address of the gadget
+     * @param grendersrc not used right now
+     * @param tabidx which tab the new gadget will be added to.
+     * @return the index of newly inserted gadget
+     * NOTE!!! the new gadget is added to the leftmost column
+     */
+    this.addNewGadget = function( gname, gspecsrc, grendersrc, tabidx ){
+        var tab = this.getTabByIndex( tabidx );
+        if (tab == null) {
+            alert("Are you adding the gadget to a invalid tab?");
+        } else {
+          var col = tab.getColumnByIndex( 0 );
+          return col.addGadget( gname, gspecsrc, grendersrc, tabidx, 0);
+        }
+    };
+
+    this.addNewGadget2Col = function( gname, gspecsrc, grendersrc, tabid, columnidx ){
+        var result = {};
+        var tab = this.getTabById(tabid, result);
+        if (tab == null) {
+            alert("Are you adding the gadget to a invalid tab?");
+        } else {
+          var tabidx = result.tabidx;
+          var col = tab.getColumnByIndex(columnidx);
+          return col.addGadget(gname, gspecsrc, grendersrc, tabidx, columnidx);
+        }
+    };
+    
+    /**
+     * delete a gadget.
+     * @param tabidx index of the tab in which the gadget appears.
+     * @param colidx index of the column in which the gadget appears.
+     * @param gidx   index of the gadget within the column.
+     */
+    this.deleteGadget = function( tabidx, colidx, gidx ){
+        var col = this.getColumnByIndex(tabidx, colidx);
+        col.deleteGadget(gidx);
+    };
+    
+    this.parseGadgetMaxId = function(gadgetMaxId) {
+        var gid = gadgetMaxId.substr(0, gadgetMaxId.length - '_max_'.length);
+        return gid;
+    }
+    this.parseGadgetToolbarId = function(gadgetTbId) {
+        var gid = gadgetTbId.substr(0, gadgetTbId.length- '_tb_'.length);
+        return gid;
+    }
+
+    /**
+     * helper function to parse gadget id.
+     * @param gadgetid gadget id to be parsed.
+     * @return [tabindex, colindex, gadgetindex]
+     */
+    this.parseGID = function(gadgetid){
+        return this.parseGID_(gadgetid);
+    };
+
+    this.parseGID_ = function(id) {
+        var len = id.length;
+        var ti = id.indexOf('_tab_');
+        var ci = id.indexOf('_col_');
+        var gi = id.indexOf('_gadget_');
+
+        var tabindex = -1, colindex = -1, gadgetindex = -1;
+        if (ti != -1) {
+            if (ci == -1) {
+                tabindex = parseInt(id.substring('_tab_'.length, len));
+            } else {
+                tabindex = parseInt(id.substring( '_tab_'.length, ci ) );
+                if (gi == -1) {
+                    colindex = parseInt(id.substring(ci+'_col_'.length, len));
+                } else {
+                    colindex = parseInt(id.substring(ci+'_col_'.length, gi));
+                    gadgetindex = parseInt(id.substring(gi+'_gadget_'.length));
+                }
+            }
+        }
+        return [tabindex, colindex, gadgetindex];
+    };
+
+    this.parseTabId = function(tabid) {
+        var tabindex = parseInt(tabid.substring( '_tab_'.length));
+        return [tabindex];
+    };
+
+    this.makeTabId = function(tabidx) {
+        return '_tab_' + tabidx;
+    }
+    this.makeColId = function(tabidx, colidx) {
+        return this.makeTabId(tabidx) + '_col_' + colidx;
+    }
+    this.makeGadgetId = function(tabidx, colidx, gadgetidx) {
+        return this.makeColId(tabidx, colidx) + '_gadget_' + gadgetidx;
+    }
+    this.makeGadgetMaxId = function(gadgetid) {
+        return gadgetid + '_max_';
+    }
+    this.makeGadgetToolbarId = function(gadgetid) {
+        return gadgetid + '_tb_';
+    }
+    this.makeGadgetIFrameId = function(gadgetid) {
+        return gadgetid + '_frame_';
+    }
+    this.makeGadgetMaxIFrameId = function(gadgetid) {
+        return gadgetid + '_max_iframe_';
+    }
+    this.makeGadgetMaxIFrameId = function(gadgetid) {
+        return gadgetid + '_max_iframe_';
+    }
+    
+    this.moveGadgetBtwnTabs = function(gadgetid, tabidx){
+        //TODO
+    };
+
+    /**
+     * move gadget within a tab.
+     * @param src source position of the gadget. 
+     *      Format: [tabidx, columnidx, gadgetidx]
+     * @param dst destination position of the gadget.
+     *      Format: [tabidx, columnidx, gadgetidx]
+     */
+    this.moveGadgetInATab = function(src, dst){
+        if( src[0] == dst[0] && src[1] == dst[1] && src[2] == dst[2] )
+            return;
+        this.markDirty();
+
+        var srccol = this.getColumnByIndex(src[0], src[1]);
+        var dstcol = this.getColumnByIndex(dst[0], dst[1]);
+        var gadget = srccol.removeGadgetByIndex(src[0], src[1], src[2]);
+        dstcol.insertGadgetByIndex(dst[0], dst[1], dst[2], gadget);
+    };
+
+    /**
+     * Changes the number of columns and column ratio
+     */
+    this.updateTabLayout = function(tabId, newColumnCount, ratios) {
+      this.setTabColumnCount(tabId, newColumnCount);
+      this.getTabById(tabId).setRatios(ratios);
+    }
+
+    /**
+     * sets the number of columns by shuffling gadgets around
+     */
+    this.setTabColumnCount = function(tabId, newColumnCount) {
+      var result = {};
+      var tab = this.getTabById(tabId, result);
+      var currentColumnCount = tab.getColumnCount();
+      var tabIdx = result.tabidx;
+
+      if( currentColumnCount >  newColumnCount ) {
+        /* Move all gadgets to other columns */
+        var moveToColumn = 0;
+        for( var columnIdx = newColumnCount; columnIdx < currentColumnCount; columnIdx++) {
+          while(tab.getColumnByIndex(columnIdx).getGadgetCount() > 0) {
+            var toGadgetIdx = tab.getColumnByIndex(moveToColumn).getGadgetCount();
+            //console.log("Move: " + tabIdx + ":" + columnIdx + ":" + 0 + "->" + tabIdx + ":" + moveToColumn + ":" + toGadgetIdx);
+            this.moveGadgetInATab([tabIdx, columnIdx, 0], [tabIdx, moveToColumn, toGadgetIdx]);
+            moveToColumn = (moveToColumn + 1) % newColumnCount;
+          }
+          //console.log("After Move ColumnIdx " + columnIdx + " has " + tab.getColumnByIndex(columnIdx).getGadgetCount() + " gadgets.");
+        }
+        tab.columnobj.splice(newColumnCount, currentColumnCount - newColumnCount);
+        //console.log("Tab with Id " + tab.getTabId() + " has " + tab.getColumnCount() + " columns.");
+      } else if( currentColumnCount < newColumnCount) {
+        tab.columnobj.push(new cgl.shindig.ui.layout.columnclass({}, tabidx, i));
+      }
+      this.markDirty();
+    };
+    
+
+    /**
+     * get index of the tab with the specified tabid.
+     * @param tabid
+     * @return
+     */
+    this.getTabIdx = function(tabid){
+        for(var i = 0; i < this.tabobj.length; ++i){
+            var tid = this.getTabByIndex(i).getTabId();
+            if( tid == tabid )
+                return i;
+        }
+    };
+    
+
+    this.serializeTabLayoutJSON = function(tabid){
+        var tabobj = this.getTabById(tabid);
+        if (tabobj != null)
+            return tabobj.serialize2JSON();
+    };
+
+    this.serializeLayoutJSON = function(){
+        var output = '{';
+        output += '"' + this.LAYOUTTYPEKEY + '":"' + this.getCurrentLayout() + '"';
+        output += ',"' + this.ACTIVETABIDXKEY + '":' + this.getActiveTabIdx();
+        output += ',"' + this.PROPERTIESKEY + '":' + this.serializeProperties();
+        output += ',"' + this.LAYOUTDATAKEY + '":[';
+        for( var i = 0 ; i < this.getTabCount() ; ++i ){
+            var tabobj = this.getTabByIndex(i);
+            if (tabobj == null) continue;
+            output += tabobj.serialize2JSON();
+            if( i < this.getTabCount() - 1)
+                output += ','
+        }
+        output += ']}';
+        if (this.useNewFormat)
+            output = '{"layouts": [' + output + ']}';
+        return output;
+    };
+
+    this.serializeProperties = function() {
+        var output = '{', first = true;
+        for (var prop in this.properties) {
+            if (this.properties.hasOwnProperty(prop) == true) {
+                if (first) {
+                    first = false;
+                } else {
+                    output += ',';
+                }
+                output += '"' + prop + '":"' + this.properties[prop] + '"';
+            }
+        }
+        output += '}';
+        return output;
+    }
+  };
+}
+
+function getTabClass() {
+  /** 
+   * this class represents the content in a single tab panel.
+   * @param jsonobj an json object which includes info of a tab
+   * @param tabidx  index of the tab
+   */
+  return function(jsonobj, tabidx){
+    this.TABNAMEKEY = 'tabname';
+    this.TABIDKEY = 'tabid';
+    this.COLUMNKEY = 'column';
+    this.COLCONTENTKEY = 'content';
+    this.RATIOSKEY = 'ratios';
+    
+    this.jsonobj = jsonobj;
+    this.columnobj = [];
+    
+    this.getStdColumnCount = function(){
+        return 3;
+    };
+    this.getStdRatios = function(){
+      return "33,34,33";
+    }; 
+    this.getOldStdRatios = function(){
+      return "33,33,33";
+    }; 
+    this.tabid = '_tab_' + tabidx;
+    
+    this.ratios = this.jsonobj[this.RATIOSKEY];
+    if(this.ratios == null)
+      this.ratios = this.getStdRatios();
+    if (this.ratios == this.getOldStdRatios())
+      this.ratios = this.getStdRatios();
+
+    // Add columns to the tab.
+    // number of column is fixed, even if some columns are empty, they are
+    // created as well.
+    var allColContentObj = this.jsonobj[this.COLCONTENTKEY];
+    if( allColContentObj != null ){
+        for(var i = 0 ; i < allColContentObj.length; ++i ){
+            this.columnobj.push(new cgl.shindig.ui.layout.columnclass(
+                  allColContentObj[i], tabidx, i));
+        }
+    } else {
+        for(var i = 0 ; i < this.getStdColumnCount(); ++i )
+            this.columnobj.push(new cgl.shindig.ui.layout.columnclass({}, tabidx, i));
+    }
+    
+    this.getGadgetIdxById = function(gadgetid) {
+        var idx = [];
+        for( var i = 0 ; i < this.getColumnCount(); ++i ){
+            var r = this.getColumnByIndex(i).getGadgetIdxById(gadgetid);
+            if( r != null ) {
+                idx.push([i, this.getColumnByIndex(i)]);
+                idx = idx.concat(r);
+                return idx;
+            }
+        }
+        return null;
+    };
+    
+    this.getColumnIdxById = function(columnid) {
+        var idx = [];
+        for( var i = 0 ; i < this.getColumnCount(); ++i ){
+            var column = this.getColumnByIndex(i);
+            if (columnid == column.getColumnId()) {
+                idx.push([i, column]);
+                return idx;
+            }
+        }
+        return null;
+    }
+
+    this.adjustIdx = function(idx) {
+        this.setTabId("_tab_" + idx);
+        for (var i = 0; i < this.getColumnCount(); ++i) {
+            this.getColumnByIndex(i).adjustIdx(this.getTabId());
+        }
+    };
+
+    this.findMaxGadgetsId = function() {
+        var result = [];
+        for (var i = 0; i < this.getColumnCount(); ++i) {
+            var gids = this.getColumnByIndex(i).findMaxGadgetsId();
+            result = result.concat(gids);
+        }
+        return result;
+    };
+
+    this.serialize2JSON = function(){
+        var output = '{';
+        output += '"'+this.TABNAMEKEY + '":"' + this.getTabName() + '"';
+        output += ',"'+this.TABIDKEY + '":"' + this.getTabId() + '"';
+        output += ',"'+this.COLUMNKEY + '":' + this.getColumnCount();
+        output += ',"'+this.RATIOSKEY + '":"' + this.getRatios() + '"';
+        output += ',"'+this.COLCONTENTKEY + '":[';
+        for( var i = 0 ; i < this.getColumnCount(); ++i ){
+            output += this.getColumnByIndex(i).serialize2JSON();
+            if( i < this.getColumnCount() - 1 ) 
+                output += ',';
+        }
+        output += ']}';
+        return output;
+    };
+    this.getTabId = function(){
+        // return this.jsonobj.tabid;
+        return this.tabid;
+    };
+    this.setTabId = function(newId){
+        this.tabid = newId;
+    };
+    this.getTabName = function(){
+        return this.jsonobj.tabname;
+    };
+    this.getColumnCount = function(){
+        return this.columnobj.length;
+    };
+    this.getColumnByIndex = function(columnindex){
+        return this.columnobj[columnindex];
+    };
+    this.getRatios = function() {
+      return this.ratios;
+    };
+    this.setRatios = function(value) {
+      this.ratios = value;
+    };
+
+
+    /**
+     * get a gadget with the specified gadget id.
+     */
+    this.getGadgetByID = function(gid) {
+        for( var i = 0 ; i < this.getColumnCount(); ++i ){
+            var r = this.getColumnByIndex(i).getGadgetByID(gid);
+            if( r != null )
+                return r;
+        }
+        return null;
+    };
+
+    this.getGadgetNameByID = function(gid){
+        for( var i = 0 ; i < this.getColumnCount(); ++i ){
+            var r = this.getColumnByIndex(i).getGadgetNameByID(gid);
+            if( r != null )
+                return r;
+        }
+        return null;
+    }
+  };
+};
+
+/* this class represents the content in a column within a tab panel */
+function getColumnClass() {
+  return function(jsonobj, tabidx, colidx){
+    this.COLUMNNAMEKEY = 'columnname';
+    this.COLUMNIDKEY = 'columnid';
+    this.COLUMNCONTENTKEY = 'content';
+    
+    this.jsonobj = jsonobj;
+    this.gadgetobj = [];
+    this.columnid = '_tab_' + tabidx + '_col_' + colidx;
+    
+    if(this.jsonobj == null){//create an empty column
+        //actually, this is impossible, because if this column would be empty, 
+        //an empty object({}) is passed in instead of null object.
+    }else{
+        var coldataobj = this.jsonobj[this.COLUMNCONTENTKEY];
+        if( coldataobj != null )
+            for(var i = 0; i < coldataobj.length; ++i){
+                this.gadgetobj.push(new cgl.shindig.ui.layout.gadgetclass(
+                      coldataobj[i], tabidx, colidx, i));
+            }
+    }
+
+    /**
+     * delete a gadget from this column.
+     * @param index of the gadget.
+     */
+    this.deleteGadget = function( gidx ){
+        this.gadgetobj.splice(gidx, 1);
+    };
+    
+    this.serialize2JSON = function(){
+        var output = '{';
+        output += '"' + this.COLUMNNAMEKEY + '":"' + this.getColumnName() +'"';
+        output += ',"' + this.COLUMNIDKEY + '":"' + this.getColumnId() + '"';
+        output += ',"' + this.COLUMNCONTENTKEY+'":[';
+        for( var i = 0 ; i < this.getGadgetCount() ; ++i ){
+            output += this.getGadgetByIndex(i).serialize2JSON();
+            if( i < this.getGadgetCount() - 1)
+                output += ',';
+        }
+        output += ']}';
+        return output;
+    };
+    
+    /**
+     * add a gadget to this column.
+     * @param gname name of the gadget
+     * @param gspecsrc
+     * @param grendersrc
+     * @param tabidx 
+     * @param colidx
+     * @return
+     */
+    this.addGadget = function( gname, gspecsrc, grendersrc, tabidx, colidx ){
+        var gadget = new cgl.shindig.ui.layout.gadgetclass({
+              'gadgetname': gname,
+              'gadgetspecsrc':gspecsrc,
+              'gadgetrendersrc':grendersrc
+            }, tabidx, colidx, this.getGadgetCount());
+        this.gadgetobj.push(gadget);
+        return gadget;
+        // return this.getGadgetCount()-1;
+    };
+    
+    this.getGadgetByIndex = function(index){
+        return this.gadgetobj[index];
+    };
+    this.getGadgetCount = function(){
+        return this.gadgetobj.length;
+    };
+    this.getColumnName = function(){
+        return this.jsonobj.columnname;
+    };
+    this.getColumnId = function(){
+        // return this.jsonobj.columnid;
+        return this.columnid;
+    };
+    this.adjustIdx = function(tabidx) {
+        this.columnid = '_tab_' + tabidx + '_col_' + colidx;
+    }
+
+    this.findMaxGadgetsId = function() {
+        var result = [];
+        for (var i = 0; i < this.getGadgetCount(); ++i) {
+            var gadget = this.getGadgetByIndex(i);
+            if (gadget.getGadgetStatus() != null && gadget.getGadgetStatus() == 'max')
+                result.push(gadget.getGadgetId());
+        }
+        return result;
+    };
+
+    this.getGadgetIdxById = function(gadgetid) {
+      var idx = [];
+        for( var i = 0 ; i < this.getGadgetCount() ; ++i ){
+            var gadget = this.getGadgetByIndex(i);
+            if( gadget.getGadgetId() == gadgetid ) {
+                idx.push([i, gadget]);
+                return idx;
+            }
+        }
+        return null;
+    };
+
+   this.getGadgetByID = function(gid) {
+        for( var i = 0 ; i < this.getGadgetCount() ; ++i ){
+            var gadget = this.getGadgetByIndex(i);
+            if( gadget.getGadgetId() == gid )
+                return gadget;
+        }
+        return null;
+    };
+
+    this.getGadgetNameByID = function(gid){
+      var gadget = this.getGadgetByID(gid);
+      if (gadget != null)
+        return gadget.getGadgetName();
+      else
+        return null;
+    }
+
+    /**
+     * remove a gadget
+     */
+    this.removeGadgetByIndex = function(tindex, cindex, gindex){
+        for( var i = gindex + 1; i < this.getGadgetCount() ; ++i ){
+            var id = this.getGadgetByIndex(i).getGadgetId();
+            if( cgl.shindig.ui.layout.dragsourcepos[id] )
+                cgl.shindig.ui.layout.dragsourcepos[id].gadgetindex -= 1;
+            else
+                alert('Something impossible happens when a gadget is removed from a column');
+        }
+        return this.gadgetobj.splice(gindex, 1)[0];
+    };
+    
+    /**
+     * insert a gadget to this column
+     */
+    this.insertGadgetByIndex = function(tindex, cindex, gindex, gadget){
+        //alert('inserting:'+cindex+'-'+gindex);
+        for( var i = gindex; i < this.getGadgetCount() ; ++i ){
+            var id = this.getGadgetByIndex(i).getGadgetId();
+            if( cgl.shindig.ui.layout.dragsourcepos[id] )
+                cgl.shindig.ui.layout.dragsourcepos[id].gadgetindex += 1;
+            else
+                alert('Something impossible happens when a gadget is inserted into a column');
+        }
+        this.gadgetobj.splice(gindex, 0, gadget);
+    };
+  };
+}
+
+
+/**
+ * represents a gadget block within a column
+ */
+function getGadgetClass() {
+  return function(jsonobj, tabidx, colidx, gidx){
+    this.GADGETNAMEKEY      = 'gadgetname';
+    this.GADGETSPECSRCKEY   = 'gadgetspecsrc';
+    this.GADGETRENDERSRC    = 'gadgetrendersrc';
+    this.GADGETID           = 'gadgetid';
+    this.USERPREFKEY        = 'userpref';
+    this.GADGETSTATUSKEY    = 'status';
+
+    this.selfref            = this;
+    
+    this.jsonobj = jsonobj;
+    if (this.jsonobj[this.USERPREFKEY] == null) {
+        this.userPrefs = {};
+    } else {
+        this.userPrefs = this.jsonobj[this.USERPREFKEY];
+        /*
+        for (var prop in this.userPrefs) {
+            if (this.userPrefs.hasOwnProperty(prop)) {
+                var value = unescape(this.userPrefs[prop]);
+                var key = unescape(prop);
+                alert(key+":"+value);
+                if (key == prop)
+                    this.userPrefs[prop] = value;
+                else {
+                    delete this.userPrefs[prop];
+                    this.userPrefs[key] = value;
+                }
+            }
+        }
+        */
+    }
+
+    this.gadgetstatus = this.jsonobj[this.GADGETSTATUSKEY];
+    if (this.gadgetstatus == null)
+        this.gadgetstatus = "normal";
+
+    this.gadgetid = '_tab_'+tabidx+'_col_'+colidx+'_gadget_'+gidx;
+
+    this.getURLEncodedUserPrefs = function(moduleId) {
+        var prefix = 'up_', first = true, output = '';
+        for (var prop in this.userPrefs) {
+            if (this.userPrefs.hasOwnProperty(prop)) {
+                if (first) {
+                    first = false;
+                } else {
+                    output += '&';
+                }
+                var value = this.userPrefs[prop];
+                // var seg = escape(prefix + prop) + '=' + escape(value);
+                var seg = prefix + prop + '=' + value;
+                output += seg;
+            }
+        }
+        return output;
+    }
+
+    this.getUserPrefs = function() {
+        return this.userPrefs;
+    }
+
+    this.getUserPrefValue = function(prefName) {
+        var value = this.userPrefs[prefName];
+        if (value != null) {
+            return unescape(value);
+        } else {
+            value;
+        }
+    };
+
+    this.setUserPrefs = function(ups) {
+        var upsobj = ups;
+        if (typeof ups == 'string') {
+            ups = ups.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+            if (ups == '') return;
+            upsobj = eval('('+ups+')');
+        }
+        if (typeof upsobj != 'object') {
+            alert("wrong user preference data");
+            return;
+        }
+        for (var prop in upsobj) {
+            if (upsobj.hasOwnProperty(prop)) 
+                this.setUserPrefValue(prop, upsobj[prop]);
+        }
+    };
+
+    this.setUserPrefValue = function(prefName, prefValue) {
+        if (prefValue != null)
+            this.userPrefs[prefName] = escape(prefValue);
+        else 
+            this.userPrefs[prefName] = '';
+    };
+
+    this.serializeUserPref2JSOn = function() {
+        var output = '{', first = true;
+        for (var prop in this.userPrefs) {
+            if (this.userPrefs.hasOwnProperty(prop)) {
+                if (first == true) {
+                    first = false;
+                } else {
+                    output += ',';
+                }
+                var value = this.getUserPrefValue(prop);
+                if (value == null)
+                  value = '';
+                    
+                output += '"'+prop + '":"' + escape(value) + '"';
+            }
+        }
+        output += '}';
+        return output;
+    };
+
+    this.serialize2JSON = function(){
+        var output = '{';
+        output += '"' + this.GADGETNAMEKEY + '":"' + this.getGadgetName() +'"';
+        output += ',"' + this.GADGETSPECSRCKEY + '":"' + this.getGadgetSpecSrc() + '"';
+        output += ',"' + this.GADGETRENDERSRC + '":"' + this.getGadgetRenderSrc() + '"';
+        output += ',"' + this.GADGETID + '":"' + this.getGadgetId() + '"';
+        output += ',"' + this.USERPREFKEY + '":' + this.serializeUserPref2JSOn();
+        output += ',"' + this.GADGETSTATUSKEY + '":"' + this.getGadgetStatus() + '"';
+        output += '}';
+        return output;
+    };
+
+    this.isInCanvasView = function() {
+        return this.gadgetstatus != null && this.gadgetstatus == "max";
+    };
+
+    this.isInHomeView = function() {
+        return this.gadgetstatus == null || this.gadgetstatus == "normal";
+    };
+
+   this.getGadgetStatus = function() {
+        return this.gadgetstatus;
+    };
+    this.setGadgetStatus = function(newgadgetstatus) {
+        this.gadgetstatus = newgadgetstatus;
+    };
+
+    this.getGadgetId = function(){
+        return this.gadgetid;
+    };
+    this.setGadgetId = function(gid){
+        this.gadgetid = gid;
+    };
+    this.getGadgetName = function(){
+        return this.jsonobj.gadgetname;
+    };
+    this.setGadgetName = function(newGadgetName){
+        return this.jsonobj.gadgetname = newGadgetName;
+    };
+    this.getGadgetSpecSrc = function(){
+        return this.jsonobj.gadgetspecsrc;
+    };
+    this.setGadgetSpecSrc = function(gadgetSpecSrc){
+        this.jsonobj.gadgetspecsrc = gadgetSpecSrc;
+    };
+    this.getEscapedGadgetSpecSrc = function(){
+        return escape(this.jsonobj.gadgetspecsrc);
+    };
+    this.getGadgetRenderSrc = function(){
+        return this.jsonobj.gadgetrendersrc;
+    };
+  };
+}
+

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadget-layout.js
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadget-layout.js?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadget-layout.js (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadget-layout.js Fri Apr  1 00:29:22 2011
@@ -0,0 +1,140 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+/*****************************************************************************
+ *          Initialize the whole page.                                      **
+ *          Basically get the layout data and load corresponding            **
+ *          scripts according to user setting.                              **
+ *****************************************************************************/
+
+/** new namespaces and global variables */
+Ext.namespace('cgl.shindig.ui.layout');
+Ext.namespace('cgl.shindig.ui.layout.remoteservice');
+
+cgl.shindig.ui.layout.curactivetabidx = -1;
+cgl.shindig.ui.layout.tbrenderlist = {};
+
+cgl.shindig.ui.layout.remoteservice.baseURL = null;
+//getBaseURL() is defined in util.js.
+cgl.shindig.ui.layout.remoteservice.layoutupdateaddress = getBaseURL() + "update/layout";
+cgl.shindig.ui.layout.remoteservice.getuinfoaddress = getBaseURL() + "users/";
+cgl.shindig.ui.layout.remoteservice.heartbeataddress = getBaseURL() + "heartbeat";
+cgl.shindig.ui.layout.remoteservice.connection = null;
+cgl.shindig.ui.layout.json = null;
+cgl.shindig.ui.layout.userinfowin = null;
+cgl.shindig.ui.layout.settingswin = null;
+
+//original json data will be converted to this internal representation
+cgl.shindig.ui.layout.layoutobj = null; 
+cgl.shindig.ui.layout.curactivetabidx = -1;
+
+
+/*
+window.onbeforeunload = function() {
+    var msg = "You have unsaved changes. " +
+        "Click 'Cancel' now, then 'logout'";
+    return msg;
+}
+*/
+
+(function () {
+
+/**
+ * The parameter of this function will be called when the page is loaded
+ */
+Ext.onReady(function (){
+    Ext.QuickTips.init();
+
+    Ext.apply(Ext.QuickTips.getQuickTip(), {
+        showDelay: 700
+    });
+
+    loadLayout();
+});
+
+function loadLayout() {
+    if( cgl.shindig.ui.layout.remoteservice.connection == null ){
+        cgl.shindig.ui.layout.remoteservice.connection = new Ext.data.Connection({
+            url: cgl.shindig.ui.layout.remoteservice.layoutupdateaddress
+        });
+    }
+    cgl.shindig.ui.layout.remoteservice.connection.request({//load initial data
+        method: 'GET',
+        url: cgl.shindig.ui.layout.remoteservice.layoutupdateaddress,
+        success: function( response, options ) {
+            cgl.shindig.ui.layout.json = eval('('+response.responseText+')');
+            // loadFirebugConsole();
+            if( cgl.shindig.ui.layout.json.error != null ) {
+                window.location.href = getURLWithoutPath() + cgl.shindig.ui.layout.json.redirect;
+            } else {
+                /* based on the configuration string, generates a new javascript object */
+        cgl.shindig.ui.layout.layoutobj = 
+          cgl.shindig.ui.layout.generateLayoutObj(cgl.shindig.ui.layout.json);
+                cgl.shindig.ui.layout.remoteservice.getuinfoaddress += 
+		    encodeURIComponent(cgl.shindig.ui.layout.layoutobj.username);
+					 /*
+					  TODO: this is from heartbeat.js?  This seems fragile, depends on index.html 
+					  loading stuff correctly. However, I'm not sure how to handle imports in
+					  javascript.
+					  */ 
+                heartBeatSetUp();
+            cgl.shindig.ops.getUserInfo(useSeparateProfile(), initLayout);
+            }
+        },
+        failure : function( response, options ) {
+            alert('init loading exception');
+				//TODO: this is defined in util.js. 
+            window.location.href = getSignURL();
+        }
+    });
+}
+
+/**
+ * load appropriate scripts according to user setting.
+ */
+function initLayout() {
+    var layoutobj = cgl.shindig.ui.layout.layoutobj;
+	 //getCurrentLayoutJsObj() is defined in gadget-layout-data-structure.js
+	 //This script prefixes javascript to the ishindig.hmlt's <head>
+	 //tag.  
+    var layouttypejsobj = layoutobj.getCurrentLayoutJsObj();
+    var script   = document.createElement("script")
+    script.type = 'text/javascript';
+	 //The script source will either be tree-layout.js or tab-layout.js
+	 //See layoutJS object definition in gadget-layout-data-structure.js
+    script.src = "js/" + layouttypejsobj.file;
+    script.onload = function(){
+        /** IE does not fire onload event for script element.
+         * I don't know why.
+         */
+        // afterLoadData();
+        // setLayoutUIText();
+        // setTheme();
+    };
+    var head = document.getElementsByTagName("head")[0];  
+	 //Append something like <script src="js/tab-layout.js" type="text/javascript"></script>
+	 //to the HTML <head> element. 
+    head.appendChild(script);
+}
+
+})();
+

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadgetui-components.js
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadgetui-components.js?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadgetui-components.js (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gadgetui-components.js Fri Apr  1 00:29:22 2011
@@ -0,0 +1,470 @@
+/*
+ *
+ * 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 toolbar of a gadget is not rendered from the start.
+  * It is only renderred when necessary.
+  * The renderring of toolbar should be executed only the first time the iframe is loaded.
+  * After that, if the iframe is reloaded or refreshed without refreshing the whole page, the toolbar
+  * should not be renderred again.
+  *
+  * @param tbdivid  id of the toolbar
+  */
+function renderAGadgetTB(tbdivid){
+    var tbidobj = getIdObjFromTbId(tbdivid);
+
+    //check whether the toolbar was rendered before.
+    if (cgl.shindig.ui.layout.tbrenderlist[tbdivid] != null) return;
+    
+    var removegadgetcallback = null;
+    try {
+        removegadgetcallback = cgl.shindig.ui.layout.gadget.removecallback;
+    } catch(err) {
+        // alert(err);
+    }
+
+    var _tb_ = createGadgetToolbar(tbdivid, false, removegadgetcallback);
+
+    _tb_.getEl().addClassOnOver('toolbar-over');
+    /* Add drag and drop support */
+    var _dd_ = new cgl.shindig.ui.dnd.DragSource(tbidobj.gid, {ddGroup:'group',
+        resizeFrame: true, /* actually this property is ignored */
+        centerFrame: false,
+        isTarget: false});
+    _dd_.setHandleElId(tbdivid);
+    _dd_.resizeFrame = true;
+    
+    _dd_.parent_colid = tbidobj.colid;
+    _dd_.gadgetindex = tbidobj.gadgetidx;//parseInt( _gid_.substr(_gid_.indexOf('_gadget_') + '_gadget_'.length) );
+    // _dd_.isTarget = false;
+    
+    //mark this toolbar has been rendered.
+    cgl.shindig.ui.layout.tbrenderlist[tbdivid] = true;
+    
+    //store the drag source of this gadget.
+    Ext.namespace("cgl.shindig.ui.layout");
+    if (cgl.shindig.ui.layout.dragsourcepos != null)
+        cgl.shindig.ui.layout.dragsourcepos[tbidobj.gid] = _dd_;
+
+    //set height according to the metadata retrieved from remote server
+    var layoutobj = cgl.shindig.ui.layout.layoutobj;
+    var gadget = layoutobj.getGadgetById(tbidobj.gid);;
+    var frameid = tbidobj.gid+'_frame_';
+    getGadgetHomeMetadata(gadget.getGadgetSpecSrc(), frameid);
+
+    var ifrurl = cgl.shindig.gadget.rendering.ops.genFullGadgetHomeRenderingURL(gadget);
+    constructIFrame(frameid, frameid + 'parent', ifrurl);
+}
+
+/** create a toolbar for default gadget display.
+ *  @param tbdivid: id of the toolbar.
+ *  @param isnewadded whether the toolbar belongs a newly created gadget. 
+ *         Lazy instantiation is used to render existing gadgets. For these gadgets, false should be passed in.
+ */
+function createGadgetToolbar(tbdivid, isnewadded, removegadgetcallback, addcallback){
+    var _gid_ = tbdivid.substr(0, tbdivid.length-('_tb_'.length));
+
+    var renameWinId = 'gadget_rename_win';
+    var newNameFieldId = 'gadget_rename_textfield';
+    var renameWin = Ext.getCmp(renameWinId);
+    if (renameWin == null) {
+        renameWin = new Ext.Window({
+            title: 'Change gadget name',
+            plain: true,
+            shadow: false,
+            closable: true,
+            closeAction: 'hide',
+            id: renameWinId,
+            x_gid: '',
+            items: [{
+                xtype: 'textfield',
+                hideLabel: true,
+                inputType: 'text',
+                emptyText: 'type new name here',
+                width: '90%',
+                id: newNameFieldId
+            }], buttons: [{
+                text: 'ok',
+                handler: function() {
+                    var newNameField = renameWin.getComponent(newNameFieldId);
+                    if (newNameField != null) {
+                        var newName = newNameField.getValue();
+                        var gid = renameWin.x_gid;
+                        if (gid == null)
+                            alert("Cannot find associated gadget");
+                        var gadget = cgl.shindig.ui.layout.layoutobj.getGadgetById(gid);
+                        if (gadget == null) alert("Cannot get the gadget you are renaming");
+                        else {
+                            gadget.setGadgetName(newName);
+                            cgl.shindig.ui.layout.layoutobj.markDirty();
+                            cgl.shindig.ops.syncLayoutData(false);
+                            var labelBtId = gid + '_label_'
+                            var btlabel = Ext.getCmp(labelBtId);
+                            btlabel.setText(newName);
+                        }
+                    } else {
+                        alert("Cannot get the new name");
+                    }
+                    renameWin.hide();
+                }
+            }, {
+                text: 'cancel',
+                handler: function() {
+                    renameWin.hide();
+                }
+            }]
+        });
+    }
+
+    
+    var gadget = cgl.shindig.ui.layout.layoutobj.getGadgetById(_gid_);
+
+    var gadgetInfoWinId = 'gadget_info_win';
+    var gadgetInfoWin = Ext.getCmp(gadgetInfoWinId);
+    if (gadgetInfoWin == null) {
+        var gadgetinfopanel = new Ext.form.FormPanel({
+            labelWidth: 125,
+            frame: true,
+            title: 'gadget information',
+            bodyStyle: 'padding:5px 5px 0',
+            autoHeight: true,
+            defaults: {
+                width: '80%'
+            },
+            buttons: [{
+                text: 'Save',
+                type: 'submit',
+                handler: function(){
+                    cgl.shindig.ui.layout.layoutobj.markDirty();
+                    gadgetinfopanel.getForm().submit();
+                    cgl.shindig.ops.syncLayoutData(false);
+                }
+            }, {
+                text: 'clear',
+                type: 'reset',
+                handler: function(){
+                    gadgetinfopanel.getForm().reset();
+                }
+            }, {
+                text: 'cancel',
+                handler: function(){
+                    gadgetInfoWin.hide();
+                }
+            }],
+            items: [{
+                xtype: 'field',
+                fieldLabel: 'gadget name',
+                name: 'gadgetname',
+                value: gadget.getGadgetName()
+                },{
+                // xtype: 'field',
+                xtype: 'texthreffield',
+                fieldLabel: 'gadget spec src',
+                name: 'gadgetspecsrc',
+                value: gadget.getGadgetSpecSrc()
+                }
+            ],
+            onSubmit: Ext.emptyFn,
+            submit: function(){
+                var gid = gadgetInfoWin.x_gid;
+                var iframeid = gid + '_frame_';
+
+                // retrieve new data from form
+                var contentobj = gadgetinfopanel.getForm().getValues();
+                var gname = contentobj.gadgetname;
+                var gspecsrc = contentobj.gadgetspecsrc;
+                var grendersrc = contentobj.gadgetrendersrc;
+                gadgetinfopanel.getForm().reset();
+                gadgetInfoWin.hide();
+                
+                var isNameChanged = true, isSpecSrcChanged = true;
+                // change underlying data structure, and sync it
+                var gadget = cgl.shindig.ui.layout.layoutobj.getGadgetById(gid);
+                if (gadget.getGadgetSpecSrc() == gspecsrc) {
+                    isSpecSrcChanged = false;
+                }
+                if (gadget.getGadgetName() == gname) {
+                    isNameChanged = false;
+                }
+                if (isNameChanged) 
+                    gadget.setGadgetName(gname);
+                if (isSpecSrcChanged)
+                    gadget.setGadgetSpecSrc(gspecsrc);
+                if (isNameChanged || isSpecSrcChanged) {
+                    cgl.shindig.ui.layout.layoutobj.markDirty();
+                    cgl.shindig.ops.syncLayoutData(false);
+                }
+
+                // rerender the gadget
+                // * change label
+                if (isNameChanged) {
+                    var labelBtId = gid + '_label_';
+                    var btlabel = Ext.getCmp(labelBtId);
+                    btlabel.setText(gname);
+                }
+                // * refresh iframe
+                if (isSpecSrcChanged) {
+                    // var renderBaseURL = getGadgetRenderBaseURL();
+                    var escapedGadgetsrc = escape(gspecsrc);
+                    var gadgetRenderFullURL = 
+                        cgl.shindig.gadget.rendering.ops.genFullGadgetHomeRenderingURL(escapedGadgetsrc) +
+                        '&' + gadget.getURLEncodedUserPrefs();
+
+                    /*
+                    var gadgetServerURL = getGadgetRenderBaseURL() + "?view=home&url=";
+                    var gadgetRenderFullURL = gadgetServerURL + escape(gspecsrc);
+                    */
+
+                    Ext.getDom(iframeid).src = gadgetRenderFullURL;
+                    getGadgetHomeMetadata(gspecsrc, iframeid);
+                }
+            }
+        });
+        gadgetInfoWin = new Ext.Window({
+            title: 'Gadget Info',
+            plain: true,
+            shadow: false,
+            closable: true,
+            closeAction: 'hide',
+            width: 500,
+            listeners: {
+                beforeshow : function() {
+                    gadgetinfopanel.items.get(0).setValue(gadget.getGadgetName());
+                    gadgetinfopanel.items.get(1).setValue(gadget.getGadgetSpecSrc());
+                }
+            },
+            items: [ gadgetinfopanel ]
+        });
+    }
+
+    var contextMenuGadget = new Ext.menu.Menu({
+        id: '',
+        style: 'overflow: visible; background-image: none;',
+        defaults: {
+            iconCls: 'xx-menu-item-no-icon'
+        },
+        items: [ {
+            text: 'Rename',
+            hideLabel: true,
+            x_gid: _gid_,
+            handler: function(This, state) {
+                renameWin.x_gid = This.x_gid;
+                renameWin.show();
+            }
+        }, {
+            text: 'Gadget Info',
+            hideLabel: true,
+            x_gid: _gid_,
+            handler: function(This, state) {
+                gadgetInfoWin.x_gid = This.x_gid;
+                gadgetInfoWin.show();
+            }
+        } ]
+    });
+    var btname = new Ext.Toolbar.Button({ 
+        xtype: 'tbbutton', 
+        text: cgl.shindig.ui.layout.layoutobj.getGadgetNameByID(_gid_),
+        id: _gid_ + '_label_',
+        menu: contextMenuGadget
+    });
+
+    var btmax = new Ext.Toolbar.Button ({
+        id: _gid_ + '_maxbt_',
+        xtype: 'tbbutton',
+        // text:'M',
+        // overCls:'xx-tool xx-tool-maximize-over',
+        // iconCls: 'x-tool xx-tool-maximize',
+        cls: 'x-btn-icon',
+        tooltip: 'maximize this gadget',
+        handler: function(){
+          maximizeGadget(_gid_);
+
+          // Save the layout data/sync data to server, no error handling
+          lazySyncLayoutData();
+        }
+    });
+
+    var btrefresh = new Ext.Toolbar.Button ({
+        // text: 'R',
+        tooltip: 'reload this gadget',
+        // iconCls: 'x-tool xx-tool-maximize',
+        cls: 'x-btn-icon',
+        handler: function(){
+            refreshGadget(_gid_);
+        }
+    });
+
+
+    var btgoback = new Ext.Toolbar.Button ({
+        cls: 'x-btn-icon',
+        tooltip: 'Go back',
+        handler: function(){
+            function getTop() { return top; }
+            var frame = getTop().document.getElementById(_gid_+'_frame_');
+            frame.contentWindow.history.back();
+            return;
+
+            // TODO: when a gadget is maximized, need more code to handle it
+            var frameid = _gid_+'_frame_';
+            cgl.shindig.gcrpc.checkSetup(frameid);
+            gadgets.rpc.call(frameid, 'goback');
+        }
+    });
+
+    var btgoforward = new Ext.Toolbar.Button ({
+        cls: 'x-btn-icon',
+        tooltip: 'Go forward',
+        handler: function(){
+            // TODO: when a gadget is maximized, need more code to handle it
+            var frameid = _gid_+'_frame_';
+            cgl.shindig.gcrpc.checkSetup(frameid);
+            gadgets.rpc.call(frameid, 'goforward');
+        }
+    });
+
+    var btsetting = new Ext.Toolbar.Button ({
+        // text: 'S',
+        // iconCls: 'x-tool xx-tool-gear',
+        cls: 'x-btn-icon',
+        tooltip: 'set this gadget',
+        handler: function(){
+            getSettingJs(_gid_);
+        }
+    });
+
+    var btmove = new Ext.Toolbar.Button( {
+        xtype: 'tbbutton',
+        text:'move',
+        disabled: true,
+        tooltip: 'move this gadget to another tab',
+        handler: function(){
+            var mw = createGadgetMove2TabWin();
+            mw.show();
+        }
+    });
+
+    var btfold = new Ext.Toolbar.Button( {
+        xtype: 'tbbutton',
+        // text:'F',
+        disabled: false,
+        // iconCls: 'x-tool xx-tool-up',
+        cls: 'x-btn-icon',
+        tooltip: 'Fold/Expand the gadget',
+        handler: function(bt){
+            var ele = Ext.get(_gid_+'_body_');
+            ele.enableDisplayMode();
+            var aniconfig = {
+                duration: 0.5,
+                easing: 'easeOut'
+            };
+            if (ele.isVisible()) {
+                ele.hide(aniconfig);
+                var tmpfunc = function(bt) { uglyAdjustBtIcon(bt, 'down'); }
+                tmpfunc.defer(500, window, [bt]);
+            } else {
+                ele.show(aniconfig);
+                var tmpfunc = function(bt) { uglyAdjustBtIcon(bt, 'up'); }
+                tmpfunc.defer(500, window, [bt]);
+            }
+        }
+    });
+
+    var btclose = new Ext.Toolbar.Button ({
+        xtype: 'tbbutton',
+        // text:'x',
+        // iconCls: 'x-tool xx-tool-close',
+        cls: 'x-btn-icon',
+        tooltip: 'remove this gadget',
+        handler: function(){
+            /** modifying underlying data structure */
+            if (cgl.shindig.ui.layout.dragsourcepos != null) {
+                var source = cgl.shindig.ui.layout.dragsourcepos[_gid_];
+                var _parent_colid_ = source.parent_colid;
+                var gadget_idx = source.gadgetindex;
+                var col_idx = parseInt( _parent_colid_.substr(_parent_colid_.lastIndexOf('_')+1) );
+                cgl.shindig.ui.layout.layoutobj.deleteGadget( cgl.shindig.ui.layout.curactivetabidx, col_idx, gadget_idx);
+                
+                delete source;
+                delete cgl.shindig.ui.layout.dragsourcepos[_gid_];
+            }
+
+            if (cgl.shindig.ui.layout.tbrenderlist != null)
+                delete cgl.shindig.ui.layout.tbrenderlist[tbdivid];
+                
+            removeIFrameCtn(_gid_+"_frame_");
+            /** delete from ui */
+            var extEle = Ext.get(_gid_);
+            extEle.remove();
+
+            if (removegadgetcallback != null)
+                removegadgetcallback(_gid_);
+
+            cgl.shindig.ui.layout.layoutobj.markDirty();
+            cgl.shindig.ops.syncLayoutData(false);
+        }
+    });
+
+    var _tb_;
+    var adjustparams = [[btclose, 'close'], [btmax, 'maximize'],
+        [btsetting, 'gear'], [btrefresh, 'refresh'], [btfold, 'up']];
+    if(isnewadded==false){
+        _tb_ = new Ext.Toolbar({ renderTo: tbdivid});
+        _tb_.add(btname, '->', /*btgoback, btgoforward,*/
+            btrefresh, btsetting, btmax, btmove, btfold, btclose);
+        contextMenuGadget.getEl().applyStyles({overflow: 'visible', 'background-image': 'none'});
+        uglyAdjust(adjustparams);
+    }else{
+        _tb_ = new Ext.Toolbar({ id: tbdivid,
+                items:[btname, '->', /*btgoback, btgoforward,*/
+                btrefresh, btsetting, btmax, btmove, btfold, btclose] });
+        contextMenuGadget.getEl().applyStyles({overflow: 'visible', 'background-image': 'none'});
+        _tb_._tb_add_callback_ = uglyAdjust;
+        _tb_._tb_add_callback_params_ = adjustparams;
+    }
+
+    function uglyAdjustBtIcon (cmp, icon) {
+        var bts = cmp.getEl().dom.getElementsByTagName('button');
+        if (bts != null && bts.length == 1) {
+            var bt = bts[0];
+            if (bt.parentNode.className != null)
+                bt.parentNode.className = bt.parentNode.className + 'x-tool xx-tool-'+icon;
+            else
+                bt.parentNode.className = 'x-tool xx-tool-'+icon;
+        }
+    }
+    function uglyAdjust(params) {
+        for (var i = 0; i < params.length; ++i) {
+            var pair = params[i];
+            uglyAdjustBtIcon(pair[0], pair[1]);
+        }
+        /*
+    uglyAdjustBtIcon(btclose, 'close');
+    uglyAdjustBtIcon(btmax, 'maximize');
+    uglyAdjustBtIcon(btsetting, 'gear');
+    uglyAdjustBtIcon(btrefresh, 'gear');
+    uglyAdjustBtIcon(btfold, 'up');
+    uglyAdjustBtIcon(btrefresh, 'refresh');
+    uglyAdjustBtIcon(btgoback, 'arrow-left');
+    uglyAdjustBtIcon(btgoforward, 'arrow-right');
+    */
+    }
+
+    return _tb_;
+}

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gc-rpc-service.js
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gc-rpc-service.js?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gc-rpc-service.js (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/gc-rpc-service.js Fri Apr  1 00:29:22 2011
@@ -0,0 +1,220 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * Gadget-Container communication services.
+ */
+
+ 
+Ext.namespace("cgl.shindig.gcrpc");
+
+cgl.shindig.gcrpc.init = function () {
+    gadgets.rpc.register("getSecurityToken", function(gadgetId) {
+        var from = this.f;
+        cgl.shindig.gcrpc.checkSetup(from);
+    });
+
+    /** borrowed from http://www.w3schools.com/js/js_cookies.asp */
+    function getCookie(c_name) {
+        if (document.cookie.length>0)
+          {
+          c_start=document.cookie.indexOf(c_name + "=");
+          if (c_start!=-1)
+            {
+            c_start=c_start + c_name.length+1;
+            c_end=document.cookie.indexOf(";",c_start);
+            if (c_end==-1) c_end=document.cookie.length;
+            return unescape(document.cookie.substring(c_start,c_end));
+            }
+          }
+        return "";
+    }
+
+    function parseGadgetId (from) {
+      var gadgetid = from;
+      if (gadgetid.indexOf("_max_iframe_") != -1)
+        gadgetid = gadgetid.substring(0, gadgetid.length-"_max_iframe_".length);
+      else if (gadgetid.indexOf("_frame_") != -1)
+        gadgetid = gadgetid.substring(0, gadgetid.length-"_frame_".length);
+      return gadgetid;
+    }
+
+    /** 
+     * 'this' object when registered service is executed looks like
+     *  { t: token, f: from, s: serviceName, etc }
+     */
+    gadgets.rpc.register("echo", function(msg) {
+        var authToken = this.t;
+        var serviceName = this.s;
+        var from = this.f;
+        var callbackId = this.c;
+        cgl.shindig.gcrpc.checkSetup(from);
+        alert("rpc info:\n  token:" + authToken + "; service:" +
+            serviceName + "; from:" + from + "; callbackId:" + callbackId
+            + "\n" + "A message is received:" + msg);
+        var username = cgl.shindig.ui.layout.layoutobj.username;
+        var sessionid = getCookie("JSESSIONID");
+        return "user: " + username + "\n" +
+            "session id:" + sessionid + "\n" +
+            "message: " + msg;
+    });
+
+	 /**
+	  * Returns username and session id. Note these are local calls that 
+	  * don't leave the browser.
+	  */
+    gadgets.rpc.register("getUserInfo", function() {
+        cgl.shindig.gcrpc.checkSetup(this.f);
+        var userobj = cgl.shindig.ui.layout.userobj;
+        /* {"timezone":"-05:00,1","dobmonth":10,
+            "screenname":"testuser2","email":"zhguo@indiana.edu",
+            "zipcode":"","dobyear":2010,"lastname":"testuser2",
+            "openid":"","language":"EN","firstname":"testuser2",
+            "dobday":4,"password":""}
+        */
+        userobj = JSON.stringify(userobj);
+        userobj = eval('('+userobj+')');
+        userobj.username = userobj.screenname;
+        var sessionid = getCookie("JSESSIONID");
+        userobj.sessionId = sessionid;
+        userobj = JSON.stringify(userobj);
+        return userobj;
+    });
+
+	 /**
+	  * Just returns the user name.
+	  */
+    gadgets.rpc.register("getUserID", function() {
+        cgl.shindig.gcrpc.checkSetup(this.f);
+        var username = cgl.shindig.ui.layout.layoutobj.username;
+        return username;
+    });
+
+	 /**
+	  * This method returns the URL of a GET method implemented by the Gadget Container (see 
+	  * web.xml).  The implementation is CertProtectedUserAdmin.java. 
+	  * 
+	  * This requires a callback to the container. The method getBaseURL() is defined in util.js
+	  */
+    gadgets.rpc.register("getUserProfileCBURL", function() {
+        var baseURL = getBaseURL();
+		  //REVIEW: these string constants should be handled better (maybe namespacing).
+        baseURL += '/cert-protected-users/users/';
+        return baseURL;
+    });
+
+    gadgets.rpc.register("getUserVerifyCBURL", function() {
+        var baseURL = getBaseURL();
+		  //REVIEW: these string constants should be handled better (maybe namespacing).
+        baseURL += '/callbacks/verify';
+        return baseURL;
+    });
+
+	 //REVIEW: Need to explain what this method is used for.
+    gadgets.rpc.register("requestNavigateTo", function(view, opt_params) {
+      cgl.shindig.gcrpc.checkSetup(this.f);
+      var gadgetid = parseGadgetId(this.f);
+
+		//REVIEW: these string constants should be handled better (maybe namespacing).
+		//I realize they are gadget names.
+      if (view == 'canvas')
+        maximizeGadget(gadgetid);
+      else if (view == 'home' || view == 'profile' || view == 'default')
+        restoreGadget(gadgetid)
+      else
+        alert("The view you specified '"+view+"' is not supported!");
+
+		//REVIEW: what happened to the code below?  You don't need to handle
+		//opt_params any more?
+      /*
+        if (opt_params) {
+          var paramStr = gadgets.json.stringify(opt_params);
+          if (paramStr.length > 0) {
+            url += '&appParams=' + encodeURIComponent(paramStr);
+          }
+        }
+
+        if (url && document.location.href.indexOf(url) == -1) {
+          document.location.href = url;
+        }
+      */
+    });
+
+	 //REVIEW: need to explain what this method is used for.
+    gadgets.rpc.register("set_pref", function(editToken, name, value) {
+      cgl.shindig.gcrpc.checkSetup(this.f);
+      var gadgetid = parseGadgetId(this.f);
+      var layoutobj = cgl.shindig.ui.layout.layoutobj;
+      var gadget = layoutobj.getGadgetById(gadgetid);
+      if (gadget == null) {
+        alert("cannot find gadget with id " + gadgetid);
+        return;
+      }
+      for (var i = 1, j = arguments.length; i < j; i += 2) {
+        gadget.setUserPrefValue(arguments[i], arguments[i+1]);
+      }
+      updateUserPrefDiagById(gadgetid);
+      cgl.shindig.ops.syncLayoutData(true, null, null, false);
+    });
+
+	 /**
+	  * This method relays an RPC call to another registered method. 
+	  */
+    gadgets.rpc.register("rpcrelay",
+      function(targetId, targetServiceName, callbackServiceName, args) {
+          cgl.shindig.gcrpc.checkSetup(this.f);
+          cgl.shindig.gcrpc.checkSetup(targetId);
+          var from = this.f;
+          var callback = function (result) {
+            if (arguments.length == 0)
+                gadgets.rpc.call(from, callbackServiceName);
+            else
+                gadgets.rpc.call(from, callbackServiceName, function(){}, result);
+          };
+
+          var rpcarguments = [targetId, targetServiceName, callback];
+          if (arguments.length > 3)
+              for (var i = 3; i < arguments.length; ++i)
+                  rpcarguments.push(arguments[i]);
+          gadgets.rpc.call.apply(gadgets.rpc, rpcarguments);
+    });
+}
+
+/**
+ * Create an array of receivers
+ */
+cgl.shindig.gcrpc.receivers = {};
+
+/**
+ * !!!! execute this function in the beginning of each service implementation
+ * to build communication channel from container to gadget.
+ */
+cgl.shindig.gcrpc.checkSetup = function(gadgetId) {
+    if (cgl.shindig.gcrpc.receivers[gadgetId] == null) {
+        gadgets.rpc.setupReceiver(gadgetId);
+        cgl.shindig.gcrpc.receivers[gadgetId] = true;
+    }
+}
+
+/**
+ * Calls init. Note this is the majority of the code in this page.
+ */
+cgl.shindig.gcrpc.init();

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/heartbeat.js
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/heartbeat.js?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/heartbeat.js (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/heartbeat.js Fri Apr  1 00:29:22 2011
@@ -0,0 +1,62 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+function heartBeatSetUp() {
+    var interval = 1000 * 60;
+    var handle = setInterval("heartBeatAct()", interval);
+}
+
+function heartBeatAct() {
+    Ext.namespace("cgl.shindig.ui.layout.remoteservice");
+
+    if( cgl.shindig.ui.layout.remoteservice.connection == null ){
+        cgl.shindig.ui.layout.remoteservice.connection = new Ext.data.Connection({
+        });
+    }
+
+    cgl.shindig.ui.layout.remoteservice.connection.request({
+        method: 'GET',
+        url: cgl.shindig.ui.layout.remoteservice.heartbeataddress,
+        success: function( response, options ) {
+            try{
+                var resultobj = eval('('+response.responseText+')');
+                // loadFirebugConsole();
+                if( resultobj.error != null ) {
+                    // alert('heartbeat sync failed (2)');
+                } else {
+                }
+            } catch (err) {
+                alert(err);
+            }
+        },
+        failure : function( response, options ) {
+            // alert('heartbeat sync failed');
+        }
+    });
+}
+
+/**
+function heartBeatTearDown() {
+    var interval = 
+    clearInterval("", interval);
+}
+*/

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/languagepicker.js
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/languagepicker.js?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/languagepicker.js (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/languagepicker.js Fri Apr  1 00:29:22 2011
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+var language='\
+EN:English|AB:Abkhazian|AA:Afar|AF:Afrikaans|SQ:Albanian|AM:Amharic|\
+AR:Arabic|HY:Armenian|AS:Assamese|AY:Aymara|AZ:Azerbaijani|BA:Bashkir|\
+EU:Basque|BN:Bengali|DZ:Bhutani|BH:Bihari|BI:Bislama|BR:Breton|\
+BG:Bulgarian|MY:Burmese|BE:Byelorussian|KM:Cambodian|CA:Catalan|\
+ZH_TW:Chinese (traditional)|ZH_CN:Chinese (simplified)|CO:Corsican|\
+HR:Croatian|CS:Czech|DA:Danish|NL:Dutch|EO:Esperanto|ET:Estonian|\
+FO:Faeroese|FJ:Fiji|FI:Finnish|FR:French|FY:Frisian|GD:Gaelic|\
+GL:Galician|KA:Georgian|DE:German|EL:Greek|KL:Greenlandic|GN:Guarani|\
+GU:Gujarati|HA:Hausa|IW:Hebrew|HI:Hindi|HU:Hungarian|IS:Icelandic|\
+IN:Indonesian|IA:Interlingua|IE:Interlingue|IK:Inupiak|GA:Irish|\
+IT:Italian|JA:Japanese|JW:Javanese|KN:Kannada|KS:Kashmiri|KK:Kazakh|\
+RW:Kinyarwanda|KY:Kirghiz|RN:Kirundi|KO:Korean|KU:Kurdish|LO:Laothian|\
+LA:Latin|LV:Latvian|LN:Lingala|LT:Lithuanian|MK:Macedonian|MG:Malagasy|\
+MS:Malay|ML:Malayalam|MT:Maltese|MI:Maori|MR:Marathi|MO:Moldavian|\
+MN:Mongolian|NA:Nauru|NE:Nepali|NO:Norwegian|OC:Occitan|OR:Oriya|\
+OM:Oromo|PS:Pashto|FA:Persian|PL:Polish|PT:Portuguese|PT_BR:Portugues(Brasil|)\
+PA:Punjabi|QU:Quechua|RM:Rhaeto-Romance|RO:Romanian|RU:Russian|SM:Samoan|\
+SG:Sangro|SA:Sanskrit|SR:Serbian|SH:Serbo-Croatian|ST:Sesotho|TN:Setswana|\
+SN:Shona|SD:Sindhi|SI:Singhalese|SS:Siswati|SK:Slovak|SL:Slovenian|SO:Somali|\
+ES:Spanish|SU:Sudanese|SW:Swahili|SV:Swedish|TL:Tagalog|TG:Tajik|TA:Tamil|\
+TT:Tatar|TE:Telugu|TH:Thai|BO:Tibetan|TI:Tigrinya|TO:Tonga|TS:Tsonga|\
+TR:Turkish|TK:Turkmen|TW:Twi|UK:Ukrainian|UR:Urdu|UZ:Uzbek|VI:Vietnamese|\
+VO:Volapuk|CY:Welsh|WO:Wolof|XH:Xhosa|JI:Yiddish|YO:Yoruba|ZU:Zulu';
+
+/** convert the long language string to array. 
+ *  Each element in the returned array is also an array: [code name].
+ */
+function cvtLangString2Arr(langStr){
+  var arr = [];
+  var langLineArray = langStr.split('|');  // Split into lines
+  for (var loop = 0; loop < langLineArray.length; loop++) {
+    lineArray = langLineArray[loop].split(':');
+    langCode  = TrimString(lineArray[0]);
+    langName  = TrimString(lineArray[1]);
+    arr.push([langCode, langName]);
+  }
+  return arr;
+}
+
+function createLangCombo(langCode){
+    var arr = cvtLangString2Arr(language);
+    var langlist = new Ext.data.SimpleStore({
+        data: arr,
+        fields: ['code', 'name'] 
+    });
+
+    var langcombo = new Ext.form.ComboBox({
+        fieldLabel: 'Language',
+        name: 'language',
+        id: 'userinfo_language',
+        hiddenId: 'userinfo_language_hide',
+        hiddenName: 'language',
+        width: 200,
+
+        typeAhead: true,
+        forceSelection: true,
+        editable: false,
+        mode: 'local',
+        triggerAction: 'all',
+        emptyText:'Select a language...',
+        selectOnFocus:true,
+        store: langlist,
+        displayField: 'name', 
+        valueField: 'code' 
+    });
+    if( arguments.length > 0 )
+        langcombo.setValue(langCode);
+    return langcombo;
+}
+