[LayoutReloaded] Ensure that positioning happens within the formatting context
[WebKit-https.git] / Tools / LayoutReloaded / LayoutTree / Box.js
index 056b08a7b0ac701467df59149559e06bf6e26a8a..d8ed8a80d7ee3106b52f57bc732118280743d6e3 100644 (file)
@@ -23,7 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-class Box {
+var Layout = { }
+
+Layout.Box = class Box {
     constructor(node, id) {
         this.m_id = id;
         this.m_rendererName = null;
@@ -32,8 +34,8 @@ class Box {
         this.m_nextSibling = null;
         this.m_previousSibling = null;
         this.m_isAnonymous = false;
-        this.m_rect = new LayoutRect(new LayoutPoint(0, 0), new LayoutSize(0, 0));
         this.m_establishedFormattingContext = null;
+        this.m_displayBox = null;
     }
 
     id() {
@@ -96,8 +98,18 @@ class Box {
         this.m_previousSibling = previousSibling;
     }
 
+    setDisplayBox(displayBox) {
+        ASSERT(!this.m_displayBox);
+        this.m_displayBox = displayBox;
+    }
+
+    displayBox() {
+        ASSERT(this.m_displayBox);
+        return this.m_displayBox;
+    }
+
     rect() {
-        return this.m_rect.clone();
+        return this.displayBox().rect();
     }
 
     topLeft() {
@@ -109,19 +121,19 @@ class Box {
     }
 
     setTopLeft(topLeft) {
-        this.m_rect.setTopLeft(topLeft);
+        this.displayBox().setTopLeft(topLeft);
     }
 
     setSize(size) {
-        this.m_rect.setSize(size);
+        this.displayBox().setSize(size);
     }
 
     setWidth(width) {
-        this.m_rect.setWidth(width);
+        this.displayBox().setWidth(width);
     }
 
     setHeight(height) {
-        this.m_rect.setHeight(height);
+        this.displayBox().setHeight(height);
     }
 
     isContainer() {
@@ -165,7 +177,7 @@ class Box {
         // Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions)
         // that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport)
         // establish new block formatting contexts for their contents.
-        return this.isFloatingPositioned() || this.isAbsolutePositioned() || (this.isBlockContainerBox() && !this.isBlockLevelBox())
+        return this.isFloatingPositioned() || this.isAbsolutelyPositioned() || (this.isBlockContainerBox() && !this.isBlockLevelBox())
             || (this.isBlockLevelBox() && !Utils.isOverflowVisible(this));
     }
 
@@ -174,15 +186,15 @@ class Box {
     }
 
     isPositioned() {
-        return this.isOutOfFlowPositioned() || this.isRelativePositioned();
+        return this.isOutOfFlowPositioned() || this.isRelativelyPositioned();
     }
 
-    isRelativePositioned() {
-        return Utils.isRelativePositioned(this);
+    isRelativelyPositioned() {
+        return Utils.isRelativelyPositioned(this);
     }
 
-    isAbsolutePositioned() {
-        return Utils.isAbsolutePositioned(this);
+    isAbsolutelyPositioned() {
+        return Utils.isAbsolutelyPositioned(this) || this.isFixedPositioned();
     }
 
     isFixedPositioned() {
@@ -196,7 +208,7 @@ class Box {
     }
 
     isOutOfFlowPositioned() {
-        return this.isAbsolutePositioned() || this.isFixedPositioned();
+        return this.isAbsolutelyPositioned() || this.isFixedPositioned();
     }
 
     isInFlowPositioned() {
@@ -211,7 +223,7 @@ class Box {
         return this.isFloatingPositioned() || this.isOutOfFlowPositioned();
     }
 
-    isRootElement() {
+    isRootBox() {
         // FIXME: This should just be a simple instanceof check, but we are in the mainframe while the test document is in an iframe
         // Let's just return root for both the RenderView and the <html> element.
         return !this.parent() || !this.parent().parent();
@@ -222,34 +234,31 @@ class Box {
             return null;
         if (!this.isPositioned() || this.isInFlowPositioned())
             return this.parent();
-        let parent = this.parent();
-        while (parent.parent()) {
-            if (this.isAbsolutePositioned() && parent.isPositioned())
-                return parent;
-            parent = parent.parent();
+        if (this.isAbsolutelyPositioned() && !this.isFixedPositioned()) {
+            let ascendant = this.parent();
+            while (ascendant.parent() && !ascendant.isPositioned())
+                ascendant = ascendant.parent();
+            return ascendant;
+        }
+        if (this.isFixedPositioned()) {
+            let ascendant = this.parent();
+            while (ascendant.parent())
+                ascendant = ascendant.parent();
+            return ascendant;
         }
-        return parent;
+        ASSERT_NOT_REACHED();
+        return null;
     }
 
     borderBox() {
-        return new LayoutRect(new LayoutPoint(0, 0), this.rect().size());
+        return this.displayBox().borderBox();
     }
 
     paddingBox() {
-        let paddingBox = this.borderBox();
-        let borderSize = Utils.computedBorderTopLeft(this);
-        paddingBox.moveBy(borderSize);
-        paddingBox.shrinkBy(borderSize);
-        paddingBox.shrinkBy(Utils.computedBorderBottomRight(this));
-        return paddingBox;
+        return this.displayBox().paddingBox();
     }
 
     contentBox() {
-        let contentBox = this.paddingBox();
-        let paddingSize = Utils.computedPaddingTopLeft(this);
-        contentBox.moveBy(paddingSize);
-        contentBox.shrinkBy(paddingSize);
-        contentBox.shrinkBy(Utils.computedPaddingBottomRight(this));
-        return contentBox;
+        return this.displayBox().contentBox();
     }
 }