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
Created attachment 27147 [details] implement CSS2.1 - 10.1.4.1
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; }
Konqueror 4.1.2 passes the test. Marking as VERIFIED