From c272c42c07e164647f9a9d74036f3ee6d478676d Mon Sep 17 00:00:00 2001 From: "Jason Y. Lee" Date: Wed, 16 Aug 2017 04:01:42 -0700 Subject: [PATCH 1/2] Fixing index.php and removing ^M characters --- assets/help_viewer.css | 34 +- assets/mod-treeview.css | 34 +- assets/msg-viewer.html | 800 +- assets/msg_sniffer.css | 166 +- assets/msg_snifferIE6.css | 40 +- assets/new-treeview.css | 208 +- assets/tree.css | 206 +- help/admin.htm | 2 +- help/assets/help.css | 60 +- help/i2b2Style.css | 2338 +-- help/tqt.html | 4716 +++--- i2b2 license 2.1-1159.txt | 112 +- index.php | 422 +- js-ext/YUI_DataTable_MD5CellEditor.js | 1064 +- js-ext/YUI_DataTable_PasswordCellEditor.js | 286 +- js-ext/excanvas-License.txt | 104 +- js-ext/excanvas.js | 1570 +- js-ext/firebug-License.txt | 938 +- js-ext/firebug/firebug-lite-compressed.js | 234 +- js-ext/firebug/firebug-lite.css | 426 +- js-ext/firebug/firebug-lite.js | 5036 +++---- js-ext/firebug/firebugx.js | 18 +- ...oConflict() _ jQuery API Documentation.htm | 1492 +- js-ext/jquerycode/jquery.layout-latest.js | 12150 ++++++++-------- js-ext/prototype-License.txt | 30 +- js-ext/yui-License.txt | 48 +- js-ext/yui/README | 612 +- js-i2b2/cells/CRC/assets/main_list.css | 26 +- js-i2b2/cells/CRC/assets/menu.css | 14 +- js-i2b2/cells/CRC/assets/modLabValues.css | 102 +- js-i2b2/cells/CRC/assets/sdx_CRC_PR.css | 52 +- js-i2b2/cells/CRC/assets/sdx_CRC_PRC.css | 52 +- js-i2b2/cells/CRC/assets/sdx_CRC_PRS.css | 52 +- js-i2b2/cells/CRC/assets/sdx_CRC_QDEF.css | 52 +- js-i2b2/cells/CRC/assets/sdx_CRC_QGDEF.css | 52 +- js-i2b2/cells/CRC/assets/sdx_CRC_QI.css | 52 +- js-i2b2/cells/CRC/assets/sdx_CRC_QM.css | 54 +- js-i2b2/cells/ONT/assets/main_list.css | 4 +- .../PLUGINMGR/PLUGINMGR_ctrlr_general.js | 368 +- js-i2b2/cells/PLUGINMGR/assets/main_list.css | 4 +- js-i2b2/cells/PLUGINMGR/assets/vwList.css | 310 +- js-i2b2/cells/PLUGINMGR/cell_config_data.js | 46 +- js-i2b2/cells/PM/assets/modProjects.css | 378 +- js-i2b2/cells/WORK/assets/main_list.css | 4 +- js-i2b2/cells/WORK/assets/sdx_WORK_XML.css | 52 +- js-i2b2/cells/WORK/assets/vwWork.css | 60 +- js-i2b2/cells/WORK/cell_config_data.js | 38 +- .../standard/Dem1Set/cell_config_data.js | 50 +- .../standard/Dem2Set/cell_config_data.js | 50 +- js-i2b2/hive/hive.ui.js | 342 +- js-i2b2/hive/hive_config_data.js | 32 +- js-i2b2/hive/master_view_ctrlr.js | 288 +- js-i2b2/hive/msg_sniffer.js | 334 +- js-i2b2/ui.styles/ui.styles.css | 40 +- 54 files changed, 18027 insertions(+), 18027 deletions(-) diff --git a/assets/help_viewer.css b/assets/help_viewer.css index fcff1179..d421830b 100755 --- a/assets/help_viewer.css +++ b/assets/help_viewer.css @@ -1,18 +1,18 @@ -#help-viewer-panel .bd { - overflow:auto; - background-color:fff; - padding:10px; -} - -#help-viewer-panel .ft { - height:15px; - padding:0; -} - -#help-viewer-panel .yui-resize-handle-br { - right:0; - bottom:0; - height: 8px; - width: 8px; - position:absolute; +#help-viewer-panel .bd { + overflow:auto; + background-color:fff; + padding:10px; +} + +#help-viewer-panel .ft { + height:15px; + padding:0; +} + +#help-viewer-panel .yui-resize-handle-br { + right:0; + bottom:0; + height: 8px; + width: 8px; + position:absolute; } \ No newline at end of file diff --git a/assets/mod-treeview.css b/assets/mod-treeview.css index fbbb3228..9b49ee7f 100755 --- a/assets/mod-treeview.css +++ b/assets/mod-treeview.css @@ -1,17 +1,17 @@ - -.ygtvtn, .ygtvtm, .ygtvtmh, -.ygtvtp, .ygtvtph, .ygtvln, -.ygtvlm, .ygtvlmh, .ygtvlp, -.ygtvlph, .ygtvloading, .ygtvdepthcell, -.ygtvblankdepthcell { - width:16px !important; - height:18px !important; -} - -.ygtvspacer { - height: 10px !important; - width: 10px !important; - margin:0px 4px !important; - text-decoration: none !important; - display: block; -} + +.ygtvtn, .ygtvtm, .ygtvtmh, +.ygtvtp, .ygtvtph, .ygtvln, +.ygtvlm, .ygtvlmh, .ygtvlp, +.ygtvlph, .ygtvloading, .ygtvdepthcell, +.ygtvblankdepthcell { + width:16px !important; + height:18px !important; +} + +.ygtvspacer { + height: 10px !important; + width: 10px !important; + margin:0px 4px !important; + text-decoration: none !important; + display: block; +} diff --git a/assets/msg-viewer.html b/assets/msg-viewer.html index d7475068..20739c36 100755 --- a/assets/msg-viewer.html +++ b/assets/msg-viewer.html @@ -1,401 +1,401 @@ - - - - Message Log - - - - - - - -
-
-
- - - - -
- - -
- -
-
- - -
- -
- -
- - + + + + Message Log + + + + + + + +
+
+
+ + + + +
+ + +
+ +
+
+ + +
+ +
+ +
+ + \ No newline at end of file diff --git a/assets/msg_sniffer.css b/assets/msg_sniffer.css index f89c6b2c..5016b574 100755 --- a/assets/msg_sniffer.css +++ b/assets/msg_sniffer.css @@ -1,83 +1,83 @@ -#commViewerSingleMsg-body PRE.msgXML.msgSent { - border-left: 8px solid #FFAFAF; - padding: 4px; -} - -#commViewerSingleMsg-body PRE.msgXML.msgReceive { - border-left: 8px solid #AFFFAF; - padding: 4px; -} - - -BODY.msgSnifferViewer { - margin:0px; - padding:0px; - background:#BCE -} - -BODY.msgSnifferViewer DIV.IndexRecord { - font-size:10px !important; - clear:both; - padding:2px; - cursor: pointer; - width:250px; -} - -BODY.msgSnifferViewer DIV.IndexRecord.selected { background-color: #FFD } - -BODY.msgSnifferViewer DIV.msgChan, -BODY.msgSnifferViewer DIV.msgAction, -BODY.msgSnifferViewer DIV.msgOrigin, -BODY.msgSnifferViewer DIV.msgTime, -{ - line-height: 10px; - font-size: 10px !important; -} - -BODY.msgSnifferViewer DIV.recvStatus, -BODY.msgSnifferViewer DIV.sentStatus { - height: 12px; - width:22px; - float: left; - border: 1px solid #000; - text-align: center; - line-height:10px; - font-size:10px; -} - -BODY.msgSnifferViewer DIV.sentStatus { - background: #E99; - border-bottom: none; -} -BODY.msgSnifferViewer DIV.recvStatus { - background: #9E9; - clear:both; -} - - -BODY.msgSnifferViewer DIV.msgXML { - background:#FFFFFF; - border:1px solid #678; - border-top:none; - xheight:100%; - xoverflow:scroll; - xwidth:100%; -} -BODY.msgSnifferViewer pre.msgXML { - border-left:8px solid; - padding:4px; -} -BODY.msgSnifferViewer pre.msgXML.msgSent { - border-color:#FFAFAF; -} -BODY.msgSnifferViewer pre.msgXML.msgRcvd { - border-color:#AFFFAF; -} - -BODY.msgSnifferViewer DIV.recvStatus.msgError { - background:#FFFF90 !important; -} - -body.msgSnifferViewer pre.msgXML.msgError { - border-color:#FFFF90 !important; -} +#commViewerSingleMsg-body PRE.msgXML.msgSent { + border-left: 8px solid #FFAFAF; + padding: 4px; +} + +#commViewerSingleMsg-body PRE.msgXML.msgReceive { + border-left: 8px solid #AFFFAF; + padding: 4px; +} + + +BODY.msgSnifferViewer { + margin:0px; + padding:0px; + background:#BCE +} + +BODY.msgSnifferViewer DIV.IndexRecord { + font-size:10px !important; + clear:both; + padding:2px; + cursor: pointer; + width:250px; +} + +BODY.msgSnifferViewer DIV.IndexRecord.selected { background-color: #FFD } + +BODY.msgSnifferViewer DIV.msgChan, +BODY.msgSnifferViewer DIV.msgAction, +BODY.msgSnifferViewer DIV.msgOrigin, +BODY.msgSnifferViewer DIV.msgTime, +{ + line-height: 10px; + font-size: 10px !important; +} + +BODY.msgSnifferViewer DIV.recvStatus, +BODY.msgSnifferViewer DIV.sentStatus { + height: 12px; + width:22px; + float: left; + border: 1px solid #000; + text-align: center; + line-height:10px; + font-size:10px; +} + +BODY.msgSnifferViewer DIV.sentStatus { + background: #E99; + border-bottom: none; +} +BODY.msgSnifferViewer DIV.recvStatus { + background: #9E9; + clear:both; +} + + +BODY.msgSnifferViewer DIV.msgXML { + background:#FFFFFF; + border:1px solid #678; + border-top:none; + xheight:100%; + xoverflow:scroll; + xwidth:100%; +} +BODY.msgSnifferViewer pre.msgXML { + border-left:8px solid; + padding:4px; +} +BODY.msgSnifferViewer pre.msgXML.msgSent { + border-color:#FFAFAF; +} +BODY.msgSnifferViewer pre.msgXML.msgRcvd { + border-color:#AFFFAF; +} + +BODY.msgSnifferViewer DIV.recvStatus.msgError { + background:#FFFF90 !important; +} + +body.msgSnifferViewer pre.msgXML.msgError { + border-color:#FFFF90 !important; +} diff --git a/assets/msg_snifferIE6.css b/assets/msg_snifferIE6.css index af4933d8..d1758fd0 100755 --- a/assets/msg_snifferIE6.css +++ b/assets/msg_snifferIE6.css @@ -1,21 +1,21 @@ -DIV#sniffer_Filters { - width: 722px !important; -} -DIV#sniffer_MatchMsgDisp { - height: 448px !important; - top: 30px !important; - width: 472px !important; -} -DIV#sniffer_MatchMsgList { - height: 448px !important; - top: 30px !important; -} - -DIV#sniffer_ListButtons { - top: 441px !important; - height: 36px !important; -} - -TBODY TR TD { - font-size: 10px !important; +DIV#sniffer_Filters { + width: 722px !important; +} +DIV#sniffer_MatchMsgDisp { + height: 448px !important; + top: 30px !important; + width: 472px !important; +} +DIV#sniffer_MatchMsgList { + height: 448px !important; + top: 30px !important; +} + +DIV#sniffer_ListButtons { + top: 441px !important; + height: 36px !important; +} + +TBODY TR TD { + font-size: 10px !important; } \ No newline at end of file diff --git a/assets/new-treeview.css b/assets/new-treeview.css index 205c9e4e..931230b2 100755 --- a/assets/new-treeview.css +++ b/assets/new-treeview.css @@ -1,104 +1,104 @@ -/* -Copyright (c) 2008, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.5.1 -*/ -/* first or middle sibling, no children */ - -.ygtvtn { - width:16px; height:18px; - background: url(sprite-orig.gif) 0 -5600px no-repeat; -} - -/* first or middle sibling, collapsable */ -.ygtvtm { - width:16px; height:18px; - cursor:pointer ; - background: url(sprite-orig.gif) 0 -4000px no-repeat; -} - -/* first or middle sibling, collapsable, hover */ -.ygtvtmh { - width:16px; height:18px; - cursor:pointer ; - background: url(sprite-orig.gif) 0 -4800px no-repeat; -} - -/* first or middle sibling, expandable */ -.ygtvtp { - width:16px; height:18px; - cursor:pointer ; - background: url(sprite-orig.gif) 0 -6400px no-repeat; -} - -/* first or middle sibling, expandable, hover */ -.ygtvtph { - width:16px; height:18px; - cursor:pointer ; - background: url(sprite-orig.gif) 0 -7200px no-repeat; -} - -/* last sibling, no children */ -.ygtvln { - width:16px; height:18px; - background: url(sprite-orig.gif) 0 -1600px no-repeat; -} - -/* Last sibling, collapsable */ -.ygtvlm { - width:16px; height:18px; - cursor:pointer ; - background: url(sprite-orig.gif) 0 0px no-repeat; -} - -/* Last sibling, collapsable, hover */ -.ygtvlmh { - width:16px; height:18px; - cursor:pointer ; - background: url(sprite-orig.gif) 0 -800px no-repeat; -} - -/* Last sibling, expandable */ -.ygtvlp { - width:16px; height:18px; - cursor:pointer ; - background: url(sprite-orig.gif) 0 -2400px no-repeat; -} - -/* Last sibling, expandable, hover */ -.ygtvlph { - width:16px; height:18px; cursor:pointer ; - background: url(sprite-orig.gif) 0 -3200px no-repeat; -} - -/* Loading icon */ -.ygtvloading { - width:16px; height:18px; cursor:pointer ; - background: url(treeview-loading.gif) 0 0 no-repeat; -} - -/* the style for the empty cells that are used for rendering the depth - * of the node */ -.ygtvdepthcell { - width:16px; height:18px; - background: url(sprite-orig.gif) 0 -8000px no-repeat; -} - -.ygtvblankdepthcell { width:16px; height:18px; } - -/* the style of the div around each node */ -.ygtvitem { } - -/* the style of the div around each node's collection of children */ -.ygtvchildren { } -* html .ygtvchildren { height:2%; } - -/* the style of the text label in ygTextNode */ -.ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover { - margin-left:2px; - text-decoration: none; - background-color: white; /* workaround for IE font smoothing bug */ -} - -.ygtvspacer { height: 10px; width: 10px; margin: 2px; } +/* +Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.5.1 +*/ +/* first or middle sibling, no children */ + +.ygtvtn { + width:16px; height:18px; + background: url(sprite-orig.gif) 0 -5600px no-repeat; +} + +/* first or middle sibling, collapsable */ +.ygtvtm { + width:16px; height:18px; + cursor:pointer ; + background: url(sprite-orig.gif) 0 -4000px no-repeat; +} + +/* first or middle sibling, collapsable, hover */ +.ygtvtmh { + width:16px; height:18px; + cursor:pointer ; + background: url(sprite-orig.gif) 0 -4800px no-repeat; +} + +/* first or middle sibling, expandable */ +.ygtvtp { + width:16px; height:18px; + cursor:pointer ; + background: url(sprite-orig.gif) 0 -6400px no-repeat; +} + +/* first or middle sibling, expandable, hover */ +.ygtvtph { + width:16px; height:18px; + cursor:pointer ; + background: url(sprite-orig.gif) 0 -7200px no-repeat; +} + +/* last sibling, no children */ +.ygtvln { + width:16px; height:18px; + background: url(sprite-orig.gif) 0 -1600px no-repeat; +} + +/* Last sibling, collapsable */ +.ygtvlm { + width:16px; height:18px; + cursor:pointer ; + background: url(sprite-orig.gif) 0 0px no-repeat; +} + +/* Last sibling, collapsable, hover */ +.ygtvlmh { + width:16px; height:18px; + cursor:pointer ; + background: url(sprite-orig.gif) 0 -800px no-repeat; +} + +/* Last sibling, expandable */ +.ygtvlp { + width:16px; height:18px; + cursor:pointer ; + background: url(sprite-orig.gif) 0 -2400px no-repeat; +} + +/* Last sibling, expandable, hover */ +.ygtvlph { + width:16px; height:18px; cursor:pointer ; + background: url(sprite-orig.gif) 0 -3200px no-repeat; +} + +/* Loading icon */ +.ygtvloading { + width:16px; height:18px; cursor:pointer ; + background: url(treeview-loading.gif) 0 0 no-repeat; +} + +/* the style for the empty cells that are used for rendering the depth + * of the node */ +.ygtvdepthcell { + width:16px; height:18px; + background: url(sprite-orig.gif) 0 -8000px no-repeat; +} + +.ygtvblankdepthcell { width:16px; height:18px; } + +/* the style of the div around each node */ +.ygtvitem { } + +/* the style of the div around each node's collection of children */ +.ygtvchildren { } +* html .ygtvchildren { height:2%; } + +/* the style of the text label in ygTextNode */ +.ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover { + margin-left:2px; + text-decoration: none; + background-color: white; /* workaround for IE font smoothing bug */ +} + +.ygtvspacer { height: 10px; width: 10px; margin: 2px; } diff --git a/assets/tree.css b/assets/tree.css index 334236d3..c712c1b5 100755 --- a/assets/tree.css +++ b/assets/tree.css @@ -1,103 +1,103 @@ -/* -Copyright (c) 2006, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.com/yui/license.txt -Version: 0.11.3 -*/ - -/* first or middle sibling, no children */ -.ygtvtn { - width:16px; height:18px; - background: url('yui/build/treeview/assets/tn.gif') 0 0 no-repeat; -} - -/* first or middle sibling, collapsable */ -.ygtvtm { - width:16px; height:18px; - cursor:pointer ; - background: url('yui/build/treeview/assets/tm.gif') 0 0 no-repeat; -} - -/* first or middle sibling, collapsable, hover */ -.ygtvtmh { - width:16px; height:18px; - cursor:pointer ; - background: url('yui/build/treeview/assets/tmh.gif') 0 0 no-repeat; -} - -/* first or middle sibling, expandable */ -.ygtvtp { - width:16px; height:18px; - cursor:pointer ; - background: url('yui/build/treeview/assets/tp.gif') 0 0 no-repeat; -} - -/* first or middle sibling, expandable, hover */ -.ygtvtph { - width:16px; height:18px; - cursor:pointer ; - background: url('yui/build/treeview/assets/tph.gif') 0 0 no-repeat; -} - -/* last sibling, no children */ -.ygtvln { - width:16px; height:18px; - background: url('yui/build/treeview/assets/ln.gif') 0 0 no-repeat; -} - -/* Last sibling, collapsable */ -.ygtvlm { - width:16px; height:18px; - cursor:pointer ; - background: url('yui/build/treeview/assets/lm.gif') 0 0 no-repeat; -} - -/* Last sibling, collapsable, hover */ -.ygtvlmh { - width:16px; height:18px; - cursor:pointer ; - background: url('yui/build/treeview/assets/lmh.gif') 0 0 no-repeat; -} - -/* Last sibling, expandable */ -.ygtvlp { - width:16px; height:18px; - cursor:pointer ; - background: url('yui/build/treeview/assets/lp.gif') 0 0 no-repeat; -} - -/* Last sibling, expandable, hover */ -.ygtvlph { - width:16px; height:18px; cursor:pointer ; - background: url('yui/build/treeview/assets/lph.gif') 0 0 no-repeat; -} - -/* Loading icon */ -.ygtvloading { - width:16px; height:18px; - background: url('yui/build/treeview/assets/loading.gif') 0 0 no-repeat; -} - -/* the style for the empty cells that are used for rendering the depth - * of the node */ -.ygtvdepthcell { - width:16px; height:18px; - background: url('yui/build/treeview/assets/vline.gif') 0 0 no-repeat; -} - -.ygtvblankdepthcell { width:16px; height:18px; } - -/* the style of the div around each node */ -.ygtvitem { } - -/* the style of the div around each node's collection of children */ -.ygtvchildren { } -* html .ygtvchildren { height:2%; } - -/* the style of the text label in ygTextNode */ -.ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover { - margin-left:2px; - text-decoration: none; -} - -.ygtvspacer { height: 10px; width: 10px; margin: 2px; } +/* +Copyright (c) 2006, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.txt +Version: 0.11.3 +*/ + +/* first or middle sibling, no children */ +.ygtvtn { + width:16px; height:18px; + background: url('yui/build/treeview/assets/tn.gif') 0 0 no-repeat; +} + +/* first or middle sibling, collapsable */ +.ygtvtm { + width:16px; height:18px; + cursor:pointer ; + background: url('yui/build/treeview/assets/tm.gif') 0 0 no-repeat; +} + +/* first or middle sibling, collapsable, hover */ +.ygtvtmh { + width:16px; height:18px; + cursor:pointer ; + background: url('yui/build/treeview/assets/tmh.gif') 0 0 no-repeat; +} + +/* first or middle sibling, expandable */ +.ygtvtp { + width:16px; height:18px; + cursor:pointer ; + background: url('yui/build/treeview/assets/tp.gif') 0 0 no-repeat; +} + +/* first or middle sibling, expandable, hover */ +.ygtvtph { + width:16px; height:18px; + cursor:pointer ; + background: url('yui/build/treeview/assets/tph.gif') 0 0 no-repeat; +} + +/* last sibling, no children */ +.ygtvln { + width:16px; height:18px; + background: url('yui/build/treeview/assets/ln.gif') 0 0 no-repeat; +} + +/* Last sibling, collapsable */ +.ygtvlm { + width:16px; height:18px; + cursor:pointer ; + background: url('yui/build/treeview/assets/lm.gif') 0 0 no-repeat; +} + +/* Last sibling, collapsable, hover */ +.ygtvlmh { + width:16px; height:18px; + cursor:pointer ; + background: url('yui/build/treeview/assets/lmh.gif') 0 0 no-repeat; +} + +/* Last sibling, expandable */ +.ygtvlp { + width:16px; height:18px; + cursor:pointer ; + background: url('yui/build/treeview/assets/lp.gif') 0 0 no-repeat; +} + +/* Last sibling, expandable, hover */ +.ygtvlph { + width:16px; height:18px; cursor:pointer ; + background: url('yui/build/treeview/assets/lph.gif') 0 0 no-repeat; +} + +/* Loading icon */ +.ygtvloading { + width:16px; height:18px; + background: url('yui/build/treeview/assets/loading.gif') 0 0 no-repeat; +} + +/* the style for the empty cells that are used for rendering the depth + * of the node */ +.ygtvdepthcell { + width:16px; height:18px; + background: url('yui/build/treeview/assets/vline.gif') 0 0 no-repeat; +} + +.ygtvblankdepthcell { width:16px; height:18px; } + +/* the style of the div around each node */ +.ygtvitem { } + +/* the style of the div around each node's collection of children */ +.ygtvchildren { } +* html .ygtvchildren { height:2%; } + +/* the style of the text label in ygTextNode */ +.ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover { + margin-left:2px; + text-decoration: none; +} + +.ygtvspacer { height: 10px; width: 10px; margin: 2px; } diff --git a/help/admin.htm b/help/admin.htm index 03448e29..4d90b690 100755 --- a/help/admin.htm +++ b/help/admin.htm @@ -1 +1 @@ -

 

i2b2 Administration

Welcome to the i2b2 Administration module of the project management interface.

The pages within i2b2 Admin are designed to assist with workflow and overall ease of use, individuals can easily save data and parameters for the hive, projects and users.

 

 

Manage Hive

View domain information and capture cell data and global parameters.

Manage Project

General information about the project as well as project specific cell data, parameters, and user access and roles.

Manage Users

General information about a user.

Manage Approvals

Captures general information used to authorize projects.

Project Requests

View information about submitted project requests.

 

The navigation bar on the left side of the page can be used to access individual pages.

 

Table of Contents

 

Introduction

Logging on to the admin application

Navigation Bar

Pages

Page Heading

Setup

Global Setup

Global Parameters

Users Setup

User Data

User Parameters

User Project Roles

Hive Setup

Hive Data

Hive Parameters

Cell Data

Cell Parameters

Project Setup

Project Data

Project Parameters

Project Users

Project User Roles

Project User Parameters

 

 

Introduction

Logging on to the admin application

 

Go to the site http://jbossHost/admin

 

1.    You will see a login screen.  Log in with a user you know has ADMIN role.

 

For those installing for the first time, use the default ADMIN user of ‘i2b2’ and password of ‘demouser’.



 

 

 

2.    Once logged on you will be presented with the admin setup page. You should see the following:


 

 

 

3.    Click the ‘Hive” in the PM Navigation. This is where you can modify the domain, cells and global parameters. Click on ‘Domain’ to see the domain information.

 

 

 

Navigation Bar

A navigation bar will remain on the left side of all the pages. This can be used if a user wants to quickly access a particular page.

 

Figure 1 Navigation Bar

 

 

Pages

Individual pages will be used to capture information throughout the project management module. These pages will be specific to the data that is collected.

 

Page Heading

At the top of each page will be a tab that contains the name of the page and its location.

 

In the example shown below, the heading tells us the user is on the project parameters page for the “demo” project.

 

Figure 2 Page Heading

 

 

Setup

To assist with workflow and overall ease of use, individuals will now be able to easily save data and parameters for the hive, projects and users.  An outline of what can be stored in the PM database and the related functionality is listed below.

 

Global Setup

In i2b2 Project Management, global data refers to information that is not specific to any one hive, project, or user. The information setup here is used by all.

 

Global Parameters

      Parameters that are to be used by all hives and projects will be defined in the global parameters page.

      The data will be stored in the PM_GLOBAL_PARAMS table.

 

Figure 3 Global Parameters Page

 

 

Users Setup

In order to use the i2b2 application a user has to be setup in project management and given access to one or many projects.  In addition, variables can be setup for a user that can be used across multiple projects or specific to one project.

 

User Data

      General information about the user will be stored in the PM_USER_DATA table.

      The user_id will be referenced in other tables such as PM_USER_PARAMS and PM_PROJECT_USER_ROLES.

 

Figure 4 User Data Page

 

 

User Parameters

      Parameters entered here are specific to the user and are not specific to any one project.

      The information will be stored in the PM_USER_PARAMS table.

 

Figure 5 User Parameters Section

 

 

User Project Roles

      The project user page captures information regarding which users have access to the project and their role.

      The information will be stored in the PM_PROJECT_USER_ROLES table. 

 

     Detailed information about user roles can be found in the project section of this document.

 

 

Hive Setup

 

 

Hive Data

      The domain page captures general information about the hive.

      Information captured includes the domain id, domain name, environment, and help URL.

      The information will be stored in the PM_HIVE_DATA table.

 

Figure 6 Hive Data (Domain) Page

 

 

Hive Parameters

      Parameters entered here are specific to the hive (domain) and are not specific to any one project or user.

      The hive parameters can be added from the hive (domain) data page. Once you click on the domain an additional section for entering the parameters will appear at the bottom of the page.

      The information will be stored in the PM_HIVE_PARAMS table.

 

Figure 7 Hive Parameters Section

 

 

Cell Data

      The cell data page captures information and registers the cells associated to the hive.

      The information will be stored in the PM_CELL_DATA table.

 

Figure 8 Cells Data Page

 

 

Cell Parameters

      Parameters entered here are specific to the cell and are not specific to any one project or user.

      The cell parameters can be added from the cell data page. Once you click on a cell an additional section for entering the parameters will appear at the bottom of the page.

      The information will be stored in the PM_CELL_PARAMS table.

 

Figure 9 Cell Parameters Section

 

 

Project Setup

A hive can have multiple projects setup.

 

Project Data

      The project data page captures general information about the project.

      The information will be stored in the PM_PROJECT_DATA table.

 

Figure 10 Project Data Page

 

 

Project Parameters

      Parameters entered here are specific to the project.

      The project parameters can be added from the project parameters page.

      The information will be stored in the PM_PROJECT_PARAMS table.

 

Figure 11 Project Parameters Page

 

 

Project Users

      The project users’ page captures information regarding which users have access to the project and their role.  (see the next section for detailed information regarding roles)

      The information will be stored in the PM_PROJECT_USER_ROLES table. 

 

Figure 12 Project Users Page

 

 

Project User Roles

Each user will have at least two roles per user_id and product_id combination.  These two roles can be further defined as a Data Protection role and a Hive Management role.

 

The data protection role/path establishes the detail of data the user can see while the hive management role/path defines their level of functionality the user has in a project.

 

 

Data Protection Track

 

Role

Access Description

DATA_OBFSC

 

OBFSC = Obfuscated

The user can see aggregated results that are obfuscated (example: patient count).

The user is limited on the number of times they can run the same query within a specified time period.  If the user exceeds the maximum number of times then their account will be locked and only the Admin user can unlock it.

DATA_AGG

 

AGG = Aggregated

The user can see aggregated results like the patient count.

The results are not obfuscated and the user is not limited to the number of times they can run the same query.

DATA_LDS

 

LDS = Limited Data Set

The user can see all fields except for those that are encrypted.

An example of an encrypted field is the blob fields in the fact and dimension tables.

DATA_DEID

 

DEID = De-identified Data

The user can see all fields including those that are encrypted.

An example of an encrypted field is the blob fields in the fact and dimension tables.

DATA_PROT

PROT = Protected

The user can see all data, including the identified data that resides in the Identity Management Cell.

 

 

 

Hive Management Track

 

Role

Access Description

USER

Can create queries and access them if he/she is the owner of the query.

MANAGER

Can create queries and can access queries created by different users within the project.

ADMIN

Can see anything in the Hive except identified data.

 

 

     Additional roles can be added to the PM_PROJECT_USER_ROLES table but there will not be any recognized hierarchy to those roles.

 

 

Project User Parameters

      Parameters entered here are specific to the user and the project.

      The project’s user parameters can be added from the project users’ page. Once you click on a project an additional section for entering the user parameters will appear at the bottom of the page.

      The information will be stored in the PM_PROJECT_USER_PARAMS table.

 

Figure 13 Project Users Parameters Section

 

 

 

 

+

 

i2b2 Administration

Welcome to the i2b2 Administration module of the project management interface.

The pages within i2b2 Admin are designed to assist with workflow and overall ease of use, individuals can easily save data and parameters for the hive, projects and users.

 

 

Manage Hive

View domain information and capture cell data and global parameters.

Manage Project

General information about the project as well as project specific cell data, parameters, and user access and roles.

Manage Users

General information about a user.

Manage Approvals

Captures general information used to authorize projects.

Project Requests

View information about submitted project requests.

 

The navigation bar on the left side of the page can be used to access individual pages.

 

Table of Contents

 

Introduction

Logging on to the admin application

Navigation Bar

Pages

Page Heading

Setup

Global Setup

Global Parameters

Users Setup

User Data

User Parameters

User Project Roles

Hive Setup

Hive Data

Hive Parameters

Cell Data

Cell Parameters

Project Setup

Project Data

Project Parameters

Project Users

Project User Roles

Project User Parameters

 

 

Introduction

Logging on to the admin application

 

Go to the site http://jbossHost/admin

 

1.    You will see a login screen.  Log in with a user you know has ADMIN role.

 

For those installing for the first time, use the default ADMIN user of ‘i2b2’ and password of ‘demouser’.



 

 

 

2.    Once logged on you will be presented with the admin setup page. You should see the following:


 

 

 

3.    Click the ‘Hive” in the PM Navigation. This is where you can modify the domain, cells and global parameters. Click on ‘Domain’ to see the domain information.

 

 

 

Navigation Bar

A navigation bar will remain on the left side of all the pages. This can be used if a user wants to quickly access a particular page.

 

Figure 1 Navigation Bar

 

 

Pages

Individual pages will be used to capture information throughout the project management module. These pages will be specific to the data that is collected.

 

Page Heading

At the top of each page will be a tab that contains the name of the page and its location.

 

In the example shown below, the heading tells us the user is on the project parameters page for the “demo” project.

 

Figure 2 Page Heading

 

 

Setup

To assist with workflow and overall ease of use, individuals will now be able to easily save data and parameters for the hive, projects and users.  An outline of what can be stored in the PM database and the related functionality is listed below.

 

Global Setup

In i2b2 Project Management, global data refers to information that is not specific to any one hive, project, or user. The information setup here is used by all.

 

Global Parameters

      Parameters that are to be used by all hives and projects will be defined in the global parameters page.

      The data will be stored in the PM_GLOBAL_PARAMS table.

 

Figure 3 Global Parameters Page

 

 

Users Setup

In order to use the i2b2 application a user has to be setup in project management and given access to one or many projects.  In addition, variables can be setup for a user that can be used across multiple projects or specific to one project.

 

User Data

      General information about the user will be stored in the PM_USER_DATA table.

      The user_id will be referenced in other tables such as PM_USER_PARAMS and PM_PROJECT_USER_ROLES.

 

Figure 4 User Data Page

 

 

User Parameters

      Parameters entered here are specific to the user and are not specific to any one project.

      The information will be stored in the PM_USER_PARAMS table.

 

Figure 5 User Parameters Section

 

 

User Project Roles

      The project user page captures information regarding which users have access to the project and their role.

      The information will be stored in the PM_PROJECT_USER_ROLES table. 

 

     Detailed information about user roles can be found in the project section of this document.

 

 

Hive Setup

 

 

Hive Data

      The domain page captures general information about the hive.

      Information captured includes the domain id, domain name, environment, and help URL.

      The information will be stored in the PM_HIVE_DATA table.

 

Figure 6 Hive Data (Domain) Page

 

 

Hive Parameters

      Parameters entered here are specific to the hive (domain) and are not specific to any one project or user.

      The hive parameters can be added from the hive (domain) data page. Once you click on the domain an additional section for entering the parameters will appear at the bottom of the page.

      The information will be stored in the PM_HIVE_PARAMS table.

 

Figure 7 Hive Parameters Section

 

 

Cell Data

      The cell data page captures information and registers the cells associated to the hive.

      The information will be stored in the PM_CELL_DATA table.

 

Figure 8 Cells Data Page

 

 

Cell Parameters

      Parameters entered here are specific to the cell and are not specific to any one project or user.

      The cell parameters can be added from the cell data page. Once you click on a cell an additional section for entering the parameters will appear at the bottom of the page.

      The information will be stored in the PM_CELL_PARAMS table.

 

Figure 9 Cell Parameters Section

 

 

Project Setup

A hive can have multiple projects setup.

 

Project Data

      The project data page captures general information about the project.

      The information will be stored in the PM_PROJECT_DATA table.

 

Figure 10 Project Data Page

 

 

Project Parameters

      Parameters entered here are specific to the project.

      The project parameters can be added from the project parameters page.

      The information will be stored in the PM_PROJECT_PARAMS table.

 

Figure 11 Project Parameters Page

 

 

Project Users

      The project users’ page captures information regarding which users have access to the project and their role.  (see the next section for detailed information regarding roles)

      The information will be stored in the PM_PROJECT_USER_ROLES table. 

 

Figure 12 Project Users Page

 

 

Project User Roles

Each user will have at least two roles per user_id and product_id combination.  These two roles can be further defined as a Data Protection role and a Hive Management role.

 

The data protection role/path establishes the detail of data the user can see while the hive management role/path defines their level of functionality the user has in a project.

 

 

Data Protection Track

 

Role

Access Description

DATA_OBFSC

 

OBFSC = Obfuscated

The user can see aggregated results that are obfuscated (example: patient count).

The user is limited on the number of times they can run the same query within a specified time period.  If the user exceeds the maximum number of times then their account will be locked and only the Admin user can unlock it.

DATA_AGG

 

AGG = Aggregated

The user can see aggregated results like the patient count.

The results are not obfuscated and the user is not limited to the number of times they can run the same query.

DATA_LDS

 

LDS = Limited Data Set

The user can see all fields except for those that are encrypted.

An example of an encrypted field is the blob fields in the fact and dimension tables.

DATA_DEID

 

DEID = De-identified Data

The user can see all fields including those that are encrypted.

An example of an encrypted field is the blob fields in the fact and dimension tables.

DATA_PROT

PROT = Protected

The user can see all data, including the identified data that resides in the Identity Management Cell.

 

 

 

Hive Management Track

 

Role

Access Description

USER

Can create queries and access them if he/she is the owner of the query.

MANAGER

Can create queries and can access queries created by different users within the project.

ADMIN

Can see anything in the Hive except identified data.

 

 

     Additional roles can be added to the PM_PROJECT_USER_ROLES table but there will not be any recognized hierarchy to those roles.

 

 

Project User Parameters

      Parameters entered here are specific to the user and the project.

      The project’s user parameters can be added from the project users’ page. Once you click on a project an additional section for entering the user parameters will appear at the bottom of the page.

      The information will be stored in the PM_PROJECT_USER_PARAMS table.

 

Figure 13 Project Users Parameters Section

 

 

 

 

diff --git a/help/assets/help.css b/help/assets/help.css index d35565e5..ed042f7a 100755 --- a/help/assets/help.css +++ b/help/assets/help.css @@ -1,31 +1,31 @@ -#help-viewer-body { - color: #333; - background-color: #FFF; -} -#help-viewer-body h1 { - color: #4E5B82; - font-size:18px; - font-weight:bold; - padding:0; - margin:0; -} -#help-viewer-body h2 { - color: #4E5B82; - font-size:15px; - font-weight:bold; - padding:0; - margin:15px 0 10px 0; -} -#help-viewer-body h3 { - font-size:12px; - font-weight:bold; - padding:0; - margin:15px 0 10px 0; -} -#help-viewer-body a { - color: #4E5B82; -} -#help-viewer-body .view { - color: #4E5B82; - font-weight:bold; +#help-viewer-body { + color: #333; + background-color: #FFF; +} +#help-viewer-body h1 { + color: #4E5B82; + font-size:18px; + font-weight:bold; + padding:0; + margin:0; +} +#help-viewer-body h2 { + color: #4E5B82; + font-size:15px; + font-weight:bold; + padding:0; + margin:15px 0 10px 0; +} +#help-viewer-body h3 { + font-size:12px; + font-weight:bold; + padding:0; + margin:15px 0 10px 0; +} +#help-viewer-body a { + color: #4E5B82; +} +#help-viewer-body .view { + color: #4E5B82; + font-weight:bold; } \ No newline at end of file diff --git a/help/i2b2Style.css b/help/i2b2Style.css index 51373d5a..66a73fe4 100755 --- a/help/i2b2Style.css +++ b/help/i2b2Style.css @@ -1,1170 +1,1170 @@ -@charset "UTF-8"; -/* CSS Document */ - -p { - margin:0in; - margin-bottom:.0001pt; - font-size:11.0pt; - font-family:Calibri; -} -p.docTitle, li.docTitle, div.docTitle { - margin-top:12.0pt; - margin-right:0in; - margin-bottom:12.0pt; - margin-left:0in; - font-size:20.0pt; - font-family:Calibri; - text-transform:uppercase; - font-weight:bold; -} -h1 { - margin-top:12.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:0in; - margin-bottom:.0001pt; - page-break-after:avoid; - font-size:16.0pt; - font-family:Cambria; - color:#365F91; - text-transform:uppercase; - font-weight:bold; -} -h2 { - margin-top:12.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:0in; - margin-bottom:.0001pt; - page-break-after:avoid; - border:none; - padding:0in; - font-size:16.0pt; - font-family:Cambria; - color:#365F91; - font-weight:bold; -} -h3 { - margin-top:10.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:0in; - margin-bottom:.0001pt; - page-break-after:avoid; - font-size:14.0pt; - font-family:Cambria; - font-weight:bold; -} -h4 { - margin-top:10.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:0in; - margin-bottom:.0001pt; - page-break-after:avoid; - font-size:14.0pt; - font-family:Cambria; - font-weight:normal; -} -h5 { - margin-top:10.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:0in; - margin-bottom:.0001pt; - page-break-after:avoid; - font-size:12.0pt; - font-family:Cambria; - font-variant:small-caps; - font-weight:bold; - font-style:italic; -} -h6 { - margin-top:10.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:0in; - margin-bottom:.0001pt; - font-size:12.0pt; - font-family:Cambria; - font-weight:bold; -} -address { - margin:0in; - margin-bottom:.0001pt; - font-size:11.0pt; - font-family:Calibri; - font-style:italic; -} -a:link, span.Hyperlink { - color:blue; - text-decoration:underline; -} -a:visited, span.HyperlinkFollowed { - color:purple; - text-decoration:underline; -} -p.Caption, li.Caption, div.Caption { - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:10.0pt; - font-family:Calibri; - font-weight:bold; -} -code { - margin-top:3.0pt; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:.75in; - font-size:9.0pt; - font-family:Verdana; -} -kbd { - font-family:Calibri; -} -pre { - margin:0in; - margin-bottom:.0001pt; - font-size:10.0pt; - font-family:Calibri; -} -samp { - font-family:Calibri; -} -tt { - font-family:Calibri; -} -p.ImportantHeading, li.ImportantHeading, div.ImportantHeading { - margin-top:6px; - margin-right:0in; - margin-bottom:0px; - margin-left:0.25in; - text-indent:0in; - font-size:11.0pt; - font-family:Calibri; - color:#000080; - font-weight:bold; - font-style:italic; -} - -p.NoteHeading, li.NoteHeading, div.NoteHeading { - margin-top:6px; - margin-right:0in; - margin-bottom:0px; - margin-left:0.25in; - text-indent:0in; - font-size:11.0pt; - font-family:Calibri; - color:#000080; - font-weight:bold; - font-style:italic; -} - -p.TipHeading, li.TipHeading, div.TipHeading { - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:0.25in; - margin-bottom:.0001pt; - text-indent:0in; - font-size:11.0pt; - font-family:Calibri; - color:#3E4D1F; - font-style:italic; -} -p.WarningHeading, li.WarningHeading, div.WarningHeading { - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:0.25in; - margin-bottom:.0001pt; - text-indent:0in; - font-size:11.0pt; - font-family:Calibri; - color:#FF0000; - font-style:italic; -} - -p.ImportantParagraph, li.ImportantParagraph, div.ImportantParagraph { - margin-top:6px; - margin-right:0in; - margin-bottom:6.0px; - margin-left:0.25in; - text-indent:0in; - font-size:11pt; - font-family:Calibri; - font-style:italic; -} - -p.NoteParagraph, li.NoteParagraph, div.NoteParagraph { - margin-top:6px; - margin-right:0in; - margin-bottom:6.0px; - margin-left:0.25in; - text-indent:0in; - font-size:11pt; - font-family:Calibri; - font-style:italic; -} - - -p.TipParagraph, li.TipParagraph, div.TipParagraph { - margin-top:6px; - margin-right:0in; - margin-bottom:6.0px; - margin-left:0.25in; - text-indent:0in; - font-size:11pt; - font-family:Calibri; - font-style:italic; -} - - -p.WarningParagraph, li.WarningParagraph, div.WarningParagraph { - margin-top:6px; - margin-right:0in; - margin-bottom:6.0px; - margin-left:0.25in; - text-indent:0in; - font-size:11pt; - font-family:Calibri; - font-style:italic; -} - - -p.VersionDoc, li.VersionDoc, div.VersionDoc { - margin-top:3.0pt; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:0in; - text-align:right; - font-size:9.0pt; - font-family:Calibri; - font-style:italic; -} - @page Section1 { - size:8.5in 11.0in; - margin:1.0in 1.0in 1.0in 1.0in; -} -div.Section1 { - page:Section1; -} -/* Tables */ - -Table { - margin:0in; - margin-bottom:.0001pt; - font-size:8.0pt; - font-family:Verdana -} - -#important { - border:1.0pt; - border-style:solid; - border-collapse:collapse; - border-color: #DBD600; - background-color: #FFFFEB; - margin-top:12.0pt; - margin-left:.5in -} - -#note { - border:1.0pt; - border-style:solid; - border-collapse:collapse; - border-color: #365F91; - background-color: #E5EEF7; - margin-top:12.0pt; - margin-left:.5in; -} - -#tip { - border:1.0pt; - border-style:solid; - border-collapse:collapse; - border-color: #3E4D1F; - background-color: #E5FFE5; - margin-top:12.0pt; - margin-left:.5in; -} - -#warning { - border:1.0pt; - border-style:solid; - border-collapse:collapse; - border-color: #FF0000; - background-color: #F6E6E6; - margin-top:12.0pt; - margin-left:.5in; -} - - - -td, th { - padding-top:12pt; - padding-right:15.0pt; - padding-bottom:12.0pt; - padding-left:5.4pt - -} - - -/* Table of Contents */ - -p.TocHeading, li.TocHeading, div.TocHeading { - margin-top:12.0pt; - margin-right:0in; - margin-bottom:12.0pt; - margin-left:0in; - border:none; - padding:0in; - font-size:12.0pt; - font-family:Helvetica; - font-weight:bold; -} -p.Toc1, li.Toc1, div.Toc1 { - margin:0in; - margin-bottom:.0001pt; - font-size:14.0pt; - font-family:Calibri; -} -p.Toc2, li.Toc2, div.Toc2 { - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:12.0pt; - margin-bottom:.0001pt; - font-size:12.0pt; - font-family:Calibri; -} -p.Toc3, li.Toc3, div.Toc3 { - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:24.0pt; - margin-bottom:.0001pt; - font-size:11.0pt; - font-family:Calibri; -} -p.Toc4, li.Toc4, div.Toc4 { - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:.5in; - margin-bottom:.0001pt; - font-size:11.0pt; - font-family:Calibri; -} -p.Toc5, li.Toc5, div.Toc5 { - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:48.0pt; - margin-bottom:.0001pt; - font-size:11.0pt; - font-family:Calibri; -} -p.Toc6, li.Toc6, div.Toc6 { - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:60.0pt; - margin-bottom:.0001pt; - font-size:11.0pt; - font-family:Calibri; -} -/* List Definitions */ -ol { - margin-top:6pt; - margin-right:0in; - margin-bottom:6pt; - margin-left:0.25in; - text-indent:.30in; - font-size:11pt; - font-family:Calibri; -} -ul { - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:0.25in; - margin-bottom:0.0001pt; - text-indent:.3in; - font-size:11pt; - font-family:Calibri; -} - -h3 - {margin-right:0in; - margin-left:0in; - font-size:13.5pt; - font-family:"Times New Roman","serif"; - font-weight:bold;} -h4 - {margin-top:12.0pt; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:14.0pt; - font-family:"Times New Roman","serif"; - font-weight:bold;} -p.MsoIndex1, li.MsoIndex1, div.MsoIndex1 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:12.0pt; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndex2, li.MsoIndex2, div.MsoIndex2 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:24.0pt; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndex3, li.MsoIndex3, div.MsoIndex3 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:.5in; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndex4, li.MsoIndex4, div.MsoIndex4 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:48.0pt; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndex5, li.MsoIndex5, div.MsoIndex5 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:60.0pt; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndex6, li.MsoIndex6, div.MsoIndex6 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:1.0in; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndex7, li.MsoIndex7, div.MsoIndex7 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:84.0pt; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndex8, li.MsoIndex8, div.MsoIndex8 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:96.0pt; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndex9, li.MsoIndex9, div.MsoIndex9 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:1.5in; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoToc1, li.MsoToc1, div.MsoToc1 - {margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:10.0pt; - font-family:"Times New Roman","serif"; - text-transform:uppercase; - font-weight:bold;} -p.MsoToc2, li.MsoToc2, div.MsoToc2 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:12.0pt; - margin-bottom:.0001pt; - font-size:10.0pt; - font-family:"Times New Roman","serif"; - font-variant:small-caps;} -p.MsoToc3, li.MsoToc3, div.MsoToc3 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:24.0pt; - margin-bottom:.0001pt; - font-size:10.0pt; - font-family:"Times New Roman","serif"; - font-style:italic;} -p.MsoToc4, li.MsoToc4, div.MsoToc4 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:.5in; - margin-bottom:.0001pt; - font-size:9.0pt; - font-family:"Times New Roman","serif";} -p.MsoToc5, li.MsoToc5, div.MsoToc5 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:48.0pt; - margin-bottom:.0001pt; - font-size:9.0pt; - font-family:"Times New Roman","serif";} -p.MsoToc6, li.MsoToc6, div.MsoToc6 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:60.0pt; - margin-bottom:.0001pt; - font-size:9.0pt; - font-family:"Times New Roman","serif";} -p.MsoToc7, li.MsoToc7, div.MsoToc7 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:1.0in; - margin-bottom:.0001pt; - font-size:9.0pt; - font-family:"Times New Roman","serif";} -p.MsoToc8, li.MsoToc8, div.MsoToc8 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:84.0pt; - margin-bottom:.0001pt; - font-size:9.0pt; - font-family:"Times New Roman","serif";} -p.MsoToc9, li.MsoToc9, div.MsoToc9 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:96.0pt; - margin-bottom:.0001pt; - font-size:9.0pt; - font-family:"Times New Roman","serif";} -p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText - {margin:0in; - margin-bottom:.0001pt; - font-size:10.0pt; - font-family:"Arial","sans-serif";} -p.MsoCommentText, li.MsoCommentText, div.MsoCommentText - {margin:0in; - margin-bottom:.0001pt; - font-size:10.0pt; - font-family:"Arial","sans-serif";} -p.MsoHeader, li.MsoHeader, div.MsoHeader - {margin:0in; - margin-bottom:.0001pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoFooter, li.MsoFooter, div.MsoFooter - {margin:0in; - margin-bottom:.0001pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoIndexHeading, li.MsoIndexHeading, div.MsoIndexHeading - {margin:0in; - margin-bottom:.0001pt; - font-size:12.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -p.MsoCaption, li.MsoCaption, div.MsoCaption - {margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.25in; - font-size:10.0pt; - font-family:"Calibri","sans-serif"; - font-weight:bold;} -p.MsoTof, li.MsoTof, div.MsoTof - {margin:0in; - margin-bottom:.0001pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -span.MsoFootnoteReference - {vertical-align:super;} -span.MsoEndnoteReference - {vertical-align:super;} -p.MsoEndnoteText, li.MsoEndnoteText, div.MsoEndnoteText - {margin:0in; - margin-bottom:.0001pt; - font-size:10.0pt; - font-family:"Arial","sans-serif";} -p.MsoToa, li.MsoToa, div.MsoToa - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:12.0pt; - margin-bottom:.0001pt; - text-indent:-12.0pt; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoMacroText, li.MsoMacroText, div.MsoMacroText - {margin:0in; - margin-bottom:.0001pt; - font-size:10.0pt; - font-family:"Courier New";} -p.MsoToaHeading, li.MsoToaHeading, div.MsoToaHeading - {margin-top:6.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:0in; - margin-bottom:.0001pt; - font-size:12.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -p.MsoListBullet2, li.MsoListBullet2, div.MsoListBullet2 - {margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:.55in; - margin-bottom:.0001pt; - text-indent:-.1in; - font-size:12.0pt; - font-family:"Arial","sans-serif";} -p.MsoTitle, li.MsoTitle, div.MsoTitle - {margin-top:12.0pt; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:0in; - text-align:center; - font-size:16.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -a:link, span.MsoHyperlink - {color:blue; - text-decoration:underline;} -a:visited, span.MsoHyperlinkFollowed - {color:purple; - text-decoration:underline;} -p.MsoDocumentMap, li.MsoDocumentMap, div.MsoDocumentMap - {margin:0in; - margin-bottom:.0001pt; - background:navy; - font-size:10.0pt; - font-family:"Tahoma","sans-serif";} -p - {margin-right:0in; - margin-left:0in; - font-size:12.0pt; - font-family:"Times New Roman","serif";} -tt - {font-family:"Courier New";} -p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject - {margin:0in; - margin-bottom:.0001pt; - font-size:10.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -p.MsoAcetate, li.MsoAcetate, div.MsoAcetate - {margin:0in; - margin-bottom:.0001pt; - font-size:8.0pt; - font-family:"Tahoma","sans-serif";} -p.jdheading1, li.jdheading1, div.jdheading1 - {mso-style-name:"jd heading 1"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:18.0pt; - font-family:"Arial","sans-serif"; - color:navy; - font-weight:bold;} -p.jdnormal, li.jdnormal, div.jdnormal - {mso-style-name:"jd normal"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - line-height:150%; - font-size:11.0pt; - font-family:"Arial","sans-serif";} -p.jdchapternumber, li.jdchapternumber, div.jdchapternumber - {mso-style-name:"jd chapter number"; - margin:0in; - margin-bottom:.0001pt; - text-align:right; - font-size:72.0pt; - font-family:"Arial","sans-serif"; - color:navy; - font-weight:bold;} -p.jdchapterheading, li.jdchapterheading, div.jdchapterheading - {mso-style-name:"jd chapter heading"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:12.0pt; - margin-left:0in; - text-align:right; - line-height:150%; - page-break-after:avoid; - border:none; - padding:0in; - font-size:18.0pt; - font-family:"Arial","sans-serif"; - color:navy; - font-weight:bold;} -p.jdheading2, li.jdheading2, div.jdheading2 - {mso-style-name:"jd heading 2"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:14.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -p.jdheading3, li.jdheading3, div.jdheading3 - {mso-style-name:"jd heading 3"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:12.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -p.jdtable, li.jdtable, div.jdtable - {mso-style-name:"jd table"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:10.0pt; - font-family:"Arial","sans-serif";} -p.jdnormalindent1, li.jdnormalindent1, div.jdnormalindent1 - {mso-style-name:"jd normal indent 1"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.25in; - line-height:150%; - font-size:11.0pt; - font-family:"Arial","sans-serif";} -p.jdlistnumbers1, li.jdlistnumbers1, div.jdlistnumbers1 - {mso-style-name:"jd list numbers 1"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.5in; - text-indent:-.25in; - line-height:150%; - font-size:11.0pt; - font-family:"Arial","sans-serif";} -p.BulletedListJD, li.BulletedListJD, div.BulletedListJD - {mso-style-name:"Bulleted List JD"; - margin-top:0in; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:11.0pt; - font-family:"Arial","sans-serif";} -p.Normal2, li.Normal2, div.Normal2 - {mso-style-name:"Normal 2"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:0in; - margin-bottom:.0001pt; - line-height:150%; - font-size:11.0pt; - font-family:"Arial","sans-serif";} -p.NormalIndent1, li.NormalIndent1, div.NormalIndent1 - {mso-style-name:"Normal Indent 1"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:.5in; - margin-bottom:.0001pt; - line-height:150%; - font-size:11.0pt; - font-family:"Arial","sans-serif";} -p.StyleBulletedListJDArial11pt, li.StyleBulletedListJDArial11pt, div.StyleBulletedListJDArial11pt - {mso-style-name:"Style Bulleted List JD + Arial 11 pt"; - margin-top:0in; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:11.0pt; - font-family:"Arial","sans-serif";} -p.StyleHeading1Right, li.StyleHeading1Right, div.StyleHeading1Right - {mso-style-name:"Style Heading 1 + Right"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:0in; - text-align:right; - page-break-after:avoid; - font-size:18.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -p.StyleHeading412pt, li.StyleHeading412pt, div.StyleHeading412pt - {mso-style-name:"Style Heading 4 + 12 pt"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:12.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -p.Style1, li.Style1, div.Style1 - {mso-style-name:Style1; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - border:none; - padding:0in; - font-size:18.0pt; - font-family:"Arial","sans-serif"; - color:navy; - font-weight:bold;} -p.SuperTitle, li.SuperTitle, div.SuperTitle - {mso-style-name:SuperTitle; - margin-top:48.0pt; - margin-right:0in; - margin-bottom:0in; - margin-left:1.0in; - margin-bottom:.0001pt; - text-align:right; - border:none; - padding:0in; - font-size:14.0pt; - font-family:"Arial","sans-serif"; - font-weight:bold;} -p.jdwebheading1, li.jdwebheading1, div.jdwebheading1 - {mso-style-name:"jd web heading 1"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:14.0pt; - font-family:"Calibri","sans-serif"; - font-weight:bold;} -p.jdwebheading2, li.jdwebheading2, div.jdwebheading2 - {mso-style-name:"jd web heading 2"; - margin-top:10.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - border:none; - padding:0in; - font-size:14.0pt; - font-family:"Cambria","serif"; - color:#365F91;} -p.jdwebheading3, li.jdwebheading3, div.jdwebheading3 - { - margin-top:10.0pt; - margin-right:0in; - margin-bottom:0; - margin-left:0in; - font-size:12.0pt; - font-family:"Cambria","serif";} -p.jdwebnormal, li.jdwebnormal, div.jdwebnormal { - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.25in; - font-size:11.0pt;} -p.jdwebheading4, li.jdwebheading4, div.jdwebheading4 { - margin-top:10.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:10.0pt; - text-transform:uppercase;} -p.jdwebfiguretitle, li.jdwebfiguretitle, div.jdwebfiguretitle { - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:10.0pt; - font-weight:bold;} -p.jdwebheading5, li.jdwebheading5, div.jdwebheading5{ - margin-top:10.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:10.0pt; - font-weight:bold;} -p.jdwebtable, li.jdwebtable, div.jdwebtable - { - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:10.0pt; - font-family:"Calibri","sans-serif";} -p.jdwebchapterheading, li.jdwebchapterheading, div.jdwebchapterheading - {mso-style-name:"jd web chapter heading"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:14.0pt; - font-family:"Helvetica","sans-serif"; - font-weight:bold;} -p.jdwebbullets, li.jdwebbullets, div.jdwebbullets - {mso-style-name:"jd web bullets"; - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:1.0in; - margin-bottom:.0001pt; - text-indent:-.25in; - line-height:150%; - font-size:11.0pt; - font-family:"Calibri","sans-serif";} -p.jdweblistnumbers, li.jdweblistnumbers, div.jdweblistnumbers - {mso-style-name:"jd web list numbers"; - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:.5in; - margin-bottom:.0001pt; - text-indent:-.25in; - line-height:150%; - font-size:11.0pt;} -p.jdwebheading7, li.jdwebheading7, div.jdwebheading7 - {mso-style-name:"jd web heading 7"; - margin-top:10.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:9.0pt; - font-family:"Cambria","serif"; - text-transform:uppercase;} -p.jdwebheading8, li.jdwebheading8, div.jdwebheading8 - {mso-style-name:"jd web heading 8"; - margin-top:10.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:9.0pt; - text-transform:uppercase; - font-style:italic; - text-decoration:underline;} -p.jdwebtablelistnumber, li.jdwebtablelistnumber, div.jdwebtablelistnumber - {mso-style-name:"jd web table list number"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.15in; - text-indent:-.15in; - font-size:10.0pt;} -p.jdwebemphasis, li.jdwebemphasis, div.jdwebemphasis - {mso-style-name:"jd web emphasis"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.25in; - font-size:11.0pt; - font-style:italic;} -p.jdwebfiguredescription, li.jdwebfiguredescription, div.jdwebfiguredescription - {mso-style-name:"jd web figure description"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:10.0pt;} -p.StylejdwebfiguretitleNotBold, li.StylejdwebfiguretitleNotBold, div.StylejdwebfiguretitleNotBold - { - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - font-size:10.0pt;} -p.jdwebheading6, li.jdwebheading6, div.jdwebheading6 - { - margin-top:10.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:0in; - page-break-after:avoid; - font-size:10.0pt; - text-decoration:underline;} -p.jdwebnormalindent, li.jdwebnormalindent, div.jdwebnormalindent - { - margin-top:6.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.5in; - font-size:11.0pt;} -p.Stylejdlistnumbers1CalibriBefore0ptAfter0pt, li.Stylejdlistnumbers1CalibriBefore0ptAfter0pt, div.Stylejdlistnumbers1CalibriBefore0ptAfter0pt - { - margin:0in; - margin-bottom:.0001pt; - line-height:150%; - font-size:11.0pt;} -p.jdweblistbullet, li.jdweblistbullet, div.jdweblistbullet - {mso-style-name:"jd web list bullet"; - margin-top:0in; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:.75in; - text-indent:-.25in; - font-size:11.0pt; - font-family:"Calibri","sans-serif";} -p.StylejdwebnormalLeft05, li.StylejdwebnormalLeft05, div.StylejdwebnormalLeft05 - {mso-style-name:"Style jd web normal + Left\: 0\.5\0022"; - margin-top:0in; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.5in; - font-size:11.0pt; - font-family:"Calibri","sans-serif";} -p.jdtocheading, li.jdtocheading, div.jdtocheading - {mso-style-name:"jd toc heading"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:12.0pt; - margin-left:0in; - page-break-after:avoid; - border:none; - padding:0in; - font-size:12.0pt; - font-family:"Helvetica","sans-serif"; - font-weight:bold;} -p.Stylejdweblistnumbersindent, li.Stylejdweblistnumbersindent, div.Stylejdweblistnumbersindent - {mso-style-name:"Style jd web list numbers indent"; - margin:0in; - margin-bottom:.0001pt; - line-height:150%; - font-size:11.0pt; - font-family:"Calibri","sans-serif";} -p.jdweblistletters, li.jdweblistletters, div.jdweblistletters - {mso-style-name:"jd web list letters"; - margin-top:0in; - margin-right:0in; - margin-bottom:0in; - margin-left:1.0in; - margin-bottom:.0001pt; - text-indent:-.25in; - font-size:11.0pt; - font-family:"Calibri","sans-serif";} -span.jdwebnormalChar - {mso-style-name:"jd web normal Char"; - mso-style-link:"jd web normal"; - font-family:"Calibri","sans-serif";} -span.jdwebfiguretitleChar - {mso-style-name:"jd web figure title Char"; - mso-style-link:"jd web figure title"; - font-family:"Calibri","sans-serif"; - font-weight:bold;} -span.StylejdwebfiguretitleNotBoldChar - {mso-style-name:"Style jd web figure title + Not Bold Char"; - mso-style-link:"Style jd web figure title + Not Bold"; - font-family:"Calibri","sans-serif"; - font-weight:bold;} -span.Heading1Char - {mso-style-name:"Heading 1 Char"; - mso-style-link:"Heading 1"; - font-family:"Arial","sans-serif"; - font-weight:bold;} -span.Heading2Char - {mso-style-name:"Heading 2 Char"; - mso-style-link:"Heading 2"; - font-family:"Arial","sans-serif"; - font-weight:bold; - font-style:italic;} -p.jddoclistnumbers1, li.jddoclistnumbers1, div.jddoclistnumbers1 - {mso-style-name:"jd doc list numbers 1"; - margin-top:6.0pt; - margin-right:0in; - margin-bottom:10.0pt; - margin-left:.5in; - text-indent:-.25in; - line-height:115%; - font-size:12.0pt; - font-family:"Calibri","sans-serif";} -p.jddoclistnumbers2, li.jddoclistnumbers2, div.jddoclistnumbers2 - {mso-style-name:"jd doc list numbers 2"; - margin-top:3.0pt; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:1.0in; - text-indent:-.25in; - line-height:115%; - font-size:12.0pt; - font-family:"Calibri","sans-serif";} -p.jddocheading1outline, li.jddocheading1outline, div.jddocheading1outline - {mso-style-name:"jd doc heading 1 outline"; - margin-top:12.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.5in; - text-indent:-.5in; - page-break-before:always; - page-break-after:avoid; - font-size:14.0pt; - font-family:"Calibri","sans-serif"; - text-transform:uppercase; - font-weight:bold;} -p.jddocheading2outline, li.jddocheading2outline, div.jddocheading2outline - {mso-style-name:"jd doc heading 2 outline"; - margin-top:10.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:44.85pt; - text-indent:-44.85pt; - page-break-after:avoid; - font-size:14.0pt; - font-family:"Cambria","serif"; - color:#365F91;} -p.jddocheading3outline, li.jddocheading3outline, div.jddocheading3outline - {mso-style-name:"jd doc heading 3 outline"; - margin-top:10.0pt; - margin-right:0in; - margin-bottom:6.0pt; - margin-left:.5in; - text-indent:-.5in; - page-break-after:avoid; - font-size:12.0pt; - font-family:"Cambria","serif"; - font-weight:bold;} -p.jddocoutlinelevel5, li.jddocoutlinelevel5, div.jddocoutlinelevel5 - {mso-style-name:"jd doc outline level 5"; - margin-top:3.0pt; - margin-right:0in; - margin-bottom:3.0pt; - margin-left:1.25in; - text-indent:-.25in; - font-size:12.0pt; - font-family:"Calibri","sans-serif";} - /* Page Definitions */ +@charset "UTF-8"; +/* CSS Document */ + +p { + margin:0in; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:Calibri; +} +p.docTitle, li.docTitle, div.docTitle { + margin-top:12.0pt; + margin-right:0in; + margin-bottom:12.0pt; + margin-left:0in; + font-size:20.0pt; + font-family:Calibri; + text-transform:uppercase; + font-weight:bold; +} +h1 { + margin-top:12.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:0in; + margin-bottom:.0001pt; + page-break-after:avoid; + font-size:16.0pt; + font-family:Cambria; + color:#365F91; + text-transform:uppercase; + font-weight:bold; +} +h2 { + margin-top:12.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:0in; + margin-bottom:.0001pt; + page-break-after:avoid; + border:none; + padding:0in; + font-size:16.0pt; + font-family:Cambria; + color:#365F91; + font-weight:bold; +} +h3 { + margin-top:10.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:0in; + margin-bottom:.0001pt; + page-break-after:avoid; + font-size:14.0pt; + font-family:Cambria; + font-weight:bold; +} +h4 { + margin-top:10.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:0in; + margin-bottom:.0001pt; + page-break-after:avoid; + font-size:14.0pt; + font-family:Cambria; + font-weight:normal; +} +h5 { + margin-top:10.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:0in; + margin-bottom:.0001pt; + page-break-after:avoid; + font-size:12.0pt; + font-family:Cambria; + font-variant:small-caps; + font-weight:bold; + font-style:italic; +} +h6 { + margin-top:10.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:0in; + margin-bottom:.0001pt; + font-size:12.0pt; + font-family:Cambria; + font-weight:bold; +} +address { + margin:0in; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:Calibri; + font-style:italic; +} +a:link, span.Hyperlink { + color:blue; + text-decoration:underline; +} +a:visited, span.HyperlinkFollowed { + color:purple; + text-decoration:underline; +} +p.Caption, li.Caption, div.Caption { + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:10.0pt; + font-family:Calibri; + font-weight:bold; +} +code { + margin-top:3.0pt; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:.75in; + font-size:9.0pt; + font-family:Verdana; +} +kbd { + font-family:Calibri; +} +pre { + margin:0in; + margin-bottom:.0001pt; + font-size:10.0pt; + font-family:Calibri; +} +samp { + font-family:Calibri; +} +tt { + font-family:Calibri; +} +p.ImportantHeading, li.ImportantHeading, div.ImportantHeading { + margin-top:6px; + margin-right:0in; + margin-bottom:0px; + margin-left:0.25in; + text-indent:0in; + font-size:11.0pt; + font-family:Calibri; + color:#000080; + font-weight:bold; + font-style:italic; +} + +p.NoteHeading, li.NoteHeading, div.NoteHeading { + margin-top:6px; + margin-right:0in; + margin-bottom:0px; + margin-left:0.25in; + text-indent:0in; + font-size:11.0pt; + font-family:Calibri; + color:#000080; + font-weight:bold; + font-style:italic; +} + +p.TipHeading, li.TipHeading, div.TipHeading { + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:0.25in; + margin-bottom:.0001pt; + text-indent:0in; + font-size:11.0pt; + font-family:Calibri; + color:#3E4D1F; + font-style:italic; +} +p.WarningHeading, li.WarningHeading, div.WarningHeading { + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:0.25in; + margin-bottom:.0001pt; + text-indent:0in; + font-size:11.0pt; + font-family:Calibri; + color:#FF0000; + font-style:italic; +} + +p.ImportantParagraph, li.ImportantParagraph, div.ImportantParagraph { + margin-top:6px; + margin-right:0in; + margin-bottom:6.0px; + margin-left:0.25in; + text-indent:0in; + font-size:11pt; + font-family:Calibri; + font-style:italic; +} + +p.NoteParagraph, li.NoteParagraph, div.NoteParagraph { + margin-top:6px; + margin-right:0in; + margin-bottom:6.0px; + margin-left:0.25in; + text-indent:0in; + font-size:11pt; + font-family:Calibri; + font-style:italic; +} + + +p.TipParagraph, li.TipParagraph, div.TipParagraph { + margin-top:6px; + margin-right:0in; + margin-bottom:6.0px; + margin-left:0.25in; + text-indent:0in; + font-size:11pt; + font-family:Calibri; + font-style:italic; +} + + +p.WarningParagraph, li.WarningParagraph, div.WarningParagraph { + margin-top:6px; + margin-right:0in; + margin-bottom:6.0px; + margin-left:0.25in; + text-indent:0in; + font-size:11pt; + font-family:Calibri; + font-style:italic; +} + + +p.VersionDoc, li.VersionDoc, div.VersionDoc { + margin-top:3.0pt; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:0in; + text-align:right; + font-size:9.0pt; + font-family:Calibri; + font-style:italic; +} + @page Section1 { + size:8.5in 11.0in; + margin:1.0in 1.0in 1.0in 1.0in; +} +div.Section1 { + page:Section1; +} +/* Tables */ + +Table { + margin:0in; + margin-bottom:.0001pt; + font-size:8.0pt; + font-family:Verdana +} + +#important { + border:1.0pt; + border-style:solid; + border-collapse:collapse; + border-color: #DBD600; + background-color: #FFFFEB; + margin-top:12.0pt; + margin-left:.5in +} + +#note { + border:1.0pt; + border-style:solid; + border-collapse:collapse; + border-color: #365F91; + background-color: #E5EEF7; + margin-top:12.0pt; + margin-left:.5in; +} + +#tip { + border:1.0pt; + border-style:solid; + border-collapse:collapse; + border-color: #3E4D1F; + background-color: #E5FFE5; + margin-top:12.0pt; + margin-left:.5in; +} + +#warning { + border:1.0pt; + border-style:solid; + border-collapse:collapse; + border-color: #FF0000; + background-color: #F6E6E6; + margin-top:12.0pt; + margin-left:.5in; +} + + + +td, th { + padding-top:12pt; + padding-right:15.0pt; + padding-bottom:12.0pt; + padding-left:5.4pt + +} + + +/* Table of Contents */ + +p.TocHeading, li.TocHeading, div.TocHeading { + margin-top:12.0pt; + margin-right:0in; + margin-bottom:12.0pt; + margin-left:0in; + border:none; + padding:0in; + font-size:12.0pt; + font-family:Helvetica; + font-weight:bold; +} +p.Toc1, li.Toc1, div.Toc1 { + margin:0in; + margin-bottom:.0001pt; + font-size:14.0pt; + font-family:Calibri; +} +p.Toc2, li.Toc2, div.Toc2 { + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:12.0pt; + margin-bottom:.0001pt; + font-size:12.0pt; + font-family:Calibri; +} +p.Toc3, li.Toc3, div.Toc3 { + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:24.0pt; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:Calibri; +} +p.Toc4, li.Toc4, div.Toc4 { + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:.5in; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:Calibri; +} +p.Toc5, li.Toc5, div.Toc5 { + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:48.0pt; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:Calibri; +} +p.Toc6, li.Toc6, div.Toc6 { + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:60.0pt; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:Calibri; +} +/* List Definitions */ +ol { + margin-top:6pt; + margin-right:0in; + margin-bottom:6pt; + margin-left:0.25in; + text-indent:.30in; + font-size:11pt; + font-family:Calibri; +} +ul { + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:0.25in; + margin-bottom:0.0001pt; + text-indent:.3in; + font-size:11pt; + font-family:Calibri; +} + +h3 + {margin-right:0in; + margin-left:0in; + font-size:13.5pt; + font-family:"Times New Roman","serif"; + font-weight:bold;} +h4 + {margin-top:12.0pt; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:14.0pt; + font-family:"Times New Roman","serif"; + font-weight:bold;} +p.MsoIndex1, li.MsoIndex1, div.MsoIndex1 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:12.0pt; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndex2, li.MsoIndex2, div.MsoIndex2 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:24.0pt; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndex3, li.MsoIndex3, div.MsoIndex3 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:.5in; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndex4, li.MsoIndex4, div.MsoIndex4 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:48.0pt; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndex5, li.MsoIndex5, div.MsoIndex5 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:60.0pt; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndex6, li.MsoIndex6, div.MsoIndex6 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:1.0in; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndex7, li.MsoIndex7, div.MsoIndex7 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:84.0pt; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndex8, li.MsoIndex8, div.MsoIndex8 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:96.0pt; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndex9, li.MsoIndex9, div.MsoIndex9 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:1.5in; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoToc1, li.MsoToc1, div.MsoToc1 + {margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:10.0pt; + font-family:"Times New Roman","serif"; + text-transform:uppercase; + font-weight:bold;} +p.MsoToc2, li.MsoToc2, div.MsoToc2 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:12.0pt; + margin-bottom:.0001pt; + font-size:10.0pt; + font-family:"Times New Roman","serif"; + font-variant:small-caps;} +p.MsoToc3, li.MsoToc3, div.MsoToc3 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:24.0pt; + margin-bottom:.0001pt; + font-size:10.0pt; + font-family:"Times New Roman","serif"; + font-style:italic;} +p.MsoToc4, li.MsoToc4, div.MsoToc4 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:.5in; + margin-bottom:.0001pt; + font-size:9.0pt; + font-family:"Times New Roman","serif";} +p.MsoToc5, li.MsoToc5, div.MsoToc5 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:48.0pt; + margin-bottom:.0001pt; + font-size:9.0pt; + font-family:"Times New Roman","serif";} +p.MsoToc6, li.MsoToc6, div.MsoToc6 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:60.0pt; + margin-bottom:.0001pt; + font-size:9.0pt; + font-family:"Times New Roman","serif";} +p.MsoToc7, li.MsoToc7, div.MsoToc7 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:1.0in; + margin-bottom:.0001pt; + font-size:9.0pt; + font-family:"Times New Roman","serif";} +p.MsoToc8, li.MsoToc8, div.MsoToc8 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:84.0pt; + margin-bottom:.0001pt; + font-size:9.0pt; + font-family:"Times New Roman","serif";} +p.MsoToc9, li.MsoToc9, div.MsoToc9 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:96.0pt; + margin-bottom:.0001pt; + font-size:9.0pt; + font-family:"Times New Roman","serif";} +p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText + {margin:0in; + margin-bottom:.0001pt; + font-size:10.0pt; + font-family:"Arial","sans-serif";} +p.MsoCommentText, li.MsoCommentText, div.MsoCommentText + {margin:0in; + margin-bottom:.0001pt; + font-size:10.0pt; + font-family:"Arial","sans-serif";} +p.MsoHeader, li.MsoHeader, div.MsoHeader + {margin:0in; + margin-bottom:.0001pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoFooter, li.MsoFooter, div.MsoFooter + {margin:0in; + margin-bottom:.0001pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoIndexHeading, li.MsoIndexHeading, div.MsoIndexHeading + {margin:0in; + margin-bottom:.0001pt; + font-size:12.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +p.MsoCaption, li.MsoCaption, div.MsoCaption + {margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.25in; + font-size:10.0pt; + font-family:"Calibri","sans-serif"; + font-weight:bold;} +p.MsoTof, li.MsoTof, div.MsoTof + {margin:0in; + margin-bottom:.0001pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +span.MsoFootnoteReference + {vertical-align:super;} +span.MsoEndnoteReference + {vertical-align:super;} +p.MsoEndnoteText, li.MsoEndnoteText, div.MsoEndnoteText + {margin:0in; + margin-bottom:.0001pt; + font-size:10.0pt; + font-family:"Arial","sans-serif";} +p.MsoToa, li.MsoToa, div.MsoToa + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:12.0pt; + margin-bottom:.0001pt; + text-indent:-12.0pt; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoMacroText, li.MsoMacroText, div.MsoMacroText + {margin:0in; + margin-bottom:.0001pt; + font-size:10.0pt; + font-family:"Courier New";} +p.MsoToaHeading, li.MsoToaHeading, div.MsoToaHeading + {margin-top:6.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:0in; + margin-bottom:.0001pt; + font-size:12.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +p.MsoListBullet2, li.MsoListBullet2, div.MsoListBullet2 + {margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:.55in; + margin-bottom:.0001pt; + text-indent:-.1in; + font-size:12.0pt; + font-family:"Arial","sans-serif";} +p.MsoTitle, li.MsoTitle, div.MsoTitle + {margin-top:12.0pt; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:0in; + text-align:center; + font-size:16.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +a:link, span.MsoHyperlink + {color:blue; + text-decoration:underline;} +a:visited, span.MsoHyperlinkFollowed + {color:purple; + text-decoration:underline;} +p.MsoDocumentMap, li.MsoDocumentMap, div.MsoDocumentMap + {margin:0in; + margin-bottom:.0001pt; + background:navy; + font-size:10.0pt; + font-family:"Tahoma","sans-serif";} +p + {margin-right:0in; + margin-left:0in; + font-size:12.0pt; + font-family:"Times New Roman","serif";} +tt + {font-family:"Courier New";} +p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject + {margin:0in; + margin-bottom:.0001pt; + font-size:10.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +p.MsoAcetate, li.MsoAcetate, div.MsoAcetate + {margin:0in; + margin-bottom:.0001pt; + font-size:8.0pt; + font-family:"Tahoma","sans-serif";} +p.jdheading1, li.jdheading1, div.jdheading1 + {mso-style-name:"jd heading 1"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:18.0pt; + font-family:"Arial","sans-serif"; + color:navy; + font-weight:bold;} +p.jdnormal, li.jdnormal, div.jdnormal + {mso-style-name:"jd normal"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + line-height:150%; + font-size:11.0pt; + font-family:"Arial","sans-serif";} +p.jdchapternumber, li.jdchapternumber, div.jdchapternumber + {mso-style-name:"jd chapter number"; + margin:0in; + margin-bottom:.0001pt; + text-align:right; + font-size:72.0pt; + font-family:"Arial","sans-serif"; + color:navy; + font-weight:bold;} +p.jdchapterheading, li.jdchapterheading, div.jdchapterheading + {mso-style-name:"jd chapter heading"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:12.0pt; + margin-left:0in; + text-align:right; + line-height:150%; + page-break-after:avoid; + border:none; + padding:0in; + font-size:18.0pt; + font-family:"Arial","sans-serif"; + color:navy; + font-weight:bold;} +p.jdheading2, li.jdheading2, div.jdheading2 + {mso-style-name:"jd heading 2"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:14.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +p.jdheading3, li.jdheading3, div.jdheading3 + {mso-style-name:"jd heading 3"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:12.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +p.jdtable, li.jdtable, div.jdtable + {mso-style-name:"jd table"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:10.0pt; + font-family:"Arial","sans-serif";} +p.jdnormalindent1, li.jdnormalindent1, div.jdnormalindent1 + {mso-style-name:"jd normal indent 1"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.25in; + line-height:150%; + font-size:11.0pt; + font-family:"Arial","sans-serif";} +p.jdlistnumbers1, li.jdlistnumbers1, div.jdlistnumbers1 + {mso-style-name:"jd list numbers 1"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.5in; + text-indent:-.25in; + line-height:150%; + font-size:11.0pt; + font-family:"Arial","sans-serif";} +p.BulletedListJD, li.BulletedListJD, div.BulletedListJD + {mso-style-name:"Bulleted List JD"; + margin-top:0in; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:11.0pt; + font-family:"Arial","sans-serif";} +p.Normal2, li.Normal2, div.Normal2 + {mso-style-name:"Normal 2"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:0in; + margin-bottom:.0001pt; + line-height:150%; + font-size:11.0pt; + font-family:"Arial","sans-serif";} +p.NormalIndent1, li.NormalIndent1, div.NormalIndent1 + {mso-style-name:"Normal Indent 1"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:.5in; + margin-bottom:.0001pt; + line-height:150%; + font-size:11.0pt; + font-family:"Arial","sans-serif";} +p.StyleBulletedListJDArial11pt, li.StyleBulletedListJDArial11pt, div.StyleBulletedListJDArial11pt + {mso-style-name:"Style Bulleted List JD + Arial 11 pt"; + margin-top:0in; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:11.0pt; + font-family:"Arial","sans-serif";} +p.StyleHeading1Right, li.StyleHeading1Right, div.StyleHeading1Right + {mso-style-name:"Style Heading 1 + Right"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:0in; + text-align:right; + page-break-after:avoid; + font-size:18.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +p.StyleHeading412pt, li.StyleHeading412pt, div.StyleHeading412pt + {mso-style-name:"Style Heading 4 + 12 pt"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:12.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +p.Style1, li.Style1, div.Style1 + {mso-style-name:Style1; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + border:none; + padding:0in; + font-size:18.0pt; + font-family:"Arial","sans-serif"; + color:navy; + font-weight:bold;} +p.SuperTitle, li.SuperTitle, div.SuperTitle + {mso-style-name:SuperTitle; + margin-top:48.0pt; + margin-right:0in; + margin-bottom:0in; + margin-left:1.0in; + margin-bottom:.0001pt; + text-align:right; + border:none; + padding:0in; + font-size:14.0pt; + font-family:"Arial","sans-serif"; + font-weight:bold;} +p.jdwebheading1, li.jdwebheading1, div.jdwebheading1 + {mso-style-name:"jd web heading 1"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:14.0pt; + font-family:"Calibri","sans-serif"; + font-weight:bold;} +p.jdwebheading2, li.jdwebheading2, div.jdwebheading2 + {mso-style-name:"jd web heading 2"; + margin-top:10.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + border:none; + padding:0in; + font-size:14.0pt; + font-family:"Cambria","serif"; + color:#365F91;} +p.jdwebheading3, li.jdwebheading3, div.jdwebheading3 + { + margin-top:10.0pt; + margin-right:0in; + margin-bottom:0; + margin-left:0in; + font-size:12.0pt; + font-family:"Cambria","serif";} +p.jdwebnormal, li.jdwebnormal, div.jdwebnormal { + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.25in; + font-size:11.0pt;} +p.jdwebheading4, li.jdwebheading4, div.jdwebheading4 { + margin-top:10.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:10.0pt; + text-transform:uppercase;} +p.jdwebfiguretitle, li.jdwebfiguretitle, div.jdwebfiguretitle { + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:10.0pt; + font-weight:bold;} +p.jdwebheading5, li.jdwebheading5, div.jdwebheading5{ + margin-top:10.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:10.0pt; + font-weight:bold;} +p.jdwebtable, li.jdwebtable, div.jdwebtable + { + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:10.0pt; + font-family:"Calibri","sans-serif";} +p.jdwebchapterheading, li.jdwebchapterheading, div.jdwebchapterheading + {mso-style-name:"jd web chapter heading"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:14.0pt; + font-family:"Helvetica","sans-serif"; + font-weight:bold;} +p.jdwebbullets, li.jdwebbullets, div.jdwebbullets + {mso-style-name:"jd web bullets"; + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:1.0in; + margin-bottom:.0001pt; + text-indent:-.25in; + line-height:150%; + font-size:11.0pt; + font-family:"Calibri","sans-serif";} +p.jdweblistnumbers, li.jdweblistnumbers, div.jdweblistnumbers + {mso-style-name:"jd web list numbers"; + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:.5in; + margin-bottom:.0001pt; + text-indent:-.25in; + line-height:150%; + font-size:11.0pt;} +p.jdwebheading7, li.jdwebheading7, div.jdwebheading7 + {mso-style-name:"jd web heading 7"; + margin-top:10.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:9.0pt; + font-family:"Cambria","serif"; + text-transform:uppercase;} +p.jdwebheading8, li.jdwebheading8, div.jdwebheading8 + {mso-style-name:"jd web heading 8"; + margin-top:10.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:9.0pt; + text-transform:uppercase; + font-style:italic; + text-decoration:underline;} +p.jdwebtablelistnumber, li.jdwebtablelistnumber, div.jdwebtablelistnumber + {mso-style-name:"jd web table list number"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.15in; + text-indent:-.15in; + font-size:10.0pt;} +p.jdwebemphasis, li.jdwebemphasis, div.jdwebemphasis + {mso-style-name:"jd web emphasis"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.25in; + font-size:11.0pt; + font-style:italic;} +p.jdwebfiguredescription, li.jdwebfiguredescription, div.jdwebfiguredescription + {mso-style-name:"jd web figure description"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:10.0pt;} +p.StylejdwebfiguretitleNotBold, li.StylejdwebfiguretitleNotBold, div.StylejdwebfiguretitleNotBold + { + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + font-size:10.0pt;} +p.jdwebheading6, li.jdwebheading6, div.jdwebheading6 + { + margin-top:10.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:0in; + page-break-after:avoid; + font-size:10.0pt; + text-decoration:underline;} +p.jdwebnormalindent, li.jdwebnormalindent, div.jdwebnormalindent + { + margin-top:6.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.5in; + font-size:11.0pt;} +p.Stylejdlistnumbers1CalibriBefore0ptAfter0pt, li.Stylejdlistnumbers1CalibriBefore0ptAfter0pt, div.Stylejdlistnumbers1CalibriBefore0ptAfter0pt + { + margin:0in; + margin-bottom:.0001pt; + line-height:150%; + font-size:11.0pt;} +p.jdweblistbullet, li.jdweblistbullet, div.jdweblistbullet + {mso-style-name:"jd web list bullet"; + margin-top:0in; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:.75in; + text-indent:-.25in; + font-size:11.0pt; + font-family:"Calibri","sans-serif";} +p.StylejdwebnormalLeft05, li.StylejdwebnormalLeft05, div.StylejdwebnormalLeft05 + {mso-style-name:"Style jd web normal + Left\: 0\.5\0022"; + margin-top:0in; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.5in; + font-size:11.0pt; + font-family:"Calibri","sans-serif";} +p.jdtocheading, li.jdtocheading, div.jdtocheading + {mso-style-name:"jd toc heading"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:12.0pt; + margin-left:0in; + page-break-after:avoid; + border:none; + padding:0in; + font-size:12.0pt; + font-family:"Helvetica","sans-serif"; + font-weight:bold;} +p.Stylejdweblistnumbersindent, li.Stylejdweblistnumbersindent, div.Stylejdweblistnumbersindent + {mso-style-name:"Style jd web list numbers indent"; + margin:0in; + margin-bottom:.0001pt; + line-height:150%; + font-size:11.0pt; + font-family:"Calibri","sans-serif";} +p.jdweblistletters, li.jdweblistletters, div.jdweblistletters + {mso-style-name:"jd web list letters"; + margin-top:0in; + margin-right:0in; + margin-bottom:0in; + margin-left:1.0in; + margin-bottom:.0001pt; + text-indent:-.25in; + font-size:11.0pt; + font-family:"Calibri","sans-serif";} +span.jdwebnormalChar + {mso-style-name:"jd web normal Char"; + mso-style-link:"jd web normal"; + font-family:"Calibri","sans-serif";} +span.jdwebfiguretitleChar + {mso-style-name:"jd web figure title Char"; + mso-style-link:"jd web figure title"; + font-family:"Calibri","sans-serif"; + font-weight:bold;} +span.StylejdwebfiguretitleNotBoldChar + {mso-style-name:"Style jd web figure title + Not Bold Char"; + mso-style-link:"Style jd web figure title + Not Bold"; + font-family:"Calibri","sans-serif"; + font-weight:bold;} +span.Heading1Char + {mso-style-name:"Heading 1 Char"; + mso-style-link:"Heading 1"; + font-family:"Arial","sans-serif"; + font-weight:bold;} +span.Heading2Char + {mso-style-name:"Heading 2 Char"; + mso-style-link:"Heading 2"; + font-family:"Arial","sans-serif"; + font-weight:bold; + font-style:italic;} +p.jddoclistnumbers1, li.jddoclistnumbers1, div.jddoclistnumbers1 + {mso-style-name:"jd doc list numbers 1"; + margin-top:6.0pt; + margin-right:0in; + margin-bottom:10.0pt; + margin-left:.5in; + text-indent:-.25in; + line-height:115%; + font-size:12.0pt; + font-family:"Calibri","sans-serif";} +p.jddoclistnumbers2, li.jddoclistnumbers2, div.jddoclistnumbers2 + {mso-style-name:"jd doc list numbers 2"; + margin-top:3.0pt; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:1.0in; + text-indent:-.25in; + line-height:115%; + font-size:12.0pt; + font-family:"Calibri","sans-serif";} +p.jddocheading1outline, li.jddocheading1outline, div.jddocheading1outline + {mso-style-name:"jd doc heading 1 outline"; + margin-top:12.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.5in; + text-indent:-.5in; + page-break-before:always; + page-break-after:avoid; + font-size:14.0pt; + font-family:"Calibri","sans-serif"; + text-transform:uppercase; + font-weight:bold;} +p.jddocheading2outline, li.jddocheading2outline, div.jddocheading2outline + {mso-style-name:"jd doc heading 2 outline"; + margin-top:10.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:44.85pt; + text-indent:-44.85pt; + page-break-after:avoid; + font-size:14.0pt; + font-family:"Cambria","serif"; + color:#365F91;} +p.jddocheading3outline, li.jddocheading3outline, div.jddocheading3outline + {mso-style-name:"jd doc heading 3 outline"; + margin-top:10.0pt; + margin-right:0in; + margin-bottom:6.0pt; + margin-left:.5in; + text-indent:-.5in; + page-break-after:avoid; + font-size:12.0pt; + font-family:"Cambria","serif"; + font-weight:bold;} +p.jddocoutlinelevel5, li.jddocoutlinelevel5, div.jddocoutlinelevel5 + {mso-style-name:"jd doc outline level 5"; + margin-top:3.0pt; + margin-right:0in; + margin-bottom:3.0pt; + margin-left:1.25in; + text-indent:-.25in; + font-size:12.0pt; + font-family:"Calibri","sans-serif";} + /* Page Definitions */ p{clear: both; display: block;} \ No newline at end of file diff --git a/help/tqt.html b/help/tqt.html index 91ef81f2..2324e270 100755 --- a/help/tqt.html +++ b/help/tqt.html @@ -1,2358 +1,2358 @@ - - - - - i2b2 Temporal Query Tool View - - - - - - -
-

i2b2 Temporal Query Tool View

- -

The Temporal Query Tool view extends the query functionalities - provided by the classic Query Tool view. Users can submit temporal queries to using - the Temporal Query Tool view.

- -

i2b2 Temporal Query Tool View

- -

The Temporal Query Tool view extends the query - functionalities provided by the classic Query Tool view. Users can create and - submit temporal queries to using the Temporal Query Tool view. It submits a - "select query" that will retrieve information from the database associated to the - i2b2 Web Client.

- -

Introduction

- -

The interface is organized to facilitate the temporal querying - process. There are three main steps in the process: Defining a population, defining - temporal relationships, and reviewing and submitting query. The interface is designed - to take users through each of these three steps. The section below describes the - interface for each step in detail.

- - - -

The image below shows the starting point of the Temporal - Query Tool view interface along with its annotations. Users would interact with - the Group Panels to define a population they are interested in. In the next - step, users would define the temporal relationships they are interested in. Finally, - users would review and submit their queries in the third step. This section breaks - down the interface for the 1st step.

- -

- -

The Patient/Encounter Dropdown Box allows users to - choose whether to define the population of the query using patients or encounters. - The default is Patient:

- -

- -

Creating a population is optional. Users can skip Step 1 to use all data in the database.

- -

Group Panel

- -

- -

At the start up, the interface for Step 1 displays three - groups by default. Each of the groups contains several components. In general, all - areas bounded by an orange-yellow highlight are clickable.

- -
    -
  1. - (Group Heading) The heading is a label to easily identify the collection of terms. - Each heading will contain "Group" followed by a sequential number.

    Example: Group 1, Group 2, Group 3, etc.

  2. - -
  3. - (Selection Criteria) This area of the panel is used to define date selections and other constraints.
  4. - -
  5. - (Panel Timing) The panel timing defines the constraint on the panel level and uses the patient's visits in determining eligibility.
  6. - -
  7. - (Group List) This section contains the terms that will be used during the process of querying the database.
  8. - -
  9. - (Delete Group) Clicking on this button will remove the group from the - query construction. Users should use it to quickly discard a group.
  10. - -
  11. - (Information Box) The content in the information box will change depending on whether or not a term is listed in the panel / group. -
      -
    • No term(s) listed -
        -
      1. The message will appear as "drop a term on here"
      2. -
      3. The color of the box will be yellow
      4. -
      -
    • -
    • Term(s) listed -
        -
      1. The message will appear as "one or more of these"
      2. -
      3. The color of the box will be green
      4. -
      5. An additional information box will appear between panels
      6. -
      -
    • -
    - -
  12. - -
- -

New/Add Group Button

- -

qtToolbarNewGroup

- -

The New Group button lets users to quickly add additional Groups.

- -

Query Drop Area

- -

A previous query saved in Workplace view or in the - Previous Query view can be dragged and dropped here to reload the query. - Reloading a query will overwrite the current query information. If the previous query - is a temporal query, its population and temporal relationships will all be loaded. If - the previous query is a non-temporal query, only the population portion of the - temporal query interface will be loaded since a non-temporal query has no temporal - relationship information.

- - - -

Step 2: Define Temporal Relationships is used to - define temporal relationships. It allows users to create a list of Events and - a list of Temporal Relationships. Users define a list of interested - Events and also define Temporal Relationships to describe how the - events are related temporally, e.g. Event A must occur before Event B.

- -

The interface is therefore a bit more complicated than Step 1 - presented in the earlier section. It is broken into two major parts, presented below. - On the left are the Event in Query panel and the Show Population panel. - The Event in Query panel lets users define a list of Events. The Show - Population panel allows users see and change the population definition originally - defined in Step 1. On the right is a panel allowing users to add, remove, or modify - relationships among the events.

- -

- - - -

Events in Query Panel

- -

(Event Panels at startup)

- -

The Events in Query Panel allows users to add, remove, and - edit each Event. Each Event is represented by an Event Panel. An - Event consists of a list of Groups just like a population definition. Users - can add, remove, and edit each of the Groups in an Event by dragging - terms into a group, changing its constraints, etc. At startup, two empty - Events are added, each with a Group. More Events can be added by - clicking on the Add Event button.

- -

One difference between an Event and a set of - Groups in Step 1 is that the first Group in an Event is special. - It cannot be removed (note the missing Remove Group button), and its Group - Binding Control is missing. The Group Binding for the 1st - Group of every Event is not changeable. All other Group's - Group Bindings are changeable. The first group anchors all other groups in an - Event. That is, the first Group determines the timing of the enclosing - Event with respect to the other Events temporally in the query.

- -

Under the list of Events is the gray background, which serves - as a Query Drop Area. Users can drop previous query in the Query Drop - Area to overwrite the current query. It has the same effect as the Query Drop - Area in Step 1.

- -

An Event Panel has several components.

- -

- -
    -
  1. - (Event ID) This area shows the Event's name and color. Clicking on this area - will expand/collapse the entire Event. When an Event Panel is - collapsed, all its Groups are hidden. Only a row that contains the Event - ID area is shown. Click on the Event ID area to expand the Event. - All Events are expanded when created. Color of an Event is assigned - only when at least one term has been added to it. -
  2. - -
  3. (Event-Wide Date - Constraints) Selecting this area allows users to specify date constraints for all - Groups in this Event. This serves a similar function as the - supplemental Query-wide Date Constraints Control Panel in the Step 1.
  4. - -
  5. (Remove Event Button) - Clicking this button will remove the Event, deleting all its content and - removing it from view.
  6. - -
  7. (Group Panel) The Group - Panel is the same as the ones in Step 1.
  8. - -
  9. (Add Group Button) - Clicking on it adds a new Group to the Event.
  10. -
- -

- -

The population in Step 1 is shown. The title changes to "Edit - Population," and every component is editable just as they are in Step 1.

- -

Temporal Relationship Definition Panel

- -

On the right hand side of the Step 3 interface is where users - can define how Events are related to one another temporally. The Temporal - Relationship Definition Panel contains a list of Temporal Relationship - Panels and an Add Temporal Relationship Button. These components are - described in detail below.

- -

Please note that at least one Temporal Relationship - Panel must be filled before users can move on to Step 3. A Temporal - Relationship Panel is filled only if has a fulfilled Event in the Top Event - Definition dropdown box and a fulfilled Event in the Bottom Event - Definition dropdown box (see the image below). A fulfilled Event is one that has - at least a fulfilled Group. A fulfilled Group is one that contains at - least one term (not empty).

- -

- -
    -
  1. - The color indicator shows the colors of the Events - that are being referenced in the Temporal Relationship. The top color (green - in this example) matches the color of the Event in the Top Event - Definition row and the bottom color (orange) matches the color of the - Event in the Bottom Event Definition row. If an Event that has - no content is referred, no color will be displayed in the Color Indicator.
  2. - -
  3. - (Top Event Definition)This row allows users designate the first Event - in this Temporal Relationship. A second event is specified in the Bottom - Event Definition row. The dropdown boxes have the following choices: - -

    (Dropdown box options for Event Definition)

    -
  4. - -
  5. - (Event Ordering) This dropdown box describes how the Top Event elates - to the Bottom Event. - -

    (Dropdown box options for Event Ordering)

    -
  6. -
  7. - (Bottom Event Definition) This row allows users designate the second - Event in this Temporal Relationship. It has the same dropdown box - options as Top Event Definition.
  8. - -
  9. - (Occurrence Temporal Constraint) Users can optionally describe the specified - Event Ordering by a time range, creating the bolded part of, for example, - "Event 1 Occurs Before Event 2 By > 5 day(s)." This additional temporal - constraint can be a bounded range such as "By > 5 day(s) And < 10 - day(s)." Users must first check the "By" checkbox to enable the dropdown - boxes on that row. The "And" checkbox becomes enabled only when the - "By" checkbox is checked. Checking the "And" checkbox enables the - dropdown boxes on its row. Both the By row and the And row have the - same options depicted below. - -

    - (Options for Occurrence Temporal Constraint) -

    -
  10. - -
  11. - (Add Temporal Relationship Button) This adds a new Temporal Relationship Panel - should users require more relationship constraints among Events.

    -
  12. -
- - -

The last step allows users to review and modify the name of - the query and selection of analyses types they want the server to return as the - results of the query.

- -

qtRunQueryWindow

- -

Query Name Area

- -

Upon entering Step 3, a query name is automatically generated. - A "(t)" prefix indicates the query is a temporal query, differentiating it from - normal queries submitted using the classic query tool. Some terms used in the query - are then appended to identify this query. A timestamp is added at the end. Users may - modify the query name however they wish. The name in the Query Name Area will - be displayed in the Previous Query view once the query is submitted

- -

Analysis Type Area

- -

The area presents the different analyses types users can - select as results of the query. They are exactly the same as the ones from the - classic Query Tool:

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table of Result Types -
- Patient list - - Provides a set of patients who met the search criteria. -
- Event list - - Provides a set of encounters for those patients who met - the search criteria. -
- Number of patients - - Provides the total number of patients who met the - search criteria. -
- Gender patient breakdown - - Provides a breakdown of the patients by their gender. -
- Vital Status patient breakdown - - Provides a breakdown of the patients by their vital - status. -
- Race patient breakdown - - Provides a breakdown of the patients by their race. -
- Age patient breakdown - - Provides a breakdown of the patients by their age -
- Timeline - - Provides a set of patients who met the defined criteria - and automatically generates a timeline in the timeline view. -
-
- -

By default Number of patients and Timeline are selected.

- -

Run Query Button

- -

In Step 3, the Footer is different. Instead of another "Next" - button, a Submit Query Button is there instead. It allows users to execute the - query they have built in Step 1 and Step 2.

- -

After pressing Submit Query, the button will become inactive - to prevent inadvertent submission. A "Processing..." text will display to indicate - that the query is being sent to the server for processing. The red rectangular button - allows users to cancel the query submission.

- -

queryStatusRun

- -

When the server completes the processing, the number of patients found will be returned:

- -

queryStatusFinish

- -

If the query takes too long, a message will be - displayed instead, in addition, the Submit Query Button will become available - again. Users are advised to monitor the Previous Queries view to see when the - query finishes.

- - - - - - -
-

NOTE:

-

- The result types that appear will depend on what you have selected when running the query.. -

-
- - - -

Many of the UI elements discussed above are for display only. - That is, they display the content of a Group or an Event or a Query, but they do not - themselves allow editing of the values. Instead, users have to click on display - components to launch an editor. The various editors are presented here.

- -

This dialogs are all modal. That means no other actions can be - performed when the dialog is launched. Users must first dismiss (typically by either - selecting OK or Cancel) the dialog before other UI elements in the Web Client can be - interacted with.

- -

The dialogs can be moved by dragging the blue title area - around, and they usually appear where the mouse pointer is when launched.

- -
    -
  1. - (Date Constraint Editor) The Date Constraint Editor is launched when - user clicks on a Date Constraint Control in every Group Panel, in the - title area of an Event, in the Supplemental Control Panel in Step 1, - and in the View Population Panel in Step 2.

    - -

    The editor starts up as the left-most figure below. Clicking - on either of the orange-yellow-highlighted textboxes will launch a calendar widget - for users to select the start (middle figure) or the end date (right-most figure). - When finished, users should click on the OK button in the gray footer area to - accept the constraints. Alternatively, clicking the Cancel button will leave - the original date constraints unmodified.

    - -

    The start and end date constraints are both inclusive. That is - if the start date is January 1, 1999, and the end date is December 31, 1999, the - range of the constraint spans from 1/1/1999 00:00:00.000 to 12/31/1999 - 23:59:59.999.

    - -

    qtConstDateWindow

    -
  2. - -
  3. - (Group Binding Editor) The Group Binding Editor is found in every - Group Panel. It lets users change the binding for that Group. The left - figure depicts the initial appearance when a Group Binding Editor is launched. - It consists of three rows, each represent a binding option. The last option - (Bound-by-Observation) is only available as a choice if a modifier is dropped - in the Group. Selecting one of the radio buttons and clicking on OK - will set the new binding. Cancel will cancel the operation and leave the - original binding unmodified.

    - -

    -
  4. - -
  5. - (Occurrence Count Constraint Editor) This editor can be launched in every - Group by clicking on its Count Control area. Users can specify how many (or - few) times the terms in a Group must occur. The editor itself is simple: a - dropdown box specifies the type of operator and a spinner allowing for a number to be - specified.

    - -

    The left figure shows the dialog at startup, and the right - figure shows all the operator options.

    - -

    qtConstOccurSelectqtConstOccurWindow

    -
  6. - -
  7. - (Value Editor) When users drop an ontology term that can be further - constrained by values into a Group, a Value Editor will automatically - launch. Users can use this editor to select a way to constrain the value of the term - and specify what values to constrain the term by. If a term that supports values - already exists in a Group, users can right click on the term and select - "Edit Value..." to launch the Value Editor for that term. Please note - that some Modifiers do not support values (e.g. Circulatory Systems [Primary - diagnosis]).

    - -

    qtConstValSelect(Right click on a term that supports value - constraints to launch the Value Editor)

    - -

    Note that the constraint is optional. The default constraint - put on these terms is "No Value," and by closing the dialog immediately, users - can quickly accept the default constraint. Please note that closing the dialog does - not cancel the value editing operation, it instead accepts the values that are - currently set.

    - -

    If multiple terms were dropped at the same time, all terms - that support value constraints in the same drop will appear in a list the left side - of dialog. Users can select the terms on the list to view and edit its value - constraint. Alternatively, users can use the navigation buttons "Previous", - "Next" to navigate. Finally, to finish, users should select the last term on - the list and click on "Finish."

    - -

    qtConstValTropI1(The Value Editor - shows two terms on its list on the left. The right half shows the currently set value constraints for the selected - term on list. The default is "No Value." Users can also navigate the list by using - the "Next" "Previous" buttons on the bottom of the right half. When - finished, click on the "Finish" button or simply close the dialog.)

    - -

    Different terms support different kinds of value constraint, - some are constrained by text, some by numeric value, some by a list of pre-arranged - values, and some by abnormal flags. For example, the Color term supports abnormal - flags and a list of pre-arranged values. These options are shown on the right half of - the dialog. By selecting the radio buttons, users can choose the kind of constraint - they want. Here are the screen shots of the right half of the dialog when radio - buttons other than "No Value" are chosen for the term Color.

    - -

    qtConstValTropI2qtConstValCpk2

    -
  8. -
- -

Creating a Query

- -

This section describes the process of adding items to the - query tool, "AND" / "OR" operators and setting constraints.

- - - -

In order to create your query, you will need to define what - information will be retrieved from the databases. Selected items from other i2b2 - Web Client views can be dragged and dropped (copied) into the Temporal Query - Tool view.

- -
    - -
  1. Concepts - -

    Concepts () can be defined as terms, - results, providers, etc. They can be added as a group (folder ()) or - individually by dragging the item(s) from Navigate Terms, Find Terms, - and Workplace views.

    -
  2. - -
  3. Modifiers - -

    Modifiers () - are associated with a concept or group of concepts. They can be added as a group (modifier folder - ()) or - individually by dragging the item(s) from Navigate Terms, Find Terms, and Workplace views.

    -
  4. - -
  5. Previous Query - -

    A new query can be created from one that has already - been run by dragging the previous query ( - or) - from Previous Query and Workplace views.

    -
  6. - -
  7. - Patient List - -

    A patient list () - can be used in a query by dragging the item(s) from Previous Query and Workplace views.

    -
  8. - -
  9. Individual Patient - -

    A patient () or several patients can be used in a - query by dragging them from Previous Query view and Workplace views.

    -
  10. - -
  11. Event List - -

    An event list () - can be used in a query by dragging the item(s) from Previous Query and Workplace views.

    -
  12. -
  13. Query Definition - -

    A new query can be created from one that has already - been run by dragging the query definition () - from the Workplace view.

    -
  14. -
  15. Group Template - -

    Users can define a group of concepts that they - frequently run and save them in their workplace view. This grouping of concepts is - referred to as a group template ().

    - -

    A new query can be created using the group template - by dragging the template from Workplace view to the Group Header.

    -
  16. -
-
-

Operators

-
- -

There are two operators, known as SQL Logical - Operators, which are necessary when running a query that has more than one term. - These operators provide a way to specify exactly what users want to retrieve. The - operators are the 'AND' and 'OR' operators.

- -

The query tool knows which operator to use based on the panels - used when defining the query. It is important to verify the users are setting up - their query correctly as each operator will return different results.

- -

AND Operator

- -

The AND operator returns a record if both the first - condition and the second conditions are true.

- -

The query tool uses the AND operator when concepts are listed - in different panels.

- -

Example:

- -

WHAT: Return only those patients who have - Acute Myocardial Infarction AND Angina Pectoris.

- -

HOW: In the query tool add the concept Acute - Myocardial Infarction to Group 1 and then add the concept Angina Pectoris to Group 2 - .

- -

RESULT: The population is limited by - requiring the patients to have both Acute myocardial infarction and Angina pectoris..

- -

- -

OR Operator

- -

The OR operator returns a record if either the first - condition or the second conditions is true.

- -

The query tool uses the OR operator when concepts are listed - in the same panel.

- -

Example:

- -

WHAT: Return any patients who have Acute - Myocardial Infarction or Angina Pectoris associated to them.

- -

HOW: In the query tool you add both concepts, - Acute Myocardial Infarction and Angina Pectoris, to Group 1.

- -

RESULT: The population is limited to include - all patients who fit either one of those criteria.

- -

- -

In short, terms within a Group are ORed - together, while different Groups are ANDed together.

- - - -

Concepts can be added to the Query Tool view by simply - dragging the concept from one of the following views.

- -

1.  Navigate Terms view

- -

2.  Find Terms view

- -

3.  Workplace view

- -

How to add a concept from each of these views is explained in the next few sections.

- -

Navigate Terms View

- -

The Navigate Terms view contains a hierarchical display - of all the items that can be used to search the database.

- -

Note: How the - items are grouped and displayed is dependent on how the database is setup.

- -

- -

Add Concept From Navigate Terms View

- -

1.      In the Navigate Terms view, - expand the folder(s) that contain the concept or grouping of concepts that you want to add.

- -

2.       Highlight the concept - () or folder - () by clicking on its name.

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the item into the panel - labeled Group 1.

- -

- -

5.       The item will now display in the - panel for Group 1.

- -

- -

Find Terms View

- -

The Find Terms view provides a way to search for a particular concept and modifier.

- -

ftView

- -

Add Concept From Find Terms View

- -

1.       In the Find Terms view, - search for the item(s) you want to add.

- -

2.       Highlight the concept - () or folder - () by clicking on its name.

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the item into the panel - labeled Group 1.

- -

qtDragFolderCardioAgents

- -

5.       The item will now display in the - panel for Group 1.

- -

qtDropFolderCardio

- -

Workplace

- -

Information in the Workplace is related to the most - common concepts, modifiers, and queries that an individual uses and in essence - becomes their personal workplace.

- -

wpView

- -

Add Concept From Workplace View

- -

1.       In the Workplace view, expand - the folder(s) that contain the concept or grouping of concepts you want to add.

- -

2.       Highlight the concept - () or folder - () by clicking on its name.

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the item into the panel - labeled Group 1.

- -

qtDragFolderCardioAgents

- -

5.       - The item will now display in the panel for Group 1.

- -

qtDragFolderCardioAgents

- - - -

Modifiers can be added to the Query Tool view by simply - dragging the modifier from one of the following views.

- -

1.  Navigate Terms view

- -

2.  Find Terms view

- -

3.  Workplace view

- -

How to add a modifier from each of these views is explained in the next few sections.

- -

Navigate Terms View

- -

The Navigate Terms view contains a hierarchical display - of all the items that can be used to search the database.

- -

Note: How the - items are grouped and displayed is dependent on how the database is setup.

- -

ntView

- -

Add modifier From Navigate Terms View

- -

1.       In the Navigate Terms view, - expand the folder(s) that contains the modifier or grouping of modifiers that you - want to add.

- -

2.       Highlight the modifier - () or modifier folder - () by - clicking on its name.

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the item into the panel - labeled Group 1.

- -

qtDragFolderCardioAgents

- -

5.       The item will now display in the - panel for Group 1.

- -

qtDropFolderCardio

- -

Find Terms View

- -

The Find Terms view provides a way to search for a particular concept and modifier.

- -

ftView

- -

Note: For detailed - information on how to search for terms and modifiers, please see the i2b2 Find Terms View chapter.

- -

Add Modifier From Find Terms View

- -

1.       In the Find Terms view, - search for the modifier(s) you want to add.

- -

2.       Highlight the modifier - () or modifier folder - () by clicking on its name.

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the item into the panel - labeled Group 1.

- -

qtDragModPrincDx

- -

5.       The item will now display in the - panel for Group 1.

- -

qtDropFolderCardio

- -

Workplace

- -

Information in the Workplace is related to the most - common concepts, modifiers, and queries that an individual uses and in essence - becomes their personal workplace.

- -

wpView

- -

Add Modifier From Workplace View

- -

1.       In the Workplace view, expand - the folder(s) that contain the modifier or grouping of modifiers you want to add.

- -

2.       Highlight the modifier - () or modifier folder - () by clicking on its name.

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       - Drop the item into the panel labeled Group 1. -

- -

qtDragModPrincDx

- -

5. -        - The item will now display in the panel for Group 1. -

- -

qtDropModPrincDx

- - - -

A previous query can be used to run a new query or as - an item within a query (query-in-query). To add a previous query to the Query Tool - view simply drag the query name from one of the following views.

- -

1.  Previous Query view

- -

2.  Workplace view

- -

Within the Query Tool view, the previous query can be added to one of the following two locations.

- - - - - - - - - - - - - -
- Query Name field - - The item(s) and constraints from the original query will - be used to create a new query. This information can be edited to make a new - query or can be used as is to run the query again. -

- - Please note that the tool does not currently support - dropping of a previous query of a previous query or a previous query of a temporal query. -
- Panel (Group) - - Used within a new query (query-in-query). Add additional search criteria (items) to be used in the new query. -
- -

How to add a previous query from each of the views listed above is explained in the next few sections.

- -

Previous Query View

- -

The Previous Query view displays the queries that were run by the user.

- -

pqView

- -

Add Previous Query From Previous Query View (New Query)

- -

1.       In the Previous Query view - highlight the previous query () by clicking on its name

- -

2.       While holding the left mouse - button down, drag the item over to the Temporal Query Tool View.

- -

3.       Drop the previous query into the - Query Drop Area in either Step 1 or Step 2.

- -

4.       The terms, Groups, - Events, and Temporal Relationships defined in that previous query will - be reconstituted in the current interface. If the previous query is a non-temporal - query, then only the Population portion of the UI will be reconstituted. If the - previous query is a temporal query, then both the Population portion and the temporal - relationship portion of the UI will be reconstituted.

- -

Add Previous Query From Previous Query View (Query-In-Query)

- -

1.       In the Previous Query view - highlight the previous query () - by clicking on its name

- -

2.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

3.       Drop the previous query into the - panel labeled Group 1.

- -

4.       - The previous query will now display in the panel for Group 1.

- -

qtDragPqToPanel

- -

Workplace View

- -

Information in the workplace is related to the most - common concepts, modifiers, and queries that an individual uses and in essence - becomes their personal workplace.

- -

wpView

- -

Add Previous Query From workplace View (New Query)

- -

1.       In the Workplace view, expand - the folder(s) that contains the previous query you want to add.

- -

2.       Highlight the previous query - () by clicking on its name

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the previous query into the - Query Drop Area in either Step 1 or Step 2.

- -

5.       The terms, Groups, - Events, and Temporal Relationships defined in that previous query will - be reconstituted in the current interface. If the previous query is a non-temporal - query, then only the Population portion of the UI will be reconstituted. If the - previous query is a temporal query, then both the Population portion and the temporal - relationship portion of the UI will be reconstituted.

- -

Add Previous Query From Previous Query View (Query-In-Query)

- -

1.       In the Workplace view, expand - the folder(s) that contains the previous query you want to add.

- -

2.       Highlight the previous query - () by clicking on its name

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the previous query into the - panel labeled Group 1.

- -

5.       The previous query will now display in the panel for Group 1.

- -

qtDropPqPanel

- - - -

A patient list can be added to the Query Tool - view by simply dragging the list of patients from one of the following views.

- -

1.  Previous Query view

- -

2.  Workplace view

- -

How to add a patient list from each of the views is explained in the next few sections.

- -

Previous Query View

- -

The Previous Query view displays the queries that were run by the user.

- -

pqView

- -

Add Patient List From Previous Query View

- -

6.       In the Previous Query view - click on the plus sign () next to the name of the previous query that - contains the patient set.

- -

7.       Click on the plus sign () next to the results folder.

- -

8.       Highlight the patient list - () by clicking on its name

- -

- -

9.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

10.   Drop the patient set into the panel labeled Group 1.

- -

qtDragPtSet

- -

11.   The patient set will now display in the panel for Group 1.

- -

qtDropPtSet

- -

Workplace View

- -

Information in the workplace is related to the most - common concepts, modifiers, and queries that an individual uses and in essence - becomes their personal workplace.

- -

wpView

- -

Add Patient List From Workplace View

- -

12.   In the - Workplace view find the patient list you want to add.

- -

13.   Highlight the - patient list () by clicking on its name

- -

14.   While holding the - left mouse button down, drag the item over to the Query Tool View.

- -

15.   Drop the patient set into the panel labeled Group 1.

- -

16.   The patient set will now display in the panel for Group 1.

- -

qtDropPtSet

- - - -

An encounter set can be added to the Query Tool - view by simply dragging the encounter set from one of the following views.

- -

1.  Previous Query view

- -

2.  Workplace view

- -

How to add an event list from each of the views is explained in the next few sections.

- -

Previous Query View

- -

The Previous Query view displays the queries that were run by the user.

- -

pqView

- -

Add Event List From Previous Query View

- -

1.       In the Previous Query view - click on the plus sign () - next to the name of the previous query that contains the encounter set.

- -

2.       Click on the plus sign - () next to the results folder.

- -

3.       Highlight the encounter set - () by clicking on its name

- -

4.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

5.       Drop the encounter set into the Group 1.

- -

6.       The encounter set will now display - in the panel for Group 1.

- -

qtDropEncSet

- -

Workplace View

- -

Information in the workplace is related to the most - common concepts, modifiers, and queries that an individual uses and in essence - becomes their personal workplace.

- -

wpView

- -

Add Event List From Workplace View

- -

1.       In the Workplace view find - the encounter set you want to add.

- -

2.       Highlight the encounter set - () by clicking on its name

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the encounter set into Group 1.

- -

5.       The encounter set will now display - in the panel for Group 1.

- -

qtDropEncSet

- - - -

A query definition can be added to the query tool view by simply dragging the query name from the workplace view.

- -

Add Query Definition From Workplace View

- -

1.       In the Workplace view, find - the query definition you want to add.

- -

wpView

- -

2.       Highlight the query - definition () by clicking on its name

- -

3.       While holding the left mouse - button down, drag the item over to the Query Tool View.

- -

4.       Drop the query definition into the - Query Drop Area in Step 1 or Step 2.

- -

5.       The item(s) associated with the - query definition will display in the appropriate group(s), the name of the query will - appear at Query Name, and any constraints that were defined when the original - query was run will now default with the new query.

- - - -

Three Group Panels are displayed in Step 1 by default. - In step 2, only one Group Panel is available per Event. Some complex - queries may require the use of additional panels. Users may use the "Add Group" - button to add more Groups.

- -

1.       - Click on the Add Group button.

- -

qtToolbarNewGroup

- -

(Add Group button in Step 1)

- -

2.       - A new panel is added with each click (two clicks are performed here to create a total - of three Group Panels).

- -

qtPanelAdd

- -

In Step 2, there is an "Add Group" button for each Event, and - an additional one to add Group to the population. These "Add Group" button work - exactly the same as the one described above.

- -

- -

(Step 2 "Add Group" button)

- - - -

Users can remove a Group from a query (or Event in the temporal query UI) or a term in a Group.

- -

Remove Groups

- -

1.       Click on the Remove Group - button () located to the right top of - every Group.

- -

2.       The Group and all its content will be removed

- -

- -

Delete a Single Item

- -

1.       Right click on the item in the group - that you want to remove.

- -

deleteItem

- -

2.       Select Delete Item from the list.

- -

3.       The item will be removed from the - Group Panel

- - - -

Constraints are used to narrow down the search criteria to a - particular time from, number of occurrences or a specific value or range of values. - In i2b2, there are several types of constraints that can be defined in the Query Tool - view.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Constraint Type - - Description -
- Group Binding (Panel Timing) - - Constraint is defined on the Group and utilizes the - patient encounters and / or instance number when determining eligibility. There - are three binding choices. The most general one is bound-by-patient, followed - by bound-by-encounter, and finally, the strictest one is - bound-by-observation. -
- Date - - Constraint uses a date range when determining eligibility. -
- Occurrence - - Constraint is by the number of occurrences an item is documented. -
- Value - - Constraint is by the value associated to a concept or modifier. Not all items have values. -
- -

Note: In the - client, the value constraints are currently the only ones that directly correspond to - a single concept. All others are defined on the query or Group level.

- -

Group Binding Constraints

- -

Group binding constraints utilize the encounter/observation - information along with the items defined to determine if a patient meets the search - criteria.

- -

Note that this is previously known as Panel Timing in the - classic Query Tool. In the classic Query Tool, users can also specify - Query Timing. In the Temporal Query Tool, Query Timing is automatically set by - the choice of Group Bindings. That is, the strictest Group Binding dictates what the - Query Timing is:

- -

-          if there is a - Group that is "bound-by-observation," then the query timing will be - "bound-by-observation" (or in the classical terminology, "same instance.")

- -

-          If there is a - Group that is bound-by-encounter," but no Groups "bound-by-observation," then the - query timing will be "bound-by-encounter," (or classically, "same encounter.")

- -

-          Otherwise the - query timing is "bound-by-patient" ("treat independently.")

- -

Group Binding

- -

Group Binding sets the binding for each Group. Possible values - are Bound-by-Patient, Bound-by-Encounter, and - Bound-by-Observation. These constraints tell the query processor that these - Groups describe the same patient, encounters or observation.

- -

In step 1, the default binding for each Group changes - depending on whether users are defining a Patient Population or an Encounter - Population. If Patient Population is used, then Bound-by-Patient is the - default, and it is unchangeable. If Encounter Population is used, then - Bound-by-Encounter is the default. However, in this case, users can change - each Group's binding to Bound-by-Patient if they so desire or to - Bound-by-Observation if a modifier term is used in that Group.

- -

Users can select one of three available options:

- -

1.       (Bound-by-Patient) The - items (facts) can occur at any time in the patient's history.

- -

2.       (Bound-by-Encounter) The - items (facts) occur during the same encounter (e.g. visit to hospital).

- -

3.       (Bound-by-Observation) The - items (facts) occur during the same observation.

- -

The values are hierarchical: a Group that is - bound-by-observation is also bound-by-encounter and bound-by-patient. A group that is - bound-by-encounter is also bound-by-patient. Every group is bound-by-patient.

- -

The Group Binding for a Group can be set by launching - the Group Binding Editor, by clicking on the highlighted area in a Group:

- -

- -

The Group Binding Editor consists of 3 rows, each representing - a possible Group Binding value. Selecting one will set the value. - -

Users can also set the Group binding for all - Groups using the Group Binding Control Panel in the Supplemental - Control Panel in Step 1.

- -

Bound-by-Patient

- -

The items (facts) can occur at any time in the patient's history.

- -

- -

Bound-by-Encounter

- -

The items (facts) occur during the same encounter (e.g. visit to hospital).

- -

- -

Example:

- -

Patient has a diagnosis of Acute MI documented at any time in their history and they have a medication with a dose greater - than 500 mg and a medication that is taken once a day documented - during the same encounter.

- -

qtTimingExample4

- -

RESULTS: In our database, there are 4 patients who have - had a medication with a dose greater than 500 mg and a frequency of once a day - entered as a fact in the observation_fact table, where the medication dose and - frequency have the same encounter_num AND the - diagnosis of acute MI, the medication dose and frequency all have the same patient_num.

- -

Bound-by-Observation

- -

The items (facts) listed in the panel occur during the same observation of a visit.

- -

Example:

- -

Patient has a diagnosis of Acute MI documented at any - time in their history and they have a medication with a dose greater - than 500 mg and a medication that is taken once a day documented - during the same instance.

- -

qtTimingExample5

- -

RESULTS: In our database, there are 3 patients who - have had a medication with a dose greater than 500 mg and a frequency of once a - day entered as a fact in the observation_fact table, where the medication dose - and frequency have the same encounter_num AND instance_num - AND the diagnosis of acute MI, the medication dose and frequency all - have the same patient_num.

- -

Date Constraint

- -

Users can define a date range to be used when querying the - database. This date range can be in any one of the following combinations. Note that - all start and end dates are inclusive.

- -

SPECIFIED DATE RANGE: FROM AND TO - DATES DEFINED

- -

Only data with activity within the defined date range will be used.

- -

Example:

- -

qtConstDateSelect

- -

Concept: Acute Myocardial Infarction

- -

From date: 01/01/2001

- -

To date: 12/31/2005

- -

In this example, if a patient has a diagnosis of - Acute Myocardial Infarction (MI) entered on the record from 01/01/2001 to 12/31/2005 - then their data will be included. If the patient does have an MI diagnosis but it was - entered prior to 01/01/2001 or after 12/31/2005 then their information will not be - included.

- -

SPECIFIC START DATE: ONLY THE FROM DATE - IS DEFINED

- -

Data from the defined start date to the latest date available. No end date defined.

- -

Example:

- -

qtConstDateFrom

- -

Concept: Acute Myocardial Infarction

- -

From date: 01/01/2001

- -

To date:

- -

In this example, if a patient has a diagnosis of - Acute Myocardial Infarction (MI) entered on the record any time on or after - 01/01/2001 will be included. If the diagnosis was entered prior to 01/01/2001 then - the data will not be included.

- -

SPECIFIC END DATE: ONLY THE TO DATE IS - DEFINED

- -

All data up until the defined end date. No start date - defined.

- -

Example:

- -

qtConstDateTo

- -

Concept: Acute Myocardial Infarction

- -

From date:

- -

To date: 12/31/2005

- -

In this example, if a patient has a diagnosis of - Acute Myocardial Infarction (MI) entered on the record prior to and including - 12/31/2005 then their data will be included. If the diagnosis was entered after - 12/31/2005 then it will not be included.

- -

SETTING THE DATE CONSTRAINT

-
    -
  1. Click on the Dates button located in the selection criteria section of the panel.
  2. -

    qtConstDateSelect

    -
  3. A new window will open.
  4. -

    qtConstDateWindow

    -
  5. Click the check box next to the date in the From box.
  6. -
  7. At this point there are two methods of entering your starting date.
  8. -
      -
    1. Manually type it in the text box.
    2. -
    3. Click on the drop-down arrow (dropDownArrow) to open the calendar view and click on the desired date. -
    4. -

      qtConstDateCal1

      -

      Once you click on the desired date the calendar window will close.

      -

      qtConstDateFrom

      -
    -
  9. Click the check box next to the date in the To box.
  10. -
  11. Highlight the default date or click on the drop-down arrow and enter the date you want to use as your ending date. -
  12. -

    qtConstDateFromTo

    -
  13. Click on the OK button.
  14. -
  15. Dates will now be underlined to indicate a date constraint has been set.
  16. -

    qtConstDateSet

    -
-

Occurrences Constraint

- -

Users can define a number of times an item has to occur in - order to be considered a positive "hit". Please note that the Occurrence - Constraint and Exclusion from the classic query tool have been rolled into - the same constraint. Here is an example of conversions from the classical query tool - occurrence and exclude specification to the new occurrence constraint - specification:

- -

1.       - (Exclude 1) (exclude anyone who has one or more occurrence of the desired - terms) -> Edit the occurrence to (=0).

- -

2.       - (Exclude 2) (Exclude anyone who has two or more occurrences of the desired - terms) -> Edit the occurrence to (<2).

- -

3.       - (1) (Only take those who have one or more occurrences of the desired terms) - -> Edit the occurrence to (>0). (This is the default)

- -

4.       - (2) (Only take those who have two or more occurrences of the desired terms) - -> Edit the occurrence to (>2).

- -

Setting the Occurrences Constraint

- -

1.       Click on the Occurrence Count - Control located in the top part of a Group Panel.

- -

qtConstOccurSelect

- -

2.       - The Occurrence Count Editor will open.

- -

qtConstOccurWindow

- -

3.       Use the dropbox to select the - desired operator and the spinner to choose the desired number. The dropbox has the following options:

- -

qtConstOccurSelection

- -

4.       Click on the OK button to accept.

- -

5.       Occurrence Count Control will - update to the new constraint (4 examples provided below):

- -

qtConstOccurSet

- -

Different operator/number combinations will have different - background. The default (>0) is white with gray text. If the operator is > and - the number is greater than 0, then it will be green. If the operator is < or =, - then the background will be pink. Please note that choosing the equal (=) - operator restricts the number to zero (0) - you cannot choose equals x - (=x), where x is any non-zero number.

- -

Value Constraint

- -

Value constraints can be associated with concept and modifiers - but not all of them will have values. For instance, the diagnosis of Acute Myocardial - Infarction does not have a value but the tests used to make the diagnosis do have - values (high/ low flags, or numeric values, etc.).

- -

Flag Value

- -

Flags are defined in the source system when the value is entered. The following are some examples that can be found in the i2b2 Demo database. -

- - - - - -

Setting the Value Constraint (Flag) for a Concept

- - - - - - -
-

NOTE:

-

- The value constraint window will open automatically when you drop a concept into a panel in the Query Tool view. This will only happen if the concept is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. -

-
- - - -
    -
  1. Using the right mouse button, click on the item listed in the panel.
  2. -
  3. A pop-up menu will open.
  4. -
  5. Select Set Value from the list.
  6. - - -

    qtConstValSelect

    - - - -
  7. A new window will open.
  8. - - -

    qtConstValTropI1

    - - - -
  9. Click on the radial dial next to By flag.
  10. -
  11. A new field with a drop-down selection box will appear.
  12. - - -

    qtConstValTropI2

    - - - -
  13. Click on the drop-down arrow to change the flag or accept the default.
  14. -
  15. Click on the OK button.
  16. -
  17. The value constraint has been set.
  18. - - -

    qtConstValTropI3

    -
- - - -

Setting the Value Constraint (Flag) for a Modifier

- - - - - - -
-

NOTE:

-

- The modifier value constraint window will open automatically when you drop a modifier into a panel in the Query Tool view. This will only happen if the modifier is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. -

-
- - - -
    -
  1. Using the right mouse button, click on the item listed in the panel.
  2. -
  3. A pop-up menu will open.
  4. -
  5. Select Set Value from the list.
  6. - - -

    qtConstValSelectMod

    - - - -
  7. A new window will open.
  8. -
  9. Click on the radial dial next to By flag.
  10. -
  11. A new field with a drop-down selection box will appear.
  12. -
  13. Click on the drop-down arrow to change the flag or accept the default.
  14. -
  15. Click on the OK button.
  16. -
  17. The value constraint has been set.
  18. -
- - - -

Text Value

- -

The text value is defined in the source system when the value is entered. The following are some examples that can be found in the i2b2 Demo database. -

- - -

Setting the Value Constraint (Text) for a Concept

- - - - -
-

NOTE:

-

- The value constraint window will open automatically when you drop a concept into a panel in the Query Tool view. This will only happen if the concept is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. -

-
- - - -
    -
  1. Using the right mouse button, click on the item listed in the panel.
  2. -
  3. A pop-up menu will open.
  4. -
  5. Select Set Value from the list.
  6. - - -

    qtConstValSelect

    - - - -
  7. A new window will open.
  8. - - -

    qtConstValCkmb1

    - - - -
  9. Click on the radial dial next to By value.
  10. -
  11. A new field listing the enumerated values will appear.
  12. -
  13. Click on the name of the value you want to include.
  14. - - -

    qtConstValCkmb2

    - - - - - - - -
    -

    TIP:

    -

    - To select more than one you can hold down the <Ctrl> key while clicking on each name. On the Macintosh you can hold down the command key instead of the <Ctrl> key. -

    -
    - - - -
  15. Click on the OK button.
  16. -
  17. The value constraint has been set.
  18. - - -

    qtConstValCkmb3

    -
- - - -

Setting the Value Constraint (Text) for a Modifier

- - - - - - -
-

NOTE:

-

- The modifier value constraint window will open automatically when you drop a modifier into a panel in the Query Tool view. This will only happen if the modifier is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. -

-
- - - -
    -
  1. Using the right mouse button, click on the item listed in the panel.
  2. -
  3. A pop-up menu will open.
  4. -
  5. Select Set Modifier Value from the list.
  6. - - -

    qtConstValSelectMod

    - - - -
  7. A new window will open.
  8. - - -

    qtConstValTrimoxFreq1

    - - - -
  9. Click on the radial dial next to By value.
  10. -
  11. A new field listing the enumerated values will appear.
  12. -
  13. Click on the name of the value you want to include.
  14. - - -

    qtConstValTrimoxFreq2

    - - - - - - - -
    -

    TIP:

    -

    - To select more than one you can hold down the <Ctrl> key while clicking on each name. On the Macintosh you can hold down the command key instead of the <Ctrl> key. -

    -
    - - - -
  15. Click on the OK button.
  16. -
  17. The value constraint has been set.
  18. - - -

    qtConstValTrimox3

    -
- - - -

Numeric Value -

The numeric value is defined in the source system when the result is entered. The following are some example formats that can be found in the i2b2 Demo database. -

- - - - -

Unlike flag and text values, numeric values use operators, such as greater than or less than when setting the constraints. The following is a listing of operators currently in use. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperatorDescription / Use
Less Than (<)Any value less than the number entered.
Less Than or Equal To (<=)Any value less than or equal to the number entered (inclusive).
Equal To (=)An exact match to the number entered.
BetweenAny value in the range of numbers entered.
Greater Than (>)Any value greater than the number entered.
Greater Than or Equal To (>=)Any value greater than or equal to the number entered (inclusive).
- - - -

Setting the Value Constraint (Numeric) for a Concept

- - - - - - -
-

NOTE:

-

- The value constraint window will open automatically when you drop a concept into a panel in the Query Tool view. This will only happen if the concept is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. -

-
- - - -

-
    -
  1. Using the right mouse button, click on the item listed in the panel.
  2. -
  3. A pop-up menu will open.
  4. -
  5. Select Set Value from the list.
  6. - - -

    qtConstValSelect

    - - - -
  7. A new window will open.
  8. - - -

    qtConstValCpk1

    - - - -
  9. Click on the radial dial next to By value.
  10. -
  11. Two new fields will appear; one with a drop down selection box and the other a text box.
  12. - - -

    qtConstValCpk2

    - - - -
  13. Click on the drop-down arrow to change the operator or accept the default.
  14. - - -

    qtConstValOperator

    - - - -
  15. Enter a numerical value at the Please enter a value field.
  16. - - -

    qtConstValEnter

    - - - -
  17. Click on the OK button.
  18. -
  19. The value constraint has been set.
  20. - - -

    qtConstValCpk3

    -
-

- - - -

Setting the Value Constraint (Numeric) for a Modifier

- - - - - - -
-

NOTE:

-

- The modifier value constraint window will open automatically when you drop a modifier into a panel in the Query Tool view. This will only happen if the modifier is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. -

-
- - - -

-
    -
  1. Using the right mouse button, click on the item listed in the panel.
  2. -
  3. A pop-up menu will open.
  4. -
  5. Select Set Modifier Value from the list.
  6. - - -

    qtConstValSelectMod

    - - - -
  7. A new window will open.
  8. - - -

    qtConstValTrimoxDose1

    - - - -
  9. Click on the radial dial next to By value.
  10. -
  11. Two new fields will appear; one with a drop down selection box and the other a text box.
  12. - - -

    qtConstValTrimoxDose2

    - - - -
  13. Click on the drop-down arrow to change the operator or accept the default.
  14. - - -

    qtConstValOperator

    - - - -
  15. Enter a numerical value at the Please enter a value field.
  16. - - -

    qtConstValEnter

    - - - -
  17. Click on the OK button.
  18. -
  19. The value constraint has been set.
  20. - - -

    qtConstValTrimoxDose3

    -
- - - -

Using Units In Value Constraints

-

Units in regards to i2b2 are the standard units of measurement associated with a value. For instance, a medication may have "mg" listed as the unit for the dose, while a HGB lab test may have "gm/dL". -

- -

The units are defined in the source system and although it is recommended that all numerical facts are stored in normalized units it is recognized that this is not always feasible. Therefore, the Web Client has the ability to convert the units when running a query. -

- -

In order for this feature to work a parameter called CRC_ENABLE_UNITCD_CONVERSION must be defined for the project. If this is not defined you need to contact your system administrator. -

- - - -

Defining the Units When Running a Query

- - - - - -
-

NOTE:

-

- The modifier value constraint window will open automatically when you drop a modifier into a panel in the Query Tool view. This will only happen if the modifier is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. -

-
-
    -
  1. Using the right mouse button, click on the item listed in the panel.
  2. -
  3. A pop-up menu will open.
  4. -
  5. Select Set Modifier Value from the list.
  6. -

    qtConstValSelectMod

    -
  7. A new window will open.
  8. -

    qtConstValUnits1

    -
  9. Click on the radial dial next to By value.
  10. -
  11. Two new fields will appear; one with a drop down selection box and the other a text box.
  12. -

    qtConstValUnits2

    -
  13. The Units will default to the normal units defined for the item.
  14. -
  15. Click on the drop-down arrow to change the units.
  16. -

    qtConstValUnitsList

    -
  17. Click on the drop-down arrow to change the operator or accept the default.
  18. -

    qtConstValOperator

    -
  19. Enter a numerical value at the Please enter a value field.
  20. -

    qtConstValEnter

    -
  21. Click on the OK button.
  22. -
  23. The value constraint has been set and the numerical value has been converted to the normal units.
  24. -

    qtConstValUnits3

    -
-

In the above scenario, the normal units are "mg". When setting up the value constraint the units were changed to "gm" and the numerical value was set to 5. Upon saving the value constraint, the Web Client converted 5 gm to 5000 mg. When the query is run it will look at those facts that have both 5 gm and 5000 mg defined in the observation_fact table. - - - - -
-

NOTE:

-

- The unit conversion information is specific to the term and is defined in the i2b2 metadata table. -

-
- -

Running a Query

- -

This section describes the process of running a query and getting results.

- - - -

Before users submit their query to the server, they must - select the analysis types they want from the Analysis Type Area in Step 3. There are - several result types available, each of which will yield a different output.

- -

qtRunQueryWindow

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Patient list - - Provides a set of patients who met the search criteria. -
- Event list - - Provides a set of encounters for those patients who met the search criteria. -
- Number of patients - - Provides the total number of patients who met the search criteria. -
- Gender patient breakdown - - Provides a breakdown of the patients by their gender. -
- Vital Status patient breakdown - - Provides a breakdown of the patients by their vital status. -
- Race patient breakdown - - Provides a breakdown of the patients by their race. -
- Age patient breakdown - - Provides a breakdown of the patients by their age -
- Timeline - - Provides a set of patients who met the defined criteria and automatically generates a timeline in the timeline view. -
- -

By default Number of patients and Timeline are selected.

- -

Patient List

- -

This option will return a list of patients who met the defined - criteria and will add the query and patient list to the previous query view.

- -

pqPtSet

- -

Event List

- -

This option will return a set of encounters for those patients - who meet the defined criteria and will add the query and patient list to the - previous query view.

- -

pqEncSet

- -

Number of Patients

- -

This option will return a total count for those patients who - meet the defined criteria and will display the appropriate information in the - following two views.

- -

Previous Query View - displays the query and the results returned.

- -

pqPtCount

- -

Note: The number - is displayed in the tool tip, which can be seen by hovering over Number of - Patients.

- -

Gender Patient Breakdown

- -

This option will return a breakdown by gender for those - patients who meet the defined criteria and will display the appropriate information - in the following two views.

- -

Previous Query View - displays the query and the results returned.

- -

pqGender

- -

Vital Status Patient Breakdown

- -

This option will return a breakdown by vital status for those - patients who met the defined criteria and will display the appropriate information in - the following two views.

- -

Previous Query View - displays the query and the results returned.

- -

pqVitalStatus

- -

Race Patient Breakdown

- -

This option will return a breakdown by race for those patients - who met the defined criteria and will display the appropriate information in the - following two views.

- -

Previous Query View - displays the query and the results returned.

- -

pqRace

- -

Age Patient Breakdown

- -

This option will return a breakdown by age for those patients - who met the defined criteria and will display the appropriate information in the - following two views.

- -

Previous Query View - displays the query and the results returned.

- -

pqAge

- -

Timeline

- -

This option will return a list of patients who met the defined - criteria and will display the appropriate information in the following two views. The - current implementation of Temporal QueryTool does not automatically launch the - Timeline visualization. Instead, users will need to drag the previous query (or the - patient set) and drop it into Timeline's configuration panel.

- -

1.       - Timeline View - displays the patients and associated concepts in the format of - a timeline.

- -

- -

2.       - Previous Query View - displays the query and the results returned.

- -

- - - -

Once the query has been created and the Analysis types - selected, the final step to retrieve your information is to run the query. This is - done by clicking on the Submit Query in the query tool.

- -

qtToolbarRunQuery

- -

- Once you begin the process of running the query the button become inactive, and a processing indicator will appear: -

- -

qtQueryStatusRunMI

- -

When the query process concludes, the results will be shown:

- -

queryStatusFinish

- -

If the query takes longer than the Web Client expects, the - query will be queued up on the server side and will be finished at a later time. An - entry is created in the Previous Query view immediately and users are to check - the entry periodically to see when the query completes. The following message will - also be displayed at the Footer. The Submit Query button will become active so - users can submit another query.

- -

-

Cancel a Query

- -

To cancel a query you simply click on the Cancel Query button.

- - - - - -
-

NOTE:

- -

- Keep in mind "Cancel Query" and the associated action will only appear when the query is still in the process of running -

-
- -
    -
  1. To cancel a query that is running, simply click on the Cancel Query button. -

    qtToolbarCancelQuery

    -
  2. - -
  3. Cancel will display in the Query Status view. - -

    qtQueryStatusCancel

    -
  4. -
- -

Saving a Query

- -

A previous query () is created automatically when the query is - run from the Temporal Query Tool. The query is stored and displayed in the - Previous Query View. Temporal Query Tool does not currently support - saving query definitions.

- -

Note: Previous - queries can also be seen in Workplace View if the user copied it to their workplace - or shared folder in workplace view.

- -

1.       Run a query.

- -

2.       Go to the Previous Query View.

- -

3.       - The query you just ran will now appear in the list of previous queries.

- -

pqView

- - -

Printing a Query

-

Users are able to print out the query information if they wish to have a hard copy of the search criteria defined for a query.

- -

When printing a query you can either print the information for a current query or - you can drag a previous query to the query tool view and print the information - associated with that query.

-

The following steps outline the process of printing a query once you have the - appropriate query in the Query Tool.

-
    -
  1. Click on the Print Query button located on the toolbar at the bottom of the Query Tool view -

    qtToolbarPrintQuery

  2. - -
  3. A new window will open displaying the information about the query. -

    qtPrintWindow

    -
  4. - -
  5. On the menu bar, click on File to display the menu options.
  6. - -
  7. Select Print from the menu.
  8. -
-
- - + + + + + i2b2 Temporal Query Tool View + + + + + + +
+

i2b2 Temporal Query Tool View

+ +

The Temporal Query Tool view extends the query functionalities + provided by the classic Query Tool view. Users can submit temporal queries to using + the Temporal Query Tool view.

+ +

i2b2 Temporal Query Tool View

+ +

The Temporal Query Tool view extends the query + functionalities provided by the classic Query Tool view. Users can create and + submit temporal queries to using the Temporal Query Tool view. It submits a + "select query" that will retrieve information from the database associated to the + i2b2 Web Client.

+ +

Introduction

+ +

The interface is organized to facilitate the temporal querying + process. There are three main steps in the process: Defining a population, defining + temporal relationships, and reviewing and submitting query. The interface is designed + to take users through each of these three steps. The section below describes the + interface for each step in detail.

+ + + +

The image below shows the starting point of the Temporal + Query Tool view interface along with its annotations. Users would interact with + the Group Panels to define a population they are interested in. In the next + step, users would define the temporal relationships they are interested in. Finally, + users would review and submit their queries in the third step. This section breaks + down the interface for the 1st step.

+ +

+ +

The Patient/Encounter Dropdown Box allows users to + choose whether to define the population of the query using patients or encounters. + The default is Patient:

+ +

+ +

Creating a population is optional. Users can skip Step 1 to use all data in the database.

+ +

Group Panel

+ +

+ +

At the start up, the interface for Step 1 displays three + groups by default. Each of the groups contains several components. In general, all + areas bounded by an orange-yellow highlight are clickable.

+ +
    +
  1. + (Group Heading) The heading is a label to easily identify the collection of terms. + Each heading will contain "Group" followed by a sequential number.

    Example: Group 1, Group 2, Group 3, etc.

  2. + +
  3. + (Selection Criteria) This area of the panel is used to define date selections and other constraints.
  4. + +
  5. + (Panel Timing) The panel timing defines the constraint on the panel level and uses the patient's visits in determining eligibility.
  6. + +
  7. + (Group List) This section contains the terms that will be used during the process of querying the database.
  8. + +
  9. + (Delete Group) Clicking on this button will remove the group from the + query construction. Users should use it to quickly discard a group.
  10. + +
  11. + (Information Box) The content in the information box will change depending on whether or not a term is listed in the panel / group. +
      +
    • No term(s) listed +
        +
      1. The message will appear as "drop a term on here"
      2. +
      3. The color of the box will be yellow
      4. +
      +
    • +
    • Term(s) listed +
        +
      1. The message will appear as "one or more of these"
      2. +
      3. The color of the box will be green
      4. +
      5. An additional information box will appear between panels
      6. +
      +
    • +
    + +
  12. + +
+ +

New/Add Group Button

+ +

qtToolbarNewGroup

+ +

The New Group button lets users to quickly add additional Groups.

+ +

Query Drop Area

+ +

A previous query saved in Workplace view or in the + Previous Query view can be dragged and dropped here to reload the query. + Reloading a query will overwrite the current query information. If the previous query + is a temporal query, its population and temporal relationships will all be loaded. If + the previous query is a non-temporal query, only the population portion of the + temporal query interface will be loaded since a non-temporal query has no temporal + relationship information.

+ + + +

Step 2: Define Temporal Relationships is used to + define temporal relationships. It allows users to create a list of Events and + a list of Temporal Relationships. Users define a list of interested + Events and also define Temporal Relationships to describe how the + events are related temporally, e.g. Event A must occur before Event B.

+ +

The interface is therefore a bit more complicated than Step 1 + presented in the earlier section. It is broken into two major parts, presented below. + On the left are the Event in Query panel and the Show Population panel. + The Event in Query panel lets users define a list of Events. The Show + Population panel allows users see and change the population definition originally + defined in Step 1. On the right is a panel allowing users to add, remove, or modify + relationships among the events.

+ +

+ + + +

Events in Query Panel

+ +

(Event Panels at startup)

+ +

The Events in Query Panel allows users to add, remove, and + edit each Event. Each Event is represented by an Event Panel. An + Event consists of a list of Groups just like a population definition. Users + can add, remove, and edit each of the Groups in an Event by dragging + terms into a group, changing its constraints, etc. At startup, two empty + Events are added, each with a Group. More Events can be added by + clicking on the Add Event button.

+ +

One difference between an Event and a set of + Groups in Step 1 is that the first Group in an Event is special. + It cannot be removed (note the missing Remove Group button), and its Group + Binding Control is missing. The Group Binding for the 1st + Group of every Event is not changeable. All other Group's + Group Bindings are changeable. The first group anchors all other groups in an + Event. That is, the first Group determines the timing of the enclosing + Event with respect to the other Events temporally in the query.

+ +

Under the list of Events is the gray background, which serves + as a Query Drop Area. Users can drop previous query in the Query Drop + Area to overwrite the current query. It has the same effect as the Query Drop + Area in Step 1.

+ +

An Event Panel has several components.

+ +

+ +
    +
  1. + (Event ID) This area shows the Event's name and color. Clicking on this area + will expand/collapse the entire Event. When an Event Panel is + collapsed, all its Groups are hidden. Only a row that contains the Event + ID area is shown. Click on the Event ID area to expand the Event. + All Events are expanded when created. Color of an Event is assigned + only when at least one term has been added to it. +
  2. + +
  3. (Event-Wide Date + Constraints) Selecting this area allows users to specify date constraints for all + Groups in this Event. This serves a similar function as the + supplemental Query-wide Date Constraints Control Panel in the Step 1.
  4. + +
  5. (Remove Event Button) + Clicking this button will remove the Event, deleting all its content and + removing it from view.
  6. + +
  7. (Group Panel) The Group + Panel is the same as the ones in Step 1.
  8. + +
  9. (Add Group Button) + Clicking on it adds a new Group to the Event.
  10. +
+ +

+ +

The population in Step 1 is shown. The title changes to "Edit + Population," and every component is editable just as they are in Step 1.

+ +

Temporal Relationship Definition Panel

+ +

On the right hand side of the Step 3 interface is where users + can define how Events are related to one another temporally. The Temporal + Relationship Definition Panel contains a list of Temporal Relationship + Panels and an Add Temporal Relationship Button. These components are + described in detail below.

+ +

Please note that at least one Temporal Relationship + Panel must be filled before users can move on to Step 3. A Temporal + Relationship Panel is filled only if has a fulfilled Event in the Top Event + Definition dropdown box and a fulfilled Event in the Bottom Event + Definition dropdown box (see the image below). A fulfilled Event is one that has + at least a fulfilled Group. A fulfilled Group is one that contains at + least one term (not empty).

+ +

+ +
    +
  1. + The color indicator shows the colors of the Events + that are being referenced in the Temporal Relationship. The top color (green + in this example) matches the color of the Event in the Top Event + Definition row and the bottom color (orange) matches the color of the + Event in the Bottom Event Definition row. If an Event that has + no content is referred, no color will be displayed in the Color Indicator.
  2. + +
  3. + (Top Event Definition)This row allows users designate the first Event + in this Temporal Relationship. A second event is specified in the Bottom + Event Definition row. The dropdown boxes have the following choices: + +

    (Dropdown box options for Event Definition)

    +
  4. + +
  5. + (Event Ordering) This dropdown box describes how the Top Event elates + to the Bottom Event. + +

    (Dropdown box options for Event Ordering)

    +
  6. +
  7. + (Bottom Event Definition) This row allows users designate the second + Event in this Temporal Relationship. It has the same dropdown box + options as Top Event Definition.
  8. + +
  9. + (Occurrence Temporal Constraint) Users can optionally describe the specified + Event Ordering by a time range, creating the bolded part of, for example, + "Event 1 Occurs Before Event 2 By > 5 day(s)." This additional temporal + constraint can be a bounded range such as "By > 5 day(s) And < 10 + day(s)." Users must first check the "By" checkbox to enable the dropdown + boxes on that row. The "And" checkbox becomes enabled only when the + "By" checkbox is checked. Checking the "And" checkbox enables the + dropdown boxes on its row. Both the By row and the And row have the + same options depicted below. + +

    + (Options for Occurrence Temporal Constraint) +

    +
  10. + +
  11. + (Add Temporal Relationship Button) This adds a new Temporal Relationship Panel + should users require more relationship constraints among Events.

    +
  12. +
+ + +

The last step allows users to review and modify the name of + the query and selection of analyses types they want the server to return as the + results of the query.

+ +

qtRunQueryWindow

+ +

Query Name Area

+ +

Upon entering Step 3, a query name is automatically generated. + A "(t)" prefix indicates the query is a temporal query, differentiating it from + normal queries submitted using the classic query tool. Some terms used in the query + are then appended to identify this query. A timestamp is added at the end. Users may + modify the query name however they wish. The name in the Query Name Area will + be displayed in the Previous Query view once the query is submitted

+ +

Analysis Type Area

+ +

The area presents the different analyses types users can + select as results of the query. They are exactly the same as the ones from the + classic Query Tool:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Table of Result Types +
+ Patient list + + Provides a set of patients who met the search criteria. +
+ Event list + + Provides a set of encounters for those patients who met + the search criteria. +
+ Number of patients + + Provides the total number of patients who met the + search criteria. +
+ Gender patient breakdown + + Provides a breakdown of the patients by their gender. +
+ Vital Status patient breakdown + + Provides a breakdown of the patients by their vital + status. +
+ Race patient breakdown + + Provides a breakdown of the patients by their race. +
+ Age patient breakdown + + Provides a breakdown of the patients by their age +
+ Timeline + + Provides a set of patients who met the defined criteria + and automatically generates a timeline in the timeline view. +
+
+ +

By default Number of patients and Timeline are selected.

+ +

Run Query Button

+ +

In Step 3, the Footer is different. Instead of another "Next" + button, a Submit Query Button is there instead. It allows users to execute the + query they have built in Step 1 and Step 2.

+ +

After pressing Submit Query, the button will become inactive + to prevent inadvertent submission. A "Processing..." text will display to indicate + that the query is being sent to the server for processing. The red rectangular button + allows users to cancel the query submission.

+ +

queryStatusRun

+ +

When the server completes the processing, the number of patients found will be returned:

+ +

queryStatusFinish

+ +

If the query takes too long, a message will be + displayed instead, in addition, the Submit Query Button will become available + again. Users are advised to monitor the Previous Queries view to see when the + query finishes.

+ + + + + + +
+

NOTE:

+

+ The result types that appear will depend on what you have selected when running the query.. +

+
+ + + +

Many of the UI elements discussed above are for display only. + That is, they display the content of a Group or an Event or a Query, but they do not + themselves allow editing of the values. Instead, users have to click on display + components to launch an editor. The various editors are presented here.

+ +

This dialogs are all modal. That means no other actions can be + performed when the dialog is launched. Users must first dismiss (typically by either + selecting OK or Cancel) the dialog before other UI elements in the Web Client can be + interacted with.

+ +

The dialogs can be moved by dragging the blue title area + around, and they usually appear where the mouse pointer is when launched.

+ +
    +
  1. + (Date Constraint Editor) The Date Constraint Editor is launched when + user clicks on a Date Constraint Control in every Group Panel, in the + title area of an Event, in the Supplemental Control Panel in Step 1, + and in the View Population Panel in Step 2.

    + +

    The editor starts up as the left-most figure below. Clicking + on either of the orange-yellow-highlighted textboxes will launch a calendar widget + for users to select the start (middle figure) or the end date (right-most figure). + When finished, users should click on the OK button in the gray footer area to + accept the constraints. Alternatively, clicking the Cancel button will leave + the original date constraints unmodified.

    + +

    The start and end date constraints are both inclusive. That is + if the start date is January 1, 1999, and the end date is December 31, 1999, the + range of the constraint spans from 1/1/1999 00:00:00.000 to 12/31/1999 + 23:59:59.999.

    + +

    qtConstDateWindow

    +
  2. + +
  3. + (Group Binding Editor) The Group Binding Editor is found in every + Group Panel. It lets users change the binding for that Group. The left + figure depicts the initial appearance when a Group Binding Editor is launched. + It consists of three rows, each represent a binding option. The last option + (Bound-by-Observation) is only available as a choice if a modifier is dropped + in the Group. Selecting one of the radio buttons and clicking on OK + will set the new binding. Cancel will cancel the operation and leave the + original binding unmodified.

    + +

    +
  4. + +
  5. + (Occurrence Count Constraint Editor) This editor can be launched in every + Group by clicking on its Count Control area. Users can specify how many (or + few) times the terms in a Group must occur. The editor itself is simple: a + dropdown box specifies the type of operator and a spinner allowing for a number to be + specified.

    + +

    The left figure shows the dialog at startup, and the right + figure shows all the operator options.

    + +

    qtConstOccurSelectqtConstOccurWindow

    +
  6. + +
  7. + (Value Editor) When users drop an ontology term that can be further + constrained by values into a Group, a Value Editor will automatically + launch. Users can use this editor to select a way to constrain the value of the term + and specify what values to constrain the term by. If a term that supports values + already exists in a Group, users can right click on the term and select + "Edit Value..." to launch the Value Editor for that term. Please note + that some Modifiers do not support values (e.g. Circulatory Systems [Primary + diagnosis]).

    + +

    qtConstValSelect(Right click on a term that supports value + constraints to launch the Value Editor)

    + +

    Note that the constraint is optional. The default constraint + put on these terms is "No Value," and by closing the dialog immediately, users + can quickly accept the default constraint. Please note that closing the dialog does + not cancel the value editing operation, it instead accepts the values that are + currently set.

    + +

    If multiple terms were dropped at the same time, all terms + that support value constraints in the same drop will appear in a list the left side + of dialog. Users can select the terms on the list to view and edit its value + constraint. Alternatively, users can use the navigation buttons "Previous", + "Next" to navigate. Finally, to finish, users should select the last term on + the list and click on "Finish."

    + +

    qtConstValTropI1(The Value Editor + shows two terms on its list on the left. The right half shows the currently set value constraints for the selected + term on list. The default is "No Value." Users can also navigate the list by using + the "Next" "Previous" buttons on the bottom of the right half. When + finished, click on the "Finish" button or simply close the dialog.)

    + +

    Different terms support different kinds of value constraint, + some are constrained by text, some by numeric value, some by a list of pre-arranged + values, and some by abnormal flags. For example, the Color term supports abnormal + flags and a list of pre-arranged values. These options are shown on the right half of + the dialog. By selecting the radio buttons, users can choose the kind of constraint + they want. Here are the screen shots of the right half of the dialog when radio + buttons other than "No Value" are chosen for the term Color.

    + +

    qtConstValTropI2qtConstValCpk2

    +
  8. +
+ +

Creating a Query

+ +

This section describes the process of adding items to the + query tool, "AND" / "OR" operators and setting constraints.

+ + + +

In order to create your query, you will need to define what + information will be retrieved from the databases. Selected items from other i2b2 + Web Client views can be dragged and dropped (copied) into the Temporal Query + Tool view.

+ +
    + +
  1. Concepts + +

    Concepts () can be defined as terms, + results, providers, etc. They can be added as a group (folder ()) or + individually by dragging the item(s) from Navigate Terms, Find Terms, + and Workplace views.

    +
  2. + +
  3. Modifiers + +

    Modifiers () + are associated with a concept or group of concepts. They can be added as a group (modifier folder + ()) or + individually by dragging the item(s) from Navigate Terms, Find Terms, and Workplace views.

    +
  4. + +
  5. Previous Query + +

    A new query can be created from one that has already + been run by dragging the previous query ( + or) + from Previous Query and Workplace views.

    +
  6. + +
  7. + Patient List + +

    A patient list () + can be used in a query by dragging the item(s) from Previous Query and Workplace views.

    +
  8. + +
  9. Individual Patient + +

    A patient () or several patients can be used in a + query by dragging them from Previous Query view and Workplace views.

    +
  10. + +
  11. Event List + +

    An event list () + can be used in a query by dragging the item(s) from Previous Query and Workplace views.

    +
  12. +
  13. Query Definition + +

    A new query can be created from one that has already + been run by dragging the query definition () + from the Workplace view.

    +
  14. +
  15. Group Template + +

    Users can define a group of concepts that they + frequently run and save them in their workplace view. This grouping of concepts is + referred to as a group template ().

    + +

    A new query can be created using the group template + by dragging the template from Workplace view to the Group Header.

    +
  16. +
+
+

Operators

+
+ +

There are two operators, known as SQL Logical + Operators, which are necessary when running a query that has more than one term. + These operators provide a way to specify exactly what users want to retrieve. The + operators are the 'AND' and 'OR' operators.

+ +

The query tool knows which operator to use based on the panels + used when defining the query. It is important to verify the users are setting up + their query correctly as each operator will return different results.

+ +

AND Operator

+ +

The AND operator returns a record if both the first + condition and the second conditions are true.

+ +

The query tool uses the AND operator when concepts are listed + in different panels.

+ +

Example:

+ +

WHAT: Return only those patients who have + Acute Myocardial Infarction AND Angina Pectoris.

+ +

HOW: In the query tool add the concept Acute + Myocardial Infarction to Group 1 and then add the concept Angina Pectoris to Group 2 + .

+ +

RESULT: The population is limited by + requiring the patients to have both Acute myocardial infarction and Angina pectoris..

+ +

+ +

OR Operator

+ +

The OR operator returns a record if either the first + condition or the second conditions is true.

+ +

The query tool uses the OR operator when concepts are listed + in the same panel.

+ +

Example:

+ +

WHAT: Return any patients who have Acute + Myocardial Infarction or Angina Pectoris associated to them.

+ +

HOW: In the query tool you add both concepts, + Acute Myocardial Infarction and Angina Pectoris, to Group 1.

+ +

RESULT: The population is limited to include + all patients who fit either one of those criteria.

+ +

+ +

In short, terms within a Group are ORed + together, while different Groups are ANDed together.

+ + + +

Concepts can be added to the Query Tool view by simply + dragging the concept from one of the following views.

+ +

1.  Navigate Terms view

+ +

2.  Find Terms view

+ +

3.  Workplace view

+ +

How to add a concept from each of these views is explained in the next few sections.

+ +

Navigate Terms View

+ +

The Navigate Terms view contains a hierarchical display + of all the items that can be used to search the database.

+ +

Note: How the + items are grouped and displayed is dependent on how the database is setup.

+ +

+ +

Add Concept From Navigate Terms View

+ +

1.      In the Navigate Terms view, + expand the folder(s) that contain the concept or grouping of concepts that you want to add.

+ +

2.       Highlight the concept + () or folder + () by clicking on its name.

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the item into the panel + labeled Group 1.

+ +

+ +

5.       The item will now display in the + panel for Group 1.

+ +

+ +

Find Terms View

+ +

The Find Terms view provides a way to search for a particular concept and modifier.

+ +

ftView

+ +

Add Concept From Find Terms View

+ +

1.       In the Find Terms view, + search for the item(s) you want to add.

+ +

2.       Highlight the concept + () or folder + () by clicking on its name.

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the item into the panel + labeled Group 1.

+ +

qtDragFolderCardioAgents

+ +

5.       The item will now display in the + panel for Group 1.

+ +

qtDropFolderCardio

+ +

Workplace

+ +

Information in the Workplace is related to the most + common concepts, modifiers, and queries that an individual uses and in essence + becomes their personal workplace.

+ +

wpView

+ +

Add Concept From Workplace View

+ +

1.       In the Workplace view, expand + the folder(s) that contain the concept or grouping of concepts you want to add.

+ +

2.       Highlight the concept + () or folder + () by clicking on its name.

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the item into the panel + labeled Group 1.

+ +

qtDragFolderCardioAgents

+ +

5.       + The item will now display in the panel for Group 1.

+ +

qtDragFolderCardioAgents

+ + + +

Modifiers can be added to the Query Tool view by simply + dragging the modifier from one of the following views.

+ +

1.  Navigate Terms view

+ +

2.  Find Terms view

+ +

3.  Workplace view

+ +

How to add a modifier from each of these views is explained in the next few sections.

+ +

Navigate Terms View

+ +

The Navigate Terms view contains a hierarchical display + of all the items that can be used to search the database.

+ +

Note: How the + items are grouped and displayed is dependent on how the database is setup.

+ +

ntView

+ +

Add modifier From Navigate Terms View

+ +

1.       In the Navigate Terms view, + expand the folder(s) that contains the modifier or grouping of modifiers that you + want to add.

+ +

2.       Highlight the modifier + () or modifier folder + () by + clicking on its name.

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the item into the panel + labeled Group 1.

+ +

qtDragFolderCardioAgents

+ +

5.       The item will now display in the + panel for Group 1.

+ +

qtDropFolderCardio

+ +

Find Terms View

+ +

The Find Terms view provides a way to search for a particular concept and modifier.

+ +

ftView

+ +

Note: For detailed + information on how to search for terms and modifiers, please see the i2b2 Find Terms View chapter.

+ +

Add Modifier From Find Terms View

+ +

1.       In the Find Terms view, + search for the modifier(s) you want to add.

+ +

2.       Highlight the modifier + () or modifier folder + () by clicking on its name.

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the item into the panel + labeled Group 1.

+ +

qtDragModPrincDx

+ +

5.       The item will now display in the + panel for Group 1.

+ +

qtDropFolderCardio

+ +

Workplace

+ +

Information in the Workplace is related to the most + common concepts, modifiers, and queries that an individual uses and in essence + becomes their personal workplace.

+ +

wpView

+ +

Add Modifier From Workplace View

+ +

1.       In the Workplace view, expand + the folder(s) that contain the modifier or grouping of modifiers you want to add.

+ +

2.       Highlight the modifier + () or modifier folder + () by clicking on its name.

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       + Drop the item into the panel labeled Group 1. +

+ +

qtDragModPrincDx

+ +

5. +        + The item will now display in the panel for Group 1. +

+ +

qtDropModPrincDx

+ + + +

A previous query can be used to run a new query or as + an item within a query (query-in-query). To add a previous query to the Query Tool + view simply drag the query name from one of the following views.

+ +

1.  Previous Query view

+ +

2.  Workplace view

+ +

Within the Query Tool view, the previous query can be added to one of the following two locations.

+ + + + + + + + + + + + + +
+ Query Name field + + The item(s) and constraints from the original query will + be used to create a new query. This information can be edited to make a new + query or can be used as is to run the query again. +

+ + Please note that the tool does not currently support + dropping of a previous query of a previous query or a previous query of a temporal query. +
+ Panel (Group) + + Used within a new query (query-in-query). Add additional search criteria (items) to be used in the new query. +
+ +

How to add a previous query from each of the views listed above is explained in the next few sections.

+ +

Previous Query View

+ +

The Previous Query view displays the queries that were run by the user.

+ +

pqView

+ +

Add Previous Query From Previous Query View (New Query)

+ +

1.       In the Previous Query view + highlight the previous query () by clicking on its name

+ +

2.       While holding the left mouse + button down, drag the item over to the Temporal Query Tool View.

+ +

3.       Drop the previous query into the + Query Drop Area in either Step 1 or Step 2.

+ +

4.       The terms, Groups, + Events, and Temporal Relationships defined in that previous query will + be reconstituted in the current interface. If the previous query is a non-temporal + query, then only the Population portion of the UI will be reconstituted. If the + previous query is a temporal query, then both the Population portion and the temporal + relationship portion of the UI will be reconstituted.

+ +

Add Previous Query From Previous Query View (Query-In-Query)

+ +

1.       In the Previous Query view + highlight the previous query () + by clicking on its name

+ +

2.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

3.       Drop the previous query into the + panel labeled Group 1.

+ +

4.       + The previous query will now display in the panel for Group 1.

+ +

qtDragPqToPanel

+ +

Workplace View

+ +

Information in the workplace is related to the most + common concepts, modifiers, and queries that an individual uses and in essence + becomes their personal workplace.

+ +

wpView

+ +

Add Previous Query From workplace View (New Query)

+ +

1.       In the Workplace view, expand + the folder(s) that contains the previous query you want to add.

+ +

2.       Highlight the previous query + () by clicking on its name

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the previous query into the + Query Drop Area in either Step 1 or Step 2.

+ +

5.       The terms, Groups, + Events, and Temporal Relationships defined in that previous query will + be reconstituted in the current interface. If the previous query is a non-temporal + query, then only the Population portion of the UI will be reconstituted. If the + previous query is a temporal query, then both the Population portion and the temporal + relationship portion of the UI will be reconstituted.

+ +

Add Previous Query From Previous Query View (Query-In-Query)

+ +

1.       In the Workplace view, expand + the folder(s) that contains the previous query you want to add.

+ +

2.       Highlight the previous query + () by clicking on its name

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the previous query into the + panel labeled Group 1.

+ +

5.       The previous query will now display in the panel for Group 1.

+ +

qtDropPqPanel

+ + + +

A patient list can be added to the Query Tool + view by simply dragging the list of patients from one of the following views.

+ +

1.  Previous Query view

+ +

2.  Workplace view

+ +

How to add a patient list from each of the views is explained in the next few sections.

+ +

Previous Query View

+ +

The Previous Query view displays the queries that were run by the user.

+ +

pqView

+ +

Add Patient List From Previous Query View

+ +

6.       In the Previous Query view + click on the plus sign () next to the name of the previous query that + contains the patient set.

+ +

7.       Click on the plus sign () next to the results folder.

+ +

8.       Highlight the patient list + () by clicking on its name

+ +

+ +

9.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

10.   Drop the patient set into the panel labeled Group 1.

+ +

qtDragPtSet

+ +

11.   The patient set will now display in the panel for Group 1.

+ +

qtDropPtSet

+ +

Workplace View

+ +

Information in the workplace is related to the most + common concepts, modifiers, and queries that an individual uses and in essence + becomes their personal workplace.

+ +

wpView

+ +

Add Patient List From Workplace View

+ +

12.   In the + Workplace view find the patient list you want to add.

+ +

13.   Highlight the + patient list () by clicking on its name

+ +

14.   While holding the + left mouse button down, drag the item over to the Query Tool View.

+ +

15.   Drop the patient set into the panel labeled Group 1.

+ +

16.   The patient set will now display in the panel for Group 1.

+ +

qtDropPtSet

+ + + +

An encounter set can be added to the Query Tool + view by simply dragging the encounter set from one of the following views.

+ +

1.  Previous Query view

+ +

2.  Workplace view

+ +

How to add an event list from each of the views is explained in the next few sections.

+ +

Previous Query View

+ +

The Previous Query view displays the queries that were run by the user.

+ +

pqView

+ +

Add Event List From Previous Query View

+ +

1.       In the Previous Query view + click on the plus sign () + next to the name of the previous query that contains the encounter set.

+ +

2.       Click on the plus sign + () next to the results folder.

+ +

3.       Highlight the encounter set + () by clicking on its name

+ +

4.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

5.       Drop the encounter set into the Group 1.

+ +

6.       The encounter set will now display + in the panel for Group 1.

+ +

qtDropEncSet

+ +

Workplace View

+ +

Information in the workplace is related to the most + common concepts, modifiers, and queries that an individual uses and in essence + becomes their personal workplace.

+ +

wpView

+ +

Add Event List From Workplace View

+ +

1.       In the Workplace view find + the encounter set you want to add.

+ +

2.       Highlight the encounter set + () by clicking on its name

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the encounter set into Group 1.

+ +

5.       The encounter set will now display + in the panel for Group 1.

+ +

qtDropEncSet

+ + + +

A query definition can be added to the query tool view by simply dragging the query name from the workplace view.

+ +

Add Query Definition From Workplace View

+ +

1.       In the Workplace view, find + the query definition you want to add.

+ +

wpView

+ +

2.       Highlight the query + definition () by clicking on its name

+ +

3.       While holding the left mouse + button down, drag the item over to the Query Tool View.

+ +

4.       Drop the query definition into the + Query Drop Area in Step 1 or Step 2.

+ +

5.       The item(s) associated with the + query definition will display in the appropriate group(s), the name of the query will + appear at Query Name, and any constraints that were defined when the original + query was run will now default with the new query.

+ + + +

Three Group Panels are displayed in Step 1 by default. + In step 2, only one Group Panel is available per Event. Some complex + queries may require the use of additional panels. Users may use the "Add Group" + button to add more Groups.

+ +

1.       + Click on the Add Group button.

+ +

qtToolbarNewGroup

+ +

(Add Group button in Step 1)

+ +

2.       + A new panel is added with each click (two clicks are performed here to create a total + of three Group Panels).

+ +

qtPanelAdd

+ +

In Step 2, there is an "Add Group" button for each Event, and + an additional one to add Group to the population. These "Add Group" button work + exactly the same as the one described above.

+ +

+ +

(Step 2 "Add Group" button)

+ + + +

Users can remove a Group from a query (or Event in the temporal query UI) or a term in a Group.

+ +

Remove Groups

+ +

1.       Click on the Remove Group + button () located to the right top of + every Group.

+ +

2.       The Group and all its content will be removed

+ +

+ +

Delete a Single Item

+ +

1.       Right click on the item in the group + that you want to remove.

+ +

deleteItem

+ +

2.       Select Delete Item from the list.

+ +

3.       The item will be removed from the + Group Panel

+ + + +

Constraints are used to narrow down the search criteria to a + particular time from, number of occurrences or a specific value or range of values. + In i2b2, there are several types of constraints that can be defined in the Query Tool + view.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Constraint Type + + Description +
+ Group Binding (Panel Timing) + + Constraint is defined on the Group and utilizes the + patient encounters and / or instance number when determining eligibility. There + are three binding choices. The most general one is bound-by-patient, followed + by bound-by-encounter, and finally, the strictest one is + bound-by-observation. +
+ Date + + Constraint uses a date range when determining eligibility. +
+ Occurrence + + Constraint is by the number of occurrences an item is documented. +
+ Value + + Constraint is by the value associated to a concept or modifier. Not all items have values. +
+ +

Note: In the + client, the value constraints are currently the only ones that directly correspond to + a single concept. All others are defined on the query or Group level.

+ +

Group Binding Constraints

+ +

Group binding constraints utilize the encounter/observation + information along with the items defined to determine if a patient meets the search + criteria.

+ +

Note that this is previously known as Panel Timing in the + classic Query Tool. In the classic Query Tool, users can also specify + Query Timing. In the Temporal Query Tool, Query Timing is automatically set by + the choice of Group Bindings. That is, the strictest Group Binding dictates what the + Query Timing is:

+ +

-          if there is a + Group that is "bound-by-observation," then the query timing will be + "bound-by-observation" (or in the classical terminology, "same instance.")

+ +

-          If there is a + Group that is bound-by-encounter," but no Groups "bound-by-observation," then the + query timing will be "bound-by-encounter," (or classically, "same encounter.")

+ +

-          Otherwise the + query timing is "bound-by-patient" ("treat independently.")

+ +

Group Binding

+ +

Group Binding sets the binding for each Group. Possible values + are Bound-by-Patient, Bound-by-Encounter, and + Bound-by-Observation. These constraints tell the query processor that these + Groups describe the same patient, encounters or observation.

+ +

In step 1, the default binding for each Group changes + depending on whether users are defining a Patient Population or an Encounter + Population. If Patient Population is used, then Bound-by-Patient is the + default, and it is unchangeable. If Encounter Population is used, then + Bound-by-Encounter is the default. However, in this case, users can change + each Group's binding to Bound-by-Patient if they so desire or to + Bound-by-Observation if a modifier term is used in that Group.

+ +

Users can select one of three available options:

+ +

1.       (Bound-by-Patient) The + items (facts) can occur at any time in the patient's history.

+ +

2.       (Bound-by-Encounter) The + items (facts) occur during the same encounter (e.g. visit to hospital).

+ +

3.       (Bound-by-Observation) The + items (facts) occur during the same observation.

+ +

The values are hierarchical: a Group that is + bound-by-observation is also bound-by-encounter and bound-by-patient. A group that is + bound-by-encounter is also bound-by-patient. Every group is bound-by-patient.

+ +

The Group Binding for a Group can be set by launching + the Group Binding Editor, by clicking on the highlighted area in a Group:

+ +

+ +

The Group Binding Editor consists of 3 rows, each representing + a possible Group Binding value. Selecting one will set the value. + +

Users can also set the Group binding for all + Groups using the Group Binding Control Panel in the Supplemental + Control Panel in Step 1.

+ +

Bound-by-Patient

+ +

The items (facts) can occur at any time in the patient's history.

+ +

+ +

Bound-by-Encounter

+ +

The items (facts) occur during the same encounter (e.g. visit to hospital).

+ +

+ +

Example:

+ +

Patient has a diagnosis of Acute MI documented at any time in their history and they have a medication with a dose greater + than 500 mg and a medication that is taken once a day documented + during the same encounter.

+ +

qtTimingExample4

+ +

RESULTS: In our database, there are 4 patients who have + had a medication with a dose greater than 500 mg and a frequency of once a day + entered as a fact in the observation_fact table, where the medication dose and + frequency have the same encounter_num AND the + diagnosis of acute MI, the medication dose and frequency all have the same patient_num.

+ +

Bound-by-Observation

+ +

The items (facts) listed in the panel occur during the same observation of a visit.

+ +

Example:

+ +

Patient has a diagnosis of Acute MI documented at any + time in their history and they have a medication with a dose greater + than 500 mg and a medication that is taken once a day documented + during the same instance.

+ +

qtTimingExample5

+ +

RESULTS: In our database, there are 3 patients who + have had a medication with a dose greater than 500 mg and a frequency of once a + day entered as a fact in the observation_fact table, where the medication dose + and frequency have the same encounter_num AND instance_num + AND the diagnosis of acute MI, the medication dose and frequency all + have the same patient_num.

+ +

Date Constraint

+ +

Users can define a date range to be used when querying the + database. This date range can be in any one of the following combinations. Note that + all start and end dates are inclusive.

+ +

SPECIFIED DATE RANGE: FROM AND TO + DATES DEFINED

+ +

Only data with activity within the defined date range will be used.

+ +

Example:

+ +

qtConstDateSelect

+ +

Concept: Acute Myocardial Infarction

+ +

From date: 01/01/2001

+ +

To date: 12/31/2005

+ +

In this example, if a patient has a diagnosis of + Acute Myocardial Infarction (MI) entered on the record from 01/01/2001 to 12/31/2005 + then their data will be included. If the patient does have an MI diagnosis but it was + entered prior to 01/01/2001 or after 12/31/2005 then their information will not be + included.

+ +

SPECIFIC START DATE: ONLY THE FROM DATE + IS DEFINED

+ +

Data from the defined start date to the latest date available. No end date defined.

+ +

Example:

+ +

qtConstDateFrom

+ +

Concept: Acute Myocardial Infarction

+ +

From date: 01/01/2001

+ +

To date:

+ +

In this example, if a patient has a diagnosis of + Acute Myocardial Infarction (MI) entered on the record any time on or after + 01/01/2001 will be included. If the diagnosis was entered prior to 01/01/2001 then + the data will not be included.

+ +

SPECIFIC END DATE: ONLY THE TO DATE IS + DEFINED

+ +

All data up until the defined end date. No start date + defined.

+ +

Example:

+ +

qtConstDateTo

+ +

Concept: Acute Myocardial Infarction

+ +

From date:

+ +

To date: 12/31/2005

+ +

In this example, if a patient has a diagnosis of + Acute Myocardial Infarction (MI) entered on the record prior to and including + 12/31/2005 then their data will be included. If the diagnosis was entered after + 12/31/2005 then it will not be included.

+ +

SETTING THE DATE CONSTRAINT

+
    +
  1. Click on the Dates button located in the selection criteria section of the panel.
  2. +

    qtConstDateSelect

    +
  3. A new window will open.
  4. +

    qtConstDateWindow

    +
  5. Click the check box next to the date in the From box.
  6. +
  7. At this point there are two methods of entering your starting date.
  8. +
      +
    1. Manually type it in the text box.
    2. +
    3. Click on the drop-down arrow (dropDownArrow) to open the calendar view and click on the desired date. +
    4. +

      qtConstDateCal1

      +

      Once you click on the desired date the calendar window will close.

      +

      qtConstDateFrom

      +
    +
  9. Click the check box next to the date in the To box.
  10. +
  11. Highlight the default date or click on the drop-down arrow and enter the date you want to use as your ending date. +
  12. +

    qtConstDateFromTo

    +
  13. Click on the OK button.
  14. +
  15. Dates will now be underlined to indicate a date constraint has been set.
  16. +

    qtConstDateSet

    +
+

Occurrences Constraint

+ +

Users can define a number of times an item has to occur in + order to be considered a positive "hit". Please note that the Occurrence + Constraint and Exclusion from the classic query tool have been rolled into + the same constraint. Here is an example of conversions from the classical query tool + occurrence and exclude specification to the new occurrence constraint + specification:

+ +

1.       + (Exclude 1) (exclude anyone who has one or more occurrence of the desired + terms) -> Edit the occurrence to (=0).

+ +

2.       + (Exclude 2) (Exclude anyone who has two or more occurrences of the desired + terms) -> Edit the occurrence to (<2).

+ +

3.       + (1) (Only take those who have one or more occurrences of the desired terms) + -> Edit the occurrence to (>0). (This is the default)

+ +

4.       + (2) (Only take those who have two or more occurrences of the desired terms) + -> Edit the occurrence to (>2).

+ +

Setting the Occurrences Constraint

+ +

1.       Click on the Occurrence Count + Control located in the top part of a Group Panel.

+ +

qtConstOccurSelect

+ +

2.       + The Occurrence Count Editor will open.

+ +

qtConstOccurWindow

+ +

3.       Use the dropbox to select the + desired operator and the spinner to choose the desired number. The dropbox has the following options:

+ +

qtConstOccurSelection

+ +

4.       Click on the OK button to accept.

+ +

5.       Occurrence Count Control will + update to the new constraint (4 examples provided below):

+ +

qtConstOccurSet

+ +

Different operator/number combinations will have different + background. The default (>0) is white with gray text. If the operator is > and + the number is greater than 0, then it will be green. If the operator is < or =, + then the background will be pink. Please note that choosing the equal (=) + operator restricts the number to zero (0) - you cannot choose equals x + (=x), where x is any non-zero number.

+ +

Value Constraint

+ +

Value constraints can be associated with concept and modifiers + but not all of them will have values. For instance, the diagnosis of Acute Myocardial + Infarction does not have a value but the tests used to make the diagnosis do have + values (high/ low flags, or numeric values, etc.).

+ +

Flag Value

+ +

Flags are defined in the source system when the value is entered. The following are some examples that can be found in the i2b2 Demo database. +

+ + + + + +

Setting the Value Constraint (Flag) for a Concept

+ + + + + + +
+

NOTE:

+

+ The value constraint window will open automatically when you drop a concept into a panel in the Query Tool view. This will only happen if the concept is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. +

+
+ + + +
    +
  1. Using the right mouse button, click on the item listed in the panel.
  2. +
  3. A pop-up menu will open.
  4. +
  5. Select Set Value from the list.
  6. + + +

    qtConstValSelect

    + + + +
  7. A new window will open.
  8. + + +

    qtConstValTropI1

    + + + +
  9. Click on the radial dial next to By flag.
  10. +
  11. A new field with a drop-down selection box will appear.
  12. + + +

    qtConstValTropI2

    + + + +
  13. Click on the drop-down arrow to change the flag or accept the default.
  14. +
  15. Click on the OK button.
  16. +
  17. The value constraint has been set.
  18. + + +

    qtConstValTropI3

    +
+ + + +

Setting the Value Constraint (Flag) for a Modifier

+ + + + + + +
+

NOTE:

+

+ The modifier value constraint window will open automatically when you drop a modifier into a panel in the Query Tool view. This will only happen if the modifier is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. +

+
+ + + +
    +
  1. Using the right mouse button, click on the item listed in the panel.
  2. +
  3. A pop-up menu will open.
  4. +
  5. Select Set Value from the list.
  6. + + +

    qtConstValSelectMod

    + + + +
  7. A new window will open.
  8. +
  9. Click on the radial dial next to By flag.
  10. +
  11. A new field with a drop-down selection box will appear.
  12. +
  13. Click on the drop-down arrow to change the flag or accept the default.
  14. +
  15. Click on the OK button.
  16. +
  17. The value constraint has been set.
  18. +
+ + + +

Text Value

+ +

The text value is defined in the source system when the value is entered. The following are some examples that can be found in the i2b2 Demo database. +

+ + +

Setting the Value Constraint (Text) for a Concept

+ + + + +
+

NOTE:

+

+ The value constraint window will open automatically when you drop a concept into a panel in the Query Tool view. This will only happen if the concept is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. +

+
+ + + +
    +
  1. Using the right mouse button, click on the item listed in the panel.
  2. +
  3. A pop-up menu will open.
  4. +
  5. Select Set Value from the list.
  6. + + +

    qtConstValSelect

    + + + +
  7. A new window will open.
  8. + + +

    qtConstValCkmb1

    + + + +
  9. Click on the radial dial next to By value.
  10. +
  11. A new field listing the enumerated values will appear.
  12. +
  13. Click on the name of the value you want to include.
  14. + + +

    qtConstValCkmb2

    + + + + + + + +
    +

    TIP:

    +

    + To select more than one you can hold down the <Ctrl> key while clicking on each name. On the Macintosh you can hold down the command key instead of the <Ctrl> key. +

    +
    + + + +
  15. Click on the OK button.
  16. +
  17. The value constraint has been set.
  18. + + +

    qtConstValCkmb3

    +
+ + + +

Setting the Value Constraint (Text) for a Modifier

+ + + + + + +
+

NOTE:

+

+ The modifier value constraint window will open automatically when you drop a modifier into a panel in the Query Tool view. This will only happen if the modifier is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. +

+
+ + + +
    +
  1. Using the right mouse button, click on the item listed in the panel.
  2. +
  3. A pop-up menu will open.
  4. +
  5. Select Set Modifier Value from the list.
  6. + + +

    qtConstValSelectMod

    + + + +
  7. A new window will open.
  8. + + +

    qtConstValTrimoxFreq1

    + + + +
  9. Click on the radial dial next to By value.
  10. +
  11. A new field listing the enumerated values will appear.
  12. +
  13. Click on the name of the value you want to include.
  14. + + +

    qtConstValTrimoxFreq2

    + + + + + + + +
    +

    TIP:

    +

    + To select more than one you can hold down the <Ctrl> key while clicking on each name. On the Macintosh you can hold down the command key instead of the <Ctrl> key. +

    +
    + + + +
  15. Click on the OK button.
  16. +
  17. The value constraint has been set.
  18. + + +

    qtConstValTrimox3

    +
+ + + +

Numeric Value +

The numeric value is defined in the source system when the result is entered. The following are some example formats that can be found in the i2b2 Demo database. +

+ + + + +

Unlike flag and text values, numeric values use operators, such as greater than or less than when setting the constraints. The following is a listing of operators currently in use. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorDescription / Use
Less Than (<)Any value less than the number entered.
Less Than or Equal To (<=)Any value less than or equal to the number entered (inclusive).
Equal To (=)An exact match to the number entered.
BetweenAny value in the range of numbers entered.
Greater Than (>)Any value greater than the number entered.
Greater Than or Equal To (>=)Any value greater than or equal to the number entered (inclusive).
+ + + +

Setting the Value Constraint (Numeric) for a Concept

+ + + + + + +
+

NOTE:

+

+ The value constraint window will open automatically when you drop a concept into a panel in the Query Tool view. This will only happen if the concept is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. +

+
+ + + +

+
    +
  1. Using the right mouse button, click on the item listed in the panel.
  2. +
  3. A pop-up menu will open.
  4. +
  5. Select Set Value from the list.
  6. + + +

    qtConstValSelect

    + + + +
  7. A new window will open.
  8. + + +

    qtConstValCpk1

    + + + +
  9. Click on the radial dial next to By value.
  10. +
  11. Two new fields will appear; one with a drop down selection box and the other a text box.
  12. + + +

    qtConstValCpk2

    + + + +
  13. Click on the drop-down arrow to change the operator or accept the default.
  14. + + +

    qtConstValOperator

    + + + +
  15. Enter a numerical value at the Please enter a value field.
  16. + + +

    qtConstValEnter

    + + + +
  17. Click on the OK button.
  18. +
  19. The value constraint has been set.
  20. + + +

    qtConstValCpk3

    +
+

+ + + +

Setting the Value Constraint (Numeric) for a Modifier

+ + + + + + +
+

NOTE:

+

+ The modifier value constraint window will open automatically when you drop a modifier into a panel in the Query Tool view. This will only happen if the modifier is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. +

+
+ + + +

+
    +
  1. Using the right mouse button, click on the item listed in the panel.
  2. +
  3. A pop-up menu will open.
  4. +
  5. Select Set Modifier Value from the list.
  6. + + +

    qtConstValSelectMod

    + + + +
  7. A new window will open.
  8. + + +

    qtConstValTrimoxDose1

    + + + +
  9. Click on the radial dial next to By value.
  10. +
  11. Two new fields will appear; one with a drop down selection box and the other a text box.
  12. + + +

    qtConstValTrimoxDose2

    + + + +
  13. Click on the drop-down arrow to change the operator or accept the default.
  14. + + +

    qtConstValOperator

    + + + +
  15. Enter a numerical value at the Please enter a value field.
  16. + + +

    qtConstValEnter

    + + + +
  17. Click on the OK button.
  18. +
  19. The value constraint has been set.
  20. + + +

    qtConstValTrimoxDose3

    +
+ + + +

Using Units In Value Constraints

+

Units in regards to i2b2 are the standard units of measurement associated with a value. For instance, a medication may have "mg" listed as the unit for the dose, while a HGB lab test may have "gm/dL". +

+ +

The units are defined in the source system and although it is recommended that all numerical facts are stored in normalized units it is recognized that this is not always feasible. Therefore, the Web Client has the ability to convert the units when running a query. +

+ +

In order for this feature to work a parameter called CRC_ENABLE_UNITCD_CONVERSION must be defined for the project. If this is not defined you need to contact your system administrator. +

+ + + +

Defining the Units When Running a Query

+ + + + + +
+

NOTE:

+

+ The modifier value constraint window will open automatically when you drop a modifier into a panel in the Query Tool view. This will only happen if the modifier is set up in the database with XML metadata. The first three steps can be used if you did not add a value constraint when you added the item or if you wish to edit an existing item. +

+
+
    +
  1. Using the right mouse button, click on the item listed in the panel.
  2. +
  3. A pop-up menu will open.
  4. +
  5. Select Set Modifier Value from the list.
  6. +

    qtConstValSelectMod

    +
  7. A new window will open.
  8. +

    qtConstValUnits1

    +
  9. Click on the radial dial next to By value.
  10. +
  11. Two new fields will appear; one with a drop down selection box and the other a text box.
  12. +

    qtConstValUnits2

    +
  13. The Units will default to the normal units defined for the item.
  14. +
  15. Click on the drop-down arrow to change the units.
  16. +

    qtConstValUnitsList

    +
  17. Click on the drop-down arrow to change the operator or accept the default.
  18. +

    qtConstValOperator

    +
  19. Enter a numerical value at the Please enter a value field.
  20. +

    qtConstValEnter

    +
  21. Click on the OK button.
  22. +
  23. The value constraint has been set and the numerical value has been converted to the normal units.
  24. +

    qtConstValUnits3

    +
+

In the above scenario, the normal units are "mg". When setting up the value constraint the units were changed to "gm" and the numerical value was set to 5. Upon saving the value constraint, the Web Client converted 5 gm to 5000 mg. When the query is run it will look at those facts that have both 5 gm and 5000 mg defined in the observation_fact table. + + + + +
+

NOTE:

+

+ The unit conversion information is specific to the term and is defined in the i2b2 metadata table. +

+
+ +

Running a Query

+ +

This section describes the process of running a query and getting results.

+ + + +

Before users submit their query to the server, they must + select the analysis types they want from the Analysis Type Area in Step 3. There are + several result types available, each of which will yield a different output.

+ +

qtRunQueryWindow

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Patient list + + Provides a set of patients who met the search criteria. +
+ Event list + + Provides a set of encounters for those patients who met the search criteria. +
+ Number of patients + + Provides the total number of patients who met the search criteria. +
+ Gender patient breakdown + + Provides a breakdown of the patients by their gender. +
+ Vital Status patient breakdown + + Provides a breakdown of the patients by their vital status. +
+ Race patient breakdown + + Provides a breakdown of the patients by their race. +
+ Age patient breakdown + + Provides a breakdown of the patients by their age +
+ Timeline + + Provides a set of patients who met the defined criteria and automatically generates a timeline in the timeline view. +
+ +

By default Number of patients and Timeline are selected.

+ +

Patient List

+ +

This option will return a list of patients who met the defined + criteria and will add the query and patient list to the previous query view.

+ +

pqPtSet

+ +

Event List

+ +

This option will return a set of encounters for those patients + who meet the defined criteria and will add the query and patient list to the + previous query view.

+ +

pqEncSet

+ +

Number of Patients

+ +

This option will return a total count for those patients who + meet the defined criteria and will display the appropriate information in the + following two views.

+ +

Previous Query View - displays the query and the results returned.

+ +

pqPtCount

+ +

Note: The number + is displayed in the tool tip, which can be seen by hovering over Number of + Patients.

+ +

Gender Patient Breakdown

+ +

This option will return a breakdown by gender for those + patients who meet the defined criteria and will display the appropriate information + in the following two views.

+ +

Previous Query View - displays the query and the results returned.

+ +

pqGender

+ +

Vital Status Patient Breakdown

+ +

This option will return a breakdown by vital status for those + patients who met the defined criteria and will display the appropriate information in + the following two views.

+ +

Previous Query View - displays the query and the results returned.

+ +

pqVitalStatus

+ +

Race Patient Breakdown

+ +

This option will return a breakdown by race for those patients + who met the defined criteria and will display the appropriate information in the + following two views.

+ +

Previous Query View - displays the query and the results returned.

+ +

pqRace

+ +

Age Patient Breakdown

+ +

This option will return a breakdown by age for those patients + who met the defined criteria and will display the appropriate information in the + following two views.

+ +

Previous Query View - displays the query and the results returned.

+ +

pqAge

+ +

Timeline

+ +

This option will return a list of patients who met the defined + criteria and will display the appropriate information in the following two views. The + current implementation of Temporal QueryTool does not automatically launch the + Timeline visualization. Instead, users will need to drag the previous query (or the + patient set) and drop it into Timeline's configuration panel.

+ +

1.       + Timeline View - displays the patients and associated concepts in the format of + a timeline.

+ +

+ +

2.       + Previous Query View - displays the query and the results returned.

+ +

+ + + +

Once the query has been created and the Analysis types + selected, the final step to retrieve your information is to run the query. This is + done by clicking on the Submit Query in the query tool.

+ +

qtToolbarRunQuery

+ +

+ Once you begin the process of running the query the button become inactive, and a processing indicator will appear: +

+ +

qtQueryStatusRunMI

+ +

When the query process concludes, the results will be shown:

+ +

queryStatusFinish

+ +

If the query takes longer than the Web Client expects, the + query will be queued up on the server side and will be finished at a later time. An + entry is created in the Previous Query view immediately and users are to check + the entry periodically to see when the query completes. The following message will + also be displayed at the Footer. The Submit Query button will become active so + users can submit another query.

+ +

+

Cancel a Query

+ +

To cancel a query you simply click on the Cancel Query button.

+ + + + + +
+

NOTE:

+ +

+ Keep in mind "Cancel Query" and the associated action will only appear when the query is still in the process of running +

+
+ +
    +
  1. To cancel a query that is running, simply click on the Cancel Query button. +

    qtToolbarCancelQuery

    +
  2. + +
  3. Cancel will display in the Query Status view. + +

    qtQueryStatusCancel

    +
  4. +
+ +

Saving a Query

+ +

A previous query () is created automatically when the query is + run from the Temporal Query Tool. The query is stored and displayed in the + Previous Query View. Temporal Query Tool does not currently support + saving query definitions.

+ +

Note: Previous + queries can also be seen in Workplace View if the user copied it to their workplace + or shared folder in workplace view.

+ +

1.       Run a query.

+ +

2.       Go to the Previous Query View.

+ +

3.       + The query you just ran will now appear in the list of previous queries.

+ +

pqView

+ + +

Printing a Query

+

Users are able to print out the query information if they wish to have a hard copy of the search criteria defined for a query.

+ +

When printing a query you can either print the information for a current query or + you can drag a previous query to the query tool view and print the information + associated with that query.

+

The following steps outline the process of printing a query once you have the + appropriate query in the Query Tool.

+
    +
  1. Click on the Print Query button located on the toolbar at the bottom of the Query Tool view +

    qtToolbarPrintQuery

  2. + +
  3. A new window will open displaying the information about the query. +

    qtPrintWindow

    +
  4. + +
  5. On the menu bar, click on File to display the menu options.
  6. + +
  7. Select Print from the menu.
  8. +
+
+ + diff --git a/i2b2 license 2.1-1159.txt b/i2b2 license 2.1-1159.txt index afa7cdcc..c0afeb6d 100755 --- a/i2b2 license 2.1-1159.txt +++ b/i2b2 license 2.1-1159.txt @@ -1,56 +1,56 @@ - -i2b2 Software License ("Software License") -Version 2.1 - 1/15/2009 - - - This Software License covers downloads from the i2b2 project ("i2b2") maintained by the Brigham and Women's Hospital, Inc. ("BWH"). - - Your downloading, copying, modifying, displaying, distributing or use of any software and/or data from i2b2 (collectively, the "Software") constitutes acceptance of all of the terms and conditions of this Software License. If you do not agree to such terms and conditions, you have no right to download, copy, modify, display, distribute or use the Software. - - -1. As used in this Software License, "you" means the individual downloading and/or using, reproducing, modifying, displaying and/or distributing the Software and the institution or entity which employs or is otherwise affiliated with such individual in connection therewith. The BWH hereby grants you, with right to sublicense, with respect to BWH's rights in the software, and related technical data, if any, which is the subject of this Software License, a royalty-free, non-exclusive license to use, reproduce, make derivative works of, display and distribute the Software, provided that: - -(a) You accept and adhere to all of the terms and conditions of this Software License; - -(b) In connection with any copy of or sublicense of all or any portion of the Software, all of the terms and conditions in this Software License shall appear in and shall apply to such copy and such sublicensee, including without limitation all source and executable forms and on any user documentation, prefaced with the following words: "All or portions of this licensed product (such portions are the "Software") have been obtained under license from The Brigham and Women's Hospital, Inc. and are subject to the following terms and conditions:" - -(c) You preserve and maintain all applicable attributions, copyright notices and licenses included in or applicable to the Software. - - - -2. Modifications to the Software shall mean any addition to or deletion from the substance or structure of either the Software or any previous Modifications. When Software is released as a series of files, a Modification is: (i) any addition to or deletion from the contents of a file containing the Software or previous Modifications; or (ii) any new file that contains any part of the Software or previous Modifications. - -(a) You agree that you will deliver, and you will cause all sublicensees to deliver, to BWH copies of all Modifications that are made to the Software, on or before the date on which the Modifications are distributed to any third party, and you hereby grant to BWH, and will cause all of your sublicensees to grant to BWH, a non-exclusive, royalty-free, irrevocable, non-terminable license to use, reproduce, make derivative works of, display, perform, and distribute any and all Modifications in source code and binary code form for any purpose and to sublicense such rights to others. - -(b) You agree that all Modifications of the Software must be clearly identified and marked as such, and must not be misrepresented as being the original Software. - -(c) You agree to consider making, but are under no obligation to make, the source code of any of your Modifications to the Software freely available to others on an open source basis. - - - -3. The license granted under this Software License includes without limitation the right to (i)incorporate the Software into proprietary programs (subject to any restrictions applicable to such programs), (ii)add your own copyright statement to your Modifications of the Software, and (iii)provide additional or different license terms and conditions in your sublicenses of Modifications of the Software; provided that in each case your use, reproduction or distribution of such modifications otherwise complies with the conditions stated in this Software License. - - -4. This Software License does not grant any rights with respect to third party software, except those rights that BWH has been authorized by a third party to grant to you, and accordingly you are solely responsible for (i) obtaining any permissions from third parties that you need to use, reproduce, make derivative works of, display and distribute the Software, and (ii) informing your sublicensees, including without limitation your end-users, of their obligations to secure any such required permissions. - - -5. The Software has been designed for research purposes only and has not been reviewed or approved by the Food and Drug Administration or by any other agency. YOU ACKNOWLEDGE AND AGREE THAT CLINICAL APPLICATIONS ARE NEITHER RECOMMENDED NOR ADVISED. Any commercialization of the Software is at the sole risk of the party or parties engaged in such commercialization. You further agree to use, reproduce, make derivative works of, display and distribute the Software in compliance with all applicable governmental laws, regulations and orders, including without limitation those relating to export and import control. - - -6. The Software is provided "AS IS" and neither BWH nor any contributor to the software (each a "Contributor") shall have any obligation to provide maintenance, support, updates, enhancements or modifications thereto. You acknowledge and agree that you are responsible for your selection, testing, modification, use and distribution of the Software, in any form, and that you hereby expressly waive any claim for any loss, damage, or injury that may occur as a result of your use or distribution of the Software. You agree that you are responsible for obtaining and will maintain insurance providing coverage (including but not limited to general liability and product liability insurance) that is appropriate in light of the waivers and assumptions of liability set forth in this Software License. You furthermore waive any right of recovery against BWH or any Contributor (including any right of subrogation against BWH or any Contributor or any insurer of BWH or any Contributor) for loss or damage arising out of or incident to your use or distribution of the Software. - -7. BWH AND ALL CONTRIBUTORS SPECIFICALLY DISCLAIM ALL EXPRESS AND IMPLIED WARRANTIES OF ANY KIND INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL BWH OR ANY CONTRIBUTOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ARISING IN ANY WAY RELATED TO THE SOFTWARE, EVEN IF BWH OR ANY CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. TO THE MAXIMUM EXTENT NOT PROHIBITED BY LAW OR REGULATION, YOU FURTHER ASSUME ALL LIABILITY FOR YOUR USE, REPRODUCTION, MAKING OF DERIVATIVE WORKS, DISPLAY, LICENSE OR DISTRIBUTION OF THE SOFTWARE AND AGREE TO INDEMNIFY AND HOLD HARMLESS BWH AND ALL CONTRIBUTORS (AND ALL RELATED INDIVIDUALS AND ENTITIES) FROM AND AGAINST ANY AND ALL CLAIMS, SUITS, ACTIONS, DEMANDS AND JUDGMENTS ARISING THEREFROM OR FROM ANY MODIFICATIONS OF THE SOFTWARE DELIVERED TO BWH HEREUNDER. - - -8. None of the names, logos or trademarks of BWH or any of BWH's affiliates or any of the Contributors, or any funding agency, may be used to endorse or promote products produced in whole or in part by operation of the Software or derived from or based on the Software without specific prior written permission from the applicable party. - - -9. Any use, reproduction or distribution of the Software which is not in accordance with this Software License shall automatically revoke all rights granted to you under this Software License and render Paragraphs 1 and 2 of this Software License null and void. - - -10. This Software License does not grant any rights in or to any intellectual property owned by BWH or any Contributor except those rights expressly granted hereunder. - - -Version 2.1 - 1/15/08 - - + +i2b2 Software License ("Software License") +Version 2.1 - 1/15/2009 + + + This Software License covers downloads from the i2b2 project ("i2b2") maintained by the Brigham and Women's Hospital, Inc. ("BWH"). + + Your downloading, copying, modifying, displaying, distributing or use of any software and/or data from i2b2 (collectively, the "Software") constitutes acceptance of all of the terms and conditions of this Software License. If you do not agree to such terms and conditions, you have no right to download, copy, modify, display, distribute or use the Software. + + +1. As used in this Software License, "you" means the individual downloading and/or using, reproducing, modifying, displaying and/or distributing the Software and the institution or entity which employs or is otherwise affiliated with such individual in connection therewith. The BWH hereby grants you, with right to sublicense, with respect to BWH's rights in the software, and related technical data, if any, which is the subject of this Software License, a royalty-free, non-exclusive license to use, reproduce, make derivative works of, display and distribute the Software, provided that: + +(a) You accept and adhere to all of the terms and conditions of this Software License; + +(b) In connection with any copy of or sublicense of all or any portion of the Software, all of the terms and conditions in this Software License shall appear in and shall apply to such copy and such sublicensee, including without limitation all source and executable forms and on any user documentation, prefaced with the following words: "All or portions of this licensed product (such portions are the "Software") have been obtained under license from The Brigham and Women's Hospital, Inc. and are subject to the following terms and conditions:" + +(c) You preserve and maintain all applicable attributions, copyright notices and licenses included in or applicable to the Software. + + + +2. Modifications to the Software shall mean any addition to or deletion from the substance or structure of either the Software or any previous Modifications. When Software is released as a series of files, a Modification is: (i) any addition to or deletion from the contents of a file containing the Software or previous Modifications; or (ii) any new file that contains any part of the Software or previous Modifications. + +(a) You agree that you will deliver, and you will cause all sublicensees to deliver, to BWH copies of all Modifications that are made to the Software, on or before the date on which the Modifications are distributed to any third party, and you hereby grant to BWH, and will cause all of your sublicensees to grant to BWH, a non-exclusive, royalty-free, irrevocable, non-terminable license to use, reproduce, make derivative works of, display, perform, and distribute any and all Modifications in source code and binary code form for any purpose and to sublicense such rights to others. + +(b) You agree that all Modifications of the Software must be clearly identified and marked as such, and must not be misrepresented as being the original Software. + +(c) You agree to consider making, but are under no obligation to make, the source code of any of your Modifications to the Software freely available to others on an open source basis. + + + +3. The license granted under this Software License includes without limitation the right to (i)incorporate the Software into proprietary programs (subject to any restrictions applicable to such programs), (ii)add your own copyright statement to your Modifications of the Software, and (iii)provide additional or different license terms and conditions in your sublicenses of Modifications of the Software; provided that in each case your use, reproduction or distribution of such modifications otherwise complies with the conditions stated in this Software License. + + +4. This Software License does not grant any rights with respect to third party software, except those rights that BWH has been authorized by a third party to grant to you, and accordingly you are solely responsible for (i) obtaining any permissions from third parties that you need to use, reproduce, make derivative works of, display and distribute the Software, and (ii) informing your sublicensees, including without limitation your end-users, of their obligations to secure any such required permissions. + + +5. The Software has been designed for research purposes only and has not been reviewed or approved by the Food and Drug Administration or by any other agency. YOU ACKNOWLEDGE AND AGREE THAT CLINICAL APPLICATIONS ARE NEITHER RECOMMENDED NOR ADVISED. Any commercialization of the Software is at the sole risk of the party or parties engaged in such commercialization. You further agree to use, reproduce, make derivative works of, display and distribute the Software in compliance with all applicable governmental laws, regulations and orders, including without limitation those relating to export and import control. + + +6. The Software is provided "AS IS" and neither BWH nor any contributor to the software (each a "Contributor") shall have any obligation to provide maintenance, support, updates, enhancements or modifications thereto. You acknowledge and agree that you are responsible for your selection, testing, modification, use and distribution of the Software, in any form, and that you hereby expressly waive any claim for any loss, damage, or injury that may occur as a result of your use or distribution of the Software. You agree that you are responsible for obtaining and will maintain insurance providing coverage (including but not limited to general liability and product liability insurance) that is appropriate in light of the waivers and assumptions of liability set forth in this Software License. You furthermore waive any right of recovery against BWH or any Contributor (including any right of subrogation against BWH or any Contributor or any insurer of BWH or any Contributor) for loss or damage arising out of or incident to your use or distribution of the Software. + +7. BWH AND ALL CONTRIBUTORS SPECIFICALLY DISCLAIM ALL EXPRESS AND IMPLIED WARRANTIES OF ANY KIND INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL BWH OR ANY CONTRIBUTOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ARISING IN ANY WAY RELATED TO THE SOFTWARE, EVEN IF BWH OR ANY CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. TO THE MAXIMUM EXTENT NOT PROHIBITED BY LAW OR REGULATION, YOU FURTHER ASSUME ALL LIABILITY FOR YOUR USE, REPRODUCTION, MAKING OF DERIVATIVE WORKS, DISPLAY, LICENSE OR DISTRIBUTION OF THE SOFTWARE AND AGREE TO INDEMNIFY AND HOLD HARMLESS BWH AND ALL CONTRIBUTORS (AND ALL RELATED INDIVIDUALS AND ENTITIES) FROM AND AGAINST ANY AND ALL CLAIMS, SUITS, ACTIONS, DEMANDS AND JUDGMENTS ARISING THEREFROM OR FROM ANY MODIFICATIONS OF THE SOFTWARE DELIVERED TO BWH HEREUNDER. + + +8. None of the names, logos or trademarks of BWH or any of BWH's affiliates or any of the Contributors, or any funding agency, may be used to endorse or promote products produced in whole or in part by operation of the Software or derived from or based on the Software without specific prior written permission from the applicable party. + + +9. Any use, reproduction or distribution of the Software which is not in accordance with this Software License shall automatically revoke all rights granted to you under this Software License and render Paragraphs 1 and 2 of this Software License null and void. + + +10. This Software License does not grant any rights in or to any intellectual property owned by BWH or any Contributor except those rights expressly granted hereunder. + + +Version 2.1 - 1/15/08 + + diff --git a/index.php b/index.php index f5ac3004..aa471fe3 100755 --- a/index.php +++ b/index.php @@ -1,211 +1,211 @@ - tag - $startPos = strpos($PostBody,"") + 14; - $endPos = strpos($PostBody,"", $startPos); - $proxyURL = substr($PostBody, $startPos, ($endPos - $startPos)); - $newXML = $PostBody; - - if ($pmCheckAllRequests) - { - error_log("Searhing for Security in " . $PostBody); - //Validate that user is valid against known PM - - preg_match("/(.*)?<\/security>/", $PostBody, $proxySecurity); - - error_log("My Security is " . $proxySecurity[1]); - preg_match("/(.*)?<\/domain>/", $proxySecurity[0], $proxyDomain); - preg_match("/(.*)?<\/username>/", $proxySecurity[0], $proxyUsername); - preg_match("/(.*)?<\/password>/", $proxySecurity[0], $proxyPassword); - - $checkPMXML = " 1.1 2.4 i2b2 Project Management 1.1 i2b2 Hive Project Management Cell 1.1 i2b2 Hive 2007-04-09T15:19:18.906-04:00 " . $proxyDomain[0] . $proxyUsername[0] . $proxyPassword[0] . " 0qazI4rX6SDlQlk46wqQ3 0 P I AL AL US undefined 180000 undefined "; - // Process the POST for proxy redirection - - - - error_log($checkPMXML,0 ); - error_log("My proxy: " . $proxyURL, 0); - - } - - // --------------------------------------------------- - // white-list processing on the URL - // --------------------------------------------------- - $isAllowed = false; - $requestedURL = strtoupper($proxyURL); - foreach ($WHITELIST as $entryValue) { - $checkValue = strtoupper(substr($requestedURL, 0, strlen($entryValue))); - if ($checkValue == strtoupper($entryValue)) { - $isAllowed = true; - break; - } - } - if (!$isAllowed) { - // security as failed - exit here and don't allow one more line of execution the opportunity to reverse this - die("The proxy has refused to relay your request."); - } - // --------------------------------------------------- - // black-list processing on the URL - // --------------------------------------------------- - foreach ($BLACKLIST as $entryValue) { - $checkValue = strtoupper(substr($requestedURL, 0, strlen($entryValue))); - if ($checkValue == strtoupper($entryValue)) { - // security as failed - exit here and don't allow one more line of execution the opportunity to reverse this - die("The proxy has refused to relay your request."); - } - } - - - - if ($pmCheckAllRequests) { - // open the URL and forward the new XML in the POST body - $proxyRequest = curl_init($pmURL); - - // these options are set for hyper-vigilance purposes - curl_setopt($proxyRequest, CURLOPT_COOKIESESSION, 0); - curl_setopt($proxyRequest, CURLOPT_FORBID_REUSE, 1); - curl_setopt($proxyRequest, CURLOPT_FRESH_CONNECT, 0); - // Specify NIC to use for outgoing connection, fixes firewall+DMZ headaches - // curl_setopt($proxyRequest, CURLOPT_INTERFACE, "XXX.XXX.XXX.XXX"); - // other options - curl_setopt($proxyRequest, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($proxyRequest, CURLOPT_CONNECTTIMEOUT, 900); // wait 15 minutes - // data to proxy thru - curl_setopt($proxyRequest, CURLOPT_POST, 1); - curl_setopt($proxyRequest, CURLOPT_POSTFIELDS, $checkPMXML); - // SEND REQUEST!!! - curl_setopt($proxyRequest, CURLOPT_HTTPHEADER, array('Expect:', 'Content-Type: text/xml')); - $proxyResult = curl_exec($proxyRequest); - // cleanup cURL connection - curl_close($proxyRequest); - error_log("My PM Result " . $proxyResult); - - - $pattern = "//i"; - //Check if request is valid - if (preg_match($pattern, $proxyResult)) { - error_log("Local PM denied request"); - die("Local PM server could not validate the request."); - } - - } - - - // open the URL and forward the new XML in the POST body - $proxyRequest = curl_init($proxyURL); - - curl_setopt($proxyRequest, CURLOPT_SSL_VERIFYPEER, FALSE); - // these options are set for hyper-vigilance purposes - curl_setopt($proxyRequest, CURLOPT_COOKIESESSION, 0); - curl_setopt($proxyRequest, CURLOPT_FORBID_REUSE, 1); - curl_setopt($proxyRequest, CURLOPT_FRESH_CONNECT, 0); - // Specify NIC to use for outgoing connection, fixes firewall+DMZ headaches - // curl_setopt($proxyRequest, CURLOPT_INTERFACE, "XXX.XXX.XXX.XXX"); - // other options - curl_setopt($proxyRequest, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($proxyRequest, CURLOPT_CONNECTTIMEOUT, 900); // wait 15 minutes - // data to proxy thru - curl_setopt($proxyRequest, CURLOPT_POST, 1); - curl_setopt($proxyRequest, CURLOPT_POSTFIELDS, $newXML); - // SEND REQUEST!!! - curl_setopt($proxyRequest, CURLOPT_HTTPHEADER, array('Expect:', 'Content-Type: text/xml')); - $proxyResult = curl_exec($proxyRequest); - // cleanup cURL connection - curl_close($proxyRequest); - - - // perform any analysis or processing on the returned result here - header("Content-Type: text/xml", true); - print($proxyResult); - -} - - -?> + tag + $startPos = strpos($PostBody,"") + 14; + $endPos = strpos($PostBody,"", $startPos); + $proxyURL = substr($PostBody, $startPos, ($endPos - $startPos)); + $newXML = $PostBody; + + if ($pmCheckAllRequests) + { + error_log("Searhing for Security in " . $PostBody); + //Validate that user is valid against known PM + + preg_match("/(.*)?<\/security>/", $PostBody, $proxySecurity); + + error_log("My Security is " . $proxySecurity[1]); + preg_match("/(.*)?<\/domain>/", $proxySecurity[0], $proxyDomain); + preg_match("/(.*)?<\/username>/", $proxySecurity[0], $proxyUsername); + preg_match("/(.*)?<\/password>/", $proxySecurity[0], $proxyPassword); + + $checkPMXML = " 1.1 2.4 i2b2 Project Management 1.1 i2b2 Hive Project Management Cell 1.1 i2b2 Hive 2007-04-09T15:19:18.906-04:00 " . $proxyDomain[0] . $proxyUsername[0] . $proxyPassword[0] . " 0qazI4rX6SDlQlk46wqQ3 0 P I AL AL US undefined 180000 undefined "; + // Process the POST for proxy redirection + + + + error_log($checkPMXML,0 ); + error_log("My proxy: " . $proxyURL, 0); + + } + + // --------------------------------------------------- + // white-list processing on the URL + // --------------------------------------------------- + $isAllowed = false; + $requestedURL = strtoupper($proxyURL); + foreach ($WHITELIST as $entryValue) { + $checkValue = strtoupper(substr($requestedURL, 0, strlen($entryValue))); + if ($checkValue == strtoupper($entryValue)) { + $isAllowed = true; + break; + } + } + if (!$isAllowed) { + // security as failed - exit here and don't allow one more line of execution the opportunity to reverse this + die("The proxy has refused to relay your request."); + } + // --------------------------------------------------- + // black-list processing on the URL + // --------------------------------------------------- + foreach ($BLACKLIST as $entryValue) { + $checkValue = strtoupper(substr($requestedURL, 0, strlen($entryValue))); + if ($checkValue == strtoupper($entryValue)) { + // security as failed - exit here and don't allow one more line of execution the opportunity to reverse this + die("The proxy has refused to relay your request."); + } + } + + + + if ($pmCheckAllRequests) { + // open the URL and forward the new XML in the POST body + $proxyRequest = curl_init($pmURL); + + // these options are set for hyper-vigilance purposes + curl_setopt($proxyRequest, CURLOPT_COOKIESESSION, 0); + curl_setopt($proxyRequest, CURLOPT_FORBID_REUSE, 1); + curl_setopt($proxyRequest, CURLOPT_FRESH_CONNECT, 0); + // Specify NIC to use for outgoing connection, fixes firewall+DMZ headaches + // curl_setopt($proxyRequest, CURLOPT_INTERFACE, "XXX.XXX.XXX.XXX"); + // other options + curl_setopt($proxyRequest, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($proxyRequest, CURLOPT_CONNECTTIMEOUT, 900); // wait 15 minutes + // data to proxy thru + curl_setopt($proxyRequest, CURLOPT_POST, 1); + curl_setopt($proxyRequest, CURLOPT_POSTFIELDS, $checkPMXML); + // SEND REQUEST!!! + curl_setopt($proxyRequest, CURLOPT_HTTPHEADER, array('Expect:', 'Content-Type: text/xml')); + $proxyResult = curl_exec($proxyRequest); + // cleanup cURL connection + curl_close($proxyRequest); + error_log("My PM Result " . $proxyResult); + + + $pattern = "//i"; + //Check if request is valid + if (preg_match($pattern, $proxyResult)) { + error_log("Local PM denied request"); + die("Local PM server could not validate the request."); + } + + } + + + // open the URL and forward the new XML in the POST body + $proxyRequest = curl_init($proxyURL); + + curl_setopt($proxyRequest, CURLOPT_SSL_VERIFYPEER, FALSE); + // these options are set for hyper-vigilance purposes + curl_setopt($proxyRequest, CURLOPT_COOKIESESSION, 0); + curl_setopt($proxyRequest, CURLOPT_FORBID_REUSE, 1); + curl_setopt($proxyRequest, CURLOPT_FRESH_CONNECT, 0); + // Specify NIC to use for outgoing connection, fixes firewall+DMZ headaches + // curl_setopt($proxyRequest, CURLOPT_INTERFACE, "XXX.XXX.XXX.XXX"); + // other options + curl_setopt($proxyRequest, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($proxyRequest, CURLOPT_CONNECTTIMEOUT, 900); // wait 15 minutes + // data to proxy thru + curl_setopt($proxyRequest, CURLOPT_POST, 1); + curl_setopt($proxyRequest, CURLOPT_POSTFIELDS, $newXML); + // SEND REQUEST!!! + curl_setopt($proxyRequest, CURLOPT_HTTPHEADER, array('Expect:', 'Content-Type: text/xml')); + $proxyResult = curl_exec($proxyRequest); + // cleanup cURL connection + curl_close($proxyRequest); + + + // perform any analysis or processing on the returned result here + header("Content-Type: text/xml", true); + print($proxyResult); + +} + + +?> diff --git a/js-ext/YUI_DataTable_MD5CellEditor.js b/js-ext/YUI_DataTable_MD5CellEditor.js index bde302c8..34597876 100755 --- a/js-ext/YUI_DataTable_MD5CellEditor.js +++ b/js-ext/YUI_DataTable_MD5CellEditor.js @@ -1,532 +1,532 @@ -/** - * MD5CellEditor - * A YUI DataTable extension - * Originally made by Mihaly Koles, http://koles.hu, 2009.02.10. - * Original version: http://koles.hu/sandbox/yui_datatable_password/YUI_DataTable_MD5CellEditor.js - */ - -var Ev = YAHOO.util.Event, - lang = YAHOO.lang, - widget = YAHOO.widget, - ua = YAHOO.env.ua; - -//Password field editor with two text inputs -widget.MD5CellEditor = function(oConfigs) { - this._sId = "yui-md5ceditor" + YAHOO.widget.BaseCellEditor._nCount++; - widget.MD5CellEditor.superclass.constructor.call(this, "textbox", oConfigs); -}; - -lang.extend(widget.MD5CellEditor, widget.BaseCellEditor, { - textbox0 : null, - textbox1 : null, - msgEl : null, - renderForm : function() { - var elTextbox0, elTextbox1, elForm; - // Bug 1802582: SF3/Mac needs a form element wrapping the input - if(ua.webkit>420) { - elForm = this.getContainerEl().appendChild(document.createElement("form")) - } - else { - elForm = this.getContainerEl(); - } - elForm.style.textAlign="right"; - elForm.appendChild(document.createElement("label")).innerHTML="Key:"; - elTextbox0= document.createElement("input"); - // elTextbox0.type = "password"; - elForm.appendChild(elTextbox0); - elForm.appendChild(document.createElement("br")); - // elForm.appendChild(document.createElement("label")).innerHTML="Confirm:"; - // elTextbox1= document.createElement("input"); - // elTextbox1.type = "password"; - // elForm.appendChild(elTextbox1); - // elForm.appendChild(document.createElement("br")); - this.msgEl=elForm.appendChild(document.createElement("span")); - - this.textbox0 = elTextbox0; - this.textbox0.value = ""; - - // this.textbox1 = elTextbox1; - - // Save on enter by default - // Bug: 1802582 Set up a listener on each textbox to track on keypress - // since SF/OP can't preventDefault on keydown - Ev.addListener(elTextbox0, "keyup", function(v){ - if (this.checkPasswords()) - { - if((v.keyCode === 13)) { - // Prevent form submit - YAHOO.util.Event.preventDefault(v); - this.save(); - } - } - }, this, true); - -// Ev.addListener(elTextbox1, "keyup", function(v){ -// if (this.checkPasswords()) -// { -// if((v.keyCode === 13)) { - // Prevent form submit - // YAHOO.util.Event.preventDefault(v); - // this.save(); - // } - // } - // }, this, true); - - if(this.disableBtns) { - // By default this is no-op since enter saves by default - this.handleDisabledBtns(); - } - }, - checkPasswords : function() - { - if (this.textbox0.value==null - || this.textbox0.value=="" - //|| this.textbox1.value==null - //|| this.textbox1.value=="" - ) - { - this.msgEl.innerHTML=""; - return false; - } - else { - - this.msgEl.innerHTML="New MD5 Key: " + hex_md5(this.textbox0.value).toLowerCase().substring(0,3); - this.msgEl.style.color="#008000"; - return true; -// if (this.textbox0.value == this.textbox1.value) { - // this.msgEl.innerHTML="New password is confirmed."; - // this.msgEl.style.color="#008000"; - // return true; - // } - // else { - // this.msgEl.innerHTML="Password don't match!"; - // this.msgEl.style.color="#800000"; - // return false; - // } - } - }, - move : function() { - this.textbox0.style.width = this.getTdEl().offsetWidth + "px"; - // this.textbox1.style.width = this.getTdEl().offsetWidth + "px"; - widget.MD5CellEditor.superclass.move.call(this); - }, - resetForm : function() { - this.textbox0.value = ""; // lang.isValue(this.value) ? this.value.toString() : ""; - // this.textbox1.value = lang.isValue(this.value) ? this.value.toString() : ""; - }, - focus : function() { - this.textbox0.focus(); - this.textbox0.select(); - }, - handleDisabledBtns : function() { - this.subscribe("blurEvent", function(v){ - if (this.checkPasswords()) { - // Save on blur - this.save(); - } - }, this, true); - }, - getInputValue : function() { - if (this.checkPasswords()) return hex_md5(this.textbox0.value).toLowerCase().substring(0,3); //this.textbox0.value; - else return ""; - } -}); - -// Copy static members to MD5CellEditor class -lang.augmentObject(widget.MD5CellEditor, widget.BaseCellEditor); - - -//cell formatter for password fields -DataTableUtils={ - PasswordFormatter:function(el,oRecord,oColumn,oData){ - if (oData==null || oData=='') oData='xxxxxxxx'; - { - el.innerHTML=''; - var oStr = new String(oData); - for (var i=0; i 16) bkey = binl_md5(bkey, key.length * 8); - - var ipad = Array(16), opad = Array(16); - for(var i = 0; i < 16; i++) - { - ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5C5C5C5C; - } - - var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); - return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); -} - -/* - * Convert a raw string to a hex string - */ -function rstr2hex(input) -{ - try { hexcase } catch(e) { hexcase=0; } - var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; - var output = ""; - var x; - for(var i = 0; i < input.length; i++) - { - x = input.charCodeAt(i); - output += hex_tab.charAt((x >>> 4) & 0x0F) - + hex_tab.charAt( x & 0x0F); - } - return output; -} - -/* - * Convert a raw string to a base-64 string - */ -function rstr2b64(input) -{ - try { b64pad } catch(e) { b64pad=''; } - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - var output = ""; - var len = input.length; - for(var i = 0; i < len; i += 3) - { - var triplet = (input.charCodeAt(i) << 16) - | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) - | (i + 2 < len ? input.charCodeAt(i+2) : 0); - for(var j = 0; j < 4; j++) - { - if(i * 8 + j * 6 > input.length * 8) output += b64pad; - else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); - } - } - return output; -} - -/* - * Convert a raw string to an arbitrary string encoding - */ -function rstr2any(input, encoding) -{ - var divisor = encoding.length; - var i, j, q, x, quotient; - - /* Convert to an array of 16-bit big-endian values, forming the dividend */ - var dividend = Array(Math.ceil(input.length / 2)); - for(i = 0; i < dividend.length; i++) - { - dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); - } - - /* - * Repeatedly perform a long division. The binary array forms the dividend, - * the length of the encoding is the divisor. Once computed, the quotient - * forms the dividend for the next step. All remainders are stored for later - * use. - */ - var full_length = Math.ceil(input.length * 8 / - (Math.log(encoding.length) / Math.log(2))); - var remainders = Array(full_length); - for(j = 0; j < full_length; j++) - { - quotient = Array(); - x = 0; - for(i = 0; i < dividend.length; i++) - { - x = (x << 16) + dividend[i]; - q = Math.floor(x / divisor); - x -= q * divisor; - if(quotient.length > 0 || q > 0) - quotient[quotient.length] = q; - } - remainders[j] = x; - dividend = quotient; - } - - /* Convert the remainders to the output string */ - var output = ""; - for(i = remainders.length - 1; i >= 0; i--) - output += encoding.charAt(remainders[i]); - - return output; -} - -/* - * Encode a string as utf-8. - * For efficiency, this assumes the input is valid utf-16. - */ -function str2rstr_utf8(input) -{ - var output = ""; - var i = -1; - var x, y; - - while(++i < input.length) - { - /* Decode utf-16 surrogate pairs */ - x = input.charCodeAt(i); - y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; - if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) - { - x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); - i++; - } - - /* Encode output as utf-8 */ - if(x <= 0x7F) - output += String.fromCharCode(x); - else if(x <= 0x7FF) - output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), - 0x80 | ( x & 0x3F)); - else if(x <= 0xFFFF) - output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), - 0x80 | ((x >>> 6 ) & 0x3F), - 0x80 | ( x & 0x3F)); - else if(x <= 0x1FFFFF) - output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), - 0x80 | ((x >>> 12) & 0x3F), - 0x80 | ((x >>> 6 ) & 0x3F), - 0x80 | ( x & 0x3F)); - } - return output; -} - -/* - * Encode a string as utf-16 - */ -function str2rstr_utf16le(input) -{ - var output = ""; - for(var i = 0; i < input.length; i++) - output += String.fromCharCode( input.charCodeAt(i) & 0xFF, - (input.charCodeAt(i) >>> 8) & 0xFF); - return output; -} - -function str2rstr_utf16be(input) -{ - var output = ""; - for(var i = 0; i < input.length; i++) - output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, - input.charCodeAt(i) & 0xFF); - return output; -} - -/* - * Convert a raw string to an array of little-endian words - * Characters >255 have their high-byte silently ignored. - */ -function rstr2binl(input) -{ - var output = Array(input.length >> 2); - for(var i = 0; i < output.length; i++) - output[i] = 0; - for(var i = 0; i < input.length * 8; i += 8) - output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32); - return output; -} - -/* - * Convert an array of little-endian words to a string - */ -function binl2rstr(input) -{ - var output = ""; - for(var i = 0; i < input.length * 32; i += 8) - output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF); - return output; -} - -/* - * Calculate the MD5 of an array of little-endian words, and a bit length. - */ -function binl_md5(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << ((len) % 32); - x[(((len + 64) >>> 9) << 4) + 14] = len; - - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - - a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); - d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); - c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); - b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); - a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); - d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); - c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); - b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); - a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); - d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); - c = md5_ff(c, d, a, b, x[i+10], 17, -42063); - b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); - a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); - d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); - c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); - b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); - - a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); - d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); - c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); - b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); - a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); - d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); - c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); - b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); - a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); - d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); - c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); - b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); - a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); - d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); - c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); - b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); - - a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); - d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); - c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); - b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); - a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); - d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); - c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); - b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); - a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); - d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); - c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); - b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); - a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); - d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); - c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); - b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); - - a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); - d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); - c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); - b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); - a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); - d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); - c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); - b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); - a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); - d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); - c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); - b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); - a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); - d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); - c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); - b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); - - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - } - return Array(a, b, c, d); -} - -/* - * These functions implement the four basic operations the algorithm uses. - */ -function md5_cmn(q, a, b, x, s, t) -{ - return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); -} -function md5_ff(a, b, c, d, x, s, t) -{ - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); -} -function md5_gg(a, b, c, d, x, s, t) -{ - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); -} -function md5_hh(a, b, c, d, x, s, t) -{ - return md5_cmn(b ^ c ^ d, a, b, x, s, t); -} -function md5_ii(a, b, c, d, x, s, t) -{ - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); -} - -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); -} - -/* - * Bitwise rotate a 32-bit number to the left. - */ -function bit_rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} +/** + * MD5CellEditor + * A YUI DataTable extension + * Originally made by Mihaly Koles, http://koles.hu, 2009.02.10. + * Original version: http://koles.hu/sandbox/yui_datatable_password/YUI_DataTable_MD5CellEditor.js + */ + +var Ev = YAHOO.util.Event, + lang = YAHOO.lang, + widget = YAHOO.widget, + ua = YAHOO.env.ua; + +//Password field editor with two text inputs +widget.MD5CellEditor = function(oConfigs) { + this._sId = "yui-md5ceditor" + YAHOO.widget.BaseCellEditor._nCount++; + widget.MD5CellEditor.superclass.constructor.call(this, "textbox", oConfigs); +}; + +lang.extend(widget.MD5CellEditor, widget.BaseCellEditor, { + textbox0 : null, + textbox1 : null, + msgEl : null, + renderForm : function() { + var elTextbox0, elTextbox1, elForm; + // Bug 1802582: SF3/Mac needs a form element wrapping the input + if(ua.webkit>420) { + elForm = this.getContainerEl().appendChild(document.createElement("form")) + } + else { + elForm = this.getContainerEl(); + } + elForm.style.textAlign="right"; + elForm.appendChild(document.createElement("label")).innerHTML="Key:"; + elTextbox0= document.createElement("input"); + // elTextbox0.type = "password"; + elForm.appendChild(elTextbox0); + elForm.appendChild(document.createElement("br")); + // elForm.appendChild(document.createElement("label")).innerHTML="Confirm:"; + // elTextbox1= document.createElement("input"); + // elTextbox1.type = "password"; + // elForm.appendChild(elTextbox1); + // elForm.appendChild(document.createElement("br")); + this.msgEl=elForm.appendChild(document.createElement("span")); + + this.textbox0 = elTextbox0; + this.textbox0.value = ""; + + // this.textbox1 = elTextbox1; + + // Save on enter by default + // Bug: 1802582 Set up a listener on each textbox to track on keypress + // since SF/OP can't preventDefault on keydown + Ev.addListener(elTextbox0, "keyup", function(v){ + if (this.checkPasswords()) + { + if((v.keyCode === 13)) { + // Prevent form submit + YAHOO.util.Event.preventDefault(v); + this.save(); + } + } + }, this, true); + +// Ev.addListener(elTextbox1, "keyup", function(v){ +// if (this.checkPasswords()) +// { +// if((v.keyCode === 13)) { + // Prevent form submit + // YAHOO.util.Event.preventDefault(v); + // this.save(); + // } + // } + // }, this, true); + + if(this.disableBtns) { + // By default this is no-op since enter saves by default + this.handleDisabledBtns(); + } + }, + checkPasswords : function() + { + if (this.textbox0.value==null + || this.textbox0.value=="" + //|| this.textbox1.value==null + //|| this.textbox1.value=="" + ) + { + this.msgEl.innerHTML=""; + return false; + } + else { + + this.msgEl.innerHTML="New MD5 Key: " + hex_md5(this.textbox0.value).toLowerCase().substring(0,3); + this.msgEl.style.color="#008000"; + return true; +// if (this.textbox0.value == this.textbox1.value) { + // this.msgEl.innerHTML="New password is confirmed."; + // this.msgEl.style.color="#008000"; + // return true; + // } + // else { + // this.msgEl.innerHTML="Password don't match!"; + // this.msgEl.style.color="#800000"; + // return false; + // } + } + }, + move : function() { + this.textbox0.style.width = this.getTdEl().offsetWidth + "px"; + // this.textbox1.style.width = this.getTdEl().offsetWidth + "px"; + widget.MD5CellEditor.superclass.move.call(this); + }, + resetForm : function() { + this.textbox0.value = ""; // lang.isValue(this.value) ? this.value.toString() : ""; + // this.textbox1.value = lang.isValue(this.value) ? this.value.toString() : ""; + }, + focus : function() { + this.textbox0.focus(); + this.textbox0.select(); + }, + handleDisabledBtns : function() { + this.subscribe("blurEvent", function(v){ + if (this.checkPasswords()) { + // Save on blur + this.save(); + } + }, this, true); + }, + getInputValue : function() { + if (this.checkPasswords()) return hex_md5(this.textbox0.value).toLowerCase().substring(0,3); //this.textbox0.value; + else return ""; + } +}); + +// Copy static members to MD5CellEditor class +lang.augmentObject(widget.MD5CellEditor, widget.BaseCellEditor); + + +//cell formatter for password fields +DataTableUtils={ + PasswordFormatter:function(el,oRecord,oColumn,oData){ + if (oData==null || oData=='') oData='xxxxxxxx'; + { + el.innerHTML=''; + var oStr = new String(oData); + for (var i=0; i 16) bkey = binl_md5(bkey, key.length * 8); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); + return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); +} + +/* + * Convert a raw string to a hex string + */ +function rstr2hex(input) +{ + try { hexcase } catch(e) { hexcase=0; } + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var output = ""; + var x; + for(var i = 0; i < input.length; i++) + { + x = input.charCodeAt(i); + output += hex_tab.charAt((x >>> 4) & 0x0F) + + hex_tab.charAt( x & 0x0F); + } + return output; +} + +/* + * Convert a raw string to a base-64 string + */ +function rstr2b64(input) +{ + try { b64pad } catch(e) { b64pad=''; } + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var output = ""; + var len = input.length; + for(var i = 0; i < len; i += 3) + { + var triplet = (input.charCodeAt(i) << 16) + | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) + | (i + 2 < len ? input.charCodeAt(i+2) : 0); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > input.length * 8) output += b64pad; + else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); + } + } + return output; +} + +/* + * Convert a raw string to an arbitrary string encoding + */ +function rstr2any(input, encoding) +{ + var divisor = encoding.length; + var i, j, q, x, quotient; + + /* Convert to an array of 16-bit big-endian values, forming the dividend */ + var dividend = Array(Math.ceil(input.length / 2)); + for(i = 0; i < dividend.length; i++) + { + dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); + } + + /* + * Repeatedly perform a long division. The binary array forms the dividend, + * the length of the encoding is the divisor. Once computed, the quotient + * forms the dividend for the next step. All remainders are stored for later + * use. + */ + var full_length = Math.ceil(input.length * 8 / + (Math.log(encoding.length) / Math.log(2))); + var remainders = Array(full_length); + for(j = 0; j < full_length; j++) + { + quotient = Array(); + x = 0; + for(i = 0; i < dividend.length; i++) + { + x = (x << 16) + dividend[i]; + q = Math.floor(x / divisor); + x -= q * divisor; + if(quotient.length > 0 || q > 0) + quotient[quotient.length] = q; + } + remainders[j] = x; + dividend = quotient; + } + + /* Convert the remainders to the output string */ + var output = ""; + for(i = remainders.length - 1; i >= 0; i--) + output += encoding.charAt(remainders[i]); + + return output; +} + +/* + * Encode a string as utf-8. + * For efficiency, this assumes the input is valid utf-16. + */ +function str2rstr_utf8(input) +{ + var output = ""; + var i = -1; + var x, y; + + while(++i < input.length) + { + /* Decode utf-16 surrogate pairs */ + x = input.charCodeAt(i); + y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; + if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) + { + x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); + i++; + } + + /* Encode output as utf-8 */ + if(x <= 0x7F) + output += String.fromCharCode(x); + else if(x <= 0x7FF) + output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), + 0x80 | ( x & 0x3F)); + else if(x <= 0xFFFF) + output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), + 0x80 | ((x >>> 6 ) & 0x3F), + 0x80 | ( x & 0x3F)); + else if(x <= 0x1FFFFF) + output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), + 0x80 | ((x >>> 12) & 0x3F), + 0x80 | ((x >>> 6 ) & 0x3F), + 0x80 | ( x & 0x3F)); + } + return output; +} + +/* + * Encode a string as utf-16 + */ +function str2rstr_utf16le(input) +{ + var output = ""; + for(var i = 0; i < input.length; i++) + output += String.fromCharCode( input.charCodeAt(i) & 0xFF, + (input.charCodeAt(i) >>> 8) & 0xFF); + return output; +} + +function str2rstr_utf16be(input) +{ + var output = ""; + for(var i = 0; i < input.length; i++) + output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, + input.charCodeAt(i) & 0xFF); + return output; +} + +/* + * Convert a raw string to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ +function rstr2binl(input) +{ + var output = Array(input.length >> 2); + for(var i = 0; i < output.length; i++) + output[i] = 0; + for(var i = 0; i < input.length * 8; i += 8) + output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32); + return output; +} + +/* + * Convert an array of little-endian words to a string + */ +function binl2rstr(input) +{ + var output = ""; + for(var i = 0; i < input.length * 32; i += 8) + output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF); + return output; +} + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ +function binl_md5(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} diff --git a/js-ext/YUI_DataTable_PasswordCellEditor.js b/js-ext/YUI_DataTable_PasswordCellEditor.js index 4f54ea4d..20566ca6 100755 --- a/js-ext/YUI_DataTable_PasswordCellEditor.js +++ b/js-ext/YUI_DataTable_PasswordCellEditor.js @@ -1,143 +1,143 @@ -/** - * PasswordCellEditor - * A YUI DataTable extension - * Originally made by Mihaly Koles, http://koles.hu, 2009.02.10. - * Original version: http://koles.hu/sandbox/yui_datatable_password/YUI_DataTable_PasswordCellEditor.js - */ - -var Ev = YAHOO.util.Event, - lang = YAHOO.lang, - widget = YAHOO.widget, - ua = YAHOO.env.ua; - -//Password field editor with two text inputs -widget.PasswordCellEditor = function(oConfigs) { - this._sId = "yui-passwordceditor" + YAHOO.widget.BaseCellEditor._nCount++; - widget.PasswordCellEditor.superclass.constructor.call(this, "textbox", oConfigs); -}; - -lang.extend(widget.PasswordCellEditor, widget.BaseCellEditor, { - textbox0 : null, - textbox1 : null, - msgEl : null, - renderForm : function() { - var elTextbox0, elTextbox1, elForm; - // Bug 1802582: SF3/Mac needs a form element wrapping the input - if(ua.webkit>420) { - elForm = this.getContainerEl().appendChild(document.createElement("form")) - } - else { - elForm = this.getContainerEl(); - } - elForm.style.textAlign="right"; - elForm.appendChild(document.createElement("label")).innerHTML="Password:"; - elTextbox0= document.createElement("input"); - elTextbox0.type = "password"; - elForm.appendChild(elTextbox0); - elForm.appendChild(document.createElement("br")); - elForm.appendChild(document.createElement("label")).innerHTML="Confirm:"; - elTextbox1= document.createElement("input"); - elTextbox1.type = "password"; - elForm.appendChild(elTextbox1); - elForm.appendChild(document.createElement("br")); - this.msgEl=elForm.appendChild(document.createElement("span")); - - this.textbox0 = elTextbox0; - this.textbox1 = elTextbox1; - - // Save on enter by default - // Bug: 1802582 Set up a listener on each textbox to track on keypress - // since SF/OP can't preventDefault on keydown - Ev.addListener(elTextbox0, "keyup", function(v){ - if (this.checkPasswords()) - { - if((v.keyCode === 13)) { - // Prevent form submit - YAHOO.util.Event.preventDefault(v); - this.save(); - } - } - }, this, true); - - Ev.addListener(elTextbox1, "keyup", function(v){ - if (this.checkPasswords()) - { - if((v.keyCode === 13)) { - // Prevent form submit - YAHOO.util.Event.preventDefault(v); - this.save(); - } - } - }, this, true); - - if(this.disableBtns) { - // By default this is no-op since enter saves by default - this.handleDisabledBtns(); - } - }, - checkPasswords : function() - { - if (this.textbox0.value==null - || this.textbox0.value=="" - || this.textbox1.value==null - || this.textbox1.value=="") - { - this.msgEl.innerHTML=""; - return false; - } - else { - if (this.textbox0.value == this.textbox1.value) { - this.msgEl.innerHTML="New password is confirmed."; - this.msgEl.style.color="#008000"; - return true; - } - else { - this.msgEl.innerHTML="Password don't match!"; - this.msgEl.style.color="#800000"; - return false; - } - } - }, - move : function() { - this.textbox0.style.width = this.getTdEl().offsetWidth + "px"; - this.textbox1.style.width = this.getTdEl().offsetWidth + "px"; - widget.PasswordCellEditor.superclass.move.call(this); - }, - resetForm : function() { - this.textbox0.value = lang.isValue(this.value) ? this.value.toString() : ""; - this.textbox1.value = lang.isValue(this.value) ? this.value.toString() : ""; - }, - focus : function() { - this.textbox0.focus(); - this.textbox0.select(); - }, - handleDisabledBtns : function() { - this.subscribe("blurEvent", function(v){ - if (this.checkPasswords()) { - // Save on blur - this.save(); - } - }, this, true); - }, - getInputValue : function() { - if (this.checkPasswords()) return this.textbox0.value; - else return ""; - } -}); - -// Copy static members to PasswordCellEditor class -lang.augmentObject(widget.PasswordCellEditor, widget.BaseCellEditor); - - -//cell formatter for password fields -DataTableUtils={ - PasswordFormatter:function(el,oRecord,oColumn,oData){ - if (oData==null || oData=='') oData='xxxxxxxx'; - { - el.innerHTML=''; - var oStr = new String(oData); - for (var i=0; i420) { + elForm = this.getContainerEl().appendChild(document.createElement("form")) + } + else { + elForm = this.getContainerEl(); + } + elForm.style.textAlign="right"; + elForm.appendChild(document.createElement("label")).innerHTML="Password:"; + elTextbox0= document.createElement("input"); + elTextbox0.type = "password"; + elForm.appendChild(elTextbox0); + elForm.appendChild(document.createElement("br")); + elForm.appendChild(document.createElement("label")).innerHTML="Confirm:"; + elTextbox1= document.createElement("input"); + elTextbox1.type = "password"; + elForm.appendChild(elTextbox1); + elForm.appendChild(document.createElement("br")); + this.msgEl=elForm.appendChild(document.createElement("span")); + + this.textbox0 = elTextbox0; + this.textbox1 = elTextbox1; + + // Save on enter by default + // Bug: 1802582 Set up a listener on each textbox to track on keypress + // since SF/OP can't preventDefault on keydown + Ev.addListener(elTextbox0, "keyup", function(v){ + if (this.checkPasswords()) + { + if((v.keyCode === 13)) { + // Prevent form submit + YAHOO.util.Event.preventDefault(v); + this.save(); + } + } + }, this, true); + + Ev.addListener(elTextbox1, "keyup", function(v){ + if (this.checkPasswords()) + { + if((v.keyCode === 13)) { + // Prevent form submit + YAHOO.util.Event.preventDefault(v); + this.save(); + } + } + }, this, true); + + if(this.disableBtns) { + // By default this is no-op since enter saves by default + this.handleDisabledBtns(); + } + }, + checkPasswords : function() + { + if (this.textbox0.value==null + || this.textbox0.value=="" + || this.textbox1.value==null + || this.textbox1.value=="") + { + this.msgEl.innerHTML=""; + return false; + } + else { + if (this.textbox0.value == this.textbox1.value) { + this.msgEl.innerHTML="New password is confirmed."; + this.msgEl.style.color="#008000"; + return true; + } + else { + this.msgEl.innerHTML="Password don't match!"; + this.msgEl.style.color="#800000"; + return false; + } + } + }, + move : function() { + this.textbox0.style.width = this.getTdEl().offsetWidth + "px"; + this.textbox1.style.width = this.getTdEl().offsetWidth + "px"; + widget.PasswordCellEditor.superclass.move.call(this); + }, + resetForm : function() { + this.textbox0.value = lang.isValue(this.value) ? this.value.toString() : ""; + this.textbox1.value = lang.isValue(this.value) ? this.value.toString() : ""; + }, + focus : function() { + this.textbox0.focus(); + this.textbox0.select(); + }, + handleDisabledBtns : function() { + this.subscribe("blurEvent", function(v){ + if (this.checkPasswords()) { + // Save on blur + this.save(); + } + }, this, true); + }, + getInputValue : function() { + if (this.checkPasswords()) return this.textbox0.value; + else return ""; + } +}); + +// Copy static members to PasswordCellEditor class +lang.augmentObject(widget.PasswordCellEditor, widget.BaseCellEditor); + + +//cell formatter for password fields +DataTableUtils={ + PasswordFormatter:function(el,oRecord,oColumn,oData){ + if (oData==null || oData=='') oData='xxxxxxxx'; + { + el.innerHTML=''; + var oStr = new String(oData); + for (var i=0; i' , - '', - ''); - - this.element_.insertAdjacentHTML("BeforeEnd", - vmlStr.join("")); - }; - - contextPrototype.stroke = function(aFill) { - var lineStr = []; - var lineOpen = false; - var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); - var color = a[0]; - var opacity = a[1] * this.globalAlpha; - - var W = 10; - var H = 10; - - lineStr.push(' max.x) { - max.x = c.x; - } - if (min.y == null || c.y < min.y) { - min.y = c.y; - } - if (max.y == null || c.y > max.y) { - max.y = c.y; - } - } - } - lineStr.push(' ">'); - - if (typeof this.fillStyle == "object") { - var focus = {x: "50%", y: "50%"}; - var width = (max.x - min.x); - var height = (max.y - min.y); - var dimension = (width > height) ? width : height; - - focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%"; - focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%"; - - var colors = []; - - // inside radius (%) - if (this.fillStyle.type_ == "gradientradial") { - var inside = (this.fillStyle.radius1_ / dimension * 100); - - // percentage that outside radius exceeds inside radius - var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside; - } else { - var inside = 0; - var expansion = 100; - } - - var insidecolor = {offset: null, color: null}; - var outsidecolor = {offset: null, color: null}; - - // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie - // won't interpret it correctly - this.fillStyle.colors_.sort(function (cs1, cs2) { - return cs1.offset - cs2.offset; - }); - - for (var i = 0; i < this.fillStyle.colors_.length; i++) { - var fs = this.fillStyle.colors_[i]; - - colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ","); - - if (fs.offset > insidecolor.offset || insidecolor.offset == null) { - insidecolor.offset = fs.offset; - insidecolor.color = fs.color; - } - - if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) { - outsidecolor.offset = fs.offset; - outsidecolor.color = fs.color; - } - } - colors.pop(); - - lineStr.push(''); - } else if (aFill) { - lineStr.push(''); - } else { - lineStr.push( - '' - ); - } - - lineStr.push(""); - - this.element_.insertAdjacentHTML("beforeEnd", lineStr.join("")); - - this.currentPath_ = []; - }; - - contextPrototype.fill = function() { - this.stroke(true); - } - - contextPrototype.closePath = function() { - this.currentPath_.push({type: "close"}); - }; - - /** - * @private - */ - contextPrototype.getCoords_ = function(aX, aY) { - return { - x: Z * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - Z2, - y: Z * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - Z2 - } - }; - - contextPrototype.save = function() { - var o = {}; - copyState(this, o); - this.aStack_.push(o); - this.mStack_.push(this.m_); - this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); - }; - - contextPrototype.restore = function() { - copyState(this.aStack_.pop(), this); - this.m_ = this.mStack_.pop(); - }; - - contextPrototype.translate = function(aX, aY) { - var m1 = [ - [1, 0, 0], - [0, 1, 0], - [aX, aY, 1] - ]; - - this.m_ = matrixMultiply(m1, this.m_); - }; - - contextPrototype.rotate = function(aRot) { - var c = mc(aRot); - var s = ms(aRot); - - var m1 = [ - [c, s, 0], - [-s, c, 0], - [0, 0, 1] - ]; - - this.m_ = matrixMultiply(m1, this.m_); - }; - - contextPrototype.scale = function(aX, aY) { - this.arcScaleX_ *= aX; - this.arcScaleY_ *= aY; - var m1 = [ - [aX, 0, 0], - [0, aY, 0], - [0, 0, 1] - ]; - - this.m_ = matrixMultiply(m1, this.m_); - }; - - /******** STUBS ********/ - contextPrototype.clip = function() { - // TODO: Implement - }; - - contextPrototype.arcTo = function() { - // TODO: Implement - }; - - contextPrototype.createPattern = function() { - return new CanvasPattern_; - }; - - // Gradient / Pattern Stubs - function CanvasGradient_(aType) { - this.type_ = aType; - this.radius1_ = 0; - this.radius2_ = 0; - this.colors_ = []; - this.focus_ = {x: 0, y: 0}; - } - - CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { - aColor = processStyle(aColor); - this.colors_.push({offset: 1-aOffset, color: aColor}); - }; - - function CanvasPattern_() {} - - // set up externs - G_vmlCanvasManager = G_vmlCanvasManager_; - CanvasRenderingContext2D = CanvasRenderingContext2D_; - CanvasGradient = CanvasGradient_; - CanvasPattern = CanvasPattern_; - -})(); - -} // if +// Copyright 2006 Google Inc. +// +// Licensed 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. + + +// Known Issues: +// +// * Patterns are not implemented. +// * Radial gradient are not implemented. The VML version of these look very +// different from the canvas one. +// * Clipping paths are not implemented. +// * Coordsize. The width and height attribute have higher priority than the +// width and height style values which isn't correct. +// * Painting mode isn't implemented. +// * Canvas width/height should is using content-box by default. IE in +// Quirks mode will draw the canvas using border-box. Either change your +// doctype to HTML5 +// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) +// or use Box Sizing Behavior from WebFX +// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) +// * Optimize. There is always room for speed improvements. + +// only add this code if we do not already have a canvas implementation +if (!window.CanvasRenderingContext2D) { + +(function () { + + // alias some functions to make (compiled) code shorter + var m = Math; + var mr = m.round; + var ms = m.sin; + var mc = m.cos; + + // this is used for sub pixel precision + var Z = 10; + var Z2 = Z / 2; + + var G_vmlCanvasManager_ = { + init: function (opt_doc) { + var doc = opt_doc || document; + if (/MSIE/.test(navigator.userAgent) && !window.opera) { + var self = this; + doc.attachEvent("onreadystatechange", function () { + self.init_(doc); + }); + } + }, + + init_: function (doc) { + if (doc.readyState == "complete") { + // create xmlns + if (!doc.namespaces["g_vml_"]) { + doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml"); + } + + // setup default css + var ss = doc.createStyleSheet(); + ss.cssText = "canvas{display:inline-block;overflow:hidden;" + + // default size is 300x150 in Gecko and Opera + "text-align:left;width:300px;height:150px}" + + "g_vml_\\:*{behavior:url(#default#VML)}"; + + // find all canvas elements + var els = doc.getElementsByTagName("canvas"); + for (var i = 0; i < els.length; i++) { + if (!els[i].getContext) { + this.initElement(els[i]); + } + } + } + }, + + fixElement_: function (el) { + // in IE before version 5.5 we would need to add HTML: to the tag name + // but we do not care about IE before version 6 + var outerHTML = el.outerHTML; + + var newEl = el.ownerDocument.createElement(outerHTML); + // if the tag is still open IE has created the children as siblings and + // it has also created a tag with the name "/FOO" + if (outerHTML.slice(-2) != "/>") { + var tagName = "/" + el.tagName; + var ns; + // remove content + while ((ns = el.nextSibling) && ns.tagName != tagName) { + ns.removeNode(); + } + // remove the incorrect closing tag + if (ns) { + ns.removeNode(); + } + } + el.parentNode.replaceChild(newEl, el); + return newEl; + }, + + /** + * Public initializes a canvas element so that it can be used as canvas + * element from now on. This is called automatically before the page is + * loaded but if you are creating elements using createElement you need to + * make sure this is called on the element. + * @param {HTMLElement} el The canvas element to initialize. + * @return {HTMLElement} the element that was created. + */ + initElement: function (el) { + el = this.fixElement_(el); + el.getContext = function () { + if (this.context_) { + return this.context_; + } + return this.context_ = new CanvasRenderingContext2D_(this); + }; + + // do not use inline function because that will leak memory + el.attachEvent('onpropertychange', onPropertyChange); + el.attachEvent('onresize', onResize); + + var attrs = el.attributes; + if (attrs.width && attrs.width.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setWidth_(attrs.width.nodeValue); + el.style.width = attrs.width.nodeValue + "px"; + } else { + el.width = el.clientWidth; + } + if (attrs.height && attrs.height.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setHeight_(attrs.height.nodeValue); + el.style.height = attrs.height.nodeValue + "px"; + } else { + el.height = el.clientHeight; + } + //el.getContext().setCoordsize_() + return el; + } + }; + + function onPropertyChange(e) { + var el = e.srcElement; + + switch (e.propertyName) { + case 'width': + el.style.width = el.attributes.width.nodeValue + "px"; + el.getContext().clearRect(); + break; + case 'height': + el.style.height = el.attributes.height.nodeValue + "px"; + el.getContext().clearRect(); + break; + } + } + + function onResize(e) { + var el = e.srcElement; + if (el.firstChild) { + el.firstChild.style.width = el.clientWidth + 'px'; + el.firstChild.style.height = el.clientHeight + 'px'; + } + } + + G_vmlCanvasManager_.init(); + + // precompute "00" to "FF" + var dec2hex = []; + for (var i = 0; i < 16; i++) { + for (var j = 0; j < 16; j++) { + dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); + } + } + + function createMatrixIdentity() { + return [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1] + ]; + } + + function matrixMultiply(m1, m2) { + var result = createMatrixIdentity(); + + for (var x = 0; x < 3; x++) { + for (var y = 0; y < 3; y++) { + var sum = 0; + + for (var z = 0; z < 3; z++) { + sum += m1[x][z] * m2[z][y]; + } + + result[x][y] = sum; + } + } + return result; + } + + function copyState(o1, o2) { + o2.fillStyle = o1.fillStyle; + o2.lineCap = o1.lineCap; + o2.lineJoin = o1.lineJoin; + o2.lineWidth = o1.lineWidth; + o2.miterLimit = o1.miterLimit; + o2.shadowBlur = o1.shadowBlur; + o2.shadowColor = o1.shadowColor; + o2.shadowOffsetX = o1.shadowOffsetX; + o2.shadowOffsetY = o1.shadowOffsetY; + o2.strokeStyle = o1.strokeStyle; + o2.arcScaleX_ = o1.arcScaleX_; + o2.arcScaleY_ = o1.arcScaleY_; + } + + function processStyle(styleString) { + var str, alpha = 1; + + styleString = String(styleString); + if (styleString.substring(0, 3) == "rgb") { + var start = styleString.indexOf("(", 3); + var end = styleString.indexOf(")", start + 1); + var guts = styleString.substring(start + 1, end).split(","); + + str = "#"; + for (var i = 0; i < 3; i++) { + str += dec2hex[Number(guts[i])]; + } + + if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) { + alpha = guts[3]; + } + } else { + str = styleString; + } + + return [str, alpha]; + } + + function processLineCap(lineCap) { + switch (lineCap) { + case "butt": + return "flat"; + case "round": + return "round"; + case "square": + default: + return "square"; + } + } + + /** + * This class implements CanvasRenderingContext2D interface as described by + * the WHATWG. + * @param {HTMLElement} surfaceElement The element that the 2D context should + * be associated with + */ + function CanvasRenderingContext2D_(surfaceElement) { + this.m_ = createMatrixIdentity(); + + this.mStack_ = []; + this.aStack_ = []; + this.currentPath_ = []; + + // Canvas context properties + this.strokeStyle = "#000"; + this.fillStyle = "#000"; + + this.lineWidth = 1; + this.lineJoin = "miter"; + this.lineCap = "butt"; + this.miterLimit = Z * 1; + this.globalAlpha = 1; + this.canvas = surfaceElement; + + var el = surfaceElement.ownerDocument.createElement('div'); + el.style.width = surfaceElement.clientWidth + 'px'; + el.style.height = surfaceElement.clientHeight + 'px'; + el.style.overflow = 'hidden'; + el.style.position = 'absolute'; + surfaceElement.appendChild(el); + + this.element_ = el; + this.arcScaleX_ = 1; + this.arcScaleY_ = 1; + }; + + var contextPrototype = CanvasRenderingContext2D_.prototype; + contextPrototype.clearRect = function() { + this.element_.innerHTML = ""; + this.currentPath_ = []; + }; + + contextPrototype.beginPath = function() { + // TODO: Branch current matrix so that save/restore has no effect + // as per safari docs. + + this.currentPath_ = []; + }; + + contextPrototype.moveTo = function(aX, aY) { + this.currentPath_.push({type: "moveTo", x: aX, y: aY}); + this.currentX_ = aX; + this.currentY_ = aY; + }; + + contextPrototype.lineTo = function(aX, aY) { + this.currentPath_.push({type: "lineTo", x: aX, y: aY}); + this.currentX_ = aX; + this.currentY_ = aY; + }; + + contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, + aCP2x, aCP2y, + aX, aY) { + this.currentPath_.push({type: "bezierCurveTo", + cp1x: aCP1x, + cp1y: aCP1y, + cp2x: aCP2x, + cp2y: aCP2y, + x: aX, + y: aY}); + this.currentX_ = aX; + this.currentY_ = aY; + }; + + contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { + // the following is lifted almost directly from + // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes + var cp1x = this.currentX_ + 2.0 / 3.0 * (aCPx - this.currentX_); + var cp1y = this.currentY_ + 2.0 / 3.0 * (aCPy - this.currentY_); + var cp2x = cp1x + (aX - this.currentX_) / 3.0; + var cp2y = cp1y + (aY - this.currentY_) / 3.0; + this.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, aX, aY); + }; + + contextPrototype.arc = function(aX, aY, aRadius, + aStartAngle, aEndAngle, aClockwise) { + aRadius *= Z; + var arcType = aClockwise ? "at" : "wa"; + + var xStart = aX + (mc(aStartAngle) * aRadius) - Z2; + var yStart = aY + (ms(aStartAngle) * aRadius) - Z2; + + var xEnd = aX + (mc(aEndAngle) * aRadius) - Z2; + var yEnd = aY + (ms(aEndAngle) * aRadius) - Z2; + + // IE won't render arches drawn counter clockwise if xStart == xEnd. + if (xStart == xEnd && !aClockwise) { + xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something + // that can be represented in binary + } + + this.currentPath_.push({type: arcType, + x: aX, + y: aY, + radius: aRadius, + xStart: xStart, + yStart: yStart, + xEnd: xEnd, + yEnd: yEnd}); + + }; + + contextPrototype.rect = function(aX, aY, aWidth, aHeight) { + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + }; + + contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { + // Will destroy any existing path (same as FF behaviour) + this.beginPath(); + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.stroke(); + }; + + contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { + // Will destroy any existing path (same as FF behaviour) + this.beginPath(); + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.fill(); + }; + + contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { + var gradient = new CanvasGradient_("gradient"); + return gradient; + }; + + contextPrototype.createRadialGradient = function(aX0, aY0, + aR0, aX1, + aY1, aR1) { + var gradient = new CanvasGradient_("gradientradial"); + gradient.radius1_ = aR0; + gradient.radius2_ = aR1; + gradient.focus_.x = aX0; + gradient.focus_.y = aY0; + return gradient; + }; + + contextPrototype.drawImage = function (image, var_args) { + var dx, dy, dw, dh, sx, sy, sw, sh; + + // to find the original width we overide the width and height + var oldRuntimeWidth = image.runtimeStyle.width; + var oldRuntimeHeight = image.runtimeStyle.height; + image.runtimeStyle.width = 'auto'; + image.runtimeStyle.height = 'auto'; + + // get the original size + var w = image.width; + var h = image.height; + + // and remove overides + image.runtimeStyle.width = oldRuntimeWidth; + image.runtimeStyle.height = oldRuntimeHeight; + + if (arguments.length == 3) { + dx = arguments[1]; + dy = arguments[2]; + sx = sy = 0; + sw = dw = w; + sh = dh = h; + } else if (arguments.length == 5) { + dx = arguments[1]; + dy = arguments[2]; + dw = arguments[3]; + dh = arguments[4]; + sx = sy = 0; + sw = w; + sh = h; + } else if (arguments.length == 9) { + sx = arguments[1]; + sy = arguments[2]; + sw = arguments[3]; + sh = arguments[4]; + dx = arguments[5]; + dy = arguments[6]; + dw = arguments[7]; + dh = arguments[8]; + } else { + throw "Invalid number of arguments"; + } + + var d = this.getCoords_(dx, dy); + + var w2 = sw / 2; + var h2 = sh / 2; + + var vmlStr = []; + + var W = 10; + var H = 10; + + // For some reason that I've now forgotten, using divs didn't work + vmlStr.push(' ' , + '', + ''); + + this.element_.insertAdjacentHTML("BeforeEnd", + vmlStr.join("")); + }; + + contextPrototype.stroke = function(aFill) { + var lineStr = []; + var lineOpen = false; + var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); + var color = a[0]; + var opacity = a[1] * this.globalAlpha; + + var W = 10; + var H = 10; + + lineStr.push(' max.x) { + max.x = c.x; + } + if (min.y == null || c.y < min.y) { + min.y = c.y; + } + if (max.y == null || c.y > max.y) { + max.y = c.y; + } + } + } + lineStr.push(' ">'); + + if (typeof this.fillStyle == "object") { + var focus = {x: "50%", y: "50%"}; + var width = (max.x - min.x); + var height = (max.y - min.y); + var dimension = (width > height) ? width : height; + + focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%"; + focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%"; + + var colors = []; + + // inside radius (%) + if (this.fillStyle.type_ == "gradientradial") { + var inside = (this.fillStyle.radius1_ / dimension * 100); + + // percentage that outside radius exceeds inside radius + var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside; + } else { + var inside = 0; + var expansion = 100; + } + + var insidecolor = {offset: null, color: null}; + var outsidecolor = {offset: null, color: null}; + + // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie + // won't interpret it correctly + this.fillStyle.colors_.sort(function (cs1, cs2) { + return cs1.offset - cs2.offset; + }); + + for (var i = 0; i < this.fillStyle.colors_.length; i++) { + var fs = this.fillStyle.colors_[i]; + + colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ","); + + if (fs.offset > insidecolor.offset || insidecolor.offset == null) { + insidecolor.offset = fs.offset; + insidecolor.color = fs.color; + } + + if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) { + outsidecolor.offset = fs.offset; + outsidecolor.color = fs.color; + } + } + colors.pop(); + + lineStr.push(''); + } else if (aFill) { + lineStr.push(''); + } else { + lineStr.push( + '' + ); + } + + lineStr.push(""); + + this.element_.insertAdjacentHTML("beforeEnd", lineStr.join("")); + + this.currentPath_ = []; + }; + + contextPrototype.fill = function() { + this.stroke(true); + } + + contextPrototype.closePath = function() { + this.currentPath_.push({type: "close"}); + }; + + /** + * @private + */ + contextPrototype.getCoords_ = function(aX, aY) { + return { + x: Z * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - Z2, + y: Z * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - Z2 + } + }; + + contextPrototype.save = function() { + var o = {}; + copyState(this, o); + this.aStack_.push(o); + this.mStack_.push(this.m_); + this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); + }; + + contextPrototype.restore = function() { + copyState(this.aStack_.pop(), this); + this.m_ = this.mStack_.pop(); + }; + + contextPrototype.translate = function(aX, aY) { + var m1 = [ + [1, 0, 0], + [0, 1, 0], + [aX, aY, 1] + ]; + + this.m_ = matrixMultiply(m1, this.m_); + }; + + contextPrototype.rotate = function(aRot) { + var c = mc(aRot); + var s = ms(aRot); + + var m1 = [ + [c, s, 0], + [-s, c, 0], + [0, 0, 1] + ]; + + this.m_ = matrixMultiply(m1, this.m_); + }; + + contextPrototype.scale = function(aX, aY) { + this.arcScaleX_ *= aX; + this.arcScaleY_ *= aY; + var m1 = [ + [aX, 0, 0], + [0, aY, 0], + [0, 0, 1] + ]; + + this.m_ = matrixMultiply(m1, this.m_); + }; + + /******** STUBS ********/ + contextPrototype.clip = function() { + // TODO: Implement + }; + + contextPrototype.arcTo = function() { + // TODO: Implement + }; + + contextPrototype.createPattern = function() { + return new CanvasPattern_; + }; + + // Gradient / Pattern Stubs + function CanvasGradient_(aType) { + this.type_ = aType; + this.radius1_ = 0; + this.radius2_ = 0; + this.colors_ = []; + this.focus_ = {x: 0, y: 0}; + } + + CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { + aColor = processStyle(aColor); + this.colors_.push({offset: 1-aOffset, color: aColor}); + }; + + function CanvasPattern_() {} + + // set up externs + G_vmlCanvasManager = G_vmlCanvasManager_; + CanvasRenderingContext2D = CanvasRenderingContext2D_; + CanvasGradient = CanvasGradient_; + CanvasPattern = CanvasPattern_; + +})(); + +} // if diff --git a/js-ext/firebug-License.txt b/js-ext/firebug-License.txt index 13679b3b..06f96514 100755 --- a/js-ext/firebug-License.txt +++ b/js-ext/firebug-License.txt @@ -1,469 +1,469 @@ - MOZILLA PUBLIC LICENSE - Version 1.1 - - --------------- - -1. Definitions. - - 1.0.1. "Commercial Use" means distribution or otherwise making the - Covered Code available to a third party. - - 1.1. "Contributor" means each entity that creates or contributes to - the creation of Modifications. - - 1.2. "Contributor Version" means the combination of the Original - Code, prior Modifications used by a Contributor, and the Modifications - made by that particular Contributor. - - 1.3. "Covered Code" means the Original Code or Modifications or the - combination of the Original Code and Modifications, in each case - including portions thereof. - - 1.4. "Electronic Distribution Mechanism" means a mechanism generally - accepted in the software development community for the electronic - transfer of data. - - 1.5. "Executable" means Covered Code in any form other than Source - Code. - - 1.6. "Initial Developer" means the individual or entity identified - as the Initial Developer in the Source Code notice required by Exhibit - A. - - 1.7. "Larger Work" means a work which combines Covered Code or - portions thereof with code not governed by the terms of this License. - - 1.8. "License" means this document. - - 1.8.1. "Licensable" means having the right to grant, to the maximum - extent possible, whether at the time of the initial grant or - subsequently acquired, any and all of the rights conveyed herein. - - 1.9. "Modifications" means any addition to or deletion from the - substance or structure of either the Original Code or any previous - Modifications. When Covered Code is released as a series of files, a - Modification is: - A. Any addition to or deletion from the contents of a file - containing Original Code or previous Modifications. - - B. Any new file that contains any part of the Original Code or - previous Modifications. - - 1.10. "Original Code" means Source Code of computer software code - which is described in the Source Code notice required by Exhibit A as - Original Code, and which, at the time of its release under this - License is not already Covered Code governed by this License. - - 1.10.1. "Patent Claims" means any patent claim(s), now owned or - hereafter acquired, including without limitation, method, process, - and apparatus claims, in any patent Licensable by grantor. - - 1.11. "Source Code" means the preferred form of the Covered Code for - making modifications to it, including all modules it contains, plus - any associated interface definition files, scripts used to control - compilation and installation of an Executable, or source code - differential comparisons against either the Original Code or another - well known, available Covered Code of the Contributor's choice. The - Source Code can be in a compressed or archival form, provided the - appropriate decompression or de-archiving software is widely available - for no charge. - - 1.12. "You" (or "Your") means an individual or a legal entity - exercising rights under, and complying with all of the terms of, this - License or a future version of this License issued under Section 6.1. - For legal entities, "You" includes any entity which controls, is - controlled by, or is under common control with You. For purposes of - this definition, "control" means (a) the power, direct or indirect, - to cause the direction or management of such entity, whether by - contract or otherwise, or (b) ownership of more than fifty percent - (50%) of the outstanding shares or beneficial ownership of such - entity. - -2. Source Code License. - - 2.1. The Initial Developer Grant. - The Initial Developer hereby grants You a world-wide, royalty-free, - non-exclusive license, subject to third party intellectual property - claims: - (a) under intellectual property rights (other than patent or - trademark) Licensable by Initial Developer to use, reproduce, - modify, display, perform, sublicense and distribute the Original - Code (or portions thereof) with or without Modifications, and/or - as part of a Larger Work; and - - (b) under Patents Claims infringed by the making, using or - selling of Original Code, to make, have made, use, practice, - sell, and offer for sale, and/or otherwise dispose of the - Original Code (or portions thereof). - - (c) the licenses granted in this Section 2.1(a) and (b) are - effective on the date Initial Developer first distributes - Original Code under the terms of this License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is - granted: 1) for code that You delete from the Original Code; 2) - separate from the Original Code; or 3) for infringements caused - by: i) the modification of the Original Code or ii) the - combination of the Original Code with other software or devices. - - 2.2. Contributor Grant. - Subject to third party intellectual property claims, each Contributor - hereby grants You a world-wide, royalty-free, non-exclusive license - - (a) under intellectual property rights (other than patent or - trademark) Licensable by Contributor, to use, reproduce, modify, - display, perform, sublicense and distribute the Modifications - created by such Contributor (or portions thereof) either on an - unmodified basis, with other Modifications, as Covered Code - and/or as part of a Larger Work; and - - (b) under Patent Claims infringed by the making, using, or - selling of Modifications made by that Contributor either alone - and/or in combination with its Contributor Version (or portions - of such combination), to make, use, sell, offer for sale, have - made, and/or otherwise dispose of: 1) Modifications made by that - Contributor (or portions thereof); and 2) the combination of - Modifications made by that Contributor with its Contributor - Version (or portions of such combination). - - (c) the licenses granted in Sections 2.2(a) and 2.2(b) are - effective on the date Contributor first makes Commercial Use of - the Covered Code. - - (d) Notwithstanding Section 2.2(b) above, no patent license is - granted: 1) for any code that Contributor has deleted from the - Contributor Version; 2) separate from the Contributor Version; - 3) for infringements caused by: i) third party modifications of - Contributor Version or ii) the combination of Modifications made - by that Contributor with other software (except as part of the - Contributor Version) or other devices; or 4) under Patent Claims - infringed by Covered Code in the absence of Modifications made by - that Contributor. - -3. Distribution Obligations. - - 3.1. Application of License. - The Modifications which You create or to which You contribute are - governed by the terms of this License, including without limitation - Section 2.2. The Source Code version of Covered Code may be - distributed only under the terms of this License or a future version - of this License released under Section 6.1, and You must include a - copy of this License with every copy of the Source Code You - distribute. You may not offer or impose any terms on any Source Code - version that alters or restricts the applicable version of this - License or the recipients' rights hereunder. However, You may include - an additional document offering the additional rights described in - Section 3.5. - - 3.2. Availability of Source Code. - Any Modification which You create or to which You contribute must be - made available in Source Code form under the terms of this License - either on the same media as an Executable version or via an accepted - Electronic Distribution Mechanism to anyone to whom you made an - Executable version available; and if made available via Electronic - Distribution Mechanism, must remain available for at least twelve (12) - months after the date it initially became available, or at least six - (6) months after a subsequent version of that particular Modification - has been made available to such recipients. You are responsible for - ensuring that the Source Code version remains available even if the - Electronic Distribution Mechanism is maintained by a third party. - - 3.3. Description of Modifications. - You must cause all Covered Code to which You contribute to contain a - file documenting the changes You made to create that Covered Code and - the date of any change. You must include a prominent statement that - the Modification is derived, directly or indirectly, from Original - Code provided by the Initial Developer and including the name of the - Initial Developer in (a) the Source Code, and (b) in any notice in an - Executable version or related documentation in which You describe the - origin or ownership of the Covered Code. - - 3.4. Intellectual Property Matters - (a) Third Party Claims. - If Contributor has knowledge that a license under a third party's - intellectual property rights is required to exercise the rights - granted by such Contributor under Sections 2.1 or 2.2, - Contributor must include a text file with the Source Code - distribution titled "LEGAL" which describes the claim and the - party making the claim in sufficient detail that a recipient will - know whom to contact. If Contributor obtains such knowledge after - the Modification is made available as described in Section 3.2, - Contributor shall promptly modify the LEGAL file in all copies - Contributor makes available thereafter and shall take other steps - (such as notifying appropriate mailing lists or newsgroups) - reasonably calculated to inform those who received the Covered - Code that new knowledge has been obtained. - - (b) Contributor APIs. - If Contributor's Modifications include an application programming - interface and Contributor has knowledge of patent licenses which - are reasonably necessary to implement that API, Contributor must - also include this information in the LEGAL file. - - (c) Representations. - Contributor represents that, except as disclosed pursuant to - Section 3.4(a) above, Contributor believes that Contributor's - Modifications are Contributor's original creation(s) and/or - Contributor has sufficient rights to grant the rights conveyed by - this License. - - 3.5. Required Notices. - You must duplicate the notice in Exhibit A in each file of the Source - Code. If it is not possible to put such notice in a particular Source - Code file due to its structure, then You must include such notice in a - location (such as a relevant directory) where a user would be likely - to look for such a notice. If You created one or more Modification(s) - You may add your name as a Contributor to the notice described in - Exhibit A. You must also duplicate this License in any documentation - for the Source Code where You describe recipients' rights or ownership - rights relating to Covered Code. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability - obligations to one or more recipients of Covered Code. However, You - may do so only on Your own behalf, and not on behalf of the Initial - Developer or any Contributor. You must make it absolutely clear than - any such warranty, support, indemnity or liability obligation is - offered by You alone, and You hereby agree to indemnify the Initial - Developer and every Contributor for any liability incurred by the - Initial Developer or such Contributor as a result of warranty, - support, indemnity or liability terms You offer. - - 3.6. Distribution of Executable Versions. - You may distribute Covered Code in Executable form only if the - requirements of Section 3.1-3.5 have been met for that Covered Code, - and if You include a notice stating that the Source Code version of - the Covered Code is available under the terms of this License, - including a description of how and where You have fulfilled the - obligations of Section 3.2. The notice must be conspicuously included - in any notice in an Executable version, related documentation or - collateral in which You describe recipients' rights relating to the - Covered Code. You may distribute the Executable version of Covered - Code or ownership rights under a license of Your choice, which may - contain terms different from this License, provided that You are in - compliance with the terms of this License and that the license for the - Executable version does not attempt to limit or alter the recipient's - rights in the Source Code version from the rights set forth in this - License. If You distribute the Executable version under a different - license You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial - Developer or any Contributor. You hereby agree to indemnify the - Initial Developer and every Contributor for any liability incurred by - the Initial Developer or such Contributor as a result of any such - terms You offer. - - 3.7. Larger Works. - You may create a Larger Work by combining Covered Code with other code - not governed by the terms of this License and distribute the Larger - Work as a single product. In such a case, You must make sure the - requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Code due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description - must be included in the LEGAL file described in Section 3.4 and must - be included with all distributions of the Source Code. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Application of this License. - - This License applies to code to which the Initial Developer has - attached the notice in Exhibit A and to related Covered Code. - -6. Versions of the License. - - 6.1. New Versions. - Netscape Communications Corporation ("Netscape") may publish revised - and/or new versions of the License from time to time. Each version - will be given a distinguishing version number. - - 6.2. Effect of New Versions. - Once Covered Code has been published under a particular version of the - License, You may always continue to use it under the terms of that - version. You may also choose to use such Covered Code under the terms - of any subsequent version of the License published by Netscape. No one - other than Netscape has the right to modify the terms applicable to - Covered Code created under this License. - - 6.3. Derivative Works. - If You create or use a modified version of this License (which you may - only do in order to apply it to code which is not already Covered Code - governed by this License), You must (a) rename Your license so that - the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", - "MPL", "NPL" or any confusingly similar phrase do not appear in your - license (except to note that your license differs from this License) - and (b) otherwise make it clear that Your version of the license - contains terms which differ from the Mozilla Public License and - Netscape Public License. (Filling in the name of the Initial - Developer, Original Code or Contributor in the notice described in - Exhibit A shall not of themselves be deemed to be modifications of - this License.) - -7. DISCLAIMER OF WARRANTY. - - COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF - DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE - IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, - YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE - COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER - OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF - ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - - 8.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to cure - such breach within 30 days of becoming aware of the breach. All - sublicenses to the Covered Code which are properly granted shall - survive any termination of this License. Provisions which, by their - nature, must remain in effect beyond the termination of this License - shall survive. - - 8.2. If You initiate litigation by asserting a patent infringement - claim (excluding declatory judgment actions) against Initial Developer - or a Contributor (the Initial Developer or Contributor against whom - You file such action is referred to as "Participant") alleging that: - - (a) such Participant's Contributor Version directly or indirectly - infringes any patent, then any and all rights granted by such - Participant to You under Sections 2.1 and/or 2.2 of this License - shall, upon 60 days notice from Participant terminate prospectively, - unless if within 60 days after receipt of notice You either: (i) - agree in writing to pay Participant a mutually agreeable reasonable - royalty for Your past and future use of Modifications made by such - Participant, or (ii) withdraw Your litigation claim with respect to - the Contributor Version against such Participant. If within 60 days - of notice, a reasonable royalty and payment arrangement are not - mutually agreed upon in writing by the parties or the litigation claim - is not withdrawn, the rights granted by Participant to You under - Sections 2.1 and/or 2.2 automatically terminate at the expiration of - the 60 day notice period specified above. - - (b) any software, hardware, or device, other than such Participant's - Contributor Version, directly or indirectly infringes any patent, then - any rights granted to You by such Participant under Sections 2.1(b) - and 2.2(b) are revoked effective as of the date You first made, used, - sold, distributed, or had made, Modifications made by that - Participant. - - 8.3. If You assert a patent infringement claim against Participant - alleging that such Participant's Contributor Version directly or - indirectly infringes any patent where such claim is resolved (such as - by license or settlement) prior to the initiation of patent - infringement litigation, then the reasonable value of the licenses - granted by such Participant under Sections 2.1 or 2.2 shall be taken - into account in determining the amount or value of any payment or - license. - - 8.4. In the event of termination under Sections 8.1 or 8.2 above, - all end user license agreements (excluding distributors and resellers) - which have been validly granted by You or any distributor hereunder - prior to termination shall survive termination. - -9. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT - (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL - DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, - OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR - ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY - CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, - WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER - COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN - INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF - LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY - RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW - PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO - THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - - The Covered Code is a "commercial item," as that term is defined in - 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer - software" and "commercial computer software documentation," as such - terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 - C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), - all U.S. Government End Users acquire Covered Code with only those - rights set forth herein. - -11. MISCELLANEOUS. - - This License represents the complete agreement concerning subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. This License shall be governed by - California law provisions (except to the extent applicable law, if - any, provides otherwise), excluding its conflict-of-law provisions. - With respect to disputes in which at least one party is a citizen of, - or an entity chartered or registered to do business in the United - States of America, any litigation relating to this License shall be - subject to the jurisdiction of the Federal Courts of the Northern - District of California, with venue lying in Santa Clara County, - California, with the losing party responsible for costs, including - without limitation, court costs and reasonable attorneys' fees and - expenses. The application of the United Nations Convention on - Contracts for the International Sale of Goods is expressly excluded. - Any law or regulation which provides that the language of a contract - shall be construed against the drafter shall not apply to this - License. - -12. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is - responsible for claims and damages arising, directly or indirectly, - out of its utilization of rights under this License and You agree to - work with Initial Developer and Contributors to distribute such - responsibility on an equitable basis. Nothing herein is intended or - shall be deemed to constitute any admission of liability. - -13. MULTIPLE-LICENSED CODE. - - Initial Developer may designate portions of the Covered Code as - "Multiple-Licensed". "Multiple-Licensed" means that the Initial - Developer permits you to utilize portions of the Covered Code under - Your choice of the NPL or the alternative licenses, if any, specified - by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. - - ``The contents of this file are subject to the Mozilla Public License - Version 1.1 (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.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - License for the specific language governing rights and limitations - under the License. - - The Original Code is ______________________________________. - - The Initial Developer of the Original Code is ________________________. - Portions created by ______________________ are Copyright (C) ______ - _______________________. All Rights Reserved. - - Contributor(s): ______________________________________. - - Alternatively, the contents of this file may be used under the terms - of the _____ license (the "[___] License"), in which case the - provisions of [______] License are applicable instead of those - above. If you wish to allow use of your version of this file only - under the terms of the [____] License and not to allow others to use - your version of this file under the MPL, indicate your decision by - deleting the provisions above and replace them with the notice and - other provisions required by the [___] License. If you do not delete - the provisions above, a recipient may use your version of this file - under either the MPL or the [___] License." - - [NOTE: The text of this Exhibit A may differ slightly from the text of - the notices in the Source Code files of the Original Code. You should - use the text of this Exhibit A rather than the text found in the - Original Code Source Code for Your Modifications.] + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (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.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] diff --git a/js-ext/firebug/firebug-lite-compressed.js b/js-ext/firebug/firebug-lite-compressed.js index af2c05dc..abd035ad 100755 --- a/js-ext/firebug/firebug-lite-compressed.js +++ b/js-ext/firebug/firebug-lite-compressed.js @@ -1,118 +1,118 @@ -var firebug={version:[1.23,20090309],el:{},env:{"cache":{},"extConsole":null,"css":"http://getfirebug.com/releases/lite/1.2/firebug-lite.css","debug":true,"detectFirebug":false,"dIndex":"console","height":295,"hideDOMFunctions":false,"init":false,"isPopup":false,"liteFilename":"firebug-lite.js","minimized":false,"openInPopup":false,"override":false,"ml":false,"popupWin":null,"showIconWhenHidden":true,"targetWindow":undefined,"popupTop":1,"popupLeft":1,"popupWidth":undefined,"popupHeight":undefined},initConsole:function(){var command;try{if((!window.console||(window.console&&!window.console.firebug))||(firebug.env.override&&!(/Firefox\/3/i.test(navigator.userAgent)))){window.console={"provider":"Firebug Lite"};for(command in firebug.d.console.cmd){window.console[command]=firebug.lib.util.Curry(firebug.d.console.run,window,command);};} -window.onerror=function(_message,_file,_line){firebug.d.console.run('error',firebug.lib.util.String.format('{0} ({1},{2})',_message,firebug.getFileName(_file),_line));};}catch(e){}},overrideConsole:function(){with(firebug){env.override=true;try{env.extConsole=window.console;}catch(e){} -initConsole();}},restoreConsole:function(){with(firebug){if(env.extConsole){env.override=false;try{window.console=env.extConsole;}catch(e){} -env.extConsole=null;}}},init:function(_css){var iconTitle="Click here or press F12, (CTRL|CMD)+SHIFT+L or SHIFT+ENTER to show Firebug Lite. CTRL|CMD click this icon to hide it.";with(firebug){if(document.getElementsByTagName('html')[0].attributes.getNamedItem('debug')){env.debug=document.getElementsByTagName('html')[0].attributes.getNamedItem('debug').nodeValue!=="false";} -if(env.isPopup){env.openInPopup=false;env.targetWindow=window.opener;env.popupWidth=window.opener.firebug.env.popupWidth||window.opener.firebug.lib.util.GetViewport().width;env.popupHeight=window.opener.firebug.env.popupHeight||window.opener.firebug.lib.util.GetViewport().height;}else{env.targetWindow=window;env.popupWidth=env.popupWidth||lib.util.GetViewport().width;env.popupHeight=env.popupHeight||lib.util.GetViewport().height;} -settings.readCookie();if(env.init||(env.detectFirebug&&window.console&&window.console.firebug)){return;} -document.getElementsByTagName("head")[0].appendChild(new lib.element("link").attribute.set("rel","stylesheet").attribute.set("type","text/css").attribute.set("href",env.css).element);if(env.override){overrideConsole();} -el.firebugIcon=new lib.element("div").attribute.set("id","firebugIconDiv").attribute.set("title",iconTitle).attribute.set("alt",iconTitle).event.addListener("mousedown",win.iconClicked).insert(document.body);el.content={};el.mainiframe=new lib.element("IFRAME").attribute.set("id","FirebugIFrame").environment.addStyle({"display":"none","width":lib.util.GetViewport().width+"px"}).insert(document.body);el.main=new lib.element("DIV").attribute.set("id","Firebug").environment.addStyle({"display":"none","width":lib.util.GetViewport().width+"px"}).insert(document.body);if(!env.isPopup){el.resizer=new lib.element("DIV").attribute.addClass("Resizer").event.addListener("mousedown",win.resizer.start).insert(el.main);} -el.header=new lib.element("DIV").attribute.addClass("Header").insert(el.main);el.left={};el.left.container=new lib.element("DIV").attribute.addClass("Left").insert(el.main);el.right={};el.right.container=new lib.element("DIV").attribute.addClass("Right").insert(el.main);el.main.child.add(new lib.element("DIV").attribute.addClass('Clear'));el.button={};el.button.container=new lib.element("DIV").attribute.addClass("ButtonContainer").insert(el.header);el.button.logo=new lib.element("A").attribute.set("title","Firebug Lite").attribute.set("target","_blank").attribute.set("href","http://getfirebug.com/lite.html").update(" ").attribute.addClass("Button Logo").insert(el.button.container);el.button.inspect=new lib.element("A").attribute.addClass("Button").event.addListener("click",env.targetWindow.firebug.d.inspector.toggle).update("Inspect").insert(el.button.container);el.button.dock=new lib.element("A").attribute.addClass("Button Dock").event.addListener("click",win.dock).insert(el.button.container);el.button.newWindow=new lib.element("A").attribute.addClass("Button NewWindow").event.addListener("click",win.newWindow).insert(el.button.container);if(!env.isPopup){el.button.maximize=new lib.element("A").attribute.addClass("Button Maximize").event.addListener("click",win.maximize).insert(el.button.container);el.button.minimize=new lib.element("A").attribute.addClass("Button Minimize").event.addListener("click",win.minimize).insert(el.button.container);el.button.close=new lib.element("A").attribute.addClass("Button Close").event.addListener("click",win.hide).insert(el.button.container);} -if(lib.env.ie||lib.env.webkit){el.button.container.environment.addStyle({"paddingTop":"12px"});} -el.nav={};el.nav.container=new lib.element("DIV").attribute.addClass("Nav").insert(el.left.container);el.nav.console=new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.navigate,window,"console")).update("Console").insert(el.nav.container);el.nav.html=new lib.element("A").attribute.addClass("Tab").update("HTML").event.addListener("click",lib.util.Curry(d.navigate,window,"html")).insert(el.nav.container);el.nav.css=new lib.element("A").attribute.addClass("Tab").update("CSS").event.addListener("click",lib.util.Curry(d.navigate,window,"css")).insert(el.nav.container);if(!env.isPopup){el.nav.scripts=new lib.element("A").attribute.addClass("Tab").update("Script").event.addListener("click",lib.util.Curry(d.navigate,window,"scripts")).insert(el.nav.container);} -el.nav.dom=new lib.element("A").attribute.addClass("Tab").update("DOM").event.addListener("click",lib.util.Curry(d.navigate,env.targetWindow,"dom")).insert(el.nav.container);el.nav.xhr=new lib.element("A").attribute.addClass("Tab").update("XHR").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).insert(el.nav.container);el.nav.optionsdiv=new lib.element("DIV").attribute.addClass("Settings").insert(el.nav.container);el.nav.options=new lib.element("A").attribute.addClass("Tab").update("Options ∨").event.addListener("click",settings.toggle).insert(el.nav.optionsdiv);el.borderInspector=new lib.element("DIV").attribute.set("id","FirebugBorderInspector").event.addListener("click",listen.inspector).insert(document.body);el.bgInspector=new lib.element("DIV").attribute.set("id","FirebugBGInspector").insert(document.body);el.left.console={};el.left.console.container=new lib.element("DIV").attribute.addClass("Console").insert(el.left.container);el.left.console.mlButton=new lib.element("A").attribute.addClass("MLButton").event.addListener("click",d.console.toggleML).insert(el.left.console.container);el.left.console.monitor=new lib.element("DIV").insert(new lib.element("DIV").attribute.addClass("Monitor").insert(el.left.console.container));el.left.console.container.child.add(new lib.element("DIV").attribute.addClass("InputArrow").update(">>>"));el.left.console.input=new lib.element("INPUT").attribute.set("type","text").attribute.addClass("Input").event.addListener("keydown",listen.consoleTextbox).insert(new lib.element("DIV").attribute.addClass("InputContainer").insert(el.left.console.container));el.right.console={};el.right.console.container=new lib.element("DIV").attribute.addClass("Console Container").insert(el.right.container);el.right.console.mlButton=new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.console.container);el.right.console.input=new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.console.container);el.right.console.input.event.addListener("keydown",lib.util.Curry(tab,window,el.right.console.input.element));el.right.console.run=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runMultiline).update("Run").insert(el.right.console.container);el.right.console.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.console.input)).update("Clear").insert(el.right.console.container);el.button.console={};el.button.console.container=new lib.element("DIV").attribute.addClass("ButtonSet").insert(el.button.container);el.button.console.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",d.console.clear).update("Clear").insert(el.button.console.container);el.left.html={};el.left.html.container=new lib.element("DIV").attribute.addClass("HTML").insert(el.left.container);el.right.html={};el.right.html.container=new lib.element("DIV").attribute.addClass("HTML Container").insert(el.right.container);el.right.html.nav={};el.right.html.nav.container=new lib.element("DIV").attribute.addClass("Nav").insert(el.right.html.container);el.right.html.nav.computedStyle=new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"computedStyle")).update("Computed Style").insert(el.right.html.nav.container);el.right.html.nav.dom=new lib.element("A").attribute.addClass("Tab").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"dom")).update("DOM").insert(el.right.html.nav.container);el.right.html.content=new lib.element("DIV").attribute.addClass("Content").insert(el.right.html.container);el.button.html={};el.button.html.container=new lib.element("DIV").attribute.addClass("ButtonSet HTML").insert(el.button.container);el.left.css={};el.left.css.container=new lib.element("DIV").attribute.addClass("CSS").insert(el.left.container);el.right.css={};el.right.css.container=new lib.element("DIV").attribute.addClass("CSS Container").insert(el.right.container);el.right.css.nav={};el.right.css.nav.container=new lib.element("DIV").attribute.addClass("Nav").insert(el.right.css.container);el.right.css.nav.runCSS=new lib.element("A").attribute.addClass("Tab Selected").update("Run CSS").insert(el.right.css.nav.container);el.right.css.mlButton=new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.css.container);el.right.css.input=new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.css.container);el.right.css.input.event.addListener("keydown",lib.util.Curry(firebug.tab,window,el.right.css.input.element));el.right.css.run=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runCSS).update("Run").insert(el.right.css.container);el.right.css.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.css.input)).update("Clear").insert(el.right.css.container);el.button.css={};el.button.css.container=new lib.element("DIV").attribute.addClass("ButtonSet CSS").insert(el.button.container);el.button.css.selectbox=new lib.element("SELECT").event.addListener("change",listen.cssSelectbox).insert(el.button.css.container);el.left.scripts={};el.left.scripts.container=new lib.element("DIV").attribute.addClass("Scripts").insert(el.left.container);el.right.scripts={};el.right.scripts.container=new lib.element("DIV").attribute.addClass("Scripts Container").insert(el.right.container);el.button.scripts={};el.button.scripts.container=new lib.element("DIV").attribute.addClass("ButtonSet Scripts").insert(el.button.container);el.button.scripts.selectbox=new lib.element("SELECT").event.addListener("change",listen.scriptsSelectbox).insert(el.button.scripts.container);el.button.scripts.lineNumbers=new lib.element("A").attribute.addClass("Button").event.addListener("click",d.scripts.toggleLineNumbers).update("Show Line Numbers").insert(el.button.scripts.container);el.left.dom={};el.left.dom.container=new lib.element("DIV").attribute.addClass("DOM").insert(el.left.container);el.right.dom={};el.right.dom.container=new lib.element("DIV").attribute.addClass("DOM Container").insert(el.right.container);el.button.dom={};el.button.dom.container=new lib.element("DIV").attribute.addClass("ButtonSet DOM").insert(el.button.container);el.button.dom.label=new lib.element("LABEL").update("Object Path:").insert(el.button.dom.container);el.button.dom.textbox=new lib.element("INPUT").event.addListener("keydown",listen.domTextbox).update(env.isPopup?"window.opener":"window").insert(el.button.dom.container);el.left.str={};el.left.str.container=new lib.element("DIV").attribute.addClass("STR").insert(el.left.container);el.right.str={};el.right.str.container=new lib.element("DIV").attribute.addClass("STR").insert(el.left.container);el.button.str={};el.button.str.container=new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container);el.button.str.watch=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).update("Back").insert(el.button.str.container);el.left.xhr={};el.left.xhr.container=new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container);el.right.xhr={};el.right.xhr.container=new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container);el.button.xhr={};el.button.xhr.container=new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container);el.button.xhr.label=new lib.element("LABEL").update("XHR Path:").insert(el.button.xhr.container);el.button.xhr.textbox=new lib.element("INPUT").event.addListener("keydown",listen.xhrTextbox).insert(el.button.xhr.container);el.button.xhr.watch=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.addXhrObject).update("Watch").insert(el.button.xhr.container);el.settings={};el.settings.container=new lib.element("DIV").child.add(new lib.element("DIV").attribute.addClass("Header").child.add(new lib.element().attribute.addClass("Title").update('Firebug Lite Settings'))).attribute.addClass("SettingsDiv").insert(el.main);el.settings.content=new lib.element("DIV").attribute.addClass("Content").insert(el.settings.container);el.settings.progressDiv=new lib.element("DIV").attribute.addClass("ProgressDiv").insert(el.settings.content);el.settings.progress=new lib.element("DIV").attribute.addClass("Progress").insert(el.settings.progressDiv);el.settings.cbxDebug=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Start visible"));new lib.element("BR").insert(el.settings.content);el.settings.cbxDetectFirebug=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Hide when Firebug active"));new lib.element("BR").insert(el.settings.content);el.settings.cbxHideDOMFunctions=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Hide DOM functions"));new lib.element("BR").insert(el.settings.content);el.settings.cbxOverride=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Override window.console"));new lib.element("BR").insert(el.settings.content);el.settings.cbxShowIcon=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Show icon when hidden"));new lib.element("BR").insert(el.settings.content);el.settings.cbxOpenInPopup=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Open in popup"));el.settings.buttonDiv=new lib.element("DIV").insert(el.settings.content);el.settings.buttonLeftDiv=new lib.element("DIV").attribute.addClass("ButtonsLeft").insert(el.settings.buttonDiv);el.settings.resetButton=new lib.element("INPUT").attribute.set("type","button").update("Reset").event.addListener("click",settings.reset).insert(el.settings.buttonLeftDiv);el.settings.buttonRightDiv=new lib.element("DIV").attribute.addClass("ButtonsRight").insert(el.settings.buttonDiv);el.settings.cancelButton=new lib.element("INPUT").attribute.set("type","button").update("Cancel").event.addListener("click",settings.hide).insert(el.settings.buttonRightDiv);el.settings.buttonRightDiv.child.add(document.createTextNode(" "));el.settings.saveButton=new lib.element("INPUT").attribute.set("type","button").update("Save").event.addListener("click",settings.saveClicked).insert(el.settings.buttonRightDiv);lib.util.AddEvent(document,"mousemove",listen.mouse)("mousemove",win.resizer.resize)("mouseup",win.resizer.stop)("keydown",listen.keyboard);env.init=true;for(var i=0,len=d.console.cache.length;i0){cookieArr=targetWindow.document.cookie.split('; ');for(i=0;i-1){scriptPath=scripts[i].src;break;}} -if(scriptPath){script=fe.popupWin.document.createElement('script'),done=false;script.type='text/javascript';script.src=scriptPath;script[firebug.lib.env.ie?"onreadystatechange":"onload"]=function(){if(!done&&(!firebug.lib.env.ie||this.readyState=="complete"||this.readyState=="loaded")){done=true;if(fe.popupWin.firebug){with(fe.popupWin.firebug){env.isPopup=true;env.css=fe.css;init();el.button.dock.environment.addStyle({"display":"block"});el.button.newWindow.environment.addStyle({"display":"none"});}}}};if(!done&&firebug.lib.env.webkit){fe.popupWin.document.write('');interval=setInterval(function(){if(fe.popupWin.firebug){clearInterval(interval);done=true;with(fe.popupWin.firebug){env.isPopup=true;env.css=fe.css;init();el.button.dock.environment.addStyle({"display":"block"});el.button.newWindow.environment.addStyle({"display":"none"});}}},10);};if(!done){fe.popupWin.document.getElementsByTagName('head')[0].appendChild(script);firebug.el.main.environment.addStyle({"display":"none"});firebug.el.mainiframe.environment.addStyle({"display":"none"});}}else{alert("Unable to detect the following script \""+fe.liteFilename+"\" ... if the script has been renamed then please set the value of firebug.env.liteFilename to reflect this change");fe.popupWin.close();fe.popupWin=null;}}}},dock:function(){with(opener.firebug){env.popupWin=null;el.main.environment.addStyle({"display":"block"});el.mainiframe.environment.addStyle({"display":"block"});settings.readCookie();window.close();};},unload:function(){with(firebug){if(env.isPopup){win.dock();}else if(env.popupWin){env.popupWin.close();}}},fitToPopup:function(){with(firebug){var viewport=lib.util.GetViewport(window);win.setHeight((window.innerHeight||viewport.height)-38);el.main.environment.addStyle({"width":(viewport.width)+"px"});el.mainiframe.environment.addStyle({"width":(viewport.width)+"px"});}},resizer:{y:[],enabled:false,start:function(_event){with(firebug){if(env.minimized)return;win.resizer.y=[el.main.element.offsetHeight,_event.clientY];if(lib.env.ie6){win.resizer.y[3]=parseInt(el.main.environment.getPosition().top);} -win.resizer.enabled=true;}},resize:function(_event){with(firebug){if(!win.resizer.enabled)return;win.resizer.y[2]=(win.resizer.y[0]+(win.resizer.y[1]-_event.clientY));el.main.environment.addStyle({"height":win.resizer.y[2]+"px"});el.mainiframe.environment.addStyle({"height":win.resizer.y[2]+"px"});if(lib.env.ie6){el.main.environment.addStyle({"top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px"});el.mainiframe.environment.addStyle({"top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px"});}}},stop:function(_event){with(firebug){if(win.resizer.enabled){win.resizer.enabled=false;win.setHeight(win.resizer.y[2]-35);}}}},setHeight:function(_height){with(firebug){env.height=_height;el.left.container.environment.addStyle({"height":_height+"px"});el.right.container.environment.addStyle({"height":_height+"px"});el.main.environment.addStyle({"height":_height+38+"px"});el.mainiframe.environment.addStyle({"height":_height+38+"px"});win.refreshSize();el.left.console.monitor.element.parentNode.style.height=_height-47+"px";el.left.console.mlButton.environment.addStyle({"top":_height+19+"px"});el.right.console.mlButton.environment.addStyle({"top":_height+19+"px"});el.right.console.input.environment.addStyle({"height":_height-29+"px"});el.left.html.container.environment.addStyle({"height":_height-23+"px"});el.right.html.content.environment.addStyle({"height":_height-23+"px"});el.left.css.container.environment.addStyle({"height":_height-33+"px"});el.right.css.input.environment.addStyle({"height":_height-55+"px"});el.left.scripts.container.environment.addStyle({"height":_height-23+"px"});el.left.dom.container.environment.addStyle({"height":_height-31+"px"});el.left.xhr.container.environment.addStyle({"height":_height-32+"px"});el.left.str.container.environment.addStyle({"height":_height-32+"px"});}},refreshDOM:function(){with(firebug){d.dom.open(eval(el.button.dom.textbox.environment.getElement().value),el.left.dom.container);if(d.html.nIndex=="dom"){firebug.d.html.navigate("dom")}}},refreshSize:function(){with(firebug){if(!env.init) -return;var dim=lib.util.GetViewport();el.main.environment.addStyle({"width":dim.width+"px"});el.mainiframe.environment.addStyle({"width":dim.width+"px"});if(lib.env.ie6) -win.setVerticalPosition(dim);}},setVerticalPosition:function(_dim,_event){with(firebug){var dim=_dim||lib.util.GetViewport();el.main.environment.addStyle({"top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px"});el.mainiframe.environment.addStyle({"top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px"});}}},d:{clean:function(_element){with(firebug){_element.update("");}},console:{addLine:function(){with(firebug){return new lib.element("DIV").attribute.addClass("Row").insert(el.left.console.monitor);}},cache:[],clear:function(){with(firebug){d.clean(el.left.console.monitor);d.console.cache=[];}},formatArgs:function(){with(firebug){var content=[];for(var i=0,len=arguments.length;i>> "+_cmd);d.console.addLine().update(d.highlight(_text,false,false,true));d.console.scroll();}},printException:function(_exception){with(firebug){var message=_exception.description||_exception.message||_exception;if(_exception.fileName){message+=' ('+(_exception.name&&(_exception.name+', ')||'')+getFileName(_exception.fileName)+', '+_exception.lineNumber+')';} -d.console.addLine().attribute.addClass("Error").update("Error: "+message,true);}},eval:function(_cmd){var result;with(firebug){if(_cmd.length==0) -return;el.left.console.input.environment.getElement().value="";d.console.historyIndex=d.console.history.push(_cmd);try{if(_cmd==='console.firebug'){d.console.addLine().attribute.addClass("Arrow").update(firebug.version);}else{result=eval.call(window,_cmd);d.console.print(_cmd,result);}}catch(e){d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd);d.console.printException(e);} -d.console.scroll();}},scroll:function(){with(firebug){el.left.console.monitor.environment.getElement().parentNode.scrollTop=Math.abs(el.left.console.monitor.environment.getSize().offsetHeight-(el.left.console.monitor.element.parentNode.offsetHeight-11));}},run:function(_command){with(firebug){if(!env.init){d.console.cache.push({"command":_command,"arg":Array.prototype.slice.call(arguments,1)});}else{d.console.cmd[_command].apply(window,Array.prototype.slice.call(arguments,1));}}},toggleML:function(){with(firebug){var open=!env.ml;env.ml=!env.ml;d.navigateRightColumn("console",open);el[open?"left":"right"].console.mlButton.environment.addStyle({display:"none"});el[!open?"left":"right"].console.mlButton.environment.addStyle({display:"block"});el.left.console.mlButton.attribute[(open?"add":"remove")+"Class"]("CloseML");}},countMap:{},timeMap:{},cmd:{log:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Log").update(args);d.console.scroll();}},warn:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Warn").update(args);d.console.scroll();}},info:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Info").update(args);d.console.scroll();}},debug:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Debug").update(args);d.console.scroll();}},error:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Error").update(args);d.console.scroll();}},trace:function(_value){with(firebug){var stackAmt=3,f=arguments.caller,isArray=lib.util.IsArray(f);if((!isArray&&f)||(isArray&&f.length>0)){d.console.addLine().attribute.addClass("Arrow").update(">>> console.trace(stack)");for(var i=0;i>> console.dir("+_value+")");d.dom.open(_value,d.console.addLine());}},dirxml:function(){with(firebug){d.console.cmd.log.apply(this,arguments);}},time:function(_name){with(firebug){d.console.timeMap[_name]=new Date().getTime();}},timeEnd:function(_name){with(firebug){if(_name in d.console.timeMap){var delta=new Date().getTime()-d.console.timeMap[_name],args=d.console.formatArgs.apply(window,[_name+":",delta+"ms"]);d.console.addLine().attribute.addClass("log").update(args);delete d.console.timeMap[_name];}}},count:function(_name){with(firebug){if(!d.console.countMap[_name]) -d.console.countMap[_name]=0;d.console.countMap[_name]++;d.console.cmd.log.apply(window,[_name,d.console.countMap[_name]]);}},group:function(){with(firebug){d.console.cmd.log.apply(this,["console.group is not supported"]);}},groupEnd:function(){with(firebug){d.console.cmd.log.apply(this,["console.groupEnd is not supported"]);}},profile:function(){with(firebug){d.console.cmd.log.apply(this,["console.profile is not supported"]);}},profileEnd:function(){with(firebug){d.console.cmd.log.apply(this,["console.profileEnd is not supported"]);}}}},css:{index:-1,open:function(_index){with(firebug){var item=env.targetWindow.document.styleSheets[_index],uri=item.href;try{var rules=item[lib.env.ie?"rules":"cssRules"],str="";for(var i=0;iAccess to restricted URI denied";} -el.left.css.container.update(str);}},printRule:function(_selector,_css,_layer){with(firebug){var str="
"+_selector+" {
";for(var i=0,len=_css.length;i"+item.replace(/(.+\:)(.+)/,"$1$2;")+"";} -str+="
}
";return str;}},refresh:function(){with(firebug){el.button.css.selectbox.update("");var collection=env.targetWindow.document.styleSheets;for(var i=0,len=collection.length;inull");}else if(vtype=="regexp"){result.push(""+_value+"");}else if(vtype=="date"){result.push("'"+_value+"'");}else if(vtype=="boolean"||vtype=="number"){result.push(""+_value+"");}else if(vtype=="function"){result.push("function()");}else{result.push("\""+(!_inObject&&!_inArray?_value:_value.substring(0,35)+(_value.length>35?" ...":"")).replace(/\n/g,"\\n").replace(/\s/g," ").replace(/>/g,">").replace(/");}} -else if(isElement){if(_value.nodeType==3) -result.push(d.highlight(_value.nodeValue));else if(_inObject){result.push(""+_value.nodeName.toLowerCase()+"");}else{result.push("");if(_inArray){result.push(_value.nodeName.toLowerCase());if(_value.getAttribute){if(_value.getAttribute&&_value.getAttribute("id")) -result.push("#"+_value.getAttribute("id")+"");var elClass=_value.getAttribute(lib.env.ie&&!lib.env.ie8?"className":"class")||"";result.push(!elClass?"":"."+elClass.split(" ")[0]+"");} -result.push("");}else{result.push("<"+_value.nodeName.toLowerCase());if(_value.attributes){for(var i=0,len=_value.attributes.length;i"+item.nodeName+"=\""+item.nodeValue+"\"");}} -result.push(">");}}} -else if(isArray||isHash){if(isArray){if(_inObject){result.push("["+_value.length+"]");}else{result.push("[ ");for(var i=0,len=_value.length;i3){result.push(", "+(len-4)+" More...");break;} -result.push((i>0?", ":"")+d.highlight(_value[i],false,true,true));} -result.push(" ]");}}else if(_inObject){result.push("Object");}else{result.push("Object");var i=0;for(var key in _value){var value=_value[key];if((_inObject||_inArray)&&i>3){result.push(" More...");break;} -result.push(" "+key+"="+d.highlight(value,true));i++;} -result.push("");}}else{result.push([""+_value+""]);}}catch(e){result.push("..");} -return result.join("");}},html:{nIndex:"computedStyle",current:null,highlight:function(_element,_clear,_event){with(firebug){if(_element.firebugElement){return;} -if(_clear){env.targetWindow.firebug.el.bgInspector.environment.addStyle({"display":"none"});return;} -d.inspector.inspect(_element,true);}},inspect:function(_element){var map=[],parentLayer,t,tagName,parent=_element;while(parent){map.push(parent);if(parent==firebug.env.targetWindow.document.body)break;parent=parent.parentNode;} -map=map.reverse();with(firebug){if(env.dIndex!="html"){env.targetWindow.firebug.d.navigate("html");} -env.targetWindow.firebug.d.inspector.toggle(false);for(t=0;t<html>").insert(parent);};for(var i=0;i<=len;i++){if(i==len){new lib.element("A").attribute.addClass("Block").update("</"+element.nodeName.toLowerCase()+">").insert(container);break;} -var item=element.childNodes[i];if(item.nodeType!=3){var container=new lib.element().attribute.addClass("Block").insert(parent),link=new lib.element("A").attribute.addClass("Link").insert(container),spacer=new lib.element("SPAN").attribute.addClass("Spacer").update(" ").insert(link),html=new lib.element("SPAN").attribute.addClass("Content").update(d.highlight(item)).insert(link),subContainer=new lib.element("DIV").attribute.addClass("SubContainer").insert(container),view=lib.util.Element.getView(item);link.event.addListener("click",lib.util.Curry(d.html.openHtmlTree,window,item,subContainer,false));link.event.addListener("mouseover",lib.util.Curry(d.html.highlight,window,item,false));link.event.addListener("mouseout",lib.util.Curry(d.html.highlight,window,item,true));returnParentVal=returnParentEl==item?subContainer:returnParentVal;if(d.html.current==null&&item==document.body){link.attribute.addClass("Selected");d.html.current=[item,link];d.html.openHtmlTree(item,subContainer);} -if(element.nodeName!="HEAD"&&element!=document.documentElement&&(view.visibility=="hidden"||view.display=="none")){container.attribute.addClass("Unvisible");};if(item.childNodes){var childLen=item.childNodes.length;if(childLen==1&&item.childNodes[0].nodeType==3){html.child.add(document.createTextNode(item.childNodes[0].nodeValue.substring(0,50)));html.child.add(document.createTextNode(""));continue;} -else -if(childLen>0){link.attribute.addClass("Parent");}}}};return returnParentVal;}},openProperties:function(){with(firebug){var index=d.html.nIndex;var node=d.html.current[0];d.clean(el.right.html.content);var str="";switch(index){case"computedStyle":var property=["opacity","filter","azimuth","background","backgroundAttachment","backgroundColor","backgroundImage","backgroundPosition","backgroundRepeat","border","borderCollapse","borderColor","borderSpacing","borderStyle","borderTop","borderRight","borderBottom","borderLeft","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderWidth","bottom","captionSide","clear","clip","color","content","counterIncrement","counterReset","cue","cueAfter","cueBefore","cursor","direction","display","elevation","emptyCells","cssFloat","font","fontFamily","fontSize","fontSizeAdjust","fontStretch","fontStyle","fontVariant","fontWeight","height","left","letterSpacing","lineHeight","listStyle","listStyleImage","listStylePosition","listStyleType","margin","marginTop","marginRight","marginBottom","marginLeft","markerOffset","marks","maxHeight","maxWidth","minHeight","minWidth","orphans","outline","outlineColor","outlineStyle","outlineWidth","overflow","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","page","pageBreakAfter","pageBreakBefore","pageBreakInside","pause","pauseAfter","pauseBefore","pitch","pitchRange","playDuring","position","quotes","richness","right","size","speak","speakHeader","speakNumeral","speakPunctuation","speechRate","stress","tableLayout","textAlign","textDecoration","textIndent","textShadow","textTransform","top","unicodeBidi","verticalAlign","visibility","voiceFamily","volume","whiteSpace","widows","width","wordSpacing","zIndex"].sort();var view=document.defaultView?document.defaultView.getComputedStyle(node,null):node.currentStyle;for(var i=0,len=property.length;i
"+item+"
"+d.highlight(view[item])+"
";} -el.right.html.content.update(str);break;case"dom":d.dom.open(node,el.right.html.content,lib.env.ie);break;}}}},inspector:{enabled:false,el:null,inspect:function(_element,_bgInspector){with(firebug){var pos=env.targetWindow.firebug.lib.util.Element.getPosition(_element);env.targetWindow.firebug.el[_bgInspector&&"bgInspector"||"borderInspector"].environment.addStyle({"width":_element.offsetWidth+"px","height":_element.offsetHeight+"px","top":pos.offsetTop-(_bgInspector?0:2)+"px","left":pos.offsetLeft-(_bgInspector?0:2)+"px","display":"block"});9 -if(!_bgInspector){d.inspector.el=_element;}};},toggle:function(_absoluteValue,_event){with(firebug){if(_absoluteValue==d.inspector.enabled) -return;d.inspector.enabled=_absoluteValue!=undefined&&!_absoluteValue.clientX?_absoluteValue:!d.inspector.enabled;el.button.inspect.attribute[(d.inspector.enabled?"add":"remove")+"Class"]("Enabled");if(d.inspector.enabled==false){el.borderInspector.environment.addStyle({"display":"none"});d.inspector.el=null;}else if(lib.env.dIndex!="html"){if(env.popupWin){env.popupWin.firebug.d.navigate("html");}else{d.navigate("html");}}}}},scripts:{index:-1,lineNumbers:false,open:function(_index){with(firebug){d.scripts.index=_index;el.left.scripts.container.update("");var script=document.getElementsByTagName("script")[_index],uri=script.src||document.location.href,source;try{if(uri!=document.location.href){source=env.cache[uri]||lib.xhr.get(uri).responseText;env.cache[uri]=source;}else{source=script.innerHTML;} -source=source.replace(/<|>/g,function(_ch){return({"<":"<",">":">"})[_ch];});if(!d.scripts.lineNumbers) -el.left.scripts.container.child.add(new lib.element("DIV").attribute.addClass("CodeContainer").update(source));else{source=source.split("
");for(var i=0;iAccess to restricted URI denied"));}}},toggleLineNumbers:function(){with(firebug){d.scripts.lineNumbers=!d.scripts.lineNumbers;el.button.scripts.lineNumbers.attribute[(d.scripts.lineNumbers?"add":"remove")+"Class"]("Enabled");d.scripts.open(d.scripts.index);}},refresh:function(){with(firebug){el.button.scripts.selectbox.clean();var collection=env.targetWindow.document.getElementsByTagName("script");for(var i=0,len=collection.length;i"))}}},xhr:{objects:[],addObject:function(){with(firebug){for(var i=0,len=arguments.length;i0&&_object[0]!=undefined&&_object[len-1]!=undefined){return true;}else{for(var key in _object){if(key!="item"&&key!="length"&&key!="setNamedItemNS"&&key!="setNamedItem"&&key!="getNamedItem"&&key!="removeNamedItem"&&key!="getNamedItemNS"&&key!="removeNamedItemNS"&&key!="tags"){return false;}} -return true};},IsHash:function(_object){return _object&&typeof _object=="object"&&(_object==window||_object instanceof Object)&&!_object.nodeName&&!pi.util.IsArray(_object)},Init:[],AddEvent:function(_element,_eventName,_fn,_useCapture){_element[pi.env.ie?"attachEvent":"addEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false);return pi.util.Curry(pi.util.AddEvent,this,_element);},RemoveEvent:function(_element,_eventName,_fn,_useCapture){_element[pi.env.ie?"detachEvent":"removeEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false);return pi.util.Curry(pi.util.RemoveEvent,this,_element);},Element:{addClass:function(_element,_class){if(!pi.util.Element.hasClass(_element,_class)) -pi.util.Element.setClass(_element,pi.util.Element.getClass(_element)+" "+_class);},getClass:function(_element){return _element.getAttribute(pi.env.ie&&!pi.env.ie8?"className":"class")||"";},hasClass:function(_element,_class){return pi.util.Array.indexOf(pi.util.Element.getClass(_element).split(" "),_class)>-1;},removeClass:function(_element,_class){if(pi.util.Element.hasClass(_element,_class)){var names=pi.util.Element.getClass(_element,_class).split(" ");pi.util.Element.setClass(_element,pi.util.Array.remove(names,pi.util.Array.indexOf(names,_class)).join(" "));}},setClass:function(_element,_value){if(pi.env.ie8){_element.setAttribute("className",_value);_element.setAttribute("class",_value);}else{_element.setAttribute(pi.env.ie?"className":"class",_value);}},toggleClass:function(){if(pi.util.Element.hasClass.apply(this,arguments)) -pi.util.Element.removeClass.apply(this,arguments);else -pi.util.Element.addClass.apply(this,arguments);},getOpacity:function(_styleObject){var styleObject=_styleObject;if(!pi.env.ie) -return styleObject["opacity"];var alpha=styleObject["filter"].match(/opacity\=(\d+)/i);return alpha?alpha[1]/100:1;},setOpacity:function(_element,_value){if(!pi.env.ie) -return pi.util.Element.addStyle(_element,{"opacity":_value});_value*=100;pi.util.Element.addStyle(_element,{"filter":"alpha(opacity="+_value+")"});return this._parent_;},getPosition:function(_element){var parent=_element,offsetLeft=document.body.offsetLeft,offsetTop=document.body.offsetTop,view=pi.util.Element.getView(_element);while(parent&&parent!=document.body&&parent!=document.firstChild){offsetLeft+=parseInt(parent.offsetLeft);offsetTop+=parseInt(parent.offsetTop);parent=parent.offsetParent;};return{"bottom":view["bottom"],"clientLeft":_element.clientLeft,"clientTop":_element.clientTop,"left":view["left"],"marginTop":view["marginTop"],"marginLeft":view["marginLeft"],"offsetLeft":offsetLeft,"offsetTop":offsetTop,"position":view["position"],"right":view["right"],"top":view["top"],"zIndex":view["zIndex"]};},getSize:function(_element){var view=pi.util.Element.getView(_element);return{"height":view["height"],"clientHeight":_element.clientHeight,"clientWidth":_element.clientWidth,"offsetHeight":_element.offsetHeight,"offsetWidth":_element.offsetWidth,"width":view["width"]}},addStyle:function(_element,_style){for(var key in _style){key=key=="float"?pi.env.ie?"styleFloat":"cssFloat":key;if(key=="opacity"&&pi.env.ie){pi.util.Element.setOpacity(_element,_style[key]);continue;} -try{_element.style[key]=_style[key];}catch(e){}}},getStyle:function(_element,_property){_property=_property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property;if(_property=="opacity"&&pi.env.ie) -return pi.util.Element.getOpacity(_element.style);return typeof _property=="string"?_element.style[_property]:_element.style;},getValue:function(_element){switch(_element.nodeName.toLowerCase()){case"input":case"textarea":return _element.value;case"select":return _element.options[_element.selectedIndex].value;default:return _element.innerHTML;break;}},getView:function(_element,_property){var view=document.defaultView?document.defaultView.getComputedStyle(_element,null):_element.currentStyle;_property=_property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property;if(_property=="opacity"&&pi.env.ie) -return pi.util.Element.getOpacity(_element,view);return typeof _property=="string"?view[_property]:view;}},Hash:{clone:function(_hash,_undeep){var tmp={};for(var key in _hash){if(!_undeep&&pi.util.IsArray(_hash[key])){tmp[key]=pi.util.Array.clone(_hash[key]);}else if(!_undeep&&pi.util.IsHash(_hash[key])){tmp[key]=pi.util.Hash.clone(_hash[key]);}else{tmp[key]=_hash[key];}} -return tmp;},merge:function(_hash,_source,_undeep){for(var key in _source){var value=_source[key];if(!_undeep&&pi.util.IsArray(_source[key])){if(pi.util.IsArray(_hash[key])){Array.prototype.push.apply(_source[key],_hash[key])} -else -value=pi.util.Array.clone(_source[key]);} -else if(!_undeep&&pi.util.IsHash(_source[key])){if(pi.util.IsHash(_hash[key])){value=pi.util.Hash.merge(_hash[key],_source[key]);}else{value=pi.util.Hash.clone(_source[key]);}}else if(_hash[key]) -value=_hash[key];_hash[key]=value;};return _hash;}},String:{format:function(_str){var values=Array.prototype.slice.call(arguments,1);return _str.replace(/\{(\d)\}/g,function(){return values[arguments[1]];})}},GetViewport:function(){return{height:document.documentElement.clientHeight||document.body.clientHeight,width:document.documentElement.clientWidth||document.body.clientWidth}}};pi.base=function(){this.body={};this.init=null;this.build=function(_skipClonning){var base=this,skipClonning=_skipClonning||false,_private={},fn=function(){var _p=pi.util.Hash.clone(_private);if(!skipClonning){for(var key in this){if(pi.util.IsArray(this[key])){this[key]=pi.util.Array.clone(this[key]);}else -if(pi.util.IsHash(this[key])){this[key]=pi.util.Hash.clone(this[key],function(_key,_object){this[_key]._parent_=this;});}}};base.createAccessors(_p,this);if(base.init) -return base.init.apply(this,arguments);return this;};this.movePrivateMembers(this.body,_private);if(this.init){fn["$Init"]=this.init;};fn.prototype=this.body;return fn;};this.createAccessors=function(_p,_branch){var getter=function(_property){return this[_property];},setter=function(_property,_value){this[_property]=_value;return _branch._parent_||_branch;};for(var name in _p){var isPrivate=name.substring(0,1)=="_",title=name.substring(1,2).toUpperCase()+name.substring(2);if(isPrivate){_branch[(_branch["get"+title]?"_":"")+"get"+title]=pi.util.Curry(getter,_p,name);_branch[(_branch["set"+title]?"_":"")+"set"+title]=pi.util.Curry(setter,_p,name);} -else -if(pi.util.IsHash(_p[name])){_branch[name]._parent_=_branch;if(!_branch[name]) -_branch[name]={};this.createAccessors(_p[name],_branch[name]);}};};this.movePrivateMembers=function(_object,_branch){for(var name in _object){var isPrivate=name.substring(0,1)=="_";if(isPrivate){_branch[name]=_object[name];delete _object[name];} -else -if(pi.util.IsHash(_object[name])){_branch[name]={};this.movePrivateMembers(_object[name],_branch[name]);}};};};pi.element=new pi.base;pi.element.init=function(_val){this.environment.setElement(typeof _val=="string"||!_val?document.createElement(_val||"DIV"):_val);return this;};pi.element.body={"addStyle":function(){return this.environment.addStyle.apply(this.environment,arguments);},"clean":function(){var childs=this.child.get();while(childs.length){childs[0].parentNode.removeChild(childs[0]);}},"clone":function(_deep){return this.environment.getElement().cloneNode(_deep);},"insert":function(_element){_element=_element.environment?_element.environment.getElement():_element;_element.appendChild(this.environment.getElement());return this;},"insertAfter":function(_referenceElement){_referenceElement=_referenceElement.environment?_referenceElement.environment.getElement():_referenceElement;_referenceElement.nextSibling?this.insertBefore(_referenceElement.nextSibling):this.insert(_referenceElement.parentNode);return this;},"insertBefore":function(_referenceElement){_referenceElement=_referenceElement.environment?_referenceElement.environment.getElement():_referenceElement;_referenceElement.parentNode.insertBefore(this.environment.getElement(),_referenceElement);return this;},"query":function(_expression,_resultType,namespaceResolver,_result){return pi.xpath(_expression,_resultType||"ORDERED_NODE_SNAPSHOT_TYPE",this.environment.getElement(),_namespaceResolver,_result);},"remove":function(){if(this.environment.getParent()){this.environment.getParent().removeChild(this.environment.getElement());}},"update":function(_value){this.element[this.element.nodeName.toLowerCase()=="textarea"||this.element.nodeName.toLowerCase()=="input"?"value":"innerHTML"]=_value;return this;},"attribute":{"getAll":function(){return this._parent_.environment.getElement().attributes;},"clear":function(_name){this.set(_name,"");return this._parent_;},"get":function(_name){return this._parent_.environment.getElement().getAttribute(_name);},"has":function(_name){return pi.env.ie?(this.get(_name)!=null):this._parent_.environment.getElement().hasAttribute(_name);},"remove":function(_name){this._parent_.environment.getElement().removeAttribute(_name);return this._parent_;},"set":function(_name,_value){this._parent_.environment.getElement().setAttribute(_name,_value);return this._parent_;},"addClass":function(_classes){for(var i=0,len=arguments.length;i>>"));el.left.console.input=new lib.element("INPUT").attribute.set("type","text").attribute.addClass("Input").event.addListener("keydown",listen.consoleTextbox).insert(new lib.element("DIV").attribute.addClass("InputContainer").insert(el.left.console.container));el.right.console={};el.right.console.container=new lib.element("DIV").attribute.addClass("Console Container").insert(el.right.container);el.right.console.mlButton=new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.console.container);el.right.console.input=new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.console.container);el.right.console.input.event.addListener("keydown",lib.util.Curry(tab,window,el.right.console.input.element));el.right.console.run=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runMultiline).update("Run").insert(el.right.console.container);el.right.console.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.console.input)).update("Clear").insert(el.right.console.container);el.button.console={};el.button.console.container=new lib.element("DIV").attribute.addClass("ButtonSet").insert(el.button.container);el.button.console.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",d.console.clear).update("Clear").insert(el.button.console.container);el.left.html={};el.left.html.container=new lib.element("DIV").attribute.addClass("HTML").insert(el.left.container);el.right.html={};el.right.html.container=new lib.element("DIV").attribute.addClass("HTML Container").insert(el.right.container);el.right.html.nav={};el.right.html.nav.container=new lib.element("DIV").attribute.addClass("Nav").insert(el.right.html.container);el.right.html.nav.computedStyle=new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"computedStyle")).update("Computed Style").insert(el.right.html.nav.container);el.right.html.nav.dom=new lib.element("A").attribute.addClass("Tab").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"dom")).update("DOM").insert(el.right.html.nav.container);el.right.html.content=new lib.element("DIV").attribute.addClass("Content").insert(el.right.html.container);el.button.html={};el.button.html.container=new lib.element("DIV").attribute.addClass("ButtonSet HTML").insert(el.button.container);el.left.css={};el.left.css.container=new lib.element("DIV").attribute.addClass("CSS").insert(el.left.container);el.right.css={};el.right.css.container=new lib.element("DIV").attribute.addClass("CSS Container").insert(el.right.container);el.right.css.nav={};el.right.css.nav.container=new lib.element("DIV").attribute.addClass("Nav").insert(el.right.css.container);el.right.css.nav.runCSS=new lib.element("A").attribute.addClass("Tab Selected").update("Run CSS").insert(el.right.css.nav.container);el.right.css.mlButton=new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.css.container);el.right.css.input=new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.css.container);el.right.css.input.event.addListener("keydown",lib.util.Curry(firebug.tab,window,el.right.css.input.element));el.right.css.run=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runCSS).update("Run").insert(el.right.css.container);el.right.css.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.css.input)).update("Clear").insert(el.right.css.container);el.button.css={};el.button.css.container=new lib.element("DIV").attribute.addClass("ButtonSet CSS").insert(el.button.container);el.button.css.selectbox=new lib.element("SELECT").event.addListener("change",listen.cssSelectbox).insert(el.button.css.container);el.left.scripts={};el.left.scripts.container=new lib.element("DIV").attribute.addClass("Scripts").insert(el.left.container);el.right.scripts={};el.right.scripts.container=new lib.element("DIV").attribute.addClass("Scripts Container").insert(el.right.container);el.button.scripts={};el.button.scripts.container=new lib.element("DIV").attribute.addClass("ButtonSet Scripts").insert(el.button.container);el.button.scripts.selectbox=new lib.element("SELECT").event.addListener("change",listen.scriptsSelectbox).insert(el.button.scripts.container);el.button.scripts.lineNumbers=new lib.element("A").attribute.addClass("Button").event.addListener("click",d.scripts.toggleLineNumbers).update("Show Line Numbers").insert(el.button.scripts.container);el.left.dom={};el.left.dom.container=new lib.element("DIV").attribute.addClass("DOM").insert(el.left.container);el.right.dom={};el.right.dom.container=new lib.element("DIV").attribute.addClass("DOM Container").insert(el.right.container);el.button.dom={};el.button.dom.container=new lib.element("DIV").attribute.addClass("ButtonSet DOM").insert(el.button.container);el.button.dom.label=new lib.element("LABEL").update("Object Path:").insert(el.button.dom.container);el.button.dom.textbox=new lib.element("INPUT").event.addListener("keydown",listen.domTextbox).update(env.isPopup?"window.opener":"window").insert(el.button.dom.container);el.left.str={};el.left.str.container=new lib.element("DIV").attribute.addClass("STR").insert(el.left.container);el.right.str={};el.right.str.container=new lib.element("DIV").attribute.addClass("STR").insert(el.left.container);el.button.str={};el.button.str.container=new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container);el.button.str.watch=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).update("Back").insert(el.button.str.container);el.left.xhr={};el.left.xhr.container=new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container);el.right.xhr={};el.right.xhr.container=new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container);el.button.xhr={};el.button.xhr.container=new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container);el.button.xhr.label=new lib.element("LABEL").update("XHR Path:").insert(el.button.xhr.container);el.button.xhr.textbox=new lib.element("INPUT").event.addListener("keydown",listen.xhrTextbox).insert(el.button.xhr.container);el.button.xhr.watch=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.addXhrObject).update("Watch").insert(el.button.xhr.container);el.settings={};el.settings.container=new lib.element("DIV").child.add(new lib.element("DIV").attribute.addClass("Header").child.add(new lib.element().attribute.addClass("Title").update('Firebug Lite Settings'))).attribute.addClass("SettingsDiv").insert(el.main);el.settings.content=new lib.element("DIV").attribute.addClass("Content").insert(el.settings.container);el.settings.progressDiv=new lib.element("DIV").attribute.addClass("ProgressDiv").insert(el.settings.content);el.settings.progress=new lib.element("DIV").attribute.addClass("Progress").insert(el.settings.progressDiv);el.settings.cbxDebug=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Start visible"));new lib.element("BR").insert(el.settings.content);el.settings.cbxDetectFirebug=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Hide when Firebug active"));new lib.element("BR").insert(el.settings.content);el.settings.cbxHideDOMFunctions=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Hide DOM functions"));new lib.element("BR").insert(el.settings.content);el.settings.cbxOverride=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Override window.console"));new lib.element("BR").insert(el.settings.content);el.settings.cbxShowIcon=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Show icon when hidden"));new lib.element("BR").insert(el.settings.content);el.settings.cbxOpenInPopup=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Open in popup"));el.settings.buttonDiv=new lib.element("DIV").insert(el.settings.content);el.settings.buttonLeftDiv=new lib.element("DIV").attribute.addClass("ButtonsLeft").insert(el.settings.buttonDiv);el.settings.resetButton=new lib.element("INPUT").attribute.set("type","button").update("Reset").event.addListener("click",settings.reset).insert(el.settings.buttonLeftDiv);el.settings.buttonRightDiv=new lib.element("DIV").attribute.addClass("ButtonsRight").insert(el.settings.buttonDiv);el.settings.cancelButton=new lib.element("INPUT").attribute.set("type","button").update("Cancel").event.addListener("click",settings.hide).insert(el.settings.buttonRightDiv);el.settings.buttonRightDiv.child.add(document.createTextNode(" "));el.settings.saveButton=new lib.element("INPUT").attribute.set("type","button").update("Save").event.addListener("click",settings.saveClicked).insert(el.settings.buttonRightDiv);lib.util.AddEvent(document,"mousemove",listen.mouse)("mousemove",win.resizer.resize)("mouseup",win.resizer.stop)("keydown",listen.keyboard);env.init=true;for(var i=0,len=d.console.cache.length;i0){cookieArr=targetWindow.document.cookie.split('; ');for(i=0;i-1){scriptPath=scripts[i].src;break;}} +if(scriptPath){script=fe.popupWin.document.createElement('script'),done=false;script.type='text/javascript';script.src=scriptPath;script[firebug.lib.env.ie?"onreadystatechange":"onload"]=function(){if(!done&&(!firebug.lib.env.ie||this.readyState=="complete"||this.readyState=="loaded")){done=true;if(fe.popupWin.firebug){with(fe.popupWin.firebug){env.isPopup=true;env.css=fe.css;init();el.button.dock.environment.addStyle({"display":"block"});el.button.newWindow.environment.addStyle({"display":"none"});}}}};if(!done&&firebug.lib.env.webkit){fe.popupWin.document.write('');interval=setInterval(function(){if(fe.popupWin.firebug){clearInterval(interval);done=true;with(fe.popupWin.firebug){env.isPopup=true;env.css=fe.css;init();el.button.dock.environment.addStyle({"display":"block"});el.button.newWindow.environment.addStyle({"display":"none"});}}},10);};if(!done){fe.popupWin.document.getElementsByTagName('head')[0].appendChild(script);firebug.el.main.environment.addStyle({"display":"none"});firebug.el.mainiframe.environment.addStyle({"display":"none"});}}else{alert("Unable to detect the following script \""+fe.liteFilename+"\" ... if the script has been renamed then please set the value of firebug.env.liteFilename to reflect this change");fe.popupWin.close();fe.popupWin=null;}}}},dock:function(){with(opener.firebug){env.popupWin=null;el.main.environment.addStyle({"display":"block"});el.mainiframe.environment.addStyle({"display":"block"});settings.readCookie();window.close();};},unload:function(){with(firebug){if(env.isPopup){win.dock();}else if(env.popupWin){env.popupWin.close();}}},fitToPopup:function(){with(firebug){var viewport=lib.util.GetViewport(window);win.setHeight((window.innerHeight||viewport.height)-38);el.main.environment.addStyle({"width":(viewport.width)+"px"});el.mainiframe.environment.addStyle({"width":(viewport.width)+"px"});}},resizer:{y:[],enabled:false,start:function(_event){with(firebug){if(env.minimized)return;win.resizer.y=[el.main.element.offsetHeight,_event.clientY];if(lib.env.ie6){win.resizer.y[3]=parseInt(el.main.environment.getPosition().top);} +win.resizer.enabled=true;}},resize:function(_event){with(firebug){if(!win.resizer.enabled)return;win.resizer.y[2]=(win.resizer.y[0]+(win.resizer.y[1]-_event.clientY));el.main.environment.addStyle({"height":win.resizer.y[2]+"px"});el.mainiframe.environment.addStyle({"height":win.resizer.y[2]+"px"});if(lib.env.ie6){el.main.environment.addStyle({"top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px"});el.mainiframe.environment.addStyle({"top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px"});}}},stop:function(_event){with(firebug){if(win.resizer.enabled){win.resizer.enabled=false;win.setHeight(win.resizer.y[2]-35);}}}},setHeight:function(_height){with(firebug){env.height=_height;el.left.container.environment.addStyle({"height":_height+"px"});el.right.container.environment.addStyle({"height":_height+"px"});el.main.environment.addStyle({"height":_height+38+"px"});el.mainiframe.environment.addStyle({"height":_height+38+"px"});win.refreshSize();el.left.console.monitor.element.parentNode.style.height=_height-47+"px";el.left.console.mlButton.environment.addStyle({"top":_height+19+"px"});el.right.console.mlButton.environment.addStyle({"top":_height+19+"px"});el.right.console.input.environment.addStyle({"height":_height-29+"px"});el.left.html.container.environment.addStyle({"height":_height-23+"px"});el.right.html.content.environment.addStyle({"height":_height-23+"px"});el.left.css.container.environment.addStyle({"height":_height-33+"px"});el.right.css.input.environment.addStyle({"height":_height-55+"px"});el.left.scripts.container.environment.addStyle({"height":_height-23+"px"});el.left.dom.container.environment.addStyle({"height":_height-31+"px"});el.left.xhr.container.environment.addStyle({"height":_height-32+"px"});el.left.str.container.environment.addStyle({"height":_height-32+"px"});}},refreshDOM:function(){with(firebug){d.dom.open(eval(el.button.dom.textbox.environment.getElement().value),el.left.dom.container);if(d.html.nIndex=="dom"){firebug.d.html.navigate("dom")}}},refreshSize:function(){with(firebug){if(!env.init) +return;var dim=lib.util.GetViewport();el.main.environment.addStyle({"width":dim.width+"px"});el.mainiframe.environment.addStyle({"width":dim.width+"px"});if(lib.env.ie6) +win.setVerticalPosition(dim);}},setVerticalPosition:function(_dim,_event){with(firebug){var dim=_dim||lib.util.GetViewport();el.main.environment.addStyle({"top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px"});el.mainiframe.environment.addStyle({"top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px"});}}},d:{clean:function(_element){with(firebug){_element.update("");}},console:{addLine:function(){with(firebug){return new lib.element("DIV").attribute.addClass("Row").insert(el.left.console.monitor);}},cache:[],clear:function(){with(firebug){d.clean(el.left.console.monitor);d.console.cache=[];}},formatArgs:function(){with(firebug){var content=[];for(var i=0,len=arguments.length;i>> "+_cmd);d.console.addLine().update(d.highlight(_text,false,false,true));d.console.scroll();}},printException:function(_exception){with(firebug){var message=_exception.description||_exception.message||_exception;if(_exception.fileName){message+=' ('+(_exception.name&&(_exception.name+', ')||'')+getFileName(_exception.fileName)+', '+_exception.lineNumber+')';} +d.console.addLine().attribute.addClass("Error").update("Error: "+message,true);}},eval:function(_cmd){var result;with(firebug){if(_cmd.length==0) +return;el.left.console.input.environment.getElement().value="";d.console.historyIndex=d.console.history.push(_cmd);try{if(_cmd==='console.firebug'){d.console.addLine().attribute.addClass("Arrow").update(firebug.version);}else{result=eval.call(window,_cmd);d.console.print(_cmd,result);}}catch(e){d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd);d.console.printException(e);} +d.console.scroll();}},scroll:function(){with(firebug){el.left.console.monitor.environment.getElement().parentNode.scrollTop=Math.abs(el.left.console.monitor.environment.getSize().offsetHeight-(el.left.console.monitor.element.parentNode.offsetHeight-11));}},run:function(_command){with(firebug){if(!env.init){d.console.cache.push({"command":_command,"arg":Array.prototype.slice.call(arguments,1)});}else{d.console.cmd[_command].apply(window,Array.prototype.slice.call(arguments,1));}}},toggleML:function(){with(firebug){var open=!env.ml;env.ml=!env.ml;d.navigateRightColumn("console",open);el[open?"left":"right"].console.mlButton.environment.addStyle({display:"none"});el[!open?"left":"right"].console.mlButton.environment.addStyle({display:"block"});el.left.console.mlButton.attribute[(open?"add":"remove")+"Class"]("CloseML");}},countMap:{},timeMap:{},cmd:{log:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Log").update(args);d.console.scroll();}},warn:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Warn").update(args);d.console.scroll();}},info:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Info").update(args);d.console.scroll();}},debug:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Debug").update(args);d.console.scroll();}},error:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Error").update(args);d.console.scroll();}},trace:function(_value){with(firebug){var stackAmt=3,f=arguments.caller,isArray=lib.util.IsArray(f);if((!isArray&&f)||(isArray&&f.length>0)){d.console.addLine().attribute.addClass("Arrow").update(">>> console.trace(stack)");for(var i=0;i>> console.dir("+_value+")");d.dom.open(_value,d.console.addLine());}},dirxml:function(){with(firebug){d.console.cmd.log.apply(this,arguments);}},time:function(_name){with(firebug){d.console.timeMap[_name]=new Date().getTime();}},timeEnd:function(_name){with(firebug){if(_name in d.console.timeMap){var delta=new Date().getTime()-d.console.timeMap[_name],args=d.console.formatArgs.apply(window,[_name+":",delta+"ms"]);d.console.addLine().attribute.addClass("log").update(args);delete d.console.timeMap[_name];}}},count:function(_name){with(firebug){if(!d.console.countMap[_name]) +d.console.countMap[_name]=0;d.console.countMap[_name]++;d.console.cmd.log.apply(window,[_name,d.console.countMap[_name]]);}},group:function(){with(firebug){d.console.cmd.log.apply(this,["console.group is not supported"]);}},groupEnd:function(){with(firebug){d.console.cmd.log.apply(this,["console.groupEnd is not supported"]);}},profile:function(){with(firebug){d.console.cmd.log.apply(this,["console.profile is not supported"]);}},profileEnd:function(){with(firebug){d.console.cmd.log.apply(this,["console.profileEnd is not supported"]);}}}},css:{index:-1,open:function(_index){with(firebug){var item=env.targetWindow.document.styleSheets[_index],uri=item.href;try{var rules=item[lib.env.ie?"rules":"cssRules"],str="";for(var i=0;iAccess to restricted URI denied";} +el.left.css.container.update(str);}},printRule:function(_selector,_css,_layer){with(firebug){var str="
"+_selector+" {
";for(var i=0,len=_css.length;i"+item.replace(/(.+\:)(.+)/,"$1$2;")+"";} +str+="
}
";return str;}},refresh:function(){with(firebug){el.button.css.selectbox.update("");var collection=env.targetWindow.document.styleSheets;for(var i=0,len=collection.length;inull
");}else if(vtype=="regexp"){result.push(""+_value+"");}else if(vtype=="date"){result.push("'"+_value+"'");}else if(vtype=="boolean"||vtype=="number"){result.push(""+_value+"");}else if(vtype=="function"){result.push("function()");}else{result.push("\""+(!_inObject&&!_inArray?_value:_value.substring(0,35)+(_value.length>35?" ...":"")).replace(/\n/g,"\\n").replace(/\s/g," ").replace(/>/g,">").replace(/");}} +else if(isElement){if(_value.nodeType==3) +result.push(d.highlight(_value.nodeValue));else if(_inObject){result.push(""+_value.nodeName.toLowerCase()+"");}else{result.push("");if(_inArray){result.push(_value.nodeName.toLowerCase());if(_value.getAttribute){if(_value.getAttribute&&_value.getAttribute("id")) +result.push("#"+_value.getAttribute("id")+"");var elClass=_value.getAttribute(lib.env.ie&&!lib.env.ie8?"className":"class")||"";result.push(!elClass?"":"."+elClass.split(" ")[0]+"");} +result.push("");}else{result.push("<"+_value.nodeName.toLowerCase());if(_value.attributes){for(var i=0,len=_value.attributes.length;i"+item.nodeName+"=\""+item.nodeValue+"\"");}} +result.push(">");}}} +else if(isArray||isHash){if(isArray){if(_inObject){result.push("["+_value.length+"]");}else{result.push("[ ");for(var i=0,len=_value.length;i3){result.push(", "+(len-4)+" More...");break;} +result.push((i>0?", ":"")+d.highlight(_value[i],false,true,true));} +result.push(" ]");}}else if(_inObject){result.push("Object");}else{result.push("Object");var i=0;for(var key in _value){var value=_value[key];if((_inObject||_inArray)&&i>3){result.push(" More...");break;} +result.push(" "+key+"="+d.highlight(value,true));i++;} +result.push("");}}else{result.push([""+_value+""]);}}catch(e){result.push("..");} +return result.join("");}},html:{nIndex:"computedStyle",current:null,highlight:function(_element,_clear,_event){with(firebug){if(_element.firebugElement){return;} +if(_clear){env.targetWindow.firebug.el.bgInspector.environment.addStyle({"display":"none"});return;} +d.inspector.inspect(_element,true);}},inspect:function(_element){var map=[],parentLayer,t,tagName,parent=_element;while(parent){map.push(parent);if(parent==firebug.env.targetWindow.document.body)break;parent=parent.parentNode;} +map=map.reverse();with(firebug){if(env.dIndex!="html"){env.targetWindow.firebug.d.navigate("html");} +env.targetWindow.firebug.d.inspector.toggle(false);for(t=0;t<html>").insert(parent);};for(var i=0;i<=len;i++){if(i==len){new lib.element("A").attribute.addClass("Block").update("</"+element.nodeName.toLowerCase()+">").insert(container);break;} +var item=element.childNodes[i];if(item.nodeType!=3){var container=new lib.element().attribute.addClass("Block").insert(parent),link=new lib.element("A").attribute.addClass("Link").insert(container),spacer=new lib.element("SPAN").attribute.addClass("Spacer").update(" ").insert(link),html=new lib.element("SPAN").attribute.addClass("Content").update(d.highlight(item)).insert(link),subContainer=new lib.element("DIV").attribute.addClass("SubContainer").insert(container),view=lib.util.Element.getView(item);link.event.addListener("click",lib.util.Curry(d.html.openHtmlTree,window,item,subContainer,false));link.event.addListener("mouseover",lib.util.Curry(d.html.highlight,window,item,false));link.event.addListener("mouseout",lib.util.Curry(d.html.highlight,window,item,true));returnParentVal=returnParentEl==item?subContainer:returnParentVal;if(d.html.current==null&&item==document.body){link.attribute.addClass("Selected");d.html.current=[item,link];d.html.openHtmlTree(item,subContainer);} +if(element.nodeName!="HEAD"&&element!=document.documentElement&&(view.visibility=="hidden"||view.display=="none")){container.attribute.addClass("Unvisible");};if(item.childNodes){var childLen=item.childNodes.length;if(childLen==1&&item.childNodes[0].nodeType==3){html.child.add(document.createTextNode(item.childNodes[0].nodeValue.substring(0,50)));html.child.add(document.createTextNode(""));continue;} +else +if(childLen>0){link.attribute.addClass("Parent");}}}};return returnParentVal;}},openProperties:function(){with(firebug){var index=d.html.nIndex;var node=d.html.current[0];d.clean(el.right.html.content);var str="";switch(index){case"computedStyle":var property=["opacity","filter","azimuth","background","backgroundAttachment","backgroundColor","backgroundImage","backgroundPosition","backgroundRepeat","border","borderCollapse","borderColor","borderSpacing","borderStyle","borderTop","borderRight","borderBottom","borderLeft","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderWidth","bottom","captionSide","clear","clip","color","content","counterIncrement","counterReset","cue","cueAfter","cueBefore","cursor","direction","display","elevation","emptyCells","cssFloat","font","fontFamily","fontSize","fontSizeAdjust","fontStretch","fontStyle","fontVariant","fontWeight","height","left","letterSpacing","lineHeight","listStyle","listStyleImage","listStylePosition","listStyleType","margin","marginTop","marginRight","marginBottom","marginLeft","markerOffset","marks","maxHeight","maxWidth","minHeight","minWidth","orphans","outline","outlineColor","outlineStyle","outlineWidth","overflow","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","page","pageBreakAfter","pageBreakBefore","pageBreakInside","pause","pauseAfter","pauseBefore","pitch","pitchRange","playDuring","position","quotes","richness","right","size","speak","speakHeader","speakNumeral","speakPunctuation","speechRate","stress","tableLayout","textAlign","textDecoration","textIndent","textShadow","textTransform","top","unicodeBidi","verticalAlign","visibility","voiceFamily","volume","whiteSpace","widows","width","wordSpacing","zIndex"].sort();var view=document.defaultView?document.defaultView.getComputedStyle(node,null):node.currentStyle;for(var i=0,len=property.length;i
"+item+"
"+d.highlight(view[item])+"
";} +el.right.html.content.update(str);break;case"dom":d.dom.open(node,el.right.html.content,lib.env.ie);break;}}}},inspector:{enabled:false,el:null,inspect:function(_element,_bgInspector){with(firebug){var pos=env.targetWindow.firebug.lib.util.Element.getPosition(_element);env.targetWindow.firebug.el[_bgInspector&&"bgInspector"||"borderInspector"].environment.addStyle({"width":_element.offsetWidth+"px","height":_element.offsetHeight+"px","top":pos.offsetTop-(_bgInspector?0:2)+"px","left":pos.offsetLeft-(_bgInspector?0:2)+"px","display":"block"});9 +if(!_bgInspector){d.inspector.el=_element;}};},toggle:function(_absoluteValue,_event){with(firebug){if(_absoluteValue==d.inspector.enabled) +return;d.inspector.enabled=_absoluteValue!=undefined&&!_absoluteValue.clientX?_absoluteValue:!d.inspector.enabled;el.button.inspect.attribute[(d.inspector.enabled?"add":"remove")+"Class"]("Enabled");if(d.inspector.enabled==false){el.borderInspector.environment.addStyle({"display":"none"});d.inspector.el=null;}else if(lib.env.dIndex!="html"){if(env.popupWin){env.popupWin.firebug.d.navigate("html");}else{d.navigate("html");}}}}},scripts:{index:-1,lineNumbers:false,open:function(_index){with(firebug){d.scripts.index=_index;el.left.scripts.container.update("");var script=document.getElementsByTagName("script")[_index],uri=script.src||document.location.href,source;try{if(uri!=document.location.href){source=env.cache[uri]||lib.xhr.get(uri).responseText;env.cache[uri]=source;}else{source=script.innerHTML;} +source=source.replace(/<|>/g,function(_ch){return({"<":"<",">":">"})[_ch];});if(!d.scripts.lineNumbers) +el.left.scripts.container.child.add(new lib.element("DIV").attribute.addClass("CodeContainer").update(source));else{source=source.split("
");for(var i=0;iAccess to restricted URI denied"));}}},toggleLineNumbers:function(){with(firebug){d.scripts.lineNumbers=!d.scripts.lineNumbers;el.button.scripts.lineNumbers.attribute[(d.scripts.lineNumbers?"add":"remove")+"Class"]("Enabled");d.scripts.open(d.scripts.index);}},refresh:function(){with(firebug){el.button.scripts.selectbox.clean();var collection=env.targetWindow.document.getElementsByTagName("script");for(var i=0,len=collection.length;i"))}}},xhr:{objects:[],addObject:function(){with(firebug){for(var i=0,len=arguments.length;i0&&_object[0]!=undefined&&_object[len-1]!=undefined){return true;}else{for(var key in _object){if(key!="item"&&key!="length"&&key!="setNamedItemNS"&&key!="setNamedItem"&&key!="getNamedItem"&&key!="removeNamedItem"&&key!="getNamedItemNS"&&key!="removeNamedItemNS"&&key!="tags"){return false;}} +return true};},IsHash:function(_object){return _object&&typeof _object=="object"&&(_object==window||_object instanceof Object)&&!_object.nodeName&&!pi.util.IsArray(_object)},Init:[],AddEvent:function(_element,_eventName,_fn,_useCapture){_element[pi.env.ie?"attachEvent":"addEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false);return pi.util.Curry(pi.util.AddEvent,this,_element);},RemoveEvent:function(_element,_eventName,_fn,_useCapture){_element[pi.env.ie?"detachEvent":"removeEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false);return pi.util.Curry(pi.util.RemoveEvent,this,_element);},Element:{addClass:function(_element,_class){if(!pi.util.Element.hasClass(_element,_class)) +pi.util.Element.setClass(_element,pi.util.Element.getClass(_element)+" "+_class);},getClass:function(_element){return _element.getAttribute(pi.env.ie&&!pi.env.ie8?"className":"class")||"";},hasClass:function(_element,_class){return pi.util.Array.indexOf(pi.util.Element.getClass(_element).split(" "),_class)>-1;},removeClass:function(_element,_class){if(pi.util.Element.hasClass(_element,_class)){var names=pi.util.Element.getClass(_element,_class).split(" ");pi.util.Element.setClass(_element,pi.util.Array.remove(names,pi.util.Array.indexOf(names,_class)).join(" "));}},setClass:function(_element,_value){if(pi.env.ie8){_element.setAttribute("className",_value);_element.setAttribute("class",_value);}else{_element.setAttribute(pi.env.ie?"className":"class",_value);}},toggleClass:function(){if(pi.util.Element.hasClass.apply(this,arguments)) +pi.util.Element.removeClass.apply(this,arguments);else +pi.util.Element.addClass.apply(this,arguments);},getOpacity:function(_styleObject){var styleObject=_styleObject;if(!pi.env.ie) +return styleObject["opacity"];var alpha=styleObject["filter"].match(/opacity\=(\d+)/i);return alpha?alpha[1]/100:1;},setOpacity:function(_element,_value){if(!pi.env.ie) +return pi.util.Element.addStyle(_element,{"opacity":_value});_value*=100;pi.util.Element.addStyle(_element,{"filter":"alpha(opacity="+_value+")"});return this._parent_;},getPosition:function(_element){var parent=_element,offsetLeft=document.body.offsetLeft,offsetTop=document.body.offsetTop,view=pi.util.Element.getView(_element);while(parent&&parent!=document.body&&parent!=document.firstChild){offsetLeft+=parseInt(parent.offsetLeft);offsetTop+=parseInt(parent.offsetTop);parent=parent.offsetParent;};return{"bottom":view["bottom"],"clientLeft":_element.clientLeft,"clientTop":_element.clientTop,"left":view["left"],"marginTop":view["marginTop"],"marginLeft":view["marginLeft"],"offsetLeft":offsetLeft,"offsetTop":offsetTop,"position":view["position"],"right":view["right"],"top":view["top"],"zIndex":view["zIndex"]};},getSize:function(_element){var view=pi.util.Element.getView(_element);return{"height":view["height"],"clientHeight":_element.clientHeight,"clientWidth":_element.clientWidth,"offsetHeight":_element.offsetHeight,"offsetWidth":_element.offsetWidth,"width":view["width"]}},addStyle:function(_element,_style){for(var key in _style){key=key=="float"?pi.env.ie?"styleFloat":"cssFloat":key;if(key=="opacity"&&pi.env.ie){pi.util.Element.setOpacity(_element,_style[key]);continue;} +try{_element.style[key]=_style[key];}catch(e){}}},getStyle:function(_element,_property){_property=_property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property;if(_property=="opacity"&&pi.env.ie) +return pi.util.Element.getOpacity(_element.style);return typeof _property=="string"?_element.style[_property]:_element.style;},getValue:function(_element){switch(_element.nodeName.toLowerCase()){case"input":case"textarea":return _element.value;case"select":return _element.options[_element.selectedIndex].value;default:return _element.innerHTML;break;}},getView:function(_element,_property){var view=document.defaultView?document.defaultView.getComputedStyle(_element,null):_element.currentStyle;_property=_property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property;if(_property=="opacity"&&pi.env.ie) +return pi.util.Element.getOpacity(_element,view);return typeof _property=="string"?view[_property]:view;}},Hash:{clone:function(_hash,_undeep){var tmp={};for(var key in _hash){if(!_undeep&&pi.util.IsArray(_hash[key])){tmp[key]=pi.util.Array.clone(_hash[key]);}else if(!_undeep&&pi.util.IsHash(_hash[key])){tmp[key]=pi.util.Hash.clone(_hash[key]);}else{tmp[key]=_hash[key];}} +return tmp;},merge:function(_hash,_source,_undeep){for(var key in _source){var value=_source[key];if(!_undeep&&pi.util.IsArray(_source[key])){if(pi.util.IsArray(_hash[key])){Array.prototype.push.apply(_source[key],_hash[key])} +else +value=pi.util.Array.clone(_source[key]);} +else if(!_undeep&&pi.util.IsHash(_source[key])){if(pi.util.IsHash(_hash[key])){value=pi.util.Hash.merge(_hash[key],_source[key]);}else{value=pi.util.Hash.clone(_source[key]);}}else if(_hash[key]) +value=_hash[key];_hash[key]=value;};return _hash;}},String:{format:function(_str){var values=Array.prototype.slice.call(arguments,1);return _str.replace(/\{(\d)\}/g,function(){return values[arguments[1]];})}},GetViewport:function(){return{height:document.documentElement.clientHeight||document.body.clientHeight,width:document.documentElement.clientWidth||document.body.clientWidth}}};pi.base=function(){this.body={};this.init=null;this.build=function(_skipClonning){var base=this,skipClonning=_skipClonning||false,_private={},fn=function(){var _p=pi.util.Hash.clone(_private);if(!skipClonning){for(var key in this){if(pi.util.IsArray(this[key])){this[key]=pi.util.Array.clone(this[key]);}else +if(pi.util.IsHash(this[key])){this[key]=pi.util.Hash.clone(this[key],function(_key,_object){this[_key]._parent_=this;});}}};base.createAccessors(_p,this);if(base.init) +return base.init.apply(this,arguments);return this;};this.movePrivateMembers(this.body,_private);if(this.init){fn["$Init"]=this.init;};fn.prototype=this.body;return fn;};this.createAccessors=function(_p,_branch){var getter=function(_property){return this[_property];},setter=function(_property,_value){this[_property]=_value;return _branch._parent_||_branch;};for(var name in _p){var isPrivate=name.substring(0,1)=="_",title=name.substring(1,2).toUpperCase()+name.substring(2);if(isPrivate){_branch[(_branch["get"+title]?"_":"")+"get"+title]=pi.util.Curry(getter,_p,name);_branch[(_branch["set"+title]?"_":"")+"set"+title]=pi.util.Curry(setter,_p,name);} +else +if(pi.util.IsHash(_p[name])){_branch[name]._parent_=_branch;if(!_branch[name]) +_branch[name]={};this.createAccessors(_p[name],_branch[name]);}};};this.movePrivateMembers=function(_object,_branch){for(var name in _object){var isPrivate=name.substring(0,1)=="_";if(isPrivate){_branch[name]=_object[name];delete _object[name];} +else +if(pi.util.IsHash(_object[name])){_branch[name]={};this.movePrivateMembers(_object[name],_branch[name]);}};};};pi.element=new pi.base;pi.element.init=function(_val){this.environment.setElement(typeof _val=="string"||!_val?document.createElement(_val||"DIV"):_val);return this;};pi.element.body={"addStyle":function(){return this.environment.addStyle.apply(this.environment,arguments);},"clean":function(){var childs=this.child.get();while(childs.length){childs[0].parentNode.removeChild(childs[0]);}},"clone":function(_deep){return this.environment.getElement().cloneNode(_deep);},"insert":function(_element){_element=_element.environment?_element.environment.getElement():_element;_element.appendChild(this.environment.getElement());return this;},"insertAfter":function(_referenceElement){_referenceElement=_referenceElement.environment?_referenceElement.environment.getElement():_referenceElement;_referenceElement.nextSibling?this.insertBefore(_referenceElement.nextSibling):this.insert(_referenceElement.parentNode);return this;},"insertBefore":function(_referenceElement){_referenceElement=_referenceElement.environment?_referenceElement.environment.getElement():_referenceElement;_referenceElement.parentNode.insertBefore(this.environment.getElement(),_referenceElement);return this;},"query":function(_expression,_resultType,namespaceResolver,_result){return pi.xpath(_expression,_resultType||"ORDERED_NODE_SNAPSHOT_TYPE",this.environment.getElement(),_namespaceResolver,_result);},"remove":function(){if(this.environment.getParent()){this.environment.getParent().removeChild(this.environment.getElement());}},"update":function(_value){this.element[this.element.nodeName.toLowerCase()=="textarea"||this.element.nodeName.toLowerCase()=="input"?"value":"innerHTML"]=_value;return this;},"attribute":{"getAll":function(){return this._parent_.environment.getElement().attributes;},"clear":function(_name){this.set(_name,"");return this._parent_;},"get":function(_name){return this._parent_.environment.getElement().getAttribute(_name);},"has":function(_name){return pi.env.ie?(this.get(_name)!=null):this._parent_.environment.getElement().hasAttribute(_name);},"remove":function(_name){this._parent_.environment.getElement().removeAttribute(_name);return this._parent_;},"set":function(_name,_value){this._parent_.environment.getElement().setAttribute(_name,_value);return this._parent_;},"addClass":function(_classes){for(var i=0,len=arguments.length;i-1){callback[i].fn.apply(this);}}}};pi.xhr=pi.xhr.build();pi.xhr.get=function(_url,_returnPiObject){var request=new pi.xhr();request.environment.setAsync(false);request.environment.setUrl(_url);request.send();return _returnPiObject?request:request.environment.getApi();};pi.util.AddEvent(pi.env.ie?window:document,pi.env.ie?"load":"DOMContentLoaded",function(){for(var i=0,len=pi.util.Init.length;i .Right { background:#fff; height:257px;} -#Firebug .Left { float:left; width:100%; } -#Firebug .Right { float:left; display:none; width:30%; overflow:hidden; } -#Firebug .Right .Container { height:100%; border-left:1px solid #ccc; } - -/* - * buttonset - */ - -#Firebug .ButtonContainer { padding:8px 0 5px 10px; *margin-top:-3px; _margin-top:0; } -#Firebug .ButtonContainer .Button { cursor:pointer; font:12px "MS Sans Serif", Geneva, sans-serif; color:#000; margin-right:5px; padding:4px 4px 4px 4px; border:1px solid transparent !important; border-color:#ccc; text-decoration:none; } -#Firebug .ButtonContainer .Button:hover { border:1px outset #aaa !important; } -#Firebug .ButtonContainer .Button:active { border-style:inset !important; background-color:#ccc; } -#Firebug .ButtonContainer .Enabled { border:1px outset #aaa !important; } -#Firebug .ButtonContainer .Logo { text-decoration:none; padding-left:24px; background:url(firebug.gif) no-repeat 5px 3px; border:0 !important; opacity:0.7; filter:Alpha(Opacity=70); } -#Firebug .ButtonContainer .Logo:hover, #Firebug .ButtonContainer .Logo:active { border:0 !important; background-color:transparent; opacity:1; filter:Alpha(Opacity=100); } -#Firebug .ButtonContainer .Maximize, #Firebug .ButtonContainer .Minimize, #Firebug .ButtonContainer .NewWindow, #Firebug .ButtonContainer .Dock, #Firebug .ButtonContainer .Close { position:absolute; right:0; top:12px; padding:6px 8px 8px 8px; background:url(firebug.gif) no-repeat -3px -48px; border:0 !important; opacity:0.7; filter:Alpha(Opacity:80); *padding:0px 7px 1px 7px; } -#Firebug .ButtonContainer .Maximize:hover, #Firebug .ButtonContainer .Maximize:active, #Firebug .ButtonContainer .NewWindow:hover, #Firebug .ButtonContainer .NewWindow:active, #Firebug .ButtonContainer .Dock:hover, #Firebug .ButtonContainer .Dock:active, #Firebug .ButtonContainer .Minimize:hover, #Firebug .ButtonContainer .Minimize:active, #Firebug .ButtonContainer .Close:hover, #Firebug .ButtonContainer .Close:active { border:0 !important; background-color:transparent; opacity:1; filter:Alpha(Opacity:100); } -#Firebug .ButtonContainer .Minimize { background-position:-3px -20px; right:40px; } -#Firebug .ButtonContainer .Maximize { display:none; background-position:-3px -34px; right:40px; } -#Firebug .ButtonContainer .NewWindow { background-position:-3px -123px; right:20px; } -#Firebug .ButtonContainer .Dock { background-position:-3px -137px; } -#Firebug .ButtonContainer .ButtonSet { border-left:1px solid #ccc; padding:0 0 0 3px; display:inline; } - -/* - * navigation - */ - -#Firebug .Nav { height:23px; background:url(firebug.gif) repeat-x 0 -62px; padding-left:10px; } -#Firebug .Nav .Tab { display:block; width:auto; float:left; padding:3px 6px 2px 6px; cursor:pointer; border:1px outset transparent !important; border:0; font:bold 11px Arial, Helvetica, sans-serif; color:#666; } -#Firebug .Nav .Tab:hover, #Firebug .Nav .Selected { border:1px outset #ccc !important; border-top-color:transparent !important; } -#Firebug .Nav .Selected { color:#111; cursor:default; background-color:#f2f2f2; } -#Firebug .Nav .Settings { float:right; } - -/* - * inspector - */ - -#FirebugBorderInspector { display:none; z-index:99999998; position:absolute; top:0; left:0; border:2px solid #0000ff; background:transparent; *background:url(spacer.gif); opacity:0.5; filter:Alpha(Opacity=50); padding:0; margin:0; } -#FirebugBGInspector { display:none; z-index:99999998; position:absolute; top:0; left:0; background:rgb(0,150,255); opacity:0.5; filter:Alpha(Opacity=50); padding:0; margin:0; } - -/* - * dom - */ - -#Firebug .DOMRow { width:100% !important; width:90%; } -#Firebug .DOMRow .DOMRowLeft { float:left; width:30%; overflow:hidden; } -#Firebug .DOMRow .DOMRowLeft a { padding-left:15px; } -#Firebug .DOMRow .DOMRowRight { float:left; width:60%; *width:60%; _overflow:hidden; white-space:nowrap; } -#Firebug .DOMRow .DOMRowLeft .Object { background:url(tree_open.gif) no-repeat left center; cursor:pointer; } -#Firebug .DOMRow .DOMRowLeft .Object:hover { text-decoration:underline; color:#0000ff; } -#Firebug .DOMRow .DOMRowLeft .Opened { background-image:url(tree_close.gif) } -#Firebug .DOMRow .DOMRowSubContainer { display:none; padding-left:25px; } - -/* - * console - */ -#Firebug .Left .Console { overflow:hidden; } -#Firebug .Left .Console .Monitor { height:210px; border-bottom:1px solid #ccc; overflow:scroll; overflow-x:hidden; } -#Firebug .Left .Console .Monitor .Error { background:#ffeff1; color:#ff0000; } -#Firebug .Left .Console .Monitor .Error strong { color:#ff0000; } -#Firebug .Left .Console .Monitor .Row { padding:2px 5px 2px 5px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; overflow:hidden; border-bottom:1px solid #e5e5e5; } -#Firebug .Left .Console .Monitor .Arrow { color:rgb(0,0,255); white-space:nowrap; } - -#Firebug .Left .Console .InputArrow { position:absolute; left:0px; width:20px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; color:#0000ff; padding:2px 4px 0 4px; } -#Firebug .Left .Console .InputContainer { margin-left:35px; margin-right:5px; } -#Firebug .Left .Console .Input { width:100% !important; margin-top:2px; width:98%; overflow:hidden; border:0; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; } -#Firebug .Console .MLButton { cursor:pointer; position:absolute; top:276px; right:-22px; width:20px; padding:4px 10px 10px 10px; font-size:1px; *padding:2px 10px 10px 10px; background:url(firebug.gif) no-repeat -3px -34px; opacity:0.8; filter:Alpha(Opacity:80); } -#Firebug .Console .MLButton:hover { opacity:1; filter:Alpha(Opacity:100); } -#Firebug .Console .CloseML { background-position:-3px -20px; } - -#Firebug .Right .Console { background:#eee; } -#Firebug .Right .Console .Input { width:100%; _width:98%; height:228px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; background:#fff; border:0; border-bottom:1px solid #ccc; margin-bottom:2px; *overflow:scroll; } -#Firebug .Right .Console .Button { cursor:pointer; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:1px 4px 1px 4px; margin:0 4px 0 4px; background:#eee; border:1px solid #eee; text-decoration:none; *display:block; *width:auto; *float:left; *margin-top:-1px; } -#Firebug .Right .Console .Button:hover { border:1px outset #ccc; background:#fff; } -#Firebug .Right .Console .Button:active { border:1px inset #ccc; background:#ccc; } - -#Firebug .Left .Console .Monitor .Warn { background:url(warningIcon.png) #00FFFF no-repeat 2px center; padding-left:20px; } -#Firebug .Left .Console .Monitor .Info { background:url(infoIcon.png) #fff no-repeat 2px center; padding-left:20px; } -#Firebug .Left .Console .Monitor .Error { background:url(errorIcon.png) #FFFFE0 no-repeat 2px center; padding-left:20px; } - - -/* - * html - */ - -#Firebug .Left .HTML { display:none; height:250px; overflow:scroll; padding:0 10px 2px 10px; } -#Firebug .Left .HTML .Block { padding:0 0 0 0px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } -#Firebug .Left .HTML .Block .Spacer { cursor:default; padding:2px 2px 2px 15px; } -#Firebug .Left .HTML .Block .Link { display:block; color:#333; padding:2px 2px 2px 0; } -#Firebug .Left .HTML .Block .Link .Content { padding:2px 2px 2px 2px; } -#Firebug .Left .HTML .Block .Link .TagName { cursor:pointer; } -#Firebug .Left .HTML .Block .Parent { font-weight:bold; color:#111; text-decoration:none; } -#Firebug .Left .HTML .Block .Parent .Spacer { background:#fff center no-repeat; } -#Firebug .Left .HTML .Block .Parent .Spacer { background-image:url(tree_open.gif); } -#Firebug .Left .HTML .Block .Open .Spacer { background-image:url(tree_close.gif) } -#Firebug .Left .HTML .Block .Selected { background-color:#4473c4; } -#Firebug .Left .HTML .Block .Selected * { color:#fff; } -#Firebug .Left .HTML .Block .SubContainer { padding-left:20px; height:0; font-size:0px; } -#Firebug .Left .HTML .Block .OpenSubContainer { height:auto; } -#Firebug .Left .HTML .Unvisible { opacity:0.5; filter:Alpha(Opacity=50); } - -#Firebug .Right .HTML { display:none; } -#Firebug .Right .HTML .Content { overflow:scroll; height:235px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } -#Firebug .Right .HTML .Content .CSSItem { padding:5px; color:#333; height:6px } -#Firebug .Right .HTML .Content .CSSProperty { width:45%; float:left; overflow:hidden; } -#Firebug .Right .HTML .Content .CSSValue { width:55%; float:left; white-space:nowrap; overflow:visible !important; overflow:hidden; } -#Firebug .Right .HTML .Content .CSSValue input { font:11px ArArial, Helvetica, sans-serif; color:#333; 3px 0 0 -3px; } -#Firebug .Right .HTML .Content .CSSItem center { color:rgb(0,150,0); padding:0 0 3px 0; font:bold 12px Arial, Helvetica, sans-serif; } -#Firebug .ButtonContainer .HTML { display:none; } - -/* - * CSS - */ - -#Firebug .Left .CSS { display:none; padding:5px; height:225px; overflow:scroll; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } -#Firebug .Right .CSS { display:none; } -#Firebug .Left .CSS .Selector { margin-top:10px } -#Firebug .Left .CSS .CSSText { padding-left:20px; } -#Firebug .Left .CSS .CSSProperty { color:#005500; margin-top:10px; } -#Firebug .Left .CSS .CSSValue { padding-left:5px; color:#000088; } -#Firebug .ButtonContainer .CSS { display:none; } - -#Firebug .Right .CSS { background:#eee; } -#Firebug .Right .CSS .Input { width:100%; _width:98%; height:205px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; background:#fff; border:0; border-bottom:1px solid #ccc; margin-bottom:2px; *overflow:scroll; } -#Firebug .Right .CSS .Button { cursor:pointer; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:1px 4px 1px 4px; margin:0 4px 0 4px; background:#eee; border:1px solid #eee; text-decoration:none; *display:block; *width:auto; *float:left; *margin-top:-1px; } -#Firebug .Right .CSS .Button:hover { border:1px outset #ccc; background:#fff; } -#Firebug .Right .CSS .Button:active { border:1px inset #ccc; background:#ccc; } - -/* - * Scripts - */ - -#Firebug .Left .Scripts { display:none; height:225px; *height:235px; overflow:scroll; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; } -#Firebug .Left .Scripts .LineNumber { float:left; width:30px; height:20px; padding:0 2px 0 0; background:#eee; color:#666; font-family:Courier; text-align:right; border-right:1px solid #ccc; } -#Firebug .Left .Scripts .CodeContainer { padding:5px; } -#Firebug .Left .Scripts .Code { height:20px; } -#Firebug .Left .Scripts .CodeContainer, #Firebug .Left .Scripts .Code { word-wrap:normal; white-space:pre; } -#Firebug .Right .Scripts { display:none; } -#Firebug .ButtonContainer .Scripts { display:none; } - -/* - * DOM - */ - -#Firebug .Left .DOM { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; } -#Firebug .Left .DOM .Object { font-weight:bold; } -#Firebug .Right .DOM { display:none; overflow:scroll; } -#Firebug .ButtonContainer .DOM { display:none; } -#Firebug .ButtonContainer .DOM label { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } - -/* - * XHR - */ - -#Firebug .Left .XHR { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; } -#Firebug .Left .XHR .Block { float:left; width:30%; } -#Firebug .Left .XHR .BlockContent { padding:3px; border-right:1px dotted #aaa; } -#Firebug .Left .XHR .Block strong { display:block; text-align:center; padding:3px; background:rgb(200,225,255); color:rgb(50,50,50); } -#Firebug .Left .XHR .Block span { display:block; text-align:center; overflow:hidden; } -#Firebug .Left .XHR .Block span a { cursor:pointer; color:rgb(0,0,200); } -#Firebug .Right .XHR { display:none; overflow:scroll; } -#Firebug .ButtonContainer .XHR { display:none; } -#Firebug .ButtonContainer .XHR label { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } - -#Firebug .Left .STR { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; } - -/* - * settings - */ -#Firebug .SettingsDiv {position:absolute;width:190px;top:60px;border:1px outset #000;-x-system-font:none;color:#000;font-family:"MS Sans Serif",Geneva,sans-serif;font-size:12px;font-size-adjust:none;font-stretch:normal;font-style:normal;font-variant:normal;font-weight:normal;line-height:normal;display:none;background-color:#FFF;} -#Firebug .SettingsDiv .Header {background:#CCC url(firebug.gif) repeat scroll 0 -85px;height:30px;border-bottom:1px inset #000;} -#Firebug .SettingsDiv .Header .Title {padding-top:10px;text-align:center;} -#Firebug .SettingsDiv .Content {padding:5px;} -#Firebug .SettingsDiv .Content .SettingsCBX{position:relative;top:2px;margin: 4px 5px 0 0; border:0 !important; padding:0 !important; height: 15px !important;} -#Firebug .SettingsDiv .Content .ButtonsLeft {float:left;padding:10px 0px 5px 0px;} -#Firebug .SettingsDiv .Content .ButtonsRight {float:right;padding:10px 0px 5px 0px;} -#Firebug .SettingsDiv .Content .ProgressDiv {background-color:#FFF;width:100%;height:100%;position:absolute;left:0;top:0;z-index:1;opacity:.8;filter:alpha(opacity=80);display:none;} -#Firebug .SettingsDiv .Content .Progress {background-image:url(progress.gif);width:66px;height:66px;position:absolute;top:50%;left:50%;margin-left:-33px;margin-top:-33px;} - -/* - * element highlighting - */ -#Firebug .Italic { font-style:italic; } -#Firebug .Strong { font-weight:bold; } -#Firebug .NormalWeight { font-weight:normal; } -#Firebug .Green { color:#008800; } -#Firebug .Gray { color:#666; } -#Firebug .Blue { color:#0000ee; } -#Firebug .DarkBlue { color:#000099; } -#Firebug .Red { color:#ee0000; } -#Firebug .Maroon { color:#800000; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } -#Firebug .Null { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; color:#fff; padding:0 2px 0 2px; background:#999; border:1px solid #666; } -#Firebug .ObjectLink, #Firebug .ObjectLinkHover { cursor:pointer; } -#Firebug .ObjectLinkHover { border-bottom:1px solid #008800; } - -#Firebug .Clear { clear:both; height:0px; font-size:0px; } - +/* */ +#Firebug div, #Firebug h3, #Firebug span, #Firebug input, #Firebug textarea, #Firebug select, #Firebug option, #Firebug a, #Firebug strong, #Firebug em, #Firebug label, #Firebug center { + position:static; float:none; width:auto; height:auto; text-align:left; border:0; overflow:visible; background:transparent none repeat left top; color:#111; font-size:1em; font-weight:normal; font-style:normal; font-family:sans-serif; margin:0; padding:0; min-height:0; +} +#Firebug input, #Firebug select, #Firebug textarea { background:#fff; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; border:1px outset #aaa; padding:2px } +#Firebug center { text-align:center; } +#Firebug strong { font-weight:bold; } +#Firebug em { font-style:italic; } +/* */ + +#FirebugIFrame { position:fixed !important; position:absolute; z-index:99999998; left:0; bottom:0; width:100%; height:295px; background:#fff; border-width:0px; } + +#Firebug { position:fixed !important; position:absolute; z-index:99999999; left:0; bottom:0; width:100%; height:295px; background:#fff; overflow:hidden; } +#Firebug .Resizer { position:absolute; top:0; width:100%; height:5px; background:transparent; *background:url(spacer.gif); cursor:n-resize; -moz-user-select:none; } +#Firebug .Header { height:38px; background:#ccc url(firebug.gif) 0 -85px; } +#Firebug .Left, #Firebug > .Right { background:#fff; height:257px;} +#Firebug .Left { float:left; width:100%; } +#Firebug .Right { float:left; display:none; width:30%; overflow:hidden; } +#Firebug .Right .Container { height:100%; border-left:1px solid #ccc; } + +/* + * buttonset + */ + +#Firebug .ButtonContainer { padding:8px 0 5px 10px; *margin-top:-3px; _margin-top:0; } +#Firebug .ButtonContainer .Button { cursor:pointer; font:12px "MS Sans Serif", Geneva, sans-serif; color:#000; margin-right:5px; padding:4px 4px 4px 4px; border:1px solid transparent !important; border-color:#ccc; text-decoration:none; } +#Firebug .ButtonContainer .Button:hover { border:1px outset #aaa !important; } +#Firebug .ButtonContainer .Button:active { border-style:inset !important; background-color:#ccc; } +#Firebug .ButtonContainer .Enabled { border:1px outset #aaa !important; } +#Firebug .ButtonContainer .Logo { text-decoration:none; padding-left:24px; background:url(firebug.gif) no-repeat 5px 3px; border:0 !important; opacity:0.7; filter:Alpha(Opacity=70); } +#Firebug .ButtonContainer .Logo:hover, #Firebug .ButtonContainer .Logo:active { border:0 !important; background-color:transparent; opacity:1; filter:Alpha(Opacity=100); } +#Firebug .ButtonContainer .Maximize, #Firebug .ButtonContainer .Minimize, #Firebug .ButtonContainer .NewWindow, #Firebug .ButtonContainer .Dock, #Firebug .ButtonContainer .Close { position:absolute; right:0; top:12px; padding:6px 8px 8px 8px; background:url(firebug.gif) no-repeat -3px -48px; border:0 !important; opacity:0.7; filter:Alpha(Opacity:80); *padding:0px 7px 1px 7px; } +#Firebug .ButtonContainer .Maximize:hover, #Firebug .ButtonContainer .Maximize:active, #Firebug .ButtonContainer .NewWindow:hover, #Firebug .ButtonContainer .NewWindow:active, #Firebug .ButtonContainer .Dock:hover, #Firebug .ButtonContainer .Dock:active, #Firebug .ButtonContainer .Minimize:hover, #Firebug .ButtonContainer .Minimize:active, #Firebug .ButtonContainer .Close:hover, #Firebug .ButtonContainer .Close:active { border:0 !important; background-color:transparent; opacity:1; filter:Alpha(Opacity:100); } +#Firebug .ButtonContainer .Minimize { background-position:-3px -20px; right:40px; } +#Firebug .ButtonContainer .Maximize { display:none; background-position:-3px -34px; right:40px; } +#Firebug .ButtonContainer .NewWindow { background-position:-3px -123px; right:20px; } +#Firebug .ButtonContainer .Dock { background-position:-3px -137px; } +#Firebug .ButtonContainer .ButtonSet { border-left:1px solid #ccc; padding:0 0 0 3px; display:inline; } + +/* + * navigation + */ + +#Firebug .Nav { height:23px; background:url(firebug.gif) repeat-x 0 -62px; padding-left:10px; } +#Firebug .Nav .Tab { display:block; width:auto; float:left; padding:3px 6px 2px 6px; cursor:pointer; border:1px outset transparent !important; border:0; font:bold 11px Arial, Helvetica, sans-serif; color:#666; } +#Firebug .Nav .Tab:hover, #Firebug .Nav .Selected { border:1px outset #ccc !important; border-top-color:transparent !important; } +#Firebug .Nav .Selected { color:#111; cursor:default; background-color:#f2f2f2; } +#Firebug .Nav .Settings { float:right; } + +/* + * inspector + */ + +#FirebugBorderInspector { display:none; z-index:99999998; position:absolute; top:0; left:0; border:2px solid #0000ff; background:transparent; *background:url(spacer.gif); opacity:0.5; filter:Alpha(Opacity=50); padding:0; margin:0; } +#FirebugBGInspector { display:none; z-index:99999998; position:absolute; top:0; left:0; background:rgb(0,150,255); opacity:0.5; filter:Alpha(Opacity=50); padding:0; margin:0; } + +/* + * dom + */ + +#Firebug .DOMRow { width:100% !important; width:90%; } +#Firebug .DOMRow .DOMRowLeft { float:left; width:30%; overflow:hidden; } +#Firebug .DOMRow .DOMRowLeft a { padding-left:15px; } +#Firebug .DOMRow .DOMRowRight { float:left; width:60%; *width:60%; _overflow:hidden; white-space:nowrap; } +#Firebug .DOMRow .DOMRowLeft .Object { background:url(tree_open.gif) no-repeat left center; cursor:pointer; } +#Firebug .DOMRow .DOMRowLeft .Object:hover { text-decoration:underline; color:#0000ff; } +#Firebug .DOMRow .DOMRowLeft .Opened { background-image:url(tree_close.gif) } +#Firebug .DOMRow .DOMRowSubContainer { display:none; padding-left:25px; } + +/* + * console + */ +#Firebug .Left .Console { overflow:hidden; } +#Firebug .Left .Console .Monitor { height:210px; border-bottom:1px solid #ccc; overflow:scroll; overflow-x:hidden; } +#Firebug .Left .Console .Monitor .Error { background:#ffeff1; color:#ff0000; } +#Firebug .Left .Console .Monitor .Error strong { color:#ff0000; } +#Firebug .Left .Console .Monitor .Row { padding:2px 5px 2px 5px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; overflow:hidden; border-bottom:1px solid #e5e5e5; } +#Firebug .Left .Console .Monitor .Arrow { color:rgb(0,0,255); white-space:nowrap; } + +#Firebug .Left .Console .InputArrow { position:absolute; left:0px; width:20px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; color:#0000ff; padding:2px 4px 0 4px; } +#Firebug .Left .Console .InputContainer { margin-left:35px; margin-right:5px; } +#Firebug .Left .Console .Input { width:100% !important; margin-top:2px; width:98%; overflow:hidden; border:0; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; } +#Firebug .Console .MLButton { cursor:pointer; position:absolute; top:276px; right:-22px; width:20px; padding:4px 10px 10px 10px; font-size:1px; *padding:2px 10px 10px 10px; background:url(firebug.gif) no-repeat -3px -34px; opacity:0.8; filter:Alpha(Opacity:80); } +#Firebug .Console .MLButton:hover { opacity:1; filter:Alpha(Opacity:100); } +#Firebug .Console .CloseML { background-position:-3px -20px; } + +#Firebug .Right .Console { background:#eee; } +#Firebug .Right .Console .Input { width:100%; _width:98%; height:228px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; background:#fff; border:0; border-bottom:1px solid #ccc; margin-bottom:2px; *overflow:scroll; } +#Firebug .Right .Console .Button { cursor:pointer; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:1px 4px 1px 4px; margin:0 4px 0 4px; background:#eee; border:1px solid #eee; text-decoration:none; *display:block; *width:auto; *float:left; *margin-top:-1px; } +#Firebug .Right .Console .Button:hover { border:1px outset #ccc; background:#fff; } +#Firebug .Right .Console .Button:active { border:1px inset #ccc; background:#ccc; } + +#Firebug .Left .Console .Monitor .Warn { background:url(warningIcon.png) #00FFFF no-repeat 2px center; padding-left:20px; } +#Firebug .Left .Console .Monitor .Info { background:url(infoIcon.png) #fff no-repeat 2px center; padding-left:20px; } +#Firebug .Left .Console .Monitor .Error { background:url(errorIcon.png) #FFFFE0 no-repeat 2px center; padding-left:20px; } + + +/* + * html + */ + +#Firebug .Left .HTML { display:none; height:250px; overflow:scroll; padding:0 10px 2px 10px; } +#Firebug .Left .HTML .Block { padding:0 0 0 0px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } +#Firebug .Left .HTML .Block .Spacer { cursor:default; padding:2px 2px 2px 15px; } +#Firebug .Left .HTML .Block .Link { display:block; color:#333; padding:2px 2px 2px 0; } +#Firebug .Left .HTML .Block .Link .Content { padding:2px 2px 2px 2px; } +#Firebug .Left .HTML .Block .Link .TagName { cursor:pointer; } +#Firebug .Left .HTML .Block .Parent { font-weight:bold; color:#111; text-decoration:none; } +#Firebug .Left .HTML .Block .Parent .Spacer { background:#fff center no-repeat; } +#Firebug .Left .HTML .Block .Parent .Spacer { background-image:url(tree_open.gif); } +#Firebug .Left .HTML .Block .Open .Spacer { background-image:url(tree_close.gif) } +#Firebug .Left .HTML .Block .Selected { background-color:#4473c4; } +#Firebug .Left .HTML .Block .Selected * { color:#fff; } +#Firebug .Left .HTML .Block .SubContainer { padding-left:20px; height:0; font-size:0px; } +#Firebug .Left .HTML .Block .OpenSubContainer { height:auto; } +#Firebug .Left .HTML .Unvisible { opacity:0.5; filter:Alpha(Opacity=50); } + +#Firebug .Right .HTML { display:none; } +#Firebug .Right .HTML .Content { overflow:scroll; height:235px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } +#Firebug .Right .HTML .Content .CSSItem { padding:5px; color:#333; height:6px } +#Firebug .Right .HTML .Content .CSSProperty { width:45%; float:left; overflow:hidden; } +#Firebug .Right .HTML .Content .CSSValue { width:55%; float:left; white-space:nowrap; overflow:visible !important; overflow:hidden; } +#Firebug .Right .HTML .Content .CSSValue input { font:11px ArArial, Helvetica, sans-serif; color:#333; 3px 0 0 -3px; } +#Firebug .Right .HTML .Content .CSSItem center { color:rgb(0,150,0); padding:0 0 3px 0; font:bold 12px Arial, Helvetica, sans-serif; } +#Firebug .ButtonContainer .HTML { display:none; } + +/* + * CSS + */ + +#Firebug .Left .CSS { display:none; padding:5px; height:225px; overflow:scroll; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } +#Firebug .Right .CSS { display:none; } +#Firebug .Left .CSS .Selector { margin-top:10px } +#Firebug .Left .CSS .CSSText { padding-left:20px; } +#Firebug .Left .CSS .CSSProperty { color:#005500; margin-top:10px; } +#Firebug .Left .CSS .CSSValue { padding-left:5px; color:#000088; } +#Firebug .ButtonContainer .CSS { display:none; } + +#Firebug .Right .CSS { background:#eee; } +#Firebug .Right .CSS .Input { width:100%; _width:98%; height:205px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; background:#fff; border:0; border-bottom:1px solid #ccc; margin-bottom:2px; *overflow:scroll; } +#Firebug .Right .CSS .Button { cursor:pointer; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:1px 4px 1px 4px; margin:0 4px 0 4px; background:#eee; border:1px solid #eee; text-decoration:none; *display:block; *width:auto; *float:left; *margin-top:-1px; } +#Firebug .Right .CSS .Button:hover { border:1px outset #ccc; background:#fff; } +#Firebug .Right .CSS .Button:active { border:1px inset #ccc; background:#ccc; } + +/* + * Scripts + */ + +#Firebug .Left .Scripts { display:none; height:225px; *height:235px; overflow:scroll; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; } +#Firebug .Left .Scripts .LineNumber { float:left; width:30px; height:20px; padding:0 2px 0 0; background:#eee; color:#666; font-family:Courier; text-align:right; border-right:1px solid #ccc; } +#Firebug .Left .Scripts .CodeContainer { padding:5px; } +#Firebug .Left .Scripts .Code { height:20px; } +#Firebug .Left .Scripts .CodeContainer, #Firebug .Left .Scripts .Code { word-wrap:normal; white-space:pre; } +#Firebug .Right .Scripts { display:none; } +#Firebug .ButtonContainer .Scripts { display:none; } + +/* + * DOM + */ + +#Firebug .Left .DOM { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; } +#Firebug .Left .DOM .Object { font-weight:bold; } +#Firebug .Right .DOM { display:none; overflow:scroll; } +#Firebug .ButtonContainer .DOM { display:none; } +#Firebug .ButtonContainer .DOM label { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } + +/* + * XHR + */ + +#Firebug .Left .XHR { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; } +#Firebug .Left .XHR .Block { float:left; width:30%; } +#Firebug .Left .XHR .BlockContent { padding:3px; border-right:1px dotted #aaa; } +#Firebug .Left .XHR .Block strong { display:block; text-align:center; padding:3px; background:rgb(200,225,255); color:rgb(50,50,50); } +#Firebug .Left .XHR .Block span { display:block; text-align:center; overflow:hidden; } +#Firebug .Left .XHR .Block span a { cursor:pointer; color:rgb(0,0,200); } +#Firebug .Right .XHR { display:none; overflow:scroll; } +#Firebug .ButtonContainer .XHR { display:none; } +#Firebug .ButtonContainer .XHR label { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } + +#Firebug .Left .STR { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; } + +/* + * settings + */ +#Firebug .SettingsDiv {position:absolute;width:190px;top:60px;border:1px outset #000;-x-system-font:none;color:#000;font-family:"MS Sans Serif",Geneva,sans-serif;font-size:12px;font-size-adjust:none;font-stretch:normal;font-style:normal;font-variant:normal;font-weight:normal;line-height:normal;display:none;background-color:#FFF;} +#Firebug .SettingsDiv .Header {background:#CCC url(firebug.gif) repeat scroll 0 -85px;height:30px;border-bottom:1px inset #000;} +#Firebug .SettingsDiv .Header .Title {padding-top:10px;text-align:center;} +#Firebug .SettingsDiv .Content {padding:5px;} +#Firebug .SettingsDiv .Content .SettingsCBX{position:relative;top:2px;margin: 4px 5px 0 0; border:0 !important; padding:0 !important; height: 15px !important;} +#Firebug .SettingsDiv .Content .ButtonsLeft {float:left;padding:10px 0px 5px 0px;} +#Firebug .SettingsDiv .Content .ButtonsRight {float:right;padding:10px 0px 5px 0px;} +#Firebug .SettingsDiv .Content .ProgressDiv {background-color:#FFF;width:100%;height:100%;position:absolute;left:0;top:0;z-index:1;opacity:.8;filter:alpha(opacity=80);display:none;} +#Firebug .SettingsDiv .Content .Progress {background-image:url(progress.gif);width:66px;height:66px;position:absolute;top:50%;left:50%;margin-left:-33px;margin-top:-33px;} + +/* + * element highlighting + */ +#Firebug .Italic { font-style:italic; } +#Firebug .Strong { font-weight:bold; } +#Firebug .NormalWeight { font-weight:normal; } +#Firebug .Green { color:#008800; } +#Firebug .Gray { color:#666; } +#Firebug .Blue { color:#0000ee; } +#Firebug .DarkBlue { color:#000099; } +#Firebug .Red { color:#ee0000; } +#Firebug .Maroon { color:#800000; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; } +#Firebug .Null { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; color:#fff; padding:0 2px 0 2px; background:#999; border:1px solid #666; } +#Firebug .ObjectLink, #Firebug .ObjectLinkHover { cursor:pointer; } +#Firebug .ObjectLinkHover { border-bottom:1px solid #008800; } + +#Firebug .Clear { clear:both; height:0px; font-size:0px; } + #firebugIconDiv {width:38px;height:38px;right:15pt;bottom:5pt;border:2px solid #000;display:none;position:fixed;background-image:url(firebug_logo.png);text-decoration:underline;cursor:pointer;filter:alpha(opacity:60);opacity:.6;z-index:99999998;} \ No newline at end of file diff --git a/js-ext/firebug/firebug-lite.js b/js-ext/firebug/firebug-lite.js index 8ce69358..211b6ebc 100755 --- a/js-ext/firebug/firebug-lite.js +++ b/js-ext/firebug/firebug-lite.js @@ -1,2518 +1,2518 @@ -var firebug = { - version:[1.23,20090309], - el:{}, - env:{ - "cache":{}, - "extConsole":null, - "css":"http://getfirebug.com/releases/lite/1.2/firebug-lite.css", - "debug":true, - "detectFirebug":false, - "dIndex":"console", - "height":295, - "hideDOMFunctions":false, - "init":false, - "isPopup":false, - "liteFilename":"firebug-lite.js", - "minimized":false, - "openInPopup": false, - "override":false, - "ml":false, - "popupWin":null, - "showIconWhenHidden":true, - "targetWindow":undefined, - "popupTop":1, - "popupLeft":1, - "popupWidth":undefined, - "popupHeight":undefined - }, - initConsole:function(){ - /* - * initialize the console - user defined values are not available within this method because FBLite is not yet initialized - */ - var command; - try{ - if((!window.console || (window.console && !window.console.firebug)) || (firebug.env.override && !(/Firefox\/3/i.test(navigator.userAgent)))){ - window.console = { "provider":"Firebug Lite" }; - - for(command in firebug.d.console.cmd){ - window.console[command] = firebug.lib.util.Curry(firebug.d.console.run,window,command); - }; - } - window.onerror = function(_message,_file,_line){ - firebug.d.console.run('error',firebug.lib.util.String.format('{0} ({1},{2})',_message,firebug.getFileName(_file),_line)); - }; - } catch(e){} - }, - overrideConsole:function(){ - with (firebug){ - env.override=true; - try{ - env.extConsole=window.console; - } catch(e){} - initConsole(); - } - }, - restoreConsole:function(){ - with(firebug){ - if(env.extConsole){ - env.override=false; - try{ - window.console=env.extConsole; - } catch(e){} - env.extConsole=null; - } - } - }, - init:function(_css){ - var iconTitle = "Click here or press F12, (CTRL|CMD)+SHIFT+L or SHIFT+ENTER to show Firebug Lite. CTRL|CMD click this icon to hide it."; - - with(firebug){ - if(document.getElementsByTagName('html')[0].attributes.getNamedItem('debug')){ - env.debug = document.getElementsByTagName('html')[0].attributes.getNamedItem('debug').nodeValue !== "false"; - } - - if(env.isPopup) { - env.openInPopup = false; - env.targetWindow = window.opener; - env.popupWidth = window.opener.firebug.env.popupWidth || window.opener.firebug.lib.util.GetViewport().width; - env.popupHeight = window.opener.firebug.env.popupHeight || window.opener.firebug.lib.util.GetViewport().height; - } else { - env.targetWindow = window; - env.popupWidth = env.popupWidth || lib.util.GetViewport().width; - env.popupHeight = env.popupHeight || lib.util.GetViewport().height; - } - - settings.readCookie(); - - if(env.init || (env.detectFirebug && window.console && window.console.firebug)) { - return; - } - - document.getElementsByTagName("head")[0].appendChild( - new lib.element("link").attribute.set("rel","stylesheet").attribute.set("type","text/css").attribute.set("href",env.css).element - ); - - if(env.override){ - overrideConsole(); - } - - /* - * Firebug Icon - */ - el.firebugIcon = new lib.element("div").attribute.set("id","firebugIconDiv").attribute.set("title",iconTitle).attribute.set("alt",iconTitle).event.addListener("mousedown",win.iconClicked).insert(document.body); - - /* - * main interface - */ - el.content = {}; - el.mainiframe = new lib.element("IFRAME").attribute.set("id","FirebugIFrame").environment.addStyle({ "display":"none", "width":lib.util.GetViewport().width+"px" }).insert(document.body); - el.main = new lib.element("DIV").attribute.set("id","Firebug").environment.addStyle({ "display":"none", "width":lib.util.GetViewport().width+"px" }).insert(document.body); - if(!env.isPopup){ - el.resizer = new lib.element("DIV").attribute.addClass("Resizer").event.addListener("mousedown",win.resizer.start).insert(el.main); - } - el.header = new lib.element("DIV").attribute.addClass("Header").insert(el.main); - el.left = {}; - el.left.container = new lib.element("DIV").attribute.addClass("Left").insert(el.main); - el.right = {}; - el.right.container = new lib.element("DIV").attribute.addClass("Right").insert(el.main); - el.main.child.add(new lib.element("DIV").attribute.addClass('Clear')); - - /* - * buttons - */ - el.button = {}; - el.button.container = new lib.element("DIV").attribute.addClass("ButtonContainer").insert(el.header); - el.button.logo = new lib.element("A").attribute.set("title","Firebug Lite").attribute.set("target","_blank").attribute.set("href","http://getfirebug.com/lite.html").update(" ").attribute.addClass("Button Logo").insert(el.button.container); - el.button.inspect = new lib.element("A").attribute.addClass("Button").event.addListener("click",env.targetWindow.firebug.d.inspector.toggle).update("Inspect").insert(el.button.container); - el.button.dock = new lib.element("A").attribute.addClass("Button Dock").event.addListener("click", win.dock).insert(el.button.container); - el.button.newWindow = new lib.element("A").attribute.addClass("Button NewWindow").event.addListener("click", win.newWindow).insert(el.button.container); - - if(!env.isPopup){ - el.button.maximize = new lib.element("A").attribute.addClass("Button Maximize").event.addListener("click",win.maximize).insert(el.button.container); - el.button.minimize = new lib.element("A").attribute.addClass("Button Minimize").event.addListener("click",win.minimize).insert(el.button.container); - el.button.close = new lib.element("A").attribute.addClass("Button Close").event.addListener("click",win.hide).insert(el.button.container); - } - - if(lib.env.ie||lib.env.webkit){ - el.button.container.environment.addStyle({ "paddingTop":"12px" }); - } - - /* - * navigation - */ - el.nav = {}; - el.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.left.container); - el.nav.console = new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.navigate,window,"console")).update("Console").insert(el.nav.container); - el.nav.html = new lib.element("A").attribute.addClass("Tab").update("HTML").event.addListener("click",lib.util.Curry(d.navigate,window,"html")).insert(el.nav.container); - el.nav.css = new lib.element("A").attribute.addClass("Tab").update("CSS").event.addListener("click",lib.util.Curry(d.navigate,window,"css")).insert(el.nav.container); - if(!env.isPopup){ - el.nav.scripts = new lib.element("A").attribute.addClass("Tab").update("Script").event.addListener("click",lib.util.Curry(d.navigate,window,"scripts")).insert(el.nav.container); - } - el.nav.dom = new lib.element("A").attribute.addClass("Tab").update("DOM").event.addListener("click",lib.util.Curry(d.navigate,env.targetWindow,"dom")).insert(el.nav.container); - el.nav.xhr = new lib.element("A").attribute.addClass("Tab").update("XHR").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).insert(el.nav.container); - el.nav.optionsdiv = new lib.element("DIV").attribute.addClass("Settings").insert(el.nav.container); - el.nav.options = new lib.element("A").attribute.addClass("Tab").update("Options ∨").event.addListener("click", settings.toggle).insert(el.nav.optionsdiv); - - /* - * inspector - */ - el.borderInspector = new lib.element("DIV").attribute.set("id","FirebugBorderInspector").event.addListener("click",listen.inspector).insert(document.body); - el.bgInspector = new lib.element("DIV").attribute.set("id","FirebugBGInspector").insert(document.body); - - /* - * console - */ - el.left.console = {}; - el.left.console.container = new lib.element("DIV").attribute.addClass("Console").insert(el.left.container); - el.left.console.mlButton = new lib.element("A").attribute.addClass("MLButton").event.addListener("click",d.console.toggleML).insert(el.left.console.container); - el.left.console.monitor = new lib.element("DIV").insert( - new lib.element("DIV").attribute.addClass("Monitor").insert(el.left.console.container) - ); - el.left.console.container.child.add( - new lib.element("DIV").attribute.addClass("InputArrow").update(">>>") - ); - el.left.console.input = new lib.element("INPUT").attribute.set("type","text").attribute.addClass("Input").event.addListener("keydown",listen.consoleTextbox).insert( - new lib.element("DIV").attribute.addClass("InputContainer").insert(el.left.console.container) - ); - - el.right.console = {}; - el.right.console.container = new lib.element("DIV").attribute.addClass("Console Container").insert(el.right.container); - el.right.console.mlButton = new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.console.container); - el.right.console.input = new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.console.container); - el.right.console.input.event.addListener("keydown",lib.util.Curry(tab,window,el.right.console.input.element)); - el.right.console.run = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runMultiline).update("Run").insert(el.right.console.container); - el.right.console.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.console.input)).update("Clear").insert(el.right.console.container); - - el.button.console = {}; - el.button.console.container = new lib.element("DIV").attribute.addClass("ButtonSet").insert(el.button.container); - el.button.console.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",d.console.clear).update("Clear").insert(el.button.console.container); - - /* - * html - */ - - el.left.html = {}; - el.left.html.container = new lib.element("DIV").attribute.addClass("HTML").insert(el.left.container); - - el.right.html = {}; - el.right.html.container = new lib.element("DIV").attribute.addClass("HTML Container").insert(el.right.container); - - el.right.html.nav = {}; - el.right.html.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.right.html.container); - el.right.html.nav.computedStyle = new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"computedStyle")).update("Computed Style").insert(el.right.html.nav.container); - el.right.html.nav.dom = new lib.element("A").attribute.addClass("Tab").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"dom")).update("DOM").insert(el.right.html.nav.container); - - el.right.html.content = new lib.element("DIV").attribute.addClass("Content").insert(el.right.html.container); - - el.button.html = {}; - el.button.html.container = new lib.element("DIV").attribute.addClass("ButtonSet HTML").insert(el.button.container); - - /* - * css - */ - - el.left.css = {}; - el.left.css.container = new lib.element("DIV").attribute.addClass("CSS").insert(el.left.container); - - el.right.css = {}; - el.right.css.container = new lib.element("DIV").attribute.addClass("CSS Container").insert(el.right.container); - - el.right.css.nav = {}; - el.right.css.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.right.css.container); - el.right.css.nav.runCSS = new lib.element("A").attribute.addClass("Tab Selected").update("Run CSS").insert(el.right.css.nav.container); - - el.right.css.mlButton = new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.css.container); - el.right.css.input = new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.css.container); - el.right.css.input.event.addListener("keydown",lib.util.Curry(firebug.tab,window,el.right.css.input.element)); - el.right.css.run = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runCSS).update("Run").insert(el.right.css.container); - el.right.css.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.css.input)).update("Clear").insert(el.right.css.container); - - el.button.css = {}; - el.button.css.container = new lib.element("DIV").attribute.addClass("ButtonSet CSS").insert(el.button.container); - el.button.css.selectbox = new lib.element("SELECT").event.addListener("change",listen.cssSelectbox).insert(el.button.css.container); - - /* - * scripts - */ - - el.left.scripts = {}; - el.left.scripts.container = new lib.element("DIV").attribute.addClass("Scripts").insert(el.left.container); - - el.right.scripts = {}; - el.right.scripts.container = new lib.element("DIV").attribute.addClass("Scripts Container").insert(el.right.container); - - el.button.scripts = {}; - el.button.scripts.container = new lib.element("DIV").attribute.addClass("ButtonSet Scripts").insert(el.button.container); - el.button.scripts.selectbox = new lib.element("SELECT").event.addListener("change",listen.scriptsSelectbox).insert(el.button.scripts.container); - el.button.scripts.lineNumbers = new lib.element("A").attribute.addClass("Button").event.addListener("click",d.scripts.toggleLineNumbers).update("Show Line Numbers").insert(el.button.scripts.container); - - /* - * dom - */ - - el.left.dom = {}; - el.left.dom.container = new lib.element("DIV").attribute.addClass("DOM").insert(el.left.container); - - el.right.dom = {}; - el.right.dom.container = new lib.element("DIV").attribute.addClass("DOM Container").insert(el.right.container); - - el.button.dom = {}; - el.button.dom.container = new lib.element("DIV").attribute.addClass("ButtonSet DOM").insert(el.button.container); - el.button.dom.label = new lib.element("LABEL").update("Object Path:").insert(el.button.dom.container); - el.button.dom.textbox = new lib.element("INPUT").event.addListener("keydown",listen.domTextbox).update(env.isPopup?"window.opener":"window").insert(el.button.dom.container); - - /* - * str - */ - el.left.str = {}; - el.left.str.container = new lib.element("DIV").attribute.addClass("STR").insert(el.left.container); - - el.right.str = {}; - el.right.str.container = new lib.element("DIV").attribute.addClass("STR").insert(el.left.container); - - el.button.str = {}; - el.button.str.container = new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container); - el.button.str.watch = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).update("Back").insert(el.button.str.container); - - /* - * xhr - */ - el.left.xhr = {}; - el.left.xhr.container = new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container); - - el.right.xhr = {}; - el.right.xhr.container = new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container); - - - el.button.xhr = {}; - el.button.xhr.container = new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container); - el.button.xhr.label = new lib.element("LABEL").update("XHR Path:").insert(el.button.xhr.container); - el.button.xhr.textbox = new lib.element("INPUT").event.addListener("keydown",listen.xhrTextbox).insert(el.button.xhr.container); - el.button.xhr.watch = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.addXhrObject).update("Watch").insert(el.button.xhr.container); - - /* - * settings - */ - el.settings = {}; - el.settings.container = new lib.element("DIV").child.add( - new lib.element("DIV").attribute.addClass("Header").child.add( - new lib.element().attribute.addClass("Title").update('Firebug Lite Settings') - ) - ).attribute.addClass("SettingsDiv").insert(el.main); - el.settings.content = new lib.element("DIV").attribute.addClass("Content").insert(el.settings.container); - el.settings.progressDiv = new lib.element("DIV").attribute.addClass("ProgressDiv").insert(el.settings.content); - el.settings.progress = new lib.element("DIV").attribute.addClass("Progress").insert(el.settings.progressDiv); - el.settings.cbxDebug = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); - el.settings.content.child.add(document.createTextNode("Start visible")); - new lib.element("BR").insert(el.settings.content); - el.settings.cbxDetectFirebug = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); - el.settings.content.child.add(document.createTextNode("Hide when Firebug active")); - new lib.element("BR").insert(el.settings.content); - el.settings.cbxHideDOMFunctions = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); - el.settings.content.child.add(document.createTextNode("Hide DOM functions")); - new lib.element("BR").insert(el.settings.content); - el.settings.cbxOverride = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); - el.settings.content.child.add(document.createTextNode("Override window.console")); - new lib.element("BR").insert(el.settings.content); - el.settings.cbxShowIcon = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); - el.settings.content.child.add(document.createTextNode("Show icon when hidden")); - new lib.element("BR").insert(el.settings.content); - el.settings.cbxOpenInPopup = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); - el.settings.content.child.add(document.createTextNode("Open in popup")); - el.settings.buttonDiv = new lib.element("DIV").insert(el.settings.content); - el.settings.buttonLeftDiv = new lib.element("DIV").attribute.addClass("ButtonsLeft").insert(el.settings.buttonDiv); - el.settings.resetButton = new lib.element("INPUT").attribute.set("type","button").update("Reset").event.addListener("click",settings.reset).insert(el.settings.buttonLeftDiv); - el.settings.buttonRightDiv = new lib.element("DIV").attribute.addClass("ButtonsRight").insert(el.settings.buttonDiv); - el.settings.cancelButton = new lib.element("INPUT").attribute.set("type","button").update("Cancel").event.addListener("click",settings.hide).insert(el.settings.buttonRightDiv); - el.settings.buttonRightDiv.child.add(document.createTextNode(" ")); - el.settings.saveButton = new lib.element("INPUT").attribute.set("type","button").update("Save").event.addListener("click",settings.saveClicked).insert(el.settings.buttonRightDiv); - - lib.util.AddEvent(document,"mousemove",listen.mouse)("mousemove",win.resizer.resize)("mouseup",win.resizer.stop)("keydown",listen.keyboard); - - env.init = true; - - for(var i=0, len=d.console.cache.length; i0) { - cookieArr=targetWindow.document.cookie.split('; '); - - for(i=0;i -1) { - scriptPath = scripts[i].src; - break; - } - } - - if (scriptPath) { - script = fe.popupWin.document.createElement('script'), done = false; - script.type = 'text/javascript'; - script.src = scriptPath; - - script[firebug.lib.env.ie?"onreadystatechange":"onload"] = function(){ - if(!done && (!firebug.lib.env.ie || this.readyState == "complete" || this.readyState=="loaded")){ - done = true; - if(fe.popupWin.firebug) { - with(fe.popupWin.firebug) { - env.isPopup = true; - env.css = fe.css; - init(); - el.button.dock.environment.addStyle({ "display": "block"}); - el.button.newWindow.environment.addStyle({ "display": "none"}); - } - } - } - }; - - if (!done && firebug.lib.env.webkit) { - fe.popupWin.document.write(''); - interval = setInterval(function() { - if (fe.popupWin.firebug) { - clearInterval(interval); - done = true; - with(fe.popupWin.firebug) { - env.isPopup = true; - env.css = fe.css; - init(); - el.button.dock.environment.addStyle({ "display": "block"}); - el.button.newWindow.environment.addStyle({ "display": "none"}); - } - } - }, 10); - }; - - if (!done) { - fe.popupWin.document.getElementsByTagName('head')[0].appendChild(script); - firebug.el.main.environment.addStyle({"display": "none"}); - firebug.el.mainiframe.environment.addStyle({"display": "none"}); - } - } else { - alert("Unable to detect the following script \"" + fe.liteFilename + - "\" ... if the script has been renamed then please set the value of firebug.env.liteFilename to reflect this change"); - fe.popupWin.close(); - fe.popupWin=null; - } - } - } - }, - dock: function() { - with(opener.firebug) { - env.popupWin = null; - el.main.environment.addStyle({ - "display": "block" - }); - el.mainiframe.environment.addStyle({ - "display": "block" - }); - settings.readCookie(); - window.close(); - }; - }, - unload: function() { - with(firebug){ - if(env.isPopup) { - win.dock(); - } else if(env.popupWin) { - env.popupWin.close(); - } - } - }, - fitToPopup: function() { - with(firebug) { - var viewport = lib.util.GetViewport(window); - win.setHeight((window.innerHeight||viewport.height) - 38); - el.main.environment.addStyle({ - "width": (viewport.width) + "px" - }); - el.mainiframe.environment.addStyle({ - "width": (viewport.width) + "px" - }); - } - }, - resizer:{ - y:[], enabled:false, - start:function(_event){ - with(firebug){ - if(env.minimized)return; - win.resizer.y=[el.main.element.offsetHeight,_event.clientY]; - if(lib.env.ie6){ - win.resizer.y[3]=parseInt(el.main.environment.getPosition().top); - } - win.resizer.enabled=true; - } - }, - resize:function(_event){ - with(firebug){ - if(!win.resizer.enabled)return; - win.resizer.y[2]=(win.resizer.y[0]+(win.resizer.y[1]-_event.clientY)); - el.main.environment.addStyle({ "height":win.resizer.y[2]+"px" }); - el.mainiframe.environment.addStyle({ "height":win.resizer.y[2]+"px" }); - if(lib.env.ie6){ - el.main.environment.addStyle({ "top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px" }); - el.mainiframe.environment.addStyle({ "top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px" }); - } - } - }, - stop:function(_event){ - with(firebug){ - if(win.resizer.enabled){ - win.resizer.enabled=false; - win.setHeight(win.resizer.y[2]-35); - } - } - } - }, - setHeight:function(_height){ - with(firebug){ - env.height=_height; - - el.left.container.environment.addStyle({ "height":_height+"px" }); - el.right.container.environment.addStyle({ "height":_height+"px" }); - el.main.environment.addStyle({ "height":_height+38+"px" }); - el.mainiframe.environment.addStyle({ "height":_height+38+"px" }); - - win.refreshSize(); - - // console - el.left.console.monitor.element.parentNode.style.height=_height-47+"px"; - el.left.console.mlButton.environment.addStyle({ "top":_height+19+"px" }); - el.right.console.mlButton.environment.addStyle({ "top":_height+19+"px" }); - el.right.console.input.environment.addStyle({ "height":_height-29+"px" }); - - // html - el.left.html.container.environment.addStyle({"height":_height-23+"px"}); - el.right.html.content.environment.addStyle({"height":_height-23+"px"}); - - // css - el.left.css.container.environment.addStyle({"height":_height-33+"px"}); - el.right.css.input.environment.addStyle({ "height":_height-55+"px" }); - - // script - el.left.scripts.container.environment.addStyle({"height":_height-23+"px"}); - - // dom - el.left.dom.container.environment.addStyle({"height":_height-31+"px"}); - - // xhr - el.left.xhr.container.environment.addStyle({"height":_height-32+"px"}); - - // string - el.left.str.container.environment.addStyle({"height":_height-32+"px"}); - } - }, - refreshDOM:function(){ - with(firebug){ - d.dom.open(eval(el.button.dom.textbox.environment.getElement().value),el.left.dom.container); - if(d.html.nIndex=="dom"){ - firebug.d.html.navigate("dom") - } - } - }, - refreshSize:function(){ - with(firebug){ - if(!env.init) - return; - - var dim = lib.util.GetViewport(); - el.main.environment.addStyle({ "width":dim.width+"px"}); - el.mainiframe.environment.addStyle({ "width":dim.width+"px"}); - if(lib.env.ie6) - win.setVerticalPosition(dim); - } - }, - setVerticalPosition:function(_dim,_event){ - with(firebug){ - var dim = _dim||lib.util.GetViewport(); - el.main.environment.addStyle({ "top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px" }); - el.mainiframe.environment.addStyle({ "top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px" }); - } - } - }, - d: { - clean:function(_element){ - with(firebug){ - _element.update(""); - } - }, - console:{ - addLine:function(){ - with (firebug) { - return new lib.element("DIV").attribute.addClass("Row").insert(el.left.console.monitor); - } - }, - cache:[], - clear:function(){ - with(firebug){ - d.clean(el.left.console.monitor); - d.console.cache = []; - } - }, - formatArgs:function(){ - with(firebug){ - var content = []; - for(var i=0, len=arguments.length; i>> "+_cmd); - d.console.addLine().update(d.highlight(_text,false,false,true)); - d.console.scroll(); - } - }, - printException: function(_exception){ - with(firebug){ - var message = _exception.description||_exception.message||_exception; - if(_exception.fileName){ - message+=' ('+(_exception.name&&(_exception.name+', ')||'')+getFileName(_exception.fileName)+', '+_exception.lineNumber+')'; - } - d.console.addLine().attribute.addClass("Error").update("Error: "+message,true); - } - }, - eval:function(_cmd){ - var result; - with(firebug){ - if(_cmd.length==0) - return; - - el.left.console.input.environment.getElement().value = ""; - d.console.historyIndex = d.console.history.push(_cmd); - - try { - if(_cmd==='console.firebug') { - d.console.addLine().attribute.addClass("Arrow").update(firebug.version); - } else { - result = eval.call(window,_cmd); - d.console.print(_cmd,result); - } - } catch(e){ - d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd); - d.console.printException(e); - } - d.console.scroll(); - } - }, - scroll:function(){ - with(firebug){ - el.left.console.monitor.environment.getElement().parentNode.scrollTop = Math.abs(el.left.console.monitor.environment.getSize().offsetHeight-(el.left.console.monitor.element.parentNode.offsetHeight-11)); - } - }, - run:function(_command){ - with(firebug){ - if(!env.init){ - d.console.cache.push({ "command":_command, "arg":Array.prototype.slice.call(arguments,1) }); - } else { - d.console.cmd[_command].apply(window,Array.prototype.slice.call(arguments,1)); - } - } - }, - toggleML:function(){ - with(firebug){ - var open = !env.ml; - env.ml = !env.ml; - d.navigateRightColumn("console",open); - el[open?"left":"right"].console.mlButton.environment.addStyle({ display:"none" }); - el[!open?"left":"right"].console.mlButton.environment.addStyle({ display:"block" }); - el.left.console.mlButton.attribute[(open?"add":"remove")+"Class"]("CloseML"); - } - }, - countMap:{}, timeMap: {}, - cmd:{ - log: function(_value){ - with(firebug){ - var args = d.console.formatArgs.apply(window,arguments); - d.console.addLine().attribute.addClass("Log").update(args); - d.console.scroll(); - } - }, - warn: function(_value){ - with(firebug){ - var args = d.console.formatArgs.apply(window,arguments); - d.console.addLine().attribute.addClass("Warn").update(args); - d.console.scroll(); - } - }, - info: function(_value){ - with(firebug){ - var args = d.console.formatArgs.apply(window,arguments); - d.console.addLine().attribute.addClass("Info").update(args); - d.console.scroll(); - } - }, - debug: function(_value){ - with(firebug){ - var args = d.console.formatArgs.apply(window,arguments); - d.console.addLine().attribute.addClass("Debug").update(args); - d.console.scroll(); - } - }, - error: function(_value){ - with(firebug){ - var args = d.console.formatArgs.apply(window,arguments); - d.console.addLine().attribute.addClass("Error").update(args); - d.console.scroll(); - } - }, - trace: function(_value){ - with(firebug){ - var stackAmt = 3, f = arguments.caller, isArray = lib.util.IsArray(f); //function that called trace - - if((!isArray&&f)||(isArray&&f.length>0)){ - d.console.addLine().attribute.addClass("Arrow").update(">>> console.trace(stack)"); - for(var i=0;i>> console.dir("+_value+")"); - d.dom.open(_value,d.console.addLine()); - } - }, - dirxml: function(){ - with(firebug){ - d.console.cmd.log.apply(this, arguments); - } - }, - time: function(_name){ - with(firebug){ - d.console.timeMap[_name] = new Date().getTime(); - } - }, - timeEnd: function(_name){ - with(firebug){ - if(_name in d.console.timeMap){ - var delta = new Date().getTime() - d.console.timeMap[_name], - args = d.console.formatArgs.apply(window,[_name+":", delta+"ms"]); - d.console.addLine().attribute.addClass("log").update(args); - delete d.console.timeMap[_name]; - } - } - }, - count: function(_name){ - with(firebug){ - if(!d.console.countMap[_name]) - d.console.countMap[_name] = 0; - d.console.countMap[_name]++; - d.console.cmd.log.apply(window, [_name, d.console.countMap[_name]]); - } - }, - group:function(){ - with(firebug){ - d.console.cmd.log.apply(this, ["console.group is not supported"]); - } - }, - groupEnd:function(){ - with(firebug){ - d.console.cmd.log.apply(this, ["console.groupEnd is not supported"]); - } - }, - profile:function(){ - with(firebug){ - d.console.cmd.log.apply(this, ["console.profile is not supported"]); - } - }, - profileEnd:function(){ - with(firebug){ - d.console.cmd.log.apply(this, ["console.profileEnd is not supported"]); - } - } - } - }, - css:{ - index:-1, - open:function(_index){ - with (firebug) { - var item = env.targetWindow.document.styleSheets[_index], - uri = item.href; - try { - var rules = item[lib.env.ie ? "rules" : "cssRules"], str = ""; - for (var i=0; i"; - for(var i=0,len=_css.length; i$1
$2;")+""; - } - str+="
}
"; - return str; - } - }, - refresh:function(){ - with(firebug){ - el.button.css.selectbox.update(""); - var collection = env.targetWindow.document.styleSheets; - for(var i=0,len=collection.length; inull"); - }else if (vtype=="regexp") { - result.push("" + _value + ""); - }else if (vtype=="date") { - result.push("'" + _value + "'"); - } else if (vtype=="boolean"||vtype=="number") { - result.push("" + _value + ""); - } else if(vtype=="function"){ - result.push("function()"); - } else { - result.push("\""+( !_inObject&&!_inArray?_value : _value.substring(0,35)+(_value.length>35?" ...":"") ).replace(/\n/g,"\\n").replace(/\s/g," ").replace(/>/g,">").replace(/"); - } - } - // element - else if(isElement){ - - if(_value.nodeType==3) - result.push(d.highlight(_value.nodeValue)); - else if(_inObject){ - result.push(""+_value.nodeName.toLowerCase()+""); - } else { - result.push(""); - - if(_inArray){ - result.push(_value.nodeName.toLowerCase()); - if(_value.getAttribute){ - if(_value.getAttribute&&_value.getAttribute("id")) - result.push("#"+_value.getAttribute("id")+""); - var elClass = _value.getAttribute(lib.env.ie&&!lib.env.ie8?"className":"class")||""; - result.push(!elClass?"":"."+elClass.split(" ")[0]+""); - } - result.push(""); - } else { - result.push("<"+ _value.nodeName.toLowerCase()); - - if(_value.attributes){ - for(var i=0,len=_value.attributes.length; i"+item.nodeName+"=\""+item.nodeValue+"\""); - } - } - - result.push(">"); - } - } - } - // array, hash - else if(isArray||isHash){ - if(isArray){ - if(_inObject){ - result.push("["+_value.length+"]"); - } else { - result.push("[ "); - - for(var i=0,len=_value.length; i3){ - result.push(", "+(len-4)+" More..."); - break; - } - result.push( (i > 0 ? ", " : "") + d.highlight(_value[i], false, true, true) ); - } - - result.push(" ]"); - } - } else if(_inObject){ - result.push("Object"); - } else { - result.push("Object"); - var i=0; - for(var key in _value){ - var value = _value[key]; - if((_inObject||_inArray)&&i>3){ - result.push(" More..."); - break; - } - result.push(" "+key+"="+d.highlight(value,true)); - i++; - } - result.push(""); - } - } else { - result.push([""+_value+""]); - } - } catch(e){ - result.push(".."); - } - return result.join(""); - } - }, - html:{ - nIndex:"computedStyle", - current:null, - highlight:function(_element,_clear,_event){ - with(firebug){ - if(_element.firebugElement){ - return; - } - if(_clear){ - env.targetWindow.firebug.el.bgInspector.environment.addStyle({ "display":"none" }); - return; - } - d.inspector.inspect(_element,true); - } - }, - inspect:function(_element){ - var map = [], - parentLayer, - t, - tagName, - parent = _element; - while (parent) { - map.push(parent); - if (parent == firebug.env.targetWindow.document.body) break; - parent = parent.parentNode; - } - map = map.reverse(); - with(firebug) { - if (env.dIndex != "html") { - env.targetWindow.firebug.d.navigate("html"); - } - - env.targetWindow.firebug.d.inspector.toggle(false); - - for (t = 0; t < el.left.html.container.child.get().length; t++) { - if (el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0]) { - if (el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].innerText) { - tagName = el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].innerText; - } else { - tagName = el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].textContent; - } - - if (/<html>").insert(parent); - }; - - for(var i=0; i<=len; i++){ - if(i==len){ - new lib.element("A").attribute.addClass("Block").update("</"+element.nodeName.toLowerCase()+">").insert(container); - break; - } - var item = element.childNodes[i]; - - if (item.nodeType != 3){ - var container = new lib.element().attribute.addClass("Block").insert(parent), - link = new lib.element("A").attribute.addClass("Link").insert(container), - spacer = new lib.element("SPAN").attribute.addClass("Spacer").update(" ").insert(link), - html = new lib.element("SPAN").attribute.addClass("Content").update(d.highlight(item)).insert(link), - subContainer = new lib.element("DIV").attribute.addClass("SubContainer").insert(container), - view = lib.util.Element.getView(item); - - link.event.addListener("click", lib.util.Curry(d.html.openHtmlTree, window, item, subContainer, false)); - link.event.addListener("mouseover", lib.util.Curry(d.html.highlight, window, item, false)); - link.event.addListener("mouseout", lib.util.Curry(d.html.highlight, window, item, true)); - - returnParentVal = returnParentEl == item ? subContainer : returnParentVal; - - if(d.html.current==null&&item==document.body){ - link.attribute.addClass("Selected"); - d.html.current = [item,link]; - d.html.openHtmlTree(item,subContainer); - } - - if(element.nodeName!="HEAD"&&element!=document.documentElement&&(view.visibility=="hidden"||view.display=="none")){ - container.attribute.addClass("Unvisible"); - }; - - if (item.childNodes){ - var childLen = item.childNodes.length; - if (childLen == 1 && item.childNodes[0].nodeType == 3) { - html.child.add(document.createTextNode(item.childNodes[0].nodeValue.substring(0, 50))); - html.child.add(document.createTextNode("")); - continue; - } - else - if (childLen > 0) { - link.attribute.addClass("Parent"); - } - } - } - }; - return returnParentVal; - } - }, - openProperties:function(){ - with(firebug){ - var index = d.html.nIndex; - var node = d.html.current[0]; - d.clean(el.right.html.content); - var str = ""; - switch(index){ - case "computedStyle": - var property = ["opacity","filter","azimuth","background","backgroundAttachment","backgroundColor","backgroundImage","backgroundPosition","backgroundRepeat","border","borderCollapse","borderColor","borderSpacing","borderStyle","borderTop","borderRight","borderBottom","borderLeft","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderWidth","bottom","captionSide","clear","clip","color","content","counterIncrement","counterReset","cue","cueAfter","cueBefore","cursor","direction","display","elevation","emptyCells","cssFloat","font","fontFamily","fontSize","fontSizeAdjust","fontStretch","fontStyle","fontVariant","fontWeight","height","left","letterSpacing","lineHeight","listStyle","listStyleImage","listStylePosition","listStyleType","margin","marginTop","marginRight","marginBottom","marginLeft","markerOffset","marks","maxHeight","maxWidth","minHeight","minWidth","orphans","outline","outlineColor","outlineStyle","outlineWidth","overflow","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","page","pageBreakAfter","pageBreakBefore","pageBreakInside","pause","pauseAfter","pauseBefore","pitch","pitchRange","playDuring","position","quotes","richness","right","size","speak","speakHeader","speakNumeral","speakPunctuation","speechRate","stress","tableLayout","textAlign","textDecoration","textIndent","textShadow","textTransform","top","unicodeBidi","verticalAlign","visibility","voiceFamily","volume","whiteSpace","widows","width","wordSpacing","zIndex"].sort(); - var view = document.defaultView?document.defaultView.getComputedStyle(node,null):node.currentStyle; - for(var i=0,len=property.length; i
"+d.highlight(view[item])+"
"; - } - el.right.html.content.update(str); - break; - case "dom": - d.dom.open(node,el.right.html.content,lib.env.ie); - break; - } - } - } - }, - inspector:{ - enabled:false, - el:null, - inspect:function(_element,_bgInspector){ - with(firebug){ - var pos = env.targetWindow.firebug.lib.util.Element.getPosition(_element); - - env.targetWindow.firebug.el[_bgInspector&&"bgInspector"||"borderInspector"].environment.addStyle({ - "width":_element.offsetWidth+"px", "height":_element.offsetHeight+"px", - "top":pos.offsetTop-(_bgInspector?0:2)+"px", "left":pos.offsetLeft-(_bgInspector?0:2)+"px", - "display":"block" - }); -9 - if(!_bgInspector){ - d.inspector.el = _element; - } - }; - }, - toggle:function(_absoluteValue,_event){ - with (firebug) { - if(_absoluteValue==d.inspector.enabled) - return; - d.inspector.enabled = _absoluteValue!=undefined&&!_absoluteValue.clientX?_absoluteValue:!d.inspector.enabled; - el.button.inspect.attribute[(d.inspector.enabled ? "add" : "remove") + "Class"]("Enabled"); - if(d.inspector.enabled==false){ - el.borderInspector.environment.addStyle({ "display":"none" }); - d.inspector.el = null; - } else if(lib.env.dIndex!="html") { - if (env.popupWin) { - env.popupWin.firebug.d.navigate("html"); - } else { - d.navigate("html"); - } - } - } - } - }, - scripts:{ - index:-1, - lineNumbers:false, - open:function(_index){ - with(firebug){ - d.scripts.index = _index; - el.left.scripts.container.update(""); - var script = document.getElementsByTagName("script")[_index],uri = script.src||document.location.href,source; - try { - if(uri!=document.location.href){ - source = env.cache[uri]||lib.xhr.get(uri).responseText; - env.cache[uri] = source; - } else { - source = script.innerHTML; - } - source = source.replace(/<|>/g,function(_ch){ - return ({"<":"<",">":">"})[_ch]; - }); - - if(!d.scripts.lineNumbers) - el.left.scripts.container.child.add( - new lib.element("DIV").attribute.addClass("CodeContainer").update(source) - ); - else { - source = source.split("
"); - for (var i = 0; i < source.length; i++) { - el.left.scripts.container.child.add(new lib.element("DIV").child.add(new lib.element("DIV").attribute.addClass("LineNumber").update(i + 1), new lib.element("DIV").attribute.addClass("Code").update(" " + source[i]), new lib.element("DIV").attribute.addClass('Clear'))); - }; - }; - } catch(e){ - el.left.scripts.container.child.add( - new lib.element("DIV").attribute.addClass("CodeContainer").update("Access to restricted URI denied") - ); - } - } - }, - toggleLineNumbers:function(){ - with(firebug){ - d.scripts.lineNumbers = !d.scripts.lineNumbers; - el.button.scripts.lineNumbers.attribute[(d.scripts.lineNumbers ? "add" : "remove") + "Class"]("Enabled"); - d.scripts.open( d.scripts.index ); - } - }, - refresh:function(){ - with(firebug){ - el.button.scripts.selectbox.clean(); - var collection = env.targetWindow.document.getElementsByTagName("script"); - for(var i=0,len=collection.length; i")) - } - } - }, - xhr:{ - objects:[], - addObject:function(){ - with(firebug){ - for(var i=0,len=arguments.length; i0&&_object[0]!=undefined&&_object[len-1]!=undefined){ - return true; - } else { - for(var key in _object){ - if(key!="item"&&key!="length"&&key!="setNamedItemNS"&&key!="setNamedItem"&&key!="getNamedItem"&&key!="removeNamedItem"&&key!="getNamedItemNS"&&key!="removeNamedItemNS"&&key!="tags"){ - return false; - } - } - return true - }; - }, - IsHash:function(_object){ - return _object && typeof _object=="object"&&(_object==window||_object instanceof Object)&&!_object.nodeName&&!pi.util.IsArray(_object) - }, - Init:[], - AddEvent: function(_element,_eventName,_fn,_useCapture){ - _element[pi.env.ie?"attachEvent":"addEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false); - return pi.util.Curry(pi.util.AddEvent,this,_element); - }, - RemoveEvent: function(_element,_eventName,_fn,_useCapture){ - _element[pi.env.ie?"detachEvent":"removeEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false); - return pi.util.Curry(pi.util.RemoveEvent,this,_element); - }, - Element:{ - addClass:function(_element,_class){ - if( !pi.util.Element.hasClass(_element,_class) ) - pi.util.Element.setClass(_element, pi.util.Element.getClass(_element) + " " + _class ); - }, - getClass:function(_element){ - return _element.getAttribute(pi.env.ie&&!pi.env.ie8?"className":"class")||""; - }, - hasClass:function(_element,_class){ - return pi.util.Array.indexOf(pi.util.Element.getClass(_element).split(" "),_class)>-1; - }, - removeClass:function(_element,_class){ - if( pi.util.Element.hasClass(_element,_class) ){ - var names = pi.util.Element.getClass(_element,_class).split(" "); - pi.util.Element.setClass( - _element, - pi.util.Array.remove(names,pi.util.Array.indexOf(names,_class)).join(" ") - ); - } - }, - setClass:function(_element,_value){ - if(pi.env.ie8){ - _element.setAttribute("className", _value ); - _element.setAttribute("class", _value ); - } else { - _element.setAttribute(pi.env.ie?"className":"class", _value ); - } - }, - toggleClass:function(){ - if(pi.util.Element.hasClass.apply(this,arguments)) - pi.util.Element.removeClass.apply(this,arguments); - else - pi.util.Element.addClass.apply(this,arguments); - }, - getOpacity:function(_styleObject){ - var styleObject = _styleObject; - if(!pi.env.ie) - return styleObject["opacity"]; - - var alpha = styleObject["filter"].match(/opacity\=(\d+)/i); - return alpha?alpha[1]/100:1; - }, - setOpacity:function(_element,_value){ - if(!pi.env.ie) - return pi.util.Element.addStyle(_element,{ "opacity":_value }); - _value*=100; - pi.util.Element.addStyle(_element,{ "filter":"alpha(opacity="+_value+")" }); - return this._parent_; - }, - getPosition:function(_element){ - var parent = _element,offsetLeft = document.body.offsetLeft, offsetTop = document.body.offsetTop, view = pi.util.Element.getView(_element); - while(parent&&parent!=document.body&&parent!=document.firstChild){ - offsetLeft +=parseInt(parent.offsetLeft); - offsetTop += parseInt(parent.offsetTop); - parent = parent.offsetParent; - }; - return { - "bottom":view["bottom"], - "clientLeft":_element.clientLeft, - "clientTop":_element.clientTop, - "left":view["left"], - "marginTop":view["marginTop"], - "marginLeft":view["marginLeft"], - "offsetLeft":offsetLeft, - "offsetTop":offsetTop, - "position":view["position"], - "right":view["right"], - "top":view["top"], - "zIndex":view["zIndex"] - }; - }, - getSize:function(_element){ - var view = pi.util.Element.getView(_element); - return { - "height":view["height"], - "clientHeight":_element.clientHeight, - "clientWidth":_element.clientWidth, - "offsetHeight":_element.offsetHeight, - "offsetWidth":_element.offsetWidth, - "width":view["width"] - } - }, - addStyle:function(_element,_style){ - for(var key in _style){ - key = key=="float"?pi.env.ie?"styleFloat":"cssFloat":key; - if (key == "opacity" && pi.env.ie) { - pi.util.Element.setOpacity(_element,_style[key]); - continue; - } - try { - _element.style[key] = _style[key]; - }catch(e){} - } - }, - getStyle:function(_element,_property){ - _property = _property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property; - if(_property=="opacity"&&pi.env.ie) - return pi.util.Element.getOpacity(_element.style); - return typeof _property=="string"?_element.style[_property]:_element.style; - }, - getValue:function(_element){ - switch(_element.nodeName.toLowerCase()){ - case "input": - case "textarea": - return _element.value; - case "select": - return _element.options[_element.selectedIndex].value; - default: - return _element.innerHTML; - break; - } - }, - getView:function(_element,_property){ - var view = document.defaultView?document.defaultView.getComputedStyle(_element,null):_element.currentStyle; - _property = _property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property; - if(_property=="opacity"&&pi.env.ie) - return pi.util.Element.getOpacity(_element,view); - return typeof _property=="string"?view[_property]:view; - } - }, - Hash: { - clone:function(_hash,_undeep){ - var tmp = {}; - for(var key in _hash){ - if( !_undeep&&pi.util.IsArray( _hash[key] ) ){ - tmp[key] = pi.util.Array.clone( _hash[key] ); - } else if( !_undeep&&pi.util.IsHash( _hash[key] ) ){ - tmp[ key ] = pi.util.Hash.clone(_hash[key]); - } else { - tmp[key] = _hash[key]; - } - } - return tmp; - }, - merge:function(_hash,_source,_undeep){ - for(var key in _source){ - var value = _source[key]; - if (!_undeep&&pi.util.IsArray(_source[key])) { - if(pi.util.IsArray( _hash[key] )){ - Array.prototype.push.apply( _source[key], _hash[key] ) - } - else - value = pi.util.Array.clone(_source[key]); - } - else if (!_undeep&&pi.util.IsHash(_source[key])) { - if (pi.util.IsHash(_hash[key])) { - value = pi.util.Hash.merge(_hash[key], _source[key]); - } else { - value = pi.util.Hash.clone( _source[key] ); - } - } else if( _hash[key] ) - value = _hash[ key ]; - _hash[key] = value; - }; - return _hash; - } - }, - String:{ - format:function(_str){ - var values = Array.prototype.slice.call(arguments,1); - return _str.replace(/\{(\d)\}/g,function(){ - return values[arguments[1]]; - }) - } - }, - GetViewport:function(){ - return { - height:document.documentElement.clientHeight||document.body.clientHeight, - width:document.documentElement.clientWidth||document.body.clientWidth - } - } - }; - - pi.base = function(){ - this.body = {}; - this.init = null; - - this.build = function(_skipClonning){ - var base = this, skipClonning = _skipClonning||false, _private = {}, - fn = function(){ - var _p = pi.util.Hash.clone(_private); - if(!skipClonning){ - for(var key in this){ - if(pi.util.IsArray( this[ key ] ) ){ - this[key] = pi.util.Array.clone( this[key] ); - } else - if( pi.util.IsHash(this[key]) ){ - this[key] = pi.util.Hash.clone( - this[ key ], - function(_key,_object){ - this[ _key ]._parent_ = this; - } - ); - //this[key]._parent_ = this; - } - } - }; - base.createAccessors( _p, this ); - if(base.init) - return base.init.apply(this,arguments); - return this; - }; - this.movePrivateMembers(this.body,_private); - if(this.init){ - fn["$Init"] = this.init; - }; - fn.prototype = this.body; - return fn; - }; - - this.createAccessors = function(_p, _branch){ - var getter = function(_property){ return this[_property]; }, - setter = function(_property,_value){ this[_property] = _value; return _branch._parent_||_branch; }; - - for (var name in _p) { - var isPrivate = name.substring(0, 1) == "_", title = name.substring(1, 2).toUpperCase() + name.substring(2); - - if (isPrivate) { - _branch[(_branch["get" + title]?"_":"")+"get" + title] = pi.util.Curry(getter,_p,name); - _branch[(_branch["set" + title]?"_":"")+"set" + title] = pi.util.Curry(setter,_p,name); - } - else - if (pi.util.IsHash(_p[name])){ - _branch[name]._parent_ = _branch; - if(!_branch[name]) - _branch[name] = {}; - this.createAccessors(_p[name], _branch[name]); - } - }; - }; - - this.movePrivateMembers = function(_object, _branch){ - for (var name in _object) { - var isPrivate = name.substring(0, 1) == "_"; - - if (isPrivate) { - _branch[name] = _object[name]; - delete _object[name]; - } - else - if (pi.util.IsHash(_object[name])){ - _branch[name] = {}; - this.movePrivateMembers(_object[name], _branch[name]); - } - }; - }; - }; - - pi.element = new pi.base; - pi.element.init = function(_val){ - this.environment.setElement( - typeof _val=="string"||!_val? - document.createElement(_val||"DIV"): - _val - ); - return this; - }; - - pi.element.body = { - "addStyle":function(){ - return this.environment.addStyle.apply(this.environment,arguments); - }, - "clean":function(){ - var childs = this.child.get(); - while(childs.length){ - childs[0].parentNode.removeChild(childs[0]); - } - }, - "clone":function(_deep){ - return this.environment.getElement().cloneNode(_deep); - }, - "insert":function(_element){ - _element = _element.environment?_element.environment.getElement():_element; - _element.appendChild(this.environment.getElement()); - return this; - }, - "insertAfter":function(_referenceElement){ - _referenceElement = _referenceElement.environment?_referenceElement.environment.getElement():_referenceElement; - _referenceElement.nextSibling?this.insertBefore(_referenceElement.nextSibling):this.insert(_referenceElement.parentNode); - return this; - }, - "insertBefore":function(_referenceElement){ - _referenceElement = _referenceElement.environment?_referenceElement.environment.getElement():_referenceElement; - _referenceElement.parentNode.insertBefore(this.environment.getElement(),_referenceElement); - return this; - }, - "query":function(_expression,_resultType,namespaceResolver,_result){ - return pi.xpath(_expression,_resultType||"ORDERED_NODE_SNAPSHOT_TYPE",this.environment.getElement(),_namespaceResolver,_result); - }, - "remove":function(){ - if (this.environment.getParent()) { - this.environment.getParent().removeChild(this.environment.getElement()); - } - }, - "update":function(_value){ - this.element[this.element.nodeName.toLowerCase()=="textarea"||this.element.nodeName.toLowerCase()=="input"?"value":"innerHTML"]=_value; - return this; - }, - "attribute":{ - "getAll":function(){ - return this._parent_.environment.getElement().attributes; - }, - "clear":function(_name){ - this.set(_name,""); - return this._parent_; - }, - "get":function(_name){ - return this._parent_.environment.getElement().getAttribute(_name); - }, - "has":function(_name){ - return pi.env.ie?(this.get(_name)!=null):this._parent_.environment.getElement().hasAttribute(_name); - }, - "remove":function(_name){ - this._parent_.environment.getElement().removeAttribute(_name); - return this._parent_; - }, - "set":function(_name,_value){ - this._parent_.environment.getElement().setAttribute(_name,_value); - return this._parent_; - }, - "addClass":function(_classes){ - for(var i=0,len=arguments.length; i-1){ - callback[i].fn.apply(this); - } - } - } - }; - pi.xhr = pi.xhr.build(); - - /* - * xml.xhr.get - */ - - pi.xhr.get = function(_url,_returnPiObject){ - var request = new pi.xhr(); - request.environment.setAsync(false); - request.environment.setUrl(_url); - request.send(); - return _returnPiObject?request:request.environment.getApi(); - }; - - /* - * registering onload event for init functions - */ - pi.util.AddEvent( - pi.env.ie?window:document, - pi.env.ie?"load":"DOMContentLoaded", - function(){ - for(var i=0,len=pi.util.Init.length; i>>") + ); + el.left.console.input = new lib.element("INPUT").attribute.set("type","text").attribute.addClass("Input").event.addListener("keydown",listen.consoleTextbox).insert( + new lib.element("DIV").attribute.addClass("InputContainer").insert(el.left.console.container) + ); + + el.right.console = {}; + el.right.console.container = new lib.element("DIV").attribute.addClass("Console Container").insert(el.right.container); + el.right.console.mlButton = new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.console.container); + el.right.console.input = new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.console.container); + el.right.console.input.event.addListener("keydown",lib.util.Curry(tab,window,el.right.console.input.element)); + el.right.console.run = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runMultiline).update("Run").insert(el.right.console.container); + el.right.console.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.console.input)).update("Clear").insert(el.right.console.container); + + el.button.console = {}; + el.button.console.container = new lib.element("DIV").attribute.addClass("ButtonSet").insert(el.button.container); + el.button.console.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",d.console.clear).update("Clear").insert(el.button.console.container); + + /* + * html + */ + + el.left.html = {}; + el.left.html.container = new lib.element("DIV").attribute.addClass("HTML").insert(el.left.container); + + el.right.html = {}; + el.right.html.container = new lib.element("DIV").attribute.addClass("HTML Container").insert(el.right.container); + + el.right.html.nav = {}; + el.right.html.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.right.html.container); + el.right.html.nav.computedStyle = new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"computedStyle")).update("Computed Style").insert(el.right.html.nav.container); + el.right.html.nav.dom = new lib.element("A").attribute.addClass("Tab").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"dom")).update("DOM").insert(el.right.html.nav.container); + + el.right.html.content = new lib.element("DIV").attribute.addClass("Content").insert(el.right.html.container); + + el.button.html = {}; + el.button.html.container = new lib.element("DIV").attribute.addClass("ButtonSet HTML").insert(el.button.container); + + /* + * css + */ + + el.left.css = {}; + el.left.css.container = new lib.element("DIV").attribute.addClass("CSS").insert(el.left.container); + + el.right.css = {}; + el.right.css.container = new lib.element("DIV").attribute.addClass("CSS Container").insert(el.right.container); + + el.right.css.nav = {}; + el.right.css.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.right.css.container); + el.right.css.nav.runCSS = new lib.element("A").attribute.addClass("Tab Selected").update("Run CSS").insert(el.right.css.nav.container); + + el.right.css.mlButton = new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.css.container); + el.right.css.input = new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.css.container); + el.right.css.input.event.addListener("keydown",lib.util.Curry(firebug.tab,window,el.right.css.input.element)); + el.right.css.run = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runCSS).update("Run").insert(el.right.css.container); + el.right.css.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.css.input)).update("Clear").insert(el.right.css.container); + + el.button.css = {}; + el.button.css.container = new lib.element("DIV").attribute.addClass("ButtonSet CSS").insert(el.button.container); + el.button.css.selectbox = new lib.element("SELECT").event.addListener("change",listen.cssSelectbox).insert(el.button.css.container); + + /* + * scripts + */ + + el.left.scripts = {}; + el.left.scripts.container = new lib.element("DIV").attribute.addClass("Scripts").insert(el.left.container); + + el.right.scripts = {}; + el.right.scripts.container = new lib.element("DIV").attribute.addClass("Scripts Container").insert(el.right.container); + + el.button.scripts = {}; + el.button.scripts.container = new lib.element("DIV").attribute.addClass("ButtonSet Scripts").insert(el.button.container); + el.button.scripts.selectbox = new lib.element("SELECT").event.addListener("change",listen.scriptsSelectbox).insert(el.button.scripts.container); + el.button.scripts.lineNumbers = new lib.element("A").attribute.addClass("Button").event.addListener("click",d.scripts.toggleLineNumbers).update("Show Line Numbers").insert(el.button.scripts.container); + + /* + * dom + */ + + el.left.dom = {}; + el.left.dom.container = new lib.element("DIV").attribute.addClass("DOM").insert(el.left.container); + + el.right.dom = {}; + el.right.dom.container = new lib.element("DIV").attribute.addClass("DOM Container").insert(el.right.container); + + el.button.dom = {}; + el.button.dom.container = new lib.element("DIV").attribute.addClass("ButtonSet DOM").insert(el.button.container); + el.button.dom.label = new lib.element("LABEL").update("Object Path:").insert(el.button.dom.container); + el.button.dom.textbox = new lib.element("INPUT").event.addListener("keydown",listen.domTextbox).update(env.isPopup?"window.opener":"window").insert(el.button.dom.container); + + /* + * str + */ + el.left.str = {}; + el.left.str.container = new lib.element("DIV").attribute.addClass("STR").insert(el.left.container); + + el.right.str = {}; + el.right.str.container = new lib.element("DIV").attribute.addClass("STR").insert(el.left.container); + + el.button.str = {}; + el.button.str.container = new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container); + el.button.str.watch = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).update("Back").insert(el.button.str.container); + + /* + * xhr + */ + el.left.xhr = {}; + el.left.xhr.container = new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container); + + el.right.xhr = {}; + el.right.xhr.container = new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container); + + + el.button.xhr = {}; + el.button.xhr.container = new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container); + el.button.xhr.label = new lib.element("LABEL").update("XHR Path:").insert(el.button.xhr.container); + el.button.xhr.textbox = new lib.element("INPUT").event.addListener("keydown",listen.xhrTextbox).insert(el.button.xhr.container); + el.button.xhr.watch = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.addXhrObject).update("Watch").insert(el.button.xhr.container); + + /* + * settings + */ + el.settings = {}; + el.settings.container = new lib.element("DIV").child.add( + new lib.element("DIV").attribute.addClass("Header").child.add( + new lib.element().attribute.addClass("Title").update('Firebug Lite Settings') + ) + ).attribute.addClass("SettingsDiv").insert(el.main); + el.settings.content = new lib.element("DIV").attribute.addClass("Content").insert(el.settings.container); + el.settings.progressDiv = new lib.element("DIV").attribute.addClass("ProgressDiv").insert(el.settings.content); + el.settings.progress = new lib.element("DIV").attribute.addClass("Progress").insert(el.settings.progressDiv); + el.settings.cbxDebug = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); + el.settings.content.child.add(document.createTextNode("Start visible")); + new lib.element("BR").insert(el.settings.content); + el.settings.cbxDetectFirebug = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); + el.settings.content.child.add(document.createTextNode("Hide when Firebug active")); + new lib.element("BR").insert(el.settings.content); + el.settings.cbxHideDOMFunctions = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); + el.settings.content.child.add(document.createTextNode("Hide DOM functions")); + new lib.element("BR").insert(el.settings.content); + el.settings.cbxOverride = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); + el.settings.content.child.add(document.createTextNode("Override window.console")); + new lib.element("BR").insert(el.settings.content); + el.settings.cbxShowIcon = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); + el.settings.content.child.add(document.createTextNode("Show icon when hidden")); + new lib.element("BR").insert(el.settings.content); + el.settings.cbxOpenInPopup = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content); + el.settings.content.child.add(document.createTextNode("Open in popup")); + el.settings.buttonDiv = new lib.element("DIV").insert(el.settings.content); + el.settings.buttonLeftDiv = new lib.element("DIV").attribute.addClass("ButtonsLeft").insert(el.settings.buttonDiv); + el.settings.resetButton = new lib.element("INPUT").attribute.set("type","button").update("Reset").event.addListener("click",settings.reset).insert(el.settings.buttonLeftDiv); + el.settings.buttonRightDiv = new lib.element("DIV").attribute.addClass("ButtonsRight").insert(el.settings.buttonDiv); + el.settings.cancelButton = new lib.element("INPUT").attribute.set("type","button").update("Cancel").event.addListener("click",settings.hide).insert(el.settings.buttonRightDiv); + el.settings.buttonRightDiv.child.add(document.createTextNode(" ")); + el.settings.saveButton = new lib.element("INPUT").attribute.set("type","button").update("Save").event.addListener("click",settings.saveClicked).insert(el.settings.buttonRightDiv); + + lib.util.AddEvent(document,"mousemove",listen.mouse)("mousemove",win.resizer.resize)("mouseup",win.resizer.stop)("keydown",listen.keyboard); + + env.init = true; + + for(var i=0, len=d.console.cache.length; i0) { + cookieArr=targetWindow.document.cookie.split('; '); + + for(i=0;i -1) { + scriptPath = scripts[i].src; + break; + } + } + + if (scriptPath) { + script = fe.popupWin.document.createElement('script'), done = false; + script.type = 'text/javascript'; + script.src = scriptPath; + + script[firebug.lib.env.ie?"onreadystatechange":"onload"] = function(){ + if(!done && (!firebug.lib.env.ie || this.readyState == "complete" || this.readyState=="loaded")){ + done = true; + if(fe.popupWin.firebug) { + with(fe.popupWin.firebug) { + env.isPopup = true; + env.css = fe.css; + init(); + el.button.dock.environment.addStyle({ "display": "block"}); + el.button.newWindow.environment.addStyle({ "display": "none"}); + } + } + } + }; + + if (!done && firebug.lib.env.webkit) { + fe.popupWin.document.write(''); + interval = setInterval(function() { + if (fe.popupWin.firebug) { + clearInterval(interval); + done = true; + with(fe.popupWin.firebug) { + env.isPopup = true; + env.css = fe.css; + init(); + el.button.dock.environment.addStyle({ "display": "block"}); + el.button.newWindow.environment.addStyle({ "display": "none"}); + } + } + }, 10); + }; + + if (!done) { + fe.popupWin.document.getElementsByTagName('head')[0].appendChild(script); + firebug.el.main.environment.addStyle({"display": "none"}); + firebug.el.mainiframe.environment.addStyle({"display": "none"}); + } + } else { + alert("Unable to detect the following script \"" + fe.liteFilename + + "\" ... if the script has been renamed then please set the value of firebug.env.liteFilename to reflect this change"); + fe.popupWin.close(); + fe.popupWin=null; + } + } + } + }, + dock: function() { + with(opener.firebug) { + env.popupWin = null; + el.main.environment.addStyle({ + "display": "block" + }); + el.mainiframe.environment.addStyle({ + "display": "block" + }); + settings.readCookie(); + window.close(); + }; + }, + unload: function() { + with(firebug){ + if(env.isPopup) { + win.dock(); + } else if(env.popupWin) { + env.popupWin.close(); + } + } + }, + fitToPopup: function() { + with(firebug) { + var viewport = lib.util.GetViewport(window); + win.setHeight((window.innerHeight||viewport.height) - 38); + el.main.environment.addStyle({ + "width": (viewport.width) + "px" + }); + el.mainiframe.environment.addStyle({ + "width": (viewport.width) + "px" + }); + } + }, + resizer:{ + y:[], enabled:false, + start:function(_event){ + with(firebug){ + if(env.minimized)return; + win.resizer.y=[el.main.element.offsetHeight,_event.clientY]; + if(lib.env.ie6){ + win.resizer.y[3]=parseInt(el.main.environment.getPosition().top); + } + win.resizer.enabled=true; + } + }, + resize:function(_event){ + with(firebug){ + if(!win.resizer.enabled)return; + win.resizer.y[2]=(win.resizer.y[0]+(win.resizer.y[1]-_event.clientY)); + el.main.environment.addStyle({ "height":win.resizer.y[2]+"px" }); + el.mainiframe.environment.addStyle({ "height":win.resizer.y[2]+"px" }); + if(lib.env.ie6){ + el.main.environment.addStyle({ "top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px" }); + el.mainiframe.environment.addStyle({ "top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px" }); + } + } + }, + stop:function(_event){ + with(firebug){ + if(win.resizer.enabled){ + win.resizer.enabled=false; + win.setHeight(win.resizer.y[2]-35); + } + } + } + }, + setHeight:function(_height){ + with(firebug){ + env.height=_height; + + el.left.container.environment.addStyle({ "height":_height+"px" }); + el.right.container.environment.addStyle({ "height":_height+"px" }); + el.main.environment.addStyle({ "height":_height+38+"px" }); + el.mainiframe.environment.addStyle({ "height":_height+38+"px" }); + + win.refreshSize(); + + // console + el.left.console.monitor.element.parentNode.style.height=_height-47+"px"; + el.left.console.mlButton.environment.addStyle({ "top":_height+19+"px" }); + el.right.console.mlButton.environment.addStyle({ "top":_height+19+"px" }); + el.right.console.input.environment.addStyle({ "height":_height-29+"px" }); + + // html + el.left.html.container.environment.addStyle({"height":_height-23+"px"}); + el.right.html.content.environment.addStyle({"height":_height-23+"px"}); + + // css + el.left.css.container.environment.addStyle({"height":_height-33+"px"}); + el.right.css.input.environment.addStyle({ "height":_height-55+"px" }); + + // script + el.left.scripts.container.environment.addStyle({"height":_height-23+"px"}); + + // dom + el.left.dom.container.environment.addStyle({"height":_height-31+"px"}); + + // xhr + el.left.xhr.container.environment.addStyle({"height":_height-32+"px"}); + + // string + el.left.str.container.environment.addStyle({"height":_height-32+"px"}); + } + }, + refreshDOM:function(){ + with(firebug){ + d.dom.open(eval(el.button.dom.textbox.environment.getElement().value),el.left.dom.container); + if(d.html.nIndex=="dom"){ + firebug.d.html.navigate("dom") + } + } + }, + refreshSize:function(){ + with(firebug){ + if(!env.init) + return; + + var dim = lib.util.GetViewport(); + el.main.environment.addStyle({ "width":dim.width+"px"}); + el.mainiframe.environment.addStyle({ "width":dim.width+"px"}); + if(lib.env.ie6) + win.setVerticalPosition(dim); + } + }, + setVerticalPosition:function(_dim,_event){ + with(firebug){ + var dim = _dim||lib.util.GetViewport(); + el.main.environment.addStyle({ "top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px" }); + el.mainiframe.environment.addStyle({ "top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px" }); + } + } + }, + d: { + clean:function(_element){ + with(firebug){ + _element.update(""); + } + }, + console:{ + addLine:function(){ + with (firebug) { + return new lib.element("DIV").attribute.addClass("Row").insert(el.left.console.monitor); + } + }, + cache:[], + clear:function(){ + with(firebug){ + d.clean(el.left.console.monitor); + d.console.cache = []; + } + }, + formatArgs:function(){ + with(firebug){ + var content = []; + for(var i=0, len=arguments.length; i>> "+_cmd); + d.console.addLine().update(d.highlight(_text,false,false,true)); + d.console.scroll(); + } + }, + printException: function(_exception){ + with(firebug){ + var message = _exception.description||_exception.message||_exception; + if(_exception.fileName){ + message+=' ('+(_exception.name&&(_exception.name+', ')||'')+getFileName(_exception.fileName)+', '+_exception.lineNumber+')'; + } + d.console.addLine().attribute.addClass("Error").update("Error: "+message,true); + } + }, + eval:function(_cmd){ + var result; + with(firebug){ + if(_cmd.length==0) + return; + + el.left.console.input.environment.getElement().value = ""; + d.console.historyIndex = d.console.history.push(_cmd); + + try { + if(_cmd==='console.firebug') { + d.console.addLine().attribute.addClass("Arrow").update(firebug.version); + } else { + result = eval.call(window,_cmd); + d.console.print(_cmd,result); + } + } catch(e){ + d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd); + d.console.printException(e); + } + d.console.scroll(); + } + }, + scroll:function(){ + with(firebug){ + el.left.console.monitor.environment.getElement().parentNode.scrollTop = Math.abs(el.left.console.monitor.environment.getSize().offsetHeight-(el.left.console.monitor.element.parentNode.offsetHeight-11)); + } + }, + run:function(_command){ + with(firebug){ + if(!env.init){ + d.console.cache.push({ "command":_command, "arg":Array.prototype.slice.call(arguments,1) }); + } else { + d.console.cmd[_command].apply(window,Array.prototype.slice.call(arguments,1)); + } + } + }, + toggleML:function(){ + with(firebug){ + var open = !env.ml; + env.ml = !env.ml; + d.navigateRightColumn("console",open); + el[open?"left":"right"].console.mlButton.environment.addStyle({ display:"none" }); + el[!open?"left":"right"].console.mlButton.environment.addStyle({ display:"block" }); + el.left.console.mlButton.attribute[(open?"add":"remove")+"Class"]("CloseML"); + } + }, + countMap:{}, timeMap: {}, + cmd:{ + log: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Log").update(args); + d.console.scroll(); + } + }, + warn: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Warn").update(args); + d.console.scroll(); + } + }, + info: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Info").update(args); + d.console.scroll(); + } + }, + debug: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Debug").update(args); + d.console.scroll(); + } + }, + error: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Error").update(args); + d.console.scroll(); + } + }, + trace: function(_value){ + with(firebug){ + var stackAmt = 3, f = arguments.caller, isArray = lib.util.IsArray(f); //function that called trace + + if((!isArray&&f)||(isArray&&f.length>0)){ + d.console.addLine().attribute.addClass("Arrow").update(">>> console.trace(stack)"); + for(var i=0;i>> console.dir("+_value+")"); + d.dom.open(_value,d.console.addLine()); + } + }, + dirxml: function(){ + with(firebug){ + d.console.cmd.log.apply(this, arguments); + } + }, + time: function(_name){ + with(firebug){ + d.console.timeMap[_name] = new Date().getTime(); + } + }, + timeEnd: function(_name){ + with(firebug){ + if(_name in d.console.timeMap){ + var delta = new Date().getTime() - d.console.timeMap[_name], + args = d.console.formatArgs.apply(window,[_name+":", delta+"ms"]); + d.console.addLine().attribute.addClass("log").update(args); + delete d.console.timeMap[_name]; + } + } + }, + count: function(_name){ + with(firebug){ + if(!d.console.countMap[_name]) + d.console.countMap[_name] = 0; + d.console.countMap[_name]++; + d.console.cmd.log.apply(window, [_name, d.console.countMap[_name]]); + } + }, + group:function(){ + with(firebug){ + d.console.cmd.log.apply(this, ["console.group is not supported"]); + } + }, + groupEnd:function(){ + with(firebug){ + d.console.cmd.log.apply(this, ["console.groupEnd is not supported"]); + } + }, + profile:function(){ + with(firebug){ + d.console.cmd.log.apply(this, ["console.profile is not supported"]); + } + }, + profileEnd:function(){ + with(firebug){ + d.console.cmd.log.apply(this, ["console.profileEnd is not supported"]); + } + } + } + }, + css:{ + index:-1, + open:function(_index){ + with (firebug) { + var item = env.targetWindow.document.styleSheets[_index], + uri = item.href; + try { + var rules = item[lib.env.ie ? "rules" : "cssRules"], str = ""; + for (var i=0; i"; + for(var i=0,len=_css.length; i$1
$2;")+""; + } + str+="
}
"; + return str; + } + }, + refresh:function(){ + with(firebug){ + el.button.css.selectbox.update(""); + var collection = env.targetWindow.document.styleSheets; + for(var i=0,len=collection.length; inull"); + }else if (vtype=="regexp") { + result.push("" + _value + ""); + }else if (vtype=="date") { + result.push("'" + _value + "'"); + } else if (vtype=="boolean"||vtype=="number") { + result.push("" + _value + ""); + } else if(vtype=="function"){ + result.push("function()"); + } else { + result.push("\""+( !_inObject&&!_inArray?_value : _value.substring(0,35)+(_value.length>35?" ...":"") ).replace(/\n/g,"\\n").replace(/\s/g," ").replace(/>/g,">").replace(/"); + } + } + // element + else if(isElement){ + + if(_value.nodeType==3) + result.push(d.highlight(_value.nodeValue)); + else if(_inObject){ + result.push(""+_value.nodeName.toLowerCase()+""); + } else { + result.push(""); + + if(_inArray){ + result.push(_value.nodeName.toLowerCase()); + if(_value.getAttribute){ + if(_value.getAttribute&&_value.getAttribute("id")) + result.push("#"+_value.getAttribute("id")+""); + var elClass = _value.getAttribute(lib.env.ie&&!lib.env.ie8?"className":"class")||""; + result.push(!elClass?"":"."+elClass.split(" ")[0]+""); + } + result.push(""); + } else { + result.push("<"+ _value.nodeName.toLowerCase()); + + if(_value.attributes){ + for(var i=0,len=_value.attributes.length; i"+item.nodeName+"=\""+item.nodeValue+"\""); + } + } + + result.push(">"); + } + } + } + // array, hash + else if(isArray||isHash){ + if(isArray){ + if(_inObject){ + result.push("["+_value.length+"]"); + } else { + result.push("[ "); + + for(var i=0,len=_value.length; i3){ + result.push(", "+(len-4)+" More..."); + break; + } + result.push( (i > 0 ? ", " : "") + d.highlight(_value[i], false, true, true) ); + } + + result.push(" ]"); + } + } else if(_inObject){ + result.push("Object"); + } else { + result.push("Object"); + var i=0; + for(var key in _value){ + var value = _value[key]; + if((_inObject||_inArray)&&i>3){ + result.push(" More..."); + break; + } + result.push(" "+key+"="+d.highlight(value,true)); + i++; + } + result.push(""); + } + } else { + result.push([""+_value+""]); + } + } catch(e){ + result.push(".."); + } + return result.join(""); + } + }, + html:{ + nIndex:"computedStyle", + current:null, + highlight:function(_element,_clear,_event){ + with(firebug){ + if(_element.firebugElement){ + return; + } + if(_clear){ + env.targetWindow.firebug.el.bgInspector.environment.addStyle({ "display":"none" }); + return; + } + d.inspector.inspect(_element,true); + } + }, + inspect:function(_element){ + var map = [], + parentLayer, + t, + tagName, + parent = _element; + while (parent) { + map.push(parent); + if (parent == firebug.env.targetWindow.document.body) break; + parent = parent.parentNode; + } + map = map.reverse(); + with(firebug) { + if (env.dIndex != "html") { + env.targetWindow.firebug.d.navigate("html"); + } + + env.targetWindow.firebug.d.inspector.toggle(false); + + for (t = 0; t < el.left.html.container.child.get().length; t++) { + if (el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0]) { + if (el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].innerText) { + tagName = el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].innerText; + } else { + tagName = el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].textContent; + } + + if (/<html>").insert(parent); + }; + + for(var i=0; i<=len; i++){ + if(i==len){ + new lib.element("A").attribute.addClass("Block").update("</"+element.nodeName.toLowerCase()+">").insert(container); + break; + } + var item = element.childNodes[i]; + + if (item.nodeType != 3){ + var container = new lib.element().attribute.addClass("Block").insert(parent), + link = new lib.element("A").attribute.addClass("Link").insert(container), + spacer = new lib.element("SPAN").attribute.addClass("Spacer").update(" ").insert(link), + html = new lib.element("SPAN").attribute.addClass("Content").update(d.highlight(item)).insert(link), + subContainer = new lib.element("DIV").attribute.addClass("SubContainer").insert(container), + view = lib.util.Element.getView(item); + + link.event.addListener("click", lib.util.Curry(d.html.openHtmlTree, window, item, subContainer, false)); + link.event.addListener("mouseover", lib.util.Curry(d.html.highlight, window, item, false)); + link.event.addListener("mouseout", lib.util.Curry(d.html.highlight, window, item, true)); + + returnParentVal = returnParentEl == item ? subContainer : returnParentVal; + + if(d.html.current==null&&item==document.body){ + link.attribute.addClass("Selected"); + d.html.current = [item,link]; + d.html.openHtmlTree(item,subContainer); + } + + if(element.nodeName!="HEAD"&&element!=document.documentElement&&(view.visibility=="hidden"||view.display=="none")){ + container.attribute.addClass("Unvisible"); + }; + + if (item.childNodes){ + var childLen = item.childNodes.length; + if (childLen == 1 && item.childNodes[0].nodeType == 3) { + html.child.add(document.createTextNode(item.childNodes[0].nodeValue.substring(0, 50))); + html.child.add(document.createTextNode("")); + continue; + } + else + if (childLen > 0) { + link.attribute.addClass("Parent"); + } + } + } + }; + return returnParentVal; + } + }, + openProperties:function(){ + with(firebug){ + var index = d.html.nIndex; + var node = d.html.current[0]; + d.clean(el.right.html.content); + var str = ""; + switch(index){ + case "computedStyle": + var property = ["opacity","filter","azimuth","background","backgroundAttachment","backgroundColor","backgroundImage","backgroundPosition","backgroundRepeat","border","borderCollapse","borderColor","borderSpacing","borderStyle","borderTop","borderRight","borderBottom","borderLeft","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderWidth","bottom","captionSide","clear","clip","color","content","counterIncrement","counterReset","cue","cueAfter","cueBefore","cursor","direction","display","elevation","emptyCells","cssFloat","font","fontFamily","fontSize","fontSizeAdjust","fontStretch","fontStyle","fontVariant","fontWeight","height","left","letterSpacing","lineHeight","listStyle","listStyleImage","listStylePosition","listStyleType","margin","marginTop","marginRight","marginBottom","marginLeft","markerOffset","marks","maxHeight","maxWidth","minHeight","minWidth","orphans","outline","outlineColor","outlineStyle","outlineWidth","overflow","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","page","pageBreakAfter","pageBreakBefore","pageBreakInside","pause","pauseAfter","pauseBefore","pitch","pitchRange","playDuring","position","quotes","richness","right","size","speak","speakHeader","speakNumeral","speakPunctuation","speechRate","stress","tableLayout","textAlign","textDecoration","textIndent","textShadow","textTransform","top","unicodeBidi","verticalAlign","visibility","voiceFamily","volume","whiteSpace","widows","width","wordSpacing","zIndex"].sort(); + var view = document.defaultView?document.defaultView.getComputedStyle(node,null):node.currentStyle; + for(var i=0,len=property.length; i
"+d.highlight(view[item])+"
"; + } + el.right.html.content.update(str); + break; + case "dom": + d.dom.open(node,el.right.html.content,lib.env.ie); + break; + } + } + } + }, + inspector:{ + enabled:false, + el:null, + inspect:function(_element,_bgInspector){ + with(firebug){ + var pos = env.targetWindow.firebug.lib.util.Element.getPosition(_element); + + env.targetWindow.firebug.el[_bgInspector&&"bgInspector"||"borderInspector"].environment.addStyle({ + "width":_element.offsetWidth+"px", "height":_element.offsetHeight+"px", + "top":pos.offsetTop-(_bgInspector?0:2)+"px", "left":pos.offsetLeft-(_bgInspector?0:2)+"px", + "display":"block" + }); +9 + if(!_bgInspector){ + d.inspector.el = _element; + } + }; + }, + toggle:function(_absoluteValue,_event){ + with (firebug) { + if(_absoluteValue==d.inspector.enabled) + return; + d.inspector.enabled = _absoluteValue!=undefined&&!_absoluteValue.clientX?_absoluteValue:!d.inspector.enabled; + el.button.inspect.attribute[(d.inspector.enabled ? "add" : "remove") + "Class"]("Enabled"); + if(d.inspector.enabled==false){ + el.borderInspector.environment.addStyle({ "display":"none" }); + d.inspector.el = null; + } else if(lib.env.dIndex!="html") { + if (env.popupWin) { + env.popupWin.firebug.d.navigate("html"); + } else { + d.navigate("html"); + } + } + } + } + }, + scripts:{ + index:-1, + lineNumbers:false, + open:function(_index){ + with(firebug){ + d.scripts.index = _index; + el.left.scripts.container.update(""); + var script = document.getElementsByTagName("script")[_index],uri = script.src||document.location.href,source; + try { + if(uri!=document.location.href){ + source = env.cache[uri]||lib.xhr.get(uri).responseText; + env.cache[uri] = source; + } else { + source = script.innerHTML; + } + source = source.replace(/<|>/g,function(_ch){ + return ({"<":"<",">":">"})[_ch]; + }); + + if(!d.scripts.lineNumbers) + el.left.scripts.container.child.add( + new lib.element("DIV").attribute.addClass("CodeContainer").update(source) + ); + else { + source = source.split("
"); + for (var i = 0; i < source.length; i++) { + el.left.scripts.container.child.add(new lib.element("DIV").child.add(new lib.element("DIV").attribute.addClass("LineNumber").update(i + 1), new lib.element("DIV").attribute.addClass("Code").update(" " + source[i]), new lib.element("DIV").attribute.addClass('Clear'))); + }; + }; + } catch(e){ + el.left.scripts.container.child.add( + new lib.element("DIV").attribute.addClass("CodeContainer").update("Access to restricted URI denied") + ); + } + } + }, + toggleLineNumbers:function(){ + with(firebug){ + d.scripts.lineNumbers = !d.scripts.lineNumbers; + el.button.scripts.lineNumbers.attribute[(d.scripts.lineNumbers ? "add" : "remove") + "Class"]("Enabled"); + d.scripts.open( d.scripts.index ); + } + }, + refresh:function(){ + with(firebug){ + el.button.scripts.selectbox.clean(); + var collection = env.targetWindow.document.getElementsByTagName("script"); + for(var i=0,len=collection.length; i")) + } + } + }, + xhr:{ + objects:[], + addObject:function(){ + with(firebug){ + for(var i=0,len=arguments.length; i0&&_object[0]!=undefined&&_object[len-1]!=undefined){ + return true; + } else { + for(var key in _object){ + if(key!="item"&&key!="length"&&key!="setNamedItemNS"&&key!="setNamedItem"&&key!="getNamedItem"&&key!="removeNamedItem"&&key!="getNamedItemNS"&&key!="removeNamedItemNS"&&key!="tags"){ + return false; + } + } + return true + }; + }, + IsHash:function(_object){ + return _object && typeof _object=="object"&&(_object==window||_object instanceof Object)&&!_object.nodeName&&!pi.util.IsArray(_object) + }, + Init:[], + AddEvent: function(_element,_eventName,_fn,_useCapture){ + _element[pi.env.ie?"attachEvent":"addEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false); + return pi.util.Curry(pi.util.AddEvent,this,_element); + }, + RemoveEvent: function(_element,_eventName,_fn,_useCapture){ + _element[pi.env.ie?"detachEvent":"removeEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false); + return pi.util.Curry(pi.util.RemoveEvent,this,_element); + }, + Element:{ + addClass:function(_element,_class){ + if( !pi.util.Element.hasClass(_element,_class) ) + pi.util.Element.setClass(_element, pi.util.Element.getClass(_element) + " " + _class ); + }, + getClass:function(_element){ + return _element.getAttribute(pi.env.ie&&!pi.env.ie8?"className":"class")||""; + }, + hasClass:function(_element,_class){ + return pi.util.Array.indexOf(pi.util.Element.getClass(_element).split(" "),_class)>-1; + }, + removeClass:function(_element,_class){ + if( pi.util.Element.hasClass(_element,_class) ){ + var names = pi.util.Element.getClass(_element,_class).split(" "); + pi.util.Element.setClass( + _element, + pi.util.Array.remove(names,pi.util.Array.indexOf(names,_class)).join(" ") + ); + } + }, + setClass:function(_element,_value){ + if(pi.env.ie8){ + _element.setAttribute("className", _value ); + _element.setAttribute("class", _value ); + } else { + _element.setAttribute(pi.env.ie?"className":"class", _value ); + } + }, + toggleClass:function(){ + if(pi.util.Element.hasClass.apply(this,arguments)) + pi.util.Element.removeClass.apply(this,arguments); + else + pi.util.Element.addClass.apply(this,arguments); + }, + getOpacity:function(_styleObject){ + var styleObject = _styleObject; + if(!pi.env.ie) + return styleObject["opacity"]; + + var alpha = styleObject["filter"].match(/opacity\=(\d+)/i); + return alpha?alpha[1]/100:1; + }, + setOpacity:function(_element,_value){ + if(!pi.env.ie) + return pi.util.Element.addStyle(_element,{ "opacity":_value }); + _value*=100; + pi.util.Element.addStyle(_element,{ "filter":"alpha(opacity="+_value+")" }); + return this._parent_; + }, + getPosition:function(_element){ + var parent = _element,offsetLeft = document.body.offsetLeft, offsetTop = document.body.offsetTop, view = pi.util.Element.getView(_element); + while(parent&&parent!=document.body&&parent!=document.firstChild){ + offsetLeft +=parseInt(parent.offsetLeft); + offsetTop += parseInt(parent.offsetTop); + parent = parent.offsetParent; + }; + return { + "bottom":view["bottom"], + "clientLeft":_element.clientLeft, + "clientTop":_element.clientTop, + "left":view["left"], + "marginTop":view["marginTop"], + "marginLeft":view["marginLeft"], + "offsetLeft":offsetLeft, + "offsetTop":offsetTop, + "position":view["position"], + "right":view["right"], + "top":view["top"], + "zIndex":view["zIndex"] + }; + }, + getSize:function(_element){ + var view = pi.util.Element.getView(_element); + return { + "height":view["height"], + "clientHeight":_element.clientHeight, + "clientWidth":_element.clientWidth, + "offsetHeight":_element.offsetHeight, + "offsetWidth":_element.offsetWidth, + "width":view["width"] + } + }, + addStyle:function(_element,_style){ + for(var key in _style){ + key = key=="float"?pi.env.ie?"styleFloat":"cssFloat":key; + if (key == "opacity" && pi.env.ie) { + pi.util.Element.setOpacity(_element,_style[key]); + continue; + } + try { + _element.style[key] = _style[key]; + }catch(e){} + } + }, + getStyle:function(_element,_property){ + _property = _property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property; + if(_property=="opacity"&&pi.env.ie) + return pi.util.Element.getOpacity(_element.style); + return typeof _property=="string"?_element.style[_property]:_element.style; + }, + getValue:function(_element){ + switch(_element.nodeName.toLowerCase()){ + case "input": + case "textarea": + return _element.value; + case "select": + return _element.options[_element.selectedIndex].value; + default: + return _element.innerHTML; + break; + } + }, + getView:function(_element,_property){ + var view = document.defaultView?document.defaultView.getComputedStyle(_element,null):_element.currentStyle; + _property = _property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property; + if(_property=="opacity"&&pi.env.ie) + return pi.util.Element.getOpacity(_element,view); + return typeof _property=="string"?view[_property]:view; + } + }, + Hash: { + clone:function(_hash,_undeep){ + var tmp = {}; + for(var key in _hash){ + if( !_undeep&&pi.util.IsArray( _hash[key] ) ){ + tmp[key] = pi.util.Array.clone( _hash[key] ); + } else if( !_undeep&&pi.util.IsHash( _hash[key] ) ){ + tmp[ key ] = pi.util.Hash.clone(_hash[key]); + } else { + tmp[key] = _hash[key]; + } + } + return tmp; + }, + merge:function(_hash,_source,_undeep){ + for(var key in _source){ + var value = _source[key]; + if (!_undeep&&pi.util.IsArray(_source[key])) { + if(pi.util.IsArray( _hash[key] )){ + Array.prototype.push.apply( _source[key], _hash[key] ) + } + else + value = pi.util.Array.clone(_source[key]); + } + else if (!_undeep&&pi.util.IsHash(_source[key])) { + if (pi.util.IsHash(_hash[key])) { + value = pi.util.Hash.merge(_hash[key], _source[key]); + } else { + value = pi.util.Hash.clone( _source[key] ); + } + } else if( _hash[key] ) + value = _hash[ key ]; + _hash[key] = value; + }; + return _hash; + } + }, + String:{ + format:function(_str){ + var values = Array.prototype.slice.call(arguments,1); + return _str.replace(/\{(\d)\}/g,function(){ + return values[arguments[1]]; + }) + } + }, + GetViewport:function(){ + return { + height:document.documentElement.clientHeight||document.body.clientHeight, + width:document.documentElement.clientWidth||document.body.clientWidth + } + } + }; + + pi.base = function(){ + this.body = {}; + this.init = null; + + this.build = function(_skipClonning){ + var base = this, skipClonning = _skipClonning||false, _private = {}, + fn = function(){ + var _p = pi.util.Hash.clone(_private); + if(!skipClonning){ + for(var key in this){ + if(pi.util.IsArray( this[ key ] ) ){ + this[key] = pi.util.Array.clone( this[key] ); + } else + if( pi.util.IsHash(this[key]) ){ + this[key] = pi.util.Hash.clone( + this[ key ], + function(_key,_object){ + this[ _key ]._parent_ = this; + } + ); + //this[key]._parent_ = this; + } + } + }; + base.createAccessors( _p, this ); + if(base.init) + return base.init.apply(this,arguments); + return this; + }; + this.movePrivateMembers(this.body,_private); + if(this.init){ + fn["$Init"] = this.init; + }; + fn.prototype = this.body; + return fn; + }; + + this.createAccessors = function(_p, _branch){ + var getter = function(_property){ return this[_property]; }, + setter = function(_property,_value){ this[_property] = _value; return _branch._parent_||_branch; }; + + for (var name in _p) { + var isPrivate = name.substring(0, 1) == "_", title = name.substring(1, 2).toUpperCase() + name.substring(2); + + if (isPrivate) { + _branch[(_branch["get" + title]?"_":"")+"get" + title] = pi.util.Curry(getter,_p,name); + _branch[(_branch["set" + title]?"_":"")+"set" + title] = pi.util.Curry(setter,_p,name); + } + else + if (pi.util.IsHash(_p[name])){ + _branch[name]._parent_ = _branch; + if(!_branch[name]) + _branch[name] = {}; + this.createAccessors(_p[name], _branch[name]); + } + }; + }; + + this.movePrivateMembers = function(_object, _branch){ + for (var name in _object) { + var isPrivate = name.substring(0, 1) == "_"; + + if (isPrivate) { + _branch[name] = _object[name]; + delete _object[name]; + } + else + if (pi.util.IsHash(_object[name])){ + _branch[name] = {}; + this.movePrivateMembers(_object[name], _branch[name]); + } + }; + }; + }; + + pi.element = new pi.base; + pi.element.init = function(_val){ + this.environment.setElement( + typeof _val=="string"||!_val? + document.createElement(_val||"DIV"): + _val + ); + return this; + }; + + pi.element.body = { + "addStyle":function(){ + return this.environment.addStyle.apply(this.environment,arguments); + }, + "clean":function(){ + var childs = this.child.get(); + while(childs.length){ + childs[0].parentNode.removeChild(childs[0]); + } + }, + "clone":function(_deep){ + return this.environment.getElement().cloneNode(_deep); + }, + "insert":function(_element){ + _element = _element.environment?_element.environment.getElement():_element; + _element.appendChild(this.environment.getElement()); + return this; + }, + "insertAfter":function(_referenceElement){ + _referenceElement = _referenceElement.environment?_referenceElement.environment.getElement():_referenceElement; + _referenceElement.nextSibling?this.insertBefore(_referenceElement.nextSibling):this.insert(_referenceElement.parentNode); + return this; + }, + "insertBefore":function(_referenceElement){ + _referenceElement = _referenceElement.environment?_referenceElement.environment.getElement():_referenceElement; + _referenceElement.parentNode.insertBefore(this.environment.getElement(),_referenceElement); + return this; + }, + "query":function(_expression,_resultType,namespaceResolver,_result){ + return pi.xpath(_expression,_resultType||"ORDERED_NODE_SNAPSHOT_TYPE",this.environment.getElement(),_namespaceResolver,_result); + }, + "remove":function(){ + if (this.environment.getParent()) { + this.environment.getParent().removeChild(this.environment.getElement()); + } + }, + "update":function(_value){ + this.element[this.element.nodeName.toLowerCase()=="textarea"||this.element.nodeName.toLowerCase()=="input"?"value":"innerHTML"]=_value; + return this; + }, + "attribute":{ + "getAll":function(){ + return this._parent_.environment.getElement().attributes; + }, + "clear":function(_name){ + this.set(_name,""); + return this._parent_; + }, + "get":function(_name){ + return this._parent_.environment.getElement().getAttribute(_name); + }, + "has":function(_name){ + return pi.env.ie?(this.get(_name)!=null):this._parent_.environment.getElement().hasAttribute(_name); + }, + "remove":function(_name){ + this._parent_.environment.getElement().removeAttribute(_name); + return this._parent_; + }, + "set":function(_name,_value){ + this._parent_.environment.getElement().setAttribute(_name,_value); + return this._parent_; + }, + "addClass":function(_classes){ + for(var i=0,len=arguments.length; i-1){ + callback[i].fn.apply(this); + } + } + } + }; + pi.xhr = pi.xhr.build(); + + /* + * xml.xhr.get + */ + + pi.xhr.get = function(_url,_returnPiObject){ + var request = new pi.xhr(); + request.environment.setAsync(false); + request.environment.setUrl(_url); + request.send(); + return _returnPiObject?request:request.environment.getApi(); + }; + + /* + * registering onload event for init functions + */ + pi.util.AddEvent( + pi.env.ie?window:document, + pi.env.ie?"load":"DOMContentLoaded", + function(){ + for(var i=0,len=pi.util.Init.length; i - - - - - - - - - - jQuery.noConflict() | jQuery API Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
- - - - -
- -
-
- -
-
-

jQuery.noConflict()

-
- -
- -
-

-jQuery.noConflict( [removeAll ] )Returns: Object -

-
-

Description: Relinquish jQuery's control of the $ variable.

- -
-

Many JavaScript libraries use $ as a function or variable name, just as jQuery does. In jQuery's case, $ is just an alias for jQuery, so all functionality is available without using $. If you need to use another JavaScript library alongside jQuery, return control of $ back to the other library with a call to $.noConflict(). Old references of $ are saved during jQuery initialization; noConflict() simply restores them.

-

If for some reason two versions of jQuery are loaded (which is not recommended), calling $.noConflict( true ) from the second version will return the globally scoped jQuery variables to those of the first version.

-
- - - - - - - -
- -
1
- -
2
- -
3
- -
4
- -
5
- -
6
- -
-
<script src="other_lib.js"></script>
<script src="jquery.js"></script>
<script>
$.noConflict();
// Code that uses other library's $ can follow here.
</script>
-
-
- -

This technique is especially effective in conjunction with the .ready() method's ability to alias the jQuery object, as within callback passed to .ready() you can use $ if you wish without fear of conflicts later:

-
- - - - - - - -
- -
1
- -
2
- -
3
- -
4
- -
5
- -
6
- -
7
- -
8
- -
9
- -
-
<script src="other_lib.js"></script>
<script src="jquery.js"></script>
<script>
$.noConflict();
jQuery( document ).ready(function( $ ) {
// Code that uses jQuery's $ can follow here.
});
// Code that uses other library's $ can follow here.
</script>
-
-
- -

If necessary, you can free up the jQuery name as well by passing true - as an argument to the method. This is rarely necessary, and if you must - do this (for example, if you need to use multiple versions of the -jQuery library on the same page), you need to consider that most -plug-ins rely on the presence of the jQuery variable and may not operate correctly in this situation.

-
-

Examples:

-

Example: Map the original object that was referenced by $ back to $. -

-
- - - - - - - -
- -
1
- -
2
- -
3
- -
4
- -
5
- -
-
jQuery.noConflict();
// Do something with jQuery
jQuery( "div p" ).hide();
// Do something with another library's $()
$( "content" ).style.display = "none";
-
-
- -
-
-

Example: Revert the $ alias and then create and -execute a function to provide the $ as a jQuery alias inside the -function's scope. Inside the function the original $ object is not -available. This works well for most plugins that don't rely on any other - library. - -

-
- - - - - - - -
- -
1
- -
2
- -
3
- -
4
- -
5
- -
6
- -
7
- -
8
- -
-
jQuery.noConflict();
(function( $ ) {
$(function() {
// More code using $ as alias to jQuery
});
})(jQuery);
// Other code using $ as an alias to the other library
-
-
- -
-
-

Example: Create a different alias instead of jQuery to use in the rest of the script. -

-
- - - - - - - -
- -
1
- -
2
- -
3
- -
4
- -
5
- -
6
- -
7
- -
-
var j = jQuery.noConflict();
// Do something with jQuery
j( "div p" ).hide();
// Do something with another library's $()
$( "content" ).style.display = "none";
-
-
- -
-
-

Example: Completely move jQuery to a new namespace in another object. -

-
- - - - - - - -
- -
1
- -
2
- -
-
var dom = {};
dom.query = jQuery.noConflict( true );
-
-
- -

Result:

-
- - - - - - - -
- -
1
- -
2
- -
3
- -
4
- -
5
- -
6
- -
7
- -
8
- -
-
// Do something with the new jQuery
dom.query( "div p" ).hide();
// Do something with another library's $()
$( "content" ).style.display = "none";
// Do something with another version of jQuery
jQuery( "div > p" ).hide();
-
-
- -
-
-

Example: Load two versions of jQuery (not recommended). Then, restore jQuery's globally scoped variables to the first loaded jQuery. -

-
- - - - - - - -
- -
1
- -
2
- -
3
- -
4
- -
5
- -
6
- -
7
- -
8
- -
9
- -
10
- -
11
- -
12
- -
13
- -
14
- -
15
- -
16
- -
17
- -
18
- -
19
- -
20
- -
21
- -
22
- -
23
- -
24
- -
25
- -
26
- -
27
- -
28
- -
29
- -
30
- -
31
- -
-
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery.noConflict demo</title>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<div id="log">
<h3>Before $.noConflict(true)</h3>
</div>
<script src="//code.jquery.com/jquery-1.6.2.js"></script>
<script>
var $log = $( "#log" );
$log.append( "2nd loaded jQuery version ($): " + $.fn.jquery + "<br>" );
// Restore globally scoped jQuery variables to the first version loaded
// (the newer version)
jq162 = jQuery.noConflict( true );
$log.append( "<h3>After $.noConflict(true)</h3>" );
$log.append( "1st loaded jQuery version ($): " + $.fn.jquery + "<br>" );
$log.append( "2nd loaded jQuery version (jq162): " + jq162.fn.jquery + "<br>" );
</script>
</body>
</html>
-
-
- -

Demo:

-
-
-
- -
-
- - -
-
-
- - - - - - - - + + + + + + + + + + + jQuery.noConflict() | jQuery API Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + +
+ +
+
+ +
+
+

jQuery.noConflict()

+
+ +
+ +
+

+jQuery.noConflict( [removeAll ] )Returns: Object +

+
+

Description: Relinquish jQuery's control of the $ variable.

+ +
+

Many JavaScript libraries use $ as a function or variable name, just as jQuery does. In jQuery's case, $ is just an alias for jQuery, so all functionality is available without using $. If you need to use another JavaScript library alongside jQuery, return control of $ back to the other library with a call to $.noConflict(). Old references of $ are saved during jQuery initialization; noConflict() simply restores them.

+

If for some reason two versions of jQuery are loaded (which is not recommended), calling $.noConflict( true ) from the second version will return the globally scoped jQuery variables to those of the first version.

+
+ + + + + + + +
+ +
1
+ +
2
+ +
3
+ +
4
+ +
5
+ +
6
+ +
+
<script src="other_lib.js"></script>
<script src="jquery.js"></script>
<script>
$.noConflict();
// Code that uses other library's $ can follow here.
</script>
+
+
+ +

This technique is especially effective in conjunction with the .ready() method's ability to alias the jQuery object, as within callback passed to .ready() you can use $ if you wish without fear of conflicts later:

+
+ + + + + + + +
+ +
1
+ +
2
+ +
3
+ +
4
+ +
5
+ +
6
+ +
7
+ +
8
+ +
9
+ +
+
<script src="other_lib.js"></script>
<script src="jquery.js"></script>
<script>
$.noConflict();
jQuery( document ).ready(function( $ ) {
// Code that uses jQuery's $ can follow here.
});
// Code that uses other library's $ can follow here.
</script>
+
+
+ +

If necessary, you can free up the jQuery name as well by passing true + as an argument to the method. This is rarely necessary, and if you must + do this (for example, if you need to use multiple versions of the +jQuery library on the same page), you need to consider that most +plug-ins rely on the presence of the jQuery variable and may not operate correctly in this situation.

+
+

Examples:

+

Example: Map the original object that was referenced by $ back to $. +

+
+ + + + + + + +
+ +
1
+ +
2
+ +
3
+ +
4
+ +
5
+ +
+
jQuery.noConflict();
// Do something with jQuery
jQuery( "div p" ).hide();
// Do something with another library's $()
$( "content" ).style.display = "none";
+
+
+ +
+
+

Example: Revert the $ alias and then create and +execute a function to provide the $ as a jQuery alias inside the +function's scope. Inside the function the original $ object is not +available. This works well for most plugins that don't rely on any other + library. + +

+
+ + + + + + + +
+ +
1
+ +
2
+ +
3
+ +
4
+ +
5
+ +
6
+ +
7
+ +
8
+ +
+
jQuery.noConflict();
(function( $ ) {
$(function() {
// More code using $ as alias to jQuery
});
})(jQuery);
// Other code using $ as an alias to the other library
+
+
+ +
+
+

Example: Create a different alias instead of jQuery to use in the rest of the script. +

+
+ + + + + + + +
+ +
1
+ +
2
+ +
3
+ +
4
+ +
5
+ +
6
+ +
7
+ +
+
var j = jQuery.noConflict();
// Do something with jQuery
j( "div p" ).hide();
// Do something with another library's $()
$( "content" ).style.display = "none";
+
+
+ +
+
+

Example: Completely move jQuery to a new namespace in another object. +

+
+ + + + + + + +
+ +
1
+ +
2
+ +
+
var dom = {};
dom.query = jQuery.noConflict( true );
+
+
+ +

Result:

+
+ + + + + + + +
+ +
1
+ +
2
+ +
3
+ +
4
+ +
5
+ +
6
+ +
7
+ +
8
+ +
+
// Do something with the new jQuery
dom.query( "div p" ).hide();
// Do something with another library's $()
$( "content" ).style.display = "none";
// Do something with another version of jQuery
jQuery( "div > p" ).hide();
+
+
+ +
+
+

Example: Load two versions of jQuery (not recommended). Then, restore jQuery's globally scoped variables to the first loaded jQuery. +

+
+ + + + + + + +
+ +
1
+ +
2
+ +
3
+ +
4
+ +
5
+ +
6
+ +
7
+ +
8
+ +
9
+ +
10
+ +
11
+ +
12
+ +
13
+ +
14
+ +
15
+ +
16
+ +
17
+ +
18
+ +
19
+ +
20
+ +
21
+ +
22
+ +
23
+ +
24
+ +
25
+ +
26
+ +
27
+ +
28
+ +
29
+ +
30
+ +
31
+ +
+
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery.noConflict demo</title>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<div id="log">
<h3>Before $.noConflict(true)</h3>
</div>
<script src="//code.jquery.com/jquery-1.6.2.js"></script>
<script>
var $log = $( "#log" );
$log.append( "2nd loaded jQuery version ($): " + $.fn.jquery + "<br>" );
// Restore globally scoped jQuery variables to the first version loaded
// (the newer version)
jq162 = jQuery.noConflict( true );
$log.append( "<h3>After $.noConflict(true)</h3>" );
$log.append( "1st loaded jQuery version ($): " + $.fn.jquery + "<br>" );
$log.append( "2nd loaded jQuery version (jq162): " + jq162.fn.jquery + "<br>" );
</script>
</body>
</html>
+
+
+ +

Demo:

+
+
+
+ +
+
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/js-ext/jquerycode/jquery.layout-latest.js b/js-ext/jquerycode/jquery.layout-latest.js index c62bd322..17864ae1 100755 --- a/js-ext/jquerycode/jquery.layout-latest.js +++ b/js-ext/jquerycode/jquery.layout-latest.js @@ -1,6075 +1,6075 @@ -/** - * @preserve - * jquery.layout 1.4.4 - * $Date: 2014-11-29 08:00:00 (Sat, 29 November 2014) $ - * $Rev: 1.0404 $ - * - * Copyright (c) 2014 Kevin Dalman (http://jquery-dev.com) - * Based on work by Fabrizio Balliano (http://www.fabrizioballiano.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * SEE: http://layout.jquery-dev.com/LICENSE.txt - * - * Changelog: http://layout.jquery-dev.com/changelog.cfm - * - * Docs: http://layout.jquery-dev.com/documentation.html - * Tips: http://layout.jquery-dev.com/tips.html - * Help: http://groups.google.com/group/jquery-ui-layout - */ - -/* JavaDoc Info: http://code.google.com/closure/compiler/docs/js-for-compiler.html - * {!Object} non-nullable type (never NULL) - * {?string} nullable type (sometimes NULL) - default for {Object} - * {number=} optional parameter - * {*} ALL types - */ -/* TODO for jQ 2.x - * check $.fn.disableSelection - this is in jQuery UI 1.9.x - */ - -// NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars - -;(function ($) { - -// alias Math methods - used a lot! -var min = Math.min -, max = Math.max -, round = Math.floor - -, isStr = function (v) { return $.type(v) === "string"; } - - /** - * @param {!Object} Instance - * @param {Array.} a_fn - */ -, runPluginCallbacks = function (Instance, a_fn) { - if ($.isArray(a_fn)) - for (var i=0, c=a_fn.length; i').appendTo("body") - , d = { width: $c.outerWidth - $c[0].clientWidth, height: 100 - $c[0].clientHeight }; - $c.remove(); - window.scrollbarWidth = d.width; - window.scrollbarHeight = d.height; - return dim.match(/^(width|height)$/) ? d[dim] : d; - } - - -, disableTextSelection: function () { - var $d = $(document) - , s = 'textSelectionDisabled' - , x = 'textSelectionInitialized' - ; - if ($.fn.disableSelection) { - if (!$d.data(x)) // document hasn't been initialized yet - $d.on('mouseup', $.layout.enableTextSelection ).data(x, true); - if (!$d.data(s)) - $d.disableSelection().data(s, true); - } - } -, enableTextSelection: function () { - var $d = $(document) - , s = 'textSelectionDisabled'; - if ($.fn.enableSelection && $d.data(s)) - $d.enableSelection().data(s, false); - } - - - /** - * Returns hash container 'display' and 'visibility' - * - * @see $.swap() - swaps CSS, runs callback, resets CSS - * @param {!Object} $E jQuery element - * @param {boolean=} [force=false] Run even if display != none - * @return {!Object} Returns current style props, if applicable - */ -, showInvisibly: function ($E, force) { - if ($E && $E.length && (force || $E.css("display") === "none")) { // only if not *already hidden* - var s = $E[0].style - // save ONLY the 'style' props because that is what we must restore - , CSS = { display: s.display || '', visibility: s.visibility || '' }; - // show element 'invisibly' so can be measured - $E.css({ display: "block", visibility: "hidden" }); - return CSS; - } - return {}; - } - - /** - * Returns data for setting size of an element (container or a pane). - * - * @see _create(), onWindowResize() for container, plus others for pane - * @return JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc - */ -, getElementDimensions: function ($E, inset) { - var - // dimensions hash - start with current data IF passed - d = { css: {}, inset: {} } - , x = d.css // CSS hash - , i = { bottom: 0 } // TEMP insets (bottom = complier hack) - , N = $.layout.cssNum - , R = Math.round - , off = $E.offset() - , b, p, ei // TEMP border, padding - ; - d.offsetLeft = off.left; - d.offsetTop = off.top; - - if (!inset) inset = {}; // simplify logic below - - $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { // e = edge - b = x["border" + e] = $.layout.borderWidth($E, e); - p = x["padding"+ e] = $.layout.cssNum($E, "padding"+e); - ei = e.toLowerCase(); - d.inset[ei] = inset[ei] >= 0 ? inset[ei] : p; // any missing insetX value = paddingX - i[ei] = d.inset[ei] + b; // total offset of content from outer side - }); - - x.width = R($E.width()); - x.height = R($E.height()); - x.top = N($E,"top",true); - x.bottom = N($E,"bottom",true); - x.left = N($E,"left",true); - x.right = N($E,"right",true); - - d.outerWidth = R($E.outerWidth()); - d.outerHeight = R($E.outerHeight()); - // calc the TRUE inner-dimensions, even in quirks-mode! - d.innerWidth = max(0, d.outerWidth - i.left - i.right); - d.innerHeight = max(0, d.outerHeight - i.top - i.bottom); - // layoutWidth/Height is used in calcs for manual resizing - // layoutW/H only differs from innerW/H when in quirks-mode - then is like outerW/H - d.layoutWidth = R($E.innerWidth()); - d.layoutHeight = R($E.innerHeight()); - - //if ($E.prop('tagName') === 'BODY') { debugData( d, $E.prop('tagName') ); } // DEBUG - - //d.visible = $E.is(":visible");// && x.width > 0 && x.height > 0; - - return d; - } - -, getElementStyles: function ($E, list) { - var - CSS = {} - , style = $E[0].style - , props = list.split(",") - , sides = "Top,Bottom,Left,Right".split(",") - , attrs = "Color,Style,Width".split(",") - , p, s, a, i, j, k - ; - for (i=0; i < props.length; i++) { - p = props[i]; - if (p.match(/(border|padding|margin)$/)) - for (j=0; j < 4; j++) { - s = sides[j]; - if (p === "border") - for (k=0; k < 3; k++) { - a = attrs[k]; - CSS[p+s+a] = style[p+s+a]; - } - else - CSS[p+s] = style[p+s]; - } - else - CSS[p] = style[p]; - }; - return CSS - } - - /** - * Return the innerWidth for the current browser/doctype - * - * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() - * @param {Array.} $E Must pass a jQuery object - first element is processed - * @param {number=} outerWidth (optional) Can pass a width, allowing calculations BEFORE element is resized - * @return {number} Returns the innerWidth of the elem by subtracting padding and borders - */ -, cssWidth: function ($E, outerWidth) { - // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed - if (outerWidth <= 0) return 0; - - var lb = $.layout.browser - , bs = !lb.boxModel ? "border-box" : lb.boxSizing ? $E.css("boxSizing") : "content-box" - , b = $.layout.borderWidth - , n = $.layout.cssNum - , W = outerWidth - ; - // strip border and/or padding from outerWidth to get CSS Width - if (bs !== "border-box") - W -= (b($E, "Left") + b($E, "Right")); - if (bs === "content-box") - W -= (n($E, "paddingLeft") + n($E, "paddingRight")); - return max(0,W); - } - - /** - * Return the innerHeight for the current browser/doctype - * - * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() - * @param {Array.} $E Must pass a jQuery object - first element is processed - * @param {number=} outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized - * @return {number} Returns the innerHeight of the elem by subtracting padding and borders - */ -, cssHeight: function ($E, outerHeight) { - // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed - if (outerHeight <= 0) return 0; - - var lb = $.layout.browser - , bs = !lb.boxModel ? "border-box" : lb.boxSizing ? $E.css("boxSizing") : "content-box" - , b = $.layout.borderWidth - , n = $.layout.cssNum - , H = outerHeight - ; - // strip border and/or padding from outerHeight to get CSS Height - if (bs !== "border-box") - H -= (b($E, "Top") + b($E, "Bottom")); - if (bs === "content-box") - H -= (n($E, "paddingTop") + n($E, "paddingBottom")); - return max(0,H); - } - - /** - * Returns the 'current CSS numeric value' for a CSS property - 0 if property does not exist - * - * @see Called by many methods - * @param {Array.} $E Must pass a jQuery object - first element is processed - * @param {string} prop The name of the CSS property, eg: top, width, etc. - * @param {boolean=} [allowAuto=false] true = return 'auto' if that is value; false = return 0 - * @return {(string|number)} Usually used to get an integer value for position (top, left) or size (height, width) - */ -, cssNum: function ($E, prop, allowAuto) { - if (!$E.jquery) $E = $($E); - var CSS = $.layout.showInvisibly($E) - , p = $.css($E[0], prop, true) - , v = allowAuto && p=="auto" ? p : Math.round(parseFloat(p) || 0); - $E.css( CSS ); // RESET - return v; - } - -, borderWidth: function (el, side) { - if (el.jquery) el = el[0]; - var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left - return $.css(el, b+"Style", true) === "none" ? 0 : Math.round(parseFloat($.css(el, b+"Width", true)) || 0); - } - - /** - * Mouse-tracking utility - FUTURE REFERENCE - * - * init: if (!window.mouse) { - * window.mouse = { x: 0, y: 0 }; - * $(document).mousemove( $.layout.trackMouse ); - * } - * - * @param {Object} evt - * -, trackMouse: function (evt) { - window.mouse = { x: evt.clientX, y: evt.clientY }; - } - */ - - /** - * SUBROUTINE for preventPrematureSlideClose option - * - * @param {Object} evt - * @param {Object=} el - */ -, isMouseOverElem: function (evt, el) { - var - $E = $(el || this) - , d = $E.offset() - , T = d.top - , L = d.left - , R = L + $E.outerWidth() - , B = T + $E.outerHeight() - , x = evt.pageX // evt.clientX ? - , y = evt.pageY // evt.clientY ? - ; - // if X & Y are < 0, probably means is over an open SELECT - return ($.layout.browser.msie && x < 0 && y < 0) || ((x >= L && x <= R) && (y >= T && y <= B)); - } - - /** - * Message/Logging Utility - * - * @example $.layout.msg("My message"); // log text - * @example $.layout.msg("My message", true); // alert text - * @example $.layout.msg({ foo: "bar" }, "Title"); // log hash-data, with custom title - * @example $.layout.msg({ foo: "bar" }, true, "Title", { sort: false }); -OR- - * @example $.layout.msg({ foo: "bar" }, "Title", { sort: false, display: true }); // alert hash-data - * - * @param {(Object|string)} info String message OR Hash/Array - * @param {(Boolean|string|Object)=} [popup=false] True means alert-box - can be skipped - * @param {(Object|string)=} [debugTitle=""] Title for Hash data - can be skipped - * @param {Object=} [debugOpts] Extra options for debug output - */ -, msg: function (info, popup, debugTitle, debugOpts) { - if ($.isPlainObject(info) && window.debugData) { - if (typeof popup === "string") { - debugOpts = debugTitle; - debugTitle = popup; - } - else if (typeof debugTitle === "object") { - debugOpts = debugTitle; - debugTitle = null; - } - var t = debugTitle || "log( )" - , o = $.extend({ sort: false, returnHTML: false, display: false }, debugOpts); - if (popup === true || o.display) - debugData( info, t, o ); - else if (window.console) - console.log(debugData( info, t, o )); - } - else if (popup) - alert(info); - else if (window.console) - console.log(info); - else { - var id = "#layoutLogger" - , $l = $(id); - if (!$l.length) - $l = createLog(); - $l.children("ul").append('
  • '+ info.replace(/\/g,">") +'
  • '); - } - - function createLog () { - var pos = $.support.fixedPosition ? 'fixed' : 'absolute' - , $e = $('
    ' - + '
    ' - + 'XLayout console.log
    ' - + '
      ' - + '
      ' - ).appendTo("body"); - $e.css('left', $(window).width() - $e.outerWidth() - 5) - if ($.ui.draggable) $e.draggable({ handle: ':first-child' }); - return $e; - }; - } - -}; - - -/* - * $.layout.browser REPLACES removed $.browser, with extra data - * Parsing code here adapted from jQuery 1.8 $.browse - */ -(function(){ - var u = navigator.userAgent.toLowerCase() - , m = /(chrome)[ \/]([\w.]+)/.exec( u ) - || /(webkit)[ \/]([\w.]+)/.exec( u ) - || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( u ) - || /(msie) ([\w.]+)/.exec( u ) - || u.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( u ) - || [] - , b = m[1] || "" - , v = m[2] || 0 - , ie = b === "msie" - , cm = document.compatMode - , $s = $.support - , bs = $s.boxSizing !== undefined ? $s.boxSizing : $s.boxSizingReliable - , bm = !ie || !cm || cm === "CSS1Compat" || $s.boxModel || false - , lb = $.layout.browser = { - version: v - , safari: b === "webkit" // webkit (NOT chrome) = safari - , webkit: b === "chrome" // chrome = webkit - , msie: ie - , isIE6: ie && v == 6 - // ONLY IE reverts to old box-model - Note that compatMode was deprecated as of IE8 - , boxModel: bm - , boxSizing: !!(typeof bs === "function" ? bs() : bs) - }; - ; - if (b) lb[b] = true; // set CURRENT browser - /* OLD versions of jQuery only set $.support.boxModel after page is loaded - * so if this is IE, use support.boxModel to test for quirks-mode (ONLY IE changes boxModel) */ - if (!bm && !cm) $(function(){ lb.boxModel = $s.boxModel; }); -})(); - - -// DEFAULT OPTIONS -$.layout.defaults = { -/* - * LAYOUT & LAYOUT-CONTAINER OPTIONS - * - none of these options are applicable to individual panes - */ - name: "" // Not required, but useful for buttons and used for the state-cookie -, containerClass: "ui-layout-container" // layout-container element -, inset: null // custom container-inset values (override padding) -, scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark) -, resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event -, resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky -, resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized -, maskPanesEarly: false // true = create pane-masks on resizer.mouseDown instead of waiting for resizer.dragstart -, onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific -, onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific -, onload_start: null // CALLBACK when Layout inits - after options initialized, but before elements -, onload_end: null // CALLBACK when Layout inits - after EVERYTHING has been initialized -, onunload_start: null // CALLBACK when Layout is destroyed OR onWindowUnload -, onunload_end: null // CALLBACK when Layout is destroyed OR onWindowUnload -, initPanes: true // false = DO NOT initialize the panes onLoad - will init later -, showErrorMessages: true // enables fatal error messages to warn developers of common errors -, showDebugMessages: false // display console-and-alert debug msgs - IF this Layout version _has_ debugging code! -// Changing this zIndex value will cause other zIndex values to automatically change -, zIndex: null // the PANE zIndex - resizers and masks will be +1 -// DO NOT CHANGE the zIndex values below unless you clearly understand their relationships -, zIndexes: { // set _default_ z-index values here... - pane_normal: 0 // normal z-index for panes - , content_mask: 1 // applied to overlays used to mask content INSIDE panes during resizing - , resizer_normal: 2 // normal z-index for resizer-bars - , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open' - , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer - , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged' - } -, errors: { - pane: "pane" // description of "layout pane element" - used only in error messages - , selector: "selector" // description of "jQuery-selector" - used only in error messages - , addButtonError: "Error Adding Button\nInvalid " - , containerMissing: "UI Layout Initialization Error\nThe specified layout-container does not exist." - , centerPaneMissing: "UI Layout Initialization Error\nThe center-pane element does not exist.\nThe center-pane is a required element." - , noContainerHeight: "UI Layout Initialization Warning\nThe layout-container \"CONTAINER\" has no height.\nTherefore the layout is 0-height and hence 'invisible'!" - , callbackError: "UI Layout Callback Error\nThe EVENT callback is not a valid function." - } -/* - * PANE DEFAULT SETTINGS - * - settings under the 'panes' key become the default settings for *all panes* - * - ALL pane-options can also be set specifically for each panes, which will override these 'default values' - */ -, panes: { // default options for 'all panes' - will be overridden by 'per-pane settings' - applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity - , closable: true // pane can open & close - , resizable: true // when open, pane can be resized - , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out - , initClosed: false // true = init pane as 'closed' - , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing - // SELECTORS - //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane - , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane! - , contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content' - , findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector) - // GENERIC ROOT-CLASSES - for auto-generated classNames - , paneClass: "ui-layout-pane" // Layout Pane - , resizerClass: "ui-layout-resizer" // Resizer Bar - , togglerClass: "ui-layout-toggler" // Toggler Button - , buttonClass: "ui-layout-button" // CUSTOM Buttons - eg: '[ui-layout-button]-toggle/-open/-close/-pin' - // ELEMENT SIZE & SPACING - //, size: 100 // MUST be pane-specific -initial size of pane - , minSize: 0 // when manually resizing a pane - , maxSize: 0 // ditto, 0 = no limit - , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open' - , spacing_closed: 6 // ditto - when pane is 'closed' - , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides - , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden' - , togglerAlign_open: "center" // top/left, bottom/right, center, OR... - , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right - , togglerContent_open: "" // text or HTML to put INSIDE the toggler - , togglerContent_closed: "" // ditto - // RESIZING OPTIONS - , resizerDblClickToggle: true // - , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes - , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed - , resizerDragOpacity: 1 // option for ui.draggable - //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar - , maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES - , maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask - , maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes - , resizingGrid: false // grid size that the resizers will snap-to during resizing, eg: [20,20] - , livePaneResizing: false // true = LIVE Resizing as resizer is dragged - , liveContentResizing: false // true = re-measure header/footer heights as resizer is dragged - , liveResizingTolerance: 1 // how many px change before pane resizes, to control performance - // SLIDING OPTIONS - , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding' - , slideTrigger_open: "click" // click, dblclick, mouseenter - , slideTrigger_close: "mouseleave"// click, mouseleave - , slideDelay_open: 300 // applies only for mouseenter event - 0 = instant open - , slideDelay_close: 300 // applies only for mouseleave event (300ms is the minimum!) - , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show? - , preventQuickSlideClose: $.layout.browser.webkit // Chrome triggers slideClosed as it is opening - , preventPrematureSlideClose: false // handle incorrect mouseleave trigger, like when over a SELECT-list in IE - // PANE-SPECIFIC TIPS & MESSAGES - , tips: { - Open: "Open" // eg: "Open Pane" - , Close: "Close" - , Resize: "Resize" - , Slide: "Slide Open" - , Pin: "Pin" - , Unpin: "Un-Pin" - , noRoomToOpen: "Not enough room to show this panel." // alert if user tries to open a pane that cannot - , minSizeWarning: "Panel has reached its minimum size" // displays in browser statusbar - , maxSizeWarning: "Panel has reached its maximum size" // ditto - } - // HOT-KEYS & MISC - , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver - , enableCursorHotkey: true // enabled 'cursor' hotkeys - //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character - , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT' - // PANE ANIMATION - // NOTE: fxSss_open, fxSss_close & fxSss_size options (eg: fxName_open) are auto-generated if not passed - , fxName: "slide" // ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size' - , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration - , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 } - , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation - , animatePaneSizing: false // true = animate resizing after dragging resizer-bar OR sizePane() is called - /* NOTE: Action-specific FX options are auto-generated from the options above if not specifically set: - fxName_open: "slide" // 'Open' pane animation - fnName_close: "slide" // 'Close' pane animation - fxName_size: "slide" // 'Size' pane animation - when animatePaneSizing = true - fxSpeed_open: null - fxSpeed_close: null - fxSpeed_size: null - fxSettings_open: {} - fxSettings_close: {} - fxSettings_size: {} - */ - // CHILD/NESTED LAYOUTS - , children: null // Layout-options for nested/child layout - even {} is valid as options - , containerSelector: '' // if child is NOT 'directly nested', a selector to find it/them (can have more than one child layout!) - , initChildren: true // true = child layout will be created as soon as _this_ layout completes initialization - , destroyChildren: true // true = destroy child-layout if this pane is destroyed - , resizeChildren: true // true = trigger child-layout.resizeAll() when this pane is resized - // EVENT TRIGGERING - , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes - , triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true - // PANE CALLBACKS - , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start - , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end - , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start - , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end - , onopen_start: null // CALLBACK when pane STARTS to Open - , onopen_end: null // CALLBACK when pane ENDS being Opened - , onclose_start: null // CALLBACK when pane STARTS to Close - , onclose_end: null // CALLBACK when pane ENDS being Closed - , onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON*** - , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON*** - , onsizecontent_start: null // CALLBACK when sizing of content-element STARTS - , onsizecontent_end: null // CALLBACK when sizing of content-element ENDS - , onswap_start: null // CALLBACK when pane STARTS to Swap - , onswap_end: null // CALLBACK when pane ENDS being Swapped - , ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized - , ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized - } -/* - * PANE-SPECIFIC SETTINGS - * - options listed below MUST be specified per-pane - they CANNOT be set under 'panes' - * - all options under the 'panes' key can also be set specifically for any pane - * - most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane - */ -, north: { - paneSelector: ".ui-layout-north" - , size: "auto" // eg: "auto", "30%", .30, 200 - , resizerCursor: "n-resize" // custom = url(myCursor.cur) - , customHotkey: "" // EITHER a charCode (43) OR a character ("o") - } -, south: { - paneSelector: ".ui-layout-south" - , size: "auto" - , resizerCursor: "s-resize" - , customHotkey: "" - } -, east: { - paneSelector: ".ui-layout-east" - , size: 200 - , resizerCursor: "e-resize" - , customHotkey: "" - } -, west: { - paneSelector: ".ui-layout-west" - , size: 200 - , resizerCursor: "w-resize" - , customHotkey: "" - } -, center: { - paneSelector: ".ui-layout-center" - , minWidth: 0 - , minHeight: 0 - } -}; - -$.layout.optionsMap = { - // layout/global options - NOT pane-options - layout: ("name,instanceKey,stateManagement,effects,inset,zIndexes,errors," - + "zIndex,scrollToBookmarkOnLoad,showErrorMessages,maskPanesEarly," - + "outset,resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay," - + "onresizeall,onresizeall_start,onresizeall_end,onload,onload_start,onload_end,onunload,onunload_start,onunload_end").split(",") -// borderPanes: [ ALL options that are NOT specified as 'layout' ] - // default.panes options that apply to the center-pane (most options apply _only_ to border-panes) -, center: ("paneClass,contentSelector,contentIgnoreSelector,findNestedContent,applyDemoStyles,triggerEventsOnLoad," - + "showOverflowOnHover,maskContents,maskObjects,liveContentResizing," - + "containerSelector,children,initChildren,resizeChildren,destroyChildren," - + "onresize,onresize_start,onresize_end,onsizecontent,onsizecontent_start,onsizecontent_end").split(",") - // options that MUST be specifically set 'per-pane' - CANNOT set in the panes (defaults) key -, noDefault: ("paneSelector,resizerCursor,customHotkey").split(",") -}; - -/** - * Processes options passed in converts flat-format data into subkey (JSON) format - * In flat-format, subkeys are _currently_ separated with 2 underscores, like north__optName - * Plugins may also call this method so they can transform their own data - * - * @param {!Object} hash Data/options passed by user - may be a single level or nested levels - * @param {boolean=} [addKeys=false] Should the primary layout.options keys be added if they do not exist? - * @return {Object} Returns hash of minWidth & minHeight - */ -$.layout.transformData = function (hash, addKeys) { - var json = addKeys ? { panes: {}, center: {} } : {} // init return object - , branch, optKey, keys, key, val, i, c; - - if (typeof hash !== "object") return json; // no options passed - - // convert all 'flat-keys' to 'sub-key' format - for (optKey in hash) { - branch = json; - val = hash[ optKey ]; - keys = optKey.split("__"); // eg: west__size or north__fxSettings__duration - c = keys.length - 1; - // convert underscore-delimited to subkeys - for (i=0; i <= c; i++) { - key = keys[i]; - if (i === c) { // last key = value - if ($.isPlainObject( val )) - branch[key] = $.layout.transformData( val ); // RECURSE - else - branch[key] = val; - } - else { - if (!branch[key]) - branch[key] = {}; // create the subkey - // recurse to sub-key for next loop - if not done - branch = branch[key]; - } - } - } - return json; -}; - -// INTERNAL CONFIG DATA - DO NOT CHANGE THIS! -$.layout.backwardCompatibility = { - // data used by renameOldOptions() - map: { - // OLD Option Name: NEW Option Name - applyDefaultStyles: "applyDemoStyles" - // CHILD/NESTED LAYOUTS - , childOptions: "children" - , initChildLayout: "initChildren" - , destroyChildLayout: "destroyChildren" - , resizeChildLayout: "resizeChildren" - , resizeNestedLayout: "resizeChildren" - // MISC Options - , resizeWhileDragging: "livePaneResizing" - , resizeContentWhileDragging: "liveContentResizing" - , triggerEventsWhileDragging: "triggerEventsDuringLiveResize" - , maskIframesOnResize: "maskContents" - // STATE MANAGEMENT - , useStateCookie: "stateManagement.enabled" - , "cookie.autoLoad": "stateManagement.autoLoad" - , "cookie.autoSave": "stateManagement.autoSave" - , "cookie.keys": "stateManagement.stateKeys" - , "cookie.name": "stateManagement.cookie.name" - , "cookie.domain": "stateManagement.cookie.domain" - , "cookie.path": "stateManagement.cookie.path" - , "cookie.expires": "stateManagement.cookie.expires" - , "cookie.secure": "stateManagement.cookie.secure" - // OLD Language options - , noRoomToOpenTip: "tips.noRoomToOpen" - , togglerTip_open: "tips.Close" // open = Close - , togglerTip_closed: "tips.Open" // closed = Open - , resizerTip: "tips.Resize" - , sliderTip: "tips.Slide" - } - -/** -* @param {Object} opts -*/ -, renameOptions: function (opts) { - var map = $.layout.backwardCompatibility.map - , oldData, newData, value - ; - for (var itemPath in map) { - oldData = getBranch( itemPath ); - value = oldData.branch[ oldData.key ]; - if (value !== undefined) { - newData = getBranch( map[itemPath], true ); - newData.branch[ newData.key ] = value; - delete oldData.branch[ oldData.key ]; - } - } - - /** - * @param {string} path - * @param {boolean=} [create=false] Create path if does not exist - */ - function getBranch (path, create) { - var a = path.split(".") // split keys into array - , c = a.length - 1 - , D = { branch: opts, key: a[c] } // init branch at top & set key (last item) - , i = 0, k, undef; - for (; i 0) { - if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) { - $E.show().data('autoHidden', false); - if (!browser.mozilla) // FireFox refreshes iframes - IE does not - // make hidden, then visible to 'refresh' display after animation - $E.css(_c.hidden).css(_c.visible); - } - } - else if (autoHide && !$E.data('autoHidden')) - $E.hide().data('autoHidden', true); - } - - /** - * @param {(string|!Object)} el - * @param {number=} outerHeight - * @param {boolean=} [autoHide=false] - */ -, setOuterHeight = function (el, outerHeight, autoHide) { - var $E = el, h; - if (isStr(el)) $E = $Ps[el]; // west - else if (!el.jquery) $E = $(el); - h = cssH($E, outerHeight); - $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent - if (h > 0 && $E.innerWidth() > 0) { - if (autoHide && $E.data('autoHidden')) { - $E.show().data('autoHidden', false); - if (!browser.mozilla) // FireFox refreshes iframes - IE does not - $E.css(_c.hidden).css(_c.visible); - } - } - else if (autoHide && !$E.data('autoHidden')) - $E.hide().data('autoHidden', true); - } - - - /** - * Converts any 'size' params to a pixel/integer size, if not already - * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated - * - /** - * @param {string} pane - * @param {(string|number)=} size - * @param {string=} [dir] - * @return {number} - */ -, _parseSize = function (pane, size, dir) { - if (!dir) dir = _c[pane].dir; - - if (isStr(size) && size.match(/%/)) - size = (size === '100%') ? -1 : parseInt(size, 10) / 100; // convert % to decimal - - if (size === 0) - return 0; - else if (size >= 1) - return parseInt(size, 10); - - var o = options, avail = 0; - if (dir=="horz") // north or south or center.minHeight - avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0); - else if (dir=="vert") // east or west or center.minWidth - avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0); - - if (size === -1) // -1 == 100% - return avail; - else if (size > 0) // percentage, eg: .25 - return round(avail * size); - else if (pane=="center") - return 0; - else { // size < 0 || size=='auto' || size==Missing || size==Invalid - // auto-size the pane - var dim = (dir === "horz" ? "height" : "width") - , $P = $Ps[pane] - , $C = dim === 'height' ? $Cs[pane] : false - , vis = $.layout.showInvisibly($P) // show pane invisibly if hidden - , szP = $P.css(dim) // SAVE current pane size - , szC = $C ? $C.css(dim) : 0 // SAVE current content size - ; - $P.css(dim, "auto"); - if ($C) $C.css(dim, "auto"); - size = (dim === "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE - $P.css(dim, szP).css(vis); // RESET size & visibility - if ($C) $C.css(dim, szC); - return size; - } - } - - /** - * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added - * - * @param {(string|!Object)} pane - * @param {boolean=} [inclSpace=false] - * @return {number} Returns EITHER Width for east/west panes OR Height for north/south panes - */ -, getPaneSize = function (pane, inclSpace) { - var - $P = $Ps[pane] - , o = options[pane] - , s = state[pane] - , oSp = (inclSpace ? o.spacing_open : 0) - , cSp = (inclSpace ? o.spacing_closed : 0) - ; - if (!$P || s.isHidden) - return 0; - else if (s.isClosed || (s.isSliding && inclSpace)) - return cSp; - else if (_c[pane].dir === "horz") - return $P.outerHeight() + oSp; - else // dir === "vert" - return $P.outerWidth() + oSp; - } - - /** - * Calculate min/max pane dimensions and limits for resizing - * - * @param {string} pane - * @param {boolean=} [slide=false] - */ -, setSizeLimits = function (pane, slide) { - if (!isInitialized()) return; - var - o = options[pane] - , s = state[pane] - , c = _c[pane] - , dir = c.dir - , type = c.sizeType.toLowerCase() - , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param - , $P = $Ps[pane] - , paneSpacing = o.spacing_open - // measure the pane on the *opposite side* from this pane - , altPane = _c.oppositeEdge[pane] - , altS = state[altPane] - , $altP = $Ps[altPane] - , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth())) - , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0) - // limitSize prevents this pane from 'overlapping' opposite pane - , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth) - , minCenterDims = cssMinDims("center") - , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth) - // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them - , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing))) - , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize ) - , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize ) - , r = s.resizerPosition = {} // used to set resizing limits - , top = sC.inset.top - , left = sC.inset.left - , W = sC.innerWidth - , H = sC.innerHeight - , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east - ; - switch (pane) { - case "north": r.min = top + minSize; - r.max = top + maxSize; - break; - case "west": r.min = left + minSize; - r.max = left + maxSize; - break; - case "south": r.min = top + H - maxSize - rW; - r.max = top + H - minSize - rW; - break; - case "east": r.min = left + W - maxSize - rW; - r.max = left + W - minSize - rW; - break; - }; - } - - /** - * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes - * - * @return JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height - */ -, calcNewCenterPaneDims = function () { - var d = { - top: getPaneSize("north", true) // true = include 'spacing' value for pane - , bottom: getPaneSize("south", true) - , left: getPaneSize("west", true) - , right: getPaneSize("east", true) - , width: 0 - , height: 0 - }; - - // NOTE: sC = state.container - // calc center-pane outer dimensions - d.width = sC.innerWidth - d.left - d.right; // outerWidth - d.height = sC.innerHeight - d.bottom - d.top; // outerHeight - // add the 'container border/padding' to get final positions relative to the container - d.top += sC.inset.top; - d.bottom += sC.inset.bottom; - d.left += sC.inset.left; - d.right += sC.inset.right; - - return d; - } - - - /** - * @param {!Object} el - * @param {boolean=} [allStates=false] - */ -, getHoverClasses = function (el, allStates) { - var - $El = $(el) - , type = $El.data("layoutRole") - , pane = $El.data("layoutEdge") - , o = options[pane] - , root = o[type +"Class"] - , _pane = "-"+ pane // eg: "-west" - , _open = "-open" - , _closed = "-closed" - , _slide = "-sliding" - , _hover = "-hover " // NOTE the trailing space - , _state = $El.hasClass(root+_closed) ? _closed : _open - , _alt = _state === _closed ? _open : _closed - , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover) - ; - if (allStates) // when 'removing' classes, also remove alternate-state classes - classes += (root+_alt+_hover) + (root+_pane+_alt+_hover); - - if (type=="resizer" && $El.hasClass(root+_slide)) - classes += (root+_slide+_hover) + (root+_pane+_slide+_hover); - - return $.trim(classes); - } -, addHover = function (evt, el) { - var $E = $(el || this); - if (evt && $E.data("layoutRole") === "toggler") - evt.stopPropagation(); // prevent triggering 'slide' on Resizer-bar - $E.addClass( getHoverClasses($E) ); - } -, removeHover = function (evt, el) { - var $E = $(el || this); - $E.removeClass( getHoverClasses($E, true) ); - } - -, onResizerEnter = function (evt) { // ALSO called by toggler.mouseenter - var pane = $(this).data("layoutEdge") - , s = state[pane] - , $d = $(document) - ; - // ignore closed-panes and mouse moving back & forth over resizer! - // also ignore if ANY pane is currently resizing - if ( s.isResizing || state.paneResizing ) return; - - if (options.maskPanesEarly) - showMasks( pane, { resizing: true }); - } -, onResizerLeave = function (evt, el) { - var e = el || this // el is only passed when called by the timer - , pane = $(e).data("layoutEdge") - , name = pane +"ResizerLeave" - , $d = $(document) - ; - timer.clear(pane+"_openSlider"); // cancel slideOpen timer, if set - timer.clear(name); // cancel enableSelection timer - may re/set below - // this method calls itself on a timer because it needs to allow - // enough time for dragging to kick-in and set the isResizing flag - // dragging has a 100ms delay set, so this delay must be >100 - if (!el) // 1st call - mouseleave event - timer.set(name, function(){ onResizerLeave(evt, e); }, 200); - // if user is resizing, dragStop will reset everything, so skip it here - else if (options.maskPanesEarly && !state.paneResizing) // 2nd call - by timer - hideMasks(); - } - -/* - * ########################### - * INITIALIZATION METHODS - * ########################### - */ - - /** - * Initialize the layout - called automatically whenever an instance of layout is created - * - * @see none - triggered onInit - * @return mixed true = fully initialized | false = panes not initialized (yet) | 'cancel' = abort - */ -, _create = function () { - // initialize config/options - initOptions(); - var o = options - , s = state; - - // TEMP state so isInitialized returns true during init process - s.creatingLayout = true; - - // init plugins for this layout, if there are any (eg: stateManagement) - runPluginCallbacks( Instance, $.layout.onCreate ); - - // options & state have been initialized, so now run beforeLoad callback - // onload will CANCEL layout creation if it returns false - if (false === _runCallbacks("onload_start")) - return 'cancel'; - - // initialize the container element - _initContainer(); - - // bind hotkey function - keyDown - if required - initHotkeys(); - - // bind window.onunload - $(window).bind("unload."+ sID, unload); - - // init plugins for this layout, if there are any (eg: customButtons) - runPluginCallbacks( Instance, $.layout.onLoad ); - - // if layout elements are hidden, then layout WILL NOT complete initialization! - // initLayoutElements will set initialized=true and run the onload callback IF successful - if (o.initPanes) _initLayoutElements(); - - delete s.creatingLayout; - - return state.initialized; - } - - /** - * Initialize the layout IF not already - * - * @see All methods in Instance run this test - * @return boolean true = layoutElements have been initialized | false = panes are not initialized (yet) - */ -, isInitialized = function () { - if (state.initialized || state.creatingLayout) return true; // already initialized - else return _initLayoutElements(); // try to init panes NOW - } - - /** - * Initialize the layout - called automatically whenever an instance of layout is created - * - * @see _create() & isInitialized - * @param {boolean=} [retry=false] // indicates this is a 2nd try - * @return An object pointer to the instance created - */ -, _initLayoutElements = function (retry) { - // initialize config/options - var o = options; - // CANNOT init panes inside a hidden container! - if (!$N.is(":visible")) { - // handle Chrome bug where popup window 'has no height' - // if layout is BODY element, try again in 50ms - // SEE: http://layout.jquery-dev.com/samples/test_popup_window.html - if ( !retry && browser.webkit && $N[0].tagName === "BODY" ) - setTimeout(function(){ _initLayoutElements(true); }, 50); - return false; - } - - // a center pane is required, so make sure it exists - if (!getPane("center").length) { - return _log( o.errors.centerPaneMissing ); - } - - // TEMP state so isInitialized returns true during init process - state.creatingLayout = true; - - // update Container dims - $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT include insetX values - - // initialize all layout elements - initPanes(); // size & position panes - calls initHandles() - which calls initResizable() - - if (o.scrollToBookmarkOnLoad) { - var l = self.location; - if (l.hash) l.replace( l.hash ); // scrollTo Bookmark - } - - // check to see if this layout 'nested' inside a pane - if (Instance.hasParentLayout) - o.resizeWithWindow = false; - // bind resizeAll() for 'this layout instance' to window.resize event - else if (o.resizeWithWindow) - $(window).bind("resize."+ sID, windowResize); - - delete state.creatingLayout; - state.initialized = true; - - // init plugins for this layout, if there are any - runPluginCallbacks( Instance, $.layout.onReady ); - - // now run the onload callback, if exists - _runCallbacks("onload_end"); - - return true; // elements initialized successfully - } - - /** - * Initialize nested layouts for a specific pane - can optionally pass layout-options - * - * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west - * @param {Object=} [opts] Layout-options - if passed, will OVERRRIDE options[pane].children - * @return An object pointer to the layout instance created - or null - */ -, createChildren = function (evt_or_pane, opts) { - var pane = evtPane.call(this, evt_or_pane) - , $P = $Ps[pane] - ; - if (!$P) return; - var $C = $Cs[pane] - , s = state[pane] - , o = options[pane] - , sm = options.stateManagement || {} - , cos = opts ? (o.children = opts) : o.children - ; - if ( $.isPlainObject( cos ) ) - cos = [ cos ]; // convert a hash to a 1-elem array - else if (!cos || !$.isArray( cos )) - return; - - $.each( cos, function (idx, co) { - if ( !$.isPlainObject( co ) ) return; - - // determine which element is supposed to be the 'child container' - // if pane has a 'containerSelector' OR a 'content-div', use those instead of the pane - var $containers = co.containerSelector ? $P.find( co.containerSelector ) : ($C || $P); - - $containers.each(function(){ - var $cont = $(this) - , child = $cont.data("layout") // see if a child-layout ALREADY exists on this element - ; - // if no layout exists, but children are set, try to create the layout now - if (!child) { - // TODO: see about moving this to the stateManagement plugin, as a method - // set a unique child-instance key for this layout, if not already set - setInstanceKey({ container: $cont, options: co }, s ); - // If THIS layout has a hash in stateManagement.autoLoad, - // then see if it also contains state-data for this child-layout - // If so, copy the stateData to child.options.stateManagement.autoLoad - if ( sm.includeChildren && state.stateData[pane] ) { - // THIS layout's state was cached when its state was loaded - var paneChildren = state.stateData[pane].children || {} - , childState = paneChildren[ co.instanceKey ] - , co_sm = co.stateManagement || (co.stateManagement = { autoLoad: true }) - ; - // COPY the stateData into the autoLoad key - if ( co_sm.autoLoad === true && childState ) { - co_sm.autoSave = false; // disable autoSave because saving handled by parent-layout - co_sm.includeChildren = true; // cascade option - FOR NOW - co_sm.autoLoad = $.extend(true, {}, childState); // COPY the state-hash - } - } - - // create the layout - child = $cont.layout( co ); - - // if successful, update data - if (child) { - // add the child and update all layout-pointers - // MAY have already been done by child-layout calling parent.refreshChildren() - refreshChildren( pane, child ); - } - } - }); - }); - } - -, setInstanceKey = function (child, parentPaneState) { - // create a named key for use in state and instance branches - var $c = child.container - , o = child.options - , sm = o.stateManagement - , key = o.instanceKey || $c.data("layoutInstanceKey") - ; - if (!key) key = (sm && sm.cookie ? sm.cookie.name : '') || o.name; // look for a name/key - if (!key) key = "layout"+ (++parentPaneState.childIdx); // if no name/key found, generate one - else key = key.replace(/[^\w-]/gi, '_').replace(/_{2,}/g, '_'); // ensure is valid as a hash key - o.instanceKey = key; - $c.data("layoutInstanceKey", key); // useful if layout is destroyed and then recreated - return key; - } - - /** - * @param {string} pane The pane being opened, ie: north, south, east, or west - * @param {Object=} newChild New child-layout Instance to add to this pane - */ -, refreshChildren = function (pane, newChild) { - var $P = $Ps[pane] - , pC = children[pane] - , s = state[pane] - , o - ; - // check for destroy()ed layouts and update the child pointers & arrays - if ($.isPlainObject( pC )) { - $.each( pC, function (key, child) { - if (child.destroyed) delete pC[key] - }); - // if no more children, remove the children hash - if ($.isEmptyObject( pC )) - pC = children[pane] = null; // clear children hash - } - - // see if there is a directly-nested layout inside this pane - // if there is, then there can be only ONE child-layout, so check that... - if (!newChild && !pC) { - newChild = $P.data("layout"); - } - - // if a newChild instance was passed, add it to children[pane] - if (newChild) { - // update child.state - newChild.hasParentLayout = true; // set parent-flag in child - // instanceKey is a key-name used in both state and children - o = newChild.options; - // set a unique child-instance key for this layout, if not already set - setInstanceKey( newChild, s ); - // add pointer to pane.children hash - if (!pC) pC = children[pane] = {}; // create an empty children hash - pC[ o.instanceKey ] = newChild.container.data("layout"); // add childLayout instance - } - - // ALWAYS refresh the pane.children alias, even if null - Instance[pane].children = children[pane]; - - // if newChild was NOT passed - see if there is a child layout NOW - if (!newChild) { - createChildren(pane); // MAY create a child and re-call this method - } - } - -, windowResize = function () { - var o = options - , delay = Number(o.resizeWithWindowDelay); - if (delay < 10) delay = 100; // MUST have a delay! - // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway - timer.clear("winResize"); // if already running - timer.set("winResize", function(){ - timer.clear("winResize"); - timer.clear("winResizeRepeater"); - var dims = elDims( $N, o.inset ); - // only trigger resizeAll() if container has changed size - if (dims.innerWidth !== sC.innerWidth || dims.innerHeight !== sC.innerHeight) - resizeAll(); - }, delay); - // ALSO set fixed-delay timer, if not already running - if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater(); - } - -, setWindowResizeRepeater = function () { - var delay = Number(options.resizeWithWindowMaxDelay); - if (delay > 0) - timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay); - } - -, unload = function () { - var o = options; - - _runCallbacks("onunload_start"); - - // trigger plugin callabacks for this layout (eg: stateManagement) - runPluginCallbacks( Instance, $.layout.onUnload ); - - _runCallbacks("onunload_end"); - } - - /** - * Validate and initialize container CSS and events - * - * @see _create() - */ -, _initContainer = function () { - var - N = $N[0] - , $H = $("html") - , tag = sC.tagName = N.tagName - , id = sC.id = N.id - , cls = sC.className = N.className - , o = options - , name = o.name - , props = "position,margin,padding,border" - , css = "layoutCSS" - , CSS = {} - , hid = "hidden" // used A LOT! - // see if this container is a 'pane' inside an outer-layout - , parent = $N.data("parentLayout") // parent-layout Instance - , pane = $N.data("layoutEdge") // pane-name in parent-layout - , isChild = parent && pane - , num = $.layout.cssNum - , $parent, n - ; - // sC = state.container - sC.selector = $N.selector.split(".slice")[0]; - sC.ref = (o.name ? o.name +' layout / ' : '') + tag + (id ? "#"+id : cls ? '.['+cls+']' : ''); // used in messages - sC.isBody = (tag === "BODY"); - - // try to find a parent-layout - if (!isChild && !sC.isBody) { - $parent = $N.closest("."+ $.layout.defaults.panes.paneClass); - parent = $parent.data("parentLayout"); - pane = $parent.data("layoutEdge"); - isChild = parent && pane; - } - - $N .data({ - layout: Instance - , layoutContainer: sID // FLAG to indicate this is a layout-container - contains unique internal ID - }) - .addClass(o.containerClass) - ; - var layoutMethods = { - destroy: '' - , initPanes: '' - , resizeAll: 'resizeAll' - , resize: 'resizeAll' - }; - // loop hash and bind all methods - include layoutID namespacing - for (name in layoutMethods) { - $N.bind("layout"+ name.toLowerCase() +"."+ sID, Instance[ layoutMethods[name] || name ]); - } - - // if this container is another layout's 'pane', then set child/parent pointers - if (isChild) { - // update parent flag - Instance.hasParentLayout = true; - // set pointers to THIS child-layout (Instance) in parent-layout - parent.refreshChildren( pane, Instance ); - } - - // SAVE original container CSS for use in destroy() - if (!$N.data(css)) { - // handle props like overflow different for BODY & HTML - has 'system default' values - if (sC.isBody) { - // SAVE CSS - $N.data(css, $.extend( styles($N, props), { - height: $N.css("height") - , overflow: $N.css("overflow") - , overflowX: $N.css("overflowX") - , overflowY: $N.css("overflowY") - })); - // ALSO SAVE CSS - $H.data(css, $.extend( styles($H, 'padding'), { - height: "auto" // FF would return a fixed px-size! - , overflow: $H.css("overflow") - , overflowX: $H.css("overflowX") - , overflowY: $H.css("overflowY") - })); - } - else // handle props normally for non-body elements - $N.data(css, styles($N, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY") ); - } - - try { - // common container CSS - CSS = { - overflow: hid - , overflowX: hid - , overflowY: hid - }; - $N.css( CSS ); - - if (o.inset && !$.isPlainObject(o.inset)) { - // can specify a single number for equal outset all-around - n = parseInt(o.inset, 10) || 0 - o.inset = { - top: n - , bottom: n - , left: n - , right: n - }; - } - - // format html & body if this is a full page layout - if (sC.isBody) { - // if HTML has padding, use this as an outer-spacing around BODY - if (!o.outset) { - // use padding from parent-elem (HTML) as outset - o.outset = { - top: num($H, "paddingTop") - , bottom: num($H, "paddingBottom") - , left: num($H, "paddingLeft") - , right: num($H, "paddingRight") - }; - } - else if (!$.isPlainObject(o.outset)) { - // can specify a single number for equal outset all-around - n = parseInt(o.outset, 10) || 0 - o.outset = { - top: n - , bottom: n - , left: n - , right: n - }; - } - // HTML - $H.css( CSS ).css({ - height: "100%" - , border: "none" // no border or padding allowed when using height = 100% - , padding: 0 // ditto - , margin: 0 - }); - // BODY - if (browser.isIE6) { - // IE6 CANNOT use the trick of setting absolute positioning on all 4 sides - must have 'height' - $N.css({ - width: "100%" - , height: "100%" - , border: "none" // no border or padding allowed when using height = 100% - , padding: 0 // ditto - , margin: 0 - , position: "relative" - }); - // convert body padding to an inset option - the border cannot be measured in IE6! - if (!o.inset) o.inset = elDims( $N ).inset; - } - else { // use absolute positioning for BODY to allow borders & padding without overflow - $N.css({ - width: "auto" - , height: "auto" - , margin: 0 - , position: "absolute" // allows for border and padding on BODY - }); - // apply edge-positioning created above - $N.css( o.outset ); - } - // set current layout-container dimensions - $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT include insetX values - } - else { - // container MUST have 'position' - var p = $N.css("position"); - if (!p || !p.match(/(fixed|absolute|relative)/)) - $N.css("position","relative"); - - // set current layout-container dimensions - if ( $N.is(":visible") ) { - $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT change insetX (padding) values - if (sC.innerHeight < 1) // container has no 'height' - warn developer - _log( o.errors.noContainerHeight.replace(/CONTAINER/, sC.ref) ); - } - } - - // if container has min-width/height, then enable scrollbar(s) - if ( num($N, "minWidth") ) $N.parent().css("overflowX","auto"); - if ( num($N, "minHeight") ) $N.parent().css("overflowY","auto"); - - } catch (ex) {} - } - - /** - * Bind layout hotkeys - if options enabled - * - * @see _create() and addPane() - * @param {string=} [panes=""] The edge(s) to process - */ -, initHotkeys = function (panes) { - panes = panes ? panes.split(",") : _c.borderPanes; - // bind keyDown to capture hotkeys, if option enabled for ANY pane - $.each(panes, function (i, pane) { - var o = options[pane]; - if (o.enableCursorHotkey || o.customHotkey) { - $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE - return false; // BREAK - binding was done - } - }); - } - - /** - * Build final OPTIONS data - * - * @see _create() - */ -, initOptions = function () { - var data, d, pane, key, val, i, c, o; - - // reprocess user's layout-options to have correct options sub-key structure - opts = $.layout.transformData( opts, true ); // panes = default subkey - - // auto-rename old options for backward compatibility - opts = $.layout.backwardCompatibility.renameAllOptions( opts ); - - // if user-options has 'panes' key (pane-defaults), clean it... - if (!$.isEmptyObject(opts.panes)) { - // REMOVE any pane-defaults that MUST be set per-pane - data = $.layout.optionsMap.noDefault; - for (i=0, c=data.length; i 0) { - z.pane_normal = zo; - z.content_mask = max(zo+1, z.content_mask); // MIN = +1 - z.resizer_normal = max(zo+2, z.resizer_normal); // MIN = +2 - } - - // DELETE 'panes' key now that we are done - values were copied to EACH pane - delete options.panes; - - - function createFxOptions ( pane ) { - var o = options[pane] - , d = options.panes; - // ensure fxSettings key to avoid errors - if (!o.fxSettings) o.fxSettings = {}; - if (!d.fxSettings) d.fxSettings = {}; - - $.each(["_open","_close","_size"], function (i,n) { - var - sName = "fxName"+ n - , sSpeed = "fxSpeed"+ n - , sSettings = "fxSettings"+ n - // recalculate fxName according to specificity rules - , fxName = o[sName] = - o[sName] // options.west.fxName_open - || d[sName] // options.panes.fxName_open - || o.fxName // options.west.fxName - || d.fxName // options.panes.fxName - || "none" // MEANS $.layout.defaults.panes.fxName == "" || false || null || 0 - , fxExists = $.effects && ($.effects[fxName] || ($.effects.effect && $.effects.effect[fxName])) - ; - // validate fxName to ensure is valid effect - MUST have effect-config data in options.effects - if (fxName === "none" || !options.effects[fxName] || !fxExists) - fxName = o[sName] = "none"; // effect not loaded OR unrecognized fxName - - // set vars for effects subkeys to simplify logic - var fx = options.effects[fxName] || {} // effects.slide - , fx_all = fx.all || null // effects.slide.all - , fx_pane = fx[pane] || null // effects.slide.west - ; - // create fxSpeed[_open|_close|_size] - o[sSpeed] = - o[sSpeed] // options.west.fxSpeed_open - || d[sSpeed] // options.west.fxSpeed_open - || o.fxSpeed // options.west.fxSpeed - || d.fxSpeed // options.panes.fxSpeed - || null // DEFAULT - let fxSetting.duration control speed - ; - // create fxSettings[_open|_close|_size] - o[sSettings] = $.extend( - true - , {} - , fx_all // effects.slide.all - , fx_pane // effects.slide.west - , d.fxSettings // options.panes.fxSettings - , o.fxSettings // options.west.fxSettings - , d[sSettings] // options.panes.fxSettings_open - , o[sSettings] // options.west.fxSettings_open - ); - }); - - // DONE creating action-specific-settings for this pane, - // so DELETE generic options - are no longer meaningful - delete o.fxName; - delete o.fxSpeed; - delete o.fxSettings; - } - } - - /** - * Initialize module objects, styling, size and position for all panes - * - * @see _initElements() - * @param {string} pane The pane to process - */ -, getPane = function (pane) { - var sel = options[pane].paneSelector - if (sel.substr(0,1)==="#") // ID selector - // NOTE: elements selected 'by ID' DO NOT have to be 'children' - return $N.find(sel).eq(0); - else { // class or other selector - var $P = $N.children(sel).eq(0); - // look for the pane nested inside a 'form' element - return $P.length ? $P : $N.children("form:first").children(sel).eq(0); - } - } - - /** - * @param {Object=} evt - */ -, initPanes = function (evt) { - // stopPropagation if called by trigger("layoutinitpanes") - use evtPane utility - evtPane(evt); - - // NOTE: do north & south FIRST so we can measure their height - do center LAST - $.each(_c.allPanes, function (idx, pane) { - addPane( pane, true ); - }); - - // init the pane-handles NOW in case we have to hide or close the pane below - initHandles(); - - // now that all panes have been initialized and initially-sized, - // make sure there is really enough space available for each pane - $.each(_c.borderPanes, function (i, pane) { - if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN - setSizeLimits(pane); - makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit() - } - }); - // size center-pane AGAIN in case we 'closed' a border-pane in loop above - sizeMidPanes("center"); - - // Chrome/Webkit sometimes fires callbacks BEFORE it completes resizing! - // Before RC30.3, there was a 10ms delay here, but that caused layout - // to load asynchrously, which is BAD, so try skipping delay for now - - // process pane contents and callbacks, and init/resize child-layout if exists - $.each(_c.allPanes, function (idx, pane) { - afterInitPane(pane); - }); - } - - /** - * Add a pane to the layout - subroutine of initPanes() - * - * @see initPanes() - * @param {string} pane The pane to process - * @param {boolean=} [force=false] Size content after init - */ -, addPane = function (pane, force) { - if ( !force && !isInitialized() ) return; - var - o = options[pane] - , s = state[pane] - , c = _c[pane] - , dir = c.dir - , fx = s.fx - , spacing = o.spacing_open || 0 - , isCenter = (pane === "center") - , CSS = {} - , $P = $Ps[pane] - , size, minSize, maxSize, child - ; - // if pane-pointer already exists, remove the old one first - if ($P) - removePane( pane, false, true, false ); - else - $Cs[pane] = false; // init - - $P = $Ps[pane] = getPane(pane); - if (!$P.length) { - $Ps[pane] = false; // logic - return; - } - - // SAVE original Pane CSS - if (!$P.data("layoutCSS")) { - var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border"; - $P.data("layoutCSS", styles($P, props)); - } - - // create alias for pane data in Instance - initHandles will add more - Instance[pane] = { - name: pane - , pane: $Ps[pane] - , content: $Cs[pane] - , options: options[pane] - , state: state[pane] - , children: children[pane] - }; - - // add classes, attributes & events - $P .data({ - parentLayout: Instance // pointer to Layout Instance - , layoutPane: Instance[pane] // NEW pointer to pane-alias-object - , layoutEdge: pane - , layoutRole: "pane" - }) - .css(c.cssReq).css("zIndex", options.zIndexes.pane_normal) - .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles - .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector' - .bind("mouseenter."+ sID, addHover ) - .bind("mouseleave."+ sID, removeHover ) - ; - var paneMethods = { - hide: '' - , show: '' - , toggle: '' - , close: '' - , open: '' - , slideOpen: '' - , slideClose: '' - , slideToggle: '' - , size: 'sizePane' - , sizePane: 'sizePane' - , sizeContent: '' - , sizeHandles: '' - , enableClosable: '' - , disableClosable: '' - , enableSlideable: '' - , disableSlideable: '' - , enableResizable: '' - , disableResizable: '' - , swapPanes: 'swapPanes' - , swap: 'swapPanes' - , move: 'swapPanes' - , removePane: 'removePane' - , remove: 'removePane' - , createChildren: '' - , resizeChildren: '' - , resizeAll: 'resizeAll' - , resizeLayout: 'resizeAll' - } - , name; - // loop hash and bind all methods - include layoutID namespacing - for (name in paneMethods) { - $P.bind("layoutpane"+ name.toLowerCase() +"."+ sID, Instance[ paneMethods[name] || name ]); - } - - // see if this pane has a 'scrolling-content element' - initContent(pane, false); // false = do NOT sizeContent() - called later - - if (!isCenter) { - // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden) - // if o.size is auto or not valid, then MEASURE the pane and use that as its 'size' - size = s.size = _parseSize(pane, o.size); - minSize = _parseSize(pane,o.minSize) || 1; - maxSize = _parseSize(pane,o.maxSize) || 100000; - if (size > 0) size = max(min(size, maxSize), minSize); - s.autoResize = o.autoResize; // used with percentage sizes - - // state for border-panes - s.isClosed = false; // true = pane is closed - s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes - s.isResizing= false; // true = pane is in process of being resized - s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible! - - // array for 'pin buttons' whose classNames are auto-updated on pane-open/-close - if (!s.pins) s.pins = []; - } - // states common to ALL panes - s.tagName = $P[0].tagName; - s.edge = pane; // useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going) - s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically - s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic - - // init pane positioning - setPanePosition( pane ); - - // if pane is not visible, - if (dir === "horz") // north or south pane - CSS.height = cssH($P, size); - else if (dir === "vert") // east or west pane - CSS.width = cssW($P, size); - //else if (isCenter) {} - - $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes - if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback - - // if manually adding a pane AFTER layout initialization, then... - if (state.initialized) { - initHandles( pane ); - initHotkeys( pane ); - } - - // close or hide the pane if specified in settings - if (o.initClosed && o.closable && !o.initHidden) - close(pane, true, true); // true, true = force, noAnimation - else if (o.initHidden || o.initClosed) - hide(pane); // will be completely invisible - no resizer or spacing - else if (!s.noRoom) - // make the pane visible - in case was initially hidden - $P.css("display","block"); - // ELSE setAsOpen() - called later by initHandles() - - // RESET visibility now - pane will appear IF display:block - $P.css("visibility","visible"); - - // check option for auto-handling of pop-ups & drop-downs - if (o.showOverflowOnHover) - $P.hover( allowOverflow, resetOverflow ); - - // if manually adding a pane AFTER layout initialization, then... - if (state.initialized) { - afterInitPane( pane ); - } - } - -, afterInitPane = function (pane) { - var $P = $Ps[pane] - , s = state[pane] - , o = options[pane] - ; - if (!$P) return; - - // see if there is a directly-nested layout inside this pane - if ($P.data("layout")) - refreshChildren( pane, $P.data("layout") ); - - // process pane contents and callbacks, and init/resize child-layout if exists - if (s.isVisible) { // pane is OPEN - if (state.initialized) // this pane was added AFTER layout was created - resizeAll(); // will also sizeContent - else - sizeContent(pane); - - if (o.triggerEventsOnLoad) - _runCallbacks("onresize_end", pane); - else // automatic if onresize called, otherwise call it specifically - // resize child - IF inner-layout already exists (created before this layout) - resizeChildren(pane, true); // a previously existing childLayout - } - - // init childLayouts - even if pane is not visible - if (o.initChildren && o.children) - createChildren(pane); - } - - /** - * @param {string=} panes The pane(s) to process - */ -, setPanePosition = function (panes) { - panes = panes ? panes.split(",") : _c.borderPanes; - - // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV - $.each(panes, function (i, pane) { - var $P = $Ps[pane] - , $R = $Rs[pane] - , o = options[pane] - , s = state[pane] - , side = _c[pane].side - , CSS = {} - ; - if (!$P) return; // pane does not exist - skip - - // set css-position to account for container borders & padding - switch (pane) { - case "north": CSS.top = sC.inset.top; - CSS.left = sC.inset.left; - CSS.right = sC.inset.right; - break; - case "south": CSS.bottom = sC.inset.bottom; - CSS.left = sC.inset.left; - CSS.right = sC.inset.right; - break; - case "west": CSS.left = sC.inset.left; // top, bottom & height set by sizeMidPanes() - break; - case "east": CSS.right = sC.inset.right; // ditto - break; - case "center": // top, left, width & height set by sizeMidPanes() - } - // apply position - $P.css(CSS); - - // update resizer position - if ($R && s.isClosed) - $R.css(side, sC.inset[side]); - else if ($R && !s.isHidden) - $R.css(side, sC.inset[side] + getPaneSize(pane)); - }); - } - - /** - * Initialize module objects, styling, size and position for all resize bars and toggler buttons - * - * @see _create() - * @param {string=} [panes=""] The edge(s) to process - */ -, initHandles = function (panes) { - panes = panes ? panes.split(",") : _c.borderPanes; - - // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV - $.each(panes, function (i, pane) { - var $P = $Ps[pane]; - $Rs[pane] = false; // INIT - $Ts[pane] = false; - if (!$P) return; // pane does not exist - skip - - var o = options[pane] - , s = state[pane] - , c = _c[pane] - , paneId = o.paneSelector.substr(0,1) === "#" ? o.paneSelector.substr(1) : "" - , rClass = o.resizerClass - , tClass = o.togglerClass - , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed) - , _pane = "-"+ pane // used for classNames - , _state = (s.isVisible ? "-open" : "-closed") // used for classNames - , I = Instance[pane] - // INIT RESIZER BAR - , $R = I.resizer = $Rs[pane] = $("
      ") - // INIT TOGGLER BUTTON - , $T = I.toggler = (o.closable ? $Ts[pane] = $("
      ") : false) - ; - - //if (s.isVisible && o.resizable) ... handled by initResizable - if (!s.isVisible && o.slidable) - $R.attr("title", o.tips.Slide).css("cursor", o.sliderCursor); - - $R // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer" - .attr("id", paneId ? paneId +"-resizer" : "" ) - .data({ - parentLayout: Instance - , layoutPane: Instance[pane] // NEW pointer to pane-alias-object - , layoutEdge: pane - , layoutRole: "resizer" - }) - .css(_c.resizers.cssReq).css("zIndex", options.zIndexes.resizer_normal) - .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles - .addClass(rClass +" "+ rClass+_pane) - .hover(addHover, removeHover) // ALWAYS add hover-classes, even if resizing is not enabled - handle with CSS instead - .hover(onResizerEnter, onResizerLeave) // ALWAYS NEED resizer.mouseleave to balance toggler.mouseenter - .mousedown($.layout.disableTextSelection) // prevent text-selection OUTSIDE resizer - .mouseup($.layout.enableTextSelection) // not really necessary, but just in case - .appendTo($N) // append DIV to container - ; - if ($.fn.disableSelection) - $R.disableSelection(); // prevent text-selection INSIDE resizer - if (o.resizerDblClickToggle) - $R.bind("dblclick."+ sID, toggle ); - - if ($T) { - $T // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler" - .attr("id", paneId ? paneId +"-toggler" : "" ) - .data({ - parentLayout: Instance - , layoutPane: Instance[pane] // NEW pointer to pane-alias-object - , layoutEdge: pane - , layoutRole: "toggler" - }) - .css(_c.togglers.cssReq) // add base/required styles - .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles - .addClass(tClass +" "+ tClass+_pane) - .hover(addHover, removeHover) // ALWAYS add hover-classes, even if toggling is not enabled - handle with CSS instead - .bind("mouseenter", onResizerEnter) // NEED toggler.mouseenter because mouseenter MAY NOT fire on resizer - .appendTo($R) // append SPAN to resizer DIV - ; - // ADD INNER-SPANS TO TOGGLER - if (o.togglerContent_open) // ui-layout-open - $(""+ o.togglerContent_open +"") - .data({ - layoutEdge: pane - , layoutRole: "togglerContent" - }) - .data("layoutRole", "togglerContent") - .data("layoutEdge", pane) - .addClass("content content-open") - .css("display","none") - .appendTo( $T ) - //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-open instead! - ; - if (o.togglerContent_closed) // ui-layout-closed - $(""+ o.togglerContent_closed +"") - .data({ - layoutEdge: pane - , layoutRole: "togglerContent" - }) - .addClass("content content-closed") - .css("display","none") - .appendTo( $T ) - //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-closed instead! - ; - // ADD TOGGLER.click/.hover - enableClosable(pane); - } - - // add Draggable events - initResizable(pane); - - // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open" - if (s.isVisible) - setAsOpen(pane); // onOpen will be called, but NOT onResize - else { - setAsClosed(pane); // onClose will be called - bindStartSlidingEvents(pane, true); // will enable events IF option is set - } - - }); - - // SET ALL HANDLE DIMENSIONS - sizeHandles(); - } - - - /** - * Initialize scrolling ui-layout-content div - if exists - * - * @see initPane() - or externally after an Ajax injection - * @param {string} pane The pane to process - * @param {boolean=} [resize=true] Size content after init - */ -, initContent = function (pane, resize) { - if (!isInitialized()) return; - var - o = options[pane] - , sel = o.contentSelector - , I = Instance[pane] - , $P = $Ps[pane] - , $C - ; - if (sel) $C = I.content = $Cs[pane] = (o.findNestedContent) - ? $P.find(sel).eq(0) // match 1-element only - : $P.children(sel).eq(0) - ; - if ($C && $C.length) { - $C.data("layoutRole", "content"); - // SAVE original Content CSS - if (!$C.data("layoutCSS")) - $C.data("layoutCSS", styles($C, "height")); - $C.css( _c.content.cssReq ); - if (o.applyDemoStyles) { - $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div - $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane - } - // ensure no vertical scrollbar on pane - will mess up measurements - if ($P.css("overflowX").match(/(scroll|auto)/)) { - $P.css("overflow", "hidden"); - } - state[pane].content = {}; // init content state - if (resize !== false) sizeContent(pane); - // sizeContent() is called AFTER init of all elements - } - else - I.content = $Cs[pane] = false; - } - - - /** - * Add resize-bars to all panes that specify it in options - * -dependancy: $.fn.resizable - will skip if not found - * - * @see _create() - * @param {string=} [panes=""] The edge(s) to process - */ -, initResizable = function (panes) { - var draggingAvailable = $.layout.plugins.draggable - , side // set in start() - ; - panes = panes ? panes.split(",") : _c.borderPanes; - - $.each(panes, function (idx, pane) { - var o = options[pane]; - if (!draggingAvailable || !$Ps[pane] || !o.resizable) { - o.resizable = false; - return true; // skip to next - } - - var s = state[pane] - , z = options.zIndexes - , c = _c[pane] - , side = c.dir=="horz" ? "top" : "left" - , $P = $Ps[pane] - , $R = $Rs[pane] - , base = o.resizerClass - , lastPos = 0 // used when live-resizing - , r, live // set in start because may change - // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process - , resizerClass = base+"-drag" // resizer-drag - , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag - // 'helper' class is applied to the CLONED resizer-bar while it is being dragged - , helperClass = base+"-dragging" // resizer-dragging - , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging - , helperLimitClass = base+"-dragging-limit" // resizer-drag - , helperPaneLimitClass = base+"-"+pane+"-dragging-limit" // resizer-north-drag - , helperClassesSet = false // logic var - ; - - if (!s.isClosed) - $R.attr("title", o.tips.Resize) - .css("cursor", o.resizerCursor); // n-resize, s-resize, etc - - $R.draggable({ - containment: $N[0] // limit resizing to layout container - , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis - , delay: 0 - , distance: 1 - , grid: o.resizingGrid - // basic format for helper - style it using class: .ui-draggable-dragging - , helper: "clone" - , opacity: o.resizerDragOpacity - , addClasses: false // avoid ui-state-disabled class when disabled - //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed - , zIndex: z.resizer_drag - - , start: function (e, ui) { - // REFRESH options & state pointers in case we used swapPanes - o = options[pane]; - s = state[pane]; - // re-read options - live = o.livePaneResizing; - - // ondrag_start callback - will CANCEL hide if returns false - // TODO: dragging CANNOT be cancelled like this, so see if there is a way? - if (false === _runCallbacks("ondrag_start", pane)) return false; - - s.isResizing = true; // prevent pane from closing while resizing - state.paneResizing = pane; // easy to see if ANY pane is resizing - timer.clear(pane+"_closeSlider"); // just in case already triggered - - // SET RESIZER LIMITS - used in drag() - setSizeLimits(pane); // update pane/resizer state - r = s.resizerPosition; - lastPos = ui.position[ side ] - - $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes - helperClassesSet = false; // reset logic var - see drag() - - // MASK PANES CONTAINING IFRAMES, APPLETS OR OTHER TROUBLESOME ELEMENTS - showMasks( pane, { resizing: true }); - } - - , drag: function (e, ui) { - if (!helperClassesSet) { // can only add classes after clone has been added to the DOM - //$(".ui-draggable-dragging") - ui.helper - .addClass( helperClass +" "+ helperPaneClass ) // add helper classes - .css({ right: "auto", bottom: "auto" }) // fix dir="rtl" issue - .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar - ; - helperClassesSet = true; - // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane! - if (s.isSliding) $Ps[pane].css("zIndex", z.pane_sliding); - } - // CONTAIN RESIZER-BAR TO RESIZING LIMITS - var limit = 0; - if (ui.position[side] < r.min) { - ui.position[side] = r.min; - limit = -1; - } - else if (ui.position[side] > r.max) { - ui.position[side] = r.max; - limit = 1; - } - // ADD/REMOVE dragging-limit CLASS - if (limit) { - ui.helper.addClass( helperLimitClass +" "+ helperPaneLimitClass ); // at dragging-limit - window.defaultStatus = (limit>0 && pane.match(/(north|west)/)) || (limit<0 && pane.match(/(south|east)/)) ? o.tips.maxSizeWarning : o.tips.minSizeWarning; - } - else { - ui.helper.removeClass( helperLimitClass +" "+ helperPaneLimitClass ); // not at dragging-limit - window.defaultStatus = ""; - } - // DYNAMICALLY RESIZE PANES IF OPTION ENABLED - // won't trigger unless resizer has actually moved! - if (live && Math.abs(ui.position[side] - lastPos) >= o.liveResizingTolerance) { - lastPos = ui.position[side]; - resizePanes(e, ui, pane) - } - } - - , stop: function (e, ui) { - $('body').enableSelection(); // RE-ENABLE TEXT SELECTION - window.defaultStatus = ""; // clear 'resizing limit' message from statusbar - $R.removeClass( resizerClass +" "+ resizerPaneClass ); // remove drag classes from Resizer - s.isResizing = false; - state.paneResizing = false; // easy to see if ANY pane is resizing - resizePanes(e, ui, pane, true); // true = resizingDone - } - - }); - }); - - /** - * resizePanes - * - * Sub-routine called from stop() - and drag() if livePaneResizing - * - * @param {!Object} evt - * @param {!Object} ui - * @param {string} pane - * @param {boolean=} [resizingDone=false] - */ - var resizePanes = function (evt, ui, pane, resizingDone) { - var dragPos = ui.position - , c = _c[pane] - , o = options[pane] - , s = state[pane] - , resizerPos - ; - switch (pane) { - case "north": resizerPos = dragPos.top; break; - case "west": resizerPos = dragPos.left; break; - case "south": resizerPos = sC.layoutHeight - dragPos.top - o.spacing_open; break; - case "east": resizerPos = sC.layoutWidth - dragPos.left - o.spacing_open; break; - }; - // remove container margin from resizer position to get the pane size - var newSize = resizerPos - sC.inset[c.side]; - - // Disable OR Resize Mask(s) created in drag.start - if (!resizingDone) { - // ensure we meet liveResizingTolerance criteria - if (Math.abs(newSize - s.size) < o.liveResizingTolerance) - return; // SKIP resize this time - // resize the pane - manualSizePane(pane, newSize, false, true); // true = noAnimation - sizeMasks(); // resize all visible masks - } - else { // resizingDone - // ondrag_end callback - if (false !== _runCallbacks("ondrag_end", pane)) - manualSizePane(pane, newSize, false, true); // true = noAnimation - hideMasks(true); // true = force hiding all masks even if one is 'sliding' - if (s.isSliding) // RE-SHOW 'object-masks' so objects won't show through sliding pane - showMasks( pane, { resizing: true }); - } - }; - } - - /** - * sizeMask - * - * Needed to overlay a DIV over an IFRAME-pane because mask CANNOT be *inside* the pane - * Called when mask created, and during livePaneResizing - */ -, sizeMask = function () { - var $M = $(this) - , pane = $M.data("layoutMask") // eg: "west" - , s = state[pane] - ; - // only masks over an IFRAME-pane need manual resizing - if (s.tagName == "IFRAME" && s.isVisible) // no need to mask closed/hidden panes - $M.css({ - top: s.offsetTop - , left: s.offsetLeft - , width: s.outerWidth - , height: s.outerHeight - }); - /* ALT Method... - var $P = $Ps[pane]; - $M.css( $P.position() ).css({ width: $P[0].offsetWidth, height: $P[0].offsetHeight }); - */ - } -, sizeMasks = function () { - $Ms.each( sizeMask ); // resize all 'visible' masks - } - - /** - * @param {string} pane The pane being resized, animated or isSliding - * @param {Object=} [args] (optional) Options: which masks to apply, and to which panes - */ -, showMasks = function (pane, args) { - var c = _c[pane] - , panes = ["center"] - , z = options.zIndexes - , a = $.extend({ - objectsOnly: false - , animation: false - , resizing: true - , sliding: state[pane].isSliding - }, args ) - , o, s - ; - if (a.resizing) - panes.push( pane ); - if (a.sliding) - panes.push( _c.oppositeEdge[pane] ); // ADD the oppositeEdge-pane - - if (c.dir === "horz") { - panes.push("west"); - panes.push("east"); - } - - $.each(panes, function(i,p){ - s = state[p]; - o = options[p]; - if (s.isVisible && ( o.maskObjects || (!a.objectsOnly && o.maskContents) )) { - getMasks(p).each(function(){ - sizeMask.call(this); - this.style.zIndex = s.isSliding ? z.pane_sliding+1 : z.pane_normal+1 - this.style.display = "block"; - }); - } - }); - } - - /** - * @param {boolean=} force Hide masks even if a pane is sliding - */ -, hideMasks = function (force) { - // ensure no pane is resizing - could be a timing issue - if (force || !state.paneResizing) { - $Ms.hide(); // hide ALL masks - } - // if ANY pane is sliding, then DO NOT remove masks from panes with maskObjects enabled - else if (!force && !$.isEmptyObject( state.panesSliding )) { - var i = $Ms.length - 1 - , p, $M; - for (; i >= 0; i--) { - $M = $Ms.eq(i); - p = $M.data("layoutMask"); - if (!options[p].maskObjects) { - $M.hide(); - } - } - } - } - - /** - * @param {string} pane - */ -, getMasks = function (pane) { - var $Masks = $([]) - , $M, i = 0, c = $Ms.length - ; - for (; i CSS - if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET CSS - $N.css( $N.data(css) ).removeData(css); - - // trigger plugins for this layout, if there are any - runPluginCallbacks( Instance, $.layout.onDestroy ); - - // trigger state-management and onunload callback - unload(); - - // clear the Instance of everything except for container & options (so could recreate) - // RE-CREATE: myLayout = myLayout.container.layout( myLayout.options ); - for (var n in Instance) - if (!n.match(/^(container|options)$/)) delete Instance[ n ]; - // add a 'destroyed' flag to make it easy to check - Instance.destroyed = true; - - // if this is a child layout, CLEAR the child-pointer in the parent - /* for now the pointer REMAINS, but with only container, options and destroyed keys - if (parentPane) { - var layout = parentPane.pane.data("parentLayout") - , key = layout.options.instanceKey || 'error'; - // THIS SYNTAX MAY BE WRONG! - parentPane.children[key] = layout.children[ parentPane.name ].children[key] = null; - } - */ - - return Instance; // for coding convenience - } - - /** - * Remove a pane from the layout - subroutine of destroy() - * - * @see destroy() - * @param {(string|Object)} evt_or_pane The pane to process - * @param {boolean=} [remove=false] Remove the DOM element? - * @param {boolean=} [skipResize=false] Skip calling resizeAll()? - * @param {boolean=} [destroyChild=true] Destroy Child-layouts? If not passed, obeys options setting - */ -, removePane = function (evt_or_pane, remove, skipResize, destroyChild) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $P = $Ps[pane] - , $C = $Cs[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - ; - // NOTE: elements can still exist even after remove() - // so check for missing data(), which is cleared by removed() - if ($P && $.isEmptyObject( $P.data() )) $P = false; - if ($C && $.isEmptyObject( $C.data() )) $C = false; - if ($R && $.isEmptyObject( $R.data() )) $R = false; - if ($T && $.isEmptyObject( $T.data() )) $T = false; - - if ($P) $P.stop(true, true); - - var o = options[pane] - , s = state[pane] - , d = "layout" - , css = "layoutCSS" - , pC = children[pane] - , hasChildren = $.isPlainObject( pC ) && !$.isEmptyObject( pC ) - , destroy = destroyChild !== undefined ? destroyChild : o.destroyChildren - ; - // FIRST destroy the child-layout(s) - if (hasChildren && destroy) { - $.each( pC, function (key, child) { - if (!child.destroyed) - child.destroy(true);// tell child-layout to destroy ALL its child-layouts too - if (child.destroyed) // destroy was successful - delete pC[key]; - }); - // if no more children, remove the children hash - if ($.isEmptyObject( pC )) { - pC = children[pane] = null; // clear children hash - hasChildren = false; - } - } - - // Note: can't 'remove' a pane element with non-destroyed children - if ($P && remove && !hasChildren) - $P.remove(); // remove the pane-element and everything inside it - else if ($P && $P[0]) { - // create list of ALL pane-classes that need to be removed - var root = o.paneClass // default="ui-layout-pane" - , pRoot = root +"-"+ pane // eg: "ui-layout-pane-west" - , _open = "-open" - , _sliding= "-sliding" - , _closed = "-closed" - , classes = [ root, root+_open, root+_closed, root+_sliding, // generic classes - pRoot, pRoot+_open, pRoot+_closed, pRoot+_sliding ] // pane-specific classes - ; - $.merge(classes, getHoverClasses($P, true)); // ADD hover-classes - // remove all Layout classes from pane-element - $P .removeClass( classes.join(" ") ) // remove ALL pane-classes - .removeData("parentLayout") - .removeData("layoutPane") - .removeData("layoutRole") - .removeData("layoutEdge") - .removeData("autoHidden") // in case set - .unbind("."+ sID) // remove ALL Layout events - // TODO: remove these extra unbind commands when jQuery is fixed - //.unbind("mouseenter"+ sID) - //.unbind("mouseleave"+ sID) - ; - // do NOT reset CSS if this pane/content is STILL the container of a nested layout! - // the nested layout will reset its 'container' CSS when/if it is destroyed - if (hasChildren && $C) { - // a content-div may not have a specific width, so give it one to contain the Layout - $C.width( $C.width() ); - $.each( pC, function (key, child) { - child.resizeAll(); // resize the Layout - }); - } - else if ($C) - $C.css( $C.data(css) ).removeData(css).removeData("layoutRole"); - // remove pane AFTER content in case there was a nested layout - if (!$P.data(d)) - $P.css( $P.data(css) ).removeData(css); - } - - // REMOVE pane resizer and toggler elements - if ($T) $T.remove(); - if ($R) $R.remove(); - - // CLEAR all pointers and state data - Instance[pane] = $Ps[pane] = $Cs[pane] = $Rs[pane] = $Ts[pane] = false; - s = { removed: true }; - - if (!skipResize) - resizeAll(); - } - - -/* - * ########################### - * ACTION METHODS - * ########################### - */ - - /** - * @param {string} pane - */ -, _hidePane = function (pane) { - var $P = $Ps[pane] - , o = options[pane] - , s = $P[0].style - ; - if (o.useOffscreenClose) { - if (!$P.data(_c.offscreenReset)) - $P.data(_c.offscreenReset, { left: s.left, right: s.right }); - $P.css( _c.offscreenCSS ); - } - else - $P.hide().removeData(_c.offscreenReset); - } - - /** - * @param {string} pane - */ -, _showPane = function (pane) { - var $P = $Ps[pane] - , o = options[pane] - , off = _c.offscreenCSS - , old = $P.data(_c.offscreenReset) - , s = $P[0].style - ; - $P .show() // ALWAYS show, just in case - .removeData(_c.offscreenReset); - if (o.useOffscreenClose && old) { - if (s.left == off.left) - s.left = old.left; - if (s.right == off.right) - s.right = old.right; - } - } - - - /** - * Completely 'hides' a pane, including its spacing - as if it does not exist - * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it - * - * @param {(string|Object)} evt_or_pane The pane being hidden, ie: north, south, east, or west - * @param {boolean=} [noAnimation=false] - */ -, hide = function (evt_or_pane, noAnimation) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - ; - if (pane === "center" || !$P || s.isHidden) return; // pane does not exist OR is already hidden - - // onhide_start callback - will CANCEL hide if returns false - if (state.initialized && false === _runCallbacks("onhide_start", pane)) return; - - s.isSliding = false; // just in case - delete state.panesSliding[pane]; - - // now hide the elements - if ($R) $R.hide(); // hide resizer-bar - if (!state.initialized || s.isClosed) { - s.isClosed = true; // to trigger open-animation on show() - s.isHidden = true; - s.isVisible = false; - if (!state.initialized) - _hidePane(pane); // no animation when loading page - sizeMidPanes(_c[pane].dir === "horz" ? "" : "center"); - if (state.initialized || o.triggerEventsOnLoad) - _runCallbacks("onhide_end", pane); - } - else { - s.isHiding = true; // used by onclose - close(pane, false, noAnimation); // adjust all panes to fit - } - } - - /** - * Show a hidden pane - show as 'closed' by default unless openPane = true - * - * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west - * @param {boolean=} [openPane=false] - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [noAlert=false] - */ -, show = function (evt_or_pane, openPane, noAnimation, noAlert) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - ; - if (pane === "center" || !$P || !s.isHidden) return; // pane does not exist OR is not hidden - - // onshow_start callback - will CANCEL show if returns false - if (false === _runCallbacks("onshow_start", pane)) return; - - s.isShowing = true; // used by onopen/onclose - //s.isHidden = false; - will be set by open/close - if not cancelled - s.isSliding = false; // just in case - delete state.panesSliding[pane]; - - // now show the elements - //if ($R) $R.show(); - will be shown by open/close - if (openPane === false) - close(pane, true); // true = force - else - open(pane, false, noAnimation, noAlert); // adjust all panes to fit - } - - - /** - * Toggles a pane open/closed by calling either open or close - * - * @param {(string|Object)} evt_or_pane The pane being toggled, ie: north, south, east, or west - * @param {boolean=} [slide=false] - */ -, toggle = function (evt_or_pane, slide) { - if (!isInitialized()) return; - var evt = evtObj(evt_or_pane) - , pane = evtPane.call(this, evt_or_pane) - , s = state[pane] - ; - if (evt) // called from to $R.dblclick OR triggerPaneEvent - evt.stopImmediatePropagation(); - if (s.isHidden) - show(pane); // will call 'open' after unhiding it - else if (s.isClosed) - open(pane, !!slide); - else - close(pane); - } - - - /** - * Utility method used during init or other auto-processes - * - * @param {string} pane The pane being closed - * @param {boolean=} [setHandles=false] - */ -, _closePane = function (pane, setHandles) { - var - $P = $Ps[pane] - , s = state[pane] - ; - _hidePane(pane); - s.isClosed = true; - s.isVisible = false; - if (setHandles) setAsClosed(pane); - } - - /** - * Close the specified pane (animation optional), and resize all other panes as needed - * - * @param {(string|Object)} evt_or_pane The pane being closed, ie: north, south, east, or west - * @param {boolean=} [force=false] - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [skipCallback=false] - */ -, close = function (evt_or_pane, force, noAnimation, skipCallback) { - var pane = evtPane.call(this, evt_or_pane); - if (pane === "center") return; // validate - // if pane has been initialized, but NOT the complete layout, close pane instantly - if (!state.initialized && $Ps[pane]) { - _closePane(pane, true); // INIT pane as closed - return; - } - if (!isInitialized()) return; - - var - $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , o = options[pane] - , s = state[pane] - , c = _c[pane] - , doFX, isShowing, isHiding, wasSliding; - - // QUEUE in case another action/animation is in progress - $N.queue(function( queueNext ){ - - if ( !$P - || (!o.closable && !s.isShowing && !s.isHiding) // invalid request // (!o.resizable && !o.closable) ??? - || (!force && s.isClosed && !s.isShowing) // already closed - ) return queueNext(); - - // onclose_start callback - will CANCEL hide if returns false - // SKIP if just 'showing' a hidden pane as 'closed' - var abort = !s.isShowing && false === _runCallbacks("onclose_start", pane); - - // transfer logic vars to temp vars - isShowing = s.isShowing; - isHiding = s.isHiding; - wasSliding = s.isSliding; - // now clear the logic vars (REQUIRED before aborting) - delete s.isShowing; - delete s.isHiding; - - if (abort) return queueNext(); - - doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none"); - s.isMoving = true; - s.isClosed = true; - s.isVisible = false; - // update isHidden BEFORE sizing panes - if (isHiding) s.isHidden = true; - else if (isShowing) s.isHidden = false; - - if (s.isSliding) // pane is being closed, so UNBIND trigger events - bindStopSlidingEvents(pane, false); // will set isSliding=false - else // resize panes adjacent to this one - sizeMidPanes(_c[pane].dir === "horz" ? "" : "center", false); // false = NOT skipCallback - - // if this pane has a resizer bar, move it NOW - before animation - setAsClosed(pane); - - // CLOSE THE PANE - if (doFX) { // animate the close - lockPaneForFX(pane, true); // need to set left/top so animation will work - $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () { - lockPaneForFX(pane, false); // undo - if (s.isClosed) close_2(); - queueNext(); - }); - } - else { // hide the pane without animation - _hidePane(pane); - close_2(); - queueNext(); - }; - }); - - // SUBROUTINE - function close_2 () { - s.isMoving = false; - bindStartSlidingEvents(pane, true); // will enable if o.slidable = true - - // if opposite-pane was autoClosed, see if it can be autoOpened now - var altPane = _c.oppositeEdge[pane]; - if (state[ altPane ].noRoom) { - setSizeLimits( altPane ); - makePaneFit( altPane ); - } - - if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) { - // onclose callback - UNLESS just 'showing' a hidden pane as 'closed' - if (!isShowing) _runCallbacks("onclose_end", pane); - // onhide OR onshow callback - if (isShowing) _runCallbacks("onshow_end", pane); - if (isHiding) _runCallbacks("onhide_end", pane); - } - } - } - - /** - * @param {string} pane The pane just closed, ie: north, south, east, or west - */ -, setAsClosed = function (pane) { - if (!$Rs[pane]) return; // handles not initialized yet! - var - $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , o = options[pane] - , s = state[pane] - , side = _c[pane].side - , rClass = o.resizerClass - , tClass = o.togglerClass - , _pane = "-"+ pane // used for classNames - , _open = "-open" - , _sliding= "-sliding" - , _closed = "-closed" - ; - $R - .css(side, sC.inset[side]) // move the resizer - .removeClass( rClass+_open +" "+ rClass+_pane+_open ) - .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) - .addClass( rClass+_closed +" "+ rClass+_pane+_closed ) - ; - // handle already-hidden panes in case called by swap() or a similar method - if (s.isHidden) $R.hide(); // hide resizer-bar - - // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvents? - if (o.resizable && $.layout.plugins.draggable) - $R - .draggable("disable") - .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here - .css("cursor", "default") - .attr("title","") - ; - - // if pane has a toggler button, adjust that too - if ($T) { - $T - .removeClass( tClass+_open +" "+ tClass+_pane+_open ) - .addClass( tClass+_closed +" "+ tClass+_pane+_closed ) - .attr("title", o.tips.Open) // may be blank - ; - // toggler-content - if exists - $T.children(".content-open").hide(); - $T.children(".content-closed").css("display","block"); - } - - // sync any 'pin buttons' - syncPinBtns(pane, false); - - if (state.initialized) { - // resize 'length' and position togglers for adjacent panes - sizeHandles(); - } - } - - /** - * Open the specified pane (animation optional), and resize all other panes as needed - * - * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west - * @param {boolean=} [slide=false] - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [noAlert=false] - */ -, open = function (evt_or_pane, slide, noAnimation, noAlert) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , o = options[pane] - , s = state[pane] - , c = _c[pane] - , doFX, isShowing - ; - if (pane === "center") return; // validate - // QUEUE in case another action/animation is in progress - $N.queue(function( queueNext ){ - - if ( !$P - || (!o.resizable && !o.closable && !s.isShowing) // invalid request - || (s.isVisible && !s.isSliding) // already open - ) return queueNext(); - - // pane can ALSO be unhidden by just calling show(), so handle this scenario - if (s.isHidden && !s.isShowing) { - queueNext(); // call before show() because it needs the queue free - show(pane, true); - return; - } - - if (s.autoResize && s.size != o.size) // resize pane to original size set in options - sizePane(pane, o.size, true, true, true); // true=skipCallback/noAnimation/forceResize - else - // make sure there is enough space available to open the pane - setSizeLimits(pane, slide); - - // onopen_start callback - will CANCEL open if returns false - var cbReturn = _runCallbacks("onopen_start", pane); - - if (cbReturn === "abort") - return queueNext(); - - // update pane-state again in case options were changed in onopen_start - if (cbReturn !== "NC") // NC = "No Callback" - setSizeLimits(pane, slide); - - if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN! - syncPinBtns(pane, false); // make sure pin-buttons are reset - if (!noAlert && o.tips.noRoomToOpen) - alert(o.tips.noRoomToOpen); - return queueNext(); // ABORT - } - - if (slide) // START Sliding - will set isSliding=true - bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane - else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead - bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false - else if (o.slidable) - bindStartSlidingEvents(pane, false); // UNBIND trigger events - - s.noRoom = false; // will be reset by makePaneFit if 'noRoom' - makePaneFit(pane); - - // transfer logic var to temp var - isShowing = s.isShowing; - // now clear the logic var - delete s.isShowing; - - doFX = !noAnimation && s.isClosed && (o.fxName_open != "none"); - s.isMoving = true; - s.isVisible = true; - s.isClosed = false; - // update isHidden BEFORE sizing panes - WHY??? Old? - if (isShowing) s.isHidden = false; - - if (doFX) { // ANIMATE - // mask adjacent panes with objects - lockPaneForFX(pane, true); // need to set left/top so animation will work - $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() { - lockPaneForFX(pane, false); // undo - if (s.isVisible) open_2(); // continue - queueNext(); - }); - } - else { // no animation - _showPane(pane);// just show pane and... - open_2(); // continue - queueNext(); - }; - }); - - // SUBROUTINE - function open_2 () { - s.isMoving = false; - - // cure iframe display issues - _fixIframe(pane); - - // NOTE: if isSliding, then other panes are NOT 'resized' - if (!s.isSliding) { // resize all panes adjacent to this one - sizeMidPanes(_c[pane].dir=="vert" ? "center" : "", false); // false = NOT skipCallback - } - - // set classes, position handles and execute callbacks... - setAsOpen(pane); - }; - - } - - /** - * @param {string} pane The pane just opened, ie: north, south, east, or west - * @param {boolean=} [skipCallback=false] - */ -, setAsOpen = function (pane, skipCallback) { - var - $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , o = options[pane] - , s = state[pane] - , side = _c[pane].side - , rClass = o.resizerClass - , tClass = o.togglerClass - , _pane = "-"+ pane // used for classNames - , _open = "-open" - , _closed = "-closed" - , _sliding= "-sliding" - ; - $R - .css(side, sC.inset[side] + getPaneSize(pane)) // move the resizer - .removeClass( rClass+_closed +" "+ rClass+_pane+_closed ) - .addClass( rClass+_open +" "+ rClass+_pane+_open ) - ; - if (s.isSliding) - $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) - else // in case 'was sliding' - $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) - - removeHover( 0, $R ); // remove hover classes - if (o.resizable && $.layout.plugins.draggable) - $R .draggable("enable") - .css("cursor", o.resizerCursor) - .attr("title", o.tips.Resize); - else if (!s.isSliding) - $R.css("cursor", "default"); // n-resize, s-resize, etc - - // if pane also has a toggler button, adjust that too - if ($T) { - $T .removeClass( tClass+_closed +" "+ tClass+_pane+_closed ) - .addClass( tClass+_open +" "+ tClass+_pane+_open ) - .attr("title", o.tips.Close); // may be blank - removeHover( 0, $T ); // remove hover classes - // toggler-content - if exists - $T.children(".content-closed").hide(); - $T.children(".content-open").css("display","block"); - } - - // sync any 'pin buttons' - syncPinBtns(pane, !s.isSliding); - - // update pane-state dimensions - BEFORE resizing content - $.extend(s, elDims($P)); - - if (state.initialized) { - // resize resizer & toggler sizes for all panes - sizeHandles(); - // resize content every time pane opens - to be sure - sizeContent(pane, true); // true = remeasure headers/footers, even if 'pane.isMoving' - } - - if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) { - // onopen callback - _runCallbacks("onopen_end", pane); - // onshow callback - TODO: should this be here? - if (s.isShowing) _runCallbacks("onshow_end", pane); - - // ALSO call onresize because layout-size *may* have changed while pane was closed - if (state.initialized) - _runCallbacks("onresize_end", pane); - } - - // TODO: Somehow sizePane("north") is being called after this point??? - } - - - /** - * slideOpen / slideClose / slideToggle - * - * Pass-though methods for sliding - */ -, slideOpen = function (evt_or_pane) { - if (!isInitialized()) return; - var evt = evtObj(evt_or_pane) - , pane = evtPane.call(this, evt_or_pane) - , s = state[pane] - , delay = options[pane].slideDelay_open - ; - if (pane === "center") return; // validate - // prevent event from triggering on NEW resizer binding created below - if (evt) evt.stopImmediatePropagation(); - - if (s.isClosed && evt && evt.type === "mouseenter" && delay > 0) - // trigger = mouseenter - use a delay - timer.set(pane+"_openSlider", open_NOW, delay); - else - open_NOW(); // will unbind events if is already open - - /** - * SUBROUTINE for timed open - */ - function open_NOW () { - if (!s.isClosed) // skip if no longer closed! - bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane - else if (!s.isMoving) - open(pane, true); // true = slide - open() will handle binding - }; - } - -, slideClose = function (evt_or_pane) { - if (!isInitialized()) return; - var evt = evtObj(evt_or_pane) - , pane = evtPane.call(this, evt_or_pane) - , o = options[pane] - , s = state[pane] - , delay = s.isMoving ? 1000 : 300 // MINIMUM delay - option may override - ; - if (pane === "center") return; // validate - if (s.isClosed || s.isResizing) - return; // skip if already closed OR in process of resizing - else if (o.slideTrigger_close === "click") - close_NOW(); // close immediately onClick - else if (o.preventQuickSlideClose && s.isMoving) - return; // handle Chrome quick-close on slide-open - else if (o.preventPrematureSlideClose && evt && $.layout.isMouseOverElem(evt, $Ps[pane])) - return; // handle incorrect mouseleave trigger, like when over a SELECT-list in IE - else if (evt) // trigger = mouseleave - use a delay - // 1 sec delay if 'opening', else .3 sec - timer.set(pane+"_closeSlider", close_NOW, max(o.slideDelay_close, delay)); - else // called programically - close_NOW(); - - /** - * SUBROUTINE for timed close - */ - function close_NOW () { - if (s.isClosed) // skip 'close' if already closed! - bindStopSlidingEvents(pane, false); // UNBIND trigger events - TODO: is this needed here? - else if (!s.isMoving) - close(pane); // close will handle unbinding - }; - } - - /** - * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west - */ -, slideToggle = function (evt_or_pane) { - var pane = evtPane.call(this, evt_or_pane); - toggle(pane, true); - } - - - /** - * Must set left/top on East/South panes so animation will work properly - * - * @param {string} pane The pane to lock, 'east' or 'south' - any other is ignored! - * @param {boolean} doLock true = set left/top, false = remove - */ -, lockPaneForFX = function (pane, doLock) { - var $P = $Ps[pane] - , s = state[pane] - , o = options[pane] - , z = options.zIndexes - ; - if (doLock) { - showMasks( pane, { animation: true, objectsOnly: true }); - $P.css({ zIndex: z.pane_animate }); // overlay all elements during animation - if (pane=="south") - $P.css({ top: sC.inset.top + sC.innerHeight - $P.outerHeight() }); - else if (pane=="east") - $P.css({ left: sC.inset.left + sC.innerWidth - $P.outerWidth() }); - } - else { // animation DONE - RESET CSS - hideMasks(); - $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); - if (pane=="south") - $P.css({ top: "auto" }); - // if pane is positioned 'off-screen', then DO NOT screw with it! - else if (pane=="east" && !$P.css("left").match(/\-99999/)) - $P.css({ left: "auto" }); - // fix anti-aliasing in IE - only needed for animations that change opacity - if (browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1) - $P[0].style.removeAttribute('filter'); - } - } - - - /** - * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger - * - * @see open(), close() - * @param {string} pane The pane to enable/disable, 'north', 'south', etc. - * @param {boolean} enable Enable or Disable sliding? - */ -, bindStartSlidingEvents = function (pane, enable) { - var o = options[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , evtName = o.slideTrigger_open.toLowerCase() - ; - if (!$R || (enable && !o.slidable)) return; - - // make sure we have a valid event - if (evtName.match(/mouseover/)) - evtName = o.slideTrigger_open = "mouseenter"; - else if (!evtName.match(/(click|dblclick|mouseenter)/)) - evtName = o.slideTrigger_open = "click"; - - // must remove double-click-toggle when using dblclick-slide - if (o.resizerDblClickToggle && evtName.match(/click/)) { - $R[enable ? "unbind" : "bind"]('dblclick.'+ sID, toggle) - } - - $R - // add or remove event - [enable ? "bind" : "unbind"](evtName +'.'+ sID, slideOpen) - // set the appropriate cursor & title/tip - .css("cursor", enable ? o.sliderCursor : "default") - .attr("title", enable ? o.tips.Slide : "") - ; - } - - /** - * Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed - * Also increases zIndex when pane is sliding open - * See bindStartSlidingEvents for code to control 'slide open' - * - * @see slideOpen(), slideClose() - * @param {string} pane The pane to process, 'north', 'south', etc. - * @param {boolean} enable Enable or Disable events? - */ -, bindStopSlidingEvents = function (pane, enable) { - var o = options[pane] - , s = state[pane] - , c = _c[pane] - , z = options.zIndexes - , evtName = o.slideTrigger_close.toLowerCase() - , action = (enable ? "bind" : "unbind") - , $P = $Ps[pane] - , $R = $Rs[pane] - ; - timer.clear(pane+"_closeSlider"); // just in case - - if (enable) { - s.isSliding = true; - state.panesSliding[pane] = true; - // remove 'slideOpen' event from resizer - // ALSO will raise the zIndex of the pane & resizer - bindStartSlidingEvents(pane, false); - } - else { - s.isSliding = false; - delete state.panesSliding[pane]; - } - - // RE/SET zIndex - increases when pane is sliding-open, resets to normal when not - $P.css("zIndex", enable ? z.pane_sliding : z.pane_normal); - $R.css("zIndex", enable ? z.pane_sliding+2 : z.resizer_normal); // NOTE: mask = pane_sliding+1 - - // make sure we have a valid event - if (!evtName.match(/(click|mouseleave)/)) - evtName = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout' - - // add/remove slide triggers - $R[action](evtName, slideClose); // base event on resize - // need extra events for mouseleave - if (evtName === "mouseleave") { - // also close on pane.mouseleave - $P[action]("mouseleave."+ sID, slideClose); - // cancel timer when mouse moves between 'pane' and 'resizer' - $R[action]("mouseenter."+ sID, cancelMouseOut); - $P[action]("mouseenter."+ sID, cancelMouseOut); - } - - if (!enable) - timer.clear(pane+"_closeSlider"); - else if (evtName === "click" && !o.resizable) { - // IF pane is not resizable (which already has a cursor and tip) - // then set the a cursor & title/tip on resizer when sliding - $R.css("cursor", enable ? o.sliderCursor : "default"); - $R.attr("title", enable ? o.tips.Close : ""); // use Toggler-tip, eg: "Close Pane" - } - - // SUBROUTINE for mouseleave timer clearing - function cancelMouseOut (evt) { - timer.clear(pane+"_closeSlider"); - evt.stopPropagation(); - } - } - - - /** - * Hides/closes a pane if there is insufficient room - reverses this when there is room again - * MUST have already called setSizeLimits() before calling this method - * - * @param {string} pane The pane being resized - * @param {boolean=} [isOpening=false] Called from onOpen? - * @param {boolean=} [skipCallback=false] Should the onresize callback be run? - * @param {boolean=} [force=false] - */ -, makePaneFit = function (pane, isOpening, skipCallback, force) { - var o = options[pane] - , s = state[pane] - , c = _c[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , isSidePane = c.dir==="vert" - , hasRoom = false - ; - // special handling for center & east/west panes - if (pane === "center" || (isSidePane && s.noVerticalRoom)) { - // see if there is enough room to display the pane - // ERROR: hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth); - hasRoom = (s.maxHeight >= 0); - if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now - _showPane(pane); - if ($R) $R.show(); - s.isVisible = true; - s.noRoom = false; - if (isSidePane) s.noVerticalRoom = false; - _fixIframe(pane); - } - else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now - _hidePane(pane); - if ($R) $R.hide(); - s.isVisible = false; - s.noRoom = true; - } - } - - // see if there is enough room to fit the border-pane - if (pane === "center") { - // ignore center in this block - } - else if (s.minSize <= s.maxSize) { // pane CAN fit - hasRoom = true; - if (s.size > s.maxSize) // pane is too big - shrink it - sizePane(pane, s.maxSize, skipCallback, true, force); // true = noAnimation - else if (s.size < s.minSize) // pane is too small - enlarge it - sizePane(pane, s.minSize, skipCallback, true, force); // true = noAnimation - // need s.isVisible because new pseudoClose method keeps pane visible, but off-screen - else if ($R && s.isVisible && $P.is(":visible")) { - // make sure resizer-bar is positioned correctly - // handles situation where nested layout was 'hidden' when initialized - var pos = s.size + sC.inset[c.side]; - if ($.layout.cssNum( $R, c.side ) != pos) $R.css( c.side, pos ); - } - - // if was previously hidden due to noRoom, then RESET because NOW there is room - if (s.noRoom) { - // s.noRoom state will be set by open or show - if (s.wasOpen && o.closable) { - if (o.autoReopen) - open(pane, false, true, true); // true = noAnimation, true = noAlert - else // leave the pane closed, so just update state - s.noRoom = false; - } - else - show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert - } - } - else { // !hasRoom - pane CANNOT fit - if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now... - s.noRoom = true; // update state - s.wasOpen = !s.isClosed && !s.isSliding; - if (s.isClosed){} // SKIP - else if (o.closable) // 'close' if possible - close(pane, true, true); // true = force, true = noAnimation - else // 'hide' pane if cannot just be closed - hide(pane, true); // true = noAnimation - } - } - } - - - /** - * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized' - * - * @param {(string|Object)} evt_or_pane The pane being resized - * @param {number} size The *desired* new size for this pane - will be validated - * @param {boolean=} [skipCallback=false] Should the onresize callback be run? - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [force=false] Force resizing even if does not seem necessary - */ -, manualSizePane = function (evt_or_pane, size, skipCallback, noAnimation, force) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , o = options[pane] - , s = state[pane] - // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete... - , forceResize = force || (o.livePaneResizing && !s.isResizing) - ; - if (pane === "center") return; // validate - // ANY call to manualSizePane disables autoResize - ie, percentage sizing - s.autoResize = false; - // flow-through... - sizePane(pane, size, skipCallback, noAnimation, forceResize); // will animate resize if option enabled - } - - /** - * sizePane is called only by internal methods whenever a pane needs to be resized - * - * @param {(string|Object)} evt_or_pane The pane being resized - * @param {number} size The *desired* new size for this pane - will be validated - * @param {boolean=} [skipCallback=false] Should the onresize callback be run? - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [force=false] Force resizing even if does not seem necessary - */ -, sizePane = function (evt_or_pane, size, skipCallback, noAnimation, force) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) // probably NEVER called from event? - , o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , side = _c[pane].side - , dimName = _c[pane].sizeType.toLowerCase() - , skipResizeWhileDragging = s.isResizing && !o.triggerEventsDuringLiveResize - , doFX = noAnimation !== true && o.animatePaneSizing - , oldSize, newSize - ; - if (pane === "center") return; // validate - // QUEUE in case another action/animation is in progress - $N.queue(function( queueNext ){ - // calculate 'current' min/max sizes - setSizeLimits(pane); // update pane-state - oldSize = s.size; - size = _parseSize(pane, size); // handle percentages & auto - size = max(size, _parseSize(pane, o.minSize)); - size = min(size, s.maxSize); - if (size < s.minSize) { // not enough room for pane! - queueNext(); // call before makePaneFit() because it needs the queue free - makePaneFit(pane, false, skipCallback); // will hide or close pane - return; - } - - // IF newSize is same as oldSize, then nothing to do - abort - if (!force && size === oldSize) - return queueNext(); - - s.newSize = size; - - // onresize_start callback CANNOT cancel resizing because this would break the layout! - if (!skipCallback && state.initialized && s.isVisible) - _runCallbacks("onresize_start", pane); - - // resize the pane, and make sure its visible - newSize = cssSize(pane, size); - - if (doFX && $P.is(":visible")) { // ANIMATE - var fx = $.layout.effects.size[pane] || $.layout.effects.size.all - , easing = o.fxSettings_size.easing || fx.easing - , z = options.zIndexes - , props = {}; - props[ dimName ] = newSize +'px'; - s.isMoving = true; - // overlay all elements during animation - $P.css({ zIndex: z.pane_animate }) - .show().animate( props, o.fxSpeed_size, easing, function(){ - // reset zIndex after animation - $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); - s.isMoving = false; - delete s.newSize; - sizePane_2(); // continue - queueNext(); - }); - } - else { // no animation - $P.css( dimName, newSize ); // resize pane - delete s.newSize; - // if pane is visible, then - if ($P.is(":visible")) - sizePane_2(); // continue - else { - // pane is NOT VISIBLE, so just update state data... - // when pane is *next opened*, it will have the new size - s.size = size; // update state.size - //$.extend(s, elDims($P)); // update state dimensions - CANNOT do this when not visible! } - } - queueNext(); - }; - - }); - - // SUBROUTINE - function sizePane_2 () { - /* Panes are sometimes not sized precisely in some browsers!? - * This code will resize the pane up to 3 times to nudge the pane to the correct size - */ - var actual = dimName==='width' ? $P.outerWidth() : $P.outerHeight() - , tries = [{ - pane: pane - , count: 1 - , target: size - , actual: actual - , correct: (size === actual) - , attempt: size - , cssSize: newSize - }] - , lastTry = tries[0] - , thisTry = {} - , msg = 'Inaccurate size after resizing the '+ pane +'-pane.' - ; - while ( !lastTry.correct ) { - thisTry = { pane: pane, count: lastTry.count+1, target: size }; - - if (lastTry.actual > size) - thisTry.attempt = max(0, lastTry.attempt - (lastTry.actual - size)); - else // lastTry.actual < size - thisTry.attempt = max(0, lastTry.attempt + (size - lastTry.actual)); - - thisTry.cssSize = cssSize(pane, thisTry.attempt); - $P.css( dimName, thisTry.cssSize ); - - thisTry.actual = dimName=='width' ? $P.outerWidth() : $P.outerHeight(); - thisTry.correct = (size === thisTry.actual); - - // log attempts and alert the user of this *non-fatal error* (if showDebugMessages) - if ( tries.length === 1) { - _log(msg, false, true); - _log(lastTry, false, true); - } - _log(thisTry, false, true); - // after 4 tries, is as close as its gonna get! - if (tries.length > 3) break; - - tries.push( thisTry ); - lastTry = tries[ tries.length - 1 ]; - } - // END TESTING CODE - - // update pane-state dimensions - s.size = size; - $.extend(s, elDims($P)); - - if (s.isVisible && $P.is(":visible")) { - // reposition the resizer-bar - if ($R) $R.css( side, size + sC.inset[side] ); - // resize the content-div - sizeContent(pane); - } - - if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible) - _runCallbacks("onresize_end", pane); - - // resize all the adjacent panes, and adjust their toggler buttons - // when skipCallback passed, it means the controlling method will handle 'other panes' - if (!skipCallback) { - // also no callback if live-resize is in progress and NOT triggerEventsDuringLiveResize - if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "" : "center", skipResizeWhileDragging, force); - sizeHandles(); - } - - // if opposite-pane was autoClosed, see if it can be autoOpened now - var altPane = _c.oppositeEdge[pane]; - if (size < oldSize && state[ altPane ].noRoom) { - setSizeLimits( altPane ); - makePaneFit( altPane, false, skipCallback ); - } - - // DEBUG - ALERT user/developer so they know there was a sizing problem - if (tries.length > 1) - _log(msg +'\nSee the Error Console for details.', true, true); - } - } - - /** - * @see initPanes(), sizePane(), resizeAll(), open(), close(), hide() - * @param {(Array.|string)} panes The pane(s) being resized, comma-delmited string - * @param {boolean=} [skipCallback=false] Should the onresize callback be run? - * @param {boolean=} [force=false] - */ -, sizeMidPanes = function (panes, skipCallback, force) { - panes = (panes ? panes : "east,west,center").split(","); - - $.each(panes, function (i, pane) { - if (!$Ps[pane]) return; // NO PANE - skip - var - o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , isCenter= (pane=="center") - , hasRoom = true - , CSS = {} - // if pane is not visible, show it invisibly NOW rather than for *each call* in this script - , visCSS = $.layout.showInvisibly($P) - - , newCenter = calcNewCenterPaneDims() - ; - - // update pane-state dimensions - $.extend(s, elDims($P)); - - if (pane === "center") { - if (!force && s.isVisible && newCenter.width === s.outerWidth && newCenter.height === s.outerHeight) { - $P.css(visCSS); - return true; // SKIP - pane already the correct size - } - // set state for makePaneFit() logic - $.extend(s, cssMinDims(pane), { - maxWidth: newCenter.width - , maxHeight: newCenter.height - }); - CSS = newCenter; - s.newWidth = CSS.width; - s.newHeight = CSS.height; - // convert OUTER width/height to CSS width/height - CSS.width = cssW($P, CSS.width); - // NEW - allow pane to extend 'below' visible area rather than hide it - CSS.height = cssH($P, CSS.height); - hasRoom = CSS.width >= 0 && CSS.height >= 0; // height >= 0 = ALWAYS TRUE NOW - - // during layout init, try to shrink east/west panes to make room for center - if (!state.initialized && o.minWidth > newCenter.width) { - var - reqPx = o.minWidth - s.outerWidth - , minE = options.east.minSize || 0 - , minW = options.west.minSize || 0 - , sizeE = state.east.size - , sizeW = state.west.size - , newE = sizeE - , newW = sizeW - ; - if (reqPx > 0 && state.east.isVisible && sizeE > minE) { - newE = max( sizeE-minE, sizeE-reqPx ); - reqPx -= sizeE-newE; - } - if (reqPx > 0 && state.west.isVisible && sizeW > minW) { - newW = max( sizeW-minW, sizeW-reqPx ); - reqPx -= sizeW-newW; - } - // IF we found enough extra space, then resize the border panes as calculated - if (reqPx === 0) { - if (sizeE && sizeE != minE) - sizePane('east', newE, true, true, force); // true = skipCallback/noAnimation - initPanes will handle when done - if (sizeW && sizeW != minW) - sizePane('west', newW, true, true, force); // true = skipCallback/noAnimation - // now start over! - sizeMidPanes('center', skipCallback, force); - $P.css(visCSS); - return; // abort this loop - } - } - } - else { // for east and west, set only the height, which is same as center height - // set state.min/maxWidth/Height for makePaneFit() logic - if (s.isVisible && !s.noVerticalRoom) - $.extend(s, elDims($P), cssMinDims(pane)) - if (!force && !s.noVerticalRoom && newCenter.height === s.outerHeight) { - $P.css(visCSS); - return true; // SKIP - pane already the correct size - } - // east/west have same top, bottom & height as center - CSS.top = newCenter.top; - CSS.bottom = newCenter.bottom; - s.newSize = newCenter.height - // NEW - allow pane to extend 'below' visible area rather than hide it - CSS.height = cssH($P, newCenter.height); - s.maxHeight = CSS.height; - hasRoom = (s.maxHeight >= 0); // ALWAYS TRUE NOW - if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic - } - - if (hasRoom) { - // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized - if (!skipCallback && state.initialized) - _runCallbacks("onresize_start", pane); - - $P.css(CSS); // apply the CSS to pane - if (pane !== "center") - sizeHandles(pane); // also update resizer length - if (s.noRoom && !s.isClosed && !s.isHidden) - makePaneFit(pane); // will re-open/show auto-closed/hidden pane - if (s.isVisible) { - $.extend(s, elDims($P)); // update pane dimensions - if (state.initialized) sizeContent(pane); // also resize the contents, if exists - } - } - else if (!s.noRoom && s.isVisible) // no room for pane - makePaneFit(pane); // will hide or close pane - - // reset visibility, if necessary - $P.css(visCSS); - - delete s.newSize; - delete s.newWidth; - delete s.newHeight; - - if (!s.isVisible) - return true; // DONE - next pane - - /* - * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes - * Normally these panes have only 'left' & 'right' positions so pane auto-sizes - * ALSO required when pane is an IFRAME because will NOT default to 'full width' - * TODO: Can I use width:100% for a north/south iframe? - * TODO: Sounds like a job for $P.outerWidth( sC.innerWidth ) SETTER METHOD - */ - if (pane === "center") { // finished processing midPanes - var fix = browser.isIE6 || !browser.boxModel; - if ($Ps.north && (fix || state.north.tagName=="IFRAME")) - $Ps.north.css("width", cssW($Ps.north, sC.innerWidth)); - if ($Ps.south && (fix || state.south.tagName=="IFRAME")) - $Ps.south.css("width", cssW($Ps.south, sC.innerWidth)); - } - - // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized - if (!skipCallback && state.initialized) - _runCallbacks("onresize_end", pane); - }); - } - - - /** - * @see window.onresize(), callbacks or custom code - * @param {(Object|boolean)=} evt_or_refresh If 'true', then also reset pane-positioning - */ -, resizeAll = function (evt_or_refresh) { - var oldW = sC.innerWidth - , oldH = sC.innerHeight - ; - // stopPropagation if called by trigger("layoutdestroy") - use evtPane utility - evtPane(evt_or_refresh); - - // cannot size layout when 'container' is hidden or collapsed - if (!$N.is(":visible")) return; - - if (!state.initialized) { - _initLayoutElements(); - return; // no need to resize since we just initialized! - } - - if (evt_or_refresh === true && $.isPlainObject(options.outset)) { - // update container CSS in case outset option has changed - $N.css( options.outset ); - } - // UPDATE container dimensions - $.extend(sC, elDims( $N, options.inset )); - if (!sC.outerHeight) return; - - // if 'true' passed, refresh pane & handle positioning too - if (evt_or_refresh === true) { - setPanePosition(); - } - - // onresizeall_start will CANCEL resizing if returns false - // state.container has already been set, so user can access this info for calcuations - if (false === _runCallbacks("onresizeall_start")) return false; - - var // see if container is now 'smaller' than before - shrunkH = (sC.innerHeight < oldH) - , shrunkW = (sC.innerWidth < oldW) - , $P, o, s - ; - // NOTE special order for sizing: S-N-E-W - $.each(["south","north","east","west"], function (i, pane) { - if (!$Ps[pane]) return; // no pane - SKIP - o = options[pane]; - s = state[pane]; - if (s.autoResize && s.size != o.size) // resize pane to original size set in options - sizePane(pane, o.size, true, true, true); // true=skipCallback/noAnimation/forceResize - else { - setSizeLimits(pane); - makePaneFit(pane, false, true, true); // true=skipCallback/forceResize - } - }); - - sizeMidPanes("", true, true); // true=skipCallback/forceResize - sizeHandles(); // reposition the toggler elements - - // trigger all individual pane callbacks AFTER layout has finished resizing - $.each(_c.allPanes, function (i, pane) { - $P = $Ps[pane]; - if (!$P) return; // SKIP - if (state[pane].isVisible) // undefined for non-existent panes - _runCallbacks("onresize_end", pane); // callback - if exists - }); - - _runCallbacks("onresizeall_end"); - //_triggerLayoutEvent(pane, 'resizeall'); - } - - /** - * Whenever a pane resizes or opens that has a nested layout, trigger resizeAll - * - * @param {(string|Object)} evt_or_pane The pane just resized or opened - */ -, resizeChildren = function (evt_or_pane, skipRefresh) { - var pane = evtPane.call(this, evt_or_pane); - - if (!options[pane].resizeChildren) return; - - // ensure the pane-children are up-to-date - if (!skipRefresh) refreshChildren( pane ); - var pC = children[pane]; - if ($.isPlainObject( pC )) { - // resize one or more children - $.each( pC, function (key, child) { - if (!child.destroyed) child.resizeAll(); - }); - } - } - - /** - * IF pane has a content-div, then resize all elements inside pane to fit pane-height - * - * @param {(string|Object)} evt_or_panes The pane(s) being resized - * @param {boolean=} [remeasure=false] Should the content (header/footer) be remeasured? - */ -, sizeContent = function (evt_or_panes, remeasure) { - if (!isInitialized()) return; - - var panes = evtPane.call(this, evt_or_panes); - panes = panes ? panes.split(",") : _c.allPanes; - - $.each(panes, function (idx, pane) { - var - $P = $Ps[pane] - , $C = $Cs[pane] - , o = options[pane] - , s = state[pane] - , m = s.content // m = measurements - ; - if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip - - // if content-element was REMOVED, update OR remove the pointer - if (!$C.length) { - initContent(pane, false); // false = do NOT sizeContent() - already there! - if (!$C) return; // no replacement element found - pointer have been removed - } - - // onsizecontent_start will CANCEL resizing if returns false - if (false === _runCallbacks("onsizecontent_start", pane)) return; - - // skip re-measuring offsets if live-resizing - if ((!s.isMoving && !s.isResizing) || o.liveContentResizing || remeasure || m.top == undefined) { - _measure(); - // if any footers are below pane-bottom, they may not measure correctly, - // so allow pane overflow and re-measure - if (m.hiddenFooters > 0 && $P.css("overflow") === "hidden") { - $P.css("overflow", "visible"); - _measure(); // remeasure while overflowing - $P.css("overflow", "hidden"); - } - } - // NOTE: spaceAbove/Below *includes* the pane paddingTop/Bottom, but not pane.borders - var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom); - - if (!$C.is(":visible") || m.height != newH) { - // size the Content element to fit new pane-size - will autoHide if not enough room - setOuterHeight($C, newH, true); // true=autoHide - m.height = newH; // save new height - }; - - if (state.initialized) - _runCallbacks("onsizecontent_end", pane); - - function _below ($E) { - return max(s.css.paddingBottom, (parseInt($E.css("marginBottom"), 10) || 0)); - }; - - function _measure () { - var - ignore = options[pane].contentIgnoreSelector - , $Fs = $C.nextAll().not(".ui-layout-mask").not(ignore || ":lt(0)") // not :lt(0) = ALL - , $Fs_vis = $Fs.filter(':visible') - , $F = $Fs_vis.filter(':last') - ; - m = { - top: $C[0].offsetTop - , height: $C.outerHeight() - , numFooters: $Fs.length - , hiddenFooters: $Fs.length - $Fs_vis.length - , spaceBelow: 0 // correct if no content footer ($E) - } - m.spaceAbove = m.top; // just for state - not used in calc - m.bottom = m.top + m.height; - if ($F.length) - //spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom) - m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F); - else // no footer - check marginBottom on Content element itself - m.spaceBelow = _below($C); - }; - }); - } - - - /** - * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary - * - * @see initHandles(), open(), close(), resizeAll() - * @param {(string|Object)=} evt_or_panes The pane(s) being resized - */ -, sizeHandles = function (evt_or_panes) { - var panes = evtPane.call(this, evt_or_panes) - panes = panes ? panes.split(",") : _c.borderPanes; - - $.each(panes, function (i, pane) { - var - o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , $TC - ; - if (!$P || !$R) return; - - var - dir = _c[pane].dir - , _state = (s.isClosed ? "_closed" : "_open") - , spacing = o["spacing"+ _state] - , togAlign = o["togglerAlign"+ _state] - , togLen = o["togglerLength"+ _state] - , paneLen - , left - , offset - , CSS = {} - ; - - if (spacing === 0) { - $R.hide(); - return; - } - else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason - $R.show(); // in case was previously hidden - - // Resizer Bar is ALWAYS same width/height of pane it is attached to - if (dir === "horz") { // north/south - //paneLen = $P.outerWidth(); // s.outerWidth || - paneLen = sC.innerWidth; // handle offscreen-panes - s.resizerLength = paneLen; - left = $.layout.cssNum($P, "left") - $R.css({ - width: cssW($R, paneLen) // account for borders & padding - , height: cssH($R, spacing) // ditto - , left: left > -9999 ? left : sC.inset.left // handle offscreen-panes - }); - } - else { // east/west - paneLen = $P.outerHeight(); // s.outerHeight || - s.resizerLength = paneLen; - $R.css({ - height: cssH($R, paneLen) // account for borders & padding - , width: cssW($R, spacing) // ditto - , top: sC.inset.top + getPaneSize("north", true) // TODO: what if no North pane? - //, top: $.layout.cssNum($Ps["center"], "top") - }); - } - - // remove hover classes - removeHover( o, $R ); - - if ($T) { - if (togLen === 0 || (s.isSliding && o.hideTogglerOnSlide)) { - $T.hide(); // always HIDE the toggler when 'sliding' - return; - } - else - $T.show(); // in case was previously hidden - - if (!(togLen > 0) || togLen === "100%" || togLen > paneLen) { - togLen = paneLen; - offset = 0; - } - else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed - if (isStr(togAlign)) { - switch (togAlign) { - case "top": - case "left": offset = 0; - break; - case "bottom": - case "right": offset = paneLen - togLen; - break; - case "middle": - case "center": - default: offset = round((paneLen - togLen) / 2); // 'default' catches typos - } - } - else { // togAlign = number - var x = parseInt(togAlign, 10); // - if (togAlign >= 0) offset = x; - else offset = paneLen - togLen + x; // NOTE: x is negative! - } - } - - if (dir === "horz") { // north/south - var width = cssW($T, togLen); - $T.css({ - width: width // account for borders & padding - , height: cssH($T, spacing) // ditto - , left: offset // TODO: VERIFY that toggler positions correctly for ALL values - , top: 0 - }); - // CENTER the toggler content SPAN - $T.children(".content").each(function(){ - $TC = $(this); - $TC.css("marginLeft", round((width-$TC.outerWidth())/2)); // could be negative - }); - } - else { // east/west - var height = cssH($T, togLen); - $T.css({ - height: height // account for borders & padding - , width: cssW($T, spacing) // ditto - , top: offset // POSITION the toggler - , left: 0 - }); - // CENTER the toggler content SPAN - $T.children(".content").each(function(){ - $TC = $(this); - $TC.css("marginTop", round((height-$TC.outerHeight())/2)); // could be negative - }); - } - - // remove ALL hover classes - removeHover( 0, $T ); - } - - // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now - if (!state.initialized && (o.initHidden || s.isHidden)) { - $R.hide(); - if ($T) $T.hide(); - } - }); - } - - - /** - * @param {(string|Object)} evt_or_pane - */ -, enableClosable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $T = $Ts[pane] - , o = options[pane] - ; - if (!$T) return; - o.closable = true; - $T .bind("click."+ sID, function(evt){ evt.stopPropagation(); toggle(pane); }) - .css("visibility", "visible") - .css("cursor", "pointer") - .attr("title", state[pane].isClosed ? o.tips.Open : o.tips.Close) // may be blank - .show(); - } - /** - * @param {(string|Object)} evt_or_pane - * @param {boolean=} [hide=false] - */ -, disableClosable = function (evt_or_pane, hide) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $T = $Ts[pane] - ; - if (!$T) return; - options[pane].closable = false; - // is closable is disable, then pane MUST be open! - if (state[pane].isClosed) open(pane, false, true); - $T .unbind("."+ sID) - .css("visibility", hide ? "hidden" : "visible") // instead of hide(), which creates logic issues - .css("cursor", "default") - .attr("title", ""); - } - - - /** - * @param {(string|Object)} evt_or_pane - */ -, enableSlidable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $R = $Rs[pane] - ; - if (!$R || !$R.data('draggable')) return; - options[pane].slidable = true; - if (state[pane].isClosed) - bindStartSlidingEvents(pane, true); - } - /** - * @param {(string|Object)} evt_or_pane - */ -, disableSlidable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $R = $Rs[pane] - ; - if (!$R) return; - options[pane].slidable = false; - if (state[pane].isSliding) - close(pane, false, true); - else { - bindStartSlidingEvents(pane, false); - $R .css("cursor", "default") - .attr("title", ""); - removeHover(null, $R[0]); // in case currently hovered - } - } - - - /** - * @param {(string|Object)} evt_or_pane - */ -, enableResizable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $R = $Rs[pane] - , o = options[pane] - ; - if (!$R || !$R.data('draggable')) return; - o.resizable = true; - $R.draggable("enable"); - if (!state[pane].isClosed) - $R .css("cursor", o.resizerCursor) - .attr("title", o.tips.Resize); - } - /** - * @param {(string|Object)} evt_or_pane - */ -, disableResizable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $R = $Rs[pane] - ; - if (!$R || !$R.data('draggable')) return; - options[pane].resizable = false; - $R .draggable("disable") - .css("cursor", "default") - .attr("title", ""); - removeHover(null, $R[0]); // in case currently hovered - } - - - /** - * Move a pane from source-side (eg, west) to target-side (eg, east) - * If pane exists on target-side, move that to source-side, ie, 'swap' the panes - * - * @param {(string|Object)} evt_or_pane1 The pane/edge being swapped - * @param {string} pane2 ditto - */ -, swapPanes = function (evt_or_pane1, pane2) { - if (!isInitialized()) return; - var pane1 = evtPane.call(this, evt_or_pane1); - // change state.edge NOW so callbacks can know where pane is headed... - state[pane1].edge = pane2; - state[pane2].edge = pane1; - // run these even if NOT state.initialized - if (false === _runCallbacks("onswap_start", pane1) - || false === _runCallbacks("onswap_start", pane2) - ) { - state[pane1].edge = pane1; // reset - state[pane2].edge = pane2; - return; - } - - var - oPane1 = copy( pane1 ) - , oPane2 = copy( pane2 ) - , sizes = {} - ; - sizes[pane1] = oPane1 ? oPane1.state.size : 0; - sizes[pane2] = oPane2 ? oPane2.state.size : 0; - - // clear pointers & state - $Ps[pane1] = false; - $Ps[pane2] = false; - state[pane1] = {}; - state[pane2] = {}; - - // ALWAYS remove the resizer & toggler elements - if ($Ts[pane1]) $Ts[pane1].remove(); - if ($Ts[pane2]) $Ts[pane2].remove(); - if ($Rs[pane1]) $Rs[pane1].remove(); - if ($Rs[pane2]) $Rs[pane2].remove(); - $Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false; - - // transfer element pointers and data to NEW Layout keys - move( oPane1, pane2 ); - move( oPane2, pane1 ); - - // cleanup objects - oPane1 = oPane2 = sizes = null; - - // make panes 'visible' again - if ($Ps[pane1]) $Ps[pane1].css(_c.visible); - if ($Ps[pane2]) $Ps[pane2].css(_c.visible); - - // fix any size discrepancies caused by swap - resizeAll(); - - // run these even if NOT state.initialized - _runCallbacks("onswap_end", pane1); - _runCallbacks("onswap_end", pane2); - - return; - - function copy (n) { // n = pane - var - $P = $Ps[n] - , $C = $Cs[n] - ; - return !$P ? false : { - pane: n - , P: $P ? $P[0] : false - , C: $C ? $C[0] : false - , state: $.extend(true, {}, state[n]) - , options: $.extend(true, {}, options[n]) - } - }; - - function move (oPane, pane) { - if (!oPane) return; - var - P = oPane.P - , C = oPane.C - , oldPane = oPane.pane - , c = _c[pane] - // save pane-options that should be retained - , s = $.extend(true, {}, state[pane]) - , o = options[pane] - // RETAIN side-specific FX Settings - more below - , fx = { resizerCursor: o.resizerCursor } - , re, size, pos - ; - $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) { - fx[k +"_open"] = o[k +"_open"]; - fx[k +"_close"] = o[k +"_close"]; - fx[k +"_size"] = o[k +"_size"]; - }); - - // update object pointers and attributes - $Ps[pane] = $(P) - .data({ - layoutPane: Instance[pane] // NEW pointer to pane-alias-object - , layoutEdge: pane - }) - .css(_c.hidden) - .css(c.cssReq) - ; - $Cs[pane] = C ? $(C) : false; - - // set options and state - options[pane] = $.extend(true, {}, oPane.options, fx); - state[pane] = $.extend(true, {}, oPane.state); - - // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west - re = new RegExp(o.paneClass +"-"+ oldPane, "g"); - P.className = P.className.replace(re, o.paneClass +"-"+ pane); - - // ALWAYS regenerate the resizer & toggler elements - initHandles(pane); // create the required resizer & toggler - - // if moving to different orientation, then keep 'target' pane size - if (c.dir != _c[oldPane].dir) { - size = sizes[pane] || 0; - setSizeLimits(pane); // update pane-state - size = max(size, state[pane].minSize); - // use manualSizePane to disable autoResize - not useful after panes are swapped - manualSizePane(pane, size, true, true); // true/true = skipCallback/noAnimation - } - else // move the resizer here - $Rs[pane].css(c.side, sC.inset[c.side] + (state[pane].isVisible ? getPaneSize(pane) : 0)); - - - // ADD CLASSNAMES & SLIDE-BINDINGS - if (oPane.state.isVisible && !s.isVisible) - setAsOpen(pane, true); // true = skipCallback - else { - setAsClosed(pane); - bindStartSlidingEvents(pane, true); // will enable events IF option is set - } - - // DESTROY the object - oPane = null; - }; - } - - - /** - * INTERNAL method to sync pin-buttons when pane is opened or closed - * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes - * - * @see open(), setAsOpen(), setAsClosed() - * @param {string} pane These are the params returned to callbacks by layout() - * @param {boolean} doPin True means set the pin 'down', False means 'up' - */ -, syncPinBtns = function (pane, doPin) { - if ($.layout.plugins.buttons) - $.each(state[pane].pins, function (i, selector) { - $.layout.buttons.setPinState(Instance, $(selector), pane, doPin); - }); - } - -; // END var DECLARATIONS - - /** - * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed - * - * @see document.keydown() - */ - function keyDown (evt) { - if (!evt) return true; - var code = evt.keyCode; - if (code < 33) return true; // ignore special keys: ENTER, TAB, etc - - var - PANE = { - 38: "north" // Up Cursor - $.ui.keyCode.UP - , 40: "south" // Down Cursor - $.ui.keyCode.DOWN - , 37: "west" // Left Cursor - $.ui.keyCode.LEFT - , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT - } - , ALT = evt.altKey // no worky! - , SHIFT = evt.shiftKey - , CTRL = evt.ctrlKey - , CURSOR = (CTRL && code >= 37 && code <= 40) - , o, k, m, pane - ; - - if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey - pane = PANE[code]; - else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey - $.each(_c.borderPanes, function (i, p) { // loop each pane to check its hotkey - o = options[p]; - k = o.customHotkey; - m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT" - if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches - if (k && code === (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches - pane = p; - return false; // BREAK - } - } - }); - - // validate pane - if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden) - return true; - - toggle(pane); - - evt.stopPropagation(); - evt.returnValue = false; // CANCEL key - return false; - }; - - -/* - * ###################################### - * UTILITY METHODS - * called externally or by initButtons - * ###################################### - */ - - /** - * Change/reset a pane overflow setting & zIndex to allow popups/drop-downs to work - * - * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event - */ - function allowOverflow (el) { - if (!isInitialized()) return; - if (this && this.tagName) el = this; // BOUND to element - var $P; - if (isStr(el)) - $P = $Ps[el]; - else if ($(el).data("layoutRole")) - $P = $(el); - else - $(el).parents().each(function(){ - if ($(this).data("layoutRole")) { - $P = $(this); - return false; // BREAK - } - }); - if (!$P || !$P.length) return; // INVALID - - var - pane = $P.data("layoutEdge") - , s = state[pane] - ; - - // if pane is already raised, then reset it before doing it again! - // this would happen if allowOverflow is attached to BOTH the pane and an element - if (s.cssSaved) - resetOverflow(pane); // reset previous CSS before continuing - - // if pane is raised by sliding or resizing, or its closed, then abort - if (s.isSliding || s.isResizing || s.isClosed) { - s.cssSaved = false; - return; - } - - var - newCSS = { zIndex: (options.zIndexes.resizer_normal + 1) } - , curCSS = {} - , of = $P.css("overflow") - , ofX = $P.css("overflowX") - , ofY = $P.css("overflowY") - ; - // determine which, if any, overflow settings need to be changed - if (of != "visible") { - curCSS.overflow = of; - newCSS.overflow = "visible"; - } - if (ofX && !ofX.match(/(visible|auto)/)) { - curCSS.overflowX = ofX; - newCSS.overflowX = "visible"; - } - if (ofY && !ofY.match(/(visible|auto)/)) { - curCSS.overflowY = ofX; - newCSS.overflowY = "visible"; - } - - // save the current overflow settings - even if blank! - s.cssSaved = curCSS; - - // apply new CSS to raise zIndex and, if necessary, make overflow 'visible' - $P.css( newCSS ); - - // make sure the zIndex of all other panes is normal - $.each(_c.allPanes, function(i, p) { - if (p != pane) resetOverflow(p); - }); - - }; - /** - * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event - */ - function resetOverflow (el) { - if (!isInitialized()) return; - if (this && this.tagName) el = this; // BOUND to element - var $P; - if (isStr(el)) - $P = $Ps[el]; - else if ($(el).data("layoutRole")) - $P = $(el); - else - $(el).parents().each(function(){ - if ($(this).data("layoutRole")) { - $P = $(this); - return false; // BREAK - } - }); - if (!$P || !$P.length) return; // INVALID - - var - pane = $P.data("layoutEdge") - , s = state[pane] - , CSS = s.cssSaved || {} - ; - // reset the zIndex - if (!s.isSliding && !s.isResizing) - $P.css("zIndex", options.zIndexes.pane_normal); - - // reset Overflow - if necessary - $P.css( CSS ); - - // clear var - s.cssSaved = false; - }; - -/* - * ##################### - * CREATE/RETURN LAYOUT - * ##################### - */ - - // validate that container exists - var $N = $(this).eq(0); // FIRST matching Container element - if (!$N.length) { - return _log( options.errors.containerMissing ); - }; - - // Users retrieve Instance of a layout with: $N.layout() OR $N.data("layout") - // return the Instance-pointer if layout has already been initialized - if ($N.data("layoutContainer") && $N.data("layout")) - return $N.data("layout"); // cached pointer - - // init global vars - var - $Ps = {} // Panes x5 - set in initPanes() - , $Cs = {} // Content x5 - set in initPanes() - , $Rs = {} // Resizers x4 - set in initHandles() - , $Ts = {} // Togglers x4 - set in initHandles() - , $Ms = $([]) // Masks - up to 2 masks per pane (IFRAME + DIV) - // aliases for code brevity - , sC = state.container // alias for easy access to 'container dimensions' - , sID = state.id // alias for unique layout ID/namespace - eg: "layout435" - ; - - // create Instance object to expose data & option Properties, and primary action Methods - var Instance = { - // layout data - options: options // property - options hash - , state: state // property - dimensions hash - // object pointers - , container: $N // property - object pointers for layout container - , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center - , contents: $Cs // property - object pointers for ALL Content: contents.north, contents.center - , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north - , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north - // border-pane open/close - , hide: hide // method - ditto - , show: show // method - ditto - , toggle: toggle // method - pass a 'pane' ("north", "west", etc) - , open: open // method - ditto - , close: close // method - ditto - , slideOpen: slideOpen // method - ditto - , slideClose: slideClose // method - ditto - , slideToggle: slideToggle // method - ditto - // pane actions - , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data - , _sizePane: sizePane // method -intended for user by plugins only! - , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto' - , sizeContent: sizeContent // method - pass a 'pane' - , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them - , showMasks: showMasks // method - pass a 'pane' OR list of panes - default = all panes with mask option set - , hideMasks: hideMasks // method - ditto' - // pane element methods - , initContent: initContent // method - ditto - , addPane: addPane // method - pass a 'pane' - , removePane: removePane // method - pass a 'pane' to remove from layout, add 'true' to delete the pane-elem - , createChildren: createChildren // method - pass a 'pane' and (optional) layout-options (OVERRIDES options[pane].children - , refreshChildren: refreshChildren // method - pass a 'pane' and a layout-instance - // special pane option setting - , enableClosable: enableClosable // method - pass a 'pane' - , disableClosable: disableClosable // method - ditto - , enableSlidable: enableSlidable // method - ditto - , disableSlidable: disableSlidable // method - ditto - , enableResizable: enableResizable // method - ditto - , disableResizable: disableResizable// method - ditto - // utility methods for panes - , allowOverflow: allowOverflow // utility - pass calling element (this) - , resetOverflow: resetOverflow // utility - ditto - // layout control - , destroy: destroy // method - no parameters - , initPanes: isInitialized // method - no parameters - , resizeAll: resizeAll // method - no parameters - // callback triggering - , runCallbacks: _runCallbacks // method - pass evtName & pane (if a pane-event), eg: trigger("onopen", "west") - // alias collections of options, state and children - created in addPane and extended elsewhere - , hasParentLayout: false // set by initContainer() - , children: children // pointers to child-layouts, eg: Instance.children.west.layoutName - , north: false // alias group: { name: pane, pane: $Ps[pane], options: options[pane], state: state[pane], children: children[pane] } - , south: false // ditto - , west: false // ditto - , east: false // ditto - , center: false // ditto - }; - - // create the border layout NOW - if (_create() === 'cancel') // onload_start callback returned false to CANCEL layout creation - return null; - else // true OR false -- if layout-elements did NOT init (hidden or do not exist), can auto-init later - return Instance; // return the Instance object - -} - - -})( jQuery ); - - - - -/** - * jquery.layout.state 1.2 - * $Date: 2014-08-30 08:00:00 (Sat, 30 Aug 2014) $ - * - * Copyright (c) 2014 - * Kevin Dalman (http://allpro.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * @requires: UI Layout 1.4.0 or higher - * @requires: $.ui.cookie (above) - * - * @see: http://groups.google.com/group/jquery-ui-layout - */ -;(function ($) { - -if (!$.layout) return; - - -/** - * UI COOKIE UTILITY - * - * A $.cookie OR $.ui.cookie namespace *should be standard*, but until then... - * This creates $.ui.cookie so Layout does not need the cookie.jquery.js plugin - * NOTE: This utility is REQUIRED by the layout.state plugin - * - * Cookie methods in Layout are created as part of State Management - */ -if (!$.ui) $.ui = {}; -$.ui.cookie = { - - // cookieEnabled is not in DOM specs, but DOES works in all browsers,including IE6 - acceptsCookies: !!navigator.cookieEnabled - -, read: function (name) { - var - c = document.cookie - , cs = c ? c.split(';') : [] - , pair, data, i - ; - for (i=0; pair=cs[i]; i++) { - data = $.trim(pair).split('='); // name=value => [ name, value ] - if (data[0] == name) // found the layout cookie - return decodeURIComponent(data[1]); - } - return null; - } - -, write: function (name, val, cookieOpts) { - var params = "" - , date = "" - , clear = false - , o = cookieOpts || {} - , x = o.expires || null - , t = $.type(x) - ; - if (t === "date") - date = x; - else if (t === "string" && x > 0) { - x = parseInt(x,10); - t = "number"; - } - if (t === "number") { - date = new Date(); - if (x > 0) - date.setDate(date.getDate() + x); - else { - date.setFullYear(1970); - clear = true; - } - } - if (date) params += ";expires="+ date.toUTCString(); - if (o.path) params += ";path="+ o.path; - if (o.domain) params += ";domain="+ o.domain; - if (o.secure) params += ";secure"; - document.cookie = name +"="+ (clear ? "" : encodeURIComponent( val )) + params; // write or clear cookie - } - -, clear: function (name) { - $.ui.cookie.write(name, "", {expires: -1}); - } - -}; -// if cookie.jquery.js is not loaded, create an alias to replicate it -// this may be useful to other plugins or code dependent on that plugin -if (!$.cookie) $.cookie = function (k, v, o) { - var C = $.ui.cookie; - if (v === null) - C.clear(k); - else if (v === undefined) - return C.read(k); - else - C.write(k, v, o); -}; - - - -/** - * State-management options stored in options.stateManagement, which includes a .cookie hash - * Default options saves ALL KEYS for ALL PANES, ie: pane.size, pane.isClosed, pane.isHidden - * - * // STATE/COOKIE OPTIONS - * @example $(el).layout({ - stateManagement: { - enabled: true - , stateKeys: "east.size,west.size,east.isClosed,west.isClosed" - , cookie: { name: "appLayout", path: "/" } - } - }) - * @example $(el).layout({ stateManagement__enabled: true }) // enable auto-state-management using cookies - * @example $(el).layout({ stateManagement__cookie: { name: "appLayout", path: "/" } }) - * @example $(el).layout({ stateManagement__cookie__name: "appLayout", stateManagement__cookie__path: "/" }) - * - * // STATE/COOKIE METHODS - * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} ); - * @example myLayout.loadCookie(); - * @example myLayout.deleteCookie(); - * @example var JSON = myLayout.readState(); // CURRENT Layout State - * @example var JSON = myLayout.readCookie(); // SAVED Layout State (from cookie) - * @example var JSON = myLayout.state.stateData; // LAST LOADED Layout State (cookie saved in layout.state hash) - * - * CUSTOM STATE-MANAGEMENT (eg, saved in a database) - * @example var JSON = myLayout.readState( "west.isClosed,north.size,south.isHidden" ); - * @example myLayout.loadState( JSON ); - */ - -// tell Layout that the state plugin is available -$.layout.plugins.stateManagement = true; - -// Add State-Management options to layout.defaults -$.layout.defaults.stateManagement = { - enabled: false // true = enable state-management, even if not using cookies -, autoSave: true // Save a state-cookie when page exits? -, autoLoad: true // Load the state-cookie when Layout inits? -, animateLoad: true // animate panes when loading state into an active layout -, includeChildren: true // recurse into child layouts to include their state as well - // List state-data to save - must be pane-specific -, stateKeys: "north.size,south.size,east.size,west.size,"+ - "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ - "north.isHidden,south.isHidden,east.isHidden,west.isHidden" -, cookie: { - name: "" // If not specified, will use Layout.name, else just "Layout" - , domain: "" // blank = current domain - , path: "" // blank = current page, "/" = entire website - , expires: "" // 'days' to keep cookie - leave blank for 'session cookie' - , secure: false - } -}; - -// Set stateManagement as a 'layout-option', NOT a 'pane-option' -$.layout.optionsMap.layout.push("stateManagement"); -// Update config so layout does not move options into the pane-default branch (panes) -$.layout.config.optionRootKeys.push("stateManagement"); - -/* - * State Management methods - */ -$.layout.state = { - - /** - * Get the current layout state and save it to a cookie - * - * myLayout.saveCookie( keys, cookieOpts ) - * - * @param {Object} inst - * @param {(string|Array)=} keys - * @param {Object=} cookieOpts - */ - saveCookie: function (inst, keys, cookieOpts) { - var o = inst.options - , sm = o.stateManagement - , oC = $.extend(true, {}, sm.cookie, cookieOpts || null) - , data = inst.state.stateData = inst.readState( keys || sm.stateKeys ) // read current panes-state - ; - $.ui.cookie.write( oC.name || o.name || "Layout", $.layout.state.encodeJSON(data), oC ); - return $.extend(true, {}, data); // return COPY of state.stateData data - } - - /** - * Remove the state cookie - * - * @param {Object} inst - */ -, deleteCookie: function (inst) { - var o = inst.options; - $.ui.cookie.clear( o.stateManagement.cookie.name || o.name || "Layout" ); - } - - /** - * Read & return data from the cookie - as JSON - * - * @param {Object} inst - */ -, readCookie: function (inst) { - var o = inst.options; - var c = $.ui.cookie.read( o.stateManagement.cookie.name || o.name || "Layout" ); - // convert cookie string back to a hash and return it - return c ? $.layout.state.decodeJSON(c) : {}; - } - - /** - * Get data from the cookie and USE IT to loadState - * - * @param {Object} inst - */ -, loadCookie: function (inst) { - var c = $.layout.state.readCookie(inst); // READ the cookie - if (c && !$.isEmptyObject( c )) { - inst.state.stateData = $.extend(true, {}, c); // SET state.stateData - inst.loadState(c); // LOAD the retrieved state - } - return c; - } - - /** - * Update layout options from the cookie, if one exists - * - * @param {Object} inst - * @param {Object=} stateData - * @param {boolean=} animate - */ -, loadState: function (inst, data, opts) { - if (!$.isPlainObject( data ) || $.isEmptyObject( data )) return; - - // normalize data & cache in the state object - data = inst.state.stateData = $.layout.transformData( data ); // panes = default subkey - - // add missing/default state-restore options - var smo = inst.options.stateManagement; - opts = $.extend({ - animateLoad: false //smo.animateLoad - , includeChildren: smo.includeChildren - }, opts ); - - if (!inst.state.initialized) { - /* - * layout NOT initialized, so just update its options - */ - // MUST remove pane.children keys before applying to options - // use a copy so we don't remove keys from original data - var o = $.extend(true, {}, data); - //delete o.center; // center has no state-data - only children - $.each($.layout.config.allPanes, function (idx, pane) { - if (o[pane]) delete o[pane].children; - }); - // update CURRENT layout-options with saved state data - $.extend(true, inst.options, o); - } - else { - /* - * layout already initialized, so modify layout's configuration - */ - var noAnimate = !opts.animateLoad - , o, c, h, state, open - ; - $.each($.layout.config.borderPanes, function (idx, pane) { - o = data[ pane ]; - if (!$.isPlainObject( o )) return; // no key, skip pane - - s = o.size; - c = o.initClosed; - h = o.initHidden; - ar = o.autoResize - state = inst.state[pane]; - open = state.isVisible; - - // reset autoResize - if (ar) - state.autoResize = ar; - // resize BEFORE opening - if (!open) - inst._sizePane(pane, s, false, false, false); // false=skipCallback/noAnimation/forceResize - // open/close as necessary - DO NOT CHANGE THIS ORDER! - if (h === true) inst.hide(pane, noAnimate); - else if (c === true) inst.close(pane, false, noAnimate); - else if (c === false) inst.open (pane, false, noAnimate); - else if (h === false) inst.show (pane, false, noAnimate); - // resize AFTER any other actions - if (open) - inst._sizePane(pane, s, false, false, noAnimate); // animate resize if option passed - }); - - /* - * RECURSE INTO CHILD-LAYOUTS - */ - if (opts.includeChildren) { - var paneStateChildren, childState; - $.each(inst.children, function (pane, paneChildren) { - paneStateChildren = data[pane] ? data[pane].children : 0; - if (paneStateChildren && paneChildren) { - $.each(paneChildren, function (stateKey, child) { - childState = paneStateChildren[stateKey]; - if (child && childState) - child.loadState( childState ); - }); - } - }); - } - } - } - - /** - * Get the *current layout state* and return it as a hash - * - * @param {Object=} inst // Layout instance to get state for - * @param {object=} [opts] // State-Managements override options - */ -, readState: function (inst, opts) { - // backward compatility - if ($.type(opts) === 'string') opts = { keys: opts }; - if (!opts) opts = {}; - var sm = inst.options.stateManagement - , ic = opts.includeChildren - , recurse = ic !== undefined ? ic : sm.includeChildren - , keys = opts.stateKeys || sm.stateKeys - , alt = { isClosed: 'initClosed', isHidden: 'initHidden' } - , state = inst.state - , panes = $.layout.config.allPanes - , data = {} - , pair, pane, key, val - , ps, pC, child, array, count, branch - ; - if ($.isArray(keys)) keys = keys.join(","); - // convert keys to an array and change delimiters from '__' to '.' - keys = keys.replace(/__/g, ".").split(','); - // loop keys and create a data hash - for (var i=0, n=keys.length; i < n; i++) { - pair = keys[i].split("."); - pane = pair[0]; - key = pair[1]; - if ($.inArray(pane, panes) < 0) continue; // bad pane! - val = state[ pane ][ key ]; - if (val == undefined) continue; - if (key=="isClosed" && state[pane]["isSliding"]) - val = true; // if sliding, then *really* isClosed - ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val; - } - - // recurse into the child-layouts for each pane - if (recurse) { - $.each(panes, function (idx, pane) { - pC = inst.children[pane]; - ps = state.stateData[pane]; - if ($.isPlainObject( pC ) && !$.isEmptyObject( pC )) { - // ensure a key exists for this 'pane', eg: branch = data.center - branch = data[pane] || (data[pane] = {}); - if (!branch.children) branch.children = {}; - $.each( pC, function (key, child) { - // ONLY read state from an initialize layout - if ( child.state.initialized ) - branch.children[ key ] = $.layout.state.readState( child ); - // if we have PREVIOUS (onLoad) state for this child-layout, KEEP IT! - else if ( ps && ps.children && ps.children[ key ] ) { - branch.children[ key ] = $.extend(true, {}, ps.children[ key ] ); - } - }); - } - }); - } - - return data; - } - - /** - * Stringify a JSON hash so can save in a cookie or db-field - */ -, encodeJSON: function (json) { - var local = window.JSON || {}; - return (local.stringify || stringify)(json); - - function stringify (h) { - var D=[], i=0, k, v, t // k = key, v = value - , a = $.isArray(h) - ; - for (k in h) { - v = h[k]; - t = typeof v; - if (t == 'string') // STRING - add quotes - v = '"'+ v +'"'; - else if (t == 'object') // SUB-KEY - recurse into it - v = parse(v); - D[i++] = (!a ? '"'+ k +'":' : '') + v; - } - return (a ? '[' : '{') + D.join(',') + (a ? ']' : '}'); - }; - } - - /** - * Convert stringified JSON back to a hash object - * @see $.parseJSON(), adding in jQuery 1.4.1 - */ -, decodeJSON: function (str) { - try { return $.parseJSON ? $.parseJSON(str) : window["eval"]("("+ str +")") || {}; } - catch (e) { return {}; } - } - - -, _create: function (inst) { - var s = $.layout.state - , o = inst.options - , sm = o.stateManagement - ; - // ADD State-Management plugin methods to inst - $.extend( inst, { - // readCookie - update options from cookie - returns hash of cookie data - readCookie: function () { return s.readCookie(inst); } - // deleteCookie - , deleteCookie: function () { s.deleteCookie(inst); } - // saveCookie - optionally pass keys-list and cookie-options (hash) - , saveCookie: function (keys, cookieOpts) { return s.saveCookie(inst, keys, cookieOpts); } - // loadCookie - readCookie and use to loadState() - returns hash of cookie data - , loadCookie: function () { return s.loadCookie(inst); } - // loadState - pass a hash of state to use to update options - , loadState: function (stateData, opts) { s.loadState(inst, stateData, opts); } - // readState - returns hash of current layout-state - , readState: function (keys) { return s.readState(inst, keys); } - // add JSON utility methods too... - , encodeJSON: s.encodeJSON - , decodeJSON: s.decodeJSON - }); - - // init state.stateData key, even if plugin is initially disabled - inst.state.stateData = {}; - - // autoLoad MUST BE one of: data-array, data-hash, callback-function, or TRUE - if ( !sm.autoLoad ) return; - - // When state-data exists in the autoLoad key USE IT, - // even if stateManagement.enabled == false - if ($.isPlainObject( sm.autoLoad )) { - if (!$.isEmptyObject( sm.autoLoad )) { - inst.loadState( sm.autoLoad ); - } - } - else if ( sm.enabled ) { - // update the options from cookie or callback - // if options is a function, call it to get stateData - if ($.isFunction( sm.autoLoad )) { - var d = {}; - try { - d = sm.autoLoad( inst, inst.state, inst.options, inst.options.name || '' ); // try to get data from fn - } catch (e) {} - if (d && $.isPlainObject( d ) && !$.isEmptyObject( d )) - inst.loadState(d); - } - else // any other truthy value will trigger loadCookie - inst.loadCookie(); - } - } - -, _unload: function (inst) { - var sm = inst.options.stateManagement; - if (sm.enabled && sm.autoSave) { - // if options is a function, call it to save the stateData - if ($.isFunction( sm.autoSave )) { - try { - sm.autoSave( inst, inst.state, inst.options, inst.options.name || '' ); // try to get data from fn - } catch (e) {} - } - else // any truthy value will trigger saveCookie - inst.saveCookie(); - } - } - -}; - -// add state initialization method to Layout's onCreate array of functions -$.layout.onCreate.push( $.layout.state._create ); -$.layout.onUnload.push( $.layout.state._unload ); - -})( jQuery ); - - - -/** - * @preserve jquery.layout.buttons 1.0 - * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ - * - * Copyright (c) 2011 - * Kevin Dalman (http://allpro.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * @dependancies: UI Layout 1.3.0.rc30.1 or higher - * - * @support: http://groups.google.com/group/jquery-ui-layout - * - * Docs: [ to come ] - * Tips: [ to come ] - */ -;(function ($) { - -if (!$.layout) return; - - -// tell Layout that the state plugin is available -$.layout.plugins.buttons = true; - -// Add State-Management options to layout.defaults -$.layout.defaults.autoBindCustomButtons = false; -// Set stateManagement as a layout-option, NOT a pane-option -$.layout.optionsMap.layout.push("autoBindCustomButtons"); - -/* - * Button methods - */ -$.layout.buttons = { - // set data used by multiple methods below - config: { - borderPanes: "north,south,west,east" - } - - /** - * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons - * - * @see _create() - */ -, init: function (inst) { - var pre = "ui-layout-button-" - , layout = inst.options.name || "" - , name; - $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) { - $.each($.layout.buttons.config.borderPanes.split(","), function (ii, pane) { - $("."+pre+action+"-"+pane).each(function(){ - // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name' - name = $(this).data("layoutName") || $(this).attr("layoutName"); - if (name == undefined || name === layout) - inst.bindButton(this, action, pane); - }); - }); - }); - } - - /** - * Helper function to validate params received by addButton utilities - * - * Two classes are added to the element, based on the buttonClass... - * The type of button is appended to create the 2nd className: - * - ui-layout-button-pin - * - ui-layout-pane-button-toggle - * - ui-layout-pane-button-open - * - ui-layout-pane-button-close - * - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. - * @return {Array.} If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null - */ -, get: function (inst, selector, pane, action) { - var $E = $(selector) - , o = inst.options - //, err = o.showErrorMessages - ; - if ($E.length && $.layout.buttons.config.borderPanes.indexOf(pane) >= 0) { - var btn = o[pane].buttonClass +"-"+ action; - $E .addClass( btn +" "+ btn +"-"+ pane ) - .data("layoutName", o.name); // add layout identifier - even if blank! - } - return $E; - } - - - /** - * NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc. - * - * @param {(string|!Object)} sel jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} action - * @param {string} pane - */ -, bind: function (inst, sel, action, pane) { - var _ = $.layout.buttons; - switch (action.toLowerCase()) { - case "toggle": _.addToggle (inst, sel, pane); break; - case "open": _.addOpen (inst, sel, pane); break; - case "close": _.addClose (inst, sel, pane); break; - case "pin": _.addPin (inst, sel, pane); break; - case "toggle-slide": _.addToggle (inst, sel, pane, true); break; - case "open-slide": _.addOpen (inst, sel, pane, true); break; - } - return inst; - } - - /** - * Add a custom Toggler button for a pane - * - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. - * @param {boolean=} slide true = slide-open, false = pin-open - */ -, addToggle: function (inst, selector, pane, slide) { - $.layout.buttons.get(inst, selector, pane, "toggle") - .click(function(evt){ - inst.toggle(pane, !!slide); - evt.stopPropagation(); - }); - return inst; - } - - /** - * Add a custom Open button for a pane - * - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. - * @param {boolean=} slide true = slide-open, false = pin-open - */ -, addOpen: function (inst, selector, pane, slide) { - $.layout.buttons.get(inst, selector, pane, "open") - .attr("title", inst.options[pane].tips.Open) - .click(function (evt) { - inst.open(pane, !!slide); - evt.stopPropagation(); - }); - return inst; - } - - /** - * Add a custom Close button for a pane - * - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. - */ -, addClose: function (inst, selector, pane) { - $.layout.buttons.get(inst, selector, pane, "close") - .attr("title", inst.options[pane].tips.Close) - .click(function (evt) { - inst.close(pane); - evt.stopPropagation(); - }); - return inst; - } - - /** - * Add a custom Pin button for a pane - * - * Four classes are added to the element, based on the paneClass for the associated pane... - * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin: - * - ui-layout-pane-pin - * - ui-layout-pane-west-pin - * - ui-layout-pane-pin-up - * - ui-layout-pane-west-pin-up - * - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the pin is for: 'north', 'south', etc. - */ -, addPin: function (inst, selector, pane) { - var $E = $.layout.buttons.get(inst, selector, pane, "pin"); - if ($E.length) { - var s = inst.state[pane]; - $E.click(function (evt) { - $.layout.buttons.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed)); - if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open - else inst.close( pane ); // slide-closed - evt.stopPropagation(); - }); - // add up/down pin attributes and classes - $.layout.buttons.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding)); - // add this pin to the pane data so we can 'sync it' automatically - // PANE.pins key is an array so we can store multiple pins for each pane - s.pins.push( selector ); // just save the selector string - } - return inst; - } - - /** - * Change the class of the pin button to make it look 'up' or 'down' - * - * @see addPin(), syncPins() - * @param {Array.} $Pin The pin-span element in a jQuery wrapper - * @param {string} pane These are the params returned to callbacks by layout() - * @param {boolean} doPin true = set the pin 'down', false = set it 'up' - */ -, setPinState: function (inst, $Pin, pane, doPin) { - var updown = $Pin.attr("pin"); - if (updown && doPin === (updown=="down")) return; // already in correct state - var - po = inst.options[pane] - , lang = po.tips - , pin = po.buttonClass +"-pin" - , side = pin +"-"+ pane - , UP = pin +"-up "+ side +"-up" - , DN = pin +"-down "+side +"-down" - ; - $Pin - .attr("pin", doPin ? "down" : "up") // logic - .attr("title", doPin ? lang.Unpin : lang.Pin) - .removeClass( doPin ? UP : DN ) - .addClass( doPin ? DN : UP ) - ; - } - - /** - * INTERNAL function to sync 'pin buttons' when pane is opened or closed - * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes - * - * @see open(), close() - * @param {string} pane These are the params returned to callbacks by layout() - * @param {boolean} doPin True means set the pin 'down', False means 'up' - */ -, syncPinBtns: function (inst, pane, doPin) { - // REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE - $.each(state[pane].pins, function (i, selector) { - $.layout.buttons.setPinState(inst, $(selector), pane, doPin); - }); - } - - -, _load: function (inst) { - // ADD Button methods to Layout Instance - $.extend( inst, { - bindButton: function (selector, action, pane) { return $.layout.buttons.bind(inst, selector, action, pane); } - // DEPRECATED METHODS... - , addToggleBtn: function (selector, pane, slide) { return $.layout.buttons.addToggle(inst, selector, pane, slide); } - , addOpenBtn: function (selector, pane, slide) { return $.layout.buttons.addOpen(inst, selector, pane, slide); } - , addCloseBtn: function (selector, pane) { return $.layout.buttons.addClose(inst, selector, pane); } - , addPinBtn: function (selector, pane) { return $.layout.buttons.addPin(inst, selector, pane); } - }); - - // init state array to hold pin-buttons - for (var i=0; i<4; i++) { - var pane = $.layout.buttons.config.borderPanes[i]; - inst.state[pane].pins = []; - } - - // auto-init buttons onLoad if option is enabled - if ( inst.options.autoBindCustomButtons ) - $.layout.buttons.init(inst); - } - -, _unload: function (inst) { - // TODO: unbind all buttons??? - } - -}; - -// add initialization method to Layout's onLoad array of functions -$.layout.onLoad.push( $.layout.buttons._load ); -//$.layout.onUnload.push( $.layout.buttons._unload ); - -})( jQuery ); - - - - -/** - * jquery.layout.browserZoom 1.0 - * $Date: 2011-12-29 08:00:00 (Thu, 29 Dec 2011) $ - * - * Copyright (c) 2012 - * Kevin Dalman (http://allpro.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * @requires: UI Layout 1.3.0.rc30.1 or higher - * - * @see: http://groups.google.com/group/jquery-ui-layout - * - * TODO: Extend logic to handle other problematic zooming in browsers - * TODO: Add hotkey/mousewheel bindings to _instantly_ respond to these zoom event - */ -(function ($) { - -// tell Layout that the plugin is available -$.layout.plugins.browserZoom = true; - -$.layout.defaults.browserZoomCheckInterval = 1000; -$.layout.optionsMap.layout.push("browserZoomCheckInterval"); - -/* - * browserZoom methods - */ -$.layout.browserZoom = { - - _init: function (inst) { - // abort if browser does not need this check - if ($.layout.browserZoom.ratio() !== false) - $.layout.browserZoom._setTimer(inst); - } - -, _setTimer: function (inst) { - // abort if layout destroyed or browser does not need this check - if (inst.destroyed) return; - var o = inst.options - , s = inst.state - // don't need check if inst has parentLayout, but check occassionally in case parent destroyed! - // MINIMUM 100ms interval, for performance - , ms = inst.hasParentLayout ? 5000 : Math.max( o.browserZoomCheckInterval, 100 ) - ; - // set the timer - setTimeout(function(){ - if (inst.destroyed || !o.resizeWithWindow) return; - var d = $.layout.browserZoom.ratio(); - if (d !== s.browserZoom) { - s.browserZoom = d; - inst.resizeAll(); - } - // set a NEW timeout - $.layout.browserZoom._setTimer(inst); - } - , ms ); - } - -, ratio: function () { - var w = window - , s = screen - , d = document - , dE = d.documentElement || d.body - , b = $.layout.browser - , v = b.version - , r, sW, cW - ; - // we can ignore all browsers that fire window.resize event onZoom - if (!b.msie || v > 8) - return false; // don't need to track zoom - if (s.deviceXDPI && s.systemXDPI) // syntax compiler hack - return calc(s.deviceXDPI, s.systemXDPI); - // everything below is just for future reference! - if (b.webkit && (r = d.body.getBoundingClientRect)) - return calc((r.left - r.right), d.body.offsetWidth); - if (b.webkit && (sW = w.outerWidth)) - return calc(sW, w.innerWidth); - if ((sW = s.width) && (cW = dE.clientWidth)) - return calc(sW, cW); - return false; // no match, so cannot - or don't need to - track zoom - - function calc (x,y) { return (parseInt(x,10) / parseInt(y,10) * 100).toFixed(); } - } - -}; -// add initialization method to Layout's onLoad array of functions -$.layout.onReady.push( $.layout.browserZoom._init ); - - -})( jQuery ); - - - - -/** - * UI Layout Plugin: Slide-Offscreen Animation - * - * Prevent panes from being 'hidden' so that an iframes/objects - * does not reload/refresh when pane 'opens' again. - * This plug-in adds a new animation called "slideOffscreen". - * It is identical to the normal "slide" effect, but avoids hiding the element - * - * Requires Layout 1.3.0.RC30.1 or later for Close offscreen - * Requires Layout 1.3.0.RC30.5 or later for Hide, initClosed & initHidden offscreen - * - * Version: 1.1 - 2012-11-18 - * Author: Kevin Dalman (kevin@jquery-dev.com) - * @preserve jquery.layout.slideOffscreen-1.1.js - */ -;(function ($) { - -// Add a new "slideOffscreen" effect -if ($.effects) { - - // add an option so initClosed and initHidden will work - $.layout.defaults.panes.useOffscreenClose = false; // user must enable when needed - /* set the new animation as the default for all panes - $.layout.defaults.panes.fxName = "slideOffscreen"; - */ - - if ($.layout.plugins) - $.layout.plugins.effects.slideOffscreen = true; - - // dupe 'slide' effect defaults as new effect defaults - $.layout.effects.slideOffscreen = $.extend(true, {}, $.layout.effects.slide); - - // add new effect to jQuery UI - $.effects.slideOffscreen = function(o) { - return this.queue(function(){ - - var fx = $.effects - , opt = o.options - , $el = $(this) - , pane = $el.data('layoutEdge') - , state = $el.data('parentLayout').state - , dist = state[pane].size - , s = this.style - , props = ['top','bottom','left','right'] - // Set options - , mode = fx.setMode($el, opt.mode || 'show') // Set Mode - , show = (mode == 'show') - , dir = opt.direction || 'left' // Default Direction - , ref = (dir == 'up' || dir == 'down') ? 'top' : 'left' - , pos = (dir == 'up' || dir == 'left') - , offscrn = $.layout.config.offscreenCSS || {} - , keyLR = $.layout.config.offscreenReset - , keyTB = 'offscreenResetTop' // only used internally - , animation = {} - ; - // Animation settings - animation[ref] = (show ? (pos ? '+=' : '-=') : (pos ? '-=' : '+=')) + dist; - - if (show) { // show() animation, so save top/bottom but retain left/right set when 'hidden' - $el.data(keyTB, { top: s.top, bottom: s.bottom }); - - // set the top or left offset in preparation for animation - // Note: ALL animations work by shifting the top or left edges - if (pos) { // top (north) or left (west) - $el.css(ref, isNaN(dist) ? "-" + dist : -dist); // Shift outside the left/top edge - } - else { // bottom (south) or right (east) - shift all the way across container - if (dir === 'right') - $el.css({ left: state.container.layoutWidth, right: 'auto' }); - else // dir === bottom - $el.css({ top: state.container.layoutHeight, bottom: 'auto' }); - } - // restore the left/right setting if is a top/bottom animation - if (ref === 'top') - $el.css( $el.data( keyLR ) || {} ); - } - else { // hide() animation, so save ALL CSS - $el.data(keyTB, { top: s.top, bottom: s.bottom }); - $el.data(keyLR, { left: s.left, right: s.right }); - } - - // Animate - $el.show().animate(animation, { queue: false, duration: o.duration, easing: opt.easing, complete: function(){ - // Restore top/bottom - if ($el.data( keyTB )) - $el.css($el.data( keyTB )).removeData( keyTB ); - if (show) // Restore left/right too - $el.css($el.data( keyLR ) || {}).removeData( keyLR ); - else // Move the pane off-screen (left: -99999, right: 'auto') - $el.css( offscrn ); - - if (o.callback) o.callback.apply(this, arguments); // Callback - $el.dequeue(); - }}); - - }); - }; - -} - -})( jQuery ); +/** + * @preserve + * jquery.layout 1.4.4 + * $Date: 2014-11-29 08:00:00 (Sat, 29 November 2014) $ + * $Rev: 1.0404 $ + * + * Copyright (c) 2014 Kevin Dalman (http://jquery-dev.com) + * Based on work by Fabrizio Balliano (http://www.fabrizioballiano.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * SEE: http://layout.jquery-dev.com/LICENSE.txt + * + * Changelog: http://layout.jquery-dev.com/changelog.cfm + * + * Docs: http://layout.jquery-dev.com/documentation.html + * Tips: http://layout.jquery-dev.com/tips.html + * Help: http://groups.google.com/group/jquery-ui-layout + */ + +/* JavaDoc Info: http://code.google.com/closure/compiler/docs/js-for-compiler.html + * {!Object} non-nullable type (never NULL) + * {?string} nullable type (sometimes NULL) - default for {Object} + * {number=} optional parameter + * {*} ALL types + */ +/* TODO for jQ 2.x + * check $.fn.disableSelection - this is in jQuery UI 1.9.x + */ + +// NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars + +;(function ($) { + +// alias Math methods - used a lot! +var min = Math.min +, max = Math.max +, round = Math.floor + +, isStr = function (v) { return $.type(v) === "string"; } + + /** + * @param {!Object} Instance + * @param {Array.} a_fn + */ +, runPluginCallbacks = function (Instance, a_fn) { + if ($.isArray(a_fn)) + for (var i=0, c=a_fn.length; i').appendTo("body") + , d = { width: $c.outerWidth - $c[0].clientWidth, height: 100 - $c[0].clientHeight }; + $c.remove(); + window.scrollbarWidth = d.width; + window.scrollbarHeight = d.height; + return dim.match(/^(width|height)$/) ? d[dim] : d; + } + + +, disableTextSelection: function () { + var $d = $(document) + , s = 'textSelectionDisabled' + , x = 'textSelectionInitialized' + ; + if ($.fn.disableSelection) { + if (!$d.data(x)) // document hasn't been initialized yet + $d.on('mouseup', $.layout.enableTextSelection ).data(x, true); + if (!$d.data(s)) + $d.disableSelection().data(s, true); + } + } +, enableTextSelection: function () { + var $d = $(document) + , s = 'textSelectionDisabled'; + if ($.fn.enableSelection && $d.data(s)) + $d.enableSelection().data(s, false); + } + + + /** + * Returns hash container 'display' and 'visibility' + * + * @see $.swap() - swaps CSS, runs callback, resets CSS + * @param {!Object} $E jQuery element + * @param {boolean=} [force=false] Run even if display != none + * @return {!Object} Returns current style props, if applicable + */ +, showInvisibly: function ($E, force) { + if ($E && $E.length && (force || $E.css("display") === "none")) { // only if not *already hidden* + var s = $E[0].style + // save ONLY the 'style' props because that is what we must restore + , CSS = { display: s.display || '', visibility: s.visibility || '' }; + // show element 'invisibly' so can be measured + $E.css({ display: "block", visibility: "hidden" }); + return CSS; + } + return {}; + } + + /** + * Returns data for setting size of an element (container or a pane). + * + * @see _create(), onWindowResize() for container, plus others for pane + * @return JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc + */ +, getElementDimensions: function ($E, inset) { + var + // dimensions hash - start with current data IF passed + d = { css: {}, inset: {} } + , x = d.css // CSS hash + , i = { bottom: 0 } // TEMP insets (bottom = complier hack) + , N = $.layout.cssNum + , R = Math.round + , off = $E.offset() + , b, p, ei // TEMP border, padding + ; + d.offsetLeft = off.left; + d.offsetTop = off.top; + + if (!inset) inset = {}; // simplify logic below + + $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { // e = edge + b = x["border" + e] = $.layout.borderWidth($E, e); + p = x["padding"+ e] = $.layout.cssNum($E, "padding"+e); + ei = e.toLowerCase(); + d.inset[ei] = inset[ei] >= 0 ? inset[ei] : p; // any missing insetX value = paddingX + i[ei] = d.inset[ei] + b; // total offset of content from outer side + }); + + x.width = R($E.width()); + x.height = R($E.height()); + x.top = N($E,"top",true); + x.bottom = N($E,"bottom",true); + x.left = N($E,"left",true); + x.right = N($E,"right",true); + + d.outerWidth = R($E.outerWidth()); + d.outerHeight = R($E.outerHeight()); + // calc the TRUE inner-dimensions, even in quirks-mode! + d.innerWidth = max(0, d.outerWidth - i.left - i.right); + d.innerHeight = max(0, d.outerHeight - i.top - i.bottom); + // layoutWidth/Height is used in calcs for manual resizing + // layoutW/H only differs from innerW/H when in quirks-mode - then is like outerW/H + d.layoutWidth = R($E.innerWidth()); + d.layoutHeight = R($E.innerHeight()); + + //if ($E.prop('tagName') === 'BODY') { debugData( d, $E.prop('tagName') ); } // DEBUG + + //d.visible = $E.is(":visible");// && x.width > 0 && x.height > 0; + + return d; + } + +, getElementStyles: function ($E, list) { + var + CSS = {} + , style = $E[0].style + , props = list.split(",") + , sides = "Top,Bottom,Left,Right".split(",") + , attrs = "Color,Style,Width".split(",") + , p, s, a, i, j, k + ; + for (i=0; i < props.length; i++) { + p = props[i]; + if (p.match(/(border|padding|margin)$/)) + for (j=0; j < 4; j++) { + s = sides[j]; + if (p === "border") + for (k=0; k < 3; k++) { + a = attrs[k]; + CSS[p+s+a] = style[p+s+a]; + } + else + CSS[p+s] = style[p+s]; + } + else + CSS[p] = style[p]; + }; + return CSS + } + + /** + * Return the innerWidth for the current browser/doctype + * + * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {number=} outerWidth (optional) Can pass a width, allowing calculations BEFORE element is resized + * @return {number} Returns the innerWidth of the elem by subtracting padding and borders + */ +, cssWidth: function ($E, outerWidth) { + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerWidth <= 0) return 0; + + var lb = $.layout.browser + , bs = !lb.boxModel ? "border-box" : lb.boxSizing ? $E.css("boxSizing") : "content-box" + , b = $.layout.borderWidth + , n = $.layout.cssNum + , W = outerWidth + ; + // strip border and/or padding from outerWidth to get CSS Width + if (bs !== "border-box") + W -= (b($E, "Left") + b($E, "Right")); + if (bs === "content-box") + W -= (n($E, "paddingLeft") + n($E, "paddingRight")); + return max(0,W); + } + + /** + * Return the innerHeight for the current browser/doctype + * + * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {number=} outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized + * @return {number} Returns the innerHeight of the elem by subtracting padding and borders + */ +, cssHeight: function ($E, outerHeight) { + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerHeight <= 0) return 0; + + var lb = $.layout.browser + , bs = !lb.boxModel ? "border-box" : lb.boxSizing ? $E.css("boxSizing") : "content-box" + , b = $.layout.borderWidth + , n = $.layout.cssNum + , H = outerHeight + ; + // strip border and/or padding from outerHeight to get CSS Height + if (bs !== "border-box") + H -= (b($E, "Top") + b($E, "Bottom")); + if (bs === "content-box") + H -= (n($E, "paddingTop") + n($E, "paddingBottom")); + return max(0,H); + } + + /** + * Returns the 'current CSS numeric value' for a CSS property - 0 if property does not exist + * + * @see Called by many methods + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {string} prop The name of the CSS property, eg: top, width, etc. + * @param {boolean=} [allowAuto=false] true = return 'auto' if that is value; false = return 0 + * @return {(string|number)} Usually used to get an integer value for position (top, left) or size (height, width) + */ +, cssNum: function ($E, prop, allowAuto) { + if (!$E.jquery) $E = $($E); + var CSS = $.layout.showInvisibly($E) + , p = $.css($E[0], prop, true) + , v = allowAuto && p=="auto" ? p : Math.round(parseFloat(p) || 0); + $E.css( CSS ); // RESET + return v; + } + +, borderWidth: function (el, side) { + if (el.jquery) el = el[0]; + var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left + return $.css(el, b+"Style", true) === "none" ? 0 : Math.round(parseFloat($.css(el, b+"Width", true)) || 0); + } + + /** + * Mouse-tracking utility - FUTURE REFERENCE + * + * init: if (!window.mouse) { + * window.mouse = { x: 0, y: 0 }; + * $(document).mousemove( $.layout.trackMouse ); + * } + * + * @param {Object} evt + * +, trackMouse: function (evt) { + window.mouse = { x: evt.clientX, y: evt.clientY }; + } + */ + + /** + * SUBROUTINE for preventPrematureSlideClose option + * + * @param {Object} evt + * @param {Object=} el + */ +, isMouseOverElem: function (evt, el) { + var + $E = $(el || this) + , d = $E.offset() + , T = d.top + , L = d.left + , R = L + $E.outerWidth() + , B = T + $E.outerHeight() + , x = evt.pageX // evt.clientX ? + , y = evt.pageY // evt.clientY ? + ; + // if X & Y are < 0, probably means is over an open SELECT + return ($.layout.browser.msie && x < 0 && y < 0) || ((x >= L && x <= R) && (y >= T && y <= B)); + } + + /** + * Message/Logging Utility + * + * @example $.layout.msg("My message"); // log text + * @example $.layout.msg("My message", true); // alert text + * @example $.layout.msg({ foo: "bar" }, "Title"); // log hash-data, with custom title + * @example $.layout.msg({ foo: "bar" }, true, "Title", { sort: false }); -OR- + * @example $.layout.msg({ foo: "bar" }, "Title", { sort: false, display: true }); // alert hash-data + * + * @param {(Object|string)} info String message OR Hash/Array + * @param {(Boolean|string|Object)=} [popup=false] True means alert-box - can be skipped + * @param {(Object|string)=} [debugTitle=""] Title for Hash data - can be skipped + * @param {Object=} [debugOpts] Extra options for debug output + */ +, msg: function (info, popup, debugTitle, debugOpts) { + if ($.isPlainObject(info) && window.debugData) { + if (typeof popup === "string") { + debugOpts = debugTitle; + debugTitle = popup; + } + else if (typeof debugTitle === "object") { + debugOpts = debugTitle; + debugTitle = null; + } + var t = debugTitle || "log( )" + , o = $.extend({ sort: false, returnHTML: false, display: false }, debugOpts); + if (popup === true || o.display) + debugData( info, t, o ); + else if (window.console) + console.log(debugData( info, t, o )); + } + else if (popup) + alert(info); + else if (window.console) + console.log(info); + else { + var id = "#layoutLogger" + , $l = $(id); + if (!$l.length) + $l = createLog(); + $l.children("ul").append('
    • '+ info.replace(/\/g,">") +'
    • '); + } + + function createLog () { + var pos = $.support.fixedPosition ? 'fixed' : 'absolute' + , $e = $('
      ' + + '
      ' + + 'XLayout console.log
      ' + + '
        ' + + '
        ' + ).appendTo("body"); + $e.css('left', $(window).width() - $e.outerWidth() - 5) + if ($.ui.draggable) $e.draggable({ handle: ':first-child' }); + return $e; + }; + } + +}; + + +/* + * $.layout.browser REPLACES removed $.browser, with extra data + * Parsing code here adapted from jQuery 1.8 $.browse + */ +(function(){ + var u = navigator.userAgent.toLowerCase() + , m = /(chrome)[ \/]([\w.]+)/.exec( u ) + || /(webkit)[ \/]([\w.]+)/.exec( u ) + || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( u ) + || /(msie) ([\w.]+)/.exec( u ) + || u.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( u ) + || [] + , b = m[1] || "" + , v = m[2] || 0 + , ie = b === "msie" + , cm = document.compatMode + , $s = $.support + , bs = $s.boxSizing !== undefined ? $s.boxSizing : $s.boxSizingReliable + , bm = !ie || !cm || cm === "CSS1Compat" || $s.boxModel || false + , lb = $.layout.browser = { + version: v + , safari: b === "webkit" // webkit (NOT chrome) = safari + , webkit: b === "chrome" // chrome = webkit + , msie: ie + , isIE6: ie && v == 6 + // ONLY IE reverts to old box-model - Note that compatMode was deprecated as of IE8 + , boxModel: bm + , boxSizing: !!(typeof bs === "function" ? bs() : bs) + }; + ; + if (b) lb[b] = true; // set CURRENT browser + /* OLD versions of jQuery only set $.support.boxModel after page is loaded + * so if this is IE, use support.boxModel to test for quirks-mode (ONLY IE changes boxModel) */ + if (!bm && !cm) $(function(){ lb.boxModel = $s.boxModel; }); +})(); + + +// DEFAULT OPTIONS +$.layout.defaults = { +/* + * LAYOUT & LAYOUT-CONTAINER OPTIONS + * - none of these options are applicable to individual panes + */ + name: "" // Not required, but useful for buttons and used for the state-cookie +, containerClass: "ui-layout-container" // layout-container element +, inset: null // custom container-inset values (override padding) +, scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark) +, resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event +, resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky +, resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized +, maskPanesEarly: false // true = create pane-masks on resizer.mouseDown instead of waiting for resizer.dragstart +, onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific +, onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific +, onload_start: null // CALLBACK when Layout inits - after options initialized, but before elements +, onload_end: null // CALLBACK when Layout inits - after EVERYTHING has been initialized +, onunload_start: null // CALLBACK when Layout is destroyed OR onWindowUnload +, onunload_end: null // CALLBACK when Layout is destroyed OR onWindowUnload +, initPanes: true // false = DO NOT initialize the panes onLoad - will init later +, showErrorMessages: true // enables fatal error messages to warn developers of common errors +, showDebugMessages: false // display console-and-alert debug msgs - IF this Layout version _has_ debugging code! +// Changing this zIndex value will cause other zIndex values to automatically change +, zIndex: null // the PANE zIndex - resizers and masks will be +1 +// DO NOT CHANGE the zIndex values below unless you clearly understand their relationships +, zIndexes: { // set _default_ z-index values here... + pane_normal: 0 // normal z-index for panes + , content_mask: 1 // applied to overlays used to mask content INSIDE panes during resizing + , resizer_normal: 2 // normal z-index for resizer-bars + , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open' + , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer + , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged' + } +, errors: { + pane: "pane" // description of "layout pane element" - used only in error messages + , selector: "selector" // description of "jQuery-selector" - used only in error messages + , addButtonError: "Error Adding Button\nInvalid " + , containerMissing: "UI Layout Initialization Error\nThe specified layout-container does not exist." + , centerPaneMissing: "UI Layout Initialization Error\nThe center-pane element does not exist.\nThe center-pane is a required element." + , noContainerHeight: "UI Layout Initialization Warning\nThe layout-container \"CONTAINER\" has no height.\nTherefore the layout is 0-height and hence 'invisible'!" + , callbackError: "UI Layout Callback Error\nThe EVENT callback is not a valid function." + } +/* + * PANE DEFAULT SETTINGS + * - settings under the 'panes' key become the default settings for *all panes* + * - ALL pane-options can also be set specifically for each panes, which will override these 'default values' + */ +, panes: { // default options for 'all panes' - will be overridden by 'per-pane settings' + applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity + , closable: true // pane can open & close + , resizable: true // when open, pane can be resized + , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out + , initClosed: false // true = init pane as 'closed' + , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing + // SELECTORS + //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane + , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane! + , contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content' + , findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector) + // GENERIC ROOT-CLASSES - for auto-generated classNames + , paneClass: "ui-layout-pane" // Layout Pane + , resizerClass: "ui-layout-resizer" // Resizer Bar + , togglerClass: "ui-layout-toggler" // Toggler Button + , buttonClass: "ui-layout-button" // CUSTOM Buttons - eg: '[ui-layout-button]-toggle/-open/-close/-pin' + // ELEMENT SIZE & SPACING + //, size: 100 // MUST be pane-specific -initial size of pane + , minSize: 0 // when manually resizing a pane + , maxSize: 0 // ditto, 0 = no limit + , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open' + , spacing_closed: 6 // ditto - when pane is 'closed' + , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides + , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden' + , togglerAlign_open: "center" // top/left, bottom/right, center, OR... + , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right + , togglerContent_open: "" // text or HTML to put INSIDE the toggler + , togglerContent_closed: "" // ditto + // RESIZING OPTIONS + , resizerDblClickToggle: true // + , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes + , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed + , resizerDragOpacity: 1 // option for ui.draggable + //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar + , maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES + , maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask + , maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes + , resizingGrid: false // grid size that the resizers will snap-to during resizing, eg: [20,20] + , livePaneResizing: false // true = LIVE Resizing as resizer is dragged + , liveContentResizing: false // true = re-measure header/footer heights as resizer is dragged + , liveResizingTolerance: 1 // how many px change before pane resizes, to control performance + // SLIDING OPTIONS + , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding' + , slideTrigger_open: "click" // click, dblclick, mouseenter + , slideTrigger_close: "mouseleave"// click, mouseleave + , slideDelay_open: 300 // applies only for mouseenter event - 0 = instant open + , slideDelay_close: 300 // applies only for mouseleave event (300ms is the minimum!) + , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show? + , preventQuickSlideClose: $.layout.browser.webkit // Chrome triggers slideClosed as it is opening + , preventPrematureSlideClose: false // handle incorrect mouseleave trigger, like when over a SELECT-list in IE + // PANE-SPECIFIC TIPS & MESSAGES + , tips: { + Open: "Open" // eg: "Open Pane" + , Close: "Close" + , Resize: "Resize" + , Slide: "Slide Open" + , Pin: "Pin" + , Unpin: "Un-Pin" + , noRoomToOpen: "Not enough room to show this panel." // alert if user tries to open a pane that cannot + , minSizeWarning: "Panel has reached its minimum size" // displays in browser statusbar + , maxSizeWarning: "Panel has reached its maximum size" // ditto + } + // HOT-KEYS & MISC + , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver + , enableCursorHotkey: true // enabled 'cursor' hotkeys + //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character + , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT' + // PANE ANIMATION + // NOTE: fxSss_open, fxSss_close & fxSss_size options (eg: fxName_open) are auto-generated if not passed + , fxName: "slide" // ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size' + , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration + , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 } + , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation + , animatePaneSizing: false // true = animate resizing after dragging resizer-bar OR sizePane() is called + /* NOTE: Action-specific FX options are auto-generated from the options above if not specifically set: + fxName_open: "slide" // 'Open' pane animation + fnName_close: "slide" // 'Close' pane animation + fxName_size: "slide" // 'Size' pane animation - when animatePaneSizing = true + fxSpeed_open: null + fxSpeed_close: null + fxSpeed_size: null + fxSettings_open: {} + fxSettings_close: {} + fxSettings_size: {} + */ + // CHILD/NESTED LAYOUTS + , children: null // Layout-options for nested/child layout - even {} is valid as options + , containerSelector: '' // if child is NOT 'directly nested', a selector to find it/them (can have more than one child layout!) + , initChildren: true // true = child layout will be created as soon as _this_ layout completes initialization + , destroyChildren: true // true = destroy child-layout if this pane is destroyed + , resizeChildren: true // true = trigger child-layout.resizeAll() when this pane is resized + // EVENT TRIGGERING + , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes + , triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true + // PANE CALLBACKS + , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start + , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end + , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start + , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end + , onopen_start: null // CALLBACK when pane STARTS to Open + , onopen_end: null // CALLBACK when pane ENDS being Opened + , onclose_start: null // CALLBACK when pane STARTS to Close + , onclose_end: null // CALLBACK when pane ENDS being Closed + , onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON*** + , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON*** + , onsizecontent_start: null // CALLBACK when sizing of content-element STARTS + , onsizecontent_end: null // CALLBACK when sizing of content-element ENDS + , onswap_start: null // CALLBACK when pane STARTS to Swap + , onswap_end: null // CALLBACK when pane ENDS being Swapped + , ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized + , ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized + } +/* + * PANE-SPECIFIC SETTINGS + * - options listed below MUST be specified per-pane - they CANNOT be set under 'panes' + * - all options under the 'panes' key can also be set specifically for any pane + * - most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane + */ +, north: { + paneSelector: ".ui-layout-north" + , size: "auto" // eg: "auto", "30%", .30, 200 + , resizerCursor: "n-resize" // custom = url(myCursor.cur) + , customHotkey: "" // EITHER a charCode (43) OR a character ("o") + } +, south: { + paneSelector: ".ui-layout-south" + , size: "auto" + , resizerCursor: "s-resize" + , customHotkey: "" + } +, east: { + paneSelector: ".ui-layout-east" + , size: 200 + , resizerCursor: "e-resize" + , customHotkey: "" + } +, west: { + paneSelector: ".ui-layout-west" + , size: 200 + , resizerCursor: "w-resize" + , customHotkey: "" + } +, center: { + paneSelector: ".ui-layout-center" + , minWidth: 0 + , minHeight: 0 + } +}; + +$.layout.optionsMap = { + // layout/global options - NOT pane-options + layout: ("name,instanceKey,stateManagement,effects,inset,zIndexes,errors," + + "zIndex,scrollToBookmarkOnLoad,showErrorMessages,maskPanesEarly," + + "outset,resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay," + + "onresizeall,onresizeall_start,onresizeall_end,onload,onload_start,onload_end,onunload,onunload_start,onunload_end").split(",") +// borderPanes: [ ALL options that are NOT specified as 'layout' ] + // default.panes options that apply to the center-pane (most options apply _only_ to border-panes) +, center: ("paneClass,contentSelector,contentIgnoreSelector,findNestedContent,applyDemoStyles,triggerEventsOnLoad," + + "showOverflowOnHover,maskContents,maskObjects,liveContentResizing," + + "containerSelector,children,initChildren,resizeChildren,destroyChildren," + + "onresize,onresize_start,onresize_end,onsizecontent,onsizecontent_start,onsizecontent_end").split(",") + // options that MUST be specifically set 'per-pane' - CANNOT set in the panes (defaults) key +, noDefault: ("paneSelector,resizerCursor,customHotkey").split(",") +}; + +/** + * Processes options passed in converts flat-format data into subkey (JSON) format + * In flat-format, subkeys are _currently_ separated with 2 underscores, like north__optName + * Plugins may also call this method so they can transform their own data + * + * @param {!Object} hash Data/options passed by user - may be a single level or nested levels + * @param {boolean=} [addKeys=false] Should the primary layout.options keys be added if they do not exist? + * @return {Object} Returns hash of minWidth & minHeight + */ +$.layout.transformData = function (hash, addKeys) { + var json = addKeys ? { panes: {}, center: {} } : {} // init return object + , branch, optKey, keys, key, val, i, c; + + if (typeof hash !== "object") return json; // no options passed + + // convert all 'flat-keys' to 'sub-key' format + for (optKey in hash) { + branch = json; + val = hash[ optKey ]; + keys = optKey.split("__"); // eg: west__size or north__fxSettings__duration + c = keys.length - 1; + // convert underscore-delimited to subkeys + for (i=0; i <= c; i++) { + key = keys[i]; + if (i === c) { // last key = value + if ($.isPlainObject( val )) + branch[key] = $.layout.transformData( val ); // RECURSE + else + branch[key] = val; + } + else { + if (!branch[key]) + branch[key] = {}; // create the subkey + // recurse to sub-key for next loop - if not done + branch = branch[key]; + } + } + } + return json; +}; + +// INTERNAL CONFIG DATA - DO NOT CHANGE THIS! +$.layout.backwardCompatibility = { + // data used by renameOldOptions() + map: { + // OLD Option Name: NEW Option Name + applyDefaultStyles: "applyDemoStyles" + // CHILD/NESTED LAYOUTS + , childOptions: "children" + , initChildLayout: "initChildren" + , destroyChildLayout: "destroyChildren" + , resizeChildLayout: "resizeChildren" + , resizeNestedLayout: "resizeChildren" + // MISC Options + , resizeWhileDragging: "livePaneResizing" + , resizeContentWhileDragging: "liveContentResizing" + , triggerEventsWhileDragging: "triggerEventsDuringLiveResize" + , maskIframesOnResize: "maskContents" + // STATE MANAGEMENT + , useStateCookie: "stateManagement.enabled" + , "cookie.autoLoad": "stateManagement.autoLoad" + , "cookie.autoSave": "stateManagement.autoSave" + , "cookie.keys": "stateManagement.stateKeys" + , "cookie.name": "stateManagement.cookie.name" + , "cookie.domain": "stateManagement.cookie.domain" + , "cookie.path": "stateManagement.cookie.path" + , "cookie.expires": "stateManagement.cookie.expires" + , "cookie.secure": "stateManagement.cookie.secure" + // OLD Language options + , noRoomToOpenTip: "tips.noRoomToOpen" + , togglerTip_open: "tips.Close" // open = Close + , togglerTip_closed: "tips.Open" // closed = Open + , resizerTip: "tips.Resize" + , sliderTip: "tips.Slide" + } + +/** +* @param {Object} opts +*/ +, renameOptions: function (opts) { + var map = $.layout.backwardCompatibility.map + , oldData, newData, value + ; + for (var itemPath in map) { + oldData = getBranch( itemPath ); + value = oldData.branch[ oldData.key ]; + if (value !== undefined) { + newData = getBranch( map[itemPath], true ); + newData.branch[ newData.key ] = value; + delete oldData.branch[ oldData.key ]; + } + } + + /** + * @param {string} path + * @param {boolean=} [create=false] Create path if does not exist + */ + function getBranch (path, create) { + var a = path.split(".") // split keys into array + , c = a.length - 1 + , D = { branch: opts, key: a[c] } // init branch at top & set key (last item) + , i = 0, k, undef; + for (; i 0) { + if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) { + $E.show().data('autoHidden', false); + if (!browser.mozilla) // FireFox refreshes iframes - IE does not + // make hidden, then visible to 'refresh' display after animation + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + } + + /** + * @param {(string|!Object)} el + * @param {number=} outerHeight + * @param {boolean=} [autoHide=false] + */ +, setOuterHeight = function (el, outerHeight, autoHide) { + var $E = el, h; + if (isStr(el)) $E = $Ps[el]; // west + else if (!el.jquery) $E = $(el); + h = cssH($E, outerHeight); + $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent + if (h > 0 && $E.innerWidth() > 0) { + if (autoHide && $E.data('autoHidden')) { + $E.show().data('autoHidden', false); + if (!browser.mozilla) // FireFox refreshes iframes - IE does not + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + } + + + /** + * Converts any 'size' params to a pixel/integer size, if not already + * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated + * + /** + * @param {string} pane + * @param {(string|number)=} size + * @param {string=} [dir] + * @return {number} + */ +, _parseSize = function (pane, size, dir) { + if (!dir) dir = _c[pane].dir; + + if (isStr(size) && size.match(/%/)) + size = (size === '100%') ? -1 : parseInt(size, 10) / 100; // convert % to decimal + + if (size === 0) + return 0; + else if (size >= 1) + return parseInt(size, 10); + + var o = options, avail = 0; + if (dir=="horz") // north or south or center.minHeight + avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0); + else if (dir=="vert") // east or west or center.minWidth + avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0); + + if (size === -1) // -1 == 100% + return avail; + else if (size > 0) // percentage, eg: .25 + return round(avail * size); + else if (pane=="center") + return 0; + else { // size < 0 || size=='auto' || size==Missing || size==Invalid + // auto-size the pane + var dim = (dir === "horz" ? "height" : "width") + , $P = $Ps[pane] + , $C = dim === 'height' ? $Cs[pane] : false + , vis = $.layout.showInvisibly($P) // show pane invisibly if hidden + , szP = $P.css(dim) // SAVE current pane size + , szC = $C ? $C.css(dim) : 0 // SAVE current content size + ; + $P.css(dim, "auto"); + if ($C) $C.css(dim, "auto"); + size = (dim === "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE + $P.css(dim, szP).css(vis); // RESET size & visibility + if ($C) $C.css(dim, szC); + return size; + } + } + + /** + * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added + * + * @param {(string|!Object)} pane + * @param {boolean=} [inclSpace=false] + * @return {number} Returns EITHER Width for east/west panes OR Height for north/south panes + */ +, getPaneSize = function (pane, inclSpace) { + var + $P = $Ps[pane] + , o = options[pane] + , s = state[pane] + , oSp = (inclSpace ? o.spacing_open : 0) + , cSp = (inclSpace ? o.spacing_closed : 0) + ; + if (!$P || s.isHidden) + return 0; + else if (s.isClosed || (s.isSliding && inclSpace)) + return cSp; + else if (_c[pane].dir === "horz") + return $P.outerHeight() + oSp; + else // dir === "vert" + return $P.outerWidth() + oSp; + } + + /** + * Calculate min/max pane dimensions and limits for resizing + * + * @param {string} pane + * @param {boolean=} [slide=false] + */ +, setSizeLimits = function (pane, slide) { + if (!isInitialized()) return; + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , dir = c.dir + , type = c.sizeType.toLowerCase() + , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param + , $P = $Ps[pane] + , paneSpacing = o.spacing_open + // measure the pane on the *opposite side* from this pane + , altPane = _c.oppositeEdge[pane] + , altS = state[altPane] + , $altP = $Ps[altPane] + , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth())) + , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0) + // limitSize prevents this pane from 'overlapping' opposite pane + , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth) + , minCenterDims = cssMinDims("center") + , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth) + // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them + , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing))) + , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize ) + , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize ) + , r = s.resizerPosition = {} // used to set resizing limits + , top = sC.inset.top + , left = sC.inset.left + , W = sC.innerWidth + , H = sC.innerHeight + , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east + ; + switch (pane) { + case "north": r.min = top + minSize; + r.max = top + maxSize; + break; + case "west": r.min = left + minSize; + r.max = left + maxSize; + break; + case "south": r.min = top + H - maxSize - rW; + r.max = top + H - minSize - rW; + break; + case "east": r.min = left + W - maxSize - rW; + r.max = left + W - minSize - rW; + break; + }; + } + + /** + * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes + * + * @return JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height + */ +, calcNewCenterPaneDims = function () { + var d = { + top: getPaneSize("north", true) // true = include 'spacing' value for pane + , bottom: getPaneSize("south", true) + , left: getPaneSize("west", true) + , right: getPaneSize("east", true) + , width: 0 + , height: 0 + }; + + // NOTE: sC = state.container + // calc center-pane outer dimensions + d.width = sC.innerWidth - d.left - d.right; // outerWidth + d.height = sC.innerHeight - d.bottom - d.top; // outerHeight + // add the 'container border/padding' to get final positions relative to the container + d.top += sC.inset.top; + d.bottom += sC.inset.bottom; + d.left += sC.inset.left; + d.right += sC.inset.right; + + return d; + } + + + /** + * @param {!Object} el + * @param {boolean=} [allStates=false] + */ +, getHoverClasses = function (el, allStates) { + var + $El = $(el) + , type = $El.data("layoutRole") + , pane = $El.data("layoutEdge") + , o = options[pane] + , root = o[type +"Class"] + , _pane = "-"+ pane // eg: "-west" + , _open = "-open" + , _closed = "-closed" + , _slide = "-sliding" + , _hover = "-hover " // NOTE the trailing space + , _state = $El.hasClass(root+_closed) ? _closed : _open + , _alt = _state === _closed ? _open : _closed + , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover) + ; + if (allStates) // when 'removing' classes, also remove alternate-state classes + classes += (root+_alt+_hover) + (root+_pane+_alt+_hover); + + if (type=="resizer" && $El.hasClass(root+_slide)) + classes += (root+_slide+_hover) + (root+_pane+_slide+_hover); + + return $.trim(classes); + } +, addHover = function (evt, el) { + var $E = $(el || this); + if (evt && $E.data("layoutRole") === "toggler") + evt.stopPropagation(); // prevent triggering 'slide' on Resizer-bar + $E.addClass( getHoverClasses($E) ); + } +, removeHover = function (evt, el) { + var $E = $(el || this); + $E.removeClass( getHoverClasses($E, true) ); + } + +, onResizerEnter = function (evt) { // ALSO called by toggler.mouseenter + var pane = $(this).data("layoutEdge") + , s = state[pane] + , $d = $(document) + ; + // ignore closed-panes and mouse moving back & forth over resizer! + // also ignore if ANY pane is currently resizing + if ( s.isResizing || state.paneResizing ) return; + + if (options.maskPanesEarly) + showMasks( pane, { resizing: true }); + } +, onResizerLeave = function (evt, el) { + var e = el || this // el is only passed when called by the timer + , pane = $(e).data("layoutEdge") + , name = pane +"ResizerLeave" + , $d = $(document) + ; + timer.clear(pane+"_openSlider"); // cancel slideOpen timer, if set + timer.clear(name); // cancel enableSelection timer - may re/set below + // this method calls itself on a timer because it needs to allow + // enough time for dragging to kick-in and set the isResizing flag + // dragging has a 100ms delay set, so this delay must be >100 + if (!el) // 1st call - mouseleave event + timer.set(name, function(){ onResizerLeave(evt, e); }, 200); + // if user is resizing, dragStop will reset everything, so skip it here + else if (options.maskPanesEarly && !state.paneResizing) // 2nd call - by timer + hideMasks(); + } + +/* + * ########################### + * INITIALIZATION METHODS + * ########################### + */ + + /** + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @see none - triggered onInit + * @return mixed true = fully initialized | false = panes not initialized (yet) | 'cancel' = abort + */ +, _create = function () { + // initialize config/options + initOptions(); + var o = options + , s = state; + + // TEMP state so isInitialized returns true during init process + s.creatingLayout = true; + + // init plugins for this layout, if there are any (eg: stateManagement) + runPluginCallbacks( Instance, $.layout.onCreate ); + + // options & state have been initialized, so now run beforeLoad callback + // onload will CANCEL layout creation if it returns false + if (false === _runCallbacks("onload_start")) + return 'cancel'; + + // initialize the container element + _initContainer(); + + // bind hotkey function - keyDown - if required + initHotkeys(); + + // bind window.onunload + $(window).bind("unload."+ sID, unload); + + // init plugins for this layout, if there are any (eg: customButtons) + runPluginCallbacks( Instance, $.layout.onLoad ); + + // if layout elements are hidden, then layout WILL NOT complete initialization! + // initLayoutElements will set initialized=true and run the onload callback IF successful + if (o.initPanes) _initLayoutElements(); + + delete s.creatingLayout; + + return state.initialized; + } + + /** + * Initialize the layout IF not already + * + * @see All methods in Instance run this test + * @return boolean true = layoutElements have been initialized | false = panes are not initialized (yet) + */ +, isInitialized = function () { + if (state.initialized || state.creatingLayout) return true; // already initialized + else return _initLayoutElements(); // try to init panes NOW + } + + /** + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @see _create() & isInitialized + * @param {boolean=} [retry=false] // indicates this is a 2nd try + * @return An object pointer to the instance created + */ +, _initLayoutElements = function (retry) { + // initialize config/options + var o = options; + // CANNOT init panes inside a hidden container! + if (!$N.is(":visible")) { + // handle Chrome bug where popup window 'has no height' + // if layout is BODY element, try again in 50ms + // SEE: http://layout.jquery-dev.com/samples/test_popup_window.html + if ( !retry && browser.webkit && $N[0].tagName === "BODY" ) + setTimeout(function(){ _initLayoutElements(true); }, 50); + return false; + } + + // a center pane is required, so make sure it exists + if (!getPane("center").length) { + return _log( o.errors.centerPaneMissing ); + } + + // TEMP state so isInitialized returns true during init process + state.creatingLayout = true; + + // update Container dims + $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT include insetX values + + // initialize all layout elements + initPanes(); // size & position panes - calls initHandles() - which calls initResizable() + + if (o.scrollToBookmarkOnLoad) { + var l = self.location; + if (l.hash) l.replace( l.hash ); // scrollTo Bookmark + } + + // check to see if this layout 'nested' inside a pane + if (Instance.hasParentLayout) + o.resizeWithWindow = false; + // bind resizeAll() for 'this layout instance' to window.resize event + else if (o.resizeWithWindow) + $(window).bind("resize."+ sID, windowResize); + + delete state.creatingLayout; + state.initialized = true; + + // init plugins for this layout, if there are any + runPluginCallbacks( Instance, $.layout.onReady ); + + // now run the onload callback, if exists + _runCallbacks("onload_end"); + + return true; // elements initialized successfully + } + + /** + * Initialize nested layouts for a specific pane - can optionally pass layout-options + * + * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {Object=} [opts] Layout-options - if passed, will OVERRRIDE options[pane].children + * @return An object pointer to the layout instance created - or null + */ +, createChildren = function (evt_or_pane, opts) { + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + ; + if (!$P) return; + var $C = $Cs[pane] + , s = state[pane] + , o = options[pane] + , sm = options.stateManagement || {} + , cos = opts ? (o.children = opts) : o.children + ; + if ( $.isPlainObject( cos ) ) + cos = [ cos ]; // convert a hash to a 1-elem array + else if (!cos || !$.isArray( cos )) + return; + + $.each( cos, function (idx, co) { + if ( !$.isPlainObject( co ) ) return; + + // determine which element is supposed to be the 'child container' + // if pane has a 'containerSelector' OR a 'content-div', use those instead of the pane + var $containers = co.containerSelector ? $P.find( co.containerSelector ) : ($C || $P); + + $containers.each(function(){ + var $cont = $(this) + , child = $cont.data("layout") // see if a child-layout ALREADY exists on this element + ; + // if no layout exists, but children are set, try to create the layout now + if (!child) { + // TODO: see about moving this to the stateManagement plugin, as a method + // set a unique child-instance key for this layout, if not already set + setInstanceKey({ container: $cont, options: co }, s ); + // If THIS layout has a hash in stateManagement.autoLoad, + // then see if it also contains state-data for this child-layout + // If so, copy the stateData to child.options.stateManagement.autoLoad + if ( sm.includeChildren && state.stateData[pane] ) { + // THIS layout's state was cached when its state was loaded + var paneChildren = state.stateData[pane].children || {} + , childState = paneChildren[ co.instanceKey ] + , co_sm = co.stateManagement || (co.stateManagement = { autoLoad: true }) + ; + // COPY the stateData into the autoLoad key + if ( co_sm.autoLoad === true && childState ) { + co_sm.autoSave = false; // disable autoSave because saving handled by parent-layout + co_sm.includeChildren = true; // cascade option - FOR NOW + co_sm.autoLoad = $.extend(true, {}, childState); // COPY the state-hash + } + } + + // create the layout + child = $cont.layout( co ); + + // if successful, update data + if (child) { + // add the child and update all layout-pointers + // MAY have already been done by child-layout calling parent.refreshChildren() + refreshChildren( pane, child ); + } + } + }); + }); + } + +, setInstanceKey = function (child, parentPaneState) { + // create a named key for use in state and instance branches + var $c = child.container + , o = child.options + , sm = o.stateManagement + , key = o.instanceKey || $c.data("layoutInstanceKey") + ; + if (!key) key = (sm && sm.cookie ? sm.cookie.name : '') || o.name; // look for a name/key + if (!key) key = "layout"+ (++parentPaneState.childIdx); // if no name/key found, generate one + else key = key.replace(/[^\w-]/gi, '_').replace(/_{2,}/g, '_'); // ensure is valid as a hash key + o.instanceKey = key; + $c.data("layoutInstanceKey", key); // useful if layout is destroyed and then recreated + return key; + } + + /** + * @param {string} pane The pane being opened, ie: north, south, east, or west + * @param {Object=} newChild New child-layout Instance to add to this pane + */ +, refreshChildren = function (pane, newChild) { + var $P = $Ps[pane] + , pC = children[pane] + , s = state[pane] + , o + ; + // check for destroy()ed layouts and update the child pointers & arrays + if ($.isPlainObject( pC )) { + $.each( pC, function (key, child) { + if (child.destroyed) delete pC[key] + }); + // if no more children, remove the children hash + if ($.isEmptyObject( pC )) + pC = children[pane] = null; // clear children hash + } + + // see if there is a directly-nested layout inside this pane + // if there is, then there can be only ONE child-layout, so check that... + if (!newChild && !pC) { + newChild = $P.data("layout"); + } + + // if a newChild instance was passed, add it to children[pane] + if (newChild) { + // update child.state + newChild.hasParentLayout = true; // set parent-flag in child + // instanceKey is a key-name used in both state and children + o = newChild.options; + // set a unique child-instance key for this layout, if not already set + setInstanceKey( newChild, s ); + // add pointer to pane.children hash + if (!pC) pC = children[pane] = {}; // create an empty children hash + pC[ o.instanceKey ] = newChild.container.data("layout"); // add childLayout instance + } + + // ALWAYS refresh the pane.children alias, even if null + Instance[pane].children = children[pane]; + + // if newChild was NOT passed - see if there is a child layout NOW + if (!newChild) { + createChildren(pane); // MAY create a child and re-call this method + } + } + +, windowResize = function () { + var o = options + , delay = Number(o.resizeWithWindowDelay); + if (delay < 10) delay = 100; // MUST have a delay! + // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway + timer.clear("winResize"); // if already running + timer.set("winResize", function(){ + timer.clear("winResize"); + timer.clear("winResizeRepeater"); + var dims = elDims( $N, o.inset ); + // only trigger resizeAll() if container has changed size + if (dims.innerWidth !== sC.innerWidth || dims.innerHeight !== sC.innerHeight) + resizeAll(); + }, delay); + // ALSO set fixed-delay timer, if not already running + if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater(); + } + +, setWindowResizeRepeater = function () { + var delay = Number(options.resizeWithWindowMaxDelay); + if (delay > 0) + timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay); + } + +, unload = function () { + var o = options; + + _runCallbacks("onunload_start"); + + // trigger plugin callabacks for this layout (eg: stateManagement) + runPluginCallbacks( Instance, $.layout.onUnload ); + + _runCallbacks("onunload_end"); + } + + /** + * Validate and initialize container CSS and events + * + * @see _create() + */ +, _initContainer = function () { + var + N = $N[0] + , $H = $("html") + , tag = sC.tagName = N.tagName + , id = sC.id = N.id + , cls = sC.className = N.className + , o = options + , name = o.name + , props = "position,margin,padding,border" + , css = "layoutCSS" + , CSS = {} + , hid = "hidden" // used A LOT! + // see if this container is a 'pane' inside an outer-layout + , parent = $N.data("parentLayout") // parent-layout Instance + , pane = $N.data("layoutEdge") // pane-name in parent-layout + , isChild = parent && pane + , num = $.layout.cssNum + , $parent, n + ; + // sC = state.container + sC.selector = $N.selector.split(".slice")[0]; + sC.ref = (o.name ? o.name +' layout / ' : '') + tag + (id ? "#"+id : cls ? '.['+cls+']' : ''); // used in messages + sC.isBody = (tag === "BODY"); + + // try to find a parent-layout + if (!isChild && !sC.isBody) { + $parent = $N.closest("."+ $.layout.defaults.panes.paneClass); + parent = $parent.data("parentLayout"); + pane = $parent.data("layoutEdge"); + isChild = parent && pane; + } + + $N .data({ + layout: Instance + , layoutContainer: sID // FLAG to indicate this is a layout-container - contains unique internal ID + }) + .addClass(o.containerClass) + ; + var layoutMethods = { + destroy: '' + , initPanes: '' + , resizeAll: 'resizeAll' + , resize: 'resizeAll' + }; + // loop hash and bind all methods - include layoutID namespacing + for (name in layoutMethods) { + $N.bind("layout"+ name.toLowerCase() +"."+ sID, Instance[ layoutMethods[name] || name ]); + } + + // if this container is another layout's 'pane', then set child/parent pointers + if (isChild) { + // update parent flag + Instance.hasParentLayout = true; + // set pointers to THIS child-layout (Instance) in parent-layout + parent.refreshChildren( pane, Instance ); + } + + // SAVE original container CSS for use in destroy() + if (!$N.data(css)) { + // handle props like overflow different for BODY & HTML - has 'system default' values + if (sC.isBody) { + // SAVE CSS + $N.data(css, $.extend( styles($N, props), { + height: $N.css("height") + , overflow: $N.css("overflow") + , overflowX: $N.css("overflowX") + , overflowY: $N.css("overflowY") + })); + // ALSO SAVE CSS + $H.data(css, $.extend( styles($H, 'padding'), { + height: "auto" // FF would return a fixed px-size! + , overflow: $H.css("overflow") + , overflowX: $H.css("overflowX") + , overflowY: $H.css("overflowY") + })); + } + else // handle props normally for non-body elements + $N.data(css, styles($N, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY") ); + } + + try { + // common container CSS + CSS = { + overflow: hid + , overflowX: hid + , overflowY: hid + }; + $N.css( CSS ); + + if (o.inset && !$.isPlainObject(o.inset)) { + // can specify a single number for equal outset all-around + n = parseInt(o.inset, 10) || 0 + o.inset = { + top: n + , bottom: n + , left: n + , right: n + }; + } + + // format html & body if this is a full page layout + if (sC.isBody) { + // if HTML has padding, use this as an outer-spacing around BODY + if (!o.outset) { + // use padding from parent-elem (HTML) as outset + o.outset = { + top: num($H, "paddingTop") + , bottom: num($H, "paddingBottom") + , left: num($H, "paddingLeft") + , right: num($H, "paddingRight") + }; + } + else if (!$.isPlainObject(o.outset)) { + // can specify a single number for equal outset all-around + n = parseInt(o.outset, 10) || 0 + o.outset = { + top: n + , bottom: n + , left: n + , right: n + }; + } + // HTML + $H.css( CSS ).css({ + height: "100%" + , border: "none" // no border or padding allowed when using height = 100% + , padding: 0 // ditto + , margin: 0 + }); + // BODY + if (browser.isIE6) { + // IE6 CANNOT use the trick of setting absolute positioning on all 4 sides - must have 'height' + $N.css({ + width: "100%" + , height: "100%" + , border: "none" // no border or padding allowed when using height = 100% + , padding: 0 // ditto + , margin: 0 + , position: "relative" + }); + // convert body padding to an inset option - the border cannot be measured in IE6! + if (!o.inset) o.inset = elDims( $N ).inset; + } + else { // use absolute positioning for BODY to allow borders & padding without overflow + $N.css({ + width: "auto" + , height: "auto" + , margin: 0 + , position: "absolute" // allows for border and padding on BODY + }); + // apply edge-positioning created above + $N.css( o.outset ); + } + // set current layout-container dimensions + $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT include insetX values + } + else { + // container MUST have 'position' + var p = $N.css("position"); + if (!p || !p.match(/(fixed|absolute|relative)/)) + $N.css("position","relative"); + + // set current layout-container dimensions + if ( $N.is(":visible") ) { + $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT change insetX (padding) values + if (sC.innerHeight < 1) // container has no 'height' - warn developer + _log( o.errors.noContainerHeight.replace(/CONTAINER/, sC.ref) ); + } + } + + // if container has min-width/height, then enable scrollbar(s) + if ( num($N, "minWidth") ) $N.parent().css("overflowX","auto"); + if ( num($N, "minHeight") ) $N.parent().css("overflowY","auto"); + + } catch (ex) {} + } + + /** + * Bind layout hotkeys - if options enabled + * + * @see _create() and addPane() + * @param {string=} [panes=""] The edge(s) to process + */ +, initHotkeys = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + // bind keyDown to capture hotkeys, if option enabled for ANY pane + $.each(panes, function (i, pane) { + var o = options[pane]; + if (o.enableCursorHotkey || o.customHotkey) { + $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE + return false; // BREAK - binding was done + } + }); + } + + /** + * Build final OPTIONS data + * + * @see _create() + */ +, initOptions = function () { + var data, d, pane, key, val, i, c, o; + + // reprocess user's layout-options to have correct options sub-key structure + opts = $.layout.transformData( opts, true ); // panes = default subkey + + // auto-rename old options for backward compatibility + opts = $.layout.backwardCompatibility.renameAllOptions( opts ); + + // if user-options has 'panes' key (pane-defaults), clean it... + if (!$.isEmptyObject(opts.panes)) { + // REMOVE any pane-defaults that MUST be set per-pane + data = $.layout.optionsMap.noDefault; + for (i=0, c=data.length; i 0) { + z.pane_normal = zo; + z.content_mask = max(zo+1, z.content_mask); // MIN = +1 + z.resizer_normal = max(zo+2, z.resizer_normal); // MIN = +2 + } + + // DELETE 'panes' key now that we are done - values were copied to EACH pane + delete options.panes; + + + function createFxOptions ( pane ) { + var o = options[pane] + , d = options.panes; + // ensure fxSettings key to avoid errors + if (!o.fxSettings) o.fxSettings = {}; + if (!d.fxSettings) d.fxSettings = {}; + + $.each(["_open","_close","_size"], function (i,n) { + var + sName = "fxName"+ n + , sSpeed = "fxSpeed"+ n + , sSettings = "fxSettings"+ n + // recalculate fxName according to specificity rules + , fxName = o[sName] = + o[sName] // options.west.fxName_open + || d[sName] // options.panes.fxName_open + || o.fxName // options.west.fxName + || d.fxName // options.panes.fxName + || "none" // MEANS $.layout.defaults.panes.fxName == "" || false || null || 0 + , fxExists = $.effects && ($.effects[fxName] || ($.effects.effect && $.effects.effect[fxName])) + ; + // validate fxName to ensure is valid effect - MUST have effect-config data in options.effects + if (fxName === "none" || !options.effects[fxName] || !fxExists) + fxName = o[sName] = "none"; // effect not loaded OR unrecognized fxName + + // set vars for effects subkeys to simplify logic + var fx = options.effects[fxName] || {} // effects.slide + , fx_all = fx.all || null // effects.slide.all + , fx_pane = fx[pane] || null // effects.slide.west + ; + // create fxSpeed[_open|_close|_size] + o[sSpeed] = + o[sSpeed] // options.west.fxSpeed_open + || d[sSpeed] // options.west.fxSpeed_open + || o.fxSpeed // options.west.fxSpeed + || d.fxSpeed // options.panes.fxSpeed + || null // DEFAULT - let fxSetting.duration control speed + ; + // create fxSettings[_open|_close|_size] + o[sSettings] = $.extend( + true + , {} + , fx_all // effects.slide.all + , fx_pane // effects.slide.west + , d.fxSettings // options.panes.fxSettings + , o.fxSettings // options.west.fxSettings + , d[sSettings] // options.panes.fxSettings_open + , o[sSettings] // options.west.fxSettings_open + ); + }); + + // DONE creating action-specific-settings for this pane, + // so DELETE generic options - are no longer meaningful + delete o.fxName; + delete o.fxSpeed; + delete o.fxSettings; + } + } + + /** + * Initialize module objects, styling, size and position for all panes + * + * @see _initElements() + * @param {string} pane The pane to process + */ +, getPane = function (pane) { + var sel = options[pane].paneSelector + if (sel.substr(0,1)==="#") // ID selector + // NOTE: elements selected 'by ID' DO NOT have to be 'children' + return $N.find(sel).eq(0); + else { // class or other selector + var $P = $N.children(sel).eq(0); + // look for the pane nested inside a 'form' element + return $P.length ? $P : $N.children("form:first").children(sel).eq(0); + } + } + + /** + * @param {Object=} evt + */ +, initPanes = function (evt) { + // stopPropagation if called by trigger("layoutinitpanes") - use evtPane utility + evtPane(evt); + + // NOTE: do north & south FIRST so we can measure their height - do center LAST + $.each(_c.allPanes, function (idx, pane) { + addPane( pane, true ); + }); + + // init the pane-handles NOW in case we have to hide or close the pane below + initHandles(); + + // now that all panes have been initialized and initially-sized, + // make sure there is really enough space available for each pane + $.each(_c.borderPanes, function (i, pane) { + if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN + setSizeLimits(pane); + makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit() + } + }); + // size center-pane AGAIN in case we 'closed' a border-pane in loop above + sizeMidPanes("center"); + + // Chrome/Webkit sometimes fires callbacks BEFORE it completes resizing! + // Before RC30.3, there was a 10ms delay here, but that caused layout + // to load asynchrously, which is BAD, so try skipping delay for now + + // process pane contents and callbacks, and init/resize child-layout if exists + $.each(_c.allPanes, function (idx, pane) { + afterInitPane(pane); + }); + } + + /** + * Add a pane to the layout - subroutine of initPanes() + * + * @see initPanes() + * @param {string} pane The pane to process + * @param {boolean=} [force=false] Size content after init + */ +, addPane = function (pane, force) { + if ( !force && !isInitialized() ) return; + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , dir = c.dir + , fx = s.fx + , spacing = o.spacing_open || 0 + , isCenter = (pane === "center") + , CSS = {} + , $P = $Ps[pane] + , size, minSize, maxSize, child + ; + // if pane-pointer already exists, remove the old one first + if ($P) + removePane( pane, false, true, false ); + else + $Cs[pane] = false; // init + + $P = $Ps[pane] = getPane(pane); + if (!$P.length) { + $Ps[pane] = false; // logic + return; + } + + // SAVE original Pane CSS + if (!$P.data("layoutCSS")) { + var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border"; + $P.data("layoutCSS", styles($P, props)); + } + + // create alias for pane data in Instance - initHandles will add more + Instance[pane] = { + name: pane + , pane: $Ps[pane] + , content: $Cs[pane] + , options: options[pane] + , state: state[pane] + , children: children[pane] + }; + + // add classes, attributes & events + $P .data({ + parentLayout: Instance // pointer to Layout Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "pane" + }) + .css(c.cssReq).css("zIndex", options.zIndexes.pane_normal) + .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles + .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector' + .bind("mouseenter."+ sID, addHover ) + .bind("mouseleave."+ sID, removeHover ) + ; + var paneMethods = { + hide: '' + , show: '' + , toggle: '' + , close: '' + , open: '' + , slideOpen: '' + , slideClose: '' + , slideToggle: '' + , size: 'sizePane' + , sizePane: 'sizePane' + , sizeContent: '' + , sizeHandles: '' + , enableClosable: '' + , disableClosable: '' + , enableSlideable: '' + , disableSlideable: '' + , enableResizable: '' + , disableResizable: '' + , swapPanes: 'swapPanes' + , swap: 'swapPanes' + , move: 'swapPanes' + , removePane: 'removePane' + , remove: 'removePane' + , createChildren: '' + , resizeChildren: '' + , resizeAll: 'resizeAll' + , resizeLayout: 'resizeAll' + } + , name; + // loop hash and bind all methods - include layoutID namespacing + for (name in paneMethods) { + $P.bind("layoutpane"+ name.toLowerCase() +"."+ sID, Instance[ paneMethods[name] || name ]); + } + + // see if this pane has a 'scrolling-content element' + initContent(pane, false); // false = do NOT sizeContent() - called later + + if (!isCenter) { + // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden) + // if o.size is auto or not valid, then MEASURE the pane and use that as its 'size' + size = s.size = _parseSize(pane, o.size); + minSize = _parseSize(pane,o.minSize) || 1; + maxSize = _parseSize(pane,o.maxSize) || 100000; + if (size > 0) size = max(min(size, maxSize), minSize); + s.autoResize = o.autoResize; // used with percentage sizes + + // state for border-panes + s.isClosed = false; // true = pane is closed + s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes + s.isResizing= false; // true = pane is in process of being resized + s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible! + + // array for 'pin buttons' whose classNames are auto-updated on pane-open/-close + if (!s.pins) s.pins = []; + } + // states common to ALL panes + s.tagName = $P[0].tagName; + s.edge = pane; // useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going) + s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically + s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic + + // init pane positioning + setPanePosition( pane ); + + // if pane is not visible, + if (dir === "horz") // north or south pane + CSS.height = cssH($P, size); + else if (dir === "vert") // east or west pane + CSS.width = cssW($P, size); + //else if (isCenter) {} + + $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes + if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback + + // if manually adding a pane AFTER layout initialization, then... + if (state.initialized) { + initHandles( pane ); + initHotkeys( pane ); + } + + // close or hide the pane if specified in settings + if (o.initClosed && o.closable && !o.initHidden) + close(pane, true, true); // true, true = force, noAnimation + else if (o.initHidden || o.initClosed) + hide(pane); // will be completely invisible - no resizer or spacing + else if (!s.noRoom) + // make the pane visible - in case was initially hidden + $P.css("display","block"); + // ELSE setAsOpen() - called later by initHandles() + + // RESET visibility now - pane will appear IF display:block + $P.css("visibility","visible"); + + // check option for auto-handling of pop-ups & drop-downs + if (o.showOverflowOnHover) + $P.hover( allowOverflow, resetOverflow ); + + // if manually adding a pane AFTER layout initialization, then... + if (state.initialized) { + afterInitPane( pane ); + } + } + +, afterInitPane = function (pane) { + var $P = $Ps[pane] + , s = state[pane] + , o = options[pane] + ; + if (!$P) return; + + // see if there is a directly-nested layout inside this pane + if ($P.data("layout")) + refreshChildren( pane, $P.data("layout") ); + + // process pane contents and callbacks, and init/resize child-layout if exists + if (s.isVisible) { // pane is OPEN + if (state.initialized) // this pane was added AFTER layout was created + resizeAll(); // will also sizeContent + else + sizeContent(pane); + + if (o.triggerEventsOnLoad) + _runCallbacks("onresize_end", pane); + else // automatic if onresize called, otherwise call it specifically + // resize child - IF inner-layout already exists (created before this layout) + resizeChildren(pane, true); // a previously existing childLayout + } + + // init childLayouts - even if pane is not visible + if (o.initChildren && o.children) + createChildren(pane); + } + + /** + * @param {string=} panes The pane(s) to process + */ +, setPanePosition = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + + // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV + $.each(panes, function (i, pane) { + var $P = $Ps[pane] + , $R = $Rs[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side + , CSS = {} + ; + if (!$P) return; // pane does not exist - skip + + // set css-position to account for container borders & padding + switch (pane) { + case "north": CSS.top = sC.inset.top; + CSS.left = sC.inset.left; + CSS.right = sC.inset.right; + break; + case "south": CSS.bottom = sC.inset.bottom; + CSS.left = sC.inset.left; + CSS.right = sC.inset.right; + break; + case "west": CSS.left = sC.inset.left; // top, bottom & height set by sizeMidPanes() + break; + case "east": CSS.right = sC.inset.right; // ditto + break; + case "center": // top, left, width & height set by sizeMidPanes() + } + // apply position + $P.css(CSS); + + // update resizer position + if ($R && s.isClosed) + $R.css(side, sC.inset[side]); + else if ($R && !s.isHidden) + $R.css(side, sC.inset[side] + getPaneSize(pane)); + }); + } + + /** + * Initialize module objects, styling, size and position for all resize bars and toggler buttons + * + * @see _create() + * @param {string=} [panes=""] The edge(s) to process + */ +, initHandles = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + + // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV + $.each(panes, function (i, pane) { + var $P = $Ps[pane]; + $Rs[pane] = false; // INIT + $Ts[pane] = false; + if (!$P) return; // pane does not exist - skip + + var o = options[pane] + , s = state[pane] + , c = _c[pane] + , paneId = o.paneSelector.substr(0,1) === "#" ? o.paneSelector.substr(1) : "" + , rClass = o.resizerClass + , tClass = o.togglerClass + , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed) + , _pane = "-"+ pane // used for classNames + , _state = (s.isVisible ? "-open" : "-closed") // used for classNames + , I = Instance[pane] + // INIT RESIZER BAR + , $R = I.resizer = $Rs[pane] = $("
        ") + // INIT TOGGLER BUTTON + , $T = I.toggler = (o.closable ? $Ts[pane] = $("
        ") : false) + ; + + //if (s.isVisible && o.resizable) ... handled by initResizable + if (!s.isVisible && o.slidable) + $R.attr("title", o.tips.Slide).css("cursor", o.sliderCursor); + + $R // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer" + .attr("id", paneId ? paneId +"-resizer" : "" ) + .data({ + parentLayout: Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "resizer" + }) + .css(_c.resizers.cssReq).css("zIndex", options.zIndexes.resizer_normal) + .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles + .addClass(rClass +" "+ rClass+_pane) + .hover(addHover, removeHover) // ALWAYS add hover-classes, even if resizing is not enabled - handle with CSS instead + .hover(onResizerEnter, onResizerLeave) // ALWAYS NEED resizer.mouseleave to balance toggler.mouseenter + .mousedown($.layout.disableTextSelection) // prevent text-selection OUTSIDE resizer + .mouseup($.layout.enableTextSelection) // not really necessary, but just in case + .appendTo($N) // append DIV to container + ; + if ($.fn.disableSelection) + $R.disableSelection(); // prevent text-selection INSIDE resizer + if (o.resizerDblClickToggle) + $R.bind("dblclick."+ sID, toggle ); + + if ($T) { + $T // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler" + .attr("id", paneId ? paneId +"-toggler" : "" ) + .data({ + parentLayout: Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "toggler" + }) + .css(_c.togglers.cssReq) // add base/required styles + .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles + .addClass(tClass +" "+ tClass+_pane) + .hover(addHover, removeHover) // ALWAYS add hover-classes, even if toggling is not enabled - handle with CSS instead + .bind("mouseenter", onResizerEnter) // NEED toggler.mouseenter because mouseenter MAY NOT fire on resizer + .appendTo($R) // append SPAN to resizer DIV + ; + // ADD INNER-SPANS TO TOGGLER + if (o.togglerContent_open) // ui-layout-open + $(""+ o.togglerContent_open +"") + .data({ + layoutEdge: pane + , layoutRole: "togglerContent" + }) + .data("layoutRole", "togglerContent") + .data("layoutEdge", pane) + .addClass("content content-open") + .css("display","none") + .appendTo( $T ) + //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-open instead! + ; + if (o.togglerContent_closed) // ui-layout-closed + $(""+ o.togglerContent_closed +"") + .data({ + layoutEdge: pane + , layoutRole: "togglerContent" + }) + .addClass("content content-closed") + .css("display","none") + .appendTo( $T ) + //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-closed instead! + ; + // ADD TOGGLER.click/.hover + enableClosable(pane); + } + + // add Draggable events + initResizable(pane); + + // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open" + if (s.isVisible) + setAsOpen(pane); // onOpen will be called, but NOT onResize + else { + setAsClosed(pane); // onClose will be called + bindStartSlidingEvents(pane, true); // will enable events IF option is set + } + + }); + + // SET ALL HANDLE DIMENSIONS + sizeHandles(); + } + + + /** + * Initialize scrolling ui-layout-content div - if exists + * + * @see initPane() - or externally after an Ajax injection + * @param {string} pane The pane to process + * @param {boolean=} [resize=true] Size content after init + */ +, initContent = function (pane, resize) { + if (!isInitialized()) return; + var + o = options[pane] + , sel = o.contentSelector + , I = Instance[pane] + , $P = $Ps[pane] + , $C + ; + if (sel) $C = I.content = $Cs[pane] = (o.findNestedContent) + ? $P.find(sel).eq(0) // match 1-element only + : $P.children(sel).eq(0) + ; + if ($C && $C.length) { + $C.data("layoutRole", "content"); + // SAVE original Content CSS + if (!$C.data("layoutCSS")) + $C.data("layoutCSS", styles($C, "height")); + $C.css( _c.content.cssReq ); + if (o.applyDemoStyles) { + $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div + $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane + } + // ensure no vertical scrollbar on pane - will mess up measurements + if ($P.css("overflowX").match(/(scroll|auto)/)) { + $P.css("overflow", "hidden"); + } + state[pane].content = {}; // init content state + if (resize !== false) sizeContent(pane); + // sizeContent() is called AFTER init of all elements + } + else + I.content = $Cs[pane] = false; + } + + + /** + * Add resize-bars to all panes that specify it in options + * -dependancy: $.fn.resizable - will skip if not found + * + * @see _create() + * @param {string=} [panes=""] The edge(s) to process + */ +, initResizable = function (panes) { + var draggingAvailable = $.layout.plugins.draggable + , side // set in start() + ; + panes = panes ? panes.split(",") : _c.borderPanes; + + $.each(panes, function (idx, pane) { + var o = options[pane]; + if (!draggingAvailable || !$Ps[pane] || !o.resizable) { + o.resizable = false; + return true; // skip to next + } + + var s = state[pane] + , z = options.zIndexes + , c = _c[pane] + , side = c.dir=="horz" ? "top" : "left" + , $P = $Ps[pane] + , $R = $Rs[pane] + , base = o.resizerClass + , lastPos = 0 // used when live-resizing + , r, live // set in start because may change + // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process + , resizerClass = base+"-drag" // resizer-drag + , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag + // 'helper' class is applied to the CLONED resizer-bar while it is being dragged + , helperClass = base+"-dragging" // resizer-dragging + , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging + , helperLimitClass = base+"-dragging-limit" // resizer-drag + , helperPaneLimitClass = base+"-"+pane+"-dragging-limit" // resizer-north-drag + , helperClassesSet = false // logic var + ; + + if (!s.isClosed) + $R.attr("title", o.tips.Resize) + .css("cursor", o.resizerCursor); // n-resize, s-resize, etc + + $R.draggable({ + containment: $N[0] // limit resizing to layout container + , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis + , delay: 0 + , distance: 1 + , grid: o.resizingGrid + // basic format for helper - style it using class: .ui-draggable-dragging + , helper: "clone" + , opacity: o.resizerDragOpacity + , addClasses: false // avoid ui-state-disabled class when disabled + //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed + , zIndex: z.resizer_drag + + , start: function (e, ui) { + // REFRESH options & state pointers in case we used swapPanes + o = options[pane]; + s = state[pane]; + // re-read options + live = o.livePaneResizing; + + // ondrag_start callback - will CANCEL hide if returns false + // TODO: dragging CANNOT be cancelled like this, so see if there is a way? + if (false === _runCallbacks("ondrag_start", pane)) return false; + + s.isResizing = true; // prevent pane from closing while resizing + state.paneResizing = pane; // easy to see if ANY pane is resizing + timer.clear(pane+"_closeSlider"); // just in case already triggered + + // SET RESIZER LIMITS - used in drag() + setSizeLimits(pane); // update pane/resizer state + r = s.resizerPosition; + lastPos = ui.position[ side ] + + $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes + helperClassesSet = false; // reset logic var - see drag() + + // MASK PANES CONTAINING IFRAMES, APPLETS OR OTHER TROUBLESOME ELEMENTS + showMasks( pane, { resizing: true }); + } + + , drag: function (e, ui) { + if (!helperClassesSet) { // can only add classes after clone has been added to the DOM + //$(".ui-draggable-dragging") + ui.helper + .addClass( helperClass +" "+ helperPaneClass ) // add helper classes + .css({ right: "auto", bottom: "auto" }) // fix dir="rtl" issue + .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar + ; + helperClassesSet = true; + // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane! + if (s.isSliding) $Ps[pane].css("zIndex", z.pane_sliding); + } + // CONTAIN RESIZER-BAR TO RESIZING LIMITS + var limit = 0; + if (ui.position[side] < r.min) { + ui.position[side] = r.min; + limit = -1; + } + else if (ui.position[side] > r.max) { + ui.position[side] = r.max; + limit = 1; + } + // ADD/REMOVE dragging-limit CLASS + if (limit) { + ui.helper.addClass( helperLimitClass +" "+ helperPaneLimitClass ); // at dragging-limit + window.defaultStatus = (limit>0 && pane.match(/(north|west)/)) || (limit<0 && pane.match(/(south|east)/)) ? o.tips.maxSizeWarning : o.tips.minSizeWarning; + } + else { + ui.helper.removeClass( helperLimitClass +" "+ helperPaneLimitClass ); // not at dragging-limit + window.defaultStatus = ""; + } + // DYNAMICALLY RESIZE PANES IF OPTION ENABLED + // won't trigger unless resizer has actually moved! + if (live && Math.abs(ui.position[side] - lastPos) >= o.liveResizingTolerance) { + lastPos = ui.position[side]; + resizePanes(e, ui, pane) + } + } + + , stop: function (e, ui) { + $('body').enableSelection(); // RE-ENABLE TEXT SELECTION + window.defaultStatus = ""; // clear 'resizing limit' message from statusbar + $R.removeClass( resizerClass +" "+ resizerPaneClass ); // remove drag classes from Resizer + s.isResizing = false; + state.paneResizing = false; // easy to see if ANY pane is resizing + resizePanes(e, ui, pane, true); // true = resizingDone + } + + }); + }); + + /** + * resizePanes + * + * Sub-routine called from stop() - and drag() if livePaneResizing + * + * @param {!Object} evt + * @param {!Object} ui + * @param {string} pane + * @param {boolean=} [resizingDone=false] + */ + var resizePanes = function (evt, ui, pane, resizingDone) { + var dragPos = ui.position + , c = _c[pane] + , o = options[pane] + , s = state[pane] + , resizerPos + ; + switch (pane) { + case "north": resizerPos = dragPos.top; break; + case "west": resizerPos = dragPos.left; break; + case "south": resizerPos = sC.layoutHeight - dragPos.top - o.spacing_open; break; + case "east": resizerPos = sC.layoutWidth - dragPos.left - o.spacing_open; break; + }; + // remove container margin from resizer position to get the pane size + var newSize = resizerPos - sC.inset[c.side]; + + // Disable OR Resize Mask(s) created in drag.start + if (!resizingDone) { + // ensure we meet liveResizingTolerance criteria + if (Math.abs(newSize - s.size) < o.liveResizingTolerance) + return; // SKIP resize this time + // resize the pane + manualSizePane(pane, newSize, false, true); // true = noAnimation + sizeMasks(); // resize all visible masks + } + else { // resizingDone + // ondrag_end callback + if (false !== _runCallbacks("ondrag_end", pane)) + manualSizePane(pane, newSize, false, true); // true = noAnimation + hideMasks(true); // true = force hiding all masks even if one is 'sliding' + if (s.isSliding) // RE-SHOW 'object-masks' so objects won't show through sliding pane + showMasks( pane, { resizing: true }); + } + }; + } + + /** + * sizeMask + * + * Needed to overlay a DIV over an IFRAME-pane because mask CANNOT be *inside* the pane + * Called when mask created, and during livePaneResizing + */ +, sizeMask = function () { + var $M = $(this) + , pane = $M.data("layoutMask") // eg: "west" + , s = state[pane] + ; + // only masks over an IFRAME-pane need manual resizing + if (s.tagName == "IFRAME" && s.isVisible) // no need to mask closed/hidden panes + $M.css({ + top: s.offsetTop + , left: s.offsetLeft + , width: s.outerWidth + , height: s.outerHeight + }); + /* ALT Method... + var $P = $Ps[pane]; + $M.css( $P.position() ).css({ width: $P[0].offsetWidth, height: $P[0].offsetHeight }); + */ + } +, sizeMasks = function () { + $Ms.each( sizeMask ); // resize all 'visible' masks + } + + /** + * @param {string} pane The pane being resized, animated or isSliding + * @param {Object=} [args] (optional) Options: which masks to apply, and to which panes + */ +, showMasks = function (pane, args) { + var c = _c[pane] + , panes = ["center"] + , z = options.zIndexes + , a = $.extend({ + objectsOnly: false + , animation: false + , resizing: true + , sliding: state[pane].isSliding + }, args ) + , o, s + ; + if (a.resizing) + panes.push( pane ); + if (a.sliding) + panes.push( _c.oppositeEdge[pane] ); // ADD the oppositeEdge-pane + + if (c.dir === "horz") { + panes.push("west"); + panes.push("east"); + } + + $.each(panes, function(i,p){ + s = state[p]; + o = options[p]; + if (s.isVisible && ( o.maskObjects || (!a.objectsOnly && o.maskContents) )) { + getMasks(p).each(function(){ + sizeMask.call(this); + this.style.zIndex = s.isSliding ? z.pane_sliding+1 : z.pane_normal+1 + this.style.display = "block"; + }); + } + }); + } + + /** + * @param {boolean=} force Hide masks even if a pane is sliding + */ +, hideMasks = function (force) { + // ensure no pane is resizing - could be a timing issue + if (force || !state.paneResizing) { + $Ms.hide(); // hide ALL masks + } + // if ANY pane is sliding, then DO NOT remove masks from panes with maskObjects enabled + else if (!force && !$.isEmptyObject( state.panesSliding )) { + var i = $Ms.length - 1 + , p, $M; + for (; i >= 0; i--) { + $M = $Ms.eq(i); + p = $M.data("layoutMask"); + if (!options[p].maskObjects) { + $M.hide(); + } + } + } + } + + /** + * @param {string} pane + */ +, getMasks = function (pane) { + var $Masks = $([]) + , $M, i = 0, c = $Ms.length + ; + for (; i CSS + if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET CSS + $N.css( $N.data(css) ).removeData(css); + + // trigger plugins for this layout, if there are any + runPluginCallbacks( Instance, $.layout.onDestroy ); + + // trigger state-management and onunload callback + unload(); + + // clear the Instance of everything except for container & options (so could recreate) + // RE-CREATE: myLayout = myLayout.container.layout( myLayout.options ); + for (var n in Instance) + if (!n.match(/^(container|options)$/)) delete Instance[ n ]; + // add a 'destroyed' flag to make it easy to check + Instance.destroyed = true; + + // if this is a child layout, CLEAR the child-pointer in the parent + /* for now the pointer REMAINS, but with only container, options and destroyed keys + if (parentPane) { + var layout = parentPane.pane.data("parentLayout") + , key = layout.options.instanceKey || 'error'; + // THIS SYNTAX MAY BE WRONG! + parentPane.children[key] = layout.children[ parentPane.name ].children[key] = null; + } + */ + + return Instance; // for coding convenience + } + + /** + * Remove a pane from the layout - subroutine of destroy() + * + * @see destroy() + * @param {(string|Object)} evt_or_pane The pane to process + * @param {boolean=} [remove=false] Remove the DOM element? + * @param {boolean=} [skipResize=false] Skip calling resizeAll()? + * @param {boolean=} [destroyChild=true] Destroy Child-layouts? If not passed, obeys options setting + */ +, removePane = function (evt_or_pane, remove, skipResize, destroyChild) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , $C = $Cs[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + ; + // NOTE: elements can still exist even after remove() + // so check for missing data(), which is cleared by removed() + if ($P && $.isEmptyObject( $P.data() )) $P = false; + if ($C && $.isEmptyObject( $C.data() )) $C = false; + if ($R && $.isEmptyObject( $R.data() )) $R = false; + if ($T && $.isEmptyObject( $T.data() )) $T = false; + + if ($P) $P.stop(true, true); + + var o = options[pane] + , s = state[pane] + , d = "layout" + , css = "layoutCSS" + , pC = children[pane] + , hasChildren = $.isPlainObject( pC ) && !$.isEmptyObject( pC ) + , destroy = destroyChild !== undefined ? destroyChild : o.destroyChildren + ; + // FIRST destroy the child-layout(s) + if (hasChildren && destroy) { + $.each( pC, function (key, child) { + if (!child.destroyed) + child.destroy(true);// tell child-layout to destroy ALL its child-layouts too + if (child.destroyed) // destroy was successful + delete pC[key]; + }); + // if no more children, remove the children hash + if ($.isEmptyObject( pC )) { + pC = children[pane] = null; // clear children hash + hasChildren = false; + } + } + + // Note: can't 'remove' a pane element with non-destroyed children + if ($P && remove && !hasChildren) + $P.remove(); // remove the pane-element and everything inside it + else if ($P && $P[0]) { + // create list of ALL pane-classes that need to be removed + var root = o.paneClass // default="ui-layout-pane" + , pRoot = root +"-"+ pane // eg: "ui-layout-pane-west" + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + , classes = [ root, root+_open, root+_closed, root+_sliding, // generic classes + pRoot, pRoot+_open, pRoot+_closed, pRoot+_sliding ] // pane-specific classes + ; + $.merge(classes, getHoverClasses($P, true)); // ADD hover-classes + // remove all Layout classes from pane-element + $P .removeClass( classes.join(" ") ) // remove ALL pane-classes + .removeData("parentLayout") + .removeData("layoutPane") + .removeData("layoutRole") + .removeData("layoutEdge") + .removeData("autoHidden") // in case set + .unbind("."+ sID) // remove ALL Layout events + // TODO: remove these extra unbind commands when jQuery is fixed + //.unbind("mouseenter"+ sID) + //.unbind("mouseleave"+ sID) + ; + // do NOT reset CSS if this pane/content is STILL the container of a nested layout! + // the nested layout will reset its 'container' CSS when/if it is destroyed + if (hasChildren && $C) { + // a content-div may not have a specific width, so give it one to contain the Layout + $C.width( $C.width() ); + $.each( pC, function (key, child) { + child.resizeAll(); // resize the Layout + }); + } + else if ($C) + $C.css( $C.data(css) ).removeData(css).removeData("layoutRole"); + // remove pane AFTER content in case there was a nested layout + if (!$P.data(d)) + $P.css( $P.data(css) ).removeData(css); + } + + // REMOVE pane resizer and toggler elements + if ($T) $T.remove(); + if ($R) $R.remove(); + + // CLEAR all pointers and state data + Instance[pane] = $Ps[pane] = $Cs[pane] = $Rs[pane] = $Ts[pane] = false; + s = { removed: true }; + + if (!skipResize) + resizeAll(); + } + + +/* + * ########################### + * ACTION METHODS + * ########################### + */ + + /** + * @param {string} pane + */ +, _hidePane = function (pane) { + var $P = $Ps[pane] + , o = options[pane] + , s = $P[0].style + ; + if (o.useOffscreenClose) { + if (!$P.data(_c.offscreenReset)) + $P.data(_c.offscreenReset, { left: s.left, right: s.right }); + $P.css( _c.offscreenCSS ); + } + else + $P.hide().removeData(_c.offscreenReset); + } + + /** + * @param {string} pane + */ +, _showPane = function (pane) { + var $P = $Ps[pane] + , o = options[pane] + , off = _c.offscreenCSS + , old = $P.data(_c.offscreenReset) + , s = $P[0].style + ; + $P .show() // ALWAYS show, just in case + .removeData(_c.offscreenReset); + if (o.useOffscreenClose && old) { + if (s.left == off.left) + s.left = old.left; + if (s.right == off.right) + s.right = old.right; + } + } + + + /** + * Completely 'hides' a pane, including its spacing - as if it does not exist + * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it + * + * @param {(string|Object)} evt_or_pane The pane being hidden, ie: north, south, east, or west + * @param {boolean=} [noAnimation=false] + */ +, hide = function (evt_or_pane, noAnimation) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (pane === "center" || !$P || s.isHidden) return; // pane does not exist OR is already hidden + + // onhide_start callback - will CANCEL hide if returns false + if (state.initialized && false === _runCallbacks("onhide_start", pane)) return; + + s.isSliding = false; // just in case + delete state.panesSliding[pane]; + + // now hide the elements + if ($R) $R.hide(); // hide resizer-bar + if (!state.initialized || s.isClosed) { + s.isClosed = true; // to trigger open-animation on show() + s.isHidden = true; + s.isVisible = false; + if (!state.initialized) + _hidePane(pane); // no animation when loading page + sizeMidPanes(_c[pane].dir === "horz" ? "" : "center"); + if (state.initialized || o.triggerEventsOnLoad) + _runCallbacks("onhide_end", pane); + } + else { + s.isHiding = true; // used by onclose + close(pane, false, noAnimation); // adjust all panes to fit + } + } + + /** + * Show a hidden pane - show as 'closed' by default unless openPane = true + * + * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {boolean=} [openPane=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [noAlert=false] + */ +, show = function (evt_or_pane, openPane, noAnimation, noAlert) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (pane === "center" || !$P || !s.isHidden) return; // pane does not exist OR is not hidden + + // onshow_start callback - will CANCEL show if returns false + if (false === _runCallbacks("onshow_start", pane)) return; + + s.isShowing = true; // used by onopen/onclose + //s.isHidden = false; - will be set by open/close - if not cancelled + s.isSliding = false; // just in case + delete state.panesSliding[pane]; + + // now show the elements + //if ($R) $R.show(); - will be shown by open/close + if (openPane === false) + close(pane, true); // true = force + else + open(pane, false, noAnimation, noAlert); // adjust all panes to fit + } + + + /** + * Toggles a pane open/closed by calling either open or close + * + * @param {(string|Object)} evt_or_pane The pane being toggled, ie: north, south, east, or west + * @param {boolean=} [slide=false] + */ +, toggle = function (evt_or_pane, slide) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , s = state[pane] + ; + if (evt) // called from to $R.dblclick OR triggerPaneEvent + evt.stopImmediatePropagation(); + if (s.isHidden) + show(pane); // will call 'open' after unhiding it + else if (s.isClosed) + open(pane, !!slide); + else + close(pane); + } + + + /** + * Utility method used during init or other auto-processes + * + * @param {string} pane The pane being closed + * @param {boolean=} [setHandles=false] + */ +, _closePane = function (pane, setHandles) { + var + $P = $Ps[pane] + , s = state[pane] + ; + _hidePane(pane); + s.isClosed = true; + s.isVisible = false; + if (setHandles) setAsClosed(pane); + } + + /** + * Close the specified pane (animation optional), and resize all other panes as needed + * + * @param {(string|Object)} evt_or_pane The pane being closed, ie: north, south, east, or west + * @param {boolean=} [force=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [skipCallback=false] + */ +, close = function (evt_or_pane, force, noAnimation, skipCallback) { + var pane = evtPane.call(this, evt_or_pane); + if (pane === "center") return; // validate + // if pane has been initialized, but NOT the complete layout, close pane instantly + if (!state.initialized && $Ps[pane]) { + _closePane(pane, true); // INIT pane as closed + return; + } + if (!isInitialized()) return; + + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , c = _c[pane] + , doFX, isShowing, isHiding, wasSliding; + + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + + if ( !$P + || (!o.closable && !s.isShowing && !s.isHiding) // invalid request // (!o.resizable && !o.closable) ??? + || (!force && s.isClosed && !s.isShowing) // already closed + ) return queueNext(); + + // onclose_start callback - will CANCEL hide if returns false + // SKIP if just 'showing' a hidden pane as 'closed' + var abort = !s.isShowing && false === _runCallbacks("onclose_start", pane); + + // transfer logic vars to temp vars + isShowing = s.isShowing; + isHiding = s.isHiding; + wasSliding = s.isSliding; + // now clear the logic vars (REQUIRED before aborting) + delete s.isShowing; + delete s.isHiding; + + if (abort) return queueNext(); + + doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none"); + s.isMoving = true; + s.isClosed = true; + s.isVisible = false; + // update isHidden BEFORE sizing panes + if (isHiding) s.isHidden = true; + else if (isShowing) s.isHidden = false; + + if (s.isSliding) // pane is being closed, so UNBIND trigger events + bindStopSlidingEvents(pane, false); // will set isSliding=false + else // resize panes adjacent to this one + sizeMidPanes(_c[pane].dir === "horz" ? "" : "center", false); // false = NOT skipCallback + + // if this pane has a resizer bar, move it NOW - before animation + setAsClosed(pane); + + // CLOSE THE PANE + if (doFX) { // animate the close + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () { + lockPaneForFX(pane, false); // undo + if (s.isClosed) close_2(); + queueNext(); + }); + } + else { // hide the pane without animation + _hidePane(pane); + close_2(); + queueNext(); + }; + }); + + // SUBROUTINE + function close_2 () { + s.isMoving = false; + bindStartSlidingEvents(pane, true); // will enable if o.slidable = true + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.oppositeEdge[pane]; + if (state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane ); + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) { + // onclose callback - UNLESS just 'showing' a hidden pane as 'closed' + if (!isShowing) _runCallbacks("onclose_end", pane); + // onhide OR onshow callback + if (isShowing) _runCallbacks("onshow_end", pane); + if (isHiding) _runCallbacks("onhide_end", pane); + } + } + } + + /** + * @param {string} pane The pane just closed, ie: north, south, east, or west + */ +, setAsClosed = function (pane) { + if (!$Rs[pane]) return; // handles not initialized yet! + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + ; + $R + .css(side, sC.inset[side]) // move the resizer + .removeClass( rClass+_open +" "+ rClass+_pane+_open ) + .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + .addClass( rClass+_closed +" "+ rClass+_pane+_closed ) + ; + // handle already-hidden panes in case called by swap() or a similar method + if (s.isHidden) $R.hide(); // hide resizer-bar + + // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvents? + if (o.resizable && $.layout.plugins.draggable) + $R + .draggable("disable") + .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here + .css("cursor", "default") + .attr("title","") + ; + + // if pane has a toggler button, adjust that too + if ($T) { + $T + .removeClass( tClass+_open +" "+ tClass+_pane+_open ) + .addClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .attr("title", o.tips.Open) // may be blank + ; + // toggler-content - if exists + $T.children(".content-open").hide(); + $T.children(".content-closed").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, false); + + if (state.initialized) { + // resize 'length' and position togglers for adjacent panes + sizeHandles(); + } + } + + /** + * Open the specified pane (animation optional), and resize all other panes as needed + * + * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {boolean=} [slide=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [noAlert=false] + */ +, open = function (evt_or_pane, slide, noAnimation, noAlert) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , c = _c[pane] + , doFX, isShowing + ; + if (pane === "center") return; // validate + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + + if ( !$P + || (!o.resizable && !o.closable && !s.isShowing) // invalid request + || (s.isVisible && !s.isSliding) // already open + ) return queueNext(); + + // pane can ALSO be unhidden by just calling show(), so handle this scenario + if (s.isHidden && !s.isShowing) { + queueNext(); // call before show() because it needs the queue free + show(pane, true); + return; + } + + if (s.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true, true); // true=skipCallback/noAnimation/forceResize + else + // make sure there is enough space available to open the pane + setSizeLimits(pane, slide); + + // onopen_start callback - will CANCEL open if returns false + var cbReturn = _runCallbacks("onopen_start", pane); + + if (cbReturn === "abort") + return queueNext(); + + // update pane-state again in case options were changed in onopen_start + if (cbReturn !== "NC") // NC = "No Callback" + setSizeLimits(pane, slide); + + if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN! + syncPinBtns(pane, false); // make sure pin-buttons are reset + if (!noAlert && o.tips.noRoomToOpen) + alert(o.tips.noRoomToOpen); + return queueNext(); // ABORT + } + + if (slide) // START Sliding - will set isSliding=true + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead + bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false + else if (o.slidable) + bindStartSlidingEvents(pane, false); // UNBIND trigger events + + s.noRoom = false; // will be reset by makePaneFit if 'noRoom' + makePaneFit(pane); + + // transfer logic var to temp var + isShowing = s.isShowing; + // now clear the logic var + delete s.isShowing; + + doFX = !noAnimation && s.isClosed && (o.fxName_open != "none"); + s.isMoving = true; + s.isVisible = true; + s.isClosed = false; + // update isHidden BEFORE sizing panes - WHY??? Old? + if (isShowing) s.isHidden = false; + + if (doFX) { // ANIMATE + // mask adjacent panes with objects + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() { + lockPaneForFX(pane, false); // undo + if (s.isVisible) open_2(); // continue + queueNext(); + }); + } + else { // no animation + _showPane(pane);// just show pane and... + open_2(); // continue + queueNext(); + }; + }); + + // SUBROUTINE + function open_2 () { + s.isMoving = false; + + // cure iframe display issues + _fixIframe(pane); + + // NOTE: if isSliding, then other panes are NOT 'resized' + if (!s.isSliding) { // resize all panes adjacent to this one + sizeMidPanes(_c[pane].dir=="vert" ? "center" : "", false); // false = NOT skipCallback + } + + // set classes, position handles and execute callbacks... + setAsOpen(pane); + }; + + } + + /** + * @param {string} pane The pane just opened, ie: north, south, east, or west + * @param {boolean=} [skipCallback=false] + */ +, setAsOpen = function (pane, skipCallback) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _closed = "-closed" + , _sliding= "-sliding" + ; + $R + .css(side, sC.inset[side] + getPaneSize(pane)) // move the resizer + .removeClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .addClass( rClass+_open +" "+ rClass+_pane+_open ) + ; + if (s.isSliding) + $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + else // in case 'was sliding' + $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + + removeHover( 0, $R ); // remove hover classes + if (o.resizable && $.layout.plugins.draggable) + $R .draggable("enable") + .css("cursor", o.resizerCursor) + .attr("title", o.tips.Resize); + else if (!s.isSliding) + $R.css("cursor", "default"); // n-resize, s-resize, etc + + // if pane also has a toggler button, adjust that too + if ($T) { + $T .removeClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .addClass( tClass+_open +" "+ tClass+_pane+_open ) + .attr("title", o.tips.Close); // may be blank + removeHover( 0, $T ); // remove hover classes + // toggler-content - if exists + $T.children(".content-closed").hide(); + $T.children(".content-open").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, !s.isSliding); + + // update pane-state dimensions - BEFORE resizing content + $.extend(s, elDims($P)); + + if (state.initialized) { + // resize resizer & toggler sizes for all panes + sizeHandles(); + // resize content every time pane opens - to be sure + sizeContent(pane, true); // true = remeasure headers/footers, even if 'pane.isMoving' + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) { + // onopen callback + _runCallbacks("onopen_end", pane); + // onshow callback - TODO: should this be here? + if (s.isShowing) _runCallbacks("onshow_end", pane); + + // ALSO call onresize because layout-size *may* have changed while pane was closed + if (state.initialized) + _runCallbacks("onresize_end", pane); + } + + // TODO: Somehow sizePane("north") is being called after this point??? + } + + + /** + * slideOpen / slideClose / slideToggle + * + * Pass-though methods for sliding + */ +, slideOpen = function (evt_or_pane) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , s = state[pane] + , delay = options[pane].slideDelay_open + ; + if (pane === "center") return; // validate + // prevent event from triggering on NEW resizer binding created below + if (evt) evt.stopImmediatePropagation(); + + if (s.isClosed && evt && evt.type === "mouseenter" && delay > 0) + // trigger = mouseenter - use a delay + timer.set(pane+"_openSlider", open_NOW, delay); + else + open_NOW(); // will unbind events if is already open + + /** + * SUBROUTINE for timed open + */ + function open_NOW () { + if (!s.isClosed) // skip if no longer closed! + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (!s.isMoving) + open(pane, true); // true = slide - open() will handle binding + }; + } + +, slideClose = function (evt_or_pane) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , delay = s.isMoving ? 1000 : 300 // MINIMUM delay - option may override + ; + if (pane === "center") return; // validate + if (s.isClosed || s.isResizing) + return; // skip if already closed OR in process of resizing + else if (o.slideTrigger_close === "click") + close_NOW(); // close immediately onClick + else if (o.preventQuickSlideClose && s.isMoving) + return; // handle Chrome quick-close on slide-open + else if (o.preventPrematureSlideClose && evt && $.layout.isMouseOverElem(evt, $Ps[pane])) + return; // handle incorrect mouseleave trigger, like when over a SELECT-list in IE + else if (evt) // trigger = mouseleave - use a delay + // 1 sec delay if 'opening', else .3 sec + timer.set(pane+"_closeSlider", close_NOW, max(o.slideDelay_close, delay)); + else // called programically + close_NOW(); + + /** + * SUBROUTINE for timed close + */ + function close_NOW () { + if (s.isClosed) // skip 'close' if already closed! + bindStopSlidingEvents(pane, false); // UNBIND trigger events - TODO: is this needed here? + else if (!s.isMoving) + close(pane); // close will handle unbinding + }; + } + + /** + * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west + */ +, slideToggle = function (evt_or_pane) { + var pane = evtPane.call(this, evt_or_pane); + toggle(pane, true); + } + + + /** + * Must set left/top on East/South panes so animation will work properly + * + * @param {string} pane The pane to lock, 'east' or 'south' - any other is ignored! + * @param {boolean} doLock true = set left/top, false = remove + */ +, lockPaneForFX = function (pane, doLock) { + var $P = $Ps[pane] + , s = state[pane] + , o = options[pane] + , z = options.zIndexes + ; + if (doLock) { + showMasks( pane, { animation: true, objectsOnly: true }); + $P.css({ zIndex: z.pane_animate }); // overlay all elements during animation + if (pane=="south") + $P.css({ top: sC.inset.top + sC.innerHeight - $P.outerHeight() }); + else if (pane=="east") + $P.css({ left: sC.inset.left + sC.innerWidth - $P.outerWidth() }); + } + else { // animation DONE - RESET CSS + hideMasks(); + $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); + if (pane=="south") + $P.css({ top: "auto" }); + // if pane is positioned 'off-screen', then DO NOT screw with it! + else if (pane=="east" && !$P.css("left").match(/\-99999/)) + $P.css({ left: "auto" }); + // fix anti-aliasing in IE - only needed for animations that change opacity + if (browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1) + $P[0].style.removeAttribute('filter'); + } + } + + + /** + * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger + * + * @see open(), close() + * @param {string} pane The pane to enable/disable, 'north', 'south', etc. + * @param {boolean} enable Enable or Disable sliding? + */ +, bindStartSlidingEvents = function (pane, enable) { + var o = options[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , evtName = o.slideTrigger_open.toLowerCase() + ; + if (!$R || (enable && !o.slidable)) return; + + // make sure we have a valid event + if (evtName.match(/mouseover/)) + evtName = o.slideTrigger_open = "mouseenter"; + else if (!evtName.match(/(click|dblclick|mouseenter)/)) + evtName = o.slideTrigger_open = "click"; + + // must remove double-click-toggle when using dblclick-slide + if (o.resizerDblClickToggle && evtName.match(/click/)) { + $R[enable ? "unbind" : "bind"]('dblclick.'+ sID, toggle) + } + + $R + // add or remove event + [enable ? "bind" : "unbind"](evtName +'.'+ sID, slideOpen) + // set the appropriate cursor & title/tip + .css("cursor", enable ? o.sliderCursor : "default") + .attr("title", enable ? o.tips.Slide : "") + ; + } + + /** + * Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed + * Also increases zIndex when pane is sliding open + * See bindStartSlidingEvents for code to control 'slide open' + * + * @see slideOpen(), slideClose() + * @param {string} pane The pane to process, 'north', 'south', etc. + * @param {boolean} enable Enable or Disable events? + */ +, bindStopSlidingEvents = function (pane, enable) { + var o = options[pane] + , s = state[pane] + , c = _c[pane] + , z = options.zIndexes + , evtName = o.slideTrigger_close.toLowerCase() + , action = (enable ? "bind" : "unbind") + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + timer.clear(pane+"_closeSlider"); // just in case + + if (enable) { + s.isSliding = true; + state.panesSliding[pane] = true; + // remove 'slideOpen' event from resizer + // ALSO will raise the zIndex of the pane & resizer + bindStartSlidingEvents(pane, false); + } + else { + s.isSliding = false; + delete state.panesSliding[pane]; + } + + // RE/SET zIndex - increases when pane is sliding-open, resets to normal when not + $P.css("zIndex", enable ? z.pane_sliding : z.pane_normal); + $R.css("zIndex", enable ? z.pane_sliding+2 : z.resizer_normal); // NOTE: mask = pane_sliding+1 + + // make sure we have a valid event + if (!evtName.match(/(click|mouseleave)/)) + evtName = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout' + + // add/remove slide triggers + $R[action](evtName, slideClose); // base event on resize + // need extra events for mouseleave + if (evtName === "mouseleave") { + // also close on pane.mouseleave + $P[action]("mouseleave."+ sID, slideClose); + // cancel timer when mouse moves between 'pane' and 'resizer' + $R[action]("mouseenter."+ sID, cancelMouseOut); + $P[action]("mouseenter."+ sID, cancelMouseOut); + } + + if (!enable) + timer.clear(pane+"_closeSlider"); + else if (evtName === "click" && !o.resizable) { + // IF pane is not resizable (which already has a cursor and tip) + // then set the a cursor & title/tip on resizer when sliding + $R.css("cursor", enable ? o.sliderCursor : "default"); + $R.attr("title", enable ? o.tips.Close : ""); // use Toggler-tip, eg: "Close Pane" + } + + // SUBROUTINE for mouseleave timer clearing + function cancelMouseOut (evt) { + timer.clear(pane+"_closeSlider"); + evt.stopPropagation(); + } + } + + + /** + * Hides/closes a pane if there is insufficient room - reverses this when there is room again + * MUST have already called setSizeLimits() before calling this method + * + * @param {string} pane The pane being resized + * @param {boolean=} [isOpening=false] Called from onOpen? + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] + */ +, makePaneFit = function (pane, isOpening, skipCallback, force) { + var o = options[pane] + , s = state[pane] + , c = _c[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isSidePane = c.dir==="vert" + , hasRoom = false + ; + // special handling for center & east/west panes + if (pane === "center" || (isSidePane && s.noVerticalRoom)) { + // see if there is enough room to display the pane + // ERROR: hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth); + hasRoom = (s.maxHeight >= 0); + if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now + _showPane(pane); + if ($R) $R.show(); + s.isVisible = true; + s.noRoom = false; + if (isSidePane) s.noVerticalRoom = false; + _fixIframe(pane); + } + else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now + _hidePane(pane); + if ($R) $R.hide(); + s.isVisible = false; + s.noRoom = true; + } + } + + // see if there is enough room to fit the border-pane + if (pane === "center") { + // ignore center in this block + } + else if (s.minSize <= s.maxSize) { // pane CAN fit + hasRoom = true; + if (s.size > s.maxSize) // pane is too big - shrink it + sizePane(pane, s.maxSize, skipCallback, true, force); // true = noAnimation + else if (s.size < s.minSize) // pane is too small - enlarge it + sizePane(pane, s.minSize, skipCallback, true, force); // true = noAnimation + // need s.isVisible because new pseudoClose method keeps pane visible, but off-screen + else if ($R && s.isVisible && $P.is(":visible")) { + // make sure resizer-bar is positioned correctly + // handles situation where nested layout was 'hidden' when initialized + var pos = s.size + sC.inset[c.side]; + if ($.layout.cssNum( $R, c.side ) != pos) $R.css( c.side, pos ); + } + + // if was previously hidden due to noRoom, then RESET because NOW there is room + if (s.noRoom) { + // s.noRoom state will be set by open or show + if (s.wasOpen && o.closable) { + if (o.autoReopen) + open(pane, false, true, true); // true = noAnimation, true = noAlert + else // leave the pane closed, so just update state + s.noRoom = false; + } + else + show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert + } + } + else { // !hasRoom - pane CANNOT fit + if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now... + s.noRoom = true; // update state + s.wasOpen = !s.isClosed && !s.isSliding; + if (s.isClosed){} // SKIP + else if (o.closable) // 'close' if possible + close(pane, true, true); // true = force, true = noAnimation + else // 'hide' pane if cannot just be closed + hide(pane, true); // true = noAnimation + } + } + } + + + /** + * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized' + * + * @param {(string|Object)} evt_or_pane The pane being resized + * @param {number} size The *desired* new size for this pane - will be validated + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [force=false] Force resizing even if does not seem necessary + */ +, manualSizePane = function (evt_or_pane, size, skipCallback, noAnimation, force) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete... + , forceResize = force || (o.livePaneResizing && !s.isResizing) + ; + if (pane === "center") return; // validate + // ANY call to manualSizePane disables autoResize - ie, percentage sizing + s.autoResize = false; + // flow-through... + sizePane(pane, size, skipCallback, noAnimation, forceResize); // will animate resize if option enabled + } + + /** + * sizePane is called only by internal methods whenever a pane needs to be resized + * + * @param {(string|Object)} evt_or_pane The pane being resized + * @param {number} size The *desired* new size for this pane - will be validated + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [force=false] Force resizing even if does not seem necessary + */ +, sizePane = function (evt_or_pane, size, skipCallback, noAnimation, force) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) // probably NEVER called from event? + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , side = _c[pane].side + , dimName = _c[pane].sizeType.toLowerCase() + , skipResizeWhileDragging = s.isResizing && !o.triggerEventsDuringLiveResize + , doFX = noAnimation !== true && o.animatePaneSizing + , oldSize, newSize + ; + if (pane === "center") return; // validate + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + // calculate 'current' min/max sizes + setSizeLimits(pane); // update pane-state + oldSize = s.size; + size = _parseSize(pane, size); // handle percentages & auto + size = max(size, _parseSize(pane, o.minSize)); + size = min(size, s.maxSize); + if (size < s.minSize) { // not enough room for pane! + queueNext(); // call before makePaneFit() because it needs the queue free + makePaneFit(pane, false, skipCallback); // will hide or close pane + return; + } + + // IF newSize is same as oldSize, then nothing to do - abort + if (!force && size === oldSize) + return queueNext(); + + s.newSize = size; + + // onresize_start callback CANNOT cancel resizing because this would break the layout! + if (!skipCallback && state.initialized && s.isVisible) + _runCallbacks("onresize_start", pane); + + // resize the pane, and make sure its visible + newSize = cssSize(pane, size); + + if (doFX && $P.is(":visible")) { // ANIMATE + var fx = $.layout.effects.size[pane] || $.layout.effects.size.all + , easing = o.fxSettings_size.easing || fx.easing + , z = options.zIndexes + , props = {}; + props[ dimName ] = newSize +'px'; + s.isMoving = true; + // overlay all elements during animation + $P.css({ zIndex: z.pane_animate }) + .show().animate( props, o.fxSpeed_size, easing, function(){ + // reset zIndex after animation + $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); + s.isMoving = false; + delete s.newSize; + sizePane_2(); // continue + queueNext(); + }); + } + else { // no animation + $P.css( dimName, newSize ); // resize pane + delete s.newSize; + // if pane is visible, then + if ($P.is(":visible")) + sizePane_2(); // continue + else { + // pane is NOT VISIBLE, so just update state data... + // when pane is *next opened*, it will have the new size + s.size = size; // update state.size + //$.extend(s, elDims($P)); // update state dimensions - CANNOT do this when not visible! } + } + queueNext(); + }; + + }); + + // SUBROUTINE + function sizePane_2 () { + /* Panes are sometimes not sized precisely in some browsers!? + * This code will resize the pane up to 3 times to nudge the pane to the correct size + */ + var actual = dimName==='width' ? $P.outerWidth() : $P.outerHeight() + , tries = [{ + pane: pane + , count: 1 + , target: size + , actual: actual + , correct: (size === actual) + , attempt: size + , cssSize: newSize + }] + , lastTry = tries[0] + , thisTry = {} + , msg = 'Inaccurate size after resizing the '+ pane +'-pane.' + ; + while ( !lastTry.correct ) { + thisTry = { pane: pane, count: lastTry.count+1, target: size }; + + if (lastTry.actual > size) + thisTry.attempt = max(0, lastTry.attempt - (lastTry.actual - size)); + else // lastTry.actual < size + thisTry.attempt = max(0, lastTry.attempt + (size - lastTry.actual)); + + thisTry.cssSize = cssSize(pane, thisTry.attempt); + $P.css( dimName, thisTry.cssSize ); + + thisTry.actual = dimName=='width' ? $P.outerWidth() : $P.outerHeight(); + thisTry.correct = (size === thisTry.actual); + + // log attempts and alert the user of this *non-fatal error* (if showDebugMessages) + if ( tries.length === 1) { + _log(msg, false, true); + _log(lastTry, false, true); + } + _log(thisTry, false, true); + // after 4 tries, is as close as its gonna get! + if (tries.length > 3) break; + + tries.push( thisTry ); + lastTry = tries[ tries.length - 1 ]; + } + // END TESTING CODE + + // update pane-state dimensions + s.size = size; + $.extend(s, elDims($P)); + + if (s.isVisible && $P.is(":visible")) { + // reposition the resizer-bar + if ($R) $R.css( side, size + sC.inset[side] ); + // resize the content-div + sizeContent(pane); + } + + if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible) + _runCallbacks("onresize_end", pane); + + // resize all the adjacent panes, and adjust their toggler buttons + // when skipCallback passed, it means the controlling method will handle 'other panes' + if (!skipCallback) { + // also no callback if live-resize is in progress and NOT triggerEventsDuringLiveResize + if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "" : "center", skipResizeWhileDragging, force); + sizeHandles(); + } + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.oppositeEdge[pane]; + if (size < oldSize && state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane, false, skipCallback ); + } + + // DEBUG - ALERT user/developer so they know there was a sizing problem + if (tries.length > 1) + _log(msg +'\nSee the Error Console for details.', true, true); + } + } + + /** + * @see initPanes(), sizePane(), resizeAll(), open(), close(), hide() + * @param {(Array.|string)} panes The pane(s) being resized, comma-delmited string + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] + */ +, sizeMidPanes = function (panes, skipCallback, force) { + panes = (panes ? panes : "east,west,center").split(","); + + $.each(panes, function (i, pane) { + if (!$Ps[pane]) return; // NO PANE - skip + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isCenter= (pane=="center") + , hasRoom = true + , CSS = {} + // if pane is not visible, show it invisibly NOW rather than for *each call* in this script + , visCSS = $.layout.showInvisibly($P) + + , newCenter = calcNewCenterPaneDims() + ; + + // update pane-state dimensions + $.extend(s, elDims($P)); + + if (pane === "center") { + if (!force && s.isVisible && newCenter.width === s.outerWidth && newCenter.height === s.outerHeight) { + $P.css(visCSS); + return true; // SKIP - pane already the correct size + } + // set state for makePaneFit() logic + $.extend(s, cssMinDims(pane), { + maxWidth: newCenter.width + , maxHeight: newCenter.height + }); + CSS = newCenter; + s.newWidth = CSS.width; + s.newHeight = CSS.height; + // convert OUTER width/height to CSS width/height + CSS.width = cssW($P, CSS.width); + // NEW - allow pane to extend 'below' visible area rather than hide it + CSS.height = cssH($P, CSS.height); + hasRoom = CSS.width >= 0 && CSS.height >= 0; // height >= 0 = ALWAYS TRUE NOW + + // during layout init, try to shrink east/west panes to make room for center + if (!state.initialized && o.minWidth > newCenter.width) { + var + reqPx = o.minWidth - s.outerWidth + , minE = options.east.minSize || 0 + , minW = options.west.minSize || 0 + , sizeE = state.east.size + , sizeW = state.west.size + , newE = sizeE + , newW = sizeW + ; + if (reqPx > 0 && state.east.isVisible && sizeE > minE) { + newE = max( sizeE-minE, sizeE-reqPx ); + reqPx -= sizeE-newE; + } + if (reqPx > 0 && state.west.isVisible && sizeW > minW) { + newW = max( sizeW-minW, sizeW-reqPx ); + reqPx -= sizeW-newW; + } + // IF we found enough extra space, then resize the border panes as calculated + if (reqPx === 0) { + if (sizeE && sizeE != minE) + sizePane('east', newE, true, true, force); // true = skipCallback/noAnimation - initPanes will handle when done + if (sizeW && sizeW != minW) + sizePane('west', newW, true, true, force); // true = skipCallback/noAnimation + // now start over! + sizeMidPanes('center', skipCallback, force); + $P.css(visCSS); + return; // abort this loop + } + } + } + else { // for east and west, set only the height, which is same as center height + // set state.min/maxWidth/Height for makePaneFit() logic + if (s.isVisible && !s.noVerticalRoom) + $.extend(s, elDims($P), cssMinDims(pane)) + if (!force && !s.noVerticalRoom && newCenter.height === s.outerHeight) { + $P.css(visCSS); + return true; // SKIP - pane already the correct size + } + // east/west have same top, bottom & height as center + CSS.top = newCenter.top; + CSS.bottom = newCenter.bottom; + s.newSize = newCenter.height + // NEW - allow pane to extend 'below' visible area rather than hide it + CSS.height = cssH($P, newCenter.height); + s.maxHeight = CSS.height; + hasRoom = (s.maxHeight >= 0); // ALWAYS TRUE NOW + if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic + } + + if (hasRoom) { + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _runCallbacks("onresize_start", pane); + + $P.css(CSS); // apply the CSS to pane + if (pane !== "center") + sizeHandles(pane); // also update resizer length + if (s.noRoom && !s.isClosed && !s.isHidden) + makePaneFit(pane); // will re-open/show auto-closed/hidden pane + if (s.isVisible) { + $.extend(s, elDims($P)); // update pane dimensions + if (state.initialized) sizeContent(pane); // also resize the contents, if exists + } + } + else if (!s.noRoom && s.isVisible) // no room for pane + makePaneFit(pane); // will hide or close pane + + // reset visibility, if necessary + $P.css(visCSS); + + delete s.newSize; + delete s.newWidth; + delete s.newHeight; + + if (!s.isVisible) + return true; // DONE - next pane + + /* + * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes + * Normally these panes have only 'left' & 'right' positions so pane auto-sizes + * ALSO required when pane is an IFRAME because will NOT default to 'full width' + * TODO: Can I use width:100% for a north/south iframe? + * TODO: Sounds like a job for $P.outerWidth( sC.innerWidth ) SETTER METHOD + */ + if (pane === "center") { // finished processing midPanes + var fix = browser.isIE6 || !browser.boxModel; + if ($Ps.north && (fix || state.north.tagName=="IFRAME")) + $Ps.north.css("width", cssW($Ps.north, sC.innerWidth)); + if ($Ps.south && (fix || state.south.tagName=="IFRAME")) + $Ps.south.css("width", cssW($Ps.south, sC.innerWidth)); + } + + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _runCallbacks("onresize_end", pane); + }); + } + + + /** + * @see window.onresize(), callbacks or custom code + * @param {(Object|boolean)=} evt_or_refresh If 'true', then also reset pane-positioning + */ +, resizeAll = function (evt_or_refresh) { + var oldW = sC.innerWidth + , oldH = sC.innerHeight + ; + // stopPropagation if called by trigger("layoutdestroy") - use evtPane utility + evtPane(evt_or_refresh); + + // cannot size layout when 'container' is hidden or collapsed + if (!$N.is(":visible")) return; + + if (!state.initialized) { + _initLayoutElements(); + return; // no need to resize since we just initialized! + } + + if (evt_or_refresh === true && $.isPlainObject(options.outset)) { + // update container CSS in case outset option has changed + $N.css( options.outset ); + } + // UPDATE container dimensions + $.extend(sC, elDims( $N, options.inset )); + if (!sC.outerHeight) return; + + // if 'true' passed, refresh pane & handle positioning too + if (evt_or_refresh === true) { + setPanePosition(); + } + + // onresizeall_start will CANCEL resizing if returns false + // state.container has already been set, so user can access this info for calcuations + if (false === _runCallbacks("onresizeall_start")) return false; + + var // see if container is now 'smaller' than before + shrunkH = (sC.innerHeight < oldH) + , shrunkW = (sC.innerWidth < oldW) + , $P, o, s + ; + // NOTE special order for sizing: S-N-E-W + $.each(["south","north","east","west"], function (i, pane) { + if (!$Ps[pane]) return; // no pane - SKIP + o = options[pane]; + s = state[pane]; + if (s.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true, true); // true=skipCallback/noAnimation/forceResize + else { + setSizeLimits(pane); + makePaneFit(pane, false, true, true); // true=skipCallback/forceResize + } + }); + + sizeMidPanes("", true, true); // true=skipCallback/forceResize + sizeHandles(); // reposition the toggler elements + + // trigger all individual pane callbacks AFTER layout has finished resizing + $.each(_c.allPanes, function (i, pane) { + $P = $Ps[pane]; + if (!$P) return; // SKIP + if (state[pane].isVisible) // undefined for non-existent panes + _runCallbacks("onresize_end", pane); // callback - if exists + }); + + _runCallbacks("onresizeall_end"); + //_triggerLayoutEvent(pane, 'resizeall'); + } + + /** + * Whenever a pane resizes or opens that has a nested layout, trigger resizeAll + * + * @param {(string|Object)} evt_or_pane The pane just resized or opened + */ +, resizeChildren = function (evt_or_pane, skipRefresh) { + var pane = evtPane.call(this, evt_or_pane); + + if (!options[pane].resizeChildren) return; + + // ensure the pane-children are up-to-date + if (!skipRefresh) refreshChildren( pane ); + var pC = children[pane]; + if ($.isPlainObject( pC )) { + // resize one or more children + $.each( pC, function (key, child) { + if (!child.destroyed) child.resizeAll(); + }); + } + } + + /** + * IF pane has a content-div, then resize all elements inside pane to fit pane-height + * + * @param {(string|Object)} evt_or_panes The pane(s) being resized + * @param {boolean=} [remeasure=false] Should the content (header/footer) be remeasured? + */ +, sizeContent = function (evt_or_panes, remeasure) { + if (!isInitialized()) return; + + var panes = evtPane.call(this, evt_or_panes); + panes = panes ? panes.split(",") : _c.allPanes; + + $.each(panes, function (idx, pane) { + var + $P = $Ps[pane] + , $C = $Cs[pane] + , o = options[pane] + , s = state[pane] + , m = s.content // m = measurements + ; + if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip + + // if content-element was REMOVED, update OR remove the pointer + if (!$C.length) { + initContent(pane, false); // false = do NOT sizeContent() - already there! + if (!$C) return; // no replacement element found - pointer have been removed + } + + // onsizecontent_start will CANCEL resizing if returns false + if (false === _runCallbacks("onsizecontent_start", pane)) return; + + // skip re-measuring offsets if live-resizing + if ((!s.isMoving && !s.isResizing) || o.liveContentResizing || remeasure || m.top == undefined) { + _measure(); + // if any footers are below pane-bottom, they may not measure correctly, + // so allow pane overflow and re-measure + if (m.hiddenFooters > 0 && $P.css("overflow") === "hidden") { + $P.css("overflow", "visible"); + _measure(); // remeasure while overflowing + $P.css("overflow", "hidden"); + } + } + // NOTE: spaceAbove/Below *includes* the pane paddingTop/Bottom, but not pane.borders + var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom); + + if (!$C.is(":visible") || m.height != newH) { + // size the Content element to fit new pane-size - will autoHide if not enough room + setOuterHeight($C, newH, true); // true=autoHide + m.height = newH; // save new height + }; + + if (state.initialized) + _runCallbacks("onsizecontent_end", pane); + + function _below ($E) { + return max(s.css.paddingBottom, (parseInt($E.css("marginBottom"), 10) || 0)); + }; + + function _measure () { + var + ignore = options[pane].contentIgnoreSelector + , $Fs = $C.nextAll().not(".ui-layout-mask").not(ignore || ":lt(0)") // not :lt(0) = ALL + , $Fs_vis = $Fs.filter(':visible') + , $F = $Fs_vis.filter(':last') + ; + m = { + top: $C[0].offsetTop + , height: $C.outerHeight() + , numFooters: $Fs.length + , hiddenFooters: $Fs.length - $Fs_vis.length + , spaceBelow: 0 // correct if no content footer ($E) + } + m.spaceAbove = m.top; // just for state - not used in calc + m.bottom = m.top + m.height; + if ($F.length) + //spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom) + m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F); + else // no footer - check marginBottom on Content element itself + m.spaceBelow = _below($C); + }; + }); + } + + + /** + * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary + * + * @see initHandles(), open(), close(), resizeAll() + * @param {(string|Object)=} evt_or_panes The pane(s) being resized + */ +, sizeHandles = function (evt_or_panes) { + var panes = evtPane.call(this, evt_or_panes) + panes = panes ? panes.split(",") : _c.borderPanes; + + $.each(panes, function (i, pane) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , $TC + ; + if (!$P || !$R) return; + + var + dir = _c[pane].dir + , _state = (s.isClosed ? "_closed" : "_open") + , spacing = o["spacing"+ _state] + , togAlign = o["togglerAlign"+ _state] + , togLen = o["togglerLength"+ _state] + , paneLen + , left + , offset + , CSS = {} + ; + + if (spacing === 0) { + $R.hide(); + return; + } + else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason + $R.show(); // in case was previously hidden + + // Resizer Bar is ALWAYS same width/height of pane it is attached to + if (dir === "horz") { // north/south + //paneLen = $P.outerWidth(); // s.outerWidth || + paneLen = sC.innerWidth; // handle offscreen-panes + s.resizerLength = paneLen; + left = $.layout.cssNum($P, "left") + $R.css({ + width: cssW($R, paneLen) // account for borders & padding + , height: cssH($R, spacing) // ditto + , left: left > -9999 ? left : sC.inset.left // handle offscreen-panes + }); + } + else { // east/west + paneLen = $P.outerHeight(); // s.outerHeight || + s.resizerLength = paneLen; + $R.css({ + height: cssH($R, paneLen) // account for borders & padding + , width: cssW($R, spacing) // ditto + , top: sC.inset.top + getPaneSize("north", true) // TODO: what if no North pane? + //, top: $.layout.cssNum($Ps["center"], "top") + }); + } + + // remove hover classes + removeHover( o, $R ); + + if ($T) { + if (togLen === 0 || (s.isSliding && o.hideTogglerOnSlide)) { + $T.hide(); // always HIDE the toggler when 'sliding' + return; + } + else + $T.show(); // in case was previously hidden + + if (!(togLen > 0) || togLen === "100%" || togLen > paneLen) { + togLen = paneLen; + offset = 0; + } + else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed + if (isStr(togAlign)) { + switch (togAlign) { + case "top": + case "left": offset = 0; + break; + case "bottom": + case "right": offset = paneLen - togLen; + break; + case "middle": + case "center": + default: offset = round((paneLen - togLen) / 2); // 'default' catches typos + } + } + else { // togAlign = number + var x = parseInt(togAlign, 10); // + if (togAlign >= 0) offset = x; + else offset = paneLen - togLen + x; // NOTE: x is negative! + } + } + + if (dir === "horz") { // north/south + var width = cssW($T, togLen); + $T.css({ + width: width // account for borders & padding + , height: cssH($T, spacing) // ditto + , left: offset // TODO: VERIFY that toggler positions correctly for ALL values + , top: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginLeft", round((width-$TC.outerWidth())/2)); // could be negative + }); + } + else { // east/west + var height = cssH($T, togLen); + $T.css({ + height: height // account for borders & padding + , width: cssW($T, spacing) // ditto + , top: offset // POSITION the toggler + , left: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginTop", round((height-$TC.outerHeight())/2)); // could be negative + }); + } + + // remove ALL hover classes + removeHover( 0, $T ); + } + + // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now + if (!state.initialized && (o.initHidden || s.isHidden)) { + $R.hide(); + if ($T) $T.hide(); + } + }); + } + + + /** + * @param {(string|Object)} evt_or_pane + */ +, enableClosable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $T = $Ts[pane] + , o = options[pane] + ; + if (!$T) return; + o.closable = true; + $T .bind("click."+ sID, function(evt){ evt.stopPropagation(); toggle(pane); }) + .css("visibility", "visible") + .css("cursor", "pointer") + .attr("title", state[pane].isClosed ? o.tips.Open : o.tips.Close) // may be blank + .show(); + } + /** + * @param {(string|Object)} evt_or_pane + * @param {boolean=} [hide=false] + */ +, disableClosable = function (evt_or_pane, hide) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $T = $Ts[pane] + ; + if (!$T) return; + options[pane].closable = false; + // is closable is disable, then pane MUST be open! + if (state[pane].isClosed) open(pane, false, true); + $T .unbind("."+ sID) + .css("visibility", hide ? "hidden" : "visible") // instead of hide(), which creates logic issues + .css("cursor", "default") + .attr("title", ""); + } + + + /** + * @param {(string|Object)} evt_or_pane + */ +, enableSlidable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R || !$R.data('draggable')) return; + options[pane].slidable = true; + if (state[pane].isClosed) + bindStartSlidingEvents(pane, true); + } + /** + * @param {(string|Object)} evt_or_pane + */ +, disableSlidable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R) return; + options[pane].slidable = false; + if (state[pane].isSliding) + close(pane, false, true); + else { + bindStartSlidingEvents(pane, false); + $R .css("cursor", "default") + .attr("title", ""); + removeHover(null, $R[0]); // in case currently hovered + } + } + + + /** + * @param {(string|Object)} evt_or_pane + */ +, enableResizable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + , o = options[pane] + ; + if (!$R || !$R.data('draggable')) return; + o.resizable = true; + $R.draggable("enable"); + if (!state[pane].isClosed) + $R .css("cursor", o.resizerCursor) + .attr("title", o.tips.Resize); + } + /** + * @param {(string|Object)} evt_or_pane + */ +, disableResizable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R || !$R.data('draggable')) return; + options[pane].resizable = false; + $R .draggable("disable") + .css("cursor", "default") + .attr("title", ""); + removeHover(null, $R[0]); // in case currently hovered + } + + + /** + * Move a pane from source-side (eg, west) to target-side (eg, east) + * If pane exists on target-side, move that to source-side, ie, 'swap' the panes + * + * @param {(string|Object)} evt_or_pane1 The pane/edge being swapped + * @param {string} pane2 ditto + */ +, swapPanes = function (evt_or_pane1, pane2) { + if (!isInitialized()) return; + var pane1 = evtPane.call(this, evt_or_pane1); + // change state.edge NOW so callbacks can know where pane is headed... + state[pane1].edge = pane2; + state[pane2].edge = pane1; + // run these even if NOT state.initialized + if (false === _runCallbacks("onswap_start", pane1) + || false === _runCallbacks("onswap_start", pane2) + ) { + state[pane1].edge = pane1; // reset + state[pane2].edge = pane2; + return; + } + + var + oPane1 = copy( pane1 ) + , oPane2 = copy( pane2 ) + , sizes = {} + ; + sizes[pane1] = oPane1 ? oPane1.state.size : 0; + sizes[pane2] = oPane2 ? oPane2.state.size : 0; + + // clear pointers & state + $Ps[pane1] = false; + $Ps[pane2] = false; + state[pane1] = {}; + state[pane2] = {}; + + // ALWAYS remove the resizer & toggler elements + if ($Ts[pane1]) $Ts[pane1].remove(); + if ($Ts[pane2]) $Ts[pane2].remove(); + if ($Rs[pane1]) $Rs[pane1].remove(); + if ($Rs[pane2]) $Rs[pane2].remove(); + $Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false; + + // transfer element pointers and data to NEW Layout keys + move( oPane1, pane2 ); + move( oPane2, pane1 ); + + // cleanup objects + oPane1 = oPane2 = sizes = null; + + // make panes 'visible' again + if ($Ps[pane1]) $Ps[pane1].css(_c.visible); + if ($Ps[pane2]) $Ps[pane2].css(_c.visible); + + // fix any size discrepancies caused by swap + resizeAll(); + + // run these even if NOT state.initialized + _runCallbacks("onswap_end", pane1); + _runCallbacks("onswap_end", pane2); + + return; + + function copy (n) { // n = pane + var + $P = $Ps[n] + , $C = $Cs[n] + ; + return !$P ? false : { + pane: n + , P: $P ? $P[0] : false + , C: $C ? $C[0] : false + , state: $.extend(true, {}, state[n]) + , options: $.extend(true, {}, options[n]) + } + }; + + function move (oPane, pane) { + if (!oPane) return; + var + P = oPane.P + , C = oPane.C + , oldPane = oPane.pane + , c = _c[pane] + // save pane-options that should be retained + , s = $.extend(true, {}, state[pane]) + , o = options[pane] + // RETAIN side-specific FX Settings - more below + , fx = { resizerCursor: o.resizerCursor } + , re, size, pos + ; + $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) { + fx[k +"_open"] = o[k +"_open"]; + fx[k +"_close"] = o[k +"_close"]; + fx[k +"_size"] = o[k +"_size"]; + }); + + // update object pointers and attributes + $Ps[pane] = $(P) + .data({ + layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + }) + .css(_c.hidden) + .css(c.cssReq) + ; + $Cs[pane] = C ? $(C) : false; + + // set options and state + options[pane] = $.extend(true, {}, oPane.options, fx); + state[pane] = $.extend(true, {}, oPane.state); + + // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west + re = new RegExp(o.paneClass +"-"+ oldPane, "g"); + P.className = P.className.replace(re, o.paneClass +"-"+ pane); + + // ALWAYS regenerate the resizer & toggler elements + initHandles(pane); // create the required resizer & toggler + + // if moving to different orientation, then keep 'target' pane size + if (c.dir != _c[oldPane].dir) { + size = sizes[pane] || 0; + setSizeLimits(pane); // update pane-state + size = max(size, state[pane].minSize); + // use manualSizePane to disable autoResize - not useful after panes are swapped + manualSizePane(pane, size, true, true); // true/true = skipCallback/noAnimation + } + else // move the resizer here + $Rs[pane].css(c.side, sC.inset[c.side] + (state[pane].isVisible ? getPaneSize(pane) : 0)); + + + // ADD CLASSNAMES & SLIDE-BINDINGS + if (oPane.state.isVisible && !s.isVisible) + setAsOpen(pane, true); // true = skipCallback + else { + setAsClosed(pane); + bindStartSlidingEvents(pane, true); // will enable events IF option is set + } + + // DESTROY the object + oPane = null; + }; + } + + + /** + * INTERNAL method to sync pin-buttons when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @see open(), setAsOpen(), setAsClosed() + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin True means set the pin 'down', False means 'up' + */ +, syncPinBtns = function (pane, doPin) { + if ($.layout.plugins.buttons) + $.each(state[pane].pins, function (i, selector) { + $.layout.buttons.setPinState(Instance, $(selector), pane, doPin); + }); + } + +; // END var DECLARATIONS + + /** + * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed + * + * @see document.keydown() + */ + function keyDown (evt) { + if (!evt) return true; + var code = evt.keyCode; + if (code < 33) return true; // ignore special keys: ENTER, TAB, etc + + var + PANE = { + 38: "north" // Up Cursor - $.ui.keyCode.UP + , 40: "south" // Down Cursor - $.ui.keyCode.DOWN + , 37: "west" // Left Cursor - $.ui.keyCode.LEFT + , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT + } + , ALT = evt.altKey // no worky! + , SHIFT = evt.shiftKey + , CTRL = evt.ctrlKey + , CURSOR = (CTRL && code >= 37 && code <= 40) + , o, k, m, pane + ; + + if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey + pane = PANE[code]; + else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey + $.each(_c.borderPanes, function (i, p) { // loop each pane to check its hotkey + o = options[p]; + k = o.customHotkey; + m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT" + if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches + if (k && code === (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches + pane = p; + return false; // BREAK + } + } + }); + + // validate pane + if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden) + return true; + + toggle(pane); + + evt.stopPropagation(); + evt.returnValue = false; // CANCEL key + return false; + }; + + +/* + * ###################################### + * UTILITY METHODS + * called externally or by initButtons + * ###################################### + */ + + /** + * Change/reset a pane overflow setting & zIndex to allow popups/drop-downs to work + * + * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event + */ + function allowOverflow (el) { + if (!isInitialized()) return; + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + ; + + // if pane is already raised, then reset it before doing it again! + // this would happen if allowOverflow is attached to BOTH the pane and an element + if (s.cssSaved) + resetOverflow(pane); // reset previous CSS before continuing + + // if pane is raised by sliding or resizing, or its closed, then abort + if (s.isSliding || s.isResizing || s.isClosed) { + s.cssSaved = false; + return; + } + + var + newCSS = { zIndex: (options.zIndexes.resizer_normal + 1) } + , curCSS = {} + , of = $P.css("overflow") + , ofX = $P.css("overflowX") + , ofY = $P.css("overflowY") + ; + // determine which, if any, overflow settings need to be changed + if (of != "visible") { + curCSS.overflow = of; + newCSS.overflow = "visible"; + } + if (ofX && !ofX.match(/(visible|auto)/)) { + curCSS.overflowX = ofX; + newCSS.overflowX = "visible"; + } + if (ofY && !ofY.match(/(visible|auto)/)) { + curCSS.overflowY = ofX; + newCSS.overflowY = "visible"; + } + + // save the current overflow settings - even if blank! + s.cssSaved = curCSS; + + // apply new CSS to raise zIndex and, if necessary, make overflow 'visible' + $P.css( newCSS ); + + // make sure the zIndex of all other panes is normal + $.each(_c.allPanes, function(i, p) { + if (p != pane) resetOverflow(p); + }); + + }; + /** + * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event + */ + function resetOverflow (el) { + if (!isInitialized()) return; + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + , CSS = s.cssSaved || {} + ; + // reset the zIndex + if (!s.isSliding && !s.isResizing) + $P.css("zIndex", options.zIndexes.pane_normal); + + // reset Overflow - if necessary + $P.css( CSS ); + + // clear var + s.cssSaved = false; + }; + +/* + * ##################### + * CREATE/RETURN LAYOUT + * ##################### + */ + + // validate that container exists + var $N = $(this).eq(0); // FIRST matching Container element + if (!$N.length) { + return _log( options.errors.containerMissing ); + }; + + // Users retrieve Instance of a layout with: $N.layout() OR $N.data("layout") + // return the Instance-pointer if layout has already been initialized + if ($N.data("layoutContainer") && $N.data("layout")) + return $N.data("layout"); // cached pointer + + // init global vars + var + $Ps = {} // Panes x5 - set in initPanes() + , $Cs = {} // Content x5 - set in initPanes() + , $Rs = {} // Resizers x4 - set in initHandles() + , $Ts = {} // Togglers x4 - set in initHandles() + , $Ms = $([]) // Masks - up to 2 masks per pane (IFRAME + DIV) + // aliases for code brevity + , sC = state.container // alias for easy access to 'container dimensions' + , sID = state.id // alias for unique layout ID/namespace - eg: "layout435" + ; + + // create Instance object to expose data & option Properties, and primary action Methods + var Instance = { + // layout data + options: options // property - options hash + , state: state // property - dimensions hash + // object pointers + , container: $N // property - object pointers for layout container + , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center + , contents: $Cs // property - object pointers for ALL Content: contents.north, contents.center + , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north + , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north + // border-pane open/close + , hide: hide // method - ditto + , show: show // method - ditto + , toggle: toggle // method - pass a 'pane' ("north", "west", etc) + , open: open // method - ditto + , close: close // method - ditto + , slideOpen: slideOpen // method - ditto + , slideClose: slideClose // method - ditto + , slideToggle: slideToggle // method - ditto + // pane actions + , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data + , _sizePane: sizePane // method -intended for user by plugins only! + , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto' + , sizeContent: sizeContent // method - pass a 'pane' + , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them + , showMasks: showMasks // method - pass a 'pane' OR list of panes - default = all panes with mask option set + , hideMasks: hideMasks // method - ditto' + // pane element methods + , initContent: initContent // method - ditto + , addPane: addPane // method - pass a 'pane' + , removePane: removePane // method - pass a 'pane' to remove from layout, add 'true' to delete the pane-elem + , createChildren: createChildren // method - pass a 'pane' and (optional) layout-options (OVERRIDES options[pane].children + , refreshChildren: refreshChildren // method - pass a 'pane' and a layout-instance + // special pane option setting + , enableClosable: enableClosable // method - pass a 'pane' + , disableClosable: disableClosable // method - ditto + , enableSlidable: enableSlidable // method - ditto + , disableSlidable: disableSlidable // method - ditto + , enableResizable: enableResizable // method - ditto + , disableResizable: disableResizable// method - ditto + // utility methods for panes + , allowOverflow: allowOverflow // utility - pass calling element (this) + , resetOverflow: resetOverflow // utility - ditto + // layout control + , destroy: destroy // method - no parameters + , initPanes: isInitialized // method - no parameters + , resizeAll: resizeAll // method - no parameters + // callback triggering + , runCallbacks: _runCallbacks // method - pass evtName & pane (if a pane-event), eg: trigger("onopen", "west") + // alias collections of options, state and children - created in addPane and extended elsewhere + , hasParentLayout: false // set by initContainer() + , children: children // pointers to child-layouts, eg: Instance.children.west.layoutName + , north: false // alias group: { name: pane, pane: $Ps[pane], options: options[pane], state: state[pane], children: children[pane] } + , south: false // ditto + , west: false // ditto + , east: false // ditto + , center: false // ditto + }; + + // create the border layout NOW + if (_create() === 'cancel') // onload_start callback returned false to CANCEL layout creation + return null; + else // true OR false -- if layout-elements did NOT init (hidden or do not exist), can auto-init later + return Instance; // return the Instance object + +} + + +})( jQuery ); + + + + +/** + * jquery.layout.state 1.2 + * $Date: 2014-08-30 08:00:00 (Sat, 30 Aug 2014) $ + * + * Copyright (c) 2014 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @requires: UI Layout 1.4.0 or higher + * @requires: $.ui.cookie (above) + * + * @see: http://groups.google.com/group/jquery-ui-layout + */ +;(function ($) { + +if (!$.layout) return; + + +/** + * UI COOKIE UTILITY + * + * A $.cookie OR $.ui.cookie namespace *should be standard*, but until then... + * This creates $.ui.cookie so Layout does not need the cookie.jquery.js plugin + * NOTE: This utility is REQUIRED by the layout.state plugin + * + * Cookie methods in Layout are created as part of State Management + */ +if (!$.ui) $.ui = {}; +$.ui.cookie = { + + // cookieEnabled is not in DOM specs, but DOES works in all browsers,including IE6 + acceptsCookies: !!navigator.cookieEnabled + +, read: function (name) { + var + c = document.cookie + , cs = c ? c.split(';') : [] + , pair, data, i + ; + for (i=0; pair=cs[i]; i++) { + data = $.trim(pair).split('='); // name=value => [ name, value ] + if (data[0] == name) // found the layout cookie + return decodeURIComponent(data[1]); + } + return null; + } + +, write: function (name, val, cookieOpts) { + var params = "" + , date = "" + , clear = false + , o = cookieOpts || {} + , x = o.expires || null + , t = $.type(x) + ; + if (t === "date") + date = x; + else if (t === "string" && x > 0) { + x = parseInt(x,10); + t = "number"; + } + if (t === "number") { + date = new Date(); + if (x > 0) + date.setDate(date.getDate() + x); + else { + date.setFullYear(1970); + clear = true; + } + } + if (date) params += ";expires="+ date.toUTCString(); + if (o.path) params += ";path="+ o.path; + if (o.domain) params += ";domain="+ o.domain; + if (o.secure) params += ";secure"; + document.cookie = name +"="+ (clear ? "" : encodeURIComponent( val )) + params; // write or clear cookie + } + +, clear: function (name) { + $.ui.cookie.write(name, "", {expires: -1}); + } + +}; +// if cookie.jquery.js is not loaded, create an alias to replicate it +// this may be useful to other plugins or code dependent on that plugin +if (!$.cookie) $.cookie = function (k, v, o) { + var C = $.ui.cookie; + if (v === null) + C.clear(k); + else if (v === undefined) + return C.read(k); + else + C.write(k, v, o); +}; + + + +/** + * State-management options stored in options.stateManagement, which includes a .cookie hash + * Default options saves ALL KEYS for ALL PANES, ie: pane.size, pane.isClosed, pane.isHidden + * + * // STATE/COOKIE OPTIONS + * @example $(el).layout({ + stateManagement: { + enabled: true + , stateKeys: "east.size,west.size,east.isClosed,west.isClosed" + , cookie: { name: "appLayout", path: "/" } + } + }) + * @example $(el).layout({ stateManagement__enabled: true }) // enable auto-state-management using cookies + * @example $(el).layout({ stateManagement__cookie: { name: "appLayout", path: "/" } }) + * @example $(el).layout({ stateManagement__cookie__name: "appLayout", stateManagement__cookie__path: "/" }) + * + * // STATE/COOKIE METHODS + * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} ); + * @example myLayout.loadCookie(); + * @example myLayout.deleteCookie(); + * @example var JSON = myLayout.readState(); // CURRENT Layout State + * @example var JSON = myLayout.readCookie(); // SAVED Layout State (from cookie) + * @example var JSON = myLayout.state.stateData; // LAST LOADED Layout State (cookie saved in layout.state hash) + * + * CUSTOM STATE-MANAGEMENT (eg, saved in a database) + * @example var JSON = myLayout.readState( "west.isClosed,north.size,south.isHidden" ); + * @example myLayout.loadState( JSON ); + */ + +// tell Layout that the state plugin is available +$.layout.plugins.stateManagement = true; + +// Add State-Management options to layout.defaults +$.layout.defaults.stateManagement = { + enabled: false // true = enable state-management, even if not using cookies +, autoSave: true // Save a state-cookie when page exits? +, autoLoad: true // Load the state-cookie when Layout inits? +, animateLoad: true // animate panes when loading state into an active layout +, includeChildren: true // recurse into child layouts to include their state as well + // List state-data to save - must be pane-specific +, stateKeys: "north.size,south.size,east.size,west.size,"+ + "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ + "north.isHidden,south.isHidden,east.isHidden,west.isHidden" +, cookie: { + name: "" // If not specified, will use Layout.name, else just "Layout" + , domain: "" // blank = current domain + , path: "" // blank = current page, "/" = entire website + , expires: "" // 'days' to keep cookie - leave blank for 'session cookie' + , secure: false + } +}; + +// Set stateManagement as a 'layout-option', NOT a 'pane-option' +$.layout.optionsMap.layout.push("stateManagement"); +// Update config so layout does not move options into the pane-default branch (panes) +$.layout.config.optionRootKeys.push("stateManagement"); + +/* + * State Management methods + */ +$.layout.state = { + + /** + * Get the current layout state and save it to a cookie + * + * myLayout.saveCookie( keys, cookieOpts ) + * + * @param {Object} inst + * @param {(string|Array)=} keys + * @param {Object=} cookieOpts + */ + saveCookie: function (inst, keys, cookieOpts) { + var o = inst.options + , sm = o.stateManagement + , oC = $.extend(true, {}, sm.cookie, cookieOpts || null) + , data = inst.state.stateData = inst.readState( keys || sm.stateKeys ) // read current panes-state + ; + $.ui.cookie.write( oC.name || o.name || "Layout", $.layout.state.encodeJSON(data), oC ); + return $.extend(true, {}, data); // return COPY of state.stateData data + } + + /** + * Remove the state cookie + * + * @param {Object} inst + */ +, deleteCookie: function (inst) { + var o = inst.options; + $.ui.cookie.clear( o.stateManagement.cookie.name || o.name || "Layout" ); + } + + /** + * Read & return data from the cookie - as JSON + * + * @param {Object} inst + */ +, readCookie: function (inst) { + var o = inst.options; + var c = $.ui.cookie.read( o.stateManagement.cookie.name || o.name || "Layout" ); + // convert cookie string back to a hash and return it + return c ? $.layout.state.decodeJSON(c) : {}; + } + + /** + * Get data from the cookie and USE IT to loadState + * + * @param {Object} inst + */ +, loadCookie: function (inst) { + var c = $.layout.state.readCookie(inst); // READ the cookie + if (c && !$.isEmptyObject( c )) { + inst.state.stateData = $.extend(true, {}, c); // SET state.stateData + inst.loadState(c); // LOAD the retrieved state + } + return c; + } + + /** + * Update layout options from the cookie, if one exists + * + * @param {Object} inst + * @param {Object=} stateData + * @param {boolean=} animate + */ +, loadState: function (inst, data, opts) { + if (!$.isPlainObject( data ) || $.isEmptyObject( data )) return; + + // normalize data & cache in the state object + data = inst.state.stateData = $.layout.transformData( data ); // panes = default subkey + + // add missing/default state-restore options + var smo = inst.options.stateManagement; + opts = $.extend({ + animateLoad: false //smo.animateLoad + , includeChildren: smo.includeChildren + }, opts ); + + if (!inst.state.initialized) { + /* + * layout NOT initialized, so just update its options + */ + // MUST remove pane.children keys before applying to options + // use a copy so we don't remove keys from original data + var o = $.extend(true, {}, data); + //delete o.center; // center has no state-data - only children + $.each($.layout.config.allPanes, function (idx, pane) { + if (o[pane]) delete o[pane].children; + }); + // update CURRENT layout-options with saved state data + $.extend(true, inst.options, o); + } + else { + /* + * layout already initialized, so modify layout's configuration + */ + var noAnimate = !opts.animateLoad + , o, c, h, state, open + ; + $.each($.layout.config.borderPanes, function (idx, pane) { + o = data[ pane ]; + if (!$.isPlainObject( o )) return; // no key, skip pane + + s = o.size; + c = o.initClosed; + h = o.initHidden; + ar = o.autoResize + state = inst.state[pane]; + open = state.isVisible; + + // reset autoResize + if (ar) + state.autoResize = ar; + // resize BEFORE opening + if (!open) + inst._sizePane(pane, s, false, false, false); // false=skipCallback/noAnimation/forceResize + // open/close as necessary - DO NOT CHANGE THIS ORDER! + if (h === true) inst.hide(pane, noAnimate); + else if (c === true) inst.close(pane, false, noAnimate); + else if (c === false) inst.open (pane, false, noAnimate); + else if (h === false) inst.show (pane, false, noAnimate); + // resize AFTER any other actions + if (open) + inst._sizePane(pane, s, false, false, noAnimate); // animate resize if option passed + }); + + /* + * RECURSE INTO CHILD-LAYOUTS + */ + if (opts.includeChildren) { + var paneStateChildren, childState; + $.each(inst.children, function (pane, paneChildren) { + paneStateChildren = data[pane] ? data[pane].children : 0; + if (paneStateChildren && paneChildren) { + $.each(paneChildren, function (stateKey, child) { + childState = paneStateChildren[stateKey]; + if (child && childState) + child.loadState( childState ); + }); + } + }); + } + } + } + + /** + * Get the *current layout state* and return it as a hash + * + * @param {Object=} inst // Layout instance to get state for + * @param {object=} [opts] // State-Managements override options + */ +, readState: function (inst, opts) { + // backward compatility + if ($.type(opts) === 'string') opts = { keys: opts }; + if (!opts) opts = {}; + var sm = inst.options.stateManagement + , ic = opts.includeChildren + , recurse = ic !== undefined ? ic : sm.includeChildren + , keys = opts.stateKeys || sm.stateKeys + , alt = { isClosed: 'initClosed', isHidden: 'initHidden' } + , state = inst.state + , panes = $.layout.config.allPanes + , data = {} + , pair, pane, key, val + , ps, pC, child, array, count, branch + ; + if ($.isArray(keys)) keys = keys.join(","); + // convert keys to an array and change delimiters from '__' to '.' + keys = keys.replace(/__/g, ".").split(','); + // loop keys and create a data hash + for (var i=0, n=keys.length; i < n; i++) { + pair = keys[i].split("."); + pane = pair[0]; + key = pair[1]; + if ($.inArray(pane, panes) < 0) continue; // bad pane! + val = state[ pane ][ key ]; + if (val == undefined) continue; + if (key=="isClosed" && state[pane]["isSliding"]) + val = true; // if sliding, then *really* isClosed + ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val; + } + + // recurse into the child-layouts for each pane + if (recurse) { + $.each(panes, function (idx, pane) { + pC = inst.children[pane]; + ps = state.stateData[pane]; + if ($.isPlainObject( pC ) && !$.isEmptyObject( pC )) { + // ensure a key exists for this 'pane', eg: branch = data.center + branch = data[pane] || (data[pane] = {}); + if (!branch.children) branch.children = {}; + $.each( pC, function (key, child) { + // ONLY read state from an initialize layout + if ( child.state.initialized ) + branch.children[ key ] = $.layout.state.readState( child ); + // if we have PREVIOUS (onLoad) state for this child-layout, KEEP IT! + else if ( ps && ps.children && ps.children[ key ] ) { + branch.children[ key ] = $.extend(true, {}, ps.children[ key ] ); + } + }); + } + }); + } + + return data; + } + + /** + * Stringify a JSON hash so can save in a cookie or db-field + */ +, encodeJSON: function (json) { + var local = window.JSON || {}; + return (local.stringify || stringify)(json); + + function stringify (h) { + var D=[], i=0, k, v, t // k = key, v = value + , a = $.isArray(h) + ; + for (k in h) { + v = h[k]; + t = typeof v; + if (t == 'string') // STRING - add quotes + v = '"'+ v +'"'; + else if (t == 'object') // SUB-KEY - recurse into it + v = parse(v); + D[i++] = (!a ? '"'+ k +'":' : '') + v; + } + return (a ? '[' : '{') + D.join(',') + (a ? ']' : '}'); + }; + } + + /** + * Convert stringified JSON back to a hash object + * @see $.parseJSON(), adding in jQuery 1.4.1 + */ +, decodeJSON: function (str) { + try { return $.parseJSON ? $.parseJSON(str) : window["eval"]("("+ str +")") || {}; } + catch (e) { return {}; } + } + + +, _create: function (inst) { + var s = $.layout.state + , o = inst.options + , sm = o.stateManagement + ; + // ADD State-Management plugin methods to inst + $.extend( inst, { + // readCookie - update options from cookie - returns hash of cookie data + readCookie: function () { return s.readCookie(inst); } + // deleteCookie + , deleteCookie: function () { s.deleteCookie(inst); } + // saveCookie - optionally pass keys-list and cookie-options (hash) + , saveCookie: function (keys, cookieOpts) { return s.saveCookie(inst, keys, cookieOpts); } + // loadCookie - readCookie and use to loadState() - returns hash of cookie data + , loadCookie: function () { return s.loadCookie(inst); } + // loadState - pass a hash of state to use to update options + , loadState: function (stateData, opts) { s.loadState(inst, stateData, opts); } + // readState - returns hash of current layout-state + , readState: function (keys) { return s.readState(inst, keys); } + // add JSON utility methods too... + , encodeJSON: s.encodeJSON + , decodeJSON: s.decodeJSON + }); + + // init state.stateData key, even if plugin is initially disabled + inst.state.stateData = {}; + + // autoLoad MUST BE one of: data-array, data-hash, callback-function, or TRUE + if ( !sm.autoLoad ) return; + + // When state-data exists in the autoLoad key USE IT, + // even if stateManagement.enabled == false + if ($.isPlainObject( sm.autoLoad )) { + if (!$.isEmptyObject( sm.autoLoad )) { + inst.loadState( sm.autoLoad ); + } + } + else if ( sm.enabled ) { + // update the options from cookie or callback + // if options is a function, call it to get stateData + if ($.isFunction( sm.autoLoad )) { + var d = {}; + try { + d = sm.autoLoad( inst, inst.state, inst.options, inst.options.name || '' ); // try to get data from fn + } catch (e) {} + if (d && $.isPlainObject( d ) && !$.isEmptyObject( d )) + inst.loadState(d); + } + else // any other truthy value will trigger loadCookie + inst.loadCookie(); + } + } + +, _unload: function (inst) { + var sm = inst.options.stateManagement; + if (sm.enabled && sm.autoSave) { + // if options is a function, call it to save the stateData + if ($.isFunction( sm.autoSave )) { + try { + sm.autoSave( inst, inst.state, inst.options, inst.options.name || '' ); // try to get data from fn + } catch (e) {} + } + else // any truthy value will trigger saveCookie + inst.saveCookie(); + } + } + +}; + +// add state initialization method to Layout's onCreate array of functions +$.layout.onCreate.push( $.layout.state._create ); +$.layout.onUnload.push( $.layout.state._unload ); + +})( jQuery ); + + + +/** + * @preserve jquery.layout.buttons 1.0 + * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ + * + * Copyright (c) 2011 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @dependancies: UI Layout 1.3.0.rc30.1 or higher + * + * @support: http://groups.google.com/group/jquery-ui-layout + * + * Docs: [ to come ] + * Tips: [ to come ] + */ +;(function ($) { + +if (!$.layout) return; + + +// tell Layout that the state plugin is available +$.layout.plugins.buttons = true; + +// Add State-Management options to layout.defaults +$.layout.defaults.autoBindCustomButtons = false; +// Set stateManagement as a layout-option, NOT a pane-option +$.layout.optionsMap.layout.push("autoBindCustomButtons"); + +/* + * Button methods + */ +$.layout.buttons = { + // set data used by multiple methods below + config: { + borderPanes: "north,south,west,east" + } + + /** + * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons + * + * @see _create() + */ +, init: function (inst) { + var pre = "ui-layout-button-" + , layout = inst.options.name || "" + , name; + $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) { + $.each($.layout.buttons.config.borderPanes.split(","), function (ii, pane) { + $("."+pre+action+"-"+pane).each(function(){ + // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name' + name = $(this).data("layoutName") || $(this).attr("layoutName"); + if (name == undefined || name === layout) + inst.bindButton(this, action, pane); + }); + }); + }); + } + + /** + * Helper function to validate params received by addButton utilities + * + * Two classes are added to the element, based on the buttonClass... + * The type of button is appended to create the 2nd className: + * - ui-layout-button-pin + * - ui-layout-pane-button-toggle + * - ui-layout-pane-button-open + * - ui-layout-pane-button-close + * + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @return {Array.} If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null + */ +, get: function (inst, selector, pane, action) { + var $E = $(selector) + , o = inst.options + //, err = o.showErrorMessages + ; + if ($E.length && $.layout.buttons.config.borderPanes.indexOf(pane) >= 0) { + var btn = o[pane].buttonClass +"-"+ action; + $E .addClass( btn +" "+ btn +"-"+ pane ) + .data("layoutName", o.name); // add layout identifier - even if blank! + } + return $E; + } + + + /** + * NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc. + * + * @param {(string|!Object)} sel jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} action + * @param {string} pane + */ +, bind: function (inst, sel, action, pane) { + var _ = $.layout.buttons; + switch (action.toLowerCase()) { + case "toggle": _.addToggle (inst, sel, pane); break; + case "open": _.addOpen (inst, sel, pane); break; + case "close": _.addClose (inst, sel, pane); break; + case "pin": _.addPin (inst, sel, pane); break; + case "toggle-slide": _.addToggle (inst, sel, pane, true); break; + case "open-slide": _.addOpen (inst, sel, pane, true); break; + } + return inst; + } + + /** + * Add a custom Toggler button for a pane + * + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @param {boolean=} slide true = slide-open, false = pin-open + */ +, addToggle: function (inst, selector, pane, slide) { + $.layout.buttons.get(inst, selector, pane, "toggle") + .click(function(evt){ + inst.toggle(pane, !!slide); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Open button for a pane + * + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @param {boolean=} slide true = slide-open, false = pin-open + */ +, addOpen: function (inst, selector, pane, slide) { + $.layout.buttons.get(inst, selector, pane, "open") + .attr("title", inst.options[pane].tips.Open) + .click(function (evt) { + inst.open(pane, !!slide); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Close button for a pane + * + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + */ +, addClose: function (inst, selector, pane) { + $.layout.buttons.get(inst, selector, pane, "close") + .attr("title", inst.options[pane].tips.Close) + .click(function (evt) { + inst.close(pane); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Pin button for a pane + * + * Four classes are added to the element, based on the paneClass for the associated pane... + * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin: + * - ui-layout-pane-pin + * - ui-layout-pane-west-pin + * - ui-layout-pane-pin-up + * - ui-layout-pane-west-pin-up + * + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the pin is for: 'north', 'south', etc. + */ +, addPin: function (inst, selector, pane) { + var $E = $.layout.buttons.get(inst, selector, pane, "pin"); + if ($E.length) { + var s = inst.state[pane]; + $E.click(function (evt) { + $.layout.buttons.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed)); + if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open + else inst.close( pane ); // slide-closed + evt.stopPropagation(); + }); + // add up/down pin attributes and classes + $.layout.buttons.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding)); + // add this pin to the pane data so we can 'sync it' automatically + // PANE.pins key is an array so we can store multiple pins for each pane + s.pins.push( selector ); // just save the selector string + } + return inst; + } + + /** + * Change the class of the pin button to make it look 'up' or 'down' + * + * @see addPin(), syncPins() + * @param {Array.} $Pin The pin-span element in a jQuery wrapper + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin true = set the pin 'down', false = set it 'up' + */ +, setPinState: function (inst, $Pin, pane, doPin) { + var updown = $Pin.attr("pin"); + if (updown && doPin === (updown=="down")) return; // already in correct state + var + po = inst.options[pane] + , lang = po.tips + , pin = po.buttonClass +"-pin" + , side = pin +"-"+ pane + , UP = pin +"-up "+ side +"-up" + , DN = pin +"-down "+side +"-down" + ; + $Pin + .attr("pin", doPin ? "down" : "up") // logic + .attr("title", doPin ? lang.Unpin : lang.Pin) + .removeClass( doPin ? UP : DN ) + .addClass( doPin ? DN : UP ) + ; + } + + /** + * INTERNAL function to sync 'pin buttons' when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @see open(), close() + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin True means set the pin 'down', False means 'up' + */ +, syncPinBtns: function (inst, pane, doPin) { + // REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE + $.each(state[pane].pins, function (i, selector) { + $.layout.buttons.setPinState(inst, $(selector), pane, doPin); + }); + } + + +, _load: function (inst) { + // ADD Button methods to Layout Instance + $.extend( inst, { + bindButton: function (selector, action, pane) { return $.layout.buttons.bind(inst, selector, action, pane); } + // DEPRECATED METHODS... + , addToggleBtn: function (selector, pane, slide) { return $.layout.buttons.addToggle(inst, selector, pane, slide); } + , addOpenBtn: function (selector, pane, slide) { return $.layout.buttons.addOpen(inst, selector, pane, slide); } + , addCloseBtn: function (selector, pane) { return $.layout.buttons.addClose(inst, selector, pane); } + , addPinBtn: function (selector, pane) { return $.layout.buttons.addPin(inst, selector, pane); } + }); + + // init state array to hold pin-buttons + for (var i=0; i<4; i++) { + var pane = $.layout.buttons.config.borderPanes[i]; + inst.state[pane].pins = []; + } + + // auto-init buttons onLoad if option is enabled + if ( inst.options.autoBindCustomButtons ) + $.layout.buttons.init(inst); + } + +, _unload: function (inst) { + // TODO: unbind all buttons??? + } + +}; + +// add initialization method to Layout's onLoad array of functions +$.layout.onLoad.push( $.layout.buttons._load ); +//$.layout.onUnload.push( $.layout.buttons._unload ); + +})( jQuery ); + + + + +/** + * jquery.layout.browserZoom 1.0 + * $Date: 2011-12-29 08:00:00 (Thu, 29 Dec 2011) $ + * + * Copyright (c) 2012 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @requires: UI Layout 1.3.0.rc30.1 or higher + * + * @see: http://groups.google.com/group/jquery-ui-layout + * + * TODO: Extend logic to handle other problematic zooming in browsers + * TODO: Add hotkey/mousewheel bindings to _instantly_ respond to these zoom event + */ +(function ($) { + +// tell Layout that the plugin is available +$.layout.plugins.browserZoom = true; + +$.layout.defaults.browserZoomCheckInterval = 1000; +$.layout.optionsMap.layout.push("browserZoomCheckInterval"); + +/* + * browserZoom methods + */ +$.layout.browserZoom = { + + _init: function (inst) { + // abort if browser does not need this check + if ($.layout.browserZoom.ratio() !== false) + $.layout.browserZoom._setTimer(inst); + } + +, _setTimer: function (inst) { + // abort if layout destroyed or browser does not need this check + if (inst.destroyed) return; + var o = inst.options + , s = inst.state + // don't need check if inst has parentLayout, but check occassionally in case parent destroyed! + // MINIMUM 100ms interval, for performance + , ms = inst.hasParentLayout ? 5000 : Math.max( o.browserZoomCheckInterval, 100 ) + ; + // set the timer + setTimeout(function(){ + if (inst.destroyed || !o.resizeWithWindow) return; + var d = $.layout.browserZoom.ratio(); + if (d !== s.browserZoom) { + s.browserZoom = d; + inst.resizeAll(); + } + // set a NEW timeout + $.layout.browserZoom._setTimer(inst); + } + , ms ); + } + +, ratio: function () { + var w = window + , s = screen + , d = document + , dE = d.documentElement || d.body + , b = $.layout.browser + , v = b.version + , r, sW, cW + ; + // we can ignore all browsers that fire window.resize event onZoom + if (!b.msie || v > 8) + return false; // don't need to track zoom + if (s.deviceXDPI && s.systemXDPI) // syntax compiler hack + return calc(s.deviceXDPI, s.systemXDPI); + // everything below is just for future reference! + if (b.webkit && (r = d.body.getBoundingClientRect)) + return calc((r.left - r.right), d.body.offsetWidth); + if (b.webkit && (sW = w.outerWidth)) + return calc(sW, w.innerWidth); + if ((sW = s.width) && (cW = dE.clientWidth)) + return calc(sW, cW); + return false; // no match, so cannot - or don't need to - track zoom + + function calc (x,y) { return (parseInt(x,10) / parseInt(y,10) * 100).toFixed(); } + } + +}; +// add initialization method to Layout's onLoad array of functions +$.layout.onReady.push( $.layout.browserZoom._init ); + + +})( jQuery ); + + + + +/** + * UI Layout Plugin: Slide-Offscreen Animation + * + * Prevent panes from being 'hidden' so that an iframes/objects + * does not reload/refresh when pane 'opens' again. + * This plug-in adds a new animation called "slideOffscreen". + * It is identical to the normal "slide" effect, but avoids hiding the element + * + * Requires Layout 1.3.0.RC30.1 or later for Close offscreen + * Requires Layout 1.3.0.RC30.5 or later for Hide, initClosed & initHidden offscreen + * + * Version: 1.1 - 2012-11-18 + * Author: Kevin Dalman (kevin@jquery-dev.com) + * @preserve jquery.layout.slideOffscreen-1.1.js + */ +;(function ($) { + +// Add a new "slideOffscreen" effect +if ($.effects) { + + // add an option so initClosed and initHidden will work + $.layout.defaults.panes.useOffscreenClose = false; // user must enable when needed + /* set the new animation as the default for all panes + $.layout.defaults.panes.fxName = "slideOffscreen"; + */ + + if ($.layout.plugins) + $.layout.plugins.effects.slideOffscreen = true; + + // dupe 'slide' effect defaults as new effect defaults + $.layout.effects.slideOffscreen = $.extend(true, {}, $.layout.effects.slide); + + // add new effect to jQuery UI + $.effects.slideOffscreen = function(o) { + return this.queue(function(){ + + var fx = $.effects + , opt = o.options + , $el = $(this) + , pane = $el.data('layoutEdge') + , state = $el.data('parentLayout').state + , dist = state[pane].size + , s = this.style + , props = ['top','bottom','left','right'] + // Set options + , mode = fx.setMode($el, opt.mode || 'show') // Set Mode + , show = (mode == 'show') + , dir = opt.direction || 'left' // Default Direction + , ref = (dir == 'up' || dir == 'down') ? 'top' : 'left' + , pos = (dir == 'up' || dir == 'left') + , offscrn = $.layout.config.offscreenCSS || {} + , keyLR = $.layout.config.offscreenReset + , keyTB = 'offscreenResetTop' // only used internally + , animation = {} + ; + // Animation settings + animation[ref] = (show ? (pos ? '+=' : '-=') : (pos ? '-=' : '+=')) + dist; + + if (show) { // show() animation, so save top/bottom but retain left/right set when 'hidden' + $el.data(keyTB, { top: s.top, bottom: s.bottom }); + + // set the top or left offset in preparation for animation + // Note: ALL animations work by shifting the top or left edges + if (pos) { // top (north) or left (west) + $el.css(ref, isNaN(dist) ? "-" + dist : -dist); // Shift outside the left/top edge + } + else { // bottom (south) or right (east) - shift all the way across container + if (dir === 'right') + $el.css({ left: state.container.layoutWidth, right: 'auto' }); + else // dir === bottom + $el.css({ top: state.container.layoutHeight, bottom: 'auto' }); + } + // restore the left/right setting if is a top/bottom animation + if (ref === 'top') + $el.css( $el.data( keyLR ) || {} ); + } + else { // hide() animation, so save ALL CSS + $el.data(keyTB, { top: s.top, bottom: s.bottom }); + $el.data(keyLR, { left: s.left, right: s.right }); + } + + // Animate + $el.show().animate(animation, { queue: false, duration: o.duration, easing: opt.easing, complete: function(){ + // Restore top/bottom + if ($el.data( keyTB )) + $el.css($el.data( keyTB )).removeData( keyTB ); + if (show) // Restore left/right too + $el.css($el.data( keyLR ) || {}).removeData( keyLR ); + else // Move the pane off-screen (left: -99999, right: 'auto') + $el.css( offscrn ); + + if (o.callback) o.callback.apply(this, arguments); // Callback + $el.dequeue(); + }}); + + }); + }; + +} + +})( jQuery ); diff --git a/js-ext/prototype-License.txt b/js-ext/prototype-License.txt index 8b21dd55..69517cd2 100755 --- a/js-ext/prototype-License.txt +++ b/js-ext/prototype-License.txt @@ -1,16 +1,16 @@ -License - -Prototype is Copyright 2005-2007 Sam Stephenson. It is freely distributable under the terms of an MIT-style license. - - Copyright (c) 2005-2007 Sam Stephenson - - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated - documentation files (the Software), to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - - THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +License + +Prototype is Copyright 2005-2007 Sam Stephenson. It is freely distributable under the terms of an MIT-style license. + + Copyright (c) 2005-2007 Sam Stephenson + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + documentation files (the Software), to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/js-ext/yui-License.txt b/js-ext/yui-License.txt index ee46ee99..15d20f15 100755 --- a/js-ext/yui-License.txt +++ b/js-ext/yui-License.txt @@ -1,25 +1,25 @@ -Please see http://developer.yahoo.com/yui/license.html - - -The following was copied from the above URL: ------------------------------------------------------------------------------------------------------------------------------------------ -Software License Agreement (BSD License) -Copyright (c) 2008, Yahoo! Inc. -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following -conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the - following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Yahoo! Inc. nor the names of its contributors may be used to endorse or promote products derived from this - software without specific prior written permission of Yahoo! Inc. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +Please see http://developer.yahoo.com/yui/license.html + + +The following was copied from the above URL: +----------------------------------------------------------------------------------------------------------------------------------------- +Software License Agreement (BSD License) +Copyright (c) 2008, Yahoo! Inc. +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following +conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the + following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Yahoo! Inc. nor the names of its contributors may be used to endorse or promote products derived from this + software without specific prior written permission of Yahoo! Inc. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/js-ext/yui/README b/js-ext/yui/README index f88b44d5..aa77970c 100755 --- a/js-ext/yui/README +++ b/js-ext/yui/README @@ -1,306 +1,306 @@ -YUI Library Release Notes - - -*** version 2.5.2 *** - -This update contains the following: - -- Patches for DataTable and Menu posted to developer site following the release of 2.5.1 have been incorporated into the build. -- FireFox 3 compatibility in advance of its release. -- Opera 9.5 beta compatibility in advance of its release. -- ActionScript source for Charts and Uploader is now included. -- Charts component now includes support for dynamically created legends, and new chart and series styles. -- DataTable bug fixes in pagination, scrolling, and column handling. -- Several Rich Text Editor bug fixes. -- Approximately 15 Source Forge bug fixes. - -Please see the README file for each component in the build directory for specific updates since version 2.5.1. - -*** version 2.5.1 *** - -This update contains the following: - -- additions to the Yahoo, Uploader, Editor, and DataSource components to improve YUI support for Adobe AIR -- Douglas Crockford's fix for a security vulnerability where the JSON parser could be tricked into processing -an unquoted string as quoted which could allow unsafe scripts to be evaled -- a new aggregate file yuiloader-dom-event.js that is the ideal baseline rollup to use to be able to -lazy-load any part of YUI on-demand -- over 60 bug fixes - -Please see the README file for each component in the build directory for specific updates since version 2.5.0. - -*** version 2.5.0 *** - -This release introduces six new components into YUI: - - * Cookie Utility - * ImageCropper - * Layout Manager - * Resize - * Uploader - * Profiler Viewer - -These new components are introduced as "beta", with the exception of the Charts -WidgeUploadert which is released as an experimental component. Please see the YUI FAQ -on the definition of beta and experimental at: -http://developer.yahoo.com/yui/articles/faq/#beta - -In addition to new components, you'll find updates and bug fixes throughout the -library. - -*** version 2.4.1 *** - -This update contains one change. We have reverted the change to the way the Event Utility cleans up -events in its page unload handler that was introduced in 2.4.0. The change resulted in some events -not being properly unloaded, which in turn resulted in IE-specific memory leaks in some YUI components -including the Menu Control and controls in the Container Family. - -*** version 2.4.0 *** - -This release introduces five new components into YUI: - - * Selector - * Charts Widget - * Get Utility - * Profiler - * JSON Utility - -These new components are introduced as "beta", with the exception of the Charts -Widget which is released as an experimental component. Please see the YUI FAQ -on the definition of beta and experimental at: -http://developer.yahoo.com/yui/articles/faq/#beta - -In addition to new components, you'll find updates and bug fixes throughout the -library. - -*** version 2.3.1 *** - -This update contains general fixes to the YUI library. Please see the README -file for each component in the build directory for specific updates since -version 2.3.0. - -*** version 2.3.0 *** - -This release introduces six new components into YUI: - - * Base CSS - * Color Picker Control - * ImageLoader Utility - * Rich Text Editor - * YUI Loader Utility - * YUI Test Utility - -These new components are introduced as "beta", with the exception of ImageLoader -Utility which is released as an experimental component. Please see the YUI -FAQ on the definition of beta and experimental at: -http://developer.yahoo.com/yui/articles/faq/#beta - -In addition to new components, you'll find updates and bug fixes throughout the -library. - -*** version 2.2.2 *** - -This update contains general fixes to the YUI library. Please see the -README file for each component in the build directory for specific updates since -version 2.2.1. - -*** version 2.2.1 *** - -This update contains general fixes to the YUI library. Please see the -README file for each component in the build directory for specific updates since -version 2.2.0. - -*** version 2.2.0 *** - -This release synchronizes the SourceForge version with Yahoo!'s version of YUI --- version number 2.2.0. Please see the following blog article for information -on this specific version increment at: -http://www.yuiblog.com/blog/2007/02/20/yui-220-released - -The following new components are introduced with this release: - - * Button - * DataTable - * Browser History Manager - - The following components are now available as utilities: - - * Element - * DataSource - -These new components are introduced as "beta", with the exception of Browser -History Manager as an experimental component. Please see the YUI FAQ on the -definition of beta and experimental at: -http://developer.yahoo.com/yui/articles/faq/#beta - -* CSS customizations * -Calendar, Container, and Menu have been revised to allow image customizations -through their respective CSS files. Please refer to each component's README to -see the full details on affected properties. - -Additional details for fixes and updates can be found in the README files for -each updated component. All YUI API cheatsheets have been updated for the -current version and can be found at: yui/docs/assets/cheatsheets.zip. - -*** version 0.12.2 *** - -This update contains general fixes to the YUI library. Please see the -README file for each component in the build directory for specific updates since -version 0.12.1. As part of the 0.12.2 update, a number of corrections have been -made to functional examples that were configured incorrectly in 0.12.1. - -*** version 0.12.1 *** - -This update contains general fixes to the YUI library. Please see the -README file for each component in the build directory for specific updates since -version 0.12.0. - -Beginning with this release, all YUI minification will be performed with JSMin( -http://www.crockford.com/javascript/jsmin.html). Line breaks will be preserved. - -*** version 0.12.0 *** - -This version introduces the Tabview widget as well as general fixes to the YUI -library. Additional details can be found in the README files for each updated -component. All YUI API cheatsheets have been updated for the current version -and can be found at: yui/docs/assets/cheatsheets.zip. - -* documentation * -The YUI API documentation format is revised with this release. This new -format -- now a flat file structure under yui/docs/ -- implements the YUI -AutoComplete widget on the main landing page to allow keyword searching of YUI. -It also contains the full API documentation for all YUI components along with -the following categories of data for each component(if applicable): - -* Inheritance hierarchy for extensions and subclasses. -* YUI dependencies -* Properties and methods -* Events -* Configuration attributes. - -* concatenated files * -For convenience, three additional, minified variations of YUI are now available -for your use: - -* reset-fonts-grids.css -* yahoo-dom-event.js -* utilities.js - -* API changes * -There are interface changes to the Calendar widget. Please see the 0.12.0 -Calendar upgrade guide at http:// developer.yahoo.com/yui/calendar/upgrade.html -to see if this update affects your Calendar implementation and instructions on -upgrading to version 0.12.0. - - -*** version 0.11.4 *** - -This update contains some priority bug fixes to the following components: - -* Yahoo -* Container -* Drag and Drop -* Event - -Additional details can be found in the README files for each updated component. - -*** version 0.11.3 *** - -This update contains general fixes to the YUI library. Please see the -README file for each component in the build directory for updates and fixes -since version 0.11.2. - -*** version 0.11.2 *** - -This update contains a high-priority fix to Drag and Drop that prevents text -selection. Additional details can be found in the README file for: - -* Drag and Drop - -*** version 0.11.1 *** - -Release 0.11.1 addresses some high-priority bugs reported in the recently -released version 0.11.0. Additional details can be found in the README files for -each updated component: - -* Animation -* Dom -* Drag and Drop -* Connection Manager -* Container - -*** version 0.11.0 *** - -This version introduces the Logger widget. The YUI cheatsheets for version -0.11.0 and 0.10.0 are also included in this distribution under docs/assets. - -Please see the README file for each component in the build directory for -updates and fixes since version 0.10.0. - -*** version 0.10.0 *** - -In this release, the directory structure has been modified to provide more -component organization. This is the new format: - -yui/ - | - -- build/ - | | - | -- dom/ - | | - | | -- assets/ - | | - | | -- dom.js - | | - -- docs/ - | | - | -- dom/ - | | - -- examples/ - | | - | -- dom/ - | | - | | -- img/ - -Notice there are three immediate directories under the -root YUI. They are: - -*build/* -This directory contains the source files for each YUI component, and each -component is presented as a sub-directory under build/. Notice that there are -generally two source files: component.js and component-min.js. The "component" -source is the raw, commented build and "component-min" is the minified version -of the same file with comments and whitespace removed. With some components, -there is an assets sub-directory. CSS and image dependencies for each -component are stored in its assets sub-directory. - -Note: If a component makes use of images, the image source path in the -component's CSS file will point to Akamai. The physical images are also -available in the assets/ directory for local availability. Please modify the -CSS image references if you wish to use your own image assets. - -*docs/* -This directory contains the jsdoc-generated API reference for every YUI -component. Each component is presented as a sub-directory under docs/. - -*examples/* -This directory contains functional examples for each component in the YUI -Library. The examples are not part of the formal distribution; rather, -they provide demonstrations of each component in use. Each example uses YUI -Library source files from the build/ directory, while all example-specific -dependencies are stored in sub-directories (e.g. examples/dom/img). -Some components, including the AutoComplete Control and Connection Manager, -make use of PHP to implement certain examples. - -For example: -In yui/examples/dom, the dom.js source file and all YUI .js dependencies -are drawn from yui/build/ directories. All other example-specific sources are -stored as sub-directories: yui/examples/dom/css and yui/examples/dom/img. - -Each functional example is also available and functional on -developer.yahoo.com/yui/. They reproduced here as part of the distribution -for your convenience. - - - - +YUI Library Release Notes + + +*** version 2.5.2 *** + +This update contains the following: + +- Patches for DataTable and Menu posted to developer site following the release of 2.5.1 have been incorporated into the build. +- FireFox 3 compatibility in advance of its release. +- Opera 9.5 beta compatibility in advance of its release. +- ActionScript source for Charts and Uploader is now included. +- Charts component now includes support for dynamically created legends, and new chart and series styles. +- DataTable bug fixes in pagination, scrolling, and column handling. +- Several Rich Text Editor bug fixes. +- Approximately 15 Source Forge bug fixes. + +Please see the README file for each component in the build directory for specific updates since version 2.5.1. + +*** version 2.5.1 *** + +This update contains the following: + +- additions to the Yahoo, Uploader, Editor, and DataSource components to improve YUI support for Adobe AIR +- Douglas Crockford's fix for a security vulnerability where the JSON parser could be tricked into processing +an unquoted string as quoted which could allow unsafe scripts to be evaled +- a new aggregate file yuiloader-dom-event.js that is the ideal baseline rollup to use to be able to +lazy-load any part of YUI on-demand +- over 60 bug fixes + +Please see the README file for each component in the build directory for specific updates since version 2.5.0. + +*** version 2.5.0 *** + +This release introduces six new components into YUI: + + * Cookie Utility + * ImageCropper + * Layout Manager + * Resize + * Uploader + * Profiler Viewer + +These new components are introduced as "beta", with the exception of the Charts +WidgeUploadert which is released as an experimental component. Please see the YUI FAQ +on the definition of beta and experimental at: +http://developer.yahoo.com/yui/articles/faq/#beta + +In addition to new components, you'll find updates and bug fixes throughout the +library. + +*** version 2.4.1 *** + +This update contains one change. We have reverted the change to the way the Event Utility cleans up +events in its page unload handler that was introduced in 2.4.0. The change resulted in some events +not being properly unloaded, which in turn resulted in IE-specific memory leaks in some YUI components +including the Menu Control and controls in the Container Family. + +*** version 2.4.0 *** + +This release introduces five new components into YUI: + + * Selector + * Charts Widget + * Get Utility + * Profiler + * JSON Utility + +These new components are introduced as "beta", with the exception of the Charts +Widget which is released as an experimental component. Please see the YUI FAQ +on the definition of beta and experimental at: +http://developer.yahoo.com/yui/articles/faq/#beta + +In addition to new components, you'll find updates and bug fixes throughout the +library. + +*** version 2.3.1 *** + +This update contains general fixes to the YUI library. Please see the README +file for each component in the build directory for specific updates since +version 2.3.0. + +*** version 2.3.0 *** + +This release introduces six new components into YUI: + + * Base CSS + * Color Picker Control + * ImageLoader Utility + * Rich Text Editor + * YUI Loader Utility + * YUI Test Utility + +These new components are introduced as "beta", with the exception of ImageLoader +Utility which is released as an experimental component. Please see the YUI +FAQ on the definition of beta and experimental at: +http://developer.yahoo.com/yui/articles/faq/#beta + +In addition to new components, you'll find updates and bug fixes throughout the +library. + +*** version 2.2.2 *** + +This update contains general fixes to the YUI library. Please see the +README file for each component in the build directory for specific updates since +version 2.2.1. + +*** version 2.2.1 *** + +This update contains general fixes to the YUI library. Please see the +README file for each component in the build directory for specific updates since +version 2.2.0. + +*** version 2.2.0 *** + +This release synchronizes the SourceForge version with Yahoo!'s version of YUI +-- version number 2.2.0. Please see the following blog article for information +on this specific version increment at: +http://www.yuiblog.com/blog/2007/02/20/yui-220-released + +The following new components are introduced with this release: + + * Button + * DataTable + * Browser History Manager + + The following components are now available as utilities: + + * Element + * DataSource + +These new components are introduced as "beta", with the exception of Browser +History Manager as an experimental component. Please see the YUI FAQ on the +definition of beta and experimental at: +http://developer.yahoo.com/yui/articles/faq/#beta + +* CSS customizations * +Calendar, Container, and Menu have been revised to allow image customizations +through their respective CSS files. Please refer to each component's README to +see the full details on affected properties. + +Additional details for fixes and updates can be found in the README files for +each updated component. All YUI API cheatsheets have been updated for the +current version and can be found at: yui/docs/assets/cheatsheets.zip. + +*** version 0.12.2 *** + +This update contains general fixes to the YUI library. Please see the +README file for each component in the build directory for specific updates since +version 0.12.1. As part of the 0.12.2 update, a number of corrections have been +made to functional examples that were configured incorrectly in 0.12.1. + +*** version 0.12.1 *** + +This update contains general fixes to the YUI library. Please see the +README file for each component in the build directory for specific updates since +version 0.12.0. + +Beginning with this release, all YUI minification will be performed with JSMin( +http://www.crockford.com/javascript/jsmin.html). Line breaks will be preserved. + +*** version 0.12.0 *** + +This version introduces the Tabview widget as well as general fixes to the YUI +library. Additional details can be found in the README files for each updated +component. All YUI API cheatsheets have been updated for the current version +and can be found at: yui/docs/assets/cheatsheets.zip. + +* documentation * +The YUI API documentation format is revised with this release. This new +format -- now a flat file structure under yui/docs/ -- implements the YUI +AutoComplete widget on the main landing page to allow keyword searching of YUI. +It also contains the full API documentation for all YUI components along with +the following categories of data for each component(if applicable): + +* Inheritance hierarchy for extensions and subclasses. +* YUI dependencies +* Properties and methods +* Events +* Configuration attributes. + +* concatenated files * +For convenience, three additional, minified variations of YUI are now available +for your use: + +* reset-fonts-grids.css +* yahoo-dom-event.js +* utilities.js + +* API changes * +There are interface changes to the Calendar widget. Please see the 0.12.0 +Calendar upgrade guide at http:// developer.yahoo.com/yui/calendar/upgrade.html +to see if this update affects your Calendar implementation and instructions on +upgrading to version 0.12.0. + + +*** version 0.11.4 *** + +This update contains some priority bug fixes to the following components: + +* Yahoo +* Container +* Drag and Drop +* Event + +Additional details can be found in the README files for each updated component. + +*** version 0.11.3 *** + +This update contains general fixes to the YUI library. Please see the +README file for each component in the build directory for updates and fixes +since version 0.11.2. + +*** version 0.11.2 *** + +This update contains a high-priority fix to Drag and Drop that prevents text +selection. Additional details can be found in the README file for: + +* Drag and Drop + +*** version 0.11.1 *** + +Release 0.11.1 addresses some high-priority bugs reported in the recently +released version 0.11.0. Additional details can be found in the README files for +each updated component: + +* Animation +* Dom +* Drag and Drop +* Connection Manager +* Container + +*** version 0.11.0 *** + +This version introduces the Logger widget. The YUI cheatsheets for version +0.11.0 and 0.10.0 are also included in this distribution under docs/assets. + +Please see the README file for each component in the build directory for +updates and fixes since version 0.10.0. + +*** version 0.10.0 *** + +In this release, the directory structure has been modified to provide more +component organization. This is the new format: + +yui/ + | + -- build/ + | | + | -- dom/ + | | + | | -- assets/ + | | + | | -- dom.js + | | + -- docs/ + | | + | -- dom/ + | | + -- examples/ + | | + | -- dom/ + | | + | | -- img/ + +Notice there are three immediate directories under the +root YUI. They are: + +*build/* +This directory contains the source files for each YUI component, and each +component is presented as a sub-directory under build/. Notice that there are +generally two source files: component.js and component-min.js. The "component" +source is the raw, commented build and "component-min" is the minified version +of the same file with comments and whitespace removed. With some components, +there is an assets sub-directory. CSS and image dependencies for each +component are stored in its assets sub-directory. + +Note: If a component makes use of images, the image source path in the +component's CSS file will point to Akamai. The physical images are also +available in the assets/ directory for local availability. Please modify the +CSS image references if you wish to use your own image assets. + +*docs/* +This directory contains the jsdoc-generated API reference for every YUI +component. Each component is presented as a sub-directory under docs/. + +*examples/* +This directory contains functional examples for each component in the YUI +Library. The examples are not part of the formal distribution; rather, +they provide demonstrations of each component in use. Each example uses YUI +Library source files from the build/ directory, while all example-specific +dependencies are stored in sub-directories (e.g. examples/dom/img). +Some components, including the AutoComplete Control and Connection Manager, +make use of PHP to implement certain examples. + +For example: +In yui/examples/dom, the dom.js source file and all YUI .js dependencies +are drawn from yui/build/ directories. All other example-specific sources are +stored as sub-directories: yui/examples/dom/css and yui/examples/dom/img. + +Each functional example is also available and functional on +developer.yahoo.com/yui/. They reproduced here as part of the distribution +for your convenience. + + + + diff --git a/js-i2b2/cells/CRC/assets/main_list.css b/js-i2b2/cells/CRC/assets/main_list.css index bd5875ba..afff6dfa 100755 --- a/js-i2b2/cells/CRC/assets/main_list.css +++ b/js-i2b2/cells/CRC/assets/main_list.css @@ -1,13 +1,13 @@ -@import url(modLabValues.css); -@import url(sdx_CRC_QDEF.css); -@import url(sdx_CRC_QGDEF.css); -@import url(sdx_CRC_PR.css); -@import url(sdx_CRC_PRC.css); -@import url(sdx_CRC_PRS.css); -@import url(sdx_CRC_QI.css); -@import url(sdx_CRC_QM.css); -@import url(vwHistory.css); -@import url(vwQryTool.css); -@import url(vwStatus.css); - - +@import url(modLabValues.css); +@import url(sdx_CRC_QDEF.css); +@import url(sdx_CRC_QGDEF.css); +@import url(sdx_CRC_PR.css); +@import url(sdx_CRC_PRC.css); +@import url(sdx_CRC_PRS.css); +@import url(sdx_CRC_QI.css); +@import url(sdx_CRC_QM.css); +@import url(vwHistory.css); +@import url(vwQryTool.css); +@import url(vwStatus.css); + + diff --git a/js-i2b2/cells/CRC/assets/menu.css b/js-i2b2/cells/CRC/assets/menu.css index cbe131b1..f0915cd0 100755 --- a/js-i2b2/cells/CRC/assets/menu.css +++ b/js-i2b2/cells/CRC/assets/menu.css @@ -1,7 +1,7 @@ -/* -Copyright (c) 2008, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.6.0 -*/ -.yuimenu{top:-999em;left:-999em;}.yuimenubar{position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{position:absolute;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-scrollbars{overflow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yuimenubaritemlabel-selected{border-color:#7D98B8;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-selected{border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{*zoom:1;_zoom:normal;border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu .yuimenu .bd{*zoom:normal;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body-scrolled{border-color:#ccc #808080;overflow:hidden;}.yui-skin-sam .yuimenu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(../../../../assets/skins/sam/sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yuimenuitem-checked{background-image:url(menuitem_checkbox.png);background-position:left center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-shadow-visible{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(menuitem_checkbox_disabled.png);} +/* +Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.6.0 +*/ +.yuimenu{top:-999em;left:-999em;}.yuimenubar{position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{position:absolute;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-scrollbars{overflow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yuimenubaritemlabel-selected{border-color:#7D98B8;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-selected{border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{*zoom:1;_zoom:normal;border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu .yuimenu .bd{*zoom:normal;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body-scrolled{border-color:#ccc #808080;overflow:hidden;}.yui-skin-sam .yuimenu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(../../../../assets/skins/sam/sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yuimenuitem-checked{background-image:url(menuitem_checkbox.png);background-position:left center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-shadow-visible{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(menuitem_checkbox_disabled.png);} diff --git a/js-i2b2/cells/CRC/assets/modLabValues.css b/js-i2b2/cells/CRC/assets/modLabValues.css index 9fd6c8cd..1fa945b4 100755 --- a/js-i2b2/cells/CRC/assets/modLabValues.css +++ b/js-i2b2/cells/CRC/assets/modLabValues.css @@ -1,52 +1,52 @@ -DIV.modLabValues DIV.mlvBody { - width:auto; -} - -DIV.modLabValues DIV#mlvfrmNUMERIC P { - top-margin:0px; - bottom-margin:5px; -} - -DIV.modLabValues INPUT.numInput { - width:50px; -} - -DIV.modLabValues INPUT.strInput { - width:250px; -} - - -DIV.modLabValues DIV.mlvtop { - display:block; - vertical-align:top; - width:100%; -} - -DIV.modLabValues DIV.mlvModesGroup { - float:left; - margin:10px; - width:136px; -} - -DIV.modLabValues DIV.mlvInputGroup { - float:left; - margin:10px; - vertical-align:top; -} - -DIV.modLabValues DIV.mlvModesGroup > DIV { - float:left; - font-size:12px; - line-height:10px; - margin:0px; - padding:4px 0px; - width:180px; -} - -DIV.modLabValues A.barlink { - display:block; - width:100%; - text-decoration:none; - color:#000; - text-align: center; +DIV.modLabValues DIV.mlvBody { + width:auto; +} + +DIV.modLabValues DIV#mlvfrmNUMERIC P { + top-margin:0px; + bottom-margin:5px; +} + +DIV.modLabValues INPUT.numInput { + width:50px; +} + +DIV.modLabValues INPUT.strInput { + width:250px; +} + + +DIV.modLabValues DIV.mlvtop { + display:block; + vertical-align:top; + width:100%; +} + +DIV.modLabValues DIV.mlvModesGroup { + float:left; + margin:10px; + width:136px; +} + +DIV.modLabValues DIV.mlvInputGroup { + float:left; + margin:10px; + vertical-align:top; +} + +DIV.modLabValues DIV.mlvModesGroup > DIV { + float:left; + font-size:12px; + line-height:10px; + margin:0px; + padding:4px 0px; + width:180px; +} + +DIV.modLabValues A.barlink { + display:block; + width:100%; + text-decoration:none; + color:#000; + text-align: center; } \ No newline at end of file diff --git a/js-i2b2/cells/CRC/assets/sdx_CRC_PR.css b/js-i2b2/cells/CRC/assets/sdx_CRC_PR.css index c6e0a52c..0facf888 100755 --- a/js-i2b2/cells/CRC/assets/sdx_CRC_PR.css +++ b/js-i2b2/cells/CRC/assets/sdx_CRC_PR.css @@ -1,26 +1,26 @@ -.sdxDefaultPR { - font-family:arial,helvetica; - font-size:12px; - white-space:nowrap; - vertical-align:bottom; - cursor:pointer; - line-height:16px; -} -.sdxDefaultPR img { - height:16px; - width:16px; - border:none; - padding-right:3px; - vertical-align:bottom; -} -.sdxDefaultPR a { - color:#000000; - text-decoration:none; -} -.sdxDefaultPR a:hover { - text-decoration:underline; -} - -.ddPRTarget { - background:#FFFFBB !important; -} +.sdxDefaultPR { + font-family:arial,helvetica; + font-size:12px; + white-space:nowrap; + vertical-align:bottom; + cursor:pointer; + line-height:16px; +} +.sdxDefaultPR img { + height:16px; + width:16px; + border:none; + padding-right:3px; + vertical-align:bottom; +} +.sdxDefaultPR a { + color:#000000; + text-decoration:none; +} +.sdxDefaultPR a:hover { + text-decoration:underline; +} + +.ddPRTarget { + background:#FFFFBB !important; +} diff --git a/js-i2b2/cells/CRC/assets/sdx_CRC_PRC.css b/js-i2b2/cells/CRC/assets/sdx_CRC_PRC.css index 06b7ba9f..80718d23 100755 --- a/js-i2b2/cells/CRC/assets/sdx_CRC_PRC.css +++ b/js-i2b2/cells/CRC/assets/sdx_CRC_PRC.css @@ -1,26 +1,26 @@ -.sdxDefaultPRC { - font-family:arial,helvetica; - font-size:12px; - white-space:nowrap; - vertical-align:bottom; - cursor:pointer; - line-height:16px; -} -.sdxDefaultPRC img { - height:16px; - width:16px; - border:none; - padding-right:3px; - vertical-align:bottom; -} -.sdxDefaultPRC a { - color:#000000; - text-decoration:none; -} -.sdxDefaultPRC a:hover { - text-decoration:underline; -} - -.ddPRCTarget { - background:#FFFFBB !important; -} +.sdxDefaultPRC { + font-family:arial,helvetica; + font-size:12px; + white-space:nowrap; + vertical-align:bottom; + cursor:pointer; + line-height:16px; +} +.sdxDefaultPRC img { + height:16px; + width:16px; + border:none; + padding-right:3px; + vertical-align:bottom; +} +.sdxDefaultPRC a { + color:#000000; + text-decoration:none; +} +.sdxDefaultPRC a:hover { + text-decoration:underline; +} + +.ddPRCTarget { + background:#FFFFBB !important; +} diff --git a/js-i2b2/cells/CRC/assets/sdx_CRC_PRS.css b/js-i2b2/cells/CRC/assets/sdx_CRC_PRS.css index 60f1de43..04ab8195 100755 --- a/js-i2b2/cells/CRC/assets/sdx_CRC_PRS.css +++ b/js-i2b2/cells/CRC/assets/sdx_CRC_PRS.css @@ -1,26 +1,26 @@ -.sdxDefaultPRS { - font-family:arial,helvetica; - font-size:12px; - white-space:nowrap; - vertical-align:bottom; - cursor:pointer; - line-height:16px; -} -.sdxDefaultPRS img { - height:16px; - width:16px; - border:none; - padding-right:3px; - vertical-align:bottom; -} -.sdxDefaultPRS a { - color:#000000; - text-decoration:none; -} -.sdxDefaultPRS a:hover { - text-decoration:underline; -} - -.ddPRSTarget { - background:#FFFFBB !important; -} +.sdxDefaultPRS { + font-family:arial,helvetica; + font-size:12px; + white-space:nowrap; + vertical-align:bottom; + cursor:pointer; + line-height:16px; +} +.sdxDefaultPRS img { + height:16px; + width:16px; + border:none; + padding-right:3px; + vertical-align:bottom; +} +.sdxDefaultPRS a { + color:#000000; + text-decoration:none; +} +.sdxDefaultPRS a:hover { + text-decoration:underline; +} + +.ddPRSTarget { + background:#FFFFBB !important; +} diff --git a/js-i2b2/cells/CRC/assets/sdx_CRC_QDEF.css b/js-i2b2/cells/CRC/assets/sdx_CRC_QDEF.css index efbc3a9c..207ecdfe 100755 --- a/js-i2b2/cells/CRC/assets/sdx_CRC_QDEF.css +++ b/js-i2b2/cells/CRC/assets/sdx_CRC_QDEF.css @@ -1,26 +1,26 @@ -.sdxDefaultQDEF { - font-family:arial,helvetica; - font-size:12px; - white-space:nowrap; - vertical-align:bottom; - cursor:pointer; - line-height:16px; -} -.sdxDefaultQDEF img { - height:16px; - width:16px; - border:none; - padding-right:3px; - vertical-align:bottom; -} -.sdxDefaultQDEF a { - color:#000000; - text-decoration:none; -} -.sdxDefaultQDEF a:hover { - text-decoration:underline; -} - -.ddQDEFTarget { - background:#FFFFBB !important; -} +.sdxDefaultQDEF { + font-family:arial,helvetica; + font-size:12px; + white-space:nowrap; + vertical-align:bottom; + cursor:pointer; + line-height:16px; +} +.sdxDefaultQDEF img { + height:16px; + width:16px; + border:none; + padding-right:3px; + vertical-align:bottom; +} +.sdxDefaultQDEF a { + color:#000000; + text-decoration:none; +} +.sdxDefaultQDEF a:hover { + text-decoration:underline; +} + +.ddQDEFTarget { + background:#FFFFBB !important; +} diff --git a/js-i2b2/cells/CRC/assets/sdx_CRC_QGDEF.css b/js-i2b2/cells/CRC/assets/sdx_CRC_QGDEF.css index 172275cb..14faf105 100755 --- a/js-i2b2/cells/CRC/assets/sdx_CRC_QGDEF.css +++ b/js-i2b2/cells/CRC/assets/sdx_CRC_QGDEF.css @@ -1,26 +1,26 @@ -.sdxDefaultQGDEF { - font-family:arial,helvetica; - font-size:12px; - white-space:nowrap; - vertical-align:bottom; - cursor:pointer; - line-height:16px; -} -.sdxDefaultQGDEF img { - height:16px; - width:16px; - border:none; - padding-right:3px; - vertical-align:bottom; -} -.sdxDefaultQGDEF a { - color:#000000; - text-decoration:none; -} -.sdxDefaultQGDEF a:hover { - text-decoration:underline; -} - -.ddQGDEFTarget { - background:#FFFFBB !important; -} +.sdxDefaultQGDEF { + font-family:arial,helvetica; + font-size:12px; + white-space:nowrap; + vertical-align:bottom; + cursor:pointer; + line-height:16px; +} +.sdxDefaultQGDEF img { + height:16px; + width:16px; + border:none; + padding-right:3px; + vertical-align:bottom; +} +.sdxDefaultQGDEF a { + color:#000000; + text-decoration:none; +} +.sdxDefaultQGDEF a:hover { + text-decoration:underline; +} + +.ddQGDEFTarget { + background:#FFFFBB !important; +} diff --git a/js-i2b2/cells/CRC/assets/sdx_CRC_QI.css b/js-i2b2/cells/CRC/assets/sdx_CRC_QI.css index e23cb8a6..6bfa8ccc 100755 --- a/js-i2b2/cells/CRC/assets/sdx_CRC_QI.css +++ b/js-i2b2/cells/CRC/assets/sdx_CRC_QI.css @@ -1,26 +1,26 @@ -.sdxDefaultQI { - font-family:arial,helvetica; - font-size:12px; - white-space:nowrap; - vertical-align:bottom; - cursor:pointer; - line-height:16px; -} -.sdxDefaultQI img { - height:16px; - width:16px; - border:none; - padding-right:3px; - vertical-align:bottom; -} -.sdxDefaultQI a { - color:#000000; - text-decoration:none; -} -.sdxDefaultQI a:hover { - text-decoration:underline; -} - -.ddQITarget { - background:#FFFFBB !important; -} +.sdxDefaultQI { + font-family:arial,helvetica; + font-size:12px; + white-space:nowrap; + vertical-align:bottom; + cursor:pointer; + line-height:16px; +} +.sdxDefaultQI img { + height:16px; + width:16px; + border:none; + padding-right:3px; + vertical-align:bottom; +} +.sdxDefaultQI a { + color:#000000; + text-decoration:none; +} +.sdxDefaultQI a:hover { + text-decoration:underline; +} + +.ddQITarget { + background:#FFFFBB !important; +} diff --git a/js-i2b2/cells/CRC/assets/sdx_CRC_QM.css b/js-i2b2/cells/CRC/assets/sdx_CRC_QM.css index 5e5bbcb6..6e6133e8 100755 --- a/js-i2b2/cells/CRC/assets/sdx_CRC_QM.css +++ b/js-i2b2/cells/CRC/assets/sdx_CRC_QM.css @@ -1,27 +1,27 @@ -.sdxDefaultQM { - font-family:arial,helvetica; - font-size:12px; - white-space:nowrap; - vertical-align:bottom; - cursor:pointer; - line-height:16px; -} -.sdxDefaultQM img { - height:16px; - width:16px; - border:none; - padding-right:3px; - vertical-align:bottom; -} -.sdxDefaultQM a { - color:#000000; - text-decoration:none; -} -.sdxDefaultQM a:hover { - text-decoration:underline; -} - -.ddQMTarget { - background:#FFFFBB !important; -} - +.sdxDefaultQM { + font-family:arial,helvetica; + font-size:12px; + white-space:nowrap; + vertical-align:bottom; + cursor:pointer; + line-height:16px; +} +.sdxDefaultQM img { + height:16px; + width:16px; + border:none; + padding-right:3px; + vertical-align:bottom; +} +.sdxDefaultQM a { + color:#000000; + text-decoration:none; +} +.sdxDefaultQM a:hover { + text-decoration:underline; +} + +.ddQMTarget { + background:#FFFFBB !important; +} + diff --git a/js-i2b2/cells/ONT/assets/main_list.css b/js-i2b2/cells/ONT/assets/main_list.css index 11bc27c5..695311ee 100755 --- a/js-i2b2/cells/ONT/assets/main_list.css +++ b/js-i2b2/cells/ONT/assets/main_list.css @@ -1,2 +1,2 @@ -@import url(sdx_ONT_CONCPT.css); -@import url(ontMain.css); +@import url(sdx_ONT_CONCPT.css); +@import url(ontMain.css); diff --git a/js-i2b2/cells/PLUGINMGR/PLUGINMGR_ctrlr_general.js b/js-i2b2/cells/PLUGINMGR/PLUGINMGR_ctrlr_general.js index 08cbaeed..05edb5af 100755 --- a/js-i2b2/cells/PLUGINMGR/PLUGINMGR_ctrlr_general.js +++ b/js-i2b2/cells/PLUGINMGR/PLUGINMGR_ctrlr_general.js @@ -1,184 +1,184 @@ -/** - * @projectDescription Main controller for the Plugin Manager system. - * @inherits i2b2 - * @namespace i2b2.PLUGINMGR - * @author Nick Benik, Griffin Weber MD PhD - * @version 1.4 - * ---------------------------------------------------------------------------------------- - * updated 9-18-09: Updates required by PM update [Nick Benik] - */ -console.group('Load & Execute component file: PLUGINMGR > ctrl > general'); -console.time('execute time'); - - -// helper function to be used by plugins to create canvas objects -i2b2.PLUGINMGR.createCanvas = function(containerDIV){ - // we must dynamically create our CANVAS node - var canvas = document.createElement("canvas"); - var trgtDIV = $(containerDIV); - if (!trgtDIV.appendChild) { - console.error("[i2b2.PLUGINMGR.createCanvas] Bad canvas container DIV provided"); - return false; - } - trgtDIV.appendChild(canvas); - - // dynamically initialize canvas object (only on IE) - if (/msie/i.test(navigator.userAgent)) { - var guid = i2b2.h.GenerateAlphaNumId(6); - canvas.id = guid; - G_vmlCanvasManager.initElement(canvas); - var canvas = $(guid); - canvas.id = ""; - } - return canvas; -}; - - -// main plugin handler -i2b2.PLUGINMGR.visible = false; -i2b2.PLUGINMGR.ctrlr.main = -{ - ZoomView: function() { - if (i2b2.hive.MasterView.getViewMode()=="Analysis") { - i2b2.hive.MasterView.setViewMode('AnalysisZoomed'); - } else { - i2b2.hive.MasterView.setViewMode('Analysis'); - } - }, -/* - getPluginList: function() { - var results = {}; - var cellsLoaded = i2b2.hive.cfg.LoadedCells; - for (var i1=0; i1Select a plugin to load'); - doc.close(); - } else { - // clear DIV - var trgt = $('anaPluginViewFrame'); - while (trgt.childNodes.length > 0) { trgt.removeChild(trgt.firstChild); } - trgt.innerHTML = ''; - } - delete i2b2.PLUGINMGR.ctrlr.main.currentPluginCtrlr; - } else { - return false; - } - } - - // show the plugin name on the main container tab - try { - if (i2b2[pluginCode].cfg.config.short_name) { - sName = i2b2[pluginCode].cfg.config.short_name; - } else { - sName = i2b2[pluginCode].cfg.config.name; - } - $('anaPluginViewBox').select('DIV.tabBox DIV')[0].innerHTML = sName; - } catch(e) { - console.warn("Could not change PluginViewBox tab label!"); - } - // LOAD PLUGIN GUI - if (!i2b2.h.isBadObjPath('i2b2.'+pluginCode+'.cfg.config.plugin.iframe')) { - // the plugin requires loading into an IFRAME - } else if (!i2b2.h.isBadObjPath('i2b2.'+pluginCode+'.cfg.config.plugin.html')) { - // the plugin requires direct loading into the DOM tree - var url = i2b2[pluginCode].cfg.config.assetDir + i2b2[pluginCode].cfg.config.plugin.html.source; - var response = new Ajax.Request(url, {method: 'get', asynchronous: false}); - console.dir(response); - if (response.transport.statusText=="OK") { - // load the html into the IFRAME - var doc = $('anaPluginIFRAME').contentDocument; - if (!doc) {var doc = $('anaPluginIFRAME').contentWindow.document; } - doc.open(); - doc.write(response.transport.responseText); - doc.close(); - // get the main screen DIV - var mainDiv = doc.getElementById(i2b2[pluginCode].cfg.config.plugin.html.mainDivId); - if (!mainDiv) { - alert("The Plugin's screen was loaded but had errors."); - return false; - } - // clear plugin view window - var trgt = $('anaPluginViewFrame'); - while (trgt.childNodes.length > 0) { trgt.removeChild(trgt.firstChild); } - // copy the div to our working window and display it. - if (mainDiv.outerHTML) { - // fix for IE issues - trgt.innerHTML = mainDiv.outerHTML; - var scrn = trgt.firstChild; - scrn.style.display = ''; - } else { - var scrn = mainDiv.cloneNode(true); - trgt.appendChild(scrn); - scrn.show(); - } - // perform GUI changes if the plugin is going to be using standard tabs at the top - var useTabs = false; - if (!i2b2.h.isBadObjPath('i2b2.'+pluginCode+'.cfg.config.plugin.standardTabs')) { - useTabs = Boolean.parseTo(i2b2[pluginCode].cfg.config.plugin.standardTabs); - } - i2b2.PLUGINMGR.view.PlugView.UsesTabs(useTabs); - // show plugin - trgt.show(); - // notify the plugin's controller class to activate - try { - i2b2[pluginCode].Init(scrn); - i2b2.PLUGINMGR.ctrlr.main.currentPluginCtrlr = i2b2[pluginCode]; - i2b2.PLUGINMGR.ctrlr.main.currentPluginParentDiv = scrn; - } catch(e) { - alert('An error has occurred while trying to initialize the Plugin.'); - } - // fire the plugin's Resize() function - i2b2.PLUGINMGR.view.PlugView.ResizeHeight(); - // Reconnect any drag drop handlers that have been dropped, if this plugin has been previously loaded (a YUI issue) - YAHOO.util.DDM.reattachHandlers(); - - - } else { - alert('A problem was encounter while loading the plugin.'); - return false; - } - } else { - alert("The plugin you clicked does not specify how it needs to be loaded."); - return false; - } - } -}; - - - -console.timeEnd('execute time'); -console.groupEnd(); +/** + * @projectDescription Main controller for the Plugin Manager system. + * @inherits i2b2 + * @namespace i2b2.PLUGINMGR + * @author Nick Benik, Griffin Weber MD PhD + * @version 1.4 + * ---------------------------------------------------------------------------------------- + * updated 9-18-09: Updates required by PM update [Nick Benik] + */ +console.group('Load & Execute component file: PLUGINMGR > ctrl > general'); +console.time('execute time'); + + +// helper function to be used by plugins to create canvas objects +i2b2.PLUGINMGR.createCanvas = function(containerDIV){ + // we must dynamically create our CANVAS node + var canvas = document.createElement("canvas"); + var trgtDIV = $(containerDIV); + if (!trgtDIV.appendChild) { + console.error("[i2b2.PLUGINMGR.createCanvas] Bad canvas container DIV provided"); + return false; + } + trgtDIV.appendChild(canvas); + + // dynamically initialize canvas object (only on IE) + if (/msie/i.test(navigator.userAgent)) { + var guid = i2b2.h.GenerateAlphaNumId(6); + canvas.id = guid; + G_vmlCanvasManager.initElement(canvas); + var canvas = $(guid); + canvas.id = ""; + } + return canvas; +}; + + +// main plugin handler +i2b2.PLUGINMGR.visible = false; +i2b2.PLUGINMGR.ctrlr.main = +{ + ZoomView: function() { + if (i2b2.hive.MasterView.getViewMode()=="Analysis") { + i2b2.hive.MasterView.setViewMode('AnalysisZoomed'); + } else { + i2b2.hive.MasterView.setViewMode('Analysis'); + } + }, +/* + getPluginList: function() { + var results = {}; + var cellsLoaded = i2b2.hive.cfg.LoadedCells; + for (var i1=0; i1Select a plugin to load'); + doc.close(); + } else { + // clear DIV + var trgt = $('anaPluginViewFrame'); + while (trgt.childNodes.length > 0) { trgt.removeChild(trgt.firstChild); } + trgt.innerHTML = ''; + } + delete i2b2.PLUGINMGR.ctrlr.main.currentPluginCtrlr; + } else { + return false; + } + } + + // show the plugin name on the main container tab + try { + if (i2b2[pluginCode].cfg.config.short_name) { + sName = i2b2[pluginCode].cfg.config.short_name; + } else { + sName = i2b2[pluginCode].cfg.config.name; + } + $('anaPluginViewBox').select('DIV.tabBox DIV')[0].innerHTML = sName; + } catch(e) { + console.warn("Could not change PluginViewBox tab label!"); + } + // LOAD PLUGIN GUI + if (!i2b2.h.isBadObjPath('i2b2.'+pluginCode+'.cfg.config.plugin.iframe')) { + // the plugin requires loading into an IFRAME + } else if (!i2b2.h.isBadObjPath('i2b2.'+pluginCode+'.cfg.config.plugin.html')) { + // the plugin requires direct loading into the DOM tree + var url = i2b2[pluginCode].cfg.config.assetDir + i2b2[pluginCode].cfg.config.plugin.html.source; + var response = new Ajax.Request(url, {method: 'get', asynchronous: false}); + console.dir(response); + if (response.transport.statusText=="OK") { + // load the html into the IFRAME + var doc = $('anaPluginIFRAME').contentDocument; + if (!doc) {var doc = $('anaPluginIFRAME').contentWindow.document; } + doc.open(); + doc.write(response.transport.responseText); + doc.close(); + // get the main screen DIV + var mainDiv = doc.getElementById(i2b2[pluginCode].cfg.config.plugin.html.mainDivId); + if (!mainDiv) { + alert("The Plugin's screen was loaded but had errors."); + return false; + } + // clear plugin view window + var trgt = $('anaPluginViewFrame'); + while (trgt.childNodes.length > 0) { trgt.removeChild(trgt.firstChild); } + // copy the div to our working window and display it. + if (mainDiv.outerHTML) { + // fix for IE issues + trgt.innerHTML = mainDiv.outerHTML; + var scrn = trgt.firstChild; + scrn.style.display = ''; + } else { + var scrn = mainDiv.cloneNode(true); + trgt.appendChild(scrn); + scrn.show(); + } + // perform GUI changes if the plugin is going to be using standard tabs at the top + var useTabs = false; + if (!i2b2.h.isBadObjPath('i2b2.'+pluginCode+'.cfg.config.plugin.standardTabs')) { + useTabs = Boolean.parseTo(i2b2[pluginCode].cfg.config.plugin.standardTabs); + } + i2b2.PLUGINMGR.view.PlugView.UsesTabs(useTabs); + // show plugin + trgt.show(); + // notify the plugin's controller class to activate + try { + i2b2[pluginCode].Init(scrn); + i2b2.PLUGINMGR.ctrlr.main.currentPluginCtrlr = i2b2[pluginCode]; + i2b2.PLUGINMGR.ctrlr.main.currentPluginParentDiv = scrn; + } catch(e) { + alert('An error has occurred while trying to initialize the Plugin.'); + } + // fire the plugin's Resize() function + i2b2.PLUGINMGR.view.PlugView.ResizeHeight(); + // Reconnect any drag drop handlers that have been dropped, if this plugin has been previously loaded (a YUI issue) + YAHOO.util.DDM.reattachHandlers(); + + + } else { + alert('A problem was encounter while loading the plugin.'); + return false; + } + } else { + alert("The plugin you clicked does not specify how it needs to be loaded."); + return false; + } + } +}; + + + +console.timeEnd('execute time'); +console.groupEnd(); diff --git a/js-i2b2/cells/PLUGINMGR/assets/main_list.css b/js-i2b2/cells/PLUGINMGR/assets/main_list.css index ce6dc2ff..98534764 100755 --- a/js-i2b2/cells/PLUGINMGR/assets/main_list.css +++ b/js-i2b2/cells/PLUGINMGR/assets/main_list.css @@ -1,2 +1,2 @@ -@import url(vwList.css); -@import url(vwViewer.css); +@import url(vwList.css); +@import url(vwViewer.css); diff --git a/js-i2b2/cells/PLUGINMGR/assets/vwList.css b/js-i2b2/cells/PLUGINMGR/assets/vwList.css index a74e3e03..0a288473 100755 --- a/js-i2b2/cells/PLUGINMGR/assets/vwList.css +++ b/js-i2b2/cells/PLUGINMGR/assets/vwList.css @@ -1,156 +1,156 @@ -DIV#anaPluginListBox { - position: absolute; -} - -DIV#anaPluginListBox DIV.tabTextBox { - background: #BBCCEE none repeat scroll 0%; - border-color: #667788; - border-style: solid solid none; - border-width: 1px; - cursor: pointer; - float: left; - height: 20px; - margin-right: 5px; - padding: 5px 5px 0px; - width: 136px; - position:relative; - z-index:10; -} - -DIV.tabText { - background: #6677AA none repeat scroll 0%; - border: 1px solid #667788; - color: #FFFFFF; - font-family: arial,helvetica; - font-size: 12px; - font-weight: bold; - height: 18px; - line-height: 17px; - text-align: center; -} - -DIV#anaPluginListBox DIV.PluginListBox { - background: #BBCCEE none repeat scroll 0%; - border: 1px solid #667788; - clear: both; - display: block; - overflow: hidden; - padding: 5px; - position: relative; - top: -1px; - height: auto; - width: auto; - z-index: 0; -} - -DIV#anaPluginListBox DIV.PluginListBox DIV.topmenu { - padding: 2px; - background: #DBE8EF; - border: 1px solid #888; - height: 21px; - text-align: right; - overflow:hidden; -} - -DIV#anaPluginListBox DIV#anaPluginList { - background: #FFF; - border: 1px solid #667788; - height: 144px; - overflow-y: scroll; - overflow-x: hidden; -} - -DIV#anaPluginListBox A.pluginRecordBox { - border-top: 1px solid #FFFFFF; - border-left: 1px solid #FFFFFF; - border-right: 1px solid #FFFFFF; - border-bottom: 1px solid #667788; - padding: 1px 5px; - display: block; - cursor: pointer; - background: #DBE8EF; -} - -DIV#anaPluginListBox A.pluginRecordBox:hover { - background-color:#FFFFCC; - -} - -DIV#anaPluginListBox A.pluginRecordBox DIV.Icon { - float: left; - background: #ffffff; - border: solid 1px #678; -} - -DIV#anaPluginListBox A.pluginRecordBox DIV.Name { - font-family: arial,helvetica; - font-size: 12px; - font-weight: bold; - line-height: 12px; -} - - - - -DIV#anaPluginListBox A.pluginRecordBox.DETAIL DIV.txtBoundBox { - padding: 0 2px; - margin: 0px 36px 0px; -} - -DIV#anaPluginListBox A.pluginRecordBox.DETAIL DIV.Name { - line-height: 14px; -} - -DIV#anaPluginListBox A.pluginRecordBox.DETAIL DIV.Descript { - font-family: arial,helvetica; - font-size: 10px; - line-height: 10px; -} - -DIV#anaPluginListBox A.pluginRecordBox.DETAIL DIV.Icon { - height: 32px; - width: 32px; -} - - - - -DIV#anaPluginListBox A.pluginRecordBox.SUMMARY { - padding: 0px 5px; - height: 16px; - overflow: hidden; -} - -DIV#anaPluginListBox A.pluginRecordBox.SUMMARY DIV.txtBoundBox { - margin: 0px 26px 0px; -} - -DIV#anaPluginListBox A.pluginRecordBox.SUMMARY DIV.Name { - line-height: 15px; - font-weight: normal; -} - -DIV#anaPluginListBox A.pluginRecordBox.SUMMARY DIV.Descript { - font-family: arial,helvetica; - font-size: 10px; - line-height: 12px; -} - -DIV#anaPluginListBox A.pluginRecordBox.SUMMARY DIV.Icon { - height: 11px; - width: 11px; - overflow: hidden; - margin-top: 1px; -} - - - - - - - - - -DIV#anaPluginListBox DIV.PluginListBox SELECT { - border: 1px solid #ABADB3; +DIV#anaPluginListBox { + position: absolute; +} + +DIV#anaPluginListBox DIV.tabTextBox { + background: #BBCCEE none repeat scroll 0%; + border-color: #667788; + border-style: solid solid none; + border-width: 1px; + cursor: pointer; + float: left; + height: 20px; + margin-right: 5px; + padding: 5px 5px 0px; + width: 136px; + position:relative; + z-index:10; +} + +DIV.tabText { + background: #6677AA none repeat scroll 0%; + border: 1px solid #667788; + color: #FFFFFF; + font-family: arial,helvetica; + font-size: 12px; + font-weight: bold; + height: 18px; + line-height: 17px; + text-align: center; +} + +DIV#anaPluginListBox DIV.PluginListBox { + background: #BBCCEE none repeat scroll 0%; + border: 1px solid #667788; + clear: both; + display: block; + overflow: hidden; + padding: 5px; + position: relative; + top: -1px; + height: auto; + width: auto; + z-index: 0; +} + +DIV#anaPluginListBox DIV.PluginListBox DIV.topmenu { + padding: 2px; + background: #DBE8EF; + border: 1px solid #888; + height: 21px; + text-align: right; + overflow:hidden; +} + +DIV#anaPluginListBox DIV#anaPluginList { + background: #FFF; + border: 1px solid #667788; + height: 144px; + overflow-y: scroll; + overflow-x: hidden; +} + +DIV#anaPluginListBox A.pluginRecordBox { + border-top: 1px solid #FFFFFF; + border-left: 1px solid #FFFFFF; + border-right: 1px solid #FFFFFF; + border-bottom: 1px solid #667788; + padding: 1px 5px; + display: block; + cursor: pointer; + background: #DBE8EF; +} + +DIV#anaPluginListBox A.pluginRecordBox:hover { + background-color:#FFFFCC; + +} + +DIV#anaPluginListBox A.pluginRecordBox DIV.Icon { + float: left; + background: #ffffff; + border: solid 1px #678; +} + +DIV#anaPluginListBox A.pluginRecordBox DIV.Name { + font-family: arial,helvetica; + font-size: 12px; + font-weight: bold; + line-height: 12px; +} + + + + +DIV#anaPluginListBox A.pluginRecordBox.DETAIL DIV.txtBoundBox { + padding: 0 2px; + margin: 0px 36px 0px; +} + +DIV#anaPluginListBox A.pluginRecordBox.DETAIL DIV.Name { + line-height: 14px; +} + +DIV#anaPluginListBox A.pluginRecordBox.DETAIL DIV.Descript { + font-family: arial,helvetica; + font-size: 10px; + line-height: 10px; +} + +DIV#anaPluginListBox A.pluginRecordBox.DETAIL DIV.Icon { + height: 32px; + width: 32px; +} + + + + +DIV#anaPluginListBox A.pluginRecordBox.SUMMARY { + padding: 0px 5px; + height: 16px; + overflow: hidden; +} + +DIV#anaPluginListBox A.pluginRecordBox.SUMMARY DIV.txtBoundBox { + margin: 0px 26px 0px; +} + +DIV#anaPluginListBox A.pluginRecordBox.SUMMARY DIV.Name { + line-height: 15px; + font-weight: normal; +} + +DIV#anaPluginListBox A.pluginRecordBox.SUMMARY DIV.Descript { + font-family: arial,helvetica; + font-size: 10px; + line-height: 12px; +} + +DIV#anaPluginListBox A.pluginRecordBox.SUMMARY DIV.Icon { + height: 11px; + width: 11px; + overflow: hidden; + margin-top: 1px; +} + + + + + + + + + +DIV#anaPluginListBox DIV.PluginListBox SELECT { + border: 1px solid #ABADB3; } \ No newline at end of file diff --git a/js-i2b2/cells/PLUGINMGR/cell_config_data.js b/js-i2b2/cells/PLUGINMGR/cell_config_data.js index 58de1e2f..9f1636c5 100755 --- a/js-i2b2/cells/PLUGINMGR/cell_config_data.js +++ b/js-i2b2/cells/PLUGINMGR/cell_config_data.js @@ -1,24 +1,24 @@ -// this file contains a list of all files that need to be loaded dynamically for this i2b2 Cell -// every file in this list will be loaded after the cell's Init function is called -{ - files: [ - "PLUGINMGR_ctrlr_general.js", - "PLUGINMGR_view_list.js", - "PLUGINMGR_view_PlugView.js" - ], - css: [ "main_list.css" ], // ONLY USE 1 STYLE SHEET: http://support.microsoft.com/kb/262161 - config: { - // additional configuration variables that are set by the system - i2b2Only: true, - name: "Plugin Viewer", - description: "This client-side cell is used to load and view other cells", - icons: { - size32x32: "PLUGIN_icon_32x32.gif" - }, - defaultListIcons: { - size16x16: "DEFAULTLIST_icon_14x14.gif", - size32x32: "DEFAULTLIST_icon_32x32.gif" - }, - category: ["core","celless"] - } +// this file contains a list of all files that need to be loaded dynamically for this i2b2 Cell +// every file in this list will be loaded after the cell's Init function is called +{ + files: [ + "PLUGINMGR_ctrlr_general.js", + "PLUGINMGR_view_list.js", + "PLUGINMGR_view_PlugView.js" + ], + css: [ "main_list.css" ], // ONLY USE 1 STYLE SHEET: http://support.microsoft.com/kb/262161 + config: { + // additional configuration variables that are set by the system + i2b2Only: true, + name: "Plugin Viewer", + description: "This client-side cell is used to load and view other cells", + icons: { + size32x32: "PLUGIN_icon_32x32.gif" + }, + defaultListIcons: { + size16x16: "DEFAULTLIST_icon_14x14.gif", + size32x32: "DEFAULTLIST_icon_32x32.gif" + }, + category: ["core","celless"] + } } \ No newline at end of file diff --git a/js-i2b2/cells/PM/assets/modProjects.css b/js-i2b2/cells/PM/assets/modProjects.css index 1863bc02..37b4886b 100755 --- a/js-i2b2/cells/PM/assets/modProjects.css +++ b/js-i2b2/cells/PM/assets/modProjects.css @@ -1,189 +1,189 @@ - -DIV.opAdd { -float:left; -overflow:hidden; -padding:6px 10px 0 0; -position:relative; -} - -DIV#i2b2_projects_modal_dialog DIV#projectAttribs { - margin-top: 8px; - border:#AAA solid; - border-width: 1px 1px 2px; - background-color:#DDDDFF; - margin-top:8px; -} - - -DIV#i2b2_projects_modal_dialog DIV.name { - background:#DDDDFF; - border-top: 1px solid #BBB; - float:left; - padding-left:4px; - width:119px; -} - -DIV#pmNavTreeview { - background: #FFFFFF; - border: 1px solid #667788; - width:auto; - padding:1px 5px; - overflow: auto; -} - -DIV#pmNav { - position: absolute; -} - -DIV#pmNav .bodyBox { - background:#BBCCEE none repeat scroll 0% 50%; - border:1px solid #667788; - clear:both; - display:block; - height:auto; - overflow:hidden; - padding:5px; - position:relative; - top:-1px; - width:auto; - z-index:0; -} - - -DIV#pmMain { - position: absolute; -} - -DIV#pmMain .bodyBox { - background:#BBCCEE none repeat scroll 0% 50%; - border:1px solid #667788; - clear:both; - display:block; - height:auto; - overflow:hidden; - padding:5px; - position:relative; - top:-1px; - width:auto; - z-index:0; -} -DIV#pmMain .bodyBox #pmMainTableview { - overflow:auto; - width: 100%; -} -DIV#pmMain .bodyBox #pmMainTableview table{ - width: 100%; -} - -DIV#pmParam { - position: absolute; -} - -DIV#pmParam .bodyBox { - background:#BBCCEE none repeat scroll 0% 50%; - border:1px solid #667788; - clear:both; - display:block; - height:auto; - overflow:hidden; - padding:5px; - position:relative; - top:-1px; - width:auto; - z-index:0; -} - -DIV#i2b2_projects_modal_dialog DIV.value { - border-left: 1px solid #BBB; - border-top: 1px solid #BBB; - float: right; - padding-left: 5px; - width: 248px; - background: #F2F2F2; -} - - -DIV#i2b2_projects_modal_dialog SELECT#loginProjs { - width: 200px; -} - - -DIV#i2b2_projects_modal_dialog DIV.NoDetails { - text-align:center; - font-style: italic; - font-size: 12px; - border-top:1px solid #BBB; - padding:4px 0px; -} - - -/* login dialog box */ - -/* DIV#i2b2_login_modal_dialog { border: 1px solid #000; } */ - -DIV#i2b2_login_modal_dialog .login-dialog { - background-image: url(login_bg.jpg); - width: 501px; - height: 178px; -} - -DIV#i2b2_login_modal_dialog DIV.formDiv { padding-top: 6px; } - -DIV#i2b2_login_modal_dialog DIV.label { font-weight: bold; } - -DIV#i2b2_login_modal_dialog DIV.input { - margin-bottom: 8px; -} - -DIV#i2b2_login_modal_dialog INPUT, -DIV#i2b2_login_modal_dialog SELECT { - width: 180px; -} - -DIV#i2b2_login_modal_dialog DIV.button INPUT { - width: 90px; - margin-top: 6px; -} - - -/*** CSS for Project Request ***/ - - -DIV#project-request-viewer-body DIV.ProjectRequest-MainContent { - background:#FFF; - border:solid #63758C; - border-width:1px 0; - overflow:auto; - height:100%; -} - - -DIV.ProjectRequest-MainContent DIV.droptrgtlbl { - padding: 6px 0px; - width:180px; - text-align:right; - float: left; - font-weight:bold; - color:#666; - margin: 15px 10px 0px 0px; -} -DIV.ProjectRequest-MainContent DIV.droptrgt { - padding: 5px 10px; - background: #DEEBEF; - margin-top: 15px; - text-align:left; - border: 1px solid #63758C; - overflow:hidden; - float:left; - white-space:nowrap; -} - - -DIV.ProjectRequest-MainContent DIV.outputOptions { - padding: 5px 10px; - margin-top: 15px; - text-align:center; - float:left; - border: 1px solid #63758C; - overflow:hidden; -} + +DIV.opAdd { +float:left; +overflow:hidden; +padding:6px 10px 0 0; +position:relative; +} + +DIV#i2b2_projects_modal_dialog DIV#projectAttribs { + margin-top: 8px; + border:#AAA solid; + border-width: 1px 1px 2px; + background-color:#DDDDFF; + margin-top:8px; +} + + +DIV#i2b2_projects_modal_dialog DIV.name { + background:#DDDDFF; + border-top: 1px solid #BBB; + float:left; + padding-left:4px; + width:119px; +} + +DIV#pmNavTreeview { + background: #FFFFFF; + border: 1px solid #667788; + width:auto; + padding:1px 5px; + overflow: auto; +} + +DIV#pmNav { + position: absolute; +} + +DIV#pmNav .bodyBox { + background:#BBCCEE none repeat scroll 0% 50%; + border:1px solid #667788; + clear:both; + display:block; + height:auto; + overflow:hidden; + padding:5px; + position:relative; + top:-1px; + width:auto; + z-index:0; +} + + +DIV#pmMain { + position: absolute; +} + +DIV#pmMain .bodyBox { + background:#BBCCEE none repeat scroll 0% 50%; + border:1px solid #667788; + clear:both; + display:block; + height:auto; + overflow:hidden; + padding:5px; + position:relative; + top:-1px; + width:auto; + z-index:0; +} +DIV#pmMain .bodyBox #pmMainTableview { + overflow:auto; + width: 100%; +} +DIV#pmMain .bodyBox #pmMainTableview table{ + width: 100%; +} + +DIV#pmParam { + position: absolute; +} + +DIV#pmParam .bodyBox { + background:#BBCCEE none repeat scroll 0% 50%; + border:1px solid #667788; + clear:both; + display:block; + height:auto; + overflow:hidden; + padding:5px; + position:relative; + top:-1px; + width:auto; + z-index:0; +} + +DIV#i2b2_projects_modal_dialog DIV.value { + border-left: 1px solid #BBB; + border-top: 1px solid #BBB; + float: right; + padding-left: 5px; + width: 248px; + background: #F2F2F2; +} + + +DIV#i2b2_projects_modal_dialog SELECT#loginProjs { + width: 200px; +} + + +DIV#i2b2_projects_modal_dialog DIV.NoDetails { + text-align:center; + font-style: italic; + font-size: 12px; + border-top:1px solid #BBB; + padding:4px 0px; +} + + +/* login dialog box */ + +/* DIV#i2b2_login_modal_dialog { border: 1px solid #000; } */ + +DIV#i2b2_login_modal_dialog .login-dialog { + background-image: url(login_bg.jpg); + width: 501px; + height: 178px; +} + +DIV#i2b2_login_modal_dialog DIV.formDiv { padding-top: 6px; } + +DIV#i2b2_login_modal_dialog DIV.label { font-weight: bold; } + +DIV#i2b2_login_modal_dialog DIV.input { + margin-bottom: 8px; +} + +DIV#i2b2_login_modal_dialog INPUT, +DIV#i2b2_login_modal_dialog SELECT { + width: 180px; +} + +DIV#i2b2_login_modal_dialog DIV.button INPUT { + width: 90px; + margin-top: 6px; +} + + +/*** CSS for Project Request ***/ + + +DIV#project-request-viewer-body DIV.ProjectRequest-MainContent { + background:#FFF; + border:solid #63758C; + border-width:1px 0; + overflow:auto; + height:100%; +} + + +DIV.ProjectRequest-MainContent DIV.droptrgtlbl { + padding: 6px 0px; + width:180px; + text-align:right; + float: left; + font-weight:bold; + color:#666; + margin: 15px 10px 0px 0px; +} +DIV.ProjectRequest-MainContent DIV.droptrgt { + padding: 5px 10px; + background: #DEEBEF; + margin-top: 15px; + text-align:left; + border: 1px solid #63758C; + overflow:hidden; + float:left; + white-space:nowrap; +} + + +DIV.ProjectRequest-MainContent DIV.outputOptions { + padding: 5px 10px; + margin-top: 15px; + text-align:center; + float:left; + border: 1px solid #63758C; + overflow:hidden; +} diff --git a/js-i2b2/cells/WORK/assets/main_list.css b/js-i2b2/cells/WORK/assets/main_list.css index 2a5120c4..ecc9b7d4 100755 --- a/js-i2b2/cells/WORK/assets/main_list.css +++ b/js-i2b2/cells/WORK/assets/main_list.css @@ -1,2 +1,2 @@ -@import url(vwWork.css); -@import url(sdx_WORK_XML.css); +@import url(vwWork.css); +@import url(sdx_WORK_XML.css); diff --git a/js-i2b2/cells/WORK/assets/sdx_WORK_XML.css b/js-i2b2/cells/WORK/assets/sdx_WORK_XML.css index e013e355..6c6a125f 100755 --- a/js-i2b2/cells/WORK/assets/sdx_WORK_XML.css +++ b/js-i2b2/cells/WORK/assets/sdx_WORK_XML.css @@ -1,26 +1,26 @@ -.sdxDefaultXML { - font-family:arial,helvetica; - font-size:12px; - white-space:nowrap; - vertical-align:bottom; - cursor:pointer; - line-height:16px; -} -.sdxDefaultXML img { - height:16px; - width:16px; - border:none; - padding-right:3px; - vertical-align:bottom; -} -.sdxDefaultXML a { - color:#000000; - text-decoration:none; -} -.sdxDefaultXML a:hover { - text-decoration:underline; -} - -.ddXMLTarget { - background:#FFFFBB !important; -} +.sdxDefaultXML { + font-family:arial,helvetica; + font-size:12px; + white-space:nowrap; + vertical-align:bottom; + cursor:pointer; + line-height:16px; +} +.sdxDefaultXML img { + height:16px; + width:16px; + border:none; + padding-right:3px; + vertical-align:bottom; +} +.sdxDefaultXML a { + color:#000000; + text-decoration:none; +} +.sdxDefaultXML a:hover { + text-decoration:underline; +} + +.ddXMLTarget { + background:#FFFFBB !important; +} diff --git a/js-i2b2/cells/WORK/assets/vwWork.css b/js-i2b2/cells/WORK/assets/vwWork.css index 029df142..75173b73 100755 --- a/js-i2b2/cells/WORK/assets/vwWork.css +++ b/js-i2b2/cells/WORK/assets/vwWork.css @@ -1,30 +1,30 @@ - -DIV#wrkTreeview { - background: #FFFFFF; - border: 1px solid #667788; - width:auto; - padding:1px 5px; - overflow: auto; -} - -DIV#wrkWorkplace { - position: absolute; -} - -DIV#wrkWorkplace .bodyBox { - background:#BBCCEE none repeat scroll 0% 50%; - border:1px solid #667788; - clear:both; - display:block; - height:auto; - overflow:hidden; - padding:5px; - position:relative; - top:-1px; - width:auto; - z-index:0; -} - -.ddDropToWorkplace { - background:#FFFF55 !important; -} + +DIV#wrkTreeview { + background: #FFFFFF; + border: 1px solid #667788; + width:auto; + padding:1px 5px; + overflow: auto; +} + +DIV#wrkWorkplace { + position: absolute; +} + +DIV#wrkWorkplace .bodyBox { + background:#BBCCEE none repeat scroll 0% 50%; + border:1px solid #667788; + clear:both; + display:block; + height:auto; + overflow:hidden; + padding:5px; + position:relative; + top:-1px; + width:auto; + z-index:0; +} + +.ddDropToWorkplace { + background:#FFFF55 !important; +} diff --git a/js-i2b2/cells/WORK/cell_config_data.js b/js-i2b2/cells/WORK/cell_config_data.js index 81a89d67..9cba467c 100755 --- a/js-i2b2/cells/WORK/cell_config_data.js +++ b/js-i2b2/cells/WORK/cell_config_data.js @@ -1,20 +1,20 @@ -// this file contains a list of all files that need to be loaded dynamically for this i2b2 Cell -// every file in this list will be loaded after the cell's Init function is called -{ - files: [ - "WORK_ctrlr_general.js", - "WORK_view.js", - "WORK_sdx_WRK.js", - "WORK_sdx_XML.js", - "i2b2_msgs.js" - ], - css: ["main_list.css"], // ONLY USE 1 STYLE SHEET: http://support.microsoft.com/kb/262161 - config: { - // additional configuration variables that are set by the system - name: "Workplace Cell", - icons: { - size32x32: "WORK_icon_32x32.gif" - }, - category: ["core","cell"] - } +// this file contains a list of all files that need to be loaded dynamically for this i2b2 Cell +// every file in this list will be loaded after the cell's Init function is called +{ + files: [ + "WORK_ctrlr_general.js", + "WORK_view.js", + "WORK_sdx_WRK.js", + "WORK_sdx_XML.js", + "i2b2_msgs.js" + ], + css: ["main_list.css"], // ONLY USE 1 STYLE SHEET: http://support.microsoft.com/kb/262161 + config: { + // additional configuration variables that are set by the system + name: "Workplace Cell", + icons: { + size32x32: "WORK_icon_32x32.gif" + }, + category: ["core","cell"] + } } \ No newline at end of file diff --git a/js-i2b2/cells/plugins/standard/Dem1Set/cell_config_data.js b/js-i2b2/cells/plugins/standard/Dem1Set/cell_config_data.js index ed912e80..25517277 100755 --- a/js-i2b2/cells/plugins/standard/Dem1Set/cell_config_data.js +++ b/js-i2b2/cells/plugins/standard/Dem1Set/cell_config_data.js @@ -1,26 +1,26 @@ -// this file contains a list of all files that need to be loaded dynamically for this i2b2 Cell -// every file in this list will be loaded after the cell's Init function is called -{ - files:[ - "Dem1Set_ctrlr.js" - ], - css:[ - "vwDem1Set.css" - ], - config: { - // additional configuration variables that are set by the system - short_name: "Demographics", - name: "Demographics (1 Patient Set) - Simple Counts", - description: "This plugin displays a demographic break-down of a Patient Set.", - category: ["celless","plugin","standard","demographics"], - plugin: { - isolateHtml: false, // this means do not use an IFRAME - isolateComm: false, // this means to expect the plugin to use AJAX communications provided by the framework - standardTabs: true, // this means the plugin uses standard tabs at top - html: { - source: 'injected_screens.html', - mainDivId: 'Dem1Set-mainDiv' - } - } - } +// this file contains a list of all files that need to be loaded dynamically for this i2b2 Cell +// every file in this list will be loaded after the cell's Init function is called +{ + files:[ + "Dem1Set_ctrlr.js" + ], + css:[ + "vwDem1Set.css" + ], + config: { + // additional configuration variables that are set by the system + short_name: "Demographics", + name: "Demographics (1 Patient Set) - Simple Counts", + description: "This plugin displays a demographic break-down of a Patient Set.", + category: ["celless","plugin","standard","demographics"], + plugin: { + isolateHtml: false, // this means do not use an IFRAME + isolateComm: false, // this means to expect the plugin to use AJAX communications provided by the framework + standardTabs: true, // this means the plugin uses standard tabs at top + html: { + source: 'injected_screens.html', + mainDivId: 'Dem1Set-mainDiv' + } + } + } } \ No newline at end of file diff --git a/js-i2b2/cells/plugins/standard/Dem2Set/cell_config_data.js b/js-i2b2/cells/plugins/standard/Dem2Set/cell_config_data.js index 30aca17d..3448df93 100755 --- a/js-i2b2/cells/plugins/standard/Dem2Set/cell_config_data.js +++ b/js-i2b2/cells/plugins/standard/Dem2Set/cell_config_data.js @@ -1,26 +1,26 @@ -// this file contains a list of all files that need to be loaded dynamically for this i2b2 Cell -// every file in this list will be loaded after the cell's Init function is called -{ - files:[ - "Dem2Set_ctrlr.js" - ], - css:[ - "vwDem2Set.css" - ], - config: { - // additional configuration variables that are set by the system - short_name: "Demographics", - name: "Demographics (2 Patient Sets) - Simple Counts", - description: "This plugin compares the demographic break-down of two Patient Sets.", - category: ["celless","plugin","standard","demographics"], - plugin: { - isolateHtml: false, // this means do not use an IFRAME - isolateComm: false, // this means to expect the plugin to use AJAX communications provided by the framework - standardTabs: true, // this means the plugin uses standard tabs at top - html: { - source: 'injected_screens.html', - mainDivId: 'Dem2Set-mainDiv' - } - } - } +// this file contains a list of all files that need to be loaded dynamically for this i2b2 Cell +// every file in this list will be loaded after the cell's Init function is called +{ + files:[ + "Dem2Set_ctrlr.js" + ], + css:[ + "vwDem2Set.css" + ], + config: { + // additional configuration variables that are set by the system + short_name: "Demographics", + name: "Demographics (2 Patient Sets) - Simple Counts", + description: "This plugin compares the demographic break-down of two Patient Sets.", + category: ["celless","plugin","standard","demographics"], + plugin: { + isolateHtml: false, // this means do not use an IFRAME + isolateComm: false, // this means to expect the plugin to use AJAX communications provided by the framework + standardTabs: true, // this means the plugin uses standard tabs at top + html: { + source: 'injected_screens.html', + mainDivId: 'Dem2Set-mainDiv' + } + } + } } \ No newline at end of file diff --git a/js-i2b2/hive/hive.ui.js b/js-i2b2/hive/hive.ui.js index 066536f5..f3de6602 100755 --- a/js-i2b2/hive/hive.ui.js +++ b/js-i2b2/hive/hive.ui.js @@ -1,171 +1,171 @@ - -/* - * Make the Splitter object - */ - -Splitter = function( name, config ) -{ - /* type is type of the event ("ONTResized" in this case), args is an array of all of the arguments that were passed to the event's fire method, - * and me is the custom object we passed in when we subscribed to the event. - */ - /* - * This method is called when CRC is initialized and when browser window is resized - */ - this.onResize = function( type, args, me ) - { - var ve = $('ontMainBox'); - if (ve.style.width === "") - { - return; - } - - var splitter = $( name ); - - if ( this.leftProportion == null ) - { - splitter.style.left = addToProperty( ve.style.width, 18, "px", "px" ); - this.leftProportion = (parseInt(splitter.style.left))/(YAHOO.util.Dom.getViewportWidth()-15); - } - else - { - splitter.style.left = this.leftProportion * (YAHOO.util.Dom.getViewportWidth()-15) + "px"; - } - splitter.style.top = this.topOffset + "px"; - splitter.style.height = (YAHOO.util.Dom.getViewportHeight()-this.topOffset) + "px"; - } - - this.onCRCinit = function( type, args, me ) - { - this.onResize( type, args, me); - this.initConstraints(); - } - - // fires when splitter is dragged - this.resizeOtherComponents = function() - { - i2b2.ONT.view.main.splitterDragged(); // resize ONT - i2b2.WORK.view.main.splitterDragged(); // resize WORK - i2b2.CRC.view.history.splitterDragged(); // resize Query History - i2b2.CRC.view.QT.splitterDragged(); // resize Query Tool - i2b2.CRC.view.status.splitterDragged(); // resize Query Status - i2b2.PLUGINMGR.view.PlugView.splitterDragged(); // resize Plugin View - i2b2.PLUGINMGR.view.list.splitterDragged(); // resize Plugin View - } - - // fires when window is resized - this.resizeComopnentHeight = function() - { - i2b2.ONT.view.main.ResizeHeight(); // resize ONT - i2b2.ONT.view.find.ResizeHeight(); // resize ONT.find - i2b2.ONT.view.nav.ResizeHeight(); // resize ONT.nav - i2b2.WORK.view.main.ResizeHeight(); // resize WORK - i2b2.CRC.view.history.ResizeHeight(); // resize Query History - i2b2.CRC.view.QT.ResizeHeight(); // resize Query Panels - i2b2.CRC.view.status.ResizeHeight(); // resize Query Status - i2b2.PLUGINMGR.view.PlugView.ResizeHeight(); // resize Plugin View - i2b2.PLUGINMGR.view.list.ResizeHeight(); // resize Plugin List - } - - /* resize all components when splitter is dragged */ - this.dragged = function() - { - var splitter = $( name ); - this.leftProportion = parseInt(splitter.style.left)/(YAHOO.util.Dom.getViewportWidth()-15); // remember the new leftProportion - this.resizeOtherComponents(); - } - - /* - * Initializing instance variables and calling super's constructor - */ - this.name = name; - this.topOffset = 33; - this.cont = config.cont; - this.leftProportion = null; - Splitter.superclass.constructor.apply(this, arguments); - - this.events.ONTInitialized = new YAHOO.util.CustomEvent("ONTInitialized", this); // create event for ONTInitialization - this.events.ONTInitialized.subscribe( this.onCRCinit, this); // listen to the event and attach handlers -} -// extension must immediately follow constructor (this makes the Splitter Drag-and-Drop-able.) -YAHOO.extend(Splitter, YAHOO.util.DD, -{ - cont: null, - init: function() - { - // Call parent's init method - Splitter.superclass.init.apply(this, arguments); - var splitter = $( this.name ); - if (YAHOO.env.ua.ie > 0) // ie does not supoprt ew-resize (see http://msdn.microsoft.com/en-us/library/ie/aa358795%28v=vs.85%29.aspx) - splitter.style.cursor = "e-resize"; - else - splitter.style.cursor = "ew-resize"; - - YAHOO.util.Event.on( window, 'resize', function() - { - this.initConstraints(); - this.onResize(); - this.resizeOtherComponents(); - this.resizeComopnentHeight(); - }, - this, - true ); - }, - - initConstraints: function() - { - var dom = YAHOO.util.Dom; - var region = dom.getRegion( this.cont ); - var el = this.getEl(); - var xy = dom.getXY(el); - var width = parseInt( dom.getStyle(el, 'width'), 10 ); - var left = xy[0] - region.left; - var right = region.right - xy[0] - width; - - this.setXConstraint( left, right); - this.setYConstraint( 0, 0 ); // no vertical travel - }, - - onDrag: function(e) - { - this.dragged(); - } -}); - - - -/* - * Property adjustment/setting utilities - */ -var stripUnit = function(numberAndUnitString, unitString) -{ return numberAndUnitString.substring(0, numberAndUnitString.indexOf(unitString)); } - -var appendUnit = function(number, unit) -{ return number+unit; } - -var setProperty = function( oldPropertyValue, newPropertyValue, oldUnit, newUnit ) -{ return appendUnit(stripUnit(oldPropertyValue, oldUnit), newUnit); } - -// propertyDiff is a Number, other parameters are Strings -var addToProperty = function( oldPropertyValue, propertyDiff, oldUnit, newUnit ) -{ return appendUnit( parseInt(stripUnit(oldPropertyValue, oldUnit)) + propertyDiff, newUnit); } - - -/* - * Debugging utilities - */ -var debugOnScreen = function( text ) -{ - $('main.debug').appendChild( document.createTextNode( text ) ); - $('main.debug').appendChild( document.createElement("br") ); -} - -var debugOnScreenWithDate = function( text ) -{ - var date = new Date(); - debugOnScreen( text + " " + date ); -} - -var debugOnScreenClear = function() -{ - $('main.debug').innerHTML = ""; -} + +/* + * Make the Splitter object + */ + +Splitter = function( name, config ) +{ + /* type is type of the event ("ONTResized" in this case), args is an array of all of the arguments that were passed to the event's fire method, + * and me is the custom object we passed in when we subscribed to the event. + */ + /* + * This method is called when CRC is initialized and when browser window is resized + */ + this.onResize = function( type, args, me ) + { + var ve = $('ontMainBox'); + if (ve.style.width === "") + { + return; + } + + var splitter = $( name ); + + if ( this.leftProportion == null ) + { + splitter.style.left = addToProperty( ve.style.width, 18, "px", "px" ); + this.leftProportion = (parseInt(splitter.style.left))/(YAHOO.util.Dom.getViewportWidth()-15); + } + else + { + splitter.style.left = this.leftProportion * (YAHOO.util.Dom.getViewportWidth()-15) + "px"; + } + splitter.style.top = this.topOffset + "px"; + splitter.style.height = (YAHOO.util.Dom.getViewportHeight()-this.topOffset) + "px"; + } + + this.onCRCinit = function( type, args, me ) + { + this.onResize( type, args, me); + this.initConstraints(); + } + + // fires when splitter is dragged + this.resizeOtherComponents = function() + { + i2b2.ONT.view.main.splitterDragged(); // resize ONT + i2b2.WORK.view.main.splitterDragged(); // resize WORK + i2b2.CRC.view.history.splitterDragged(); // resize Query History + i2b2.CRC.view.QT.splitterDragged(); // resize Query Tool + i2b2.CRC.view.status.splitterDragged(); // resize Query Status + i2b2.PLUGINMGR.view.PlugView.splitterDragged(); // resize Plugin View + i2b2.PLUGINMGR.view.list.splitterDragged(); // resize Plugin View + } + + // fires when window is resized + this.resizeComopnentHeight = function() + { + i2b2.ONT.view.main.ResizeHeight(); // resize ONT + i2b2.ONT.view.find.ResizeHeight(); // resize ONT.find + i2b2.ONT.view.nav.ResizeHeight(); // resize ONT.nav + i2b2.WORK.view.main.ResizeHeight(); // resize WORK + i2b2.CRC.view.history.ResizeHeight(); // resize Query History + i2b2.CRC.view.QT.ResizeHeight(); // resize Query Panels + i2b2.CRC.view.status.ResizeHeight(); // resize Query Status + i2b2.PLUGINMGR.view.PlugView.ResizeHeight(); // resize Plugin View + i2b2.PLUGINMGR.view.list.ResizeHeight(); // resize Plugin List + } + + /* resize all components when splitter is dragged */ + this.dragged = function() + { + var splitter = $( name ); + this.leftProportion = parseInt(splitter.style.left)/(YAHOO.util.Dom.getViewportWidth()-15); // remember the new leftProportion + this.resizeOtherComponents(); + } + + /* + * Initializing instance variables and calling super's constructor + */ + this.name = name; + this.topOffset = 33; + this.cont = config.cont; + this.leftProportion = null; + Splitter.superclass.constructor.apply(this, arguments); + + this.events.ONTInitialized = new YAHOO.util.CustomEvent("ONTInitialized", this); // create event for ONTInitialization + this.events.ONTInitialized.subscribe( this.onCRCinit, this); // listen to the event and attach handlers +} +// extension must immediately follow constructor (this makes the Splitter Drag-and-Drop-able.) +YAHOO.extend(Splitter, YAHOO.util.DD, +{ + cont: null, + init: function() + { + // Call parent's init method + Splitter.superclass.init.apply(this, arguments); + var splitter = $( this.name ); + if (YAHOO.env.ua.ie > 0) // ie does not supoprt ew-resize (see http://msdn.microsoft.com/en-us/library/ie/aa358795%28v=vs.85%29.aspx) + splitter.style.cursor = "e-resize"; + else + splitter.style.cursor = "ew-resize"; + + YAHOO.util.Event.on( window, 'resize', function() + { + this.initConstraints(); + this.onResize(); + this.resizeOtherComponents(); + this.resizeComopnentHeight(); + }, + this, + true ); + }, + + initConstraints: function() + { + var dom = YAHOO.util.Dom; + var region = dom.getRegion( this.cont ); + var el = this.getEl(); + var xy = dom.getXY(el); + var width = parseInt( dom.getStyle(el, 'width'), 10 ); + var left = xy[0] - region.left; + var right = region.right - xy[0] - width; + + this.setXConstraint( left, right); + this.setYConstraint( 0, 0 ); // no vertical travel + }, + + onDrag: function(e) + { + this.dragged(); + } +}); + + + +/* + * Property adjustment/setting utilities + */ +var stripUnit = function(numberAndUnitString, unitString) +{ return numberAndUnitString.substring(0, numberAndUnitString.indexOf(unitString)); } + +var appendUnit = function(number, unit) +{ return number+unit; } + +var setProperty = function( oldPropertyValue, newPropertyValue, oldUnit, newUnit ) +{ return appendUnit(stripUnit(oldPropertyValue, oldUnit), newUnit); } + +// propertyDiff is a Number, other parameters are Strings +var addToProperty = function( oldPropertyValue, propertyDiff, oldUnit, newUnit ) +{ return appendUnit( parseInt(stripUnit(oldPropertyValue, oldUnit)) + propertyDiff, newUnit); } + + +/* + * Debugging utilities + */ +var debugOnScreen = function( text ) +{ + $('main.debug').appendChild( document.createTextNode( text ) ); + $('main.debug').appendChild( document.createElement("br") ); +} + +var debugOnScreenWithDate = function( text ) +{ + var date = new Date(); + debugOnScreen( text + " " + date ); +} + +var debugOnScreenClear = function() +{ + $('main.debug').innerHTML = ""; +} diff --git a/js-i2b2/hive/hive_config_data.js b/js-i2b2/hive/hive_config_data.js index 2e595667..eead2508 100755 --- a/js-i2b2/hive/hive_config_data.js +++ b/js-i2b2/hive/hive_config_data.js @@ -1,17 +1,17 @@ -// this file contains a list of all files that need to be loaded dynamically for the i2b2 framework -// every file in this list will be loaded after page load -{ - files: [ - "hive_globals.js", - "hive_helpers.js", - "hive_SDX.js", - "msg_sniffer.js", - "help_viewer.js", - "master_view_ctrlr.js", - "i2b2_cell_communicator.js" - ], - config: { - // additional configuration variables that are set by the system - validMasterViews: ['Patients', 'Analysis'] - } +// this file contains a list of all files that need to be loaded dynamically for the i2b2 framework +// every file in this list will be loaded after page load +{ + files: [ + "hive_globals.js", + "hive_helpers.js", + "hive_SDX.js", + "msg_sniffer.js", + "help_viewer.js", + "master_view_ctrlr.js", + "i2b2_cell_communicator.js" + ], + config: { + // additional configuration variables that are set by the system + validMasterViews: ['Patients', 'Analysis'] + } } \ No newline at end of file diff --git a/js-i2b2/hive/master_view_ctrlr.js b/js-i2b2/hive/master_view_ctrlr.js index ffd620c0..288e710a 100755 --- a/js-i2b2/hive/master_view_ctrlr.js +++ b/js-i2b2/hive/master_view_ctrlr.js @@ -1,144 +1,144 @@ -/** - * @projectDescription Module used to manage GUI view modes and window "zooming". - * @author Nick Benik, Griffin Weber MD PhD - * @version 1.3 - * updated 10-29-08: RC4 launch [Nick Benik] - */ -console.group('Load & Execute component file: hive > master view controller'); -console.time('execute time'); - - -// Master View Mode controller -// ================================================================================================== // -i2b2.hive.MasterView = { - _validViews: ['Patients', 'Admin', 'Analysis', 'AnalysisZoomed'], - _currentView: false, - _ZoomWindows: [], - eventChangeMode: {}, - eventZoomWindows: {}, - // ================================================================================================== // - initViewMode: function() - { - var newMode = 'Patients'; - var tn = $("viewMode-"+newMode); - if (tn) - { - // remove highlighting from old screen mode links - var old = $$('.selectedView'); - old.each(function(el) - { - el.removeClassName('selectedView'); - }); - // highlight the new screen mode's label - tn.addClassName('selectedView'); - } - - // update data - this._currentView = newMode; - this.eventInitView.fire( newMode ); - return true; - }, - -// ================================================================================================== // - setViewMode: function(requestedMode) { - if (this._currentView == requestedMode) { return true; } - var newMode = false; - for (var i=0; i master view controller'); +console.time('execute time'); + + +// Master View Mode controller +// ================================================================================================== // +i2b2.hive.MasterView = { + _validViews: ['Patients', 'Admin', 'Analysis', 'AnalysisZoomed'], + _currentView: false, + _ZoomWindows: [], + eventChangeMode: {}, + eventZoomWindows: {}, + // ================================================================================================== // + initViewMode: function() + { + var newMode = 'Patients'; + var tn = $("viewMode-"+newMode); + if (tn) + { + // remove highlighting from old screen mode links + var old = $$('.selectedView'); + old.each(function(el) + { + el.removeClassName('selectedView'); + }); + // highlight the new screen mode's label + tn.addClassName('selectedView'); + } + + // update data + this._currentView = newMode; + this.eventInitView.fire( newMode ); + return true; + }, + +// ================================================================================================== // + setViewMode: function(requestedMode) { + if (this._currentView == requestedMode) { return true; } + var newMode = false; + for (var i=0; i'; - } catch (e) { console.error("Could not display information!"); } - i2b2.hive.MsgSniffer.yuiModalMsg.show(); - - }, - showSingleMsgResponse: function(strXML) { - this._showSingleMsgModal(); - try { - var t = $("commViewerSingleMsg-panel").select(".hd")[0]; - t.innerHTML = "Last Response Message"; - var t = $("commViewerSingleMsg-body").select(".xmlMsg")[0]; -// t.style.background = "#FFAFAF"; - t.innerHTML = '
        '+strXML+'
        '; - } catch (e) { console.error("Could not display information!"); } - i2b2.hive.MsgSniffer.yuiModalMsg.show(); - }, - show: function() { - this.asyncStackFilter = false; - this._spawnWin.call(this); - }, - _spawnWin: function() { - try { - // spawn new - i2b2.hive.MsgSniffer.windowRef = window.open('assets/msg-viewer.html', 'i2b2_msgsniffer', 'toolbar=no,resizable=yes,scrollbars=yes,height=480,width=740', false); - i2b2.hive.MsgSniffer.windowRef.focus(); - } catch(e) { - // bring to front, resize, make visible, etc - i2b2.hive.MsgSniffer.windowRef.focus(); - } - if (!i2b2.hive.MsgSniffer.windowRef) { - alert('Could not display the Communications Channel Viewer.\n Please disable any popup blockers and try again.'); - return; - } - }, - showStack: function(viewtitle, origins, cells, actions) { - // put info into asyncStackFilter that msgViewer code will check upon it's initialization - this.asyncStackFilter = { - title: viewtitle+" Msg Stack", - origins: origins, - cells: cells, - actions: actions - }; - i2b2.hive.MsgSniffer._spawnWin(); - }, - // Register event for message sources - RegisterMessageSource: function(regMsg) { - // expected data format: { - // channelName: "CELLNAME", - // channelActions: ["the names", "of the", "Cell's server calls"], - // channelSniffEvent: {yui custom event} - // } - if (!regMsg.channelName || !regMsg.channelActions || !regMsg.channelSniffEvent || !regMsg.channelSniffEvent.subscribe) { - console.error('MsgSniffer: bad registration info / '+Object.inspect(regMsg)); - return false; - } - var t = regMsg.channelName; - regMsg.channelCode = t; - if (i2b2[t]) { - if (i2b2[t].cfg.config.name) { - regMsg.channelName = i2b2[t].cfg.config.name; - - } - } - var was_found = false; - for (var i = 0; i < this.sniffSources.length; i++) { - if (this.sniffSources[i].channelSniffEvent === regMsg.channelSniffEvent) { - was_found = true; - var t = this.sniffSources[i].channelActions.concat(regMsg.channelActions); - t = t.uniq(); - this.sniffSources[i].channelActions = t; - } - } - if (!was_found) { - this.sniffSources.push(regMsg); - regMsg.channelSniffEvent.subscribe(i2b2.hive.MsgSniffer.MsgHandler); - } - return true; - }, - MsgHandler: function(msgType, sniffMsg) { - // Function where the messages enter the sniffer subsystem - // (SCOPE IS NOT IN NAMESPACE WHEN FUNCTION IS CALLED) - var thisobj = i2b2.hive.MsgSniffer; - if (!i2b2.PM.model.login_debugging) { return true; } - // save the data if the framework is in debug mode - sniffMsg = sniffMsg[0]; - sniffMsg.SignalType = msgType; - var d = new Date(); - sniffMsg.SignalTimestamp = d; - thisobj.signalMessageDB.push(sniffMsg); - - if (thisobj.signalOrigins.indexOf(sniffMsg.SignalOrigin) == -1) { - thisobj.signalOrigins.push(sniffMsg.SignalOrigin); - } - // refresh the message viewer window if it is open - if (!i2b2.hive.MsgSniffer.windowRef || !i2b2.hive.MsgSniffer.windowRef.focus) { return true; } - i2b2.hive.MsgSniffer.windowRef.SnifferDisplay.renderFilteredList(); - return true; - } -}; +/** + * @projectDescription Message Sniffer object - sniffs communication for objects which expose a _DebugMessaging event. Example: i2b2.CRC.ajax._DebugMessaging is a custom YUI event object. + * @author Nick Benik, Griffin Weber MD PhD + * @version 1.3 + * updated 9-15-08: RC4 launch [Nick Benik] + */ + +i2b2.hive.MsgSniffer = { + yuiModalMsg: false, + crtlDown: false, + windowRef: null, + sniffSources: [], + signalOrigins: [], + signalMessageDB: [], + asyncStackFilter: false, + initialize: function(doActivate) {}, + _showSingleMsgModal: function() { + if (!i2b2.hive.MsgSniffer.yuiModalMsg) { + // show non-modal dialog with help documentation + var panel = new YAHOO.widget.Panel("commViewerSingleMsg-panel", { + draggable: true, + zindex:10000, + width: "650px", + height: "450px", + autofillheight: "body", + constraintoviewport: true, + context: ["tl", "bl"], + visible: false + }); + $("commViewerSingleMsg-panel").show(); + panel.render(document.body); + i2b2.hive.MsgSniffer.yuiModalMsg = panel; + + // resizer object and event handlers + i2b2.hive.MsgSniffer.yuiSingleMsgResizer = new YAHOO.util.Resize("commViewerSingleMsg-panel", { + handles: ['br'], + autoRatio: false, + minWidth: 350, + minHeight: 250, + status: false + }); + + i2b2.hive.MsgSniffer.yuiSingleMsgResizer.on('resize', function(args) { + var panelHeight = args.height; + this.cfg.setProperty("height", panelHeight + "px"); + }, i2b2.hive.MsgSniffer.yuiModalMsg, true); + + i2b2.hive.MsgSniffer.yuiSingleMsgResizer.on('startResize', function(args) { + if (this.cfg.getProperty("constraintoviewport")) { + var D = YAHOO.util.Dom; + var clientRegion = D.getClientRegion(); + var elRegion = D.getRegion(this.element); + resize.set("maxWidth", clientRegion.right - elRegion.left - YAHOO.widget.Overlay.VIEWPORT_OFFSET); + resize.set("maxHeight", clientRegion.bottom - elRegion.top - YAHOO.widget.Overlay.VIEWPORT_OFFSET); + } else { + resize.set("maxWidth", null); + resize.set("maxHeight", null); + } + }, i2b2.hive.MsgSniffer.yuiModalMsg, true); + } + }, + showSingleMsgRequest: function(strXML) { + this._showSingleMsgModal(); + try { + var t = $("commViewerSingleMsg-panel").select(".hd")[0]; + t.innerHTML = "Last Request Message"; + var t = $("commViewerSingleMsg-body").select(".xmlMsg")[0]; +// t.style.background = "#AFFFAF"; + t.innerHTML = '
        '+strXML+'
        '; + } catch (e) { console.error("Could not display information!"); } + i2b2.hive.MsgSniffer.yuiModalMsg.show(); + + }, + showSingleMsgResponse: function(strXML) { + this._showSingleMsgModal(); + try { + var t = $("commViewerSingleMsg-panel").select(".hd")[0]; + t.innerHTML = "Last Response Message"; + var t = $("commViewerSingleMsg-body").select(".xmlMsg")[0]; +// t.style.background = "#FFAFAF"; + t.innerHTML = '
        '+strXML+'
        '; + } catch (e) { console.error("Could not display information!"); } + i2b2.hive.MsgSniffer.yuiModalMsg.show(); + }, + show: function() { + this.asyncStackFilter = false; + this._spawnWin.call(this); + }, + _spawnWin: function() { + try { + // spawn new + i2b2.hive.MsgSniffer.windowRef = window.open('assets/msg-viewer.html', 'i2b2_msgsniffer', 'toolbar=no,resizable=yes,scrollbars=yes,height=480,width=740', false); + i2b2.hive.MsgSniffer.windowRef.focus(); + } catch(e) { + // bring to front, resize, make visible, etc + i2b2.hive.MsgSniffer.windowRef.focus(); + } + if (!i2b2.hive.MsgSniffer.windowRef) { + alert('Could not display the Communications Channel Viewer.\n Please disable any popup blockers and try again.'); + return; + } + }, + showStack: function(viewtitle, origins, cells, actions) { + // put info into asyncStackFilter that msgViewer code will check upon it's initialization + this.asyncStackFilter = { + title: viewtitle+" Msg Stack", + origins: origins, + cells: cells, + actions: actions + }; + i2b2.hive.MsgSniffer._spawnWin(); + }, + // Register event for message sources + RegisterMessageSource: function(regMsg) { + // expected data format: { + // channelName: "CELLNAME", + // channelActions: ["the names", "of the", "Cell's server calls"], + // channelSniffEvent: {yui custom event} + // } + if (!regMsg.channelName || !regMsg.channelActions || !regMsg.channelSniffEvent || !regMsg.channelSniffEvent.subscribe) { + console.error('MsgSniffer: bad registration info / '+Object.inspect(regMsg)); + return false; + } + var t = regMsg.channelName; + regMsg.channelCode = t; + if (i2b2[t]) { + if (i2b2[t].cfg.config.name) { + regMsg.channelName = i2b2[t].cfg.config.name; + + } + } + var was_found = false; + for (var i = 0; i < this.sniffSources.length; i++) { + if (this.sniffSources[i].channelSniffEvent === regMsg.channelSniffEvent) { + was_found = true; + var t = this.sniffSources[i].channelActions.concat(regMsg.channelActions); + t = t.uniq(); + this.sniffSources[i].channelActions = t; + } + } + if (!was_found) { + this.sniffSources.push(regMsg); + regMsg.channelSniffEvent.subscribe(i2b2.hive.MsgSniffer.MsgHandler); + } + return true; + }, + MsgHandler: function(msgType, sniffMsg) { + // Function where the messages enter the sniffer subsystem + // (SCOPE IS NOT IN NAMESPACE WHEN FUNCTION IS CALLED) + var thisobj = i2b2.hive.MsgSniffer; + if (!i2b2.PM.model.login_debugging) { return true; } + // save the data if the framework is in debug mode + sniffMsg = sniffMsg[0]; + sniffMsg.SignalType = msgType; + var d = new Date(); + sniffMsg.SignalTimestamp = d; + thisobj.signalMessageDB.push(sniffMsg); + + if (thisobj.signalOrigins.indexOf(sniffMsg.SignalOrigin) == -1) { + thisobj.signalOrigins.push(sniffMsg.SignalOrigin); + } + // refresh the message viewer window if it is open + if (!i2b2.hive.MsgSniffer.windowRef || !i2b2.hive.MsgSniffer.windowRef.focus) { return true; } + i2b2.hive.MsgSniffer.windowRef.SnifferDisplay.renderFilteredList(); + return true; + } +}; diff --git a/js-i2b2/ui.styles/ui.styles.css b/js-i2b2/ui.styles/ui.styles.css index e73d48d3..0314cbc1 100755 --- a/js-i2b2/ui.styles/ui.styles.css +++ b/js-i2b2/ui.styles/ui.styles.css @@ -1,20 +1,20 @@ - -/* - * Style for a splitter that's draggable over a left-hand-side UI and a right-hand-side UI. - * Height of the splitter spans the entire width of its containing element. - * Use inline style elements to override the defaults - */ -.vertical_splitter -{ - position: absolute; - top: 0px; - left: 200px; - width: 6px; - bottom: 0%; - background-color: #BBCCEE; - background-image: url('../../assets/images/splitter.handle.image.gif'); - background-repeat: no-repeat; - background-position:center; - cursor: ew-resize; - z-index:99; -} + +/* + * Style for a splitter that's draggable over a left-hand-side UI and a right-hand-side UI. + * Height of the splitter spans the entire width of its containing element. + * Use inline style elements to override the defaults + */ +.vertical_splitter +{ + position: absolute; + top: 0px; + left: 200px; + width: 6px; + bottom: 0%; + background-color: #BBCCEE; + background-image: url('../../assets/images/splitter.handle.image.gif'); + background-repeat: no-repeat; + background-position:center; + cursor: ew-resize; + z-index:99; +} From c649ddae74c6cd31550c1849e63ce9603a5b1968 Mon Sep 17 00:00:00 2001 From: "Jason Y. Lee" Date: Wed, 16 Aug 2017 04:04:52 -0700 Subject: [PATCH 2/2] Committing git attributes file --- .gitattributes | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..fbf9358b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.h text + +# Declare files that will always have CRLF line endings on checkout. +*.sln text eol=crlf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary