You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by at...@apache.org on 2007/03/27 01:55:41 UTC

svn commit: r522665 [25/29] - in /portals/jetspeed-2/branches/J2-M2-REDUX: ./ components/ components/jetspeed-cm/ components/jetspeed-cm/src/test/java/org/apache/jetspeed/cache/general/ components/jetspeed-cm/src/test/resources/ components/jetspeed-cm/...

Added: portals/jetspeed-2/branches/J2-M2-REDUX/jetspeed-portal-resources/src/main/resources/webapp/javascript/jetspeed/desktop/core.js
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/J2-M2-REDUX/jetspeed-portal-resources/src/main/resources/webapp/javascript/jetspeed/desktop/core.js?view=auto&rev=522665
==============================================================================
--- portals/jetspeed-2/branches/J2-M2-REDUX/jetspeed-portal-resources/src/main/resources/webapp/javascript/jetspeed/desktop/core.js (added)
+++ portals/jetspeed-2/branches/J2-M2-REDUX/jetspeed-portal-resources/src/main/resources/webapp/javascript/jetspeed/desktop/core.js Mon Mar 26 16:53:34 2007
@@ -0,0 +1,4633 @@
+/*
+ * 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.
+ *
+ * author: Steve Milek
+ * author: David Sean Taylor
+ */
+
+/**
+ * jetspeed desktop core javascript objects and types
+ *
+ * 2007-02-20: this file desperately needs to be broken up once deployment support
+ *             for javascript compression and aggregation is implemented
+ */
+
+dojo.provide("jetspeed.desktop.core");
+
+dojo.require("dojo.lang.*");
+dojo.require("dojo.event.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.uri.Uri");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.collections.ArrayList");
+dojo.require("dojo.collections.Set");
+dojo.require("jetspeed.common");
+
+
+// ... jetspeed base objects
+if ( ! window.jetspeed )
+    jetspeed = {} ;
+if ( ! jetspeed.om )
+    jetspeed.om = {} ;
+if ( ! jetspeed.ui )
+    jetspeed.ui = {} ;
+if ( ! jetspeed.ui.widget )
+    jetspeed.ui.widget = {} ;
+
+
+// ... jetspeed.id
+jetspeed.id =
+{
+    PAGE: "jetspeedPage",
+    DESKTOP_CELL: "jetspeedDesktopCell",
+    DESKTOP: "jetspeedDesktop",
+    COLUMNS: "jetspeedColumns",
+    PAGE_CONTROLS: "jetspeedPageControls",
+
+    TASKBAR: "jetspeedTaskbar",
+    SELECTOR: "jetspeedSelector",
+    
+    PORTLET_STYLE_CLASS: "portlet",
+    PORTLET_WINDOW_STYLE_CLASS: "dojoFloatingPane",
+    PORTLET_WINDOW_GHOST_STYLE_CLASS: "ghostPane",
+    PORTLET_WINDOW_ID_PREFIX: "portletWindow_",
+
+    PORTLET_PROP_WIDGET_ID: "widgetId",
+    PORTLET_PROP_CONTENT_RETRIEVER: "contentRetriever",
+    PORTLET_PROP_DESKTOP_EXTENDED: "jsdesktop",
+    PORTLET_PROP_WINDOW_POSITION_STATIC: "windowPositionStatic",
+    PORTLET_PROP_WINDOW_HEIGHT_TO_FIT: "windowHeightToFit",
+    PORTLET_PROP_WINDOW_DECORATION: "windowDecoration",
+    PORTLET_PROP_WINDOW_TITLE: "title",
+    PORTLET_PROP_WINDOW_ICON: "windowIcon",
+    PORTLET_PROP_WIDTH: "width",
+    PORTLET_PROP_HEIGHT: "height",
+    PORTLET_PROP_LEFT: "left",
+    PORTLET_PROP_TOP: "top",
+    PORTLET_PROP_COLUMN: "column",
+    PORTLET_PROP_ROW: "row",
+    PORTLET_PROP_EXCLUDE_PCONTENT: "excludePContent",
+    PORTLET_PROP_WINDOW_STATE: "windowState",
+
+    PORTLET_PROP_DESKTOP_EXTENDED_STATICPOS: "staticpos",
+    PORTLET_PROP_DESKTOP_EXTENDED_FITHEIGHT: "fitheight",
+    PORTLET_PROP_DESKTOP_EXTENDED_PROP_SEPARATOR: "=",
+    PORTLET_PROP_DESKTOP_EXTENDED_PAIR_SEPARATOR: ";",
+
+    // these constants for action names are defined because they have special meaning to desktop (ie. this is not a list of all supported actions)
+    ACTION_NAME_MENU: "menu",
+    ACTION_NAME_MINIMIZE: "minimized",
+    ACTION_NAME_MAXIMIZE: "maximized",
+    ACTION_NAME_RESTORE: "normal",
+    ACTION_NAME_PRINT: "print",
+    ACTION_NAME_EDIT: "edit",
+    ACTION_NAME_VIEW: "view",
+    ACTION_NAME_HELP: "help",
+    ACTION_NAME_ADDPORTLET: "addportlet",
+    ACTION_NAME_REMOVEPORTLET: "removeportlet",
+
+    ACTION_NAME_DESKTOP_TILE: "tile",
+    ACTION_NAME_DESKTOP_UNTILE: "untile",
+    ACTION_NAME_DESKTOP_HEIGHT_EXPAND: "heightexpand",
+    ACTION_NAME_DESKTOP_HEIGHT_NORMAL: "heightnormal",
+
+    PORTLET_ACTION_TYPE_MODE: "mode",
+    PORTLET_ACTION_TYPE_STATE: "state",
+
+    MENU_WIDGET_ID_PREFIX: "jetspeed-menu-",
+
+    PAGE_EDITOR_WIDGET_ID: "jetspeed-page-editor",
+    PAGE_EDITOR_INITIATE_PARAMETER: "editPage",
+    PORTAL_ORIGINATE_PARAMETER: "portal",
+
+    DEBUG_WINDOW_TAG: "js-dojo-debug"
+};
+
+// ... jetspeed desktop preferences - defaults
+jetspeed.prefs = 
+{
+    windowTiling: true,                 // false indicates no-columns, free-floating windows
+    windowHeightExpand: false,          // only meaningful when windowTiling == true
+    
+    windowWidth: null,                  // last-ditch defaults for these defined in initializeDesktop
+    windowHeight: null,
+
+    layoutName: null,                   // do not access directly - use getLayoutName()
+    layoutRootUrl: null,                // do not access directly - use getLayoutRootUrl()
+    getLayoutName: function()
+    {
+        if ( jetspeed.prefs.layoutName == null && djConfig.jetspeed != null )
+            jetspeed.prefs.layoutName = djConfig.jetspeed.layoutName;
+        return jetspeed.prefs.layoutName;
+    },
+    getLayoutRootUrl: function()
+    {
+        if ( jetspeed.prefs.layoutRootUrl == null && djConfig.jetspeed != null )
+            jetspeed.prefs.layoutRootUrl = jetspeed.url.basePortalDesktopUrl() + djConfig.jetspeed.layoutDecorationPath;
+        return jetspeed.prefs.layoutRootUrl;
+    },
+    getPortletDecorationsRootUrl: function()
+    {
+        if ( jetspeed.prefs.portletDecorationsRootUrl == null && djConfig.jetspeed != null )
+            jetspeed.prefs.portletDecorationsRootUrl = jetspeed.url.basePortalDesktopUrl() + djConfig.jetspeed.portletDecorationsPath;
+        return jetspeed.prefs.portletDecorationsRootUrl;
+    },
+
+    portletSelectorWindowTitle: "Portlet Selector",
+    portletSelectorWindowIcon: "text-x-script.png",
+    portletSelectorBounds: { x: 20, y: 20, width: 400, height: 600 },
+
+    windowActionButtonOrder: [ jetspeed.id.ACTION_NAME_MENU, "edit", "view", "help", jetspeed.id.ACTION_NAME_MINIMIZE, jetspeed.id.ACTION_NAME_RESTORE, jetspeed.id.ACTION_NAME_MAXIMIZE ],
+    windowActionNotPortlet: [ jetspeed.id.ACTION_NAME_MENU, jetspeed.id.ACTION_NAME_MINIMIZE, jetspeed.id.ACTION_NAME_RESTORE, jetspeed.id.ACTION_NAME_MAXIMIZE ],
+    windowActionButtonMax: 5,
+    windowActionButtonHide: false,
+    windowActionButtonTooltip: true,
+    windowActionMenuOrder: [ jetspeed.id.ACTION_NAME_DESKTOP_HEIGHT_EXPAND, jetspeed.id.ACTION_NAME_DESKTOP_HEIGHT_NORMAL, jetspeed.id.ACTION_NAME_DESKTOP_TILE, jetspeed.id.ACTION_NAME_DESKTOP_UNTILE ],
+    
+    windowIconEnabled: true,
+    windowIconPath: "/images/portlets/small/",
+
+    windowDecoration: "tigris",
+
+    pageActionButtonTooltip: true,
+
+    getPortletDecorationBaseUrl: function( portletDecorationName )
+    {
+        return jetspeed.prefs.getPortletDecorationsRootUrl() + "/" + portletDecorationName;
+    },
+
+    getPortletDecorationConfig: function( portletDecorationName )
+    {
+        if ( jetspeed.prefs.portletDecorationsConfig == null || portletDecorationName == null )
+            return null;
+        return jetspeed.prefs.portletDecorationsConfig[ portletDecorationName ];
+    }
+};
+
+// ... jetspeed debug options
+jetspeed.debug =
+{
+    pageLoad: true,
+    retrievePsml: false,
+    setPortletContent: false,
+    doRenderDoAction: false,
+    postParseAnnotateHtml: false,
+    confirmOnSubmit: false,
+    createWindow: false,
+    initializeWindowState: false,
+    submitChangedWindowState: false,
+
+    windowDecorationRandom: false,
+
+    debugContainerId: ( djConfig.debugContainerId ? djConfig.debugContainerId : dojo.hostenv.defaultDebugContainerId )
+};
+jetspeed.debugInPortletWindow = true;                             // dojo debug in portlet window (dojo isDebug must be true)
+//jetspeed.debugPortletEntityIdFilter = [ "dp-7", "dp-3" ];       // load listed portlets only
+//jetspeed.debugPortletEntityIdFilter = [];                       // disable all portlets
+//jetspeed.debugContentDumpIds = [ ".*" ];                        // dump all responses
+//jetspeed.debugContentDumpIds = [ "getmenus", "getmenu-.*" ];    // dump getmenus response and all getmenu responses
+//jetspeed.debugContentDumpIds = [ "page-.*" ];                   // dump page psml response
+//jetspeed.debugContentDumpIds = [ "js-cp-selector.2" ];          // dump portlet selector content
+//jetspeed.debugContentDumpIds = [ "moveabs-layout" ];            // dump move layout response
+
+// ... load page /portlets
+jetspeed.page = null ;
+jetspeed.initializeDesktop = function()
+{
+    jetspeed.url.pathInitialize();
+    jetspeed.browser_IE = dojo.render.html.ie;
+    jetspeed.browser_IEpre7 = ( dojo.render.html.ie50 || dojo.render.html.ie55 || dojo.render.html.ie60 );
+    if ( djConfig.jetspeed != null )
+    {
+        for ( var prefKey in djConfig.jetspeed )
+        {
+            var prefOverrideVal = djConfig.jetspeed[ prefKey ];
+            if ( prefOverrideVal != null )
+            {
+                if ( jetspeed.debug[ prefKey ] != null )
+                    jetspeed.debug[ prefKey ] = prefOverrideVal;
+                else
+                    jetspeed.prefs[ prefKey ] = prefOverrideVal;
+            }
+        }
+        if ( jetspeed.prefs.windowWidth == null || isNaN( jetspeed.prefs.windowWidth ) )
+            jetspeed.prefs.windowWidth = "280";
+        if ( jetspeed.prefs.windowHeight == null || isNaN( jetspeed.prefs.windowHeight ) )
+            jetspeed.prefs.windowHeight = "200";
+        
+        var windowActionDesktop = {};
+        windowActionDesktop[ jetspeed.id.ACTION_NAME_DESKTOP_HEIGHT_EXPAND ] = true;
+        windowActionDesktop[ jetspeed.id.ACTION_NAME_DESKTOP_HEIGHT_NORMAL ] = true;
+        windowActionDesktop[ jetspeed.id.ACTION_NAME_DESKTOP_TILE ] = true;
+        windowActionDesktop[ jetspeed.id.ACTION_NAME_DESKTOP_UNTILE ] = true;
+        jetspeed.prefs.windowActionDesktop = windowActionDesktop;
+    }
+    dojo.html.insertCssFile( jetspeed.ui.getDefaultFloatingPaneTemplateCss(), document, true );
+
+    if ( jetspeed.prefs.portletDecorationsAllowed == null || jetspeed.prefs.portletDecorationsAllowed.length == 0 )
+    {
+        if ( jetspeed.prefs.windowDecoration != null )
+            jetspeed.prefs.portletDecorationsAllowed = [ jetspeed.prefs.windowDecoration ];
+    }
+    else if ( jetspeed.prefs.windowDecoration == null )
+    {
+        jetspeed.prefs.windowDecoration = jetspeed.prefs.portletDecorationsAllowed[0];
+    }
+    if ( jetspeed.prefs.windowDecoration == null || jetspeed.prefs.portletDecorationsAllowed == null )
+    {
+        dojo.raise( "Cannot load page because there are no defined jetspeed portlet decorations" );
+        return;
+    }
+
+    if ( jetspeed.prefs.windowActionNoImage != null )
+    {
+        var noImageMap = {};
+        for ( var i = 0 ; i < jetspeed.prefs.windowActionNoImage.length; i++ )
+        {
+            noImageMap[ jetspeed.prefs.windowActionNoImage[ i ] ] = true;
+        }
+        jetspeed.prefs.windowActionNoImage = noImageMap;
+    }
+
+    var docUrlObj = jetspeed.url.parse( document.location.href );
+    var printModeOnly = jetspeed.url.getQueryParameter( docUrlObj, "jsprintmode" ) == "true";
+    if ( printModeOnly )
+    {
+        printModeOnly = {};
+        printModeOnly.action = jetspeed.url.getQueryParameter( docUrlObj, "jsaction" );
+        printModeOnly.entity = jetspeed.url.getQueryParameter( docUrlObj, "jsentity" );
+        printModeOnly.layout = jetspeed.url.getQueryParameter( docUrlObj, "jslayoutid" );
+        jetspeed.prefs.printModeOnly = printModeOnly;
+        jetspeed.prefs.windowTiling = true;
+        jetspeed.prefs.windowHeightExpand = true;
+    }
+
+    jetspeed.prefs.portletDecorationsConfig = {};
+    for ( var i = 0 ; i < jetspeed.prefs.portletDecorationsAllowed.length ; i++ )
+    {
+        jetspeed.loadPortletDecorationConfig( jetspeed.prefs.portletDecorationsAllowed[ i ] );
+    }
+    
+    jetspeed.debugWindowLoad();
+
+    if ( jetspeed.prefs.printModeOnly != null )
+    {
+        for ( var portletDecorationName in jetspeed.prefs.portletDecorationsConfig )
+        {
+            var pdConfig = jetspeed.prefs.portletDecorationsConfig[ portletDecorationName ];
+            if ( pdConfig != null )
+            {
+                pdConfig.windowActionButtonOrder = null;
+                pdConfig.windowActionMenuOrder = null;
+                pdConfig.windowDisableResize = true;
+                pdConfig.windowDisableMove = true;
+            }
+        }
+    }
+
+    jetspeed.loadPage();
+};
+jetspeed.loadPage = function()
+{
+    jetspeed.page = new jetspeed.om.Page();
+    jetspeed.page.retrievePsml();
+};
+jetspeed.updatePage = function()
+{
+    var previousPage = jetspeed.page;
+    if ( previousPage != null )
+    {
+        jetspeed.page = new jetspeed.om.Page();
+        jetspeed.page.retrievePsml( jetspeed.om.PageContentListenerUpdate( previousPage ) );
+    }
+};
+
+jetspeed.debugWindowLoad = function()
+{
+    if ( djConfig.isDebug && jetspeed.debugInPortletWindow && dojo.byId( jetspeed.debug.debugContainerId ) == null )
+    {
+        var debugWindowState = jetspeed.debugWindowReadCookie( true );
+        var windowParams = {};
+        var debugWindowWidgetId = jetspeed.id.PORTLET_WINDOW_ID_PREFIX + jetspeed.id.DEBUG_WINDOW_TAG;
+        windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_POSITION_STATIC ] = false;
+        windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_HEIGHT_TO_FIT ] = false;
+        windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_DECORATION ] = jetspeed.prefs.windowDecoration;
+        windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_TITLE ] = "Dojo Debug";
+        windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_ICON ] = "text-x-script.png";
+        windowParams[ jetspeed.id.PORTLET_PROP_WIDGET_ID ] = debugWindowWidgetId;
+        windowParams[ jetspeed.id.PORTLET_PROP_WIDTH ] = debugWindowState.width;
+        windowParams[ jetspeed.id.PORTLET_PROP_HEIGHT ] = debugWindowState.height;
+        windowParams[ jetspeed.id.PORTLET_PROP_LEFT ] = debugWindowState.left;
+        windowParams[ jetspeed.id.PORTLET_PROP_TOP ] = debugWindowState.top;
+        windowParams[ jetspeed.id.PORTLET_PROP_EXCLUDE_PCONTENT ] = false;
+        windowParams[ jetspeed.id.PORTLET_PROP_CONTENT_RETRIEVER ] = new jetspeed.om.DojoDebugContentRetriever();
+        windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_STATE ] = debugWindowState.windowState;
+        var pwWidgetParams = jetspeed.widget.PortletWindow.prototype.staticDefineAsAltInitParameters( null, windowParams );
+        jetspeed.ui.createPortletWindow( pwWidgetParams );
+        pwWidgetParams.retrieveContent( null, null );
+        var debugWindowWidget = dojo.widget.byId( debugWindowWidgetId );
+        var debugContainer = dojo.byId( jetspeed.debug.debugContainerId );
+
+        dojo.event.connect( "after", dojo.hostenv, "println", debugWindowWidget, "contentChanged" );
+    
+        dojo.event.connect( debugWindowWidget, "windowActionButtonSync", jetspeed, "debugWindowSave" );
+        dojo.event.connect( debugWindowWidget, "endSizing", jetspeed, "debugWindowSave" );
+        dojo.event.connect( debugWindowWidget, "endDragging", jetspeed, "debugWindowSave" );
+    }
+};
+jetspeed.debugWindowReadCookie = function( useDefaults )
+{
+    var debugState = {};
+    if ( useDefaults )
+        debugState = { width: "400", height: "400", left: "320", top: "0", windowState: jetspeed.id.ACTION_NAME_MINIMIZE };
+    var stateCookieVal = dojo.io.cookie.getCookie( jetspeed.id.DEBUG_WINDOW_TAG );
+    if ( stateCookieVal != null && stateCookieVal.length > 0 )
+    {
+        var debugStateRaw = stateCookieVal.split( "|" );
+        if ( debugStateRaw && debugStateRaw.length >= 4 )
+        {
+            debugState.width = debugStateRaw[0]; debugState.height = debugStateRaw[1]; debugState.top = debugStateRaw[2]; debugState.left = debugStateRaw[3];
+            if ( debugStateRaw.length > 4 && debugStateRaw[4] != null && debugStateRaw[4].length > 0 )
+                debugState.windowState=debugStateRaw[4];
+        }
+    }
+    return debugState;
+};
+jetspeed.debugWindowRestore = function()
+{
+    var debugWindowWidgetId = jetspeed.id.PORTLET_WINDOW_ID_PREFIX + jetspeed.id.DEBUG_WINDOW_TAG;
+    var debugWindowWidget = dojo.widget.byId( debugWindowWidgetId );
+    if ( ! debugWindowWidget ) return;
+    debugWindowWidget.restoreWindow();
+};
+jetspeed.debugWindow = function()
+{
+    var debugWindowWidgetId = jetspeed.id.PORTLET_WINDOW_ID_PREFIX + jetspeed.id.DEBUG_WINDOW_TAG;
+    return dojo.widget.byId( debugWindowWidgetId );
+};
+jetspeed.debugWindowSave = function()
+{
+    var debugWindowWidgetId = jetspeed.id.PORTLET_WINDOW_ID_PREFIX + jetspeed.id.DEBUG_WINDOW_TAG;
+    var debugWindowWidget = dojo.widget.byId( debugWindowWidgetId );
+    if ( ! debugWindowWidget ) return null;
+    if ( ! debugWindowWidget.windowPositionStatic )
+    {
+        var currentState = debugWindowWidget.getCurrentWindowStateForPersistence( false );
+        var cWidth = currentState.width; var cHeight = currentState.height; var cTop = currentState.top; var cLeft = currentState.left;
+        if ( debugWindowWidget.windowState == jetspeed.id.ACTION_NAME_MINIMIZE )
+        {
+            var lastPositionInfo = debugWindowWidget.getLastPositionInfo();
+            if ( lastPositionInfo != null )
+            {
+                if ( lastPositionInfo.height != null && lastPositionInfo.height > 0 )
+                    cHeight = lastPositionInfo.height;
+            }
+            else
+            {
+                var debugWindowState = jetspeed.debugWindowReadCookie( false );
+                if ( debugWindowState.height != null && debugWindowState.height > 0 )
+                    cHeight = debugWindowState.height;
+            }
+        }
+
+        var stateCookieVal = cWidth + "|" + cHeight + "|" + cTop + "|" + cLeft + "|" + debugWindowWidget.windowState;
+        dojo.io.cookie.setCookie( jetspeed.id.DEBUG_WINDOW_TAG, stateCookieVal, 30, "/" );
+    }
+};
+
+// ... jetspeed.doRender
+jetspeed.doRender = function( bindArgs, portletEntityId )
+{
+    if ( ! bindArgs )
+    {
+        bindArgs = {};
+    }
+    else if ( ( typeof bindArgs == "string" || bindArgs instanceof String ) )
+    {
+        bindArgs = { url: bindArgs };
+    }
+    var targetPortlet = jetspeed.page.getPortlet( portletEntityId );
+    if ( targetPortlet )
+    {
+        if ( jetspeed.debug.doRenderDoAction )
+            dojo.debug( "doRender [" + portletEntityId + "] url: " + bindArgs.url );
+        targetPortlet.retrieveContent( null, bindArgs );
+    }
+};
+
+// ... jetspeed.doRenderAll
+jetspeed.doRenderAll = function( url, windowArray, isPageLoad )
+{
+    var debugMsg = jetspeed.debug.doRenderDoAction;
+    var debugPageLoad = jetspeed.debug.pageLoad && isPageLoad;
+    if ( ! windowArray )
+        windowArray = jetspeed.page.getPortletArray();
+    var renderMsg = "";
+    var suppressGetActions = true;
+    var jsPageUrl = null ;
+    if ( isPageLoad )
+    {
+        jsPageUrl = jetspeed.url.parse( jetspeed.page.getPageUrl() );
+    }
+    for ( var i = 0; i < windowArray.length; i++ )
+    {
+        var renderObj = windowArray[i];
+        if ( (debugMsg || debugPageLoad) )
+        {
+            if ( i > 0 ) renderMsg = renderMsg + ", ";
+            var widgetId = null;
+            if ( renderObj.getProperty != null )
+                widgetId = renderObj.getProperty( jetspeed.id.PORTLET_PROP_WIDGET_ID );
+            if ( ! widgetId )
+                widgetId = renderObj.widgetId;
+            if ( ! widgetId )
+                widgetId = renderObj.toString();
+            if ( renderObj.entityId )
+            {
+                renderMsg = renderMsg + renderObj.entityId + "(" + widgetId + ")";
+                if ( debugPageLoad && renderObj.getProperty( jetspeed.id.PORTLET_PROP_WINDOW_TITLE ) )
+                    renderMsg = renderMsg + " " + renderObj.getProperty( jetspeed.id.PORTLET_PROP_WINDOW_TITLE );
+            }
+            else
+            {
+                renderMsg = renderMsg + widgetId;
+            }
+        }
+        renderObj.retrieveContent( null, { url: url, jsPageUrl: jsPageUrl }, suppressGetActions );
+    }
+    if ( debugMsg )
+        dojo.debug( "doRenderAll [" + renderMsg + "] url: " + url );
+    else if ( debugPageLoad )   // this.getPsmlUrl() ;
+        dojo.debug( "doRenderAll page-url: " + jetspeed.page.getPsmlUrl() + " portlets: [" + renderMsg + "]" + ( url ? ( " url: " + url ) : "" ) );
+};
+
+// ... jetspeed.doAction
+jetspeed.doAction = function( bindArgs, portletEntityId )
+{
+    if ( ! bindArgs )
+    {
+        bindArgs = {};
+    }
+    else if ( ( typeof bindArgs == "string" || bindArgs instanceof String ) )
+    {
+        bindArgs = { url: bindArgs };
+    }
+    var targetPortlet = jetspeed.page.getPortlet( portletEntityId );
+    if ( targetPortlet )
+    {
+        if ( jetspeed.debug.doRenderDoAction )
+        {
+            if ( ! bindArgs.formNode )
+                dojo.debug( "doAction [" + portletEntityId + "] url: " + bindArgs.url + " form: null" );
+            else
+                dojo.debug( "doAction [" + portletEntityId + "] url: " + bindArgs.url + " form: " + jetspeed.debugDumpForm( bindArgs.formNode ) );
+        }
+        targetPortlet.retrieveContent( new jetspeed.om.PortletActionContentListener(), bindArgs );
+    }
+};
+
+jetspeed.portleturl =
+{
+    JAVASCRIPT_ACTION_PREFIX: "javascript:doAction",
+    JAVASCRIPT_RENDER_PREFIX: "javascript:doRender",
+    JAVASCRIPT_ARG_QUOTE: "&" + "quot;",
+    PORTLET_REQUEST_ACTION: "action",
+    PORTLET_REQUEST_RENDER: "render",
+    JETSPEED_DO_NOTHING_ACTION: "javascript:jetspeed.doNothingNav()",
+
+    parseJSPseudoUrlActionRender: function( /* String */ javascriptPseudoUrl )
+    {
+        var op = null;
+        var justTheUrl = javascriptPseudoUrl;
+        var entityId = null;
+        var argsSuffix = null;
+        if ( javascriptPseudoUrl && javascriptPseudoUrl.length > this.JAVASCRIPT_ACTION_PREFIX.length && javascriptPseudoUrl.indexOf( this.JAVASCRIPT_ACTION_PREFIX ) == 0 )
+        {   // annotate away javascript invocation in form action
+            justTheUrl = null;
+            op = jetspeed.portleturl.PORTLET_REQUEST_ACTION;
+            argsSuffix = javascriptPseudoUrl.substring( this.JAVASCRIPT_ACTION_PREFIX.length );
+        }
+        else if ( javascriptPseudoUrl && javascriptPseudoUrl.length > this.JAVASCRIPT_RENDER_PREFIX.length && javascriptPseudoUrl.indexOf( this.JAVASCRIPT_RENDER_PREFIX ) == 0 )
+        {
+            justTheUrl = null;
+            op = jetspeed.portleturl.PORTLET_REQUEST_RENDER;
+            argsSuffix = javascriptPseudoUrl.substring( this.JAVASCRIPT_RENDER_PREFIX.length );
+        }
+        if ( argsSuffix != null )
+        {
+            var quoteDelim = "\"";
+            var argsEnd = argsSuffix.lastIndexOf( quoteDelim );
+            var altargsEnd = argsSuffix.lastIndexOf( this.JAVASCRIPT_ARG_QUOTE );
+            if ( altargsEnd > argsEnd )
+            {
+                quoteDelim = this.JAVASCRIPT_ARG_QUOTE;
+                argsEnd = altargsEnd;
+            }
+            if ( argsEnd >= 0 )
+            {
+                argsSuffix = dojo.string.trim( argsSuffix.substring( 0, argsEnd + quoteDelim.length ) );
+                var argsData = argsSuffix.split( quoteDelim );
+                if ( argsData && argsData.length >=4 )
+                {
+                    justTheUrl = argsData[1];
+                    entityId = argsData[3];
+                }
+            }
+        }
+        else
+        {
+            op = null;
+        }
+        
+        if ( ! jetspeed.url.validateUrlStartsWithHttp( justTheUrl ) )
+            justTheUrl = null;
+
+        return { url: justTheUrl, operation: op, portletEntityId: entityId };
+    },
+
+    generateJSPseudoUrlActionRender: function( parsedPseudoUrl, makeDummy )
+    {   // NOTE: no form can be passed in one of these
+        if ( ! parsedPseudoUrl || ! parsedPseudoUrl.url || ! parsedPseudoUrl.portletEntityId ) return null;
+        var hrefJScolon = null;
+        if ( makeDummy )
+        {
+            hrefJScolon = jetspeed.portleturl.JETSPEED_DO_NOTHING_ACTION;
+        }
+        else
+        {
+            hrefJScolon = "javascript:";
+            var badnews = false;
+            if ( parsedPseudoUrl.operation == jetspeed.portleturl.PORTLET_REQUEST_ACTION )
+                hrefJScolon += "doAction(\"";
+            else if ( parsedPseudoUrl.operation == jetspeed.portleturl.PORTLET_REQUEST_RENDER )
+                hrefJScolon += "doRender(\"";
+            else badnews = true;
+            if ( badnews ) return null;
+            hrefJScolon += parsedPseudoUrl.url + "\",\"" + parsedPseudoUrl.portletEntityId + "\"";
+            hrefJScolon += ")";
+        }
+        return hrefJScolon;
+    }
+
+};
+
+jetspeed.doNothingNav = function()
+{   // replacing form actions with javascript: doNothingNav() is 
+    // useful for preventing form submission in cases like: <a onclick="form.submit(); return false;" >
+    // JSF h:commandLink uses the above anchor onclick practice
+    false;
+};
+jetspeed.loadPortletDecorationStyles = function( portletDecorationName )
+{
+    var portletDecorationConfig = jetspeed.prefs.getPortletDecorationConfig( portletDecorationName );
+    if ( portletDecorationConfig != null && ! portletDecorationConfig.css_loaded )
+    {
+        var pdBaseUrl = jetspeed.prefs.getPortletDecorationBaseUrl( portletDecorationName );
+        portletDecorationConfig.css_loaded = true;
+        portletDecorationConfig.cssPathCommon = new dojo.uri.Uri( pdBaseUrl + "/css/styles.css" );
+        portletDecorationConfig.cssPathDesktop = new dojo.uri.Uri( pdBaseUrl + "/css/desktop.css" );
+        
+        dojo.html.insertCssFile( portletDecorationConfig.cssPathCommon, null, true );
+        dojo.html.insertCssFile( portletDecorationConfig.cssPathDesktop, null, true );
+    }
+    return portletDecorationConfig;
+};
+jetspeed.loadPortletDecorationConfig = function( portletDecorationName )
+{
+    // setup default portlet decoration config
+    var pdConfig = {};
+    jetspeed.prefs.portletDecorationsConfig[ portletDecorationName ] = pdConfig;
+    pdConfig.windowActionButtonOrder = jetspeed.prefs.windowActionButtonOrder;
+    pdConfig.windowActionNotPortlet = jetspeed.prefs.windowActionNotPortlet;
+    pdConfig.windowActionButtonMax = jetspeed.prefs.windowActionButtonMax;
+    pdConfig.windowActionButtonHide = jetspeed.prefs.windowActionButtonHide;
+    pdConfig.windowActionButtonTooltip = jetspeed.prefs.windowActionButtonTooltip;
+    pdConfig.windowActionMenuOrder = jetspeed.prefs.windowActionMenuOrder;
+    pdConfig.windowActionNoImage = jetspeed.prefs.windowActionNoImage;
+    pdConfig.windowIconEnabled = jetspeed.prefs.windowIconEnabled;
+    pdConfig.windowIconPath = jetspeed.prefs.windowIconPath;
+
+    // load portlet decoration config
+    var portletDecorationConfigUri = jetspeed.prefs.getPortletDecorationBaseUrl( portletDecorationName ) + "/" + portletDecorationName + ".js";
+    dojo.hostenv.loadUri( portletDecorationConfigUri, function(hash) {
+				for ( var j in hash )
+                {
+                    pdConfig[ j ] = hash[j];
+                }
+                if ( pdConfig.windowActionNoImage != null )
+                {
+                    var noImageMap = {};
+                    for ( var i = 0 ; i < pdConfig.windowActionNoImage.length; i++ )
+                    {
+                        noImageMap[ pdConfig.windowActionNoImage[ i ] ] = true;
+                    }
+                    pdConfig.windowActionNoImage = noImageMap;
+                }
+                if ( pdConfig.windowIconPath != null )
+                {
+                    pdConfig.windowIconPath = dojo.string.trim( pdConfig.windowIconPath );
+                    if ( pdConfig.windowIconPath == null || pdConfig.windowIconPath.length == 0 )
+                        pdConfig.windowIconPath = null;
+                    else
+                    {
+                        var winIconsPath = pdConfig.windowIconPath;
+                        var firstCh = winIconsPath.charAt(0);
+                        if ( firstCh != "/" )
+                            winIconsPath = "/" + winIconsPath;
+                        var lastCh = winIconsPath.charAt( winIconsPath.length -1 );
+                        if ( lastCh != "/" )
+                            winIconsPath = winIconsPath + "/";
+                        pdConfig.windowIconPath = winIconsPath;
+                    }
+                }
+			});
+};
+
+// jetspeed.purifyIdentifier
+jetspeed.purifyIdentifier = function( src, replaceCh, camel )
+{
+    if ( src == null ) return src;
+    var limit = src.length;
+    if ( limit == 0 ) return src;
+    if ( replaceCh == null )
+        replaceCh = "_";
+    var regEx = new RegExp( "[^a-z_0-9A-Z]", "g" );
+    var chCode = src.charCodeAt( 0 );
+    var buff = null;
+    if ( ( chCode >= 65 && chCode <= 90 ) || chCode == 95 || ( chCode >= 97 && chCode <= 122 ) )
+        buff = src.charAt( 0 );
+    else
+        buff = replaceCh;
+    var hiCamel = false, loCamel = false;
+    if ( camel != null )
+    {
+        camel = camel.toLowerCase();
+        hiCamel = ( camel == "hi" ? true : false );
+        loCamel = ( camel == "lo" ? true : false );
+    }
+    if ( limit > 1 )
+    {
+        if ( hiCamel || loCamel )
+        {
+            upNext = false;
+            for ( var i = 1 ; i < limit ; i++ )
+            {
+                chCode = src.charCodeAt( i );
+                if ( ( chCode >= 65 && chCode <= 90 ) || chCode == 95 || ( chCode >= 97 && chCode <= 122 ) || ( chCode >= 48 && chCode <= 57 ) )
+                {
+                    if ( upNext && ( chCode >= 97 && chCode <= 122 ) )
+                        buff += String.fromCharCode( chCode - 32 );
+                    else
+                        buff += src.charAt( i );
+                    upNext = false;
+                }
+                else
+                {
+                    upNext = true;
+                    buff += replaceCh;
+                }
+            }
+        }
+        else
+        {
+            buff += src.substring( 1 ).replace( regEx, replaceCh );
+        }
+    }
+    if ( hiCamel )
+    {
+        chCode = buff.charCodeAt( 0 );
+        if ( chCode >= 97 && chCode <= 122 )
+            buff = String.fromCharCode( chCode - 32 ) + buff.substring( 1 );
+    }   
+    return buff;
+};
+
+// ... jetspeed.notifyRetrieveAllMenusFinished
+jetspeed.notifyRetrieveAllMenusFinished = function()
+{   // dojo.event.connect to this or add to your page content, one of the functions that it invokes ( doMenuBuildAll() or doMenuBuild() )
+    jetspeed.pageNavigateSuppress = true;
+
+    if ( dojo.lang.isFunction( window.doMenuBuildAll ) )
+    {   
+        window.doMenuBuildAll();
+    }
+    
+    var menuNames = jetspeed.page.getMenuNames();
+    for ( var i = 0 ; i < menuNames.length; i++ )
+    {
+        var menuNm = menuNames[i];
+        var menuWidget = dojo.widget.byId( jetspeed.id.MENU_WIDGET_ID_PREFIX + menuNm );
+        if ( menuWidget )
+        {
+            menuWidget.createJetspeedMenu( jetspeed.page.getMenu( menuNm ) );
+        }
+    }
+    
+    jetspeed.pageNavigateSuppress = false;
+};
+
+// ... jetspeed.notifyRetrieveMenuFinished
+jetspeed.notifyRetrieveMenuFinished = function( /* jetspeed.om.Menu */ menuObj )
+{   // dojo.event.connect to this or add to your page content the function that it invokes ( doMenuBuild() )
+    if ( dojo.lang.isFunction( window.doMenuBuild ) )
+    {
+        window.doMenuBuild( menuObj );
+    }
+};
+
+jetspeed.menuNavClickWidget = function( /* Tab widget || Tab widgetId */ tabWidget, /* int || String */ selectedTab )
+{
+    dojo.debug( "jetspeed.menuNavClick" );
+    if ( ! tabWidget ) return;
+    if ( dojo.lang.isString( tabWidget ) )
+    {
+        var tabWidgetId = tabWidget;
+        tabWidget = dojo.widget.byId( tabWidgetId );
+        if ( ! tabWidget )
+            dojo.raise( "menuNavClick could not find tab widget for " + tabWidgetId );
+    }
+    if ( tabWidget )
+    {
+        var jetspeedMenuName = tabWidget.jetspeedmenuname;
+        if ( ! jetspeedMenuName && tabWidget.extraArgs )
+            jetspeedMenuName = tabWidget.extraArgs.jetspeedmenuname;
+        if ( ! jetspeedMenuName )
+            dojo.raise( "menuNavClick tab widget [" + tabWidget.widgetId + "] does not define jetspeedMenuName" );
+        var menuObj = jetspeed.page.getMenu( jetspeedMenuName );
+        if ( ! menuObj )
+            dojo.raise( "menuNavClick Menu lookup for tab widget [" + tabWidget.widgetId + "] failed: " + jetspeedMenuName );
+        var menuOpt = menuObj.getOptionByIndex( selectedTab );
+        
+        jetspeed.menuNavClick( menuOpt );
+    }
+};
+
+jetspeed.pageNavigateSuppress = false;
+jetspeed.pageNavigate = function( navUrl, navTarget )
+{
+    if ( ! navUrl || jetspeed.pageNavigateSuppress ) return;
+
+    if ( jetspeed.page && jetspeed.page.equalsPageUrl( navUrl ) )
+        return ;
+
+    navUrl = jetspeed.page.makePageUrl( navUrl );
+    
+    if ( navTarget == "top" )
+        top.location.href = navUrl;
+    else if ( navTarget == "parent" )
+        parent.location.href = navUrl;
+    else
+        window.location.href = navUrl;  // BOZO:NOW: popups
+};
+
+jetspeed.loadPortletSelector = function()
+{
+    var windowParams = {};
+    windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_POSITION_STATIC ] = false;
+    windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_HEIGHT_TO_FIT ] = false;
+    windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_DECORATION ] = jetspeed.page.getPortletDecorationDefault();
+    windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_TITLE ] = jetspeed.prefs.portletSelectorWindowTitle;
+    windowParams[ jetspeed.id.PORTLET_PROP_WINDOW_ICON ] = jetspeed.prefs.portletSelectorWindowIcon;
+    windowParams[ jetspeed.id.PORTLET_PROP_WIDGET_ID ] = jetspeed.id.PORTLET_WINDOW_ID_PREFIX + jetspeed.id.SELECTOR;
+    windowParams[ jetspeed.id.PORTLET_PROP_WIDTH ] = jetspeed.prefs.portletSelectorBounds.width;
+    windowParams[ jetspeed.id.PORTLET_PROP_HEIGHT ] = jetspeed.prefs.portletSelectorBounds.height;
+    windowParams[ jetspeed.id.PORTLET_PROP_LEFT ] = jetspeed.prefs.portletSelectorBounds.x;
+    windowParams[ jetspeed.id.PORTLET_PROP_TOP ] = jetspeed.prefs.portletSelectorBounds.y;
+    windowParams[ jetspeed.id.PORTLET_PROP_EXCLUDE_PCONTENT ] = true;
+    windowParams[ jetspeed.id.PORTLET_PROP_CONTENT_RETRIEVER ] = new jetspeed.om.PortletSelectorContentRetriever();
+    var pwWidgetParams = jetspeed.widget.PortletWindow.prototype.staticDefineAsAltInitParameters( null, windowParams );
+    jetspeed.ui.createPortletWindow( pwWidgetParams );
+    pwWidgetParams.retrieveContent( null, null );
+    jetspeed.getPortletDefinitions();
+};
+
+jetspeed.getPortletDefinitions = function()
+{
+    var contentListener = new jetspeed.om.PortletSelectorAjaxApiContentListener();
+    var queryString = "?action=getportlets";
+    var getPortletsUrl = jetspeed.url.basePortalUrl() + jetspeed.url.path.AJAX_API + queryString ;
+    var mimetype = "text/xml";
+    var ajaxApiContext = new jetspeed.om.Id( "getportlets", { } );
+    jetspeed.url.retrieveContent( { url: getPortletsUrl, mimetype: mimetype }, contentListener, ajaxApiContext, jetspeed.debugContentDumpIds );
+};
+
+jetspeed.searchForPortletDefinitions = function(filter, catPortlets)
+{
+    var contentListener = new jetspeed.om.PortletSelectorSearchContentListener(catPortlets);
+    var queryString = "?action=getportlets&filter=" + filter;
+    var getPortletsUrl = jetspeed.url.basePortalUrl() + jetspeed.url.path.AJAX_API + queryString ;
+    var mimetype = "text/xml";
+    var ajaxApiContext = new jetspeed.om.Id( "getportlets", { } );
+    jetspeed.url.retrieveContent( { url: getPortletsUrl, mimetype: mimetype }, contentListener, ajaxApiContext, jetspeed.debugContentDumpIds );
+};
+
+jetspeed.getFolders = function(data, handler)
+{
+    var contentListener = new jetspeed.om.FoldersListContentListener(handler);
+    var queryString = "?action=getfolders&data=" + data;
+    var getPortletsUrl = jetspeed.url.basePortalUrl() + jetspeed.url.path.AJAX_API + queryString ;
+    var mimetype = "text/xml";
+	//alert('getPortletsUrl ' + getPortletsUrl);
+    var ajaxApiContext = new jetspeed.om.Id( "getfolders", { } );
+    jetspeed.url.retrieveContent( { url: getPortletsUrl, mimetype: mimetype }, contentListener, ajaxApiContext, jetspeed.debugContentDumpIds );
+};
+
+jetspeed.portletDefinitionsforSelector = function(filter,category,pagenumber,portletPerPages,catPortlets)
+{
+    var contentListener = new jetspeed.om.PortletSelectorSearchContentListener(catPortlets);
+    var queryString = "?action=selectorPortlets&category=" + category + "&portletPerPages=" + portletPerPages + "&pageNumber=" + pagenumber + "&filter=" + filter;
+    var getPortletsUrl = jetspeed.url.basePortalUrl() + jetspeed.url.path.AJAX_API + queryString ;
+    var mimetype = "text/xml";
+    //alert('getPortletsUrl '  + getPortletsUrl);
+	var ajaxApiContext = new jetspeed.om.Id( "selectorPortlets", { } );
+    jetspeed.url.retrieveContent( { url: getPortletsUrl, mimetype: mimetype }, contentListener, ajaxApiContext, jetspeed.debugContentDumpIds );
+};
+jetspeed.getActionsForPortlet = function( /* String */ portletEntityId, contentListener )
+{
+    if ( portletEntityId == null ) return;
+    jetspeed.getActionsForPortlets( [ portletEntityId ], contentListener );
+};
+jetspeed.getActionsForPortlets = function( /* Array */ portletEntityIds, contentListener )
+{
+    if ( contentListener == null )
+        contentListener = new jetspeed.om.PortletActionsContentListener();
+    var queryString = "?action=getactions";
+    if ( portletEntityIds == null )
+        portletEntityIds = jetspeed.page.getPortletIds();
+    for ( var i = 0 ; i < portletEntityIds.length ; i++ )
+    {
+        queryString += "&id=" + portletEntityIds[i];
+    }
+    var getActionsUrl = jetspeed.url.basePortalUrl() + jetspeed.url.path.AJAX_API + jetspeed.page.getPath() + queryString;
+    var mimetype = "text/xml";
+    var ajaxApiContext = new jetspeed.om.Id( "getactions", { } );
+    jetspeed.url.retrieveContent( { url: getActionsUrl, mimetype: mimetype }, contentListener, ajaxApiContext, jetspeed.debugContentDumpIds );
+};
+jetspeed.changeActionForPortlet = function( /* String */ portletEntityId, /* String */ changeActionState, /* String */ changeActionMode, contentListener )
+{
+    if ( portletEntityId == null ) return;
+    if ( contentListener == null )
+        contentListener = new jetspeed.om.PortletChangeActionContentListener( portletEntityId );
+    var queryString = "?action=window&id=" + ( portletEntityId != null ? portletEntityId : "" );
+    if ( changeActionState != null )
+        queryString += "&state=" + changeActionState;
+    if ( changeActionMode != null )
+        queryString += "&mode=" + changeActionMode;
+    var changeActionUrl = jetspeed.url.basePortalUrl() + jetspeed.url.path.AJAX_API + jetspeed.page.getPath() + queryString ;
+    var mimetype = "text/xml";
+    var ajaxApiContext = new jetspeed.om.Id( "changeaction", { } );
+    jetspeed.url.retrieveContent( { url: changeActionUrl, mimetype: mimetype }, contentListener, ajaxApiContext, jetspeed.debugContentDumpIds );
+};
+
+jetspeed.addNewPortletDefinition = function( /* jetspeed.om.PortletDef */ portletDef, windowWidgetId, /* String */ psmlUrl, /* String */ layoutId )
+{
+    var addToCurrentPage = true;
+    if ( psmlUrl != null )
+    {
+        addToCurrentPage = false;
+    }
+    var contentListener = new jetspeed.om.PortletAddAjaxApiCallbackContentListener( portletDef, windowWidgetId, addToCurrentPage );
+    var queryString = "?action=add&id=" + escape( portletDef.getPortletName() );
+    if ( layoutId != null && layoutId.length > 0 )
+    {
+        queryString += "&layoutid=" + escape( layoutId );
+    }
+    var addPortletUrl = null;
+    if ( psmlUrl != null )
+    {
+        addPortletUrl = psmlUrl + queryString;   //  psmlUrl example: http://localhost:8080/jetspeed/ajaxapi/google-maps.psml
+    }
+    else
+    {
+        addPortletUrl = jetspeed.page.getPsmlUrl() + queryString;
+    }
+    var mimetype = "text/xml";
+    var ajaxApiContext = new jetspeed.om.Id( "addportlet", { } );
+    jetspeed.url.retrieveContent( { url: addPortletUrl, mimetype: mimetype }, contentListener, ajaxApiContext, jetspeed.debugContentDumpIds );
+};
+
+jetspeed.editPageInitiate = function()
+{
+    if ( ! jetspeed.page.editMode )
+    {
+        var fromDesktop = true;
+        var fromPortal = jetspeed.url.getQueryParameter( document.location.href, jetspeed.id.PORTAL_ORIGINATE_PARAMETER );
+        if ( fromPortal != null && fromPortal == "true" )
+            fromDesktop = false;
+        jetspeed.page.editMode = true;
+        var pageEditorWidget = dojo.widget.byId( jetspeed.id.PAGE_EDITOR_WIDGET_ID );
+        if ( pageEditorWidget == null )
+        {
+            pageEditorWidget = dojo.widget.createWidget( "jetspeed:PageEditor", { widgetId: jetspeed.id.PAGE_EDITOR_WIDGET_ID, editorInitiatedFromDesktop: fromDesktop } );
+            var allColumnsContainer = document.getElementById( jetspeed.id.COLUMNS );
+            allColumnsContainer.insertBefore( pageEditorWidget.domNode, allColumnsContainer.firstChild );
+        }
+        else
+        {
+            pageEditorWidget.editPageShow();
+        }
+        jetspeed.page.syncPageControls();
+    }
+};
+jetspeed.editPageTerminate = function()
+{
+    if ( jetspeed.page.editMode )
+    {
+        jetspeed.page.editMode = false;
+        var pageEditorWidget = dojo.widget.byId( jetspeed.id.PAGE_EDITOR_WIDGET_ID );
+        if ( ! pageEditorWidget.editorInitiatedFromDesktop )
+        {
+            var portalPageUrl = jetspeed.page.getPageUrl( true );
+            portalPageUrl = jetspeed.url.removeQueryParameter( portalPageUrl, jetspeed.id.PAGE_EDITOR_INITIATE_PARAMETER );
+            portalPageUrl = jetspeed.url.removeQueryParameter( portalPageUrl, jetspeed.id.PORTAL_ORIGINATE_PARAMETER );
+            window.location.href = portalPageUrl;
+        }
+        else
+        {
+            if ( pageEditorWidget != null )
+            {
+                pageEditorWidget.editPageHide();
+            }
+            jetspeed.page.syncPageControls();
+        }
+    }
+};
+
+jetspeed.debugDumpForm = function( formNode )
+{
+    if ( ! formNode ) return null ;
+    var formDump = formNode.toString() ;
+    if ( formNode.name )
+        formDump += " name=" + formNode.name;
+    if ( formNode.id )
+        formDump += " id=" + formNode.id;
+    var queryString = dojo.io.encodeForm( formNode );
+    formDump += " data=" + queryString; 
+    return formDump;
+};
+
+// ... jetspeed.om.PortletContentRetriever
+jetspeed.om.PortletContentRetriever = function()
+{
+};
+jetspeed.om.PortletContentRetriever.prototype =
+{   // /* Portlet */ portlet, /* String */ requestUrl, /* PortletContentListener */ portletContentListener
+    getContent: function( bindArgs, contentListener, domainModelObject, /* String[] */ debugContentDumpIds )
+    {
+        if ( ! bindArgs )
+            bindArgs = {};
+        jetspeed.url.retrieveContent( bindArgs, contentListener, domainModelObject, debugContentDumpIds );
+    }
+};
+
+// ... jetspeed.om.DojoDebugContentRetriever
+jetspeed.om.DojoDebugContentRetriever = function()
+{
+    this.initialized = false;
+};
+jetspeed.om.DojoDebugContentRetriever.prototype =
+{
+    getContent: function( bindArgs, contentListener, domainModelObject, /* String[] */ debugContentDumpIds )
+    {
+        if ( ! bindArgs )
+            bindArgs = {};
+        if ( ! this.initialized )
+        {
+            var content = "";
+            if ( jetspeed.altDebugWindowContent )
+                content = jetspeed.altDebugWindowContent();
+            else
+            {
+                content += '<div id="' + jetspeed.debug.debugContainerId + '"></div>';
+            }
+            if ( ! contentListener )
+                contentListener = new jetspeed.om.BasicContentListener();
+            contentListener.notifySuccess( content, bindArgs.url, domainModelObject ) ;
+            this.initialized = true;
+        }
+    }
+};
+
+// ... jetspeed.om.PortletSelectorContentRetriever
+jetspeed.om.PortletSelectorContentRetriever = function()
+{
+};
+jetspeed.om.PortletSelectorContentRetriever.prototype =
+{
+    getContent: function( bindArgs, contentListener, domainModelObject, /* String[] */ debugContentDumpIds )
+    {
+        if ( ! bindArgs )
+            bindArgs = {};
+        var content = '<div widgetId="' + jetspeed.id.SELECTOR + '" dojoType="PortletDefContainer"></div>';
+        if ( ! contentListener )
+            contentListener = new jetspeed.om.BasicContentListener();
+        contentListener.notifySuccess( content, bindArgs.url, domainModelObject ) ;
+    }
+};
+
+// ... jetspeed.om.PortletSelectorContentListener
+jetspeed.om.PortletSelectorContentListener = function()
+{
+};
+jetspeed.om.PortletSelectorContentListener.prototype =
+{
+    notifySuccess: function( /* String */ portletContent, /* String */ requestUrl, /* Portlet */ portlet )
+    {
+        var windowWidget = this.getPortletWindow();
+        if ( windowWidget )
+        {
+            windowWidget.setPortletContent( portletContent, renderUrl );
+        }
+    },
+    notifyFailure: function( /* String */ type, /* Object */ error, /* String */ requestUrl, /* Portlet */ portlet )
+    {
+        dojo.raise( "PortletSelectorContentListener notifyFailure url: " + requestUrl + " type: " + type + jetspeed.url.formatBindError( error ) );
+    }
+};
+
+// ... jetspeed.om.PageContentListenerUpdate
+jetspeed.om.PageContentListenerUpdate = function( /* jetspeed.om.Page */ previousPage )
+{
+    this.previousPage = previousPage;
+};
+jetspeed.om.PageContentListenerUpdate.prototype =
+{
+    notifySuccess: function( /* XMLDocument */ data, /* String */ requestUrl, /* Page */ page )
+    {
+        dojo.raise( "PageContentListenerUpdate notifySuccess - BUT NOT SUPPORTED - url=" + requestUrl ) ;
+        //page.getPortletsFromPSML( data );  // the new getFragmentsFromPSML is not compatible with this usage
+        //var updatedPortlets = page.getPortletArray();
+        //for ( var i = 0 ; i < updatedPortlets.length ; i++ )
+        //{
+        //    var prevPortlet = this.previousPage.getPortlet( updatedPortlets[i].entityId );
+        //    if ( prevPortlet == null )
+        //    {
+        //        dojo.debug( "PageContentListenerUpdate  new portlet definition in page: " + updatedPortlets[i].toString() ) ;
+        //    }
+        //}
+    },
+    notifyFailure: function( /* String */ type, /* Object */ error, /* String */ requestUrl, /* Page */ page )
+    {
+        dojo.raise( "PageContentListenerUpdate notifyFailure url: " + requestUrl + " type: " + type + jetspeed.url.formatBindError( error ) );
+    }
+};
+
+// ... jetspeed.om.PageContentListenerCreateWidget
+jetspeed.om.PageContentListenerCreateWidget = function()
+{
+};
+jetspeed.om.PageContentListenerCreateWidget.prototype =
+{
+    notifySuccess: function( /* XMLDocument */ data, /* String */ requestUrl, /* Page */ page )
+    {
+        page.loadFromPSML( data );
+    },
+    notifyFailure: function( /* String */ type, /* Object */ error, /* String */ requestUrl, /* Page */ page )
+    {
+        dojo.raise( "PageContentListenerCreateWidget error url: " + requestUrl + " type: " + type + jetspeed.url.formatBindError( error ) );
+    }
+};
+
+// ... jetspeed.om.Id
+jetspeed.om.Id = function( /* ... */ )  // intended as a simple, general object with an id and a getId() function
+{
+    var idBuff = "";
+    for ( var i = 0; i < arguments.length; i++ )
+    {
+        if( dojo.lang.isString( arguments[i] ) )
+        {
+            if ( idBuff.length > 0 )
+                idBuff += "-";
+            idBuff += arguments[i];
+        }
+        else if ( dojo.lang.isObject( arguments[i] ) )
+        {
+            for ( var slotKey in arguments[i] )
+            {
+                this[ slotKey ] = arguments[i][slotKey];
+            }
+        }
+    }
+    this.jetspeed_om_id = idBuff;
+};
+dojo.lang.extend( jetspeed.om.Id,
+{
+    getId: function()
+    {
+        return this.jetspeed_om_id;
+    }
+});
+
+// ... jetspeed.om.Page
+jetspeed.om.Page = function( pagePsmlPath, pageName, pageTitle )
+{
+    this.psmlPath = pagePsmlPath;
+    if ( this.psmlPath == null )
+        this.setPsmlPathFromDocumentUrl();
+    this.name = pageName;
+    this.title = pageTitle;
+    this.layouts = {};
+    this.columns = [];
+    this.portlets = [];
+    this.menus = [];
+};
+dojo.inherits( jetspeed.om.Page, jetspeed.om.Id );
+dojo.lang.extend( jetspeed.om.Page,
+{
+    psmlPath: null,
+    name: null,
+    path: null,
+    pageUrl: null,
+    pagePathAndQuery: null,
+    title: null,
+    shortTitle: null,
+    layoutDecorator: null,
+    portletDecorator: null,
+
+    layouts: null,
+    columns: null,
+    portlets: null,
+
+    editMode: false,
+    themeDefinitions: null,
+
+    menus: null,
+
+    getId: function()  // jetspeed.om.Id protocol
+    {
+        var idsuffix = ( this.name != null && this.name.length > 0 ? this.name : null );
+        if ( ! idsuffix )
+        {
+            this.getPsmlUrl();
+            idsuffix = this.psmlPath;
+        }
+        return "page-" + idsuffix;
+    },
+    
+    setPsmlPathFromDocumentUrl: function()
+    {
+        var psmlPath = jetspeed.url.path.AJAX_API ;
+        var docPath = document.location.pathname ;
+        
+        var contextAndServletPath = jetspeed.url.path.DESKTOP ;
+        var contextAndServletPathPos = docPath.indexOf( contextAndServletPath ) ;
+        if ( contextAndServletPathPos != -1 && docPath.length > ( contextAndServletPathPos + contextAndServletPath.length ) )
+        {
+            psmlPath = psmlPath + docPath.substring( contextAndServletPathPos + contextAndServletPath.length ) ;
+        }
+        this.psmlPath = psmlPath ;
+    },
+    
+    getPsmlUrl: function()
+    {
+        if ( this.psmlPath == null )
+            this.setPsmlPathFromDocumentUrl() ;
+
+        var psmlUrl = jetspeed.url.basePortalUrl() + this.psmlPath;
+        if ( jetspeed.prefs.printModeOnly != null )
+        {
+            psmlUrl = jetspeed.url.addQueryParameter( psmlUrl, "layoutid", jetspeed.prefs.printModeOnly.layout );
+            psmlUrl = jetspeed.url.addQueryParameter( psmlUrl, "entity", jetspeed.prefs.printModeOnly.entity ).toString();
+        }
+        return psmlUrl;
+    },
+    
+    retrievePsml: function( pageContentListener )
+    {
+        if ( pageContentListener == null )
+            pageContentListener = new jetspeed.om.PageContentListenerCreateWidget();
+
+        var psmlUrl = this.getPsmlUrl() ;
+        var mimetype = "text/xml";
+
+        if ( jetspeed.debug.retrievePsml )
+            dojo.debug( "retrievePsml url: " + psmlUrl ) ;
+
+        jetspeed.url.retrieveContent( { url: psmlUrl, mimetype: mimetype }, pageContentListener, this, jetspeed.debugContentDumpIds );
+    },
+
+    loadFromPSML: function( psml )
+    {
+        // parse PSML
+        var parsedRootLayoutFragment = this._parsePSML( psml );
+
+        // create layout model
+        var portletsByPageColumn = {};
+        this.columnsStructure = this._layoutCreateModel( parsedRootLayoutFragment, null, portletsByPageColumn, true );
+
+        this.rootFragmentId = parsedRootLayoutFragment.id ;
+
+        // create columns
+        if ( jetspeed.prefs.windowTiling )
+        {
+            this._createColumnsStart( document.getElementById( jetspeed.id.DESKTOP ) );
+        }
+
+        // create portlet windows
+        var windowsToRender = new Array();
+        var colLen = this.columns.length;
+        for ( var colIndex = 0 ; colIndex <= this.columns.length ; colIndex++ )  // iterate to one past last column index
+        {
+            var portletArray = null;
+            if ( colIndex == colLen )
+            {
+                portletArray = portletsByPageColumn[ "z" ];
+                if ( portletArray != null )
+                    portletArray.sort( this._loadPortletZIndexCompare );
+            }
+            else
+            {
+                portletArray = portletsByPageColumn[ colIndex.toString() ];
+            }
+        
+            if ( portletArray != null )
+            {
+                for ( var i = 0; i < portletArray.length; i++ )
+                {
+                    var portlet = portletArray[i].portlet;
+                    windowsToRender.push( portlet );
+                    portlet.createPortletWindow( colIndex );
+                }
+            }
+        }
+
+        if ( jetspeed.prefs.printModeOnly == null )
+        {
+            // render portlets
+            if ( windowsToRender && windowsToRender.length > 0 )
+            {
+                jetspeed.doRenderAll( null, windowsToRender, true );
+            }
+
+            // initialize portlet window state
+            this._portletsInitializeWindowState( portletsByPageColumn[ "z" ] );
+
+            // load menus
+            this.retrieveAllMenus();
+    
+            // render page buttons
+            this.renderPageControls();
+            this.syncPageControls();
+    
+            // detect edit mode force - likely to be temporary
+            var pageEditorInititate = jetspeed.url.getQueryParameter( document.location.href, jetspeed.id.PAGE_EDITOR_INITIATE_PARAMETER );
+            if ( ( pageEditorInititate != null && pageEditorInititate == "true" ) || this.actions[ jetspeed.id.ACTION_NAME_VIEW ] != null )
+            {
+                if ( this.actions != null && ( this.actions[ jetspeed.id.ACTION_NAME_EDIT ] != null || this.actions[ jetspeed.id.ACTION_NAME_VIEW ] != null ) )
+                    jetspeed.editPageInitiate();
+            }
+        }
+        else
+        {
+            var portlet = null;
+            for ( var portletIndex in this.portlets )
+            {
+                portlet = this.portlets[portletIndex];
+                break;
+            }
+            if ( portlet != null )
+            {
+                portlet.renderAction( null, jetspeed.prefs.printModeOnly.action );
+
+                this._portletsInitializeWindowState( portletsByPageColumn[ "z" ] );
+            }
+        }
+    },
+    _parsePSML: function( psml )
+    {
+        var pageElements = psml.getElementsByTagName( "page" );
+        if ( ! pageElements || pageElements.length > 1 )
+            dojo.raise( "unexpected zero or multiple <page> elements in psml" );
+        var pageElement = pageElements[0];
+        var children = pageElement.childNodes;
+        var simpleValueLNames = new RegExp( "(name|path|profiledPath|title|short-title)" );
+        var rootFragment = null;
+        var rootFragmentActions = {};
+        for ( var i = 0 ; i < children.length ; i++ )
+        {
+            var child = children[i];
+            if ( child.nodeType != dojo.dom.ELEMENT_NODE )
+                continue;
+            var childLName = child.nodeName;
+            if ( childLName == "fragment" )
+            {
+                rootFragment = child;
+            }
+            else if ( childLName == "defaults" )
+            {
+                this.layoutDecorator = child.getAttribute( "layout-decorator" );
+                this.portletDecorator = child.getAttribute( "portlet-decorator" );
+            }
+            else if ( childLName && childLName.match( simpleValueLNames  ) )
+            {
+                this[ jetspeed.purifyIdentifier( childLName, "", "lo" ) ] = ( ( child && child.firstChild ) ? child.firstChild.nodeValue : null );
+            }
+            else if ( childLName == "action" )
+            {
+                this._parsePSMLAction( child, rootFragmentActions ) ;
+            }
+        }
+        this.actions = rootFragmentActions;
+
+        if ( rootFragment == null )
+        {
+            dojo.raise( "No root fragment in PSML." );
+            return null;
+        }
+        
+        var parsedRootLayoutFragment = this._parsePSMLLayoutFragment( rootFragment, 0 );    // rootFragment must be a layout fragment - /portal requires this as well
+        return parsedRootLayoutFragment;
+    },
+    _parsePSMLLayoutFragment: function( layoutNode, layoutNodeDocumentOrderIndex )
+    {
+        var fragChildren = new Array();
+        var layoutFragType = ( (layoutNode != null) ? layoutNode.getAttribute( "type" ) : null );
+        if ( layoutFragType != "layout" )
+        {
+            dojo.raise( "_parsePSMLLayoutFragment called with non-layout fragment: " + layoutNode );
+            return null;
+        }
+
+        var sizes = null, sizesSum = 0;
+        var propertiesMap = {};
+        var children = layoutNode.childNodes;
+        var child, childLName, propName, propVal, fragType;
+        for ( var i = 0 ; i < children.length ; i++ )
+        {
+            child = children[i];
+            if ( child.nodeType != dojo.dom.ELEMENT_NODE )
+                continue;
+            childLName = child.nodeName;
+            if ( childLName == "fragment" )
+            {
+                fragType = child.getAttribute( "type" );
+                if ( fragType == "layout" )
+                {
+                    var parsedLayoutChildFragment = this._parsePSMLLayoutFragment( child, i );
+                    if ( parsedLayoutChildFragment != null )
+                    {
+                        fragChildren.push( parsedLayoutChildFragment ) ;
+                    }
+                }
+                else
+                {
+                    var portletProps = this._parsePSMLProperties( child, null );
+                    var portletIcon = portletProps[ jetspeed.id.PORTLET_PROP_WINDOW_ICON ];
+                    if ( portletIcon == null || portletIcon.length == 0 )
+                    {
+                        portletIcon = this._parsePSMLIcon( child );
+                        if ( portletIcon != null && portletIcon.length > 0 )
+                        {
+                            portletProps[ jetspeed.id.PORTLET_PROP_WINDOW_ICON ] = portletIcon;
+                        }
+                    }
+                    fragChildren.push( { id: child.getAttribute( "id" ), type: fragType, name: child.getAttribute( "name" ), properties: portletProps, actions: this._parsePSMLActions( child, null ), currentActionState: this._parsePSMLCurrentActionState( child ), currentActionMode: this._parsePSMLCurrentActionMode( child ), decorator: child.getAttribute( "decorator" ), documentOrderIndex: i } );
+                }
+            }
+            else if ( childLName == "property" )
+            {
+                if ( this._parsePSMLProperty( child, propertiesMap ) == "sizes" )
+                {
+                    if ( sizes != null )
+                    {
+                        dojo.raise( "_parsePSMLLayoutFragment called with layout fragment that contains more than one sizes property: " + layoutNode );
+                        return null;
+                    }
+                    if ( jetspeed.prefs.printModeOnly != null )
+                    {
+                        sizes = [ "100" ];
+                        sizesSum = 100;
+                    }
+                    else
+                    {
+                        propVal = child.getAttribute( "value" );
+                        if ( propVal != null && propVal.length > 0 )
+                        {
+                            sizes = propVal.split( "," );
+                            for ( var j = 0 ; j < sizes.length ; j++ )
+                            {
+                                var re = /^[^0-9]*([0-9]+)[^0-9]*$/;
+                                sizes[j] = sizes[j].replace( re, "$1" );
+                                sizesSum += new Number( sizes[j] );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        fragChildren.sort( this._fragmentRowCompare );
+
+        var layoutFragIndexes = new Array();
+        var otherFragIndexes = new Array();        
+        for ( var i = 0 ; i < fragChildren.length ; i++ )
+        {
+            if ( fragChildren[i].type == "layout" )
+                layoutFragIndexes.push( i );
+            else
+                otherFragIndexes.push( i );
+        }
+        if ( sizes == null )
+        {
+            sizes = new Array();
+            sizes.push( "100" );
+            sizesSum = 100;
+        }
+        return { id: layoutNode.getAttribute( "id" ), type: layoutFragType, name: layoutNode.getAttribute( "name" ), decorator: layoutNode.getAttribute( "decorator" ), columnSizes: sizes, columnSizesSum: sizesSum, properties: propertiesMap, fragments: fragChildren, layoutFragmentIndexes: layoutFragIndexes, otherFragmentIndexes: otherFragIndexes, documentOrderIndex: layoutNodeDocumentOrderIndex };
+    },
+    _parsePSMLActions: function( fragmentNode, actionsMap )
+    {
+        if ( actionsMap == null )
+            actionsMap = {};
+        var actionChildren = fragmentNode.getElementsByTagName( "action" );
+        for( var actionsIdx=0; actionsIdx < actionChildren.length; actionsIdx++ )
+        {
+            var actionNode = actionChildren[actionsIdx];
+            this._parsePSMLAction( actionNode, actionsMap );
+        }
+        return actionsMap;
+    },
+    _parsePSMLAction: function( actionNode, actionsMap )
+    {
+        var actionName = actionNode.getAttribute( "id" );
+        if ( actionName != null )
+        {
+            var actionType = actionNode.getAttribute( "type" );
+            var actionLabel = actionNode.getAttribute( "name" );
+            var actionUrl = actionNode.getAttribute( "url" );
+            var actionAlt = actionNode.getAttribute( "alt" );
+            actionsMap[ actionName.toLowerCase() ] = { id: actionName, type: actionType, label: actionLabel, url: actionUrl, alt: actionAlt };
+        }
+    },
+    _parsePSMLCurrentActionState: function( fragmentNode )
+    {
+        var nodes = fragmentNode.getElementsByTagName( "state" );
+        if ( nodes != null && nodes.length == 1 && nodes[0].firstChild != null )
+        {
+            return nodes[0].firstChild.nodeValue;
+        }
+        return null;
+    },
+    _parsePSMLCurrentActionMode: function( fragmentNode )
+    {
+        var nodes = fragmentNode.getElementsByTagName( "mode" );
+        if ( nodes != null && nodes.length == 1 && nodes[0].firstChild != null )
+        {
+            return nodes[0].firstChild.nodeValue;
+        }
+        return null;
+    },
+    _parsePSMLIcon: function( fragmentNode )
+    {
+        var nodes = fragmentNode.getElementsByTagName( "icon" );
+        if ( nodes != null && nodes.length == 1 && nodes[0].firstChild != null )
+        {
+            return nodes[0].firstChild.nodeValue;
+        }
+        return null;
+    },
+    _parsePSMLProperties: function( fragmentNode, propertiesMap )
+    {
+        if ( propertiesMap == null )
+            propertiesMap = {};
+        var props = fragmentNode.getElementsByTagName( "property" );
+        for( var propsIdx=0; propsIdx < props.length; propsIdx++ )
+        {
+            this._parsePSMLProperty( props[propsIdx], propertiesMap );
+        }
+        return propertiesMap;
+    },
+    _parsePSMLProperty: function( propertyNode, propertiesMap )
+    {
+        var propName = propertyNode.getAttribute( "name" );
+        var propValue = propertyNode.getAttribute( "value" );
+        propertiesMap[ propName ] = propValue;
+        return propName;
+    },
+    _fragmentRowCompare: function( fragmentA, fragmentB )
+    {
+        var rowA = fragmentA.documentOrderIndex * 1000 ;  // so that frags without row property fall after those with row property
+        var rowB = fragmentB.documentOrderIndex * 1000 ;
+
+        var rowAprop = fragmentA.properties[ "row" ];
+        if ( rowAprop != null )
+            rowA = rowAprop;
+        var rowBprop = fragmentB.properties[ "row" ];
+        if ( rowBprop != null )
+            rowB = rowBprop;
+        return ( rowA - rowB );
+    },
+
+    _layoutCreateModel: function( layoutFragment, parentColumn, portletsByPageColumn, omitLayoutHeader )
+    {  // layoutFragmentParentColumnIndex, parentColumnsInLayout
+        var allColumnsStartIndex = this.columns.length;
+        var colModelResult = this._layoutRegisterAndCreateColumnsModel( layoutFragment, parentColumn, omitLayoutHeader );
+        var columnsInLayout = colModelResult.columnsInLayout;
+        if ( colModelResult.addedLayoutHeaderColumn )
+            allColumnsStartIndex++;
+        var columnsInLayoutLen = ( columnsInLayout == null ? 0 : columnsInLayout.length ) ;
+
+        if ( layoutFragment.layoutFragmentIndexes != null && layoutFragment.layoutFragmentIndexes.length > 0 )
+        {   // layout contains child layout fragments
+            var currentClonedLayoutFragByCol = null;
+            var clonedLayoutFragmentCount = 0;
+            if ( layoutFragment.otherFragmentIndexes != null && layoutFragment.otherFragmentIndexes.length > 0 )
+                currentClonedLayoutFragByCol = new Array();
+
+            for ( var i = 0 ; i < layoutFragment.fragments.length ; i++ )
+            {
+                var childFrag = layoutFragment.fragments[ i ];
+            }
+            
+            var columnsInLayoutPopulated = new Array();
+            for ( var i = 0 ; i < columnsInLayoutLen ; i++ )
+            {
+                if ( currentClonedLayoutFragByCol != null )
+                    currentClonedLayoutFragByCol.push( null );
+                columnsInLayoutPopulated.push( false );
+            }
+            for ( var i = 0 ; i < layoutFragment.fragments.length ; i++ )
+            {
+                var childFrag = layoutFragment.fragments[ i ];
+                var childFragInColIndex = i;
+                if ( childFrag.properties && childFrag.properties[ jetspeed.id.PORTLET_PROP_COLUMN ] >= 0 )
+                {
+                    if ( childFrag.properties[ jetspeed.id.PORTLET_PROP_COLUMN ] != null && childFrag.properties[ jetspeed.id.PORTLET_PROP_COLUMN ] >= 0 )
+                        childFragInColIndex = childFrag.properties[ jetspeed.id.PORTLET_PROP_COLUMN ] ;
+                }
+                if ( childFragInColIndex >= columnsInLayoutLen )
+                {
+                    childFragInColIndex = ( columnsInLayoutLen > 0 ? ( columnsInLayoutLen -1 ) : 0 );
+                }
+
+                var currentClonedLayoutFragForCol = ( (currentClonedLayoutFragByCol == null) ? null : currentClonedLayoutFragByCol[ childFragInColIndex ] );
+                if ( childFrag.type == "layout" )
+                {
+                    columnsInLayoutPopulated[ childFragInColIndex ] = true;
+                    if ( currentClonedLayoutFragForCol != null )
+                    {
+                        this._layoutCreateModel( currentClonedLayoutFragForCol, columnsInLayout[childFragInColIndex], portletsByPageColumn, true ) ;
+                        currentClonedLayoutFragByCol[ childFragInColIndex ] = null;
+                    }
+                    this._layoutCreateModel( childFrag, columnsInLayout[childFragInColIndex], portletsByPageColumn, false ) ;
+                }
+                else
+                {
+                    if ( currentClonedLayoutFragForCol == null )
+                    {
+                        clonedLayoutFragmentCount++;
+                        var clonedPortletLayout = {};
+                        dojo.lang.mixin( clonedPortletLayout, layoutFragment );
+                        clonedPortletLayout.fragments = new Array();
+                        clonedPortletLayout.layoutFragmentIndexes = new Array();
+                        clonedPortletLayout.otherFragmentIndexes = new Array();
+                        clonedPortletLayout.documentOrderIndex = layoutFragment.fragments[i].documentOrderIndex;
+                        clonedPortletLayout.clonedFromRootId = clonedPortletLayout.id;
+                        clonedPortletLayout.clonedLayoutFragmentIndex = clonedLayoutFragmentCount;
+                        clonedPortletLayout.columnSizes = [ "100" ];
+                        clonedPortletLayout.columnSizesSum = [ 100 ];
+                        clonedPortletLayout.id = clonedPortletLayout.id + "-jsclone_" + clonedLayoutFragmentCount;
+                        currentClonedLayoutFragByCol[ childFragInColIndex ] = clonedPortletLayout;
+                        currentClonedLayoutFragForCol = clonedPortletLayout;
+                    }
+                    currentClonedLayoutFragForCol.fragments.push( childFrag );
+                    currentClonedLayoutFragForCol.otherFragmentIndexes.push( currentClonedLayoutFragForCol.fragments.length -1 );
+                }
+            }
+            if ( currentClonedLayoutFragByCol != null )
+            {
+                for ( var i = 0 ; i < columnsInLayoutLen ; i++ )
+                {
+                    var currentClonedLayoutFragForCol = currentClonedLayoutFragByCol[ i ];
+                    if ( currentClonedLayoutFragForCol != null )
+                    {
+                        columnsInLayoutPopulated[ i ] = true;
+                        this._layoutCreateModel( currentClonedLayoutFragForCol, columnsInLayout[i], portletsByPageColumn, true ) ;
+                    }
+                }
+            }
+            for ( var i = 0 ; i < columnsInLayoutLen ; i++ )
+            {
+                if ( columnsInLayoutPopulated[ i ] )
+                    columnsInLayout[i].columnContainer = true;   // column cannot contain portlets
+            }
+            if ( layoutFragment.otherFragmentIndexes != null && layoutFragment.otherFragmentIndexes.length > 0 )
+            {
+                var correctedFragments = new Array();
+                for ( var i = 0 ; i < layoutFragment.fragments.length ; i++ )
+                {
+                    var includeFrag = true;
+                    for ( var j = 0 ; j < layoutFragment.otherFragmentIndexes.length ; j++ )
+                    {
+                        if ( layoutFragment.otherFragmentIndexes[j] == i )
+                        {
+                            includeFrag = false;
+                            break;
+                        }
+                    }
+                    if ( includeFrag )
+                        correctedFragments.push( layoutFragment.fragments[ i ] );
+                }
+                layoutFragment.fragments = correctedFragments;
+                layoutFragment.otherFragmentIndexes = new Array();
+            }
+        }
+        this._layoutCreatePortletsModel( layoutFragment, columnsInLayout, allColumnsStartIndex, portletsByPageColumn ) ;
+
+        return columnsInLayout;
+    },
+
+    _layoutFragmentChildCollapse: function( layoutFragment, targetLayoutFragment )
+    {
+        var hasNestedLayouts = false;
+        if ( targetLayoutFragment == null )
+            targetLayoutFragment = layoutFragment;
+        if ( layoutFragment.layoutFragmentIndexes != null && layoutFragment.layoutFragmentIndexes.length > 0 )
+        {   // if contains nested layouts - collect their portlets into targetLayoutFragment
+            hasNestedLayouts = true;
+            for ( var i = 0 ; i < layoutFragment.layoutFragmentIndexes.length ; i++ )
+            {
+                var layoutChildFrag = layoutFragment.fragments[ layoutFragment.layoutFragmentIndexes[i] ];
+                if ( layoutChildFrag.otherFragmentIndexes != null && layoutChildFrag.otherFragmentIndexes.length > 0 )
+                {
+                    for ( var i = 0 ; i < layoutChildFrag.otherFragmentIndexes.length ; i++ )
+                    {
+                        var pFrag = layoutChildFrag.fragments[ layoutChildFrag.otherFragmentIndexes[i] ];
+                        pFrag.properties[ jetspeed.id.PORTLET_PROP_COLUMN ] = -1;
+                        pFrag.properties[ jetspeed.id.PORTLET_PROP_ROW ] = -1;
+                        // BOZO:NOW: ^^ should we set to -1 or delete row & column properties ?
+                        pFrag.documentOrderIndex = targetLayoutFragment.fragments.length;
+                        targetLayoutFragment.fragments.push( pFrag );
+                        targetLayoutFragment.otherFragIndexes.push( targetLayoutFragment.fragments.length ) ;
+                    }
+                }
+                this._layoutFragmentChildCollapse( layoutChildFrag, targetLayoutFragment );
+            }
+        }
+        return hasNestedLayouts;
+    },
+
+    _layoutRegisterAndCreateColumnsModel: function( layoutFragment, parentColumn, omitLayoutHeader )
+    {
+        this.layouts[ layoutFragment.id ] = layoutFragment;
+        var addedLayoutHeaderColumn = false;
+        var columnsInLayout = new Array();
+        if ( jetspeed.prefs.windowTiling && layoutFragment.columnSizes.length > 0 )
+        {
+            var subOneLast = false;
+            if ( jetspeed.browser_IE ) // IE can't deal with 100% here on any nested column - so subtract 0.1% - bug not fixed in IE7
+                subOneLast = true;
+            
+            if ( parentColumn != null && ! omitLayoutHeader )
+            {
+                var layoutHeaderColModelObj = new jetspeed.om.Column( 0, layoutFragment.id, ( subOneLast ? layoutFragment.columnSizesSum-0.1 : layoutFragment.columnSizesSum ), this.columns.length );
+                layoutHeaderColModelObj.layoutHeader = true;
+                this.columns.push( layoutHeaderColModelObj );
+                if ( parentColumn.columnChildren == null )
+                    parentColumn.columnChildren = new Array();
+                parentColumn.columnChildren.push( layoutHeaderColModelObj );
+                parentColumn = layoutHeaderColModelObj;
+                addedLayoutHeaderColumn = true;
+            }
+            
+            for ( var i = 0 ; i < layoutFragment.columnSizes.length ; i++ )
+            {
+                var size = layoutFragment.columnSizes[i];
+                if ( subOneLast && i == (layoutFragment.columnSizes.length - 1) )
+                    size = size - 0.1;
+                var colModelObj = new jetspeed.om.Column( i, layoutFragment.id, size, this.columns.length );
+                this.columns.push( colModelObj );
+                if ( parentColumn != null )
+                {
+                    if ( parentColumn.columnChildren == null )
+                        parentColumn.columnChildren = new Array();
+                    parentColumn.columnChildren.push( colModelObj );
+                }
+                columnsInLayout.push( colModelObj );
+            }
+        }
+        return { columnsInLayout: columnsInLayout, addedLayoutHeaderColumn: addedLayoutHeaderColumn };
+    },
+    _layoutCreatePortletsModel: function( layoutFragment, columnsInLayout, pageColumnStartIndex, portletsByPageColumn )
+    {
+        if ( layoutFragment.otherFragmentIndexes != null && layoutFragment.otherFragmentIndexes.length > 0 )
+        {
+            var portletsByColumn = new Array();    // for dispersing portlets when column specification is not valid
+            for ( var i = 0 ; i < columnsInLayout.length; i++ )
+            {
+                portletsByColumn.push( new Array() );
+            }
+            for ( var i = 0 ; i < layoutFragment.otherFragmentIndexes.length ; i++ )
+            {
+                var pFrag = layoutFragment.fragments[ layoutFragment.otherFragmentIndexes[i] ];
+    
+                if ( jetspeed.debugPortletEntityIdFilter )
+                {
+                    if ( ! dojo.lang.inArray( jetspeed.debugPortletEntityIdFilter, pFrag.id ) )
+                        pFrag = null;
+                }
+                
+                if ( pFrag != null )
+                {
+                    var portletPageColumnKey = "z";
+                    var portletWindowExtendedProperty = pFrag.properties[ jetspeed.id.PORTLET_PROP_DESKTOP_EXTENDED ];
+                    
+                    var portletWindowPositionStatic = jetspeed.prefs.windowTiling;
+                    var portletWindowHeightToFit = jetspeed.prefs.windowHeightExpand;
+                    if ( portletWindowExtendedProperty != null && jetspeed.prefs.windowTiling && jetspeed.prefs.printModeOnly == null )
+                    {
+                        var extPropData = portletWindowExtendedProperty.split( jetspeed.id.PORTLET_PROP_DESKTOP_EXTENDED_PAIR_SEPARATOR );
+                        var extProp = null, extPropLen = 0, extPropName = null, extPropValue = null, extPropFlag = false;
+                        if ( extPropData != null && extPropData.length > 0 )
+                        {
+                            var propSeparator = jetspeed.id.PORTLET_PROP_DESKTOP_EXTENDED_PROP_SEPARATOR;
+                            for ( var extPropIndex = 0 ; extPropIndex < extPropData.length ; extPropIndex++ )
+                            {
+                                extProp = extPropData[extPropIndex];
+                                extPropLen = ( ( extProp != null ) ? extProp.length : 0 );
+                                if ( extPropLen > 0 )
+                                {
+                                    var eqPos = extProp.indexOf( propSeparator );
+                                    if ( eqPos > 0 && eqPos < (extPropLen-1) )
+                                    {
+                                        extPropName = extProp.substring( 0, eqPos );
+                                        extPropValue = extProp.substring( eqPos +1 );
+                                        extPropFlag = ( ( extPropValue == "true" ) ? true : false );
+                                        if ( extPropName == jetspeed.id.PORTLET_PROP_DESKTOP_EXTENDED_STATICPOS )
+                                            portletWindowPositionStatic = extPropFlag;
+                                        else if ( extPropName == jetspeed.id.PORTLET_PROP_DESKTOP_EXTENDED_FITHEIGHT )
+                                            portletWindowHeightToFit = extPropFlag;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    else if ( ! jetspeed.prefs.windowTiling )
+                    {
+                        portletWindowPositionStatic = false;
+                    }
+                    pFrag.properties[ jetspeed.id.PORTLET_PROP_WINDOW_POSITION_STATIC ] = portletWindowPositionStatic;
+                    pFrag.properties[ jetspeed.id.PORTLET_PROP_WINDOW_HEIGHT_TO_FIT ] = portletWindowHeightToFit;
+                    
+                    if ( portletWindowPositionStatic && jetspeed.prefs.windowTiling )
+                    {
+                        var portletColumnIndex = pFrag.properties[ jetspeed.id.PORTLET_PROP_COLUMN ];
+                        if ( portletColumnIndex == null || portletColumnIndex == "" || portletColumnIndex < 0 || portletColumnIndex >= columnsInLayout.length )
+                        {
+                            var minPortlets = -1; 
+                            for ( var j = 0 ; j < columnsInLayout.length ; j++ )
+                            {
+                                if ( minPortlets == -1 || portletsByColumn[j].length < minPortlets )
+                                {
+                                    minPortlets = portletsByColumn[j].length;
+                                    portletColumnIndex = j;
+                                }
+                            }
+                        }
+                        portletsByColumn[portletColumnIndex].push( pFrag.id );
+                        var portletPageColumnIndex = pageColumnStartIndex + new Number( portletColumnIndex );
+                        portletPageColumnKey = portletPageColumnIndex.toString();
+                    }
+                    var portlet = new jetspeed.om.Portlet( pFrag.name, pFrag.id, null, pFrag.properties, pFrag.actions, pFrag.currentActionState, pFrag.currentActionMode, pFrag.decorator );
+                    portlet.initialize();
+
+                    this.putPortlet( portlet ) ;
+
+                    if ( portletsByPageColumn[ portletPageColumnKey ] == null )
+                    {
+                        portletsByPageColumn[ portletPageColumnKey ] = new Array();
+                    }
+                    portletsByPageColumn[ portletPageColumnKey ].push( { portlet: portlet, layout: layoutFragment.id } );
+                }
+            }
+        }
+    },
+
+    _portletsInitializeWindowState: function( /* Array */ portletsByPageColumnZ )
+    {
+        var initialColumnRowAllPortlets = {};
+        this.getPortletCurrentColumnRow( null, false, initialColumnRowAllPortlets );
+        for ( var portletIndex in this.portlets )
+        {
+            var portlet = this.portlets[portletIndex];
+            var portletInitialColRow = initialColumnRowAllPortlets[ portlet.getId() ];
+            if ( portletInitialColRow == null && portletsByPageColumnZ )
+            {
+                for ( var i = 0 ; i < portletsByPageColumnZ.length ; i++ )
+                {
+                    if ( portletsByPageColumnZ[i].portlet.getId() == portlet.getId() )
+                    {
+                        portletInitialColRow = { layout: portletsByPageColumnZ[i].layout };
+                        // NOTE: if portlet is put in tiling mode it should be placed in the bottom row of column 0 of layout
+                        break;
+                    }
+                }
+            }
+            if ( portletInitialColRow != null )
+                portlet._initializeWindowState( portletInitialColRow, false );
+            else
+                dojo.raise( "page._portletsInitializeWindowState could not find window state init data for portlet: " + portlet.getId() );
+        }
+    },
+
+    _loadPortletZIndexCompare: function( portletA, portletB )
+    {
+        var aZIndex = null;
+        var bZIndex = null;
+        var windowState = null;
+        aZIndex = portletA.portlet._getInitialZIndex();
+        bZIndex = portletB.portlet._getInitialZIndex();
+        if ( aZIndex && ! bZIndex )
+            return -1;
+        else if ( bZIndex && ! aZIndex )
+            return 1;
+        else if ( aZIndex == bZIndex )
+            return 0;
+        return ( aZIndex - bZIndex );
+    },
+
+    _createColumnsStart: function( allColumnsParent )
+    {
+        if ( ! this.columnsStructure || this.columnsStructure.length == 0 ) return;
+        var columnContainerNode = document.createElement( "div" );
+        columnContainerNode.id = jetspeed.id.COLUMNS;
+        columnContainerNode.setAttribute( "id", jetspeed.id.COLUMNS );
+        for ( var colIndex = 0 ; colIndex < this.columnsStructure.length ; colIndex++ )
+        {
+            var colObj = this.columnsStructure[colIndex];
+            this._createColumns( colObj, columnContainerNode ) ;
+        }
+        allColumnsParent.appendChild( columnContainerNode );
+    },
+
+    _createColumns: function( column, columnContainerNode )
+    {
+        column.createColumn() ;
+        if ( column.columnChildren != null && column.columnChildren.length > 0 )
+        {
+            for ( var colIndex = 0 ; colIndex < column.columnChildren.length ; colIndex++ )
+            {
+                var colObj = column.columnChildren[ colIndex ];
+                this._createColumns( colObj, column.domNode ) ;
+            }
+        }
+        columnContainerNode.appendChild( column.domNode );
+    },
+    _removeColumns: function( /* DOM Node */ preserveWindowNodesInNode )
+    {
+        if ( ! this.columns || this.columns.length == 0 ) return;
+        for ( var i = 0 ; i < this.columns.length ; i++ )
+        {
+            if ( this.columns[i] )
+            {
+                if ( preserveWindowNodesInNode )
+                {
+                    var windowNodesInColumn = jetspeed.ui.getPortletWindowChildren( this.columns[i].domNode, null );
+                    dojo.lang.forEach( windowNodesInColumn,
+                        function( windowNode ) { preserveWindowNodesInNode.appendChild( windowNode ); } );
+                }
+                dojo.dom.removeNode( this.columns[i] );
+                this.columns[i] = null;
+            }
+        }
+        var columnContainerNode = dojo.byId( jetspeed.id.COLUMNS );
+        if ( columnContainerNode )
+            dojo.dom.removeNode( columnContainerNode );
+        this.columns = [];
+    },
+
+    getPortletCurrentColumnRow: function( /* DOM node */ justForPortletWindowNode, /* boolean */ includeGhosts, /* map */ currentColumnRowAllPortlets )
+    {
+        if ( ! this.columns || this.columns.length == 0 ) return null;
+        var result = null;
+        var includeLayouts = ( ( justForPortletWindowNode != null ) ? true : false );
+        var clonedLayoutCompletedRowCount = 0;
+        var currentLayout = null;
+        var currentLayoutId = null;
+        var currentLayoutRowCount = 0;
+        var currentLayoutIsRegular = false;
+        for ( var colIndex = 0 ; colIndex < this.columns.length ; colIndex++ )
+        {
+            var colObj = this.columns[colIndex];
+            var colChildNodes = colObj.domNode.childNodes;
+            if ( currentLayoutId == null || currentLayoutId != colObj.getLayoutId() )
+            {
+                //if ( currentLayoutId != null && ! currentLayoutIsRegular )
+                //{
+                //    clonedLayoutCompletedRowCount = clonedLayoutCompletedRowCount + currentLayoutRowCount;
+                //}
+                currentLayoutId = colObj.getLayoutId();
+                currentLayout = this.layouts[ currentLayoutId ];
+                if ( currentLayout == null )
+                {
+                    dojo.raise( "getPortletCurrentColumnRow cannot locate layout id: " + currentLayoutId ) ;
+                    return null;
+                }
+                currentLayoutRowCount = 0;
+                currentLayoutIsRegular = false;
+                if ( currentLayout.clonedFromRootId == null )
+                {
+                    currentLayoutIsRegular = true ;
+                    //clonedLayoutCompletedRowCount = clonedLayoutCompletedRowCount + 1;
+                    // BOZO: should it ^^ be 0 if no portlets are contained in layout
+                }
+                else
+                {
+                    var parentColObj = this.getColumnFromColumnNode( colObj.domNode.parentNode );
+                    if ( parentColObj == null )
+                    {
+                        dojo.raise( "getPortletCurrentColumnRow cannot locate parent column for column: " + colObj ) ;
+                        return null;
+                    }
+                    colObj = parentColObj;
+                }
+            }
+
+            var colCurrentRow = null;
+            for ( var colChildIndex = 0 ; colChildIndex < colChildNodes.length ; colChildIndex++ )
+            {
+                var colChild = colChildNodes[colChildIndex];
+
+                if ( dojo.html.hasClass( colChild, jetspeed.id.PORTLET_WINDOW_STYLE_CLASS ) || ( includeGhosts && dojo.html.hasClass( colChild, jetspeed.id.PORTLET_WINDOW_GHOST_STYLE_CLASS ) ) || ( includeLayouts && dojo.html.hasClass( colChild, "desktopColumn" ) ) )
+                {
+                    colCurrentRow = ( colCurrentRow == null ? 0 : colCurrentRow + 1 );
+                    if ( (colCurrentRow + 1) > currentLayoutRowCount )
+                        currentLayoutRowCount = (colCurrentRow + 1);
+                    if ( justForPortletWindowNode == null || colChild == justForPortletWindowNode )
+                    {
+                        var portletResult = { layout: currentLayoutId, column: colObj.getLayoutColumnIndex(), row: colCurrentRow };
+                        if ( ! currentLayoutIsRegular )
+                        {
+                            portletResult.layout = currentLayout.clonedFromRootId;
+                            //portletResult.row = ( clonedLayoutCompletedRowCount + colCurrentRow );
+                        }
+                        if ( justForPortletWindowNode != null )
+                        {
+                            result = portletResult;
+                            break;
+                        }
+                        else if ( currentColumnRowAllPortlets != null )
+                        {
+                            var portletWindowWidget = this.getPortletWindowFromNode( colChild );
+                            if ( portletWindowWidget == null )
+                            {
+                                dojo.raise( "getPortletCurrentColumnRow cannot locate PortletWindow for node." ) ;

[... 2647 lines stripped ...]


---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org