PAL Portal (J2 デスクトップの調査)

jetspeed.loadPortletWindowsから見てみましょ。

jetspeed.loadPortletWindows = function( portletWindowFactory )
{
if ( jetspeed.prefs.windowTiling > 0 )
{
var numberOfColumns = jetspeed.page.getNumberOfColumns();
jetspeed.ui.createColumns( document.getElementById( jetspeed.id.DESKTOP ), numberOfColumns );
}
var windowsToRender = [];
var portletArray = jetspeed.page.getPortletArrayByColumnRow();
jetspeed.ui._loadPortletWindows( portletArray, windowsToRender, portletWindowFactory );
portletArray = jetspeed.page.getPortletArrayByZIndex();
jetspeed.ui._loadPortletWindows( portletArray, windowsToRender, portletWindowFactory );
if ( windowsToRender && windowsToRender.length > 0 )
{
jetspeed.doRenderAll( null, windowsToRender, true );
}
jetspeed.page.retrieveAllMenus();   // BOZO: should not be happening here!
};

あ、jetspeed.prefsについて、確認し忘れていたので、ここで確認しておこう。jetspeed.initializeDesktopから使っていたね・・・(^^;

jetspeed.prefs =
{
windowTiling: 2,     // number > 0 is interpreted as number of columns; 0 or false indicates no-columns, free-floating windows
windowTilingVariableWidth: false,   // only meaningful when windowTiling > 0
windowTilingVariableHeight: true,   // only meaningful when windowTiling > 0
//portalTaskBarType: "blee"  // BOZO: need pref/s to handle this ( instead of html elements in the content )
defaultPortletWidth: "280",
defaultPortletHeight: "200",
desktopTheme: null,
desktopThemeRootUrl: null,
getDesktopTheme: function()
{
if ( jetspeed.prefs.desktopTheme == null )
return djConfig.desktopTheme;
return jetspeed.prefs.desktopTheme;
},
getDesktopThemeRootUrl: function()
{
if ( jetspeed.prefs.desktopThemeRootUrl == null )
return djConfig.desktopThemeRootUrl;
return jetspeed.prefs.desktopThemeRootUrl;
},
portletSelectorWindowTitle: "Portlet Selector",
portletSelectorWindowIcon: "text-x-script.png",
portletSelectorBounds: { x: 20, y: 20, width: 400, height: 600 }
};

windowTilingにはデフォルトで2を与えているのね・・・。ポートレットの幅と高さもこんなところにあるな。

windowTilingは2だから、getNumberOfColumnsに入って、

getNumberOfColumns: function()
{
var numberOfColumns = 1;
if ( this.columns != null )
return this.columns;
var portletArray = this.getPortletArray();
if ( ! portletArray ) return portletArray;
var filteredPortletArray = [];
for ( var i = 0 ; i < portletArray.length; i++ )
{
if ( portletArray[i].getProperty( jetspeed.id.PORTLET_PROP_WINDOW_POSITION_STATIC ) )
{
var windowState = portletArray[i].getLastSavedWindowState();
if ( windowState && windowState.column != null && (windowState.column + 1) > numberOfColumns )
numberOfColumns = new Number( windowState.column ) + 1;
}
}
return numberOfColumns;
},

columnsはnullだから、下の処理にいって、ポートレットの配列の中から位置の固定のものをチェックしていくのね。ポートレットのgetLastSavedWindowState()は、

getLastSavedWindowState: function()
{
if ( ! this.lastSavedWindowState )
this._initializeWindowState();
return this.lastSavedWindowState;
},

で、lastSavedWindowStateはセットされていないから、_initializeWindowStateに行って、

_initializeWindowState: function( /* boolean */ reset )
{
var initialWindowState = {};
var windowPositionStatic = this.getProperty( jetspeed.id.PORTLET_PROP_WINDOW_POSITION_STATIC );
var portletWidth = this.getProperty( "width" );
if ( ! reset && portletWidth != null && portletWidth > 0 )
initialWindowState.width = Math.floor( portletWidth );
else if ( reset )
initialWindowState.width = -1;
var portletHeight = this.getProperty( "height" );
if ( ! reset && portletHeight != null && portletHeight > 0  )
initialWindowState.height = Math.floor( portletHeight );
else if ( reset )
initialWindowState.height = -1;
if ( ! windowPositionStatic )
{
var portletLeft = this.getProperty( "x" );
if ( ! reset && portletLeft != null && portletLeft >= 0 )
initialWindowState.left = Math.floor( ( (portletLeft > 0) ? portletLeft : 0 ) );
else if ( reset )
initialWindowState.left = -1;
var portletTop = this.getProperty( "y" );
if ( ! reset && portletTop != null && portletTop >= 0 )
initialWindowState.top = Math.floor( ( (portletTop > 0) ? portletTop : 0 ) );
else
initialWindowState.top = -1;
var portletZIndex = this.getProperty( "z" );
if ( ! reset && portletZIndex != null && portletZIndex >= 0 )
initialWindowState.zIndex = Math.floor( portletZIndex );
else if ( reset )
initialWindowState.zIndex = -1;
}
else
{
var portletColumn = this.getProperty( jetspeed.id.PORTLET_PROP_COLUMN );
initialWindowState.column = portletColumn;
var portletRow = this.getProperty( jetspeed.id.PORTLET_PROP_ROW );
initialWindowState.row = portletRow;
}
if ( jetspeed.debug.initializeWindowState )
{
if ( ! windowPositionStatic )
dojo.debug( "initializeWindowState [" + this.entityId + "] z=" + initialWindowState.zIndex + " x=" + initialWindowState.left + " y=" + initialWindowState.top + " width=" + initialWindowState.width + " height=" + initialWindowState.height );
else
dojo.debug( "initializeWindowState [" + this.entityId + "] column=" + initialWindowState.column + " row=" + initialWindowState.row + " width=" + initialWindowState.width + " height=" + initialWindowState.height );
}
this.lastSavedWindowState = initialWindowState;
return initialWindowState;
},

何の処理かを見ると、高さと幅をセットして、場所が固定であれば、行と列をセットし、そうでなければ、x,y,z の位置情報をセットする。値は、initialWindowStateに保持するのね。まぁ、最後の方のはデバッグで表示するかだな。そんで、lastSavedWindowStateにもコピーしておくのだね。っでgetNumberOfColumnsに戻る。

getNumberOfColumnsのwindowStateは、ポートレットウィンドウの場所情報のinitialWindowStateが入って、getNumberOfColumnsよりwindowState.column+1が大きかったら、getNumberOfColumnsにwindowState.column+1を入れるのね。はて、なぜ、+1 より大きくする必要があるのだろうか?単純に column の最大値が入れば良さそうな気もするけど。ループの比較で使うからかな??

引き続き見ていくと、

if ( jetspeed.prefs.windowTiling > 0 )
{
var numberOfColumns = jetspeed.page.getNumberOfColumns();
jetspeed.ui.createColumns( document.getElementById( jetspeed.id.DESKTOP ), numberOfColumns );
}

だから、numberOfColumns に得た値を入れて、createColumns で、まず、columnsParent にドキュメント上の id がjetspeedDesktopとなっている要素を渡している。たとえば、blue.jspを見ると以下のような感じ。

<div class="<%= desktopThemeStyleClass %>" id="jetspeedDesktop"></div>

そんで、2番目のcolumnTotalにはさっき取得したnumberOfColumnsが入って、

jetspeed.ui.createColumns = function( columnsParent, columnTotal )
{
if ( columnTotal > 0 )
{
jetspeed.columns = new Array( columnTotal );
var columnContainer = document.createElement( "div" );
columnContainer.id = jetspeed.id.COLUMNS;
for ( var i = 0 ; i < columnTotal ; i++ )
{
jetspeed.ui.createColumn( columnContainer, i, columnTotal );
}
columnsParent.appendChild( columnContainer );
}
};

jetspeed.columnsの配列を作って、jetspeedDesktopをidとして持つタグに対して、div タグで id にjetspeed.id.COLUMNS(値はjetspeedColumns)をセットしたタグを最終的にappendChildで貼り付けるのね。ループ内のcreateColumnを見てみると、

jetspeed.ui.createColumn = function( columnContainer, columnIndex, columnTotal )
{
var divElmt = document.createElement("div");
divElmt.setAttribute("columnIndex", columnIndex);
var colWidthPctg = Math.round(100/columnTotal);
if ( columnIndex == (columnTotal-1) && ( (columnTotal * colWidthPctg) >= 100 ) )
colWidthPctg = colWidthPctg -1;
divElmt.style.width = colWidthPctg + "%";
divElmt.style.minHeight = "1px";
divElmt.className = "DesktopColumn";
jetspeed.columns[columnIndex]  = divElmt;
columnContainer.appendChild(divElmt);
//divElmt.appendChild( document.createTextNode( "LayoutColumn" + (columnIndex +1) ) );
};

div タグを作って、columnIndex属性に0から始める番号を与えて、100をcolumnTotalで割った値を%として、幅として与える。そんで、そのタグのクラス名にDesktopColumnを与えて、jetspeed.columns配列に入れておく(操作しやすいようにかね)。そんで、先ほど作った、親の div タグに貼り付ける。というわけで、ここまでで、表示するためのレイアウトとなるタグを表示するHTMLに貼り付けたわけだね。そして、jetspeed.loadPortletWindowsにもどる。

var windowsToRender = [];
var portletArray = jetspeed.page.getPortletArrayByColumnRow();

次の処理は、getPortletArrayByColumnRowで

getPortletArrayByColumnRow: function()
{
var portletArray = this.getPortletArray();
if ( ! portletArray ) return portletArray;
var filteredPortletArray = [];
for ( var i = 0 ; i < portletArray.length; i++ )
{
var posStatic = portletArray[i].getProperty( jetspeed.id.PORTLET_PROP_WINDOW_POSITION_STATIC );
var colSpan = portletArray[i].getProperty( jetspeed.id.PORTLET_PROP_COLUMN_SPAN );
if ( posStatic || colSpan != null )
{
filteredPortletArray.push( portletArray[i] );
}
}
filteredPortletArray.sort( this._portletColumnRowCompare );
return filteredPortletArray;
},

ここでは、登録されたポートレット配列で列情報をもち、場所が固定じゃないものをfilteredPortletArray配列に入れていき、入れ終わったところで、sortを実行。その比較の際に使われるのが、

_portletColumnRowCompare: function( portletA, portletB )
{   // uses saved state only - does not check with window widget
var windowState = portletA.getLastSavedWindowState();
var col = ( windowState.column == null ? 50 : windowState.column );
var row = ( windowState.row == null ? 0 : windowState.row );
var aVal = ( col * 1000 ) + row;
windowState = portletB.getLastSavedWindowState();
col = ( windowState.column == null ? 50 : windowState.column );
row = ( windowState.row == null ? 0 : windowState.row );
var bVal = ( col * 1000 ) + row;
return ( aVal - bVal );
},

で、( col * 1000 ) + row というのが比較の際の基準だね。ソートして、jetspeed.loadPortletWindowsに戻って、portletArrayにその配列を渡す。

次は、

jetspeed.ui._loadPortletWindows( portletArray, windowsToRender, portletWindowFactory );

で、windowsToRenderは空の配列で、portletWindowsFactoryはnullかね。

今日はここまで・・・。

コメントを残す

メールアドレスが公開されることはありません。