Bug 170095 - [testcase] Absolutely positioned boxes in inlines: positioning at top right
Summary: [testcase] Absolutely positioned boxes in inlines: positioning at top right
Status: VERIFIED FIXED
Alias: None
Product: konqueror
Classification: Applications
Component: khtml (show other bugs)
Version: 4.1.0
Platform: Microsoft Windows Microsoft Windows
: NOR normal
Target Milestone: ---
Assignee: Konqueror Developers
URL: http://www.hixie.ch/tests/adhoc/css/b...
Keywords:
Depends on:
Blocks:
 
Reported: 2008-08-30 19:40 UTC by Gérard Talbot (no longer involved)
Modified: 2008-12-06 20:49 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
implement CSS2.1 - 10.1.4.1 (5.17 KB, patch)
2008-08-31 05:25 UTC, Germain Garand
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Gérard Talbot (no longer involved) 2008-08-30 19:40:45 UTC
Testcase:
http://www.hixie.ch/tests/adhoc/css/box/absolute/inline/004.html

Relevant code:

  .test { position: relative; }
  .absolute { color: white; background: green; position: absolute; top: 0; right: 0; }
  .fail { color: yellow; background: red; }
   
(...)
<span class="test"><span class="absolute">PASSED</span><span class="fail">FAILED</span></span>
(...)

The <span class="absolute"> box should have overlapped, masked the <span class="fail">

Internet Explorer 7, Internet Explorer 8 beta 2, Firefox 3, Opera 9.50, Safari 3.1.2 all pass this test.

Regards, Gérard
Comment 1 Germain Garand 2008-08-31 05:25:29 UTC
Created attachment 27147 [details]
implement CSS2.1 - 10.1.4.1
Comment 2 Germain Garand 2008-08-31 17:12:32 UTC
SVN commit 855323 by ggarand:

properly compute width of containing block of inline elements
as per CSS 2.1 - 10.1.4.1

BUG: 170095


 M  +30 -12    render_box.cpp  
 M  +1 -1      render_box.h  
 M  +2 -2      render_object.cpp  
 M  +2 -2      render_object.h  


--- trunk/KDE/kdelibs/khtml/rendering/render_box.cpp #855322:855323
@@ -789,7 +789,7 @@
     setNeedsLayoutAndMinMaxRecalc();
 }
 
-short RenderBox::containingBlockWidth() const
+short RenderBox::containingBlockWidth(RenderObject* providedCB) const
 {
     if (isCanvas() && canvas()->view())
     {
@@ -799,18 +799,36 @@
             return canvas()->view()->visibleWidth();
     }
 
-    RenderBlock* cb = containingBlock();
+    RenderObject* cb = providedCB ? providedCB : containingBlock();
     if (isRenderBlock() && cb->isTable() && static_cast<RenderTable*>(cb)->caption() == this) {
         //captions are not affected by table border or padding
         return cb->width();
     }
-    if (isPositioned())
-        // cf. 10.1.4.2 - use padding edge
-        // ### FIXME: still wrong for inline CBs - 10.1.4.1
+    if (isPositioned()) {
+        // cf. 10.1.4 - use padding edge
+        if (cb->isInlineFlow()) {
+            // 10.1.4.1
+            int l, r;
+            InlineFlowBox* firstLineBox = static_cast<const RenderFlow*>(cb)->firstLineBox();
+            InlineFlowBox* lastLineBox = static_cast<const RenderFlow*>(cb)->lastLineBox();
+            if (!lastLineBox)
+                return 0;
+            if (cb->style()->direction() == RTL) {
+                l = lastLineBox->xPos() + lastLineBox->borderLeft();
+                r = firstLineBox->xPos() + firstLineBox->width() - firstLineBox->borderRight();
+            } else {
+                l = firstLineBox->xPos() + firstLineBox->borderLeft();
+                r = lastLineBox->xPos() + lastLineBox->width() - lastLineBox->borderRight();
+            }
+            return qMax(0, r-l);
+        }    
+        // 10.1.4.2
         return cb->contentWidth() + cb->paddingLeft() + cb->paddingRight();
-    else if (usesLineWidth())
-        return cb->lineWidth(m_y);
-    else
+    }
+    else if (usesLineWidth()) {
+        assert( cb->isRenderBlock() );
+        return static_cast<RenderBlock*>(cb)->lineWidth(m_y);
+    } else
         return cb->contentWidth();
 }
 
@@ -1466,9 +1484,9 @@
 
     // We don't use containingBlock(), since we may be positioned by an enclosing
     // relative positioned inline.
-    const RenderObject* containerBlock = container();
+    RenderObject* containerBlock = container();
 
-    const int containerWidth = containingBlockWidth();
+    const int containerWidth = containingBlockWidth(containerBlock);
 
     // To match WinIE, in quirks mode use the parent's 'direction' property
     // instead of the the container block's.
@@ -1982,9 +2000,9 @@
     // the numbers correspond to numbers in spec)
 
     // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
-    const RenderObject* containerBlock = container();
+    RenderObject* containerBlock = container();
 
-    const int containerWidth = containingBlockWidth();
+    const int containerWidth = containingBlockWidth(containerBlock);
 
     // To match WinIE, in quirks mode use the parent's 'direction' property
     // instead of the the container block's.
--- trunk/KDE/kdelibs/khtml/rendering/render_box.h #855322:855323
@@ -96,7 +96,7 @@
 
     virtual void repaintRectangle(int x, int y, int w, int h, Priority p=NormalPriority, bool f=false);
 
-    virtual short containingBlockWidth() const;
+    virtual short containingBlockWidth(RenderObject* providedCB=0) const;
     void relativePositionOffset(int &tx, int &ty) const;
 
     virtual void calcWidth();
--- trunk/KDE/kdelibs/khtml/rendering/render_object.cpp #855322:855323
@@ -788,13 +788,13 @@
     return static_cast<RenderBlock*>( o );
 }
 
-short RenderObject::containingBlockWidth() const
+short RenderObject::containingBlockWidth(RenderObject*) const
 {
     // ###
     return containingBlock()->contentWidth();
 }
 
-int RenderObject::containingBlockHeight() const
+int RenderObject::containingBlockHeight(RenderObject*) const
 {
     // ###
     return containingBlock()->contentHeight();
--- trunk/KDE/kdelibs/khtml/rendering/render_object.h #855322:855323
@@ -567,9 +567,9 @@
     RenderBlock *containingBlock() const;
 
     // return just the width of the containing block
-    virtual short containingBlockWidth() const;
+    virtual short containingBlockWidth(RenderObject* providedCB=0) const;
     // return just the height of the containing block
-    virtual int containingBlockHeight() const;
+    virtual int containingBlockHeight(RenderObject* providedCB=0) const;
 
     // size of the content area (box size minus padding/border)
     virtual short contentWidth() const { return 0; }
Comment 3 Gérard Talbot (no longer involved) 2008-12-06 20:49:21 UTC
Konqueror 4.1.2 passes the test.

Marking as VERIFIED