Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Commit

Permalink
Merge pull request #2092 from jbalsas/resizer-events
Browse files Browse the repository at this point in the history
Clean up panel resize events; fix bugs with double-clicking to expand/collapse (#2079); fix bug with dragging mouse outside window bounds (##2117)
  • Loading branch information
peterflynn committed Nov 21, 2012
2 parents f4d5070 + 4cdf319 commit b92c2a7
Showing 1 changed file with 80 additions and 54 deletions.
134 changes: 80 additions & 54 deletions src/utils/Resizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ define(function (require, exports, module) {
* before collapse. May occur without any resize events.
* - panelExpanded: When the panel gets expanded (or shown). Passed the initial size.
* May occur without any resize events.
* TODO (#2079): Spurious resize events may occur after collapse or before expand, reporting
* the wrong size. If a panel is currently hidden (display:none), ignore these events.
*
* @param {!DOMNode} element DOM element which should be made resizable.
* @param {!string} direction Direction of the resize action: one of the DIRECTION_* constants.
Expand Down Expand Up @@ -167,11 +165,24 @@ define(function (require, exports, module) {
}
}

function resizeElement(elementSize, contentSize) {
elementSizeFunction.apply($element, [elementSize]);

if ($resizableElement.length) {
contentSizeFunction.apply($resizableElement, [contentSize]);
}
}

$element.data("show", function () {
var elementOffset = $element.offset(),
elementSize = elementSizeFunction.apply($element),
elementSize = elementSizeFunction.apply($element) || elementPrefs.size,
contentSize = contentSizeFunction.apply($resizableElement) || elementPrefs.contentSize,
resizerSize = elementSizeFunction.apply($resizer);


// Resize the element before showing it again. If the panel was collapsed by dragging
// the resizer, the size of the element should be 0, so we restore size in preferences
resizeElement(elementSize, contentSize);

$element.show();
elementPrefs.visible = true;

Expand Down Expand Up @@ -229,18 +240,18 @@ define(function (require, exports, module) {
}

$resizer.on("mousedown", function (e) {
var $resizeCont = $("<div class='resizing-container " + direction + "-resizing' />"),
var $resizeShield = $("<div class='resizing-container " + direction + "-resizing' />"),
startPosition = e[directionProperty],
startSize = $element.is(":visible") ? elementSizeFunction.apply($element) : 0,
newSize = startSize,
previousSize = startSize,
baseSize = 0,
doResize = false,
isMouseDown = true,
resizeStarted = false;

$body.append($resizeCont);
$body.append($resizeShield);

if ($resizableElement !== undefined) {
if ($resizableElement.length) {
$element.children().not(".horz-resizer, .vert-resizer, .resizable-content").each(function (index, child) {
if (direction === DIRECTION_HORIZONTAL) {
baseSize += $(child).outerWidth();
Expand All @@ -250,94 +261,109 @@ define(function (require, exports, module) {
});
}

animationRequest = window.webkitRequestAnimationFrame(function doRedraw() {
function doRedraw() {
// only run this if the mouse is down so we don't constantly loop even
// after we're done resizing.
if (!isMouseDown) {
return;
}

if (doResize) {
// resize the main element to the new size
if ($element.is(":visible")) {
elementSizeFunction.apply($element, [newSize]);

// if there is a content element, its size is the new size
// minus the size of the non-resizable elements
if ($resizableElement !== undefined) {
contentSizeFunction.apply($resizableElement, [newSize - baseSize]);
}
// Check for real size changes to avoid unnecessary resizing and events
if (newSize !== previousSize) {
previousSize = newSize;

if ($element.is(":visible")) {
if (newSize < 10) {
toggle($element);
elementSizeFunction.apply($element, [0]);
} else {
// Trigger resizeStarted just before the first successful resize update
if (!resizeStarted) {
resizeStarted = true;
$element.trigger("panelResizeStart", newSize);
}

// Resize the main element to the new size. If there is a content element,
// its size is the new size minus the size of the non-resizable elements
resizeElement(newSize, (newSize - baseSize));
forceMargins(newSize);

$element.trigger("panelResizeUpdate", [newSize]);
}
} else if (newSize > 10) {
elementSizeFunction.apply($element, [newSize]);
toggle($element);
$element.trigger("panelResizeStart", [elementSizeFunction.apply($element)]);

// Trigger resizeStarted after expanding the element if it was previously collapsed
if (!resizeStarted) {
resizeStarted = true;
$element.trigger("panelResizeStart", newSize);
}
}

// Vertical resize affects editor directly; horizontal resize could change height of top toolbar
EditorManager.resizeEditor();
}

animationRequest = window.webkitRequestAnimationFrame(doRedraw);
});
}

$resizeCont.on("mousemove", function (e) {

// Trigger resizeStarted only if we move the mouse to avoid a resizeStarted event
// when double clicking for collapse/expand functionality
if (!resizeStarted) {
resizeStarted = true;
$element.trigger("panelResizeStart", [elementSizeFunction.apply($element)]);
}

doResize = true;
function onMouseMove(e) {
// calculate newSize adding to startSize the difference
// between starting and current position, capped at minSize
newSize = Math.max(startSize + directionIncrement * (startPosition - e[directionProperty]), minSize);
$element.trigger("panelResizeUpdate", [newSize]);
e.preventDefault();
});

if (animationRequest === null) {
animationRequest = window.webkitRequestAnimationFrame(doRedraw);
}
}

$(window.document).on("mousemove", onMouseMove);

// If the element is marked as collapsible, check for double click
// to toggle the element visibility
if (collapsible) {
$resizeCont.on("mousedown", function (e) {
$resizeShield.on("mousedown", function (e) {
$(window.document).off("mousemove", onMouseMove);
$resizeShield.off("mousedown");
$resizeShield.remove();
animationRequest = null;
toggle($element);
});
}

function endResize(e) {
var elementSize = elementSizeFunction.apply($element);

elementPrefs.size = elementSize;

if (contentSizeFunction) {
elementPrefs.contentSize = contentSizeFunction.apply($resizableElement);
}

if (isMouseDown) {

var elementSize = elementSizeFunction.apply($element);
if ($element.is(":visible")) {
elementPrefs.size = elementSize;
if ($resizableElement.length) {
elementPrefs.contentSize = contentSizeFunction.apply($resizableElement);
}
_prefs.setValue(elementID, elementPrefs);
repositionResizer(elementSize);
}

isMouseDown = false;
repositionResizer(elementSize);
$element.trigger("panelResizeEnd", [elementSize]);
_prefs.setValue(elementID, elementPrefs);

// We wait 100ms to remove the resizer container to capture a mousedown
if (resizeStarted) {
$element.trigger("panelResizeEnd", [elementSize]);
}

// We wait 300ms to remove the resizer container to capture a mousedown
// on the container that would account for double click
window.setTimeout(function () {
$resizeCont.off("mousemove");
$resizeCont.off("mousedown");
$resizeCont.remove();
}, 100);
$(window.document).off("mousemove", onMouseMove);
$resizeShield.off("mousedown");
$resizeShield.remove();
animationRequest = null;
}, 300);
}
}

$resizeCont.one("mouseup", endResize);
$resizeCont.mouseleave(endResize);
$(window.document).one("mouseup", endResize);

e.preventDefault();
});
Expand All @@ -346,11 +372,11 @@ define(function (require, exports, module) {
if (elementPrefs) {

if (elementPrefs.size !== undefined) {
elementSizeFunction.apply($element, [Math.max(elementPrefs.size, minSize)]);
elementSizeFunction.apply($element, [elementPrefs.size]);
}

if (elementPrefs.contentSize !== undefined) {
contentSizeFunction.apply($resizableElement, [Math.max(elementPrefs.contentSize, minSize)]);
contentSizeFunction.apply($resizableElement, [elementPrefs.contentSize]);
}

if (elementPrefs.visible !== undefined && !elementPrefs.visible) {
Expand Down

0 comments on commit b92c2a7

Please sign in to comment.