You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by er...@apache.org on 2013/03/25 18:00:19 UTC

svn commit: r1460762 [1/4] - in /rave/trunk/rave-portal-resources/src: main/webapp/static/script/ main/webapp/static/script/core/ main/webapp/static/script/portal/ test/dependencies/ test/javascript/

Author: erinnp
Date: Mon Mar 25 17:00:18 2013
New Revision: 1460762

URL: http://svn.apache.org/r1460762
Log:
Added js file updates


Added:
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_ajax.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_api.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_core.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_widget.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_wookie.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_admin.js
      - copied unchanged from r1460755, rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_admin.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_backbone.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_forms.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_layout.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_models.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_person_profile.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_portal.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_store.js
      - copied unchanged from r1460755, rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_store.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_ui.js
    rave/trunk/rave-portal-resources/src/test/dependencies/
    rave/trunk/rave-portal-resources/src/test/dependencies/underscore.min.js
    rave/trunk/rave-portal-resources/src/test/javascript/rave_api_spec.js
    rave/trunk/rave-portal-resources/src/test/javascript/rave_core_spec.js
    rave/trunk/rave-portal-resources/src/test/javascript/rave_widget_spec.js
Removed:
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_admin.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_api.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_backbone.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_forms.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_layout.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_models.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_opensocial.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_person_profile.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_store.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_ui.js
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_wookie.js
    rave/trunk/rave-portal-resources/src/test/javascript/raveApiSpec.js
    rave/trunk/rave-portal-resources/src/test/javascript/raveFormsSpec.js
    rave/trunk/rave-portal-resources/src/test/javascript/raveOpenSocialSpec.js
    rave/trunk/rave-portal-resources/src/test/javascript/raveProfileSpec.js
    rave/trunk/rave-portal-resources/src/test/javascript/raveSpec.js
    rave/trunk/rave-portal-resources/src/test/javascript/raveStoreSpec.js
    rave/trunk/rave-portal-resources/src/test/javascript/raveWookieSpec.js

Added: rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_ajax.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_ajax.js?rev=1460762&view=auto
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_ajax.js (added)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_ajax.js Mon Mar 25 17:00:18 2013
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+rave = rave || {};
+
+/*
+The rave.ajax function is a simple wrapper for jquery's ajax function.
+If you wish to use a different ajax library, you can overlay this file and
+wrap it to match jquery's ajax api: http://api.jquery.com/jQuery.ajax/
+ */
+rave.ajax = $.ajax;
\ No newline at end of file

Added: rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_api.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_api.js?rev=1460762&view=auto
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_api.js (added)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_api.js Mon Mar 25 17:00:18 2013
@@ -0,0 +1,1088 @@
+/*
+ * 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 rave = rave || {};
+/**
+ * Namespace that provides client access to Rave server APIs.
+ * Note required jquery libraries must be imported by the containing page.
+ */
+rave.api = rave.api || (function () {
+    //stores virtual host context of application execution
+    var context = "";
+
+    function handleError(jqXhr, status, error) {
+        alert(rave.getClientMessage("api.error") + error);
+    }
+
+    var restApi = (function () {
+        //Base path to RPC services
+        var path = "api/rest/";
+
+        function saveWidgetPreferences(args) {
+            var preferencesData = {"preferences": []};
+            for (var prefName in args.userPrefs) {
+                preferencesData.preferences.push({"name": prefName, "value": args.userPrefs[prefName]});
+            }
+
+            rave.ajax({
+                type: 'PUT',
+                url: context + path + "regionWidgets/" + args.regionWidgetId + "/preferences",
+                data: JSON.stringify(preferencesData),
+                contentType: 'application/json',
+                dataType: 'json',
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function saveWidgetPreference(args) {
+            rave.ajax({
+                type: 'PUT',
+                url: context + path + "regionWidgets/" + args.regionWidgetId + "/preferences/" + args.userPref.prefName,
+                data: JSON.stringify({"name": args.userPref.prefName, "value": args.userPref.prefValue}),
+                contentType: 'application/json',
+                dataType: 'json',
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function saveWidgetCollapsedState(args) {
+            rave.ajax({
+                type: 'PUT',
+                url: context + path + "regionWidgets/" + args.regionWidgetId + "/collapsed",
+                data: JSON.stringify(args.collapsed),
+                contentType: 'application/json',
+                dataType: 'json',
+                success: args.successCallback,
+                error: handleError
+            });
+        }
+
+        function deletePage(args) {
+            rave.ajax({
+                type: 'DELETE',
+                url: context + path + "page/" + args.pageId,
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function deleteWidgetRating(args) {
+            rave.ajax({
+                type: 'DELETE',
+                url: context + path + "widgets/" + args.widgetId + "/rating",
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            })
+        }
+
+        function updateWidgetRating(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "widgets/" + args.widgetId + "/rating?score=" + args.score,
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            })
+        }
+
+        function createWidgetComment(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "widgets/" + args.widgetId + "/comments?text=" + escape(args.text),
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            })
+        }
+
+        function deleteWidgetComment(args) {
+            rave.ajax({
+                type: 'DELETE',
+                url: context + path + "widgets/" + args.widgetId + "/comments/" + args.commentId,
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            })
+        }
+
+        function updateWidgetComment(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "widgets/" + args.widgetId + "/comments/" + args.commentId + "?text=" + escape(args.text),
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            })
+        }
+
+        function getUsersForWidget(args) {
+            rave.ajax({
+                type: 'GET',
+                url: context + path + "widgets/" + args.widgetId + "/users",
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback(result);
+                    }
+                },
+                error: handleError
+            })
+        }
+
+        function createWidgetTag(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "widgets/" + args.widgetId + "/tags?tagText=" + escape(args.text),
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback();
+                    }
+                },
+                error: handleError
+            })
+        }
+
+        function getTags(args) {
+            rave.ajax({
+                type: 'GET',
+                url: context + path + "widgets/" + args.widgetId + "/tags",
+                dataType: "json",
+                success: function (data) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback(data);
+                    }
+                }
+            });
+        }
+
+        function getSecurityToken(args) {
+            rave.ajax({
+                type: 'GET',
+                url: context + "api/rest/" + "st?url=" + args.url + "&pageid=" + args.pageid,
+                dataType: "json",
+                success: function (data) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback(data);
+                    }
+                }
+            });
+        }
+
+        return {
+            updateWidgetRating: updateWidgetRating,
+            deleteWidgetRating: deleteWidgetRating,
+            saveWidgetPreferences: saveWidgetPreferences,
+            saveWidgetPreference: saveWidgetPreference,
+            saveWidgetCollapsedState: saveWidgetCollapsedState,
+            createWidgetComment: createWidgetComment,
+            updateWidgetComment: updateWidgetComment,
+            deleteWidgetComment: deleteWidgetComment,
+            deletePage: deletePage,
+            getUsersForWidget: getUsersForWidget,
+            createWidgetTag: createWidgetTag,
+            getTags: getTags
+        };
+    })();
+
+    var rpcApi = (function () {
+        //Base path to RPC services
+        var path = "api/rpc/";
+
+        //This method is implemented by PageApi.java.
+        //TODO: should be deprecated and replaced by moveWidgetToRegion
+        function moveWidgetOnPage(args) {
+            var widgetObjectId = rave.getObjectIdFromDomId(args.widget.id);
+            var toRegionObjectId = rave.getObjectIdFromDomId(args.targetRegion.id);
+            var fromRegionObjectId = rave.getObjectIdFromDomId(args.currentRegion.id);
+            //Note context must be set outside this library.  See page.jsp for example.
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/regionWidget/" + widgetObjectId + "/move",
+                data: {
+                    newPosition: args.targetIndex,
+                    toRegion: toRegionObjectId,
+                    fromRegion: fromRegionObjectId
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function moveWidgetToRegion(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/regionWidget/" + args.regionWidgetId + "/move",
+                data: {
+                    newPosition: args.toIndex,
+                    toRegion: args.toRegionId,
+                    fromRegion: args.fromRegionId
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function addWidgetToPage(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/widget/add",
+                data: {
+                    widgetId: args.widgetId
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    } else {
+                        //TODO: get rid of any dom manipulation here!
+                        //TODO: this is breaking core dependency chain
+                        var widgetTitle = rave.getClientMessage("widget.add_prefix");
+                        var addedWidget = result.result != undefined ? result.result.widgetId : undefined;
+
+                        if (addedWidget != undefined && addedWidget.title != undefined && addedWidget.title.length > 0) {
+                        widgetTitle = addedWidget.title;
+                        }
+                        // if a callback is supplied, invoke it with the regionwidget id
+                        if (args.successCallback && addedWidget != undefined) {
+                            args.successCallback(result.result.id);
+                        }
+                        rave.showInfoMessage(widgetTitle + ' ' + rave.getClientMessage("widget.add_suffix"));
+
+                        // Update Add Widget button to reflect status
+                        var addWidgetButton = "#addWidget_" + args.widgetId;
+                        var addedText = '<i class="icon icon-ok icon-white"></i> ' + $(addWidgetButton).data('success');
+
+                        $(addWidgetButton).removeClass("btn-primary").addClass("btn-success").html(addedText);
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function addWidgetToPageRegion(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/widget/add/region/" + args.regionId,
+                data: {
+                    widgetId: args.widgetId
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    } else {
+                        //TODO: move this logic
+                        var widgetTitle = rave.getClientMessage("widget.add_prefix");
+                        var addedWidget = result.result != undefined ? result.result.widgetId : undefined;
+
+                        if (addedWidget != undefined && addedWidget.title != undefined && addedWidget.title.length > 0) {
+                            widgetTitle = addedWidget.title;
+                        }
+                        // if a callback is supplied, invoke it with the regionwidget id
+                        if (args.successCallback && addedWidget != undefined) {
+                            args.successCallback(result.result.id);
+                        }
+                        rave.showInfoMessage(widgetTitle + ' ' + rave.getClientMessage("widget.add_suffix"));
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function deleteWidgetOnPage(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/regionWidget/" + args.regionWidgetId + "/delete",
+                data: null,
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    } else {
+                        if (_.isFunction(args.successCallback)) {
+                            args.successCallback();
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function addPage(args) {
+
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/add",
+                data: {
+                    pageName: args.pageName,
+                    pageLayoutCode: args.pageLayoutCode
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        // check to see if a duplicate page name error occurred
+                        if (result.errorCode == 'DUPLICATE_ITEM') {
+                            //TODO: git rid of dom manipulation
+                            $("#" + args.errorLabel).html(rave.getClientMessage("page.duplicate_name"));
+                        } else {
+                            handleRpcError(result);
+                        }
+                    } else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        //TODO: what does this do...
+        function getPage(args) {
+            rave.ajax({
+                type: 'GET',
+                url: context + path + "page/get",
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    } else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function movePage(args) {
+            // the moveAfterPageId attribute could be undefined if moving
+            // to the first position. In that case don't send a moveAfterPageId
+            // post parameter
+            var data = {};
+            if (args.moveAfterPageId) {
+                data["moveAfterPageId"] = args.moveAfterPageId;
+            }
+
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/move",
+                data: data,
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    } else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function moveWidgetToPage(args) {
+            var data = {};
+            if (args.toPageId) {
+                data["toPageId"] = args.toPageId;
+                data["regionWidgetId"] = args.regionWidgetId;
+            }
+
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.toPageId + "/moveWidget",
+                data: data,
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    } else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function updatePagePrefs(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/update",
+                data: {
+                    "name": args.title,
+                    "layout": args.layout
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        if (result.errorCode == 'DUPLICATE_ITEM') {
+                            //TODO: git rid of dom manipulation
+                            $("#" + args.errorLabel).html(rave.getClientMessage("page.duplicate_name"));
+                        } else {
+                            handleRpcError(result);
+                        }
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function getPagePrefs(args) {
+            rave.ajax({
+                type: 'GET',
+                url: context + path + "page/get?pageId=" + args.pageId,
+                dataType: 'json',
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback(result);
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        //TODO RAVE-228: Create a more robust error handling system and interrogation of RPC results
+        function handleRpcError(rpcResult) {
+            switch (rpcResult.errorCode) {
+                case "NO_ERROR" :
+                    break;
+                case "INVALID_PARAMS":
+                    alert(rave.getClientMessage("api.rpc.error.invalid_params"));
+                    break;
+                case "INTERNAL_ERROR":
+                    alert(rave.getClientMessage("api.rpc.error.internal"));
+                    break;
+            }
+        }
+
+        function getWidgetMetadata(args) {
+            var url = args.url;
+            var providerType = args.providerType;
+            if (url == null || providerType == null) {
+                alert(rave.getClientMessage("api.widget_metadata.invalid_params"));
+                return;
+            }
+
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "widget/metadata/get",
+                data: {
+                    "url": url,
+                    "type": providerType
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        alert(rave.getClientMessage("api.widget_metadata.parse_error"));
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function getWidgetMetadataGroup(args) {
+            var url = args.url;
+            var providerType = args.providerType;
+            if (url == null || providerType == null) {
+                alert(rave.getClientMessage("api.widget_metadata.invalid_params"));
+                return;
+            }
+
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "widget/metadatagroup/get",
+                data: {
+                    "url": url,
+                    "type": providerType
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        alert(rave.getClientMessage("api.widget_metadata.parse_error"));
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function getAllWidgets(args) {
+            rave.ajax({
+                type: 'GET',
+                url: context + path + "widget/getall",
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function getUsers(args) {
+            var offset = args.offset;
+
+            rave.ajax({
+                type: 'GET',
+                url: context + path + "person/get",
+                data: {"offset": offset},
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function searchUsers(args) {
+            var searchTerm = args.searchTerm;
+            var offset = args.offset;
+            if (searchTerm == null || searchTerm == "") {
+                alert(rave.getClientMessage("api.rpc.empty.search.term"));
+                return;
+            }
+
+            rave.ajax({
+                type: 'GET',
+                url: context + path + "person/search",
+                data: {"searchTerm": searchTerm, "offset": offset},
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function clonePageForUser(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/clone",
+                data: {
+                    "userId": args.userId,
+                    "pageName": args.pageName
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (typeof args.successCallback == 'function') {
+                        args.successCallback(result);
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function addMemberToPage(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/addmember",
+                data: {
+                    "userId": args.userId
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function removeMemberFromPage(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/removemember",
+                data: {
+                    "userId": args.userId
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function updateSharedPageStatus(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/sharestatus",
+                data: {
+                    "shareStatus": args.shareStatus
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function updatePageEditingStatus(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "page/" + args.pageId + "/editstatus",
+                data: {
+                    "userId": args.userId,
+                    "isEditor": args.isEditor
+                },
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function addFriend(args) {
+            var user = encodeURIComponent(encodeURIComponent(args.friendUsername));
+
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "person/" + user + "/addfriend",
+                data: null,
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function removeFriend(args) {
+            var user = encodeURIComponent(encodeURIComponent(args.friendUsername));
+
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "person/" + user + "/removefriend",
+                data: null,
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function getFriends(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "person/getFriends",
+                data: null,
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function acceptFriendRequest(args) {
+            var user = encodeURIComponent(encodeURIComponent(args.friendUsername));
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "person/" + user + "/acceptfriendrequest",
+                data: null,
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        function addWidgetFromMarketplace(args) {
+            rave.ajax({
+                type: 'POST',
+                url: context + path + "marketplace/add",
+                data: {"url": args.url,
+                    providerType: args.providerType},
+                dataType: 'json',
+                success: function (result) {
+                    if (result.error) {
+                        handleRpcError(result);
+                    }
+                    else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                },
+                error: handleError
+            });
+        }
+
+        return {
+            moveWidget: moveWidgetOnPage,
+            moveWidgetToRegion: moveWidgetToRegion,
+            addWidgetToPage: addWidgetToPage,
+            addWidgetToPageRegion: addWidgetToPageRegion,
+            removeWidget: deleteWidgetOnPage,
+            addPage: addPage,
+            getPage: getPage,
+            updatePagePrefs: updatePagePrefs,
+            getPagePrefs: getPagePrefs,
+            movePage: movePage,
+            moveWidgetToPage: moveWidgetToPage,
+            getWidgetMetadata: getWidgetMetadata,
+            getWidgetMetadataGroup: getWidgetMetadataGroup,
+            getUsers: getUsers,
+            searchUsers: searchUsers,
+            clonePageForUser: clonePageForUser,
+            addMemberToPage: addMemberToPage,
+            removeMemberFromPage: removeMemberFromPage,
+            updateSharedPageStatus: updateSharedPageStatus,
+            updatePageEditingStatus: updatePageEditingStatus,
+            addFriend: addFriend,
+            removeFriend: removeFriend,
+            getFriends: getFriends,
+            acceptFriendRequest: acceptFriendRequest,
+            addWidgetFromMarketplace: addWidgetFromMarketplace,
+            getAllWidgets: getAllWidgets
+        };
+
+    })();
+
+    /*
+     *	Handler functions to handle modifications on user events
+     */
+    var handlerApi = (function () {
+
+        //function to handle widget rating changes
+        function widgetRatingHandler(widgetRating) {
+
+            //retrieving the current total likes
+            var likeTotalLabel = document.getElementById("totalLikes-" + widgetRating.widgetId);
+            var likeTotal = likeTotalLabel.getAttribute("data-rave-widget-likes");
+
+            //retrieving the current total dislikes
+            var dislikeTotalLabel = document.getElementById("totalDislikes-" + widgetRating.widgetId);
+            var dislikeTotal = dislikeTotalLabel.getAttribute("data-rave-widget-dislikes");
+
+            //initializing temporary variables
+            var incrementingTotal = -1;
+            var decrementingTotal = -1;
+            var curButton = "";
+            var prevButton = "";
+            var prevRating = -1;
+
+            //check if like rating needs to be updated
+            if (widgetRating.isLike) {
+
+                //set incrementing total to like total
+                incrementingTotal = likeTotal;
+
+                //set the incrementing total label to like total label
+                incrementingTotalLabel = likeTotalLabel;
+
+                //set decrementing total to dislike total
+                decrementingTotal = dislikeTotal;
+
+                //set the decrementing total label to dislike total label
+                decrementingTotalLabel = dislikeTotalLabel;
+
+                //set the current clicked button to like button
+                curButton = widgetRating.widgetLikeButton;
+
+                //set the previous clicked button to dislike button
+                prevButton = widgetRating.widgetDislikeButton;
+
+                //set the previous rating to 0 to check if dislike was clicked earlier
+                prevRating = 0;
+            }
+
+            //check if dislike rating needs to be updated
+            else {
+
+                //set incrementing total to dislike total
+                incrementingTotal = dislikeTotal;
+
+                //set the incrementing total label to dislike total label
+                incrementingTotalLabel = dislikeTotalLabel;
+
+                //set decrementing total to like total
+                decrementingTotal = likeTotal;
+
+                //set the decrementing total label to like total label
+                decrementingTotalLabel = likeTotalLabel;
+
+                //set the current clicked button to dislike button
+                curButton = widgetRating.widgetDislikeButton;
+
+                //set the previous clicked button to like button
+                prevButton = widgetRating.widgetLikeButton;
+
+                //set the previous rating to 10 to check if like was clicked earlier
+                prevRating = 10;
+            }
+
+            //update incrementing total
+            incrementingTotal = parseInt(incrementingTotal) + 1;
+            if (incrementingTotalLabel == likeTotalLabel) {
+                incrementingTotalLabel.setAttribute("data-rave-widget-likes", incrementingTotal);
+                incrementingTotalLabel.innerHTML = incrementingTotal;
+            }
+            else {
+                incrementingTotalLabel.setAttribute("data-rave-widget-dislikes", incrementingTotal);
+                incrementingTotalLabel.innerHTML = incrementingTotal;
+            }
+
+            //get the value of hidden user rating
+            var hiddenButton = document.getElementById("rate-" + widgetRating.widgetId);
+            var userPrevRate = hiddenButton.value;
+
+            //if the other button in this pair was checked then ajdust its total, except in IE where
+            //the button has already toggled BEFORE the 'change' event in which case we have to assume
+            //that the user had a contrary selection prior to the change event
+            if (prevButton.get(0).getAttribute("checked") == "true" || curButton.checked == true) {
+                prevButton.get(0).setAttribute("checked", "false");
+
+                //remove the previous rating made by the user if any by checking change in userRating
+                if (parseInt(userPrevRate) == prevRating) {
+
+                    //update decrementing total
+                    if (parseInt(decrementingTotal) - 1 > -1) {
+                        decrementingTotal = parseInt(decrementingTotal) - 1;
+                        if (decrementingTotalLabel == likeTotalLabel) {
+                            decrementingTotalLabel.setAttribute("data-rave-widget-likes", decrementingTotal);
+                            decrementingTotalLabel.innerHTML = decrementingTotal;
+                        }
+                        else {
+                            decrementingTotalLabel.setAttribute("data-rave-widget-dislikes", decrementingTotal);
+                            decrementingTotalLabel.innerHTML = decrementingTotal;
+                        }
+                    }
+                }
+
+            }
+
+            //flag this element as the currently checked one
+            curButton.setAttribute("checked", "true");
+
+            //set the user rating of the hidden field
+            if (widgetRating.isLike) {
+                hiddenButton.value = "10";
+            }
+            else {
+                hiddenButton.value = "0";
+            }
+        }
+
+        //TODO: git rid of dom manipulation
+        //function to toggle sliding down and up of user profile tabs
+        function userProfileTabHandler(profileTab) {
+            //parsing profile tab id to obtain panel id
+            var panelId = "#" + profileTab.id.substring(0, profileTab.id.indexOf("Tab")) + "Panel";
+            $(panelId).slideToggle("slow");
+        }
+
+        //function to toggle hide and show of tag pages
+        function userProfileTagHandler(profileTag, defaultTagPage) {
+
+            //first close any tag pages if open
+            $(".profile-tag-page").hide();
+
+            //show default tag page is set true
+            if (defaultTagPage != null) {
+                $(defaultTagPage).show();
+            }
+
+            else {
+                //extract the tag page id from profile tag id
+                var tagPageId = "#" + profileTag.id + "Page";
+                //show the requested tag page
+                $(tagPageId).show();
+            }
+        }
+
+        function userProfileEditHandler(isEdit) {
+            //get the edit element
+            var profileInfo = document.getElementById("profileInfo");
+            //extract hidden fields through their class
+            var hiddenFields = "." + profileInfo.value + "-hidden";
+            //extract labels through their class
+            var visibleFields = "." + profileInfo.value + "-visible";
+
+            if (isEdit) {
+                //make hidden fields visible
+                $(hiddenFields).show();
+                //make visible fields invisible
+                $(visibleFields).hide();
+            }
+
+            else {
+                //make hidden fields invisible
+                $(hiddenFields).hide();
+                //make visible fields visible
+                $(visibleFields).show();
+            }
+        }
+
+        return {
+            widgetRatingHandler: widgetRatingHandler,
+            userProfileTabHandler: userProfileTabHandler,
+            userProfileTagHandler: userProfileTagHandler,
+            userProfileEditHandler: userProfileEditHandler
+        };
+
+    })();
+
+    function setContext(ctx) {
+        context = ctx;
+    }
+
+    return {
+        rest: restApi,
+        rpc: rpcApi,
+        handler: handlerApi,
+        setContext: setContext
+    };
+})();
+

Added: rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_core.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_core.js?rev=1460762&view=auto
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_core.js (added)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_core.js Mon Mar 25 17:00:18 2013
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+
+rave = (function () {
+    var INITIALIZED = false,
+    //providers - opensocial, wookie...
+        providers = {},
+    //hash of widgets by regionWidgetId
+        regionWidgets = {},
+    //hash of registered views by name
+        registeredViews = {},
+    //hash of registered views that have been rendered by a generated uid
+        renderedViews = {},
+    //event handlers to fire on rave init
+        initHandlers = [],
+    //oajaxhub to support pubsub. only initialized if needed
+        openAjaxHub;
+
+    var exports = {};
+
+    exports.registerProvider = function (name, provider) {
+        providers[name.toLowerCase()] = provider;
+        if (INITIALIZED) {
+            provider.init();
+        }
+        return provider;
+    }
+
+    exports.getProvider = function (name) {
+        return providers[name.toLowerCase()];
+    }
+
+    //TODO: regionId isn't really needed, but the script text is hard coded and I don't want to mess with it yet
+    exports.registerWidget = function (regionId, definition) {
+        //make regionId optional
+        if (!definition) {
+            definition = regionId;
+        }
+        regionWidgets[definition.regionWidgetId] = definition;
+        if (INITIALIZED) {
+            regionWidgets[definition.regionWidgetId] = new rave.RegionWidget(definition)
+        }
+        return regionWidgets[definition.regionWidgetId];
+    }
+
+    //uregister a regionwidget, identified by a RegionWidget object, a widget definition, or just an id
+    exports.unregisterWidget = function (widget) {
+        var regionWidgetId = widget.regionWidgetId || widget;
+
+        delete regionWidgets[regionWidgetId];
+    }
+
+    //get registered widget by regionWidgetId
+    exports.getWidget = function (regionWidgetId) {
+        return regionWidgets[regionWidgetId];
+    }
+
+    //TODO: add some sort of filtering?
+    exports.getWidgets = function () {
+        return regionWidgets;
+    }
+
+    /*
+     key: view name
+     view: any object that manages and renders a view. At minimum must have render and destroy methods. render should return 'this'
+     TODO: any view that will be used for gadget injection (popups, widget chrome) should also have a function
+     getWidgetSite that returns a dom element where the widget is injected.
+     */
+    exports.registerView = function (key, view) {
+        registeredViews[key.toLowerCase()] = view;
+    }
+
+    exports.getView = function (key) {
+        return registeredViews[key.toLowerCase()];
+    }
+
+    exports.renderView = function (key) {
+        //apply remaining arguments to the view function - you know best!
+        var args = _.toArray(arguments).slice(1);
+
+        var view = rave.getView(key);
+        if (!view) {
+            throw new Error('Attempted to render undefined view: ' + key);
+        }
+        //if registered view is a constructor, create a new instance
+        if (_.isFunction(view)) {
+            view = new view();
+        }
+        view.render.apply(view, args);
+        view._uid = _.uniqueId('rave_view_');
+        renderedViews[view._uid] = view;
+        return view;
+    }
+
+    exports.getRenderedView = function (_uid) {
+        return renderedViews[_uid];
+    }
+
+    exports.destroyView = function (view) {
+        var args = _.toArray(arguments).slice(1);
+
+        //accept view object or view _uid
+        if (_.isString(view)) {
+            view = rave.getRenderedView(view);
+        }
+        delete renderedViews[view._uid];
+        view.destroy(args);
+    }
+
+    exports.getManagedHub = function () {
+        if (!openAjaxHub) {
+            if (_.isUndefined(OpenAjax)) {
+                throw new Error("No implementation of OpenAjax found.  " +
+                    "Please ensure that an implementation has been included in the page.");
+            }
+            openAjaxHub = new OpenAjax.hub.ManagedHub();
+        }
+        return openAjaxHub;
+    }
+
+    /*
+     //TODO: should this be a thing? I think no. what's up css.
+     width, height value in pixels
+     */
+    exports.setDefaultGadgetSize = function (width, height) {
+        _.invoke(providers, 'setDefaultGadgetSize', width, height);
+    }
+
+    exports.setDefaultGadgetView = function (view) {
+        _.invoke(providers, 'setDefaultGadgetView', view);
+    }
+
+    exports.registerOnInitHandler = function (handler) {
+        if (!_.isFunction(handler)) {
+            throw new Error('Init event handler must be a function');
+        }
+        if (INITIALIZED) {
+            return handler();
+        }
+        initHandlers.push(handler);
+    }
+
+    exports.init = function () {
+        INITIALIZED = true;
+        _.invoke(providers, 'init');
+        _.each(regionWidgets, function (definition) {
+            regionWidgets[definition.regionWidgetId] = new rave.RegionWidget(definition)
+        });
+        _.each(initHandlers, function (fn) {
+            fn();
+        });
+    }
+
+    //wrap a safe version of console.log
+    exports.log = (console && console.log) || function () {
+    };
+
+    //reset internal data - used for testing cleanup
+    exports.reset = function () {
+        INITIALIZED = false;
+        providers = {};
+        regionWidgets = {};
+        registeredViews = {};
+        renderedViews = {};
+        initHandlers = [];
+        openAjaxHub;
+    }
+
+    return exports;
+
+})();
\ No newline at end of file

Added: rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js?rev=1460762&view=auto
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js (added)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_opensocial.js Mon Mar 25 17:00:18 2013
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+rave.registerProvider(
+    'opensocial',
+    (function () {
+        var exports = {};
+
+        var container,
+            defaultView = 'default';
+
+        exports.init = function () {
+            var containerConfig = {};
+            containerConfig[osapi.container.ServiceConfig.API_PATH] = "/rpc";
+            containerConfig[osapi.container.ContainerConfig.RENDER_DEBUG] = rave.getJavaScriptDebugMode();
+            container = new osapi.container.Container(containerConfig);
+
+            //rpcRegister();
+            implementViews();
+        }
+
+        function rpcRegister() {
+            container.rpcRegister('set_title', setTitle);
+            container.rpcRegister('requestNavigateTo', requestNavigateTo);
+            container.rpcRegister('set_pref', setPref);
+            container.rpcRegister('hideWidget', hideWidget);
+            container.rpcRegister('showWidget', showWidget);
+        }
+
+        function implementViews() {
+            container.views.createElementForGadget = function (metadata, rel, opt_view, opt_viewTarget, opt_coordinates, parentSite, opt_callback) {
+                if (opt_viewTarget) {
+                    var prefs = (metadata && metadata.views && metadata.views[opt_view])
+                    var view = rave.renderView(opt_viewTarget, prefs);
+                    var el = view.getWidgetSite();
+                    el.setAttribute('data-rave-view', view._uid);
+                    return el;
+                }
+            };
+
+            container.views.createElementForEmbeddedExperience = function (rel, opt_gadgetInfo, opt_viewTarget, opt_coordinates, parentSite, opt_callback) {
+                var widgetUrl = opt_gadgetInfo.url;
+
+                rave.api.rest.getSecurityToken({
+                    "url": widgetUrl,
+                    //TODO: need to remove reference to rave.ui once we understand need for current pageid
+                    //violates core dependency
+                    "pageid": rave.ui.getCurrentPageId(),
+                    "successCallback": renderEE
+                });
+
+                function renderEE(data) {
+                    if (data.error) {
+                        return rave.log(data.error.message)
+                    }
+                    var gadget = {
+                            "widgetUrl": widgetUrl,
+                            "securityToken": data.securityToken,
+                            "metadata": opt_gadgetInfo
+                        },
+                        height = data.metadata ? data.metadata.height : 500,
+                        width = data.metadata ? data.metadata.width : 525;
+
+                    preloadMetadata(gadget);
+
+                    if (opt_viewTarget) {
+                        var view = rave.renderView(opt_viewTarget, {"preferredHeight": height, preferredWidth: width});
+                        var el = view.getWidgetSite();
+                        el.setAttribute('data-rave-view', view._uid);
+                        opt_callback(el);
+                    }
+                }
+            };
+
+            container.views.createElementForUrl = function (rel, opt_viewTarget, opt_coordinates, parentSite, opt_callback) {
+                if (opt_viewTarget) {
+                    var view = rave.renderView(opt_viewTarget);
+                    var el = view.getWidgetSite();
+                    el.setAttribute('data-rave-view', view._uid);
+                    opt_callback(el);
+                }
+            };
+
+            container.views.destroyElement = function (site) {
+                var el = site.el_;
+                container.closeGadget(site);
+                var _uid = el.getAttribute('data-rave-view');
+                rave.destroyView(_uid);
+            };
+        }
+
+        exports.initWidget = function (widget) {
+            widget.error = getMetadataErrors(widget.metadata);
+            if (!widget.error) {
+                preloadMetadata(widget);
+            }
+        }
+
+        /*
+         Opts -
+         full spectrum of allowed render options!
+         */
+        exports.renderWidget = function (widget, el, opts) {
+            opts = opts || {};
+            var site = container.newGadgetSite(el);
+            widget._site = site;
+
+            var renderParams = {};
+            renderParams[osapi.container.RenderParam.VIEW] = opts.view || defaultView;
+            renderParams[osapi.container.RenderParam.ALLOW_DEFAULT_VIEW ] = opts.allowDefaultView;
+            renderParams[osapi.container.RenderParam.DEBUG ] = opts.debug;
+            renderParams[osapi.container.RenderParam.HEIGHT ] = opts.height;
+            renderParams[osapi.container.RenderParam.NO_CACHE ] = opts.noCache;
+            renderParams[osapi.container.RenderParam.TEST_MODE] = opts.testMode;
+            renderParams[osapi.container.RenderParam.WIDTH ] = opts.width;
+            renderParams[osapi.container.RenderParam.USER_PREFS] = getCompleteUserPrefSet(widget.userPrefs, widget.metadata.userPrefs);
+            container.navigateGadget(site, widget.widgetUrl, opts.view_params, renderParams, opts.callback);
+        }
+
+        /**
+         * Combines the default user pref list from the metadata with those set by the user
+         * @param setPrefs preferences already set by the user
+         * @param metadataPrefs list of all available metadata objects
+         */
+        function getCompleteUserPrefSet(setPrefs, metadataPrefs) {
+            var combined = {};
+            _.each(metadataPrefs, function (metaPref) {
+                var userPref = setPrefs[metaPref.name];
+                combined[metaPref.name] = _.isUndefined(userPref) ? metaPref.defaultValue : userPref;
+            });
+            return combined;
+        }
+
+        function preloadMetadata(gadget) {
+            //Put our gadget metadata into the form that the common container is expecting
+            var commonContainerMetadataWrapper = {};
+            commonContainerMetadataWrapper[gadget.widgetUrl] = gadget.metadata;
+
+            //Put our gadget security token data into the form that the common container is expecting
+            var commonContainerTokenData = {};
+            commonContainerTokenData[osapi.container.TokenResponse.TOKEN] = gadget.securityToken;
+            commonContainerTokenData[osapi.container.MetadataResponse.RESPONSE_TIME_MS] = new Date().getTime();
+            var commonContainerTokenWrapper = {};
+            commonContainerTokenWrapper[gadget.widgetUrl] = commonContainerTokenData;
+
+            //Setup the preloadConfig data with all our preload data
+            var preloadConfig = {};
+            preloadConfig[osapi.container.ContainerConfig.PRELOAD_METADATAS] = commonContainerMetadataWrapper;
+            preloadConfig[osapi.container.ContainerConfig.PRELOAD_TOKENS] = commonContainerTokenWrapper;
+            preloadConfig[osapi.container.ContainerConfig.PRELOAD_REF_TIME] = null;
+
+            //Preload our data into the common container
+            container.preloadCaches(preloadConfig);
+        }
+
+        function getMetadataErrors(metadata) {
+            return metadata.error;
+        }
+
+        exports.closeWidget = function (widget) {
+            if (widget._site) {
+                container.closeGadget(widget._site);
+            }
+        }
+
+        exports.setDefaultGadgetSize = function (width, height) {
+            if (_.isNumber(width)) {
+                osapi.container.GadgetSite.DEFAULT_WIDTH_ = width;
+            }
+            if (_.isNumber(height)) {
+                osapi.container.GadgetSite.DEFAULT_HEIGHT_ = height;
+            }
+        }
+
+        exports.setDefaultGadgetView = function (view) {
+            defaultView = view;
+        }
+
+        return exports;
+    })()
+)
\ No newline at end of file

Added: rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_widget.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_widget.js?rev=1460762&view=auto
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_widget.js (added)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_widget.js Mon Mar 25 17:00:18 2013
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+rave = rave || {};
+
+/*
+ Rave RegionWidget Interface
+
+ Dependencies:
+ rave.ui
+ rave.api
+ */
+
+rave.RegionWidget = (function () {
+    /*
+     rave widget constructor
+     */
+    var Widget = function (definition) {
+        var provider = definition.type;
+
+        _.extend(this, definition);
+
+        this._provider = rave.getProvider(provider);
+
+        if(!this._provider) {
+            throw new Error('Cannot render widget '+definition.widgetUrl+ '. ' +
+                'Provider '+provider+' is not registered.');
+        }
+
+        this._provider.initWidget(this);
+    }
+
+    Widget.extend = function (mixin) {
+        _.extend(this.prototype, mixin);
+    }
+
+    /*
+     el: valid dom element to which the widget will be injected
+     OR valid view name that has been registered via rave.registerView
+     opts: rendering options
+     */
+    Widget.prototype.render = function (el, opts) {
+        if (this.error) {
+            this.view = rave.renderView('errorWidget', el, this);
+            return;
+        }
+        if (_.isString(el)) {
+            var view = rave.renderView(el, this);
+            el = view.getWidgetSite();
+            this._view = view;
+        }
+        this._el = el;
+        this._provider.renderWidget(this, el, opts);
+        return this;
+    }
+
+    Widget.prototype.hide = function () {
+        this.collapsed = true;
+
+        rave.api.rest.saveWidgetCollapsedState({
+            regionWidgetId: this.regionWidgetId,
+            collapsed: this.collapsed
+        });
+    }
+
+    Widget.prototype.show = function () {
+        this.collapsed = false;
+
+        rave.api.rest.saveWidgetCollapsedState({
+            regionWidgetId: this.regionWidgetId,
+            collapsed: this.collapsed
+        });
+    }
+
+    Widget.prototype.close = function (opts) {
+        this._provider.closeWidget(this, opts);
+        if (this._view) {
+            rave.destroyView(this._view);
+        }
+
+        rave.api.rpc.removeWidget({
+            regionWidgetId: this.regionWidgetId
+        });
+    }
+
+    Widget.prototype.moveToPage = function (toPageId, cb) {
+        rave.api.rpc.moveWidgetToPage({
+            toPageId: toPageId,
+            regionWidgetId: this.regionWidgetId,
+            successCallback: cb
+        });
+    }
+
+    Widget.prototype.moveToRegion = function (fromRegionId, toRegionId, toIndex) {
+        rave.api.rpc.moveWidgetToRegion({
+            regionWidgetId: this.regionWidgetId,
+            fromRegionId: fromRegionId,
+            toRegionId: toRegionId,
+            toIndex: toIndex
+        });
+    }
+
+    Widget.prototype.savePreferences = function (updatedPrefs) {
+        this.userPrefs = updatedPrefs;
+        rave.api.rest.saveWidgetPreferences({regionWidgetId: this.regionWidgetId, userPrefs: updatedPrefs});
+    }
+
+
+    return Widget;
+
+})();
\ No newline at end of file

Added: rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_wookie.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_wookie.js?rev=1460762&view=auto
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_wookie.js (added)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/core/rave_wookie.js Mon Mar 25 17:00:18 2013
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+rave.registerProvider(
+    'wookie',
+    (function () {
+        var exports = {}
+
+        //set default widget size to the same as opensocial spec
+        var defaultHeight = 200,
+            defaultWidth = 320,
+            defaultView = 'default';
+
+        exports.init = function(){};
+        exports.initWidget = function(widget){}
+        exports.renderWidget = function(widget, el, opts){
+            new OpenAjax.hub.IframeContainer(rave.getManagedHub() , ""+widget.regionWidgetId,
+                {
+                    Container: {
+                        onSecurityAlert: onClientSecurityAlert,
+                        onConnect:       onClientConnect,
+                        onDisconnect:    onClientDisconnect
+                    },
+                    IframeContainer: {
+                        parent:      el,
+                        //TODO: I dropped a bunch of the attrs here - seems like it should all be css
+                        //unless it is being defined by the gadget spec
+                        iframeAttrs: {
+                            height: widget.height || defaultHeight,
+                            width:  widget.width || defaultWidth
+                        },
+                        uri: widget.widgetUrl
+                    }
+                }
+            );
+        }
+
+        function onClientSecurityAlert(source, alertType) {  /* Handle client-side security alerts */  }
+        function onClientConnect(container) {        /* Called when client connects */   }
+        function onClientDisconnect(container) {     /* Called when client disconnects */ }
+
+        exports.closeWidget = function(widget){
+            //TODO...
+        }
+
+        exports.setDefaultGadgetSize = function(width, height){
+            if(_.isNumber(width)){
+                defaultWidth = width;
+            }
+            if(_.isNumber(height)){
+                defaultHeight = height;
+            }
+        }
+
+        exports.setDefaultGadgetView = function(view){
+            defaultView = view;
+        }
+
+        return exports;
+    })()
+)
\ No newline at end of file

Added: rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_backbone.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_backbone.js?rev=1460762&view=auto
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_backbone.js (added)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_backbone.js Mon Mar 25 17:00:18 2013
@@ -0,0 +1,77 @@
+/*
+ * 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 rave = rave || {};
+
+/*
+Extend backbone's standard model and collection with some
+ */
+rave.Model = Backbone.Model.extend({
+    get: function(attr){
+        //tweak model get so that array / object members are passed by value instead of reference
+        //needed for managing deep objects
+        return _.clone(this.attributes[attr]);
+    },
+
+    /*
+    Overridable function that models can implement for serializing themselves for view rendering,
+    since often a handlebars template needs explicit keys or booleans that don't make sense
+    in a normal json representation of the model. By default will just return toJSON().
+     */
+    toViewModel: function () {
+        return this.toJSON();
+    }
+});
+
+rave.Collection = Backbone.Collection.extend({
+    toViewModel: function () {
+        return this.map(function (model) {
+            return model.toViewModel();
+        });
+    }
+})
+
+
+/*
+ rave.View is an extension of Backbone's view with some scaffolding put in place. The expectation is that a view
+ will be declared with a hash of models (models or collections) that will be merged and fed to the view at render
+ time. By default on any change to the models the view will be re-rendered. Also provides an implementation of
+ render that probably will not need to be overrridden.
+ */
+rave.View = Backbone.View.extend({
+    initialize: function () {
+        var self = this;
+        _.bindAll(this);
+
+        _.each(this.models, function (model) {
+            model.on('change', self.render);
+            model.on('reset', self.render);
+        });
+    },
+    render: function () {
+        var template = this.template;
+
+        var viewData = {};
+        _.each(this.models, function (model, key) {
+            viewData[key] = model.toViewModel();
+        });
+
+        this.$el.html(template(viewData));
+        return this;
+    }
+});
\ No newline at end of file

Added: rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_forms.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_forms.js?rev=1460762&view=auto
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_forms.js (added)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/portal/rave_forms.js Mon Mar 25 17:00:18 2013
@@ -0,0 +1,100 @@
+/*
+ * 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 rave = rave || {};
+rave.forms = rave.forms || (function() {
+
+    function validateNewAccountForm() {
+        $("#newAccountForm").validate({
+            rules: {
+                username : {
+                    required: true,
+                    minlength: 2
+                },
+                password : {
+                    required: true,
+                    minlength: 4
+                },
+                confirmPassword : {
+                    required: true,
+                    minlength: 4,
+                    equalTo: "#passwordField"
+                },
+                email : {
+                    required: true,
+                    email: true
+                }
+            },
+            messages: {
+                confirmPassword: {
+                    equalTo: rave.getClientMessage("form.password.invalid_match")
+                }
+            }
+        });
+    }
+
+    function validateUserProfileForm() {
+        $("#userProfileForm").validate({
+            rules: {
+                password : {
+                    required: true,
+                    minlength: 4
+                },
+                passwordConfirm : {
+                    required: true,
+                    minlength: 4,
+                    equalTo: "#passwordField"
+                }
+            },
+            messages: {
+                passwordConfirm: {
+                    equalTo: rave.getClientMessage("form.password.invalid_match")
+                }
+            }
+        });
+    }
+    
+    function validateEditAccountForm() {
+        $("#editAccountForm").validate({
+            rules: {
+            	 email : {
+                     required: true,
+                     email: true
+                 }
+            }            
+        });
+    }
+    
+    function validatePageForm() {
+        $("#pageForm").validate({
+            rules: {
+                tab_title : {
+                    required: true
+                }
+            }
+        });
+    }
+
+    return {
+        validateNewAccountForm : validateNewAccountForm,
+	    validateUserProfileForm: validateUserProfileForm,
+	    validateEditAccountForm: validateEditAccountForm,
+        validatePageForm: validatePageForm
+    };
+})();