-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Resize events consolidation and minor resizer bugs (#2079) #2092
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. | ||
|
@@ -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; | ||
|
||
|
@@ -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(); | ||
|
@@ -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(); | ||
}); | ||
|
@@ -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]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason you removed the checks for minSize? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, yeah... I forgot to comment on that. The previous logic was wrong and somehow misleading and I wanted to check with you the best approach to take here. Now that the panels have
There were a couple of issues with 2 before:
Which behavior do you prefer? If it's the second, I could push it along with the rest of review changes or fix it in a separate issue (I'd say that without the checks, the code at least behaves is it says it does) |
||
} | ||
|
||
if (elementPrefs.visible !== undefined && !elementPrefs.visible) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I think of it,
currentSize
may be a better name for this...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
previousSize
is an ok enough name.