2008-05-17 16:44:42 +04:00
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Script :
mocha . js version 0.8
Copyright :
Copyright ( c ) 2007 - 2008 Greg Houston , < http : //greghoustondesign.com/>
License :
MIT - style license
Contributors :
Scott F . Frederick
Joel Lindau
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
var MochaUI = new Class ( {
options : {
// Global options for windows:
// Some of these options can be overriden for individual windows in newWindow()
resizable : true ,
draggable : true ,
minimizable : true , // Requires dock
maximizable : true , // Requires desktop
closable : true ,
effects : true , // Toggles the majority of window fade and move effects
minWidth : 250 , // Minimum width of windows when resized
maxWidth : 2500 , // Maximum width of windows when resized
minHeight : 100 , // Minimum height of windows when resized
maxHeight : 2000 , // Maximum height of windows when resized
// Style options:
headerHeight : 25 , // Height of window titlebar
footerHeight : 26 ,
cornerRadius : 9 ,
bodyBgColor : '#fff' , // Body background color - Hex
headerStartColor : [ 250 , 250 , 250 ] , // Header gradient's top color - RGB
headerStopColor : [ 228 , 228 , 228 ] , // Header gradient's bottom color
footerBgColor : [ 246 , 246 , 246 ] , // Background color of the main canvas shape
minimizeColor : [ 231 , 231 , 209 ] , // Minimize button color
maximizeColor : [ 217 , 229 , 217 ] , // Maximize button color
closeColor : [ 229 , 217 , 217 ] , // Close button color
resizableColor : [ 209 , 209 , 209 ] , // Resizable icon color
// Cascade options:
desktopTopOffset : 20 , // Use a negative number if neccessary to place first window where you want it
desktopLeftOffset : 290 ,
mochaTopOffset : 70 , // Initial vertical spacing of each window
mochaLeftOffset : 70 , // Initial horizontal spacing of each window
// Naming options:
// If you change the IDs of the Mocha Desktop containers in your HTML, you need to change them here as well.
desktop : 'mochaDesktop' ,
desktopHeader : 'mochaDesktopHeader' ,
desktopNavBar : 'mochaDesktopNavbar' ,
pageWrapper : 'mochaPageWrapper' ,
dock : 'mochaDock'
} ,
initialize : function ( options ) {
this . setOptions ( options ) ;
// Private properties
this . ieSupport = 'excanvas' // Makes it easier to switch between Excanvas and Moocanvas for testing
this . indexLevel = 1 ; // Used for z-Index
this . windowIDCount = 0 ;
this . myTimer = '' ; // Used with accordian
this . iconAnimation = '' ; // Used with loading icon
this . mochaControlsWidth = 0 ;
this . minimizebuttonX = 0 ; // Minimize button horizontal position
this . maximizebuttonX = 0 ; // Maximize button horizontal position
this . closebuttonX = 0 ; // Close button horizontal position
this . shadowWidth = 3 ;
this . shadowOffset = this . shadowWidth * 2 ;
this . HeaderFooterShadow = this . options . headerHeight + this . options . footerHeight + this . shadowOffset ;
this . desktop = $ ( this . options . desktop ) ;
this . desktopHeader = $ ( this . options . desktopHeader ) ;
this . desktopNavBar = $ ( this . options . desktopNavBar ) ;
this . pageWrapper = $ ( this . options . pageWrapper ) ;
this . dock = $ ( this . options . dock ) ;
this . dockVisible = this . dock ? true : false ; // True when dock is visible, false when not
this . dockAutoHide = false ; // True when dock autohide is set to on, false if set to off
if ( this . dock ) { this . initializeDock ( ) ; }
this . setDesktopSize ( ) ;
this . newWindowsFromXHTML ( ) ;
this . modalInitialize ( ) ;
this . menuInitialize ( ) ;
// Resize desktop, page wrapper, modal overlay, and maximized windows when browser window is resized
window . onresize = function ( ) { this . onBrowserResize ( ) ; } . bind ( this ) ;
} ,
menuInitialize : function ( ) {
// Fix for dropdown menus in IE6
if ( Browser . Engine . trident4 && this . desktopNavBar ) {
this . desktopNavBar . getElements ( 'li' ) . each ( function ( element ) {
element . addEvent ( 'mouseenter' , function ( ) {
this . addClass ( 'ieHover' ) ;
} )
element . addEvent ( 'mouseleave' , function ( ) {
this . removeClass ( 'ieHover' ) ;
} )
} )
} ;
} ,
modalInitialize : function ( ) {
var modalOverlay = new Element ( 'div' , {
'id' : 'mochaModalOverlay' ,
'styles' : {
'height' : document . getCoordinates ( ) . height
}
} ) ;
modalOverlay . injectInside ( this . desktop ? this . desktop : document . body ) ;
modalOverlay . setStyle ( 'opacity' , . 4 ) ;
this . modalOpenMorph = new Fx . Morph ( $ ( 'mochaModalOverlay' ) , {
'duration' : 200
} ) ;
this . modalCloseMorph = new Fx . Morph ( $ ( 'mochaModalOverlay' ) , {
'duration' : 200 ,
onComplete : function ( ) {
$ ( 'mochaModalOverlay' ) . setStyle ( 'display' , 'none' ) ;
} . bind ( this )
} ) ;
} ,
onBrowserResize : function ( ) {
this . setDesktopSize ( ) ;
this . setModalSize ( ) ;
// Resize maximized windows to fit new browser window size
setTimeout ( function ( ) {
$$ ( 'div.mocha' ) . each ( function ( el ) {
if ( el . isMaximized ) {
var iframe = this . getSubElement ( el , 'iframe' ) ;
if ( iframe ) {
iframe . setStyle ( 'visibility' , 'hidden' ) ;
}
var windowDimensions = document . getCoordinates ( ) ;
var contentWrapper = this . getSubElement ( el , 'contentWrapper' ) ;
contentWrapper . setStyles ( {
'height' : ( windowDimensions . height - this . options . headerHeight - this . options . footerHeight ) ,
'width' : windowDimensions . width
} ) ;
this . drawWindow ( el ) ;
if ( iframe ) {
iframe . setStyles ( {
'height' : contentWrapper . getStyle ( 'height' )
} ) ;
iframe . setStyle ( 'visibility' , 'visible' ) ;
}
}
} . bind ( this ) ) ;
} . bind ( this ) , 100 ) ;
} ,
newWindowsFromXHTML : function ( properties , cascade ) {
$$ ( 'div.mocha' ) . each ( function ( el , i ) {
// Get the window title and destroy that element, so it does not end up in window content
if ( Browser . Engine . presto || Browser . Engine . trident5 )
el . setStyle ( 'display' , 'block' ) ; // Required by Opera, and probably IE7
var title = el . getElement ( 'h3.mochaTitle' ) ;
var elDimensions = el . getStyles ( 'height' , 'width' ) ;
var properties = {
id : el . getProperty ( 'id' ) ,
height : elDimensions . height . toInt ( ) ,
width : elDimensions . width . toInt ( )
}
// If there is a title element, set title and destroy the element so it does not end up in window content
if ( title ) {
properties . title = title . innerHTML ;
title . destroy ( ) ;
}
/ *
// Make sure there are no null values
for ( var key in properties ) {
if ( ! properties [ key ] )
delete properties [ key ] ;
} * /
// Get content and destroy the element
properties . content = el . innerHTML ;
el . destroy ( ) ;
// Create window
this . newWindow ( properties , true ) ;
} . bind ( this ) ) ;
this . arrangeCascade ( ) ;
} ,
/ *
Method : newWindowsFromJSON
Description : Create one or more windows from JSON data . You can define all the same properties
as you can for newWindow . Undefined properties are set to their defaults .
* /
newWindowsFromJSON : function ( properties ) {
properties . each ( function ( properties ) {
this . newWindow ( properties ) ;
} . bind ( this ) ) ;
} ,
/ *
Method : newWindow
Arguments :
properties
cascade - boolean - this is set to true for windows parsed from the original XHTML
* /
newWindow : function ( properties , cascade ) {
var windowProperties = $extend ( {
id : null ,
title : 'New Window' ,
loadMethod : 'html' , // html, xhr, or iframe
content : '' , // used if loadMethod is set to 'html'
contentURL : 'pages/lipsum.html' , // used if loadMethod is set to 'xhr' or 'iframe'
modal : false ,
width : 300 ,
height : 125 ,
x : null ,
y : null ,
scrollbars : true ,
draggable : this . options . draggable ,
resizable : this . options . resizable ,
minimizable : this . options . minimizable ,
maximizable : this . options . maximizable ,
closable : this . options . closable ,
// Styling
paddingVertical : 10 ,
paddingHorizontal : 12 ,
bodyBgColor : this . options . bodyBgColor ,
headerStartColor : this . options . headerStartColor , // Header gradient's top color
headerStopColor : this . options . headerStopColor , // Header gradient's bottom color
footerBgColor : this . options . footerBgColor , // Background color of the main canvas shape
minimizeColor : this . options . minimizeColor , // Minimize button color
maximizeColor : this . options . maximizeColor , // Maximize button color
closeColor : this . options . closeColor , // Close button color
resizableColor : this . options . resizableColor , // Resizable icon color
// Events
onContentLoaded : $empty , // Event, fired when content is successfully loaded via XHR
onFocus : $empty , // Event, fired when the window is focused
onResize : $empty , // Event, fired when the window is resized
onMinimize : $empty , // Event, fired when the window is minimized
onMaximize : $empty , // Event, fired when the window is maximized
onClose : $empty , // Event, fired just before the window is closed
onCloseComplete : $empty // Event, fired after the window is closed
} , properties || { } ) ;
var windowEl = $ ( windowProperties . id ) ;
// Check if window already exists and is not in progress of closing down
if ( windowEl && ! windowEl . isClosing ) {
if ( windowEl . isMinimized ) // If minimized -> restore
this . restoreMinimized ( windowEl ) ;
else // else focus
setTimeout ( function ( ) { this . focusWindow ( windowEl ) ; } . bind ( this ) , 10 ) ;
return ;
}
// Create window div
var windowEl = new Element ( 'div' , {
'class' : 'mocha' ,
'id' : windowProperties . id && windowProperties . id != null ? windowProperties . id : 'win' + ( ++ this . windowIDCount ) ,
'styles' : {
'width' : windowProperties . width ,
'height' : windowProperties . height ,
'display' : 'block'
}
} ) ;
// Part of fix for scrollbar issues in Mac FF2
if ( Browser . Platform . mac && Browser . Engine . gecko ) {
windowEl . setStyle ( 'position' , 'fixed' ) ;
}
if ( windowProperties . loadMethod == 'iframe' ) {
// Iframes have their own scrollbars and padding.
windowProperties . scrollbars = false ;
windowProperties . paddingVertical = 0 ;
windowProperties . paddingHorizontal = 0 ;
}
// Extend our window element
windowEl = $extend ( windowEl , {
// Custom properties
id : windowProperties . id ,
oldTop : 0 ,
oldLeft : 0 ,
oldWidth : 0 , // Using this?
oldHeight : 0 ,
iconAnimation : $empty ,
modal : windowProperties . modal ,
scrollbars : windowProperties . scrollbars ,
contentBorder : null ,
// Always use close buttons for modal windows
closable : windowProperties . closable || windowProperties . modal ,
resizable : windowProperties . resizable && ! windowProperties . modal ,
draggable : windowProperties . draggable && ! windowProperties . modal ,
// Minimizable, dock is required and window cannot be modal
minimizable : this . dock && windowProperties . minimizable && ! windowProperties . modal ,
// Maximizable, desktop is required
maximizable : this . desktop && windowProperties . maximizable && ! windowProperties . modal ,
iframe : windowProperties . loadMethod == 'iframe' ? true : false ,
isMaximized : false ,
isMinimized : false ,
// Custom styling
headerStartColor : windowProperties . headerStartColor , // Header gradient's top color
headerStopColor : windowProperties . headerStopColor , // Header gradient's bottom color
footerBgColor : windowProperties . footerBgColor , // Background color of the main canvas shape
minimizeColor : windowProperties . minimizeColor , // Minimize button color
maximizeColor : windowProperties . maximizeColor , // Maximize button color
closeColor : windowProperties . closeColor , // Close button color
resizableColor : windowProperties . resizableColor , // Resizable icon color
// Custom events
onFocus : windowProperties . onFocus ,
onResize : windowProperties . onResize ,
onMinimize : windowProperties . onMinimize ,
onMaximize : windowProperties . onMaximize ,
onClose : windowProperties . onClose ,
onCloseComplete : windowProperties . onCloseComplete
} ) ;
// Insert sub elements inside windowEl and cache them locally while creating the new window
var subElements = this . insertWindowElements ( windowEl , windowProperties . height , windowProperties . width ) ;
// Set title
2008-09-14 14:14:54 +04:00
subElements . title . set ( 'html' , windowProperties . title ) ;
2008-05-17 16:44:42 +04:00
// Add content to window
switch ( windowProperties . loadMethod ) {
case 'xhr' :
new Request ( {
url : windowProperties . contentURL ,
onRequest : function ( ) {
this . showLoadingIcon ( subElements . canvasIcon ) ;
} . bind ( this ) ,
onFailure : function ( ) {
2008-09-14 14:14:54 +04:00
subElements . content . set ( 'html' , '<p><strong>Error Loading XMLHttpRequest</strong></p><p>Make sure all of your content is uploaded to your server, and that you are attempting to load a document from the same domain as this page. XMLHttpRequests will not work on your local machine.</p>' ) ;
2008-05-17 16:44:42 +04:00
this . hideLoadingIcon . delay ( 150 , this , subElements . canvasIcon ) ;
} . bind ( this ) ,
onSuccess : function ( response ) {
2008-09-14 14:14:54 +04:00
subElements . content . set ( 'html' , response ) ;
2008-05-17 16:44:42 +04:00
this . hideLoadingIcon . delay ( 150 , this , subElements . canvasIcon ) ;
windowProperties . onContentLoaded ( ) ;
} . bind ( this )
} ) . get ( ) ;
break ;
case 'iframe' :
if ( windowProperties . contentURL == '' ) {
break ;
}
subElements . iframe = new Element ( 'iframe' , {
'id' : windowEl . id + '_iframe' ,
'class' : 'mochaIframe' ,
'src' : windowProperties . contentURL ,
'marginwidth' : 0 ,
'marginheight' : 0 ,
'frameBorder' : 0 ,
'scrolling' : 'auto'
} ) . injectInside ( subElements . content ) ;
// Add onload event to iframe so we can stop the loading icon and run onContentLoaded()
subElements . iframe . addEvent ( 'load' , function ( e ) {
this . hideLoadingIcon . delay ( 150 , this , subElements . canvasIcon ) ;
windowProperties . onContentLoaded ( ) ;
} . bind ( this ) ) ;
this . showLoadingIcon ( subElements . canvasIcon ) ;
break ;
case 'html' :
default :
2008-09-14 14:14:54 +04:00
subElements . content . set ( 'html' , windowProperties . content ) ;
2008-05-17 16:44:42 +04:00
windowProperties . onContentLoaded ( ) ;
break ;
}
// Set scrollbars, always use 'hidden' for iframe windows
subElements . contentWrapper . setStyles ( {
'overflow' : windowProperties . scrollbars && ! windowProperties . iframe ? 'auto' : 'hidden' ,
'background' : windowProperties . bodyBgColor
} ) ;
// Set content padding
subElements . content . setStyles ( {
'padding-top' : windowProperties . paddingVertical ,
'padding-bottom' : windowProperties . paddingVertical ,
'padding-left' : windowProperties . paddingHorizontal ,
'padding-right' : windowProperties . paddingHorizontal
} ) ;
// Attach events to the window
this . attachResizable ( windowEl , subElements ) ;
this . setupEvents ( windowEl , subElements ) ;
// Move new window into position. If position not specified by user then center the window on the page
var dimensions = document . getCoordinates ( ) ;
if ( ! windowProperties . y ) {
var windowPosTop = ( dimensions . height * . 5 ) - ( ( windowProperties . height + this . HeaderFooterShadow ) * . 5 ) ;
}
else {
var windowPosTop = windowProperties . y
}
if ( ! windowProperties . x ) {
var windowPosLeft = ( dimensions . width * . 5 ) - ( windowProperties . width * . 5 ) ;
}
else {
var windowPosLeft = windowProperties . x
}
if ( windowEl . modal ) {
$ ( 'mochaModalOverlay' ) . setStyle ( 'display' , 'block' ) ;
if ( this . options . effects == false ) {
$ ( 'mochaModalOverlay' ) . setStyle ( 'opacity' , . 55 ) ;
}
else {
this . modalCloseMorph . cancel ( ) ;
this . modalOpenMorph . start ( {
'opacity' : . 55
} ) ;
}
windowEl . setStyles ( {
'top' : windowPosTop ,
'left' : windowPosLeft ,
'zIndex' : 11000
} ) ;
}
else if ( cascade == true ) {
// do nothing
}
else if ( this . options . effects == false ) {
windowEl . setStyles ( {
'top' : windowPosTop ,
'left' : windowPosLeft
} ) ;
}
else {
windowEl . positionMorph = new Fx . Morph ( windowEl , {
'duration' : 300
} ) ;
windowEl . positionMorph . start ( {
'top' : windowPosTop ,
'left' : windowPosLeft
} ) ;
setTimeout ( function ( ) { this . focusWindow ( windowEl ) ; } . bind ( this ) , 10 ) ;
}
// Inject window into DOM
windowEl . injectInside ( this . desktop ? this . desktop : document . body ) ;
this . drawWindow ( windowEl , subElements ) ;
// Drag.Move() does not work in IE until element has been injected, thus setting here
this . attachDraggable ( windowEl , subElements . titleBar ) ;
} ,
/ *
Method : closeWindow
Arguments :
el : the $ ( window ) to be closed
Returns :
true : the window was closed
false : the window was not closed
* /
closeWindow : function ( windowEl ) {
// Does window exist and is not already in process of closing ?
if ( ! ( windowEl = $ ( windowEl ) ) || windowEl . isClosing )
return ;
windowEl . isClosing = true ;
windowEl . onClose ( ) ;
if ( this . options . effects == false ) {
if ( windowEl . modal ) {
$ ( 'mochaModalOverlay' ) . setStyle ( 'opacity' , 0 ) ;
}
windowEl . destroy ( ) ;
windowEl . onCloseComplete ( ) ;
}
else {
// Redraws IE windows without shadows since IE messes up canvas alpha when you change element opacity
if ( Browser . Engine . trident ) this . drawWindow ( windowEl , null , false ) ;
if ( windowEl . modal ) {
this . modalCloseMorph . start ( {
'opacity' : 0
} ) ;
}
var closeMorph = new Fx . Morph ( windowEl , {
duration : 250 ,
onComplete : function ( ) {
windowEl . destroy ( ) ;
windowEl . onCloseComplete ( ) ;
} . bind ( this )
} ) ;
closeMorph . start ( {
'opacity' : . 4
} ) ;
}
return true ;
} ,
/ *
Method : closeAll
Notes : This closes all the windows
Returns :
true : the windows were closed
false : the windows were not closed
* /
closeAll : function ( ) {
$$ ( 'div.mocha' ) . each ( function ( el ) {
this . closeWindow ( el ) ;
$$ ( 'button.mochaDockButton' ) . destroy ( ) ;
} . bind ( this ) ) ;
return true ;
} ,
focusWindow : function ( windowEl ) {
if ( ! ( windowEl = $ ( windowEl ) ) )
return ;
// Only focus when needed
if ( windowEl . getStyle ( 'zIndex' ) . toInt ( ) == this . indexLevel )
return ;
this . indexLevel ++ ;
windowEl . setStyle ( 'zIndex' , this . indexLevel ) ;
windowEl . onFocus ( ) ;
} ,
maximizeWindow : function ( windowEl ) {
// If window no longer exists or is maximized, stop
if ( ! ( windowEl = $ ( windowEl ) ) || windowEl . isMaximized )
return ;
var contentWrapper = this . getSubElement ( windowEl , 'contentWrapper' ) ;
windowEl . onMaximize ( ) ;
// Save original position, width and height
windowEl . oldTop = windowEl . getStyle ( 'top' ) ;
windowEl . oldLeft = windowEl . getStyle ( 'left' ) ;
contentWrapper . oldWidth = contentWrapper . getStyle ( 'width' ) ;
contentWrapper . oldHeight = contentWrapper . getStyle ( 'height' ) ;
// Hide iframe
// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
if ( windowEl . iframe ) {
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'hidden' ) ;
}
var windowDimensions = document . getCoordinates ( ) ;
if ( this . options . effects == false ) {
windowEl . setStyles ( {
'top' : - this . shadowWidth ,
'left' : - this . shadowWidth
} ) ;
contentWrapper . setStyles ( {
'height' : windowDimensions . height - this . options . headerHeight - this . options . footerHeight ,
'width' : windowDimensions . width
} ) ;
this . drawWindow ( windowEl ) ;
// Show iframe
if ( windowEl . iframe ) {
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'visible' ) ;
}
}
else {
var maximizeMorph = new Fx . Morph ( windowEl , {
'duration' : 200 ,
'onComplete' : function ( windowEl ) {
contentWrapper . setStyles ( {
'height' : ( windowDimensions . height - this . options . headerHeight - this . options . footerHeight ) ,
'width' : windowDimensions . width
} ) ;
this . drawWindow ( windowEl ) ;
// Show iframe
if ( windowEl . iframe ) {
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'visible' ) ;
}
} . bind ( this )
} ) ;
maximizeMorph . start ( {
'top' : - this . shadowWidth , // Takes shadow width into account
'left' : - this . shadowWidth // Takes shadow width into account
} ) ;
}
windowEl . isMaximized = true ;
} ,
restoreWindow : function ( windowEl ) {
// Window exists and is maximized ?
if ( ! ( windowEl = $ ( windowEl ) ) || ! windowEl . isMaximized )
return ;
// Hide iframe
// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
if ( windowEl . iframe ) {
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'hidden' ) ;
}
var contentWrapper = this . getSubElement ( windowEl , 'contentWrapper' ) ;
contentWrapper . setStyles ( {
'width' : contentWrapper . oldWidth ,
'height' : contentWrapper . oldHeight
} ) ;
windowEl . isMaximized = false ;
this . drawWindow ( windowEl ) ;
if ( this . options . effects == false ) {
windowEl . setStyles ( {
'top' : windowEl . oldTop ,
'left' : windowEl . oldLeft
} ) ;
}
else {
var mochaMorph = new Fx . Morph ( windowEl , {
'duration' : 150 ,
'onComplete' : function ( el ) {
if ( windowEl . iframe ) {
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'visible' ) ;
}
} . bind ( this )
} ) ;
mochaMorph . start ( {
'top' : windowEl . oldTop ,
'left' : windowEl . oldLeft
} ) ;
}
} ,
minimizeWindow : function ( windowEl ) {
// What if there is no dock, react how ?? ignore request?
if ( ! ( windowEl = $ ( windowEl ) ) || ! this . dock )
return ;
// Hide iframe
// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
if ( windowEl . iframe ) {
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'hidden' ) ;
}
var title = this . getSubElement ( windowEl , 'title' ) ;
var mochaContentWrapper = windowEl . getElement ( '.mochaContentWrapper' ) ;
var titleText = title . innerHTML ;
windowEl . onMinimize ( ) ;
// Hide window and add to dock
windowEl . setStyle ( 'visibility' , 'hidden' ) ;
// Fixes a scrollbar issue in Mac FF2
if ( Browser . Platform . mac && Browser . Engine . gecko ) {
this . getSubElement ( windowEl , 'contentWrapper' ) . setStyle ( 'overflow' , 'hidden' ) ;
}
windowEl . isMinimized = true ;
var dockButton = new Element ( 'button' , {
'id' : windowEl . id + '_dockButton' ,
'class' : 'mochaDockButton' ,
'title' : titleText
2008-09-14 14:14:54 +04:00
} ) . set ( 'html' , titleText . substring ( 0 , 13 ) + ( titleText . length > 13 ? '...' : '' ) ) . injectInside ( $ ( this . dock ) ) ;
2008-05-17 16:44:42 +04:00
dockButton . addEvent ( 'click' , function ( event ) {
this . restoreMinimized ( windowEl ) ;
} . bind ( this ) ) ;
// Fixes a scrollbar issue in Mac FF2.
// Have to use timeout because window gets focused when you click on the minimize button
setTimeout ( function ( ) { windowEl . setStyle ( 'zIndex' , 1 ) ; } . bind ( this ) , 100 ) ;
} ,
restoreMinimized : function ( windowEl ) {
// Part of Mac FF2 scrollbar fix
if ( windowEl . scrollbars == true && windowEl . iframe == false ) {
this . getSubElement ( windowEl , 'contentWrapper' ) . setStyle ( 'overflow' , 'auto' ) ;
}
windowEl . setStyle ( 'visibility' , 'visible' ) ;
// Show iframe
if ( windowEl . iframe ) {
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'visible' ) ;
}
windowEl . isMinimized = false ;
this . focusWindow ( windowEl ) ;
this . dock . getElementById ( windowEl . id + '_dockButton' ) . destroy ( ) ;
} ,
/* -- START Private Methods -- */
/ *
Method : getSubElement ( )
Description :
Get a single subElement within windowEl . Subelements have IDs that are made up of the windowEl ID plus
an element key . e . g . , myWindow _content or myWindow _iframe .
Might rename these parentWindow and childElements in the future .
Arguments :
windowEl , subElementKey
Returns :
subElement
* /
getSubElement : function ( windowEl , subElementKey ) {
return windowEl . getElementById ( ( windowEl . id + '_' + subElementKey ) ) ;
} ,
/ *
Method : getSubElements ( )
Description :
Get subElements within windowEl referenced in array subElementsKeys
Arguments :
windowEl , subElementKeys
Returns :
Object , where elements are object . key
* /
getSubElements : function ( windowEl , subElementKeys ) {
var subElements = { } ;
subElementKeys . each ( function ( key ) {
subElements [ key ] = this . getSubElement ( windowEl , key ) ;
} . bind ( this ) ) ;
return subElements ;
} ,
/ *
Method : setupControlEvents ( )
Usage : internal
Arguments :
windowEl
* /
setupEvents : function ( windowEl , subElements ) {
/ * i f ( ! s u b E l e m e n t s )
subElements = this . getSubElements ( windowEl , [ 'closeButton' , 'minimizeButton' , 'maximizeButton' ] ) ; * /
// Set events
// Note: if a button does not exist, its due to properties passed to newWindow() stating otherwice
if ( subElements . closeButton )
subElements . closeButton . addEvent ( 'click' , function ( ) { this . closeWindow ( windowEl ) ; } . bind ( this ) ) ;
if ( ! windowEl . modal )
windowEl . addEvent ( 'click' , function ( ) { this . focusWindow ( windowEl ) ; } . bind ( this ) ) ;
if ( subElements . minimizeButton )
subElements . minimizeButton . addEvent ( 'click' , function ( ) { this . minimizeWindow ( windowEl ) ; } . bind ( this ) ) ;
if ( subElements . maximizeButton ) {
subElements . maximizeButton . addEvent ( 'click' , function ( ) {
if ( windowEl . isMaximized ) {
this . restoreWindow ( windowEl ) ;
subElements . maximizeButton . setProperty ( 'title' , 'Maximize' ) ;
} else {
this . maximizeWindow ( windowEl ) ;
subElements . maximizeButton . setProperty ( 'title' , 'Restore' ) ;
}
} . bind ( this ) ) ;
}
} ,
/ *
Method : attachDraggable ( )
Description : make window draggable
Usage : internal
Arguments :
windowEl
* /
attachDraggable : function ( windowEl , handleEl ) {
if ( ! windowEl . draggable )
return ;
new Drag . Move ( windowEl , {
handle : handleEl ,
onStart : function ( ) {
this . focusWindow ( windowEl ) ;
if ( windowEl . iframe )
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'hidden' ) ;
} . bind ( this ) ,
onComplete : function ( ) {
if ( windowEl . iframe )
this . getSubElement ( windowEl , 'iframe' ) . setStyle ( 'visibility' , 'visible' ) ;
} . bind ( this )
} ) ;
} ,
/ *
Method : attachResizable ( )
Description : make window resizable
Usage : internal
Arguments :
windowEl
* /
attachResizable : function ( windowEl , subElements ) {
if ( ! windowEl . resizable )
return ;
subElements . contentWrapper . makeResizable ( {
handle : subElements . resizeHandle ,
modifiers : {
x : 'width' ,
y : 'height'
} ,
limit : {
x : [ this . options . minWidth , this . options . maxWidth ] ,
y : [ this . options . minHeight , this . options . maxHeight ]
} ,
onStart : function ( ) {
this . cacheSubElements = this . getSubElements ( windowEl , [ 'title' , 'content' , 'canvas' , 'contentWrapper' , 'overlay' , 'titleBar' , 'iframe' , 'zIndexFix' ] ) ;
if ( this . cacheSubElements . iframe )
this . cacheSubElements . iframe . setStyle ( 'visibility' , 'hidden' ) ;
} . bind ( this ) ,
onDrag : function ( ) {
this . drawWindow ( windowEl , this . cacheSubElements ) ;
} . bind ( this ) ,
onComplete : function ( ) {
if ( this . cacheSubElements . iframe )
this . cacheSubElements . iframe . setStyle ( 'visibility' , 'visible' ) ;
delete this . cacheSubElements ;
this . cacheSubElements = null ;
windowEl . onResize ( ) ;
} . bind ( this )
} ) ;
} ,
setDesktopSize : function ( ) {
var windowDimensions = document . getCoordinates ( ) ;
if ( this . desktop ) {
this . desktop . setStyle ( 'height' , windowDimensions . height ) ;
}
// Set pageWrapper height so the dock doesn't cover the pageWrapper scrollbars.
if ( this . pageWrapper && this . desktopHeader ) {
var pageWrapperHeight = ( windowDimensions . height - this . desktopHeader . offsetHeight - ( this . dockVisible ? this . dock . offsetHeight : 0 ) ) ;
if ( pageWrapperHeight < 0 ) {
pageWrapperHeight = 0 ;
}
this . pageWrapper . setStyle ( 'height' , pageWrapperHeight + 'px' ) ;
}
} ,
setModalSize : function ( ) {
$ ( 'mochaModalOverlay' ) . setStyle ( 'height' , document . getCoordinates ( ) . height ) ;
} ,
/ *
Method : insertWindowElements
Arguments :
windowEl
Returns :
object containing all elements created within [ windowEl ]
* /
insertWindowElements : function ( windowEl , height , width ) {
var subElements = { } ;
if ( Browser . Engine . trident4 ) {
subElements . zIndexFix = new Element ( 'iframe' , {
'class' : 'zIndexFix' ,
'scrolling' : 'no' ,
'marginWidth' : 0 ,
'marginHeight' : 0 ,
'src' : '' ,
'id' : windowEl . id + '_zIndexFix'
} ) . injectInside ( windowEl ) ;
}
subElements . overlay = new Element ( 'div' , {
'class' : 'mochaOverlay' ,
'id' : windowEl . id + '_overlay'
} ) . injectInside ( windowEl ) ;
//Insert mochaTitlebar
subElements . titleBar = new Element ( 'div' , {
'class' : 'mochaTitlebar' ,
'id' : windowEl . id + '_titleBar' ,
'styles' : {
'cursor' : windowEl . draggable ? 'move' : 'default'
}
} ) . injectTop ( subElements . overlay ) ;
// Create window header
subElements . title = new Element ( 'h3' , {
'class' : 'mochaTitle' ,
'id' : windowEl . id + '_title'
} ) . injectInside ( subElements . titleBar ) ;
windowEl . contentBorder = new Element ( 'div' , {
'class' : 'mochaContentBorder' ,
'id' : this . options . id + '_contentBorder'
} ) . injectInside ( subElements . overlay ) ;
subElements . contentWrapper = new Element ( 'div' , {
'class' : 'mochaContentWrapper' ,
'id' : windowEl . id + '_contentWrapper' ,
'styles' : {
'width' : width + 'px' ,
'height' : height + 'px'
}
} ) . injectInside ( windowEl . contentBorder ) ;
subElements . content = new Element ( 'div' , {
'class' : 'mochaContent' ,
'id' : windowEl . id + '_content'
} ) . injectInside ( subElements . contentWrapper ) ;
//Insert canvas
subElements . canvas = new Element ( 'canvas' , {
'class' : 'mochaCanvas' ,
'width' : 1 ,
'height' : 1 ,
'id' : windowEl . id + '_canvas'
} ) . injectInside ( windowEl ) ;
// Dynamically initialize canvas using excanvas. This is only required by IE
if ( Browser . Engine . trident && this . ieSupport == 'excanvas' ) {
G _vmlCanvasManager . initElement ( subElements . canvas ) ;
// This is odd, .getContext() method does not exist before retrieving the
// element via getElement
subElements . canvas = windowEl . getElement ( '.mochaCanvas' ) ;
}
//Insert resize handles
if ( windowEl . resizable ) {
subElements . resizeHandle = new Element ( 'div' , {
'class' : 'resizeHandle' ,
'id' : windowEl . id + '_resizeHandle'
} ) . injectAfter ( subElements . overlay ) ;
if ( Browser . Engine . trident )
subElements . resizeHandle . setStyle ( 'zIndex' , 2 ) ;
}
//Insert mochaTitlebar controls
subElements . controls = new Element ( 'div' , {
'class' : 'mochaControls' ,
'id' : windowEl . id + '_controls'
} ) . injectAfter ( subElements . overlay ) ;
//Insert close button
if ( windowEl . closable ) {
subElements . closeButton = new Element ( 'div' , {
'class' : 'mochaClose' ,
'title' : 'Close Window' ,
'id' : windowEl . id + '_closeButton'
} ) . injectInside ( subElements . controls ) ;
}
//Insert maximize button
if ( windowEl . maximizable ) {
subElements . maximizeButton = new Element ( 'div' , {
'class' : 'maximizeToggle' ,
'title' : 'Maximize' ,
'id' : windowEl . id + '_maximizeButton'
} ) . injectInside ( subElements . controls ) ;
}
//Insert minimize button
if ( windowEl . minimizable ) {
subElements . minimizeButton = new Element ( 'div' , {
'class' : 'minimizeToggle' ,
'title' : 'Minimize' ,
'id' : windowEl . id + '_minimizeButton'
} ) . injectInside ( subElements . controls ) ;
}
//Insert canvas
subElements . canvasIcon = new Element ( 'canvas' , {
'class' : 'mochaLoadingIcon' ,
'width' : 18 ,
'height' : 18 ,
'id' : windowEl . id + '_canvasIcon'
} ) . injectBottom ( windowEl ) ;
// Dynamically initialize canvas using excanvas. This is only required by IE
if ( Browser . Engine . trident && this . ieSupport == 'excanvas' ) {
G _vmlCanvasManager . initElement ( subElements . canvasIcon ) ;
// This is odd, .getContext() method does not exist before retrieving the
// element via getElement
subElements . canvasIcon = windowEl . getElement ( '.mochaLoadingIcon' ) ;
}
if ( Browser . Engine . trident ) {
subElements . controls . setStyle ( 'zIndex' , 2 )
subElements . overlay . setStyle ( 'zIndex' , 2 )
}
// For Mac Firefox 2 to help reduce scrollbar bugs in that browser
if ( Browser . Platform . mac && Browser . Engine . gecko )
subElements . overlay . setStyle ( 'overflow' , 'auto' ) ;
this . setMochaControlsWidth ( windowEl , subElements ) ;
return subElements ;
} ,
/ *
Method : drawWindow
Arguments :
windowEl : the $ ( window )
subElements : children of $ ( window )
shadows : ( boolean ) false will draw a window without shadows
Notes : This is where we create the canvas GUI
* /
drawWindow : function ( windowEl , subElements , shadows ) {
if ( ! subElements ) {
subElements = this . getSubElements ( windowEl , [ 'title' , 'content' , 'canvas' , 'contentWrapper' , 'overlay' , 'titleBar' , 'iframe' , 'zIndexFix' ] ) ;
}
windowEl . contentBorder . setStyles ( {
'width' : subElements . contentWrapper . offsetWidth
} ) ;
// Resize iframe when window is resized
if ( windowEl . iframe ) {
subElements . iframe . setStyles ( {
'height' : subElements . contentWrapper . offsetHeight
} ) ;
}
var mochaHeight = subElements . contentWrapper . getStyle ( 'height' ) . toInt ( ) + this . HeaderFooterShadow ;
var mochaWidth = subElements . contentWrapper . getStyle ( 'width' ) . toInt ( ) + this . shadowOffset ;
subElements . overlay . setStyle ( 'height' , mochaHeight ) ;
windowEl . setStyle ( 'height' , mochaHeight ) ;
// If opera height and width must be set like this, when resizing:
subElements . canvas . height = Browser . Engine . webkit ? 4000 : mochaHeight ;
subElements . canvas . width = Browser . Engine . webkit ? 2000 : mochaWidth ;
// Part of the fix for IE6 select z-index bug and FF on Mac scrollbar z-index bug
if ( Browser . Engine . trident4 ) {
subElements . zIndexFix . setStyles ( {
'width' : mochaWidth ,
'height' : mochaHeight
} )
}
// Set width
windowEl . setStyle ( 'width' , mochaWidth ) ;
subElements . overlay . setStyle ( 'width' , mochaWidth ) ;
subElements . titleBar . setStyles ( {
'width' : mochaWidth - this . shadowOffset ,
'height' : this . options . headerHeight
} ) ;
// Draw shapes
var ctx = subElements . canvas . getContext ( '2d' ) ;
var dimensions = document . getCoordinates ( ) ;
ctx . clearRect ( 0 , 0 , dimensions . width , dimensions . height ) ;
// This is the drop shadow. It is created onion style with three layers
if ( shadows != false ) {
this . roundedRect ( ctx , 0 , 0 , mochaWidth , mochaHeight , this . options . cornerRadius , [ 0 , 0 , 0 ] , 0.06 ) ;
this . roundedRect ( ctx , 1 , 1 , mochaWidth - 2 , mochaHeight - 2 , this . options . cornerRadius , [ 0 , 0 , 0 ] , 0.08 ) ;
this . roundedRect ( ctx , 2 , 2 , mochaWidth - 4 , mochaHeight - 4 , this . options . cornerRadius , [ 0 , 0 , 0 ] , 0.3 ) ;
}
// Mocha body
this . bodyRoundedRect (
ctx , // context
3 , // x
2 , // y
mochaWidth - this . shadowOffset , // width
mochaHeight - this . shadowOffset , // height
this . options . cornerRadius , // corner radius
windowEl . footerBgColor // Footer color
) ;
// Mocha header
this . topRoundedRect (
ctx , // context
3 , // x
2 , // y
mochaWidth - this . shadowOffset , // width
this . options . headerHeight , // height
this . options . cornerRadius , // corner radius
windowEl . headerStartColor , // Header gradient's top color
windowEl . headerStopColor // Header gradient's bottom color
) ;
// Calculate X position for controlbuttons
this . closebuttonX = mochaWidth - ( windowEl . closable ? 15 : - 4 ) ;
this . maximizebuttonX = this . closebuttonX - ( windowEl . maximizable ? 19 : 0 ) ;
this . minimizebuttonX = this . maximizebuttonX - ( windowEl . minimizable ? 19 : 0 ) ;
if ( windowEl . closable )
this . closebutton ( ctx , this . closebuttonX , 15 , windowEl . closeColor , 1.0 ) ;
if ( windowEl . maximizable )
this . maximizebutton ( ctx , this . maximizebuttonX , 15 , windowEl . maximizeColor , 1.0 ) ;
if ( windowEl . minimizable )
this . minimizebutton ( ctx , this . minimizebuttonX , 15 , windowEl . minimizeColor , 1.0 ) ; // Minimize
if ( windowEl . resizable )
this . triangle ( ctx , mochaWidth - 20 , mochaHeight - 20 , 12 , 12 , windowEl . resizableColor , 1.0 ) ; // Resize handle
// Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7.
this . triangle ( ctx , 0 , 0 , 10 , 10 , windowEl . resizableColor , 0 ) ;
} ,
// Window body
bodyRoundedRect : function ( ctx , x , y , width , height , radius , rgb ) {
ctx . fillStyle = 'rgba(' + rgb . join ( ',' ) + ', 100)' ;
ctx . beginPath ( ) ;
ctx . moveTo ( x , y + radius ) ;
ctx . lineTo ( x , y + height - radius ) ;
ctx . quadraticCurveTo ( x , y + height , x + radius , y + height ) ;
ctx . lineTo ( x + width - radius , y + height ) ;
ctx . quadraticCurveTo ( x + width , y + height , x + width , y + height - radius ) ;
ctx . lineTo ( x + width , y + radius ) ;
ctx . quadraticCurveTo ( x + width , y , x + width - radius , y ) ;
ctx . lineTo ( x + radius , y ) ;
ctx . quadraticCurveTo ( x , y , x , y + radius ) ;
ctx . fill ( ) ;
} ,
roundedRect : function ( ctx , x , y , width , height , radius , rgb , a ) {
ctx . fillStyle = 'rgba(' + rgb . join ( ',' ) + ',' + a + ')' ;
ctx . beginPath ( ) ;
ctx . moveTo ( x , y + radius ) ;
ctx . lineTo ( x , y + height - radius ) ;
ctx . quadraticCurveTo ( x , y + height , x + radius , y + height ) ;
ctx . lineTo ( x + width - radius , y + height ) ;
ctx . quadraticCurveTo ( x + width , y + height , x + width , y + height - radius ) ;
ctx . lineTo ( x + width , y + radius ) ;
ctx . quadraticCurveTo ( x + width , y , x + width - radius , y ) ;
ctx . lineTo ( x + radius , y ) ;
ctx . quadraticCurveTo ( x , y , x , y + radius ) ;
ctx . fill ( ) ;
} ,
// Window header with gradient background
topRoundedRect : function ( ctx , x , y , width , height , radius , headerStartColor , headerStopColor ) {
// Create gradient
if ( Browser . Engine . presto != null ) {
var lingrad = ctx . createLinearGradient ( 0 , 0 , 0 , this . options . headerHeight + 2 ) ;
}
else {
var lingrad = ctx . createLinearGradient ( 0 , 0 , 0 , this . options . headerHeight ) ;
}
lingrad . addColorStop ( 0 , 'rgba(' + headerStartColor . join ( ',' ) + ', 100)' ) ;
lingrad . addColorStop ( 1 , 'rgba(' + headerStopColor . join ( ',' ) + ', 100)' ) ;
ctx . fillStyle = lingrad ;
// Draw header
ctx . beginPath ( ) ;
ctx . moveTo ( x , y ) ;
ctx . lineTo ( x , y + height ) ;
ctx . lineTo ( x + width , y + height ) ;
ctx . lineTo ( x + width , y + radius ) ;
ctx . quadraticCurveTo ( x + width , y , x + width - radius , y ) ;
ctx . lineTo ( x + radius , y ) ;
ctx . quadraticCurveTo ( x , y , x , y + radius ) ;
ctx . fill ( ) ;
} ,
// Resize handle
triangle : function ( ctx , x , y , width , height , rgb , a ) {
ctx . beginPath ( ) ;
ctx . moveTo ( x + width , y ) ;
ctx . lineTo ( x , y + height ) ;
ctx . lineTo ( x + width , y + height ) ;
ctx . closePath ( ) ;
ctx . fillStyle = 'rgba(' + rgb . join ( ',' ) + ',' + a + ')' ;
ctx . fill ( ) ;
} ,
drawCircle : function ( ctx , x , y , diameter , rgb , a ) {
// Circle
ctx . beginPath ( ) ;
ctx . moveTo ( x , y ) ;
ctx . arc ( x , y , diameter , 0 , Math . PI * 2 , true ) ;
ctx . fillStyle = 'rgba(' + rgb . join ( ',' ) + ',' + a + ')' ;
ctx . fill ( ) ;
} ,
maximizebutton : function ( ctx , x , y , rgb , a ) { // This could reuse the drawCircle method above
// Circle
ctx . beginPath ( ) ;
ctx . moveTo ( x , y ) ;
ctx . arc ( x , y , 7 , 0 , Math . PI * 2 , true ) ;
ctx . fillStyle = 'rgba(' + rgb . join ( ',' ) + ',' + a + ')' ;
ctx . fill ( ) ;
// X sign
ctx . beginPath ( ) ;
ctx . moveTo ( x , y - 4 ) ;
ctx . lineTo ( x , y + 4 ) ;
ctx . stroke ( ) ;
ctx . beginPath ( ) ;
ctx . moveTo ( x - 4 , y ) ;
ctx . lineTo ( x + 4 , y ) ;
ctx . stroke ( ) ;
} ,
closebutton : function ( ctx , x , y , rgb , a ) { // This could reuse the drawCircle method above
// Circle
ctx . beginPath ( ) ;
ctx . moveTo ( x , y ) ;
ctx . arc ( x , y , 7 , 0 , Math . PI * 2 , true ) ;
ctx . fillStyle = 'rgba(' + rgb . join ( ',' ) + ',' + a + ')' ;
ctx . fill ( ) ;
// Plus sign
ctx . beginPath ( ) ;
ctx . moveTo ( x - 3 , y - 3 ) ;
ctx . lineTo ( x + 3 , y + 3 ) ;
ctx . stroke ( ) ;
ctx . beginPath ( ) ;
ctx . moveTo ( x + 3 , y - 3 ) ;
ctx . lineTo ( x - 3 , y + 3 ) ;
ctx . stroke ( ) ;
} ,
minimizebutton : function ( ctx , x , y , rgb , a ) { // This could reuse the drawCircle method above
// Circle
ctx . beginPath ( ) ;
ctx . moveTo ( x , y ) ;
ctx . arc ( x , y , 7 , 0 , Math . PI * 2 , true ) ;
ctx . fillStyle = 'rgba(' + rgb . join ( ',' ) + ',' + a + ')' ;
ctx . fill ( ) ;
// Minus sign
ctx . beginPath ( ) ;
ctx . moveTo ( x - 4 , y ) ;
ctx . lineTo ( x + 4 , y ) ;
ctx . stroke ( ) ;
} ,
hideLoadingIcon : function ( canvas ) {
$ ( canvas ) . setStyle ( 'display' , 'none' ) ;
$clear ( canvas . iconAnimation ) ;
} ,
/ *
Method : showLoadingIcon
* /
showLoadingIcon : function ( canvas ) {
$ ( canvas ) . setStyles ( {
'display' : 'block'
} ) ;
var t = 1 ;
var iconAnimation = function ( canvas ) {
var ctx = $ ( canvas ) . getContext ( '2d' ) ;
ctx . clearRect ( 0 , 0 , 18 , 18 ) ; // Clear canvas
ctx . save ( ) ;
ctx . translate ( 9 , 9 ) ;
ctx . rotate ( t * ( Math . PI / 8 ) ) ;
var color = 0 ;
for ( i = 0 ; i < 8 ; i ++ ) { // Draw individual dots
color = Math . floor ( 255 / 8 * i ) ;
ctx . fillStyle = "rgb(" + color + "," + color + "," + color + ")" ;
ctx . rotate ( - Math . PI / 4 ) ;
ctx . beginPath ( ) ;
ctx . arc ( 0 , 7 , 2 , 0 , Math . PI * 2 , true ) ;
ctx . fill ( ) ;
}
ctx . restore ( ) ;
t ++ ;
} . bind ( this ) ;
canvas . iconAnimation = iconAnimation . periodical ( 125 , this , canvas ) ;
} ,
setMochaControlsWidth : function ( windowEl , subElements ) {
var controlWidth = 14 ;
var marginWidth = 5 ;
this . mochaControlsWidth = 0 ;
if ( windowEl . minimizable )
this . mochaControlsWidth += ( marginWidth + controlWidth ) ;
if ( windowEl . maximizable ) {
this . mochaControlsWidth += ( marginWidth + controlWidth ) ;
subElements . maximizeButton . setStyle ( 'margin-left' , marginWidth ) ;
}
if ( windowEl . closable ) {
this . mochaControlsWidth += ( marginWidth + controlWidth ) ;
subElements . closeButton . setStyle ( 'margin-left' , marginWidth ) ;
}
subElements . controls . setStyle ( 'width' , this . mochaControlsWidth ) ;
} ,
initializeDock : function ( ) {
this . dock . setStyles ( {
'display' : 'block' ,
'position' : 'absolute' ,
'top' : null ,
'bottom' : 0 ,
'left' : 0
} ) ;
// Probably: this event should be added/removed when toggling AutoHide, since we dont need it when AutoHide is turned off
// this.dockVisible tracks the status of the dock, so that showing/hiding is not done when not needed
document . addEvent ( 'mousemove' , function ( event ) {
if ( ! this . dockAutoHide )
return ;
var ev = new Event ( event ) ;
if ( ev . client . y > ( document . getCoordinates ( ) . height - 25 ) ) {
if ( ! this . dockVisible ) {
this . dock . setStyle ( 'display' , 'block' ) ;
this . dockVisible = true ;
this . setDesktopSize ( ) ;
}
} else {
if ( this . dockVisible ) {
this . dock . setStyle ( 'display' , 'none' ) ;
this . dockVisible = false ;
this . setDesktopSize ( ) ;
}
}
} . bind ( this ) ) ;
// Insert canvas
var canvas = new Element ( 'canvas' , {
'class' : 'mochaCanvas' ,
'id' : 'dockCanvas' ,
'width' : '15' ,
'height' : '18'
} ) . injectInside ( this . dock ) . setStyles ( {
position : 'absolute' ,
top : '4px' ,
left : '2px' ,
zIndex : 2
} ) ;
// Dynamically initialize canvas using excanvas. This is only required by IE
if ( Browser . Engine . trident && this . ieSupport == 'excanvas' ) {
G _vmlCanvasManager . initElement ( canvas ) ;
}
// Position top or bottom selector
$ ( 'mochaDockPlacement' ) . setProperty ( 'title' , 'Position Dock Top' ) ;
// Auto Hide toggle switch
$ ( 'mochaDockAutoHide' ) . setProperty ( 'title' , 'Turn Auto Hide On' ) ;
// Attach event
$ ( 'mochaDockPlacement' ) . addEvent ( 'click' , function ( event ) {
var ctx = this . dock . getElement ( '.mochaCanvas' ) . getContext ( '2d' ) ;
// Move dock to top position
if ( this . dock . getStyle ( 'position' ) != 'relative' ) {
this . dock . setStyles ( {
'position' : 'relative' ,
'bottom' : null ,
'border-top' : '1px solid #fff' ,
'border-bottom' : '1px solid #bbb'
} )
this . setDesktopSize ( ) ;
this . dock . setProperty ( 'dockPosition' , 'Top' ) ;
this . drawCircle ( ctx , 5 , 4 , 3 , [ 0 , 255 , 0 ] , 1.0 ) ; // green
this . drawCircle ( ctx , 5 , 14 , 3 , [ 212 , 208 , 200 ] , 1.0 ) ; // gray
$ ( 'mochaDockPlacement' ) . setProperty ( 'title' , 'Position Dock Bottom' ) ;
$ ( 'mochaDockAutoHide' ) . setProperty ( 'title' , 'Auto Hide Disabled in Top Dock Position' ) ;
this . dockAutoHide = false ;
}
// Move dock to bottom position
else {
this . dock . setStyles ( {
'position' : 'absolute' ,
'bottom' : 0 ,
'border-top' : '1px solid #bbb' ,
'border-bottom' : '1px solid #fff'
} )
this . setDesktopSize ( ) ;
this . dock . setProperty ( 'dockPosition' , 'Bottom' ) ;
this . drawCircle ( ctx , 5 , 4 , 3 , [ 241 , 102 , 116 ] , 1.0 ) ; // orange
this . drawCircle ( ctx , 5 , 14 , 3 , [ 241 , 102 , 116 ] , 1.0 ) ; // orange
$ ( 'mochaDockPlacement' ) . setProperty ( 'title' , 'Position Dock Top' ) ;
$ ( 'mochaDockAutoHide' ) . setProperty ( 'title' , 'Turn Auto Hide On' ) ;
}
} . bind ( this ) ) ;
// Attach event Auto Hide
$ ( 'mochaDockAutoHide' ) . addEvent ( 'click' , function ( event ) {
if ( this . dock . getProperty ( 'dockPosition' ) == 'Top' )
return false ;
var ctx = this . dock . getElement ( '.mochaCanvas' ) . getContext ( '2d' ) ;
this . dockAutoHide = ! this . dockAutoHide ; // Toggle
if ( this . dockAutoHide ) {
$ ( 'mochaDockAutoHide' ) . setProperty ( 'title' , 'Turn Auto Hide Off' ) ;
this . drawCircle ( ctx , 5 , 14 , 3 , [ 0 , 255 , 0 ] , 1.0 ) ; // green
} else {
$ ( 'mochaDockAutoHide' ) . setProperty ( 'title' , 'Turn Auto Hide On' ) ;
this . drawCircle ( ctx , 5 , 14 , 3 , [ 241 , 102 , 116 ] , 1.0 ) ; // orange
}
} . bind ( this ) ) ;
this . drawDock ( this . dock ) ;
} ,
drawDock : function ( el ) {
var ctx = el . getElement ( '.mochaCanvas' ) . getContext ( '2d' ) ;
this . drawCircle ( ctx , 5 , 4 , 3 , [ 241 , 102 , 116 ] , 1.0 ) ; // orange
this . drawCircle ( ctx , 5 , 14 , 3 , [ 241 , 102 , 116 ] , 1.0 ) ; // orange
} ,
dynamicResize : function ( windowEl ) {
this . getSubElement ( windowEl , 'contentWrapper' ) . setStyle ( 'height' , this . getSubElement ( windowEl , 'content' ) . offsetHeight ) ;
this . drawWindow ( windowEl ) ;
} ,
/ *
Method : arrangeCascade
* /
arrangeCascade : function ( ) {
var x = this . options . desktopLeftOffset
var y = this . options . desktopTopOffset ;
$$ ( 'div.mocha' ) . each ( function ( windowEl ) {
if ( ! windowEl . isMinimized && ! windowEl . isMaximized ) {
this . focusWindow ( windowEl ) ;
x += this . options . mochaLeftOffset ;
y += this . options . mochaTopOffset ;
if ( this . options . effects == false ) {
windowEl . setStyles ( {
'top' : y ,
'left' : x
} ) ;
}
else {
var cascadeMorph = new Fx . Morph ( windowEl , {
'duration' : 550
} ) ;
cascadeMorph . start ( {
'top' : y ,
'left' : x
} ) ;
}
}
} . bind ( this ) ) ;
} ,
/ *
Method : garbageCleanup
Notes : Empties an all windows of their children , removes and garbages the windows .
It is does not trigger onClose ( ) or onCloseComplete ( ) .
This is useful to clear memory before the pageUnload .
* /
garbageCleanUp : function ( ) {
$$ ( 'div.mocha' ) . each ( function ( el ) {
el . destroy ( ) ;
} . bind ( this ) ) ;
}
} ) ;
MochaUI . implement ( new Options ) ;
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MOCHA SCREENS
Notes : This class can be removed if you are not creating multiple screens / workspaces .
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
var MochaScreens = new Class ( {
options : {
defaultScreen : 0 // Default screen
} ,
initialize : function ( options ) {
this . setOptions ( options ) ;
this . setScreen ( this . options . defaultScreen ) ;
} ,
setScreen : function ( index ) {
if ( ! $ ( 'mochaScreens' ) )
return ;
$$ ( '#mochaScreens div.screen' ) . each ( function ( el , i ) {
el . setStyle ( 'display' , i == index ? 'block' : 'none' ) ;
} ) ;
}
} ) ;
MochaScreens . implement ( new Options ) ;
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MOCHA WINDOW FROM FORM
Notes : This class can be removed if you are not creating new windows dynamically from a form .
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
var MochaWindowForm = new Class ( {
options : {
id : null ,
title : 'New Window' ,
loadMethod : 'html' , // html, xhr, or iframe
content : '' , // used if loadMethod is set to 'html'
contentURL : 'pages/lipsum.html' , // used if loadMethod is set to 'xhr' or 'iframe'
modal : false ,
width : 300 ,
height : 125 ,
scrollbars : true , // true sets the overflow to auto and false sets it to hidden
x : null , // if x or y is null or modal is false the new window is centered in the browser window
y : null ,
paddingVertical : 10 ,
paddingHorizontal : 12
} ,
initialize : function ( options ) {
this . setOptions ( options ) ;
this . options . id = 'win' + ( ++ document . mochaUI . windowIDCount ) ;
this . options . title = $ ( 'mochaNewWindowHeaderTitle' ) . value ;
if ( $ ( 'htmlLoadMethod' ) . checked ) {
this . options . loadMethod = 'html' ;
}
if ( $ ( 'xhrLoadMethod' ) . checked ) {
this . options . loadMethod = 'xhr' ;
}
if ( $ ( 'iframeLoadMethod' ) . checked ) {
this . options . loadMethod = 'iframe' ;
}
this . options . content = $ ( 'mochaNewWindowContent' ) . value ;
if ( $ ( 'mochaNewWindowContentURL' ) . value ) {
this . options . contentURL = $ ( 'mochaNewWindowContentURL' ) . value ;
}
if ( $ ( 'mochaNewWindowModal' ) . checked ) {
this . options . modal = true ;
}
this . options . width = $ ( 'mochaNewWindowWidth' ) . value . toInt ( ) ;
this . options . height = $ ( 'mochaNewWindowHeight' ) . value . toInt ( ) ;
this . options . x = $ ( 'mochaNewWindowX' ) . value . toInt ( ) ;
this . options . y = $ ( 'mochaNewWindowY' ) . value . toInt ( ) ;
this . options . paddingVertical = $ ( 'mochaNewWindowPaddingVertical' ) . value . toInt ( ) ;
this . options . paddingHorizontal = $ ( 'mochaNewWindowPaddingHorizontal' ) . value . toInt ( ) ;
document . mochaUI . newWindow ( this . options ) ;
}
} ) ;
MochaWindowForm . implement ( new Options ) ;
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Corner Radius Slider
Notes : Remove this function and it ' s reference in onload if you are not
using the example corner radius slider
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
function addSlider ( ) {
if ( $ ( 'sliderarea' ) ) {
mochaSlide = new Slider ( $ ( 'sliderarea' ) , $ ( 'sliderknob' ) , {
steps : 20 ,
offset : 5 ,
onChange : function ( pos ) {
2008-09-14 14:14:54 +04:00
$ ( 'updatevalue' ) . set ( 'html' , pos ) ;
2008-05-17 16:44:42 +04:00
document . mochaUI . options . cornerRadius = pos ;
$$ ( 'div.mocha' ) . each ( function ( windowEl , i ) {
document . mochaUI . drawWindow ( windowEl ) ;
} ) ;
document . mochaUI . indexLevel ++ ;
}
} ) . set ( document . mochaUI . options . cornerRadius ) ;
}
}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Initialize Everything onLoad
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
window . addEvent ( 'domready' , function ( ) {
document . mochaScreens = new MochaScreens ( ) ;
document . mochaUI = new MochaUI ( ) ;
attachMochaLinkEvents ( ) ; // See mocha-events.js
addSlider ( ) ; // remove this if you remove the example corner radius slider
} ) ;
// This runs when a person leaves your page.
window . addEvent ( 'unload' , function ( ) {
if ( document . mochaUI ) document . mochaUI . garbageCleanUp ( ) ;
} ) ;