+2018-03-28 Zalan Bujtas <zalan@apple.com>
+
+ [LayoutReloaded] Convert floating left/right stack display boxes absolute to the formatting context's root.
+ https://bugs.webkit.org/show_bug.cgi?id=184123
+
+ Reviewed by Antti Koivisto.
+
+ 1. The left/right floating array should hold the Display.Box (and not the Layout.Box)
+ 2. Clone the Display.Box and convert its rect absolute to the formatting context's root so that we
+ don't have to keep converting the coordinates while computing the positions.
+
+ * LayoutReloaded/DisplayTree/Box.js:
+ (Display.Box.prototype.clone):
+ (Display.Box.prototype.setRect):
+ * LayoutReloaded/FormattingContext/FloatingContext.js:
+ (FloatingContext.prototype.computePosition):
+ (FloatingContext.prototype._positionForFloating):
+ (FloatingContext.prototype._addFloating):
+ (FloatingContext.prototype._moveToNextVerticalPosition):
+ (FloatingContext.prototype._availableSpace):
+ (FloatingContext.prototype._findFloatingAtVerticalPosition):
+ (FloatingContext.prototype._adjustedFloatingPosition):
+ (FloatingContext.prototype._bottom):
+
2018-03-28 Chris Dumez <cdumez@apple.com>
Unreviewed iOS build fix after r230060.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// All geometry here is absolute to the formatting context's root.
class FloatingContext {
constructor(formattingContext) {
this.m_leftFloatingBoxStack = new Array();
return;
let displayBox = this._formattingContext().displayBox(layoutBox);
if (layoutBox.isFloatingPositioned()) {
- let position = this._positionForFloating(layoutBox);
+ displayBox.setTopLeft(this._positionForFloating(layoutBox));
this._addFloating(layoutBox);
- return displayBox.setTopLeft(position);
+ return;
}
if (Utils.hasClear(layoutBox))
return displayBox.setTopLeft(this._positionForClear(layoutBox));
}
_positionForFloating(floatingBox) {
+ let absoluteFloatingBox = this._formattingContext().absoluteMarginBox(floatingBox);
if (this._isEmpty())
- return this._adjustedFloatingPosition(floatingBox, this._formattingContext().absoluteMarginBox(floatingBox).top());
- let verticalPosition = Math.max(this._formattingContext().absoluteMarginBox(floatingBox).top(), this._formattingContext().absoluteMarginBox(this.m_lastFloating).top());
- let spaceNeeded = this._formattingContext().absoluteMarginBox(floatingBox).width();
+ return this._adjustedFloatingPosition(floatingBox, absoluteFloatingBox.top());
+ let verticalPosition = Math.max(absoluteFloatingBox.top(), this.m_lastFloating.top());
+ let spaceNeeded = absoluteFloatingBox.width();
while (true) {
let floatingPair = this._findInnerMostLeftAndRight(verticalPosition);
if (this._availableSpace(floatingBox.containingBlock(), floatingPair) >= spaceNeeded)
}
_addFloating(floatingBox) {
- this.m_lastFloating = floatingBox;
+ // Convert floating box to absolute.
+ let floatingDisplayBox = this._formattingContext().displayBox(floatingBox).clone();
+ floatingDisplayBox.setRect(this._formattingContext().absoluteMarginBox(floatingBox));
+ this.m_lastFloating = floatingDisplayBox;
if (Utils.isFloatingLeft(floatingBox)) {
- this.m_leftFloatingBoxStack.push(floatingBox);
+ this.m_leftFloatingBoxStack.push(floatingDisplayBox);
return;
}
- this.m_rightFloatingBoxStack.push(floatingBox);
+ this.m_rightFloatingBoxStack.push(floatingDisplayBox);
}
_findInnerMostLeftAndRight(verticalPosition) {
let leftBottom = Number.POSITIVE_INFINITY;
let rightBottom = Number.POSITIVE_INFINITY;
if (floatingPair.left)
- leftBottom = this._formattingContext().absoluteMarginBox(floatingPair.left).bottom();
+ leftBottom = floatingPair.left.bottom();
if (floatingPair.right)
- rightBottom = this._formattingContext().absoluteMarginBox(floatingPair.right).bottom();
+ rightBottom = floatingPair.right.bottom();
return Math.min(leftBottom, rightBottom);
}
_availableSpace(containingBlock, floatingPair) {
let containingBlockContentBox = this._formattingContext().displayBox(containingBlock);
if (floatingPair.left && floatingPair.right)
- return this._formattingContext().absoluteMarginBox(floatingPair.right).left() - this._formattingContext().absoluteMarginBox(floatingPair.left).right();
+ return floatingPair.right.left() - floatingPair.left.right();
if (floatingPair.left)
- return containingBlockContentBox.width() - (this._formattingContext().absoluteMarginBox(floatingPair.left).right() - this._formattingContext().absoluteBorderBox(containingBlock).left());
+ return containingBlockContentBox.width() - (floatingPair.left.right() - this._formattingContext().absoluteBorderBox(containingBlock).left());
if (floatingPair.right)
- return this._formattingContext().absoluteMarginBox(floatingPair.right).left();
+ return floatingPair.right.left();
return containingBlockContentBox.width();
}
_findFloatingAtVerticalPosition(verticalPosition, floatingStack) {
let index = floatingStack.length;
- while (--index >= 0 && this._formattingContext().absoluteMarginBox(floatingStack[index]).bottom() <= verticalPosition);
+ while (--index >= 0 && floatingStack[index].bottom() <= verticalPosition);
return index >= 0 ? floatingStack[index] : null;
}
let right = this._formattingContext().absoluteContentBox(containingBlock).right();
if (leftRightFloatings) {
if (leftRightFloatings.left) {
- let floatingBoxRight = this._formattingContext().absoluteMarginBox(leftRightFloatings.left).right();
+ let floatingBoxRight = leftRightFloatings.left.right();
if (floatingBoxRight > left)
left = floatingBoxRight;
}
if (leftRightFloatings.right) {
- let floatingBoxLeft = this._formattingContext().absoluteMarginBox(leftRightFloatings.right).left();
+ let floatingBoxLeft = leftRightFloatings.right.left();
if (floatingBoxLeft < right)
right = floatingBoxLeft;
}
return Number.NaN;
let max = Number.NEGATIVE_INFINITY;
for (let i = 0; i < floatingStack.length; ++i)
- max = Math.max(this._formattingContext().absoluteMarginBox(floatingStack[i]).bottom(), max);
+ max = Math.max(floatingStack[i].bottom(), max);
return max;
}