Commit 7cc928e9 authored by Alexandre Leray's avatar Alexandre Leray
Browse files

Merge branch 'master' of git.constantvzw.org:aa.wiki

parents 0cb6e63e 5dd0e5cc
/**
* @preserve jquery.layout 1.3.0 - Release Candidate 29.15
* $Date: 2011-06-25 08:00:00 (Sat, 25 Jun 2011) $
* $Rev: 302915 $
*
* Copyright (c) 2010
* Fabrizio Balliano (http://www.fabrizioballiano.net)
* 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.
*
* Changelog: http://layout.jquery-dev.net/changelog.cfm#1.3.0.rc29.15
*
* Docs: http://layout.jquery-dev.net/documentation.html
* Tips: http://layout.jquery-dev.net/tips.html
* Help: http://groups.google.com/group/jquery-ui-layout
*/
// NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars
;(function ($) {
/*
* GENERIC $.layout METHODS - used by all layouts
*/
$.layout = {
version: "1.3.rc29.15"
, revision: 0.032915 // 1.3.0 final = 1.0300 - major(n+).minor(nn)+patch(nn+)
// LANGUAGE CUSTOMIZATION
, language: {
// Tips and messages for resizers, togglers, custom buttons, etc.
Open: "Open" // eg: "Open Pane"
, Close: "Close"
, Resize: "Resize"
, Slide: "Slide Open"
, Pin: "Pin"
, Unpin: "Un-Pin"
, noRoomToOpenTip: "Not enough room to show this pane."
// Developer error messages
, pane: "pane" // description of "layout pane element"
, selector: "selector" // description of "jQuery-selector"
, errButton: "Error Adding Button \n\nInvalid "
, errContainerMissing: "UI Layout Initialization Error\n\nThe specified layout-container does not exist."
, errCenterPaneMissing: "UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element."
, errContainerHeight: "UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!"
}
// can update code here if $.browser is phased out
, browser: {
mozilla: !!$.browser.mozilla
, webkit: !!$.browser.webkit || !!$.browser.safari // webkit = jQ 1.4
, msie: !!$.browser.msie
, isIE6: !!$.browser.msie && $.browser.version == 6
, boxModel: false // page must load first, so will be updated set by _create
//, version: $.browser.version - not used
}
/*
* GENERIC UTILITY METHODS
*/
// calculate and return the scrollbar width, as an integer
, scrollbarWidth: function () { return window.scrollbarWidth || $.layout.getScrollbarSize('width'); }
, scrollbarHeight: function () { return window.scrollbarHeight || $.layout.getScrollbarSize('height'); }
, getScrollbarSize: function (dim) {
var $c = $('<div style="position: absolute; top: -10000px; left: -10000px; width: 100px; height: 100px; overflow: scroll;"></div>').appendTo("body");
var d = { width: $c.width() - $c[0].clientWidth, height: $c.height() - $c[0].clientHeight };
$c.remove();
window.scrollbarWidth = d.width;
window.scrollbarHeight = d.height;
return dim.match(/^(width|height)$/i) ? d[dim] : d;
}
/**
* Returns hash container 'display' and 'visibility'
*
* @see $.swap() - swaps CSS, runs callback, resets CSS
*/
, showInvisibly: function ($E, force) {
if (!$E) return {};
if (!$E.jquery) $E = $($E);
var CSS = {
display: $E.css('display')
, visibility: $E.css('visibility')
};
if (force || CSS.display == "none") { // only if not *already hidden*
$E.css({ display: "block", visibility: "hidden" }); // show element 'invisibly' so can be measured
return CSS;
}
else 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) {
var
d = {} // dimensions hash
, x = d.css = {} // CSS hash
, i = {} // TEMP insets
, b, p // TEMP border, padding
, N = $.layout.cssNum
, off = $E.offset()
;
d.offsetLeft = off.left;
d.offsetTop = off.top;
$.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);
i[e] = b + p; // total offset of content from outer side
d["inset"+ e] = p;
});
d.offsetWidth = $E.innerWidth();
d.offsetHeight = $E.innerHeight();
d.outerWidth = $E.outerWidth();
d.outerHeight = $E.outerHeight();
d.innerWidth = Math.max(0, d.outerWidth - i.Left - i.Right);
d.innerHeight = Math.max(0, d.outerHeight - i.Top - i.Bottom);
x.width = $E.width();
x.height = $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.visible = $E.is(":visible");// && x.width > 0 && x.height > 0;
return d;
}
, getElementCSS: 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
}
/**
* Contains logic to check boxModel & browser, and return the correct width/height for the current browser/doctype
*
* @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles()
* @param {Array.<Object>} $E Must pass a jQuery object - first element is processed
* @param {number=} outerWidth/outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized
* @return {number} Returns the innerWidth/Height of the elem by subtracting padding and borders
*/
, cssWidth: function ($E, outerWidth) {
var
b = $.layout.borderWidth
, n = $.layout.cssNum
;
// a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed
if (outerWidth <= 0) return 0;
if (!$.layout.browser.boxModel) return outerWidth;
// strip border and padding from outerWidth to get CSS Width
var W = outerWidth
- b($E, "Left")
- b($E, "Right")
- n($E, "paddingLeft")
- n($E, "paddingRight")
;
return Math.max(0,W);
}
, cssHeight: function ($E, outerHeight) {
var
b = $.layout.borderWidth
, n = $.layout.cssNum
;
// a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed
if (outerHeight <= 0) return 0;
if (!$.layout.browser.boxModel) return outerHeight;
// strip border and padding from outerHeight to get CSS Height
var H = outerHeight
- b($E, "Top")
- b($E, "Bottom")
- n($E, "paddingTop")
- n($E, "paddingBottom")
;
return Math.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.<Object>} $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 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 = $.curCSS($E[0], prop, true)
, v = allowAuto && p=="auto" ? p : (parseInt(p, 10) || 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 $.curCSS(el, b+"Style", true) == "none" ? 0 : (parseInt($.curCSS(el, b+"Width", true), 10) || 0);
}
/**
* UTLITY for mouse tracking - 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));
}
};
$.fn.layout = function (opts) {
/*
* ###########################
* WIDGET CONFIG & OPTIONS
* ###########################
*/
var
// LANGUAGE - for tips & messages
lang = $.layout.language // internal alias
// DEFAULT OPTIONS - CHANGE IF DESIRED
, options = {
name: "" // Not required, but useful for buttons and used for the state-cookie
, containerClass: "ui-layout-container" // layout-container element
, 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
, 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
, autoBindCustomButtons: false // search for buttons with ui-layout-button class and auto-bind them
, zIndex: null // the PANE zIndex - resizers and masks will be +1
, initPanes: true // false = DO NOT initialize the panes onLoad - will init later
, showErrorMessages: true // enables fatal error messages to warn developers of common errors
// PANE SETTINGS
, defaults: { // 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" // border-Pane - default: 'ui-layout-pane'
, resizerClass: "ui-layout-resizer" // Resizer Bar - default: 'ui-layout-resizer'
, togglerClass: "ui-layout-toggler" // Toggler Button - default: 'ui-layout-toggler'
, buttonClass: "ui-layout-button" // CUSTOM Buttons - default: '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
, togglerTip_open: lang.Close // Toggler tool-tip (title)
, togglerTip_closed: lang.Open // ditto
, 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
, maskIframesOnResize: true // true = all iframes OR = iframe-selector(s) - adds masking-div during resizing/dragging
, resizeNestedLayout: true // true = trigger nested.resizeAll() when a 'pane' of this layout is the 'container' for another
, resizeWhileDragging: false // true = LIVE Resizing as resizer is dragged
, resizeContentWhileDragging: false // true = re-measure header/footer heights as resizer is dragged
// TIPS & MESSAGES - also see lang object
, noRoomToOpenTip: lang.noRoomToOpenTip
, resizerTip: lang.Resize // Resizer tool-tip (title)
, sliderTip: lang.Slide // resizer-bar triggers 'sliding' when pane is closed
, 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
// 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 options (eg: fxName_open) are auto-generated if not passed
, fxName: "slide" // ('none' or blank), slide, drop, scale
, 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
// CALLBACKS
, triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes
, triggerEventsWhileDragging: true // true = trigger onresize callback REPEATEDLY if resizeWhileDragging==true
, 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
}
, north: {
paneSelector: ".ui-layout-north"
, size: "auto" // eg: "auto", "30%", 200
, resizerCursor: "n-resize" // custom = url(myCursor.cur)
, customHotkey: "" // EITHER a charCode OR a character
}
, 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
}
// STATE MANAGMENT
, useStateCookie: false // Enable cookie-based state-management - can fine-tune with cookie.autoLoad/autoSave
, cookie: {
name: "" // If not specified, will use Layout.name, else just "Layout"
, autoSave: true // Save a state cookie when page exits?
, autoLoad: true // Load the state cookie when Layout inits?
// Cookie Options
, domain: ""
, path: ""
, expires: "" // 'days' to keep cookie - leave blank for 'session cookie'
, secure: false
// List of options to save in the cookie - must be pane-specific
, keys: "north.size,south.size,east.size,west.size,"+
"north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+
"north.isHidden,south.isHidden,east.isHidden,west.isHidden"
}
}
// PREDEFINED EFFECTS / DEFAULTS
, effects = { // LIST *PREDEFINED EFFECTS* HERE, even if effect has no settings
slide: {
all: { duration: "fast" } // eg: duration: 1000, easing: "easeOutBounce"
, north: { direction: "up" }
, south: { direction: "down" }
, east: { direction: "right"}
, west: { direction: "left" }
}
, drop: {
all: { duration: "slow" } // eg: duration: 1000, easing: "easeOutQuint"
, north: { direction: "up" }
, south: { direction: "down" }
, east: { direction: "right"}
, west: { direction: "left" }
}
, scale: {
all: { duration: "fast" }
}
}
// DYNAMIC DATA - IS READ-ONLY EXTERNALLY!
, state = {
// generate unique ID to use for event.namespace so can unbind only events added by 'this layout'
id: "layout"+ new Date().getTime() // code uses alias: sID
, initialized: false
, container: {} // init all keys
, north: {}
, south: {}
, east: {}
, west: {}
, center: {}
, cookie: {} // State Managment data storage
}
// INTERNAL CONFIG DATA - DO NOT CHANGE THIS!
, _c = {
allPanes: "north,south,west,east,center"
, borderPanes: "north,south,west,east"
, altSide: {
north: "south"
, south: "north"
, east: "west"
, west: "east"
}
// CSS used in multiple places
, hidden: { visibility: "hidden" }
, visible: { visibility: "visible" }
// layout element settings
, zIndex: { // set z-index values here
pane_normal: 1 // normal z-index for panes
, resizer_normal: 2 // normal z-index for resizer-bars
, iframe_mask: 2 // overlay div used to mask pane(s) during resizing
, 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'
}
, resizers: {
cssReq: {
position: "absolute"
, padding: 0
, margin: 0
, fontSize: "1px"
, textAlign: "left" // to counter-act "center" alignment!
, overflow: "hidden" // prevent toggler-button from overflowing
// SEE c.zIndex.resizer_normal
}
, cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
background: "#DDD"
, border: "none"
}
}
, togglers: {
cssReq: {
position: "absolute"
, display: "block"
, padding: 0
, margin: 0
, overflow: "hidden"
, textAlign: "center"
, fontSize: "1px"
, cursor: "pointer"
, zIndex: 1
}
, cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
background: "#AAA"
}
}
, content: {
cssReq: {
position: "relative" /* contain floated or positioned elements */
}
, cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
overflow: "auto"
, padding: "10px"
}
, cssDemoPane: { // DEMO CSS - REMOVE scrolling from 'pane' when it has a content-div
overflow: "hidden"
, padding: 0
}
}
, panes: { // defaults for ALL panes - overridden by 'per-pane settings' below
cssReq: {
position: "absolute"
, margin: 0
// SEE c.zIndex.pane_normal
}
, cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
padding: "10px"
, background: "#FFF"
, border: "1px solid #BBB"
, overflow: "auto"
}
}
, north: {
side: "Top"
, sizeType: "Height"
, dir: "horz"
, cssReq: {
top: 0
, bottom: "auto"
, left: 0
, right: 0
, width: "auto"
// height: DYNAMIC
}
, pins: [] // array of 'pin buttons' to be auto-updated on open/close (classNames)
}
, south: {
side: "Bottom"
, sizeType: "Height"
, dir: "horz"
, cssReq: {
top: "auto"
, bottom: 0
, left: 0
, right: 0
, width: "auto"
// height: DYNAMIC
}
, pins: []
}
, east: {
side: "Right"
, sizeType: "Width"
, dir: "vert"
, cssReq: {