/*! Split Pane v0.3 Copyright (c) 2012 Simon Hagström Released under the MIT license https://raw.github.com/shagstrom/split-pane/master/LICENSE */ (function($) { $.fn.splitPane = function() { var $splitPanes = this; $splitPanes.each(setMinHeightAndMinWidth); $splitPanes.append('
'); $splitPanes.children('.split-pane-divider').bind('mousedown', mousedownHandler); setTimeout(function() { // Doing this later because of an issue with Chrome (v23.0.1271.64) returning split-pane width = 0 // and triggering multiple resize events when page is being opened from an . $splitPanes.bind('_splitpaneparentresize', parentresizeHandler); $(window).trigger('resize'); }, 100); }; var SPLITPANERESIZE_HANDLER = '_splitpaneparentresizeHandler'; /** * A special event that will "capture" a resize event from the parent split-pane or window. * The event will NOT propagate to grandchildren. */ jQuery.event.special._splitpaneparentresize = { setup: function(data, namespaces) { var element = this, parent = $(this).parent().closest('.split-pane')[0] || window; $(this).data(SPLITPANERESIZE_HANDLER, function(event) { var target = event.target === document ? window : event.target; if (target === parent) { event.type = "_splitpaneparentresize"; jQuery.event.dispatch.apply(element, arguments); } else { event.stopPropagation(); } }); $(parent).bind('resize', $(this).data(SPLITPANERESIZE_HANDLER)); }, teardown: function(namespaces) { var parent = $(this).parent().closest('.split-pane')[0] || window; $(parent).unbind('resize', $(this).data(SPLITPANERESIZE_HANDLER)); $(this).removeData(SPLITPANERESIZE_HANDLER); } }; function setMinHeightAndMinWidth() { var $splitPane = $(this), $firstComponent = $splitPane.children('.split-pane-component:first'), $divider = $splitPane.children('.split-pane-divider'), $lastComponent = $splitPane.children('.split-pane-component:last'); if ($splitPane.is('.fixed-top, .fixed-bottom, .horizontal-percent')) { $splitPane.css('min-height', (minHeight($firstComponent) + minHeight($lastComponent) + $divider.height()) + 'px'); } else { $splitPane.css('min-width', (minWidth($firstComponent) + minWidth($lastComponent) + $divider.width()) + 'px'); } } function mousedownHandler(event) { event.preventDefault(); var $resizeShim = $(this).siblings('.split-pane-resize-shim').show(), mousemove = createMousemove($(this).parent(), event.pageX, event.pageY); $(document).mousemove(mousemove); $(document).one('mouseup', function(event) { $(document).unbind('mousemove', mousemove); $resizeShim.hide(); }); } function parentresizeHandler() { var $splitPane = $(this), $firstComponent = $splitPane.children('.split-pane-component:first'), $divider = $splitPane.children('.split-pane-divider'), $lastComponent = $splitPane.children('.split-pane-component:last'); if ($splitPane.is('.fixed-top')) { var maxfirstComponentHeight = $splitPane.height() - minHeight($lastComponent) - $divider.height(); if ($firstComponent.height() > maxfirstComponentHeight) { setTop($splitPane, $firstComponent, $divider, $lastComponent, maxfirstComponentHeight + 'px'); } else { $splitPane.resize(); } } else if ($splitPane.is('.fixed-bottom')) { var maxLastComponentHeight = $splitPane.height() - minHeight($firstComponent) - $divider.height(); if ($lastComponent.height() > maxLastComponentHeight) { setBottom($splitPane, $firstComponent, $divider, $lastComponent, maxLastComponentHeight + 'px') } else { $splitPane.resize(); } } else if ($splitPane.is('.horizontal-percent')) { var maxLastComponentHeight = $splitPane.height() - minHeight($firstComponent) - $divider.height(); if ($lastComponent.height() > maxLastComponentHeight) { setBottom($splitPane, $firstComponent, $divider, $lastComponent, (maxLastComponentHeight / $splitPane.height() * 100) + '%'); } else { var lastComponentMinHeight = minHeight($lastComponent); if ($splitPane.height() - $firstComponent.height() - $divider.height() < lastComponentMinHeight) { setBottom($splitPane, $firstComponent, $divider, $lastComponent, (lastComponentMinHeight / $splitPane.height() * 100) + '%'); } else { $splitPane.resize(); } } } else if ($splitPane.is('.fixed-left')) { var maxFirstComponentWidth = $splitPane.width() - minWidth($lastComponent) - $divider.width(); if ($firstComponent.width() > maxFirstComponentWidth) { setLeft($splitPane, $firstComponent, $divider, $lastComponent, maxFirstComponentWidth + 'px'); } else { $splitPane.resize(); } } else if ($splitPane.is('.fixed-right')) { var maxLastComponentWidth = $splitPane.width() - minWidth($firstComponent) - $divider.width(); if ($lastComponent.width() > maxLastComponentWidth) { setRight($splitPane, $firstComponent, $divider, $lastComponent, maxLastComponentWidth + 'px') } else { $splitPane.resize(); } } else if ($splitPane.is('.vertical-percent')) { var maxLastComponentWidth = $splitPane.width() - minWidth($firstComponent) - $divider.width(); if ($lastComponent.width() > maxLastComponentWidth) { setRight($splitPane, $firstComponent, $divider, $lastComponent, (maxLastComponentWidth / $splitPane.width() * 100) + '%'); } else { var lastComponentMinWidth = minWidth($lastComponent); if ($splitPane.width() - $firstComponent.width() - $divider.width() < lastComponentMinWidth) { setRight($splitPane, $firstComponent, $divider, $lastComponent, (lastComponentMinWidth / $splitPane.width() * 100) + '%'); } else { $splitPane.resize(); } } } } function createMousemove($splitPane, pageX, pageY) { var $firstComponent = $splitPane.children('.split-pane-component:first'), $divider = $splitPane.children('.split-pane-divider'), $lastComponent = $splitPane.children('.split-pane-component:last'); if ($splitPane.is('.fixed-top')) { var firstComponentMinHeight = minHeight($firstComponent), maxFirstComponentHeight = $splitPane.height() - minHeight($lastComponent) - $divider.height(), topOffset = $divider.position().top - pageY; return function(event) { event.preventDefault(); var top = Math.min(Math.max(firstComponentMinHeight, topOffset + event.pageY), maxFirstComponentHeight); setTop($splitPane, $firstComponent, $divider, $lastComponent, top + 'px') }; } else if ($splitPane.is('.fixed-bottom')) { var lastComponentMinHeight = minHeight($lastComponent), maxLastComponentHeight = $splitPane.height() - minHeight($firstComponent) - $divider.height(), bottomOffset = $lastComponent.height() + pageY; return function(event) { event.preventDefault(); var bottom = Math.min(Math.max(lastComponentMinHeight, bottomOffset - event.pageY), maxLastComponentHeight); setBottom($splitPane, $firstComponent, $divider, $lastComponent, bottom + 'px'); }; } else if ($splitPane.is('.horizontal-percent')) { var splitPaneHeight = $splitPane.height(), lastComponentMinHeight = minHeight($lastComponent), maxLastComponentHeight = splitPaneHeight - minHeight($firstComponent) - $divider.height(), bottomOffset = $lastComponent.height() + pageY; return function(event) { event.preventDefault(); var bottom = Math.min(Math.max(lastComponentMinHeight, bottomOffset - event.pageY), maxLastComponentHeight); setBottom($splitPane, $firstComponent, $divider, $lastComponent, (bottom / splitPaneHeight * 100) + '%'); }; } else if ($splitPane.is('.fixed-left')) { var firstComponentMinWidth = minWidth($firstComponent), maxFirstComponentWidth = $splitPane.width() - minWidth($lastComponent) - $divider.width(), leftOffset = $divider.position().left - pageX; return function(event) { event.preventDefault(); var left = Math.min(Math.max(firstComponentMinWidth, leftOffset + event.pageX), maxFirstComponentWidth); setLeft($splitPane, $firstComponent, $divider, $lastComponent, left + 'px') }; } else if ($splitPane.is('.fixed-right')) { var lastComponentMinWidth = minWidth($lastComponent), maxLastComponentWidth = $splitPane.width() - minWidth($firstComponent) - $divider.width(), rightOffset = $lastComponent.width() + pageX; return function(event) { event.preventDefault(); var right = Math.min(Math.max(lastComponentMinWidth, rightOffset - event.pageX), maxLastComponentWidth); setRight($splitPane, $firstComponent, $divider, $lastComponent, right + 'px'); }; } else if ($splitPane.is('.vertical-percent')) { var splitPaneWidth = $splitPane.width(), lastComponentMinWidth = minWidth($lastComponent), maxLastComponentWidth = splitPaneWidth - minWidth($firstComponent) - $divider.width(), rightOffset = $lastComponent.width() + pageX; return function(event) { event.preventDefault(); var right = Math.min(Math.max(lastComponentMinWidth, rightOffset - event.pageX), maxLastComponentWidth); setRight($splitPane, $firstComponent, $divider, $lastComponent, (right / splitPaneWidth * 100) + '%'); }; } } function minHeight($element) { return parseInt($element.css('min-height')) || 0; } function minWidth($element) { return parseInt($element.css('min-width')) || 0; } function setTop($splitPane, $firstComponent, $divider, $lastComponent, top) { $firstComponent.css('height', top); $divider.css('top', top); $lastComponent.css('top', top); $splitPane.resize(); } function setBottom($splitPane, $firstComponent, $divider, $lastComponent, bottom) { $firstComponent.css('bottom', bottom); $divider.css('bottom', bottom); $lastComponent.css('height', bottom); $splitPane.resize(); } function setLeft($splitPane, $firstComponent, $divider, $lastComponent, left) { $firstComponent.css('width', left); $divider.css('left', left); $lastComponent.css('left', left); $splitPane.resize(); } function setRight($splitPane, $firstComponent, $divider, $lastComponent, right) { $firstComponent.css('right', right); $divider.css('right', right); $lastComponent.css('width', right); $splitPane.resize(); } })(jQuery);