Closed
Bug 44508
Opened 24 years ago
Closed 22 years ago
[ABS POS][INLINE]Wrong 'top:auto' calculation on absolute "inline"
Categories
(Core :: Layout, defect, P3)
Core
Layout
Tracking
()
VERIFIED
FIXED
mozilla1.2alpha
People
(Reporter: bob_erek, Assigned: MatsPalmgren_bugz)
References
Details
(Keywords: css2, testcase)
Attachments
(4 files, 3 obsolete files)
606 bytes,
text/html
|
Details | |
439 bytes,
text/html
|
Details | |
4.24 KB,
patch
|
dbaron
:
review+
bzbarsky
:
superreview+
|
Details | Diff | Splinter Review |
3.66 KB,
text/html
|
Details |
From Bugzilla Helper: User-Agent: Mozilla/5.0 (Windows; U; WinNT4.0; en-US; m17) Gecko/20000702 BuildID: 2000070208 In the attachment, the <SPAN> element with an absolute position and 'top:auto' is about one line under the correct position. Reproducible: Always Steps to Reproduce: 1.Look the attachment Actual Results: The red '--' is in front of the line after 'THIS' word. Expected Results: The red '--' should to the left of 'THIS' word, at the same level. (see CSS2 specs at 9.8.4, it is the last example) The source code of the attachment: (it is the example of W3C) <P style="position: relative; left: 10px; width: 200px;"> I used two red hyphens to serve as a change bar. They will "float" to the left of the line containing THIS <SPAN style="position: absolute; top: auto; left: -1em; color: red;">--</SPAN> word. Here is some extra text to demonstrate the bug.</P>
Confirming bug, although I think this may be a duplicate. I'm not 100% sure this is a bug. The issue is I think that elements with 'display:inline' and 'position:absolute' have their display property changed to block. The question is whether the 'static-position' that 'auto' turns into refers to the position as if they had 'display: block' or as if they had 'display: inline'.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Wrong 'top:auto' calculation with <SPAN> 'position:absolute' → [ABSPOS][INLINE]Wrong 'top:auto' calculation on absolute "inline"
P3 bugs are getting moved to "future" milestone. They will not be addressed for NS6 RTM.
Status: NEW → ASSIGNED
Target Milestone: --- → Future
Summary: [ABSPOS][INLINE]Wrong 'top:auto' calculation on absolute "inline" → [ABS POS][INLINE]Wrong 'top:auto' calculation on absolute "inline"
Comment 5•24 years ago
|
||
Upon managerial request, adding the "testcase" keyword to 84 open layout bugs that do not have the "testcase" keyword and yet have an attachement with the word "test" in the description field. Apologies for any mistakes.
Keywords: testcase
Comment 7•23 years ago
|
||
In reply to David Baron's note: According to http://www.w3.org/TR/REC-CSS2/visudet.html#abs-non-replaced-height : If 'top' has the value 'auto', replace it with the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its 'position' property had been 'static'. So this is indeed a bug. Also note that the testcase given above appears in the CSS2 spec yet is rendererd incorrectly.
Comment 8•23 years ago
|
||
Build reassigning Buster's bugs to Marc.
Assignee: buster → attinasi
Status: ASSIGNED → NEW
Comment 9•22 years ago
|
||
Reproduced on Linux, marking as platform=ALL,os=ALL (also adding css2 keyword).
Assignee | ||
Comment 10•22 years ago
|
||
Attachment #10970 -
Attachment is obsolete: true
Assignee | ||
Comment 11•22 years ago
|
||
I have a patch that fixes this bug. It also fixes bug 53052 and bug 87712. The problem is that "nsRuleNode::ComputeDisplayData" is resetting 'display' to 'block' for abs. pos. elements (to satisfy CSS2 9.7). This makes the hypothetical box calculation (nsHTMLReflowState::CalculateHypotheticalBox) always calulate it as it were a block.
Target Milestone: Future → ---
Assignee | ||
Comment 12•22 years ago
|
||
Assignee | ||
Comment 13•22 years ago
|
||
The patch saves the original 'display' value just before it is reset to 'block' in nsRuleNode::ComputeDisplayData. The original value is then used to calculate the hypothetical box. Also fixed a bug in CalculateHypotheticalBox() in the case of inlines (this code hasn't been used until now) when the containing block had NS_AUTOHEIGHT. I resorted to the same kind of code as is done for blocks (take the viewport height).
Keywords: patch
Attachment #93444 -
Flags: needs-work+
Comment on attachment 93444 [details] [diff] [review] Patch The parts of the patch that are directly related to this bug look like a good solution, but I'm a bit concerned about some of the other changes. > // Get the placeholder x-offset and y-offset in the coordinate > // space of the block frame that contains it >- GetPlaceholderOffset(aPlaceholderFrame, aBlockFrame, placeholderOffset); >+ aPlaceholderFrame->GetOrigin(placeholderOffset); This change (and the removal of GetPlaceholderOffset) seems wrong. Consider something like <div> This is some text <span>that has an inline element within it that <img style="position: absolute;"> has an absolutely</span> positioned element within it. </div> The following code looks like it needs the coordinate relative to the block. If that's not the case, then you need to change the comments. >@@ -906,19 +866,22 @@ > if (aBlockFrame) { > nsBlockFrame* blockFrame = NS_STATIC_CAST(nsBlockFrame*, aBlockFrame); > >- // We need the immediate child of the block frame, and that may not be >- // the placeholder frame >- nsIFrame *blockChild = FindImmediateChildOf(aBlockFrame, aPlaceholderFrame); >- nsBlockFrame::line_iterator lineBox = blockFrame->FindLineFor(blockChild); >- if (lineBox != blockFrame->end_lines()) { >- // The top of the hypothetical box is just below the line containing >- // the placeholder >- aHypotheticalBox.mTop = lineBox->mBounds.YMost(); >- } else { >+ // Find the YMost of the previous in flow frame >+ nsIFrame *prevInFlow; >+ aPlaceholderFrame->GetPrevInFlow(&prevInFlow); >+ if (nsnull != prevInFlow) { >+ nsBlockFrame::line_iterator lineBox = blockFrame->FindLineFor(prevInFlow); >+ if (lineBox != blockFrame->end_lines()) { >+ aHypotheticalBox.mTop = lineBox->mBounds.YMost(); >+ } else { >+ prevInFlow = nsnull; >+ } >+ } >+ if (nsnull == prevInFlow) { Why did you change this (and remove FindImmediateChildOf)? FindLineFor only searches children (that could be better documented in nsBlockFrame.h, but it can be discovered by following the implementation to nsLineBox::Contains and nsLineBox::IndexOf), and the placeholder (see the example above) need not be a child of the block. > nsPoint placeholderOffset; > > // Just use the placeholder's y-offset >- GetPlaceholderOffset(aPlaceholderFrame, aBlockFrame, placeholderOffset); >+ aPlaceholderFrame->GetOrigin(placeholderOffset); same as before. > aHypotheticalBox.mTop = placeholderOffset.y; > } > } >- if (NS_CSS_FRAME_TYPE_ABSOLUTE == type) { >+ if ((NS_AUTOHEIGHT == aContainingBlockHeight)) { >+ // Use the viewport height as the containing block height >+ const nsHTMLReflowState* rs = cbrs->parentReflowState; >+ while (rs->parentReflowState) { >+ rs = rs->parentReflowState; >+ } >+ aContainingBlockHeight = rs->mComputedHeight; >+ } >+ else if (NS_CSS_FRAME_TYPE_ABSOLUTE == type) { What led you to make this change? It doesn't seem right, but I'm not sure what you were trying to fix.
Comment on attachment 93444 [details] [diff] [review] Patch The parts of the patch that are directly related to this bug look like a good solution, but I'm a bit concerned about some of the other changes. > // Get the placeholder x-offset and y-offset in the coordinate > // space of the block frame that contains it >- GetPlaceholderOffset(aPlaceholderFrame, aBlockFrame, placeholderOffset); >+ aPlaceholderFrame->GetOrigin(placeholderOffset); This change (and the removal of GetPlaceholderOffset) seems wrong. Consider something like <div> This is some text <span>that has an inline element within it that <img style="position: absolute;"> has an absolutely</span> positioned element within it. </div> The following code looks like it needs the coordinate relative to the block. If that's not the case, then you need to change the comments. >@@ -906,19 +866,22 @@ > if (aBlockFrame) { > nsBlockFrame* blockFrame = NS_STATIC_CAST(nsBlockFrame*, aBlockFrame); > >- // We need the immediate child of the block frame, and that may not be >- // the placeholder frame >- nsIFrame *blockChild = FindImmediateChildOf(aBlockFrame, aPlaceholderFrame); >- nsBlockFrame::line_iterator lineBox = blockFrame->FindLineFor(blockChild); >- if (lineBox != blockFrame->end_lines()) { >- // The top of the hypothetical box is just below the line containing >- // the placeholder >- aHypotheticalBox.mTop = lineBox->mBounds.YMost(); >- } else { >+ // Find the YMost of the previous in flow frame >+ nsIFrame *prevInFlow; >+ aPlaceholderFrame->GetPrevInFlow(&prevInFlow); >+ if (nsnull != prevInFlow) { >+ nsBlockFrame::line_iterator lineBox = blockFrame->FindLineFor(prevInFlow); >+ if (lineBox != blockFrame->end_lines()) { >+ aHypotheticalBox.mTop = lineBox->mBounds.YMost(); >+ } else { >+ prevInFlow = nsnull; >+ } >+ } >+ if (nsnull == prevInFlow) { Why did you change this (and remove FindImmediateChildOf)? FindLineFor only searches children (that could be better documented in nsBlockFrame.h, but it can be discovered by following the implementation to nsLineBox::Contains and nsLineBox::IndexOf), and the placeholder (see the example above) need not be a child of the block. > nsPoint placeholderOffset; > > // Just use the placeholder's y-offset >- GetPlaceholderOffset(aPlaceholderFrame, aBlockFrame, placeholderOffset); >+ aPlaceholderFrame->GetOrigin(placeholderOffset); same as before. > aHypotheticalBox.mTop = placeholderOffset.y; > } > } >- if (NS_CSS_FRAME_TYPE_ABSOLUTE == type) { >+ if ((NS_AUTOHEIGHT == aContainingBlockHeight)) { >+ // Use the viewport height as the containing block height >+ const nsHTMLReflowState* rs = cbrs->parentReflowState; >+ while (rs->parentReflowState) { >+ rs = rs->parentReflowState; >+ } >+ aContainingBlockHeight = rs->mComputedHeight; >+ } >+ else if (NS_CSS_FRAME_TYPE_ABSOLUTE == type) { What led you to make this change? It doesn't quite seem right, but I'm not sure what the testcase is that you were trying to fix. Does it affect our conformance to 10.1 of CSS2? Does it affect the way we compute percentage heights?
Assignee | ||
Comment 16•22 years ago
|
||
Assignee | ||
Comment 17•22 years ago
|
||
> This change (and the removal of GetPlaceholderOffset) seems wrong. Consider > something like ... Yep, you are right, I was looking at a more complex testcase involving relative positioned parents (from bug 53052). GetPlaceholderOffset() is back. (see Testcase #2) > Why did you change this (and remove FindImmediateChildOf)? FindLineFor only > searches children ... I still think there is a bug in that code (bug 87712), but I rolled back this part and will make that into a patch for bug 87712 instead. > >- if (NS_CSS_FRAME_TYPE_ABSOLUTE == type) { > >+ if ((NS_AUTOHEIGHT == aContainingBlockHeight)) { > >+ // Use the viewport height as the containing block height > >+ const nsHTMLReflowState* rs = cbrs->parentReflowState; > >+ while (rs->parentReflowState) { > >+ rs = rs->parentReflowState; > >+ } > >+ aContainingBlockHeight = rs->mComputedHeight; > >+ } > >+ else if (NS_CSS_FRAME_TYPE_ABSOLUTE == type) { > > What led you to make this change? It doesn't seem right, but I'm not sure what > you were trying to fix. Well, I saw this assertion in InitAbsoluteConstraints(): ###!!! ASSERTION: containing block height must be constrained: 'containingBlockHeight != NS_AUTOHEIGHT', file nsHTMLReflowState.cpp, line 999 and I thought it was a result of the block->inline change, but it turns out that this assertion is also in the original code. I have removed this part as well (it can be handled in bug 53052 since it was triggered with the testcase there). I looked at all these three bugs at once since I fooled myself into believing they were related. I now think they can be handled separately. New (much simpler) patch coming up. FWIW, it also passes the block regression tests (although positioned elements isn't very stressed in those tests).
Assignee | ||
Comment 18•22 years ago
|
||
Attachment #93444 -
Attachment is obsolete: true
Assignee | ||
Comment 19•22 years ago
|
||
*** Bug 142433 has been marked as a duplicate of this bug. ***
Comment 20•22 years ago
|
||
Hm... could we: 1) Initialize mOriginalDisplay in nsStyleDisplay::nsStyleDisplay() (preferably to some value that should never happen in real life, like "-1" or NS_STYLE_DISPLAY_NONE (dbaron? Thoughts on that?) 2) Assert that the value is not equal to said bogus value in nsHTMLReflowState.cpp 3) Change nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) to properly copy mOriginalDisplay? Other than that, looks good. ;)
Assignee | ||
Comment 21•22 years ago
|
||
Fixed Boris' three points above.
Attachment #93519 -
Attachment is obsolete: true
Assignee | ||
Comment 22•22 years ago
|
||
Comment 23•22 years ago
|
||
Comment on attachment 93711 [details] [diff] [review] Patch rev. 3 sr=bzbarsky
Attachment #93711 -
Flags: superreview+
Comment on attachment 93711 [details] [diff] [review] Patch rev. 3 r=dbaron
Attachment #93711 -
Flags: review+
Updated•22 years ago
|
Target Milestone: --- → Future
Did you need someone to check this in for you?
Target Milestone: Future → ---
Actually....
Assignee: attinasi → mats.palmgren
... it looks like bzbarsky checked this in to the trunk, 2002-08-15 16:00 PDT.
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.2alpha
Assignee | ||
Comment 28•22 years ago
|
||
Verified fixed in 2002-08-20-08 trunk Linux.
Status: RESOLVED → VERIFIED
Comment 29•22 years ago
|
||
Likely bug 59788. I can't reproduce bug 59788 after I can't reproduce this problem.
Assignee | ||
Comment 30•22 years ago
|
||
*** Bug 59788 has been marked as a duplicate of this bug. ***
Comment 31•22 years ago
|
||
My apologies for not commenting in this bug when I checked in the patch...
This exposed an underlying bug: bug 181644.
You need to log in
before you can comment on or make changes to this bug.
Description
•