I understand why now. Not that I was wrong. But I understand now why not many people, even possibly no one, saw the problem.
Unless I'm totally wrong of course, there is a big flaw in the dialog resizing method. But for it to become apparent, a few conditions must be met. Nothing extraordinary.
The biggest problem stems from the logic used. The method is tracking the mouse one pixel at a time, and depending on the computer's speed and the mouse's speed, the size adjustments are always calculated between two consecutive positions. This means that size adjustments of a single pixel are frequent. And this is a problem.
It is a problem because... the element's initial height is derived from its offsetHeight property. Then it's adjusted by subtracting margin and border widths. BUT, and here lies the problem, it is assumed that these are integral values. The method making the adjustment (domhandler.js#getHeight) neglects to take into account that widths may be set in other units, which may result in fractional pixel dimensions.
Imagine a padding value in em's resulting in 7.7px. When the padding width is treated as an integer, we obtain 14px total for top and bottom, with an error of 1.4px. And the adjustment we're making is just 1px. The error in measuring the current height is greater than the adjustment we're making. And when you try to shrink the window, it can grow uncontrollably larger instead.
The solution to this problem is to correct the DomHandler.getHeight method as follows:
Code: Select all
DomHandler.prototype.getHeight = function (el) {
var height = el.offsetHeight;
var style = getComputedStyle(el);
// height -= parseInt(style.paddingTop) + parseInt(style.paddingBottom) + parseInt(style.borderTopWidth) + parseInt(style.borderBottomWidth); // remove this line
height -= parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) + parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); // use this instead
return height;
};
I'm using a library that sets the CSS property box-sizing to 'border-box'. When the height is set, it is assumed by the Dialog#onResize method that setting the height sets a dimension excluding padding and border. But if box-sizing is set to 'border-box', adjusting for border and padding is not necessary.
With another change to DomHandler#getHeight, the problem goes away:
Code: Select all
DomHandler.prototype.getHeight = function (el) {
var height = el.offsetHeight;
var style = getComputedStyle(el);
if (style.boxSizing == 'content-box') { // make height adjustment conditional
height -= parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) + parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
}
return height;
};
Code: Select all
div.ui-widget div.ui-widget-content
box-sizing: content-box!important
In any event, the parseInt problem needs to be fixed. Or the logic should be changed to something like the one I proposed in a previous post on this topic. I proposed to recalculate the size relative to the initial size when resizing started, not using a delta between two consecutive positions. Fractional pixel errors do not accumulate and are negligible with this logic.