Closed
Bug 1330962
Opened 6 years ago
Closed 6 years ago
inline-block with a display:block <input> child element has a wrong baseline
Categories
(Core :: Layout: Form Controls, defect, P3)
Core
Layout: Form Controls
Tracking
()
RESOLVED
FIXED
mozilla54
Tracking | Status | |
---|---|---|
firefox54 | --- | fixed |
People
(Reporter: jsnajdr, Assigned: MatsPalmgren_bugz)
References
Details
(Keywords: testcase)
Attachments
(6 files, 3 obsolete files)
3.69 KB,
text/html
|
Details | |
5.46 KB,
patch
|
dholbert
:
review+
|
Details | Diff | Splinter Review |
18.78 KB,
patch
|
Details | Diff | Splinter Review | |
5.55 KB,
patch
|
dholbert
:
review+
|
Details | Diff | Splinter Review |
3.61 KB,
patch
|
dholbert
:
review+
|
Details | Diff | Splinter Review |
4.70 KB,
patch
|
MatsPalmgren_bugz
:
review+
|
Details | Diff | Splinter Review |
Steps to reproduce: This is a UI to register a subdomain for a service: <body> <div style="display:inline-block"> <label>Team URL</label> <input style="display:block;text-align:right" type="text" value="company"></input> </div> <span>.domain.com</span> </body> Expected result: The baselines of the input and the span are aligned on a common baseline, and together form a "company.domain.com" domain name. Actual result: The baselines of the label (Team URL) and the ".domain.com" span are aligned, the UI is broken. Used browser: latest Nightly (FF 53) Chrome and Safari show the expected result, Firefox (and Servo too, by the way) shows the wrong result. I'm not sure what the spec says about this, so it's entirely possible that Firefox behavior is correct and there is a bug in Chrome/Safari. But it's definitely a webcompat issue. I found this issue on a real website (productboard.com). As often happens, developed and tested on Chrome, broken in Firefox.
Assignee | ||
Comment 1•6 years ago
|
||
Looks like Chrome pick up a baseline for a few other controls as well...
Assignee | ||
Updated•6 years ago
|
Has STR: --- → yes
Component: Layout: Block and Inline → Layout: Form Controls
Keywords: testcase
OS: Unspecified → All
Priority: -- → P3
Hardware: Unspecified → All
Summary: Box with an input element child has a wrong baseline → inline-block with a display:block <input> child element has a wrong baseline
Assignee | ||
Updated•6 years ago
|
Assignee: nobody → mats
Assignee | ||
Comment 2•6 years ago
|
||
Attachment #8829035 -
Flags: review?(dholbert)
Assignee | ||
Comment 3•6 years ago
|
||
Attachment #8829036 -
Flags: review?(dholbert)
Assignee | ||
Comment 4•6 years ago
|
||
Attachment #8829038 -
Flags: review?(dholbert)
Assignee | ||
Comment 5•6 years ago
|
||
Attachment #8829039 -
Flags: review?(dholbert)
Assignee | ||
Comment 6•6 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=47b139fbf7850608386593a943ab6bdf9d1985cc
Assignee | ||
Comment 7•6 years ago
|
||
These patches makes us compatible with Chrome for the testcase in the first attachment. Edge is mostly compatible, but it seems they additionally implement baselines for block <textarea>s, but they don't implement baselines for block scroll frames in other cases.
Assignee | ||
Comment 8•6 years ago
|
||
Comment on attachment 8829038 [details] [diff] [review] part 3 - Add baseline methods to nsFieldSetFrame. > + case mozilla::StyleDisplay::Grid: FYI, the reason I'm using the full name here even though we have a "using namespace mozilla" at the top of this file is that GCC fails to compile it without the "mozilla::" prefix. :-(
Updated•6 years ago
|
Attachment #8829039 -
Flags: review?(dholbert) → review+
Comment 10•6 years ago
|
||
Comment on attachment 8829035 [details] [diff] [review] part 1 - Add baseline methods to nsTextControlFrame. Review of attachment 8829035 [details] [diff] [review]: ----------------------------------------------------------------- ::: layout/forms/nsTextControlFrame.cpp @@ +104,5 @@ > #endif > > nsTextControlFrame::nsTextControlFrame(nsStyleContext* aContext) > : nsContainerFrame(aContext) > + , mFirstBaseline(ReflowOutput::ASK_FOR_BASELINE) I'm not sure ASK_FOR_BASELINE is the right meaningful sentinel-value to use here. Right now, it looks like that enum-value *only* has meaning inside of ReflowOutput (that's the only place we set it / check for it, I think). And there, it means "Ask the frame for more details" -- so it's a bit odd that the *frame itself* might also be storing the same sentinel value as its own answer that it might provide. (Odd for the frame to say "ask the frame".) In nsFlexContainerFrame and nsGridContainerFrame, we initialize the equivalent members to NS_INTRINSIC_WIDTH_UNKNOWN. Maybe we should use that same sentinel here? @@ +547,5 @@ > nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight, > wm.IsLineInverted()) + > + aReflowInput.ComputedLogicalBorderPadding().BStart(wm); > + if (MOZ_UNLIKELY(mFirstBaseline == ReflowOutput::ASK_FOR_BASELINE)) { > + mFirstBaseline = ReflowOutput::ASK_FOR_BASELINE - 1; What's going on with this magic "ASK_FOR_BASELINE - 1" value? Perhaps this is just to avoid tripping the MOZ_ASSERT that I noted in the header file, when the author uses bogusly huge sizes that happen to produce this as an actual baseline value? If so: I expect you can get rid of this special case if you adjust the assert as I suggested. (Or if there's some other reason for this, it definitely merits a code comment to explain what's going on...) ::: layout/forms/nsTextControlFrame.h @@ +75,5 @@ > + if (!IsSingleLineTextControl()) { > + return false; > + } > + MOZ_ASSERT(mFirstBaseline != ReflowOutput::ASK_FOR_BASELINE, > + "please call Reflow before asking for the baseline"); Fuzzer testcases can obviously trip this with huge sizes. Let's make this "have we reflowed" check more explicit & unfuzzable, like so: MOZ_ASSERT(!HasAnyStateBits(NS_FRAME_FIRST_REFLOW), "please call Reflow [etc]");
Attachment #8829035 -
Flags: review?(dholbert) → review-
Comment 11•6 years ago
|
||
Comment on attachment 8829036 [details] [diff] [review] part 2 - Add baseline methods to nsHTMLButtonControlFrame. Review of attachment 8829036 [details] [diff] [review]: ----------------------------------------------------------------- ::: layout/forms/nsHTMLButtonControlFrame.cpp @@ +361,5 @@ > + nscoord* aBaseline) const > +{ > + nsIFrame* inner = mFrames.FirstChild(); > + if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM) || > + !inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline))) { This line is too long -- wrap after "aBaselineGroup," perhaps. @@ +366,5 @@ > + return false; > + } > + if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { > + return false; > + } This second early-return is redundant. It's already handled as the first early return here (the first condition of that if-check). So, unless I'm missing something, please drop these last 3 lines. @@ +369,5 @@ > + return false; > + } > + if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { > + // <input type=color> has an empty block frame as inner frame > + *aBaseline = inner-> This is redundant too... This condition is also covered in the first early-return (though with different behavior!). So, this if-check will never be entered right now, IIUC... r- for now, since it looks like something's wrong here.
Attachment #8829036 -
Flags: review?(dholbert) → review-
Comment 12•6 years ago
|
||
Comment on attachment 8829038 [details] [diff] [review] part 3 - Add baseline methods to nsFieldSetFrame. Review of attachment 8829038 [details] [diff] [review]: ----------------------------------------------------------------- r=me with GetParent() calls removed (or explained) as noted below ::: layout/forms/nsFieldSetFrame.cpp @@ +651,5 @@ > + MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM)); > + if (!inner->GetVerticalAlignBaseline(aWM, aBaseline)) { > + return false; > + } > + nscoord innerBStart = inner->BStart(aWM, GetParent()->GetSize()); I'm pretty sure you really want to drop the GetParent() here. (so just pass in "GetSize()", not "GetParent()->GetSize()".) The inner frame's position is represented (in its mRect) with respect to *our* origin, AFAICT -- it's an offset from the nsFieldSetFrame's origin, not the nsFieldSetFrame's parent's origin. So that means we should be passing the nsFieldSetFrame's size into this inner->BStart method, so that it can subtract from that size in the unlikely event that it needs to flip the representation to correct for writing-mode antiparallelism. @@ +666,5 @@ > + MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM)); > + if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { > + return false; > + } > + nscoord innerBStart = inner->BStart(aWM, GetParent()->GetSize()); Same here -- I don't think you want the GetParent() call here.
Attachment #8829038 -
Flags: review?(dholbert) → review+
Assignee | ||
Comment 13•6 years ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #10) > Fuzzer testcases can obviously trip this with huge sizes. Let's make this > "have we reflowed" check more explicit & unfuzzable, like so: > MOZ_ASSERT(!HasAnyStateBits(NS_FRAME_FIRST_REFLOW), > "please call Reflow [etc]"); Unfortunately, NS_FRAME_FIRST_REFLOW is only set once and never again, so this has limited value. Using a sentinel value is better, especially if we reset it in MarkIntrinsicISizesDirty(), which I forgot in the first version. Yes, this can give false positives with nscoord overflows, so I've made it non-fatal.
Assignee | ||
Comment 14•6 years ago
|
||
Attachment #8829035 -
Attachment is obsolete: true
Attachment #8830502 -
Flags: review?(dholbert)
Assignee | ||
Comment 15•6 years ago
|
||
> This second early-return is redundant.
Good catch, but it was actually the first chunk that I forgot to remove.
(I'll add some tests that would have caught that eventually, but that
needs some baseline call tweaks in Grid or Flexbox first I think.)
Attachment #8829036 -
Attachment is obsolete: true
Attachment #8830503 -
Flags: review?(dholbert)
Assignee | ||
Comment 16•6 years ago
|
||
> I'm pretty sure you really want to drop the GetParent() here.
Right, I actually saw that too, but figured I should just keep it
as is for now before I had a chance to investigate it.
nsFieldSetFrame layout is pretty weird after all. :-)
But since you agree, let's just fix that and hope we're right.
Attachment #8829038 -
Attachment is obsolete: true
Attachment #8830505 -
Flags: review+
Updated•6 years ago
|
Attachment #8830502 -
Flags: review?(dholbert) → review+
Updated•6 years ago
|
Attachment #8830503 -
Flags: review?(dholbert) → review+
Comment 17•6 years ago
|
||
Pushed by mpalmgren@mozilla.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/cc7508381dc1 part 1 - Add baseline methods to nsTextControlFrame. r=dholbert https://hg.mozilla.org/integration/mozilla-inbound/rev/0b92b30ed1d3 part 2 - Add baseline methods to nsHTMLButtonControlFrame. r=dholbert https://hg.mozilla.org/integration/mozilla-inbound/rev/2394701998b2 part 3 - Add baseline methods to nsFieldSetFrame. r=dholbert https://hg.mozilla.org/integration/mozilla-inbound/rev/8cfebee598a6 part 4 - Cleanup some #includes and make nsLegendFrame 'final'. r=dholbert https://hg.mozilla.org/integration/mozilla-inbound/rev/71c277105903 part 5 - Reftests for baseline alignment of various form controls.
Comment 18•6 years ago
|
||
Backed out in https://hg.mozilla.org/integration/mozilla-inbound/rev/df2eaf826663 for fairly comprehensible Windows no-accel failures like https://treeherder.mozilla.org/logviewer.html#?job_id=72785378&repo=mozilla-inbound and incomprehensible Android debug failures like https://treeherder.mozilla.org/logviewer.html#?job_id=72774970&repo=mozilla-inbound
Assignee | ||
Comment 19•6 years ago
|
||
> for fairly comprehensible Windows no-accel failures ... Some anti-aliasing differences that I missed because they didn't show up in my Try run (comment 6) because "-p all" apparently doesn't include Win8. > ... and incomprehensible Android debug failures Yeah, that failure is unrelated to the code changes, but the failure comes from adding the new reftests. Here's a Try run with only part 5 (the tests) that also fails in layout/reftests/bugs/315920-17.html : https://treeherder.mozilla.org/#/jobs?repo=try&revision=512b79c26c636f20f4d7675286df8c4943086337&exclusion_profile=false&selectedJob=72824028 I'm guessing adding the new tests changes the reftest chunks somehow.
Assignee | ||
Comment 20•6 years ago
|
||
layout/reftests/bugs/315920-17.html is the very first test in R15 in the Try run above.
Assignee | ||
Comment 21•6 years ago
|
||
I don't see any obvious focus dependencies in that test, but I added a "needs-focus" anyway to see if it helps: https://treeherder.mozilla.org/#/jobs?repo=try&revision=9922b3dfd5b0b8c1641b8a94418f84f63a76362e
Assignee | ||
Comment 22•6 years ago
|
||
Nope, same failure. OK, let's try "MozReftestInvalidate" instead of "onload" then: https://treeherder.mozilla.org/#/jobs?repo=try&revision=be592c00cbc062c295bee9a612c141a2a62f9ed8
Comment 23•6 years ago
|
||
(In reply to Mats Palmgren (:mats) from comment #19) > "-p all" apparently doesn't include Win8. -p all does, it's -u reftest that doesn't. I think the least typing which currently does include Win8, without excluding anything else and without running things known to be broken for trunk pushes, is something like -u reftest[-10.6,-Windows XP]. - to negate a filter (when it is the first filter) has the magic property of including all non-default platforms, so before we started breaking platforms on the trunk it was -u reftest[-goats], but now you don't want to have to see the burning 10.6 and WinXP jobs that would produce.
Assignee | ||
Comment 24•6 years ago
|
||
Thanks for the tip! I'll use that henceforth when I want "all" reftests.
Assignee | ||
Comment 25•6 years ago
|
||
The "MozReftestInvalidate" fix solved the layout/reftests/bugs/315920-17.html failure. Hmm, it's kind of odd that it only needs that when it's the first test in the chunk. Now let's see if switching to an Ahem font helps the anti-aliasing issue on Windows: https://treeherder.mozilla.org/#/jobs?repo=try&revision=62a6a67a0c481b7cccf1defc749f48abeec54b22
Comment 26•6 years ago
|
||
Pushed by mpalmgren@mozilla.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/e5318543f3e1 part 1 - Add baseline methods to nsTextControlFrame. r=dholbert https://hg.mozilla.org/integration/mozilla-inbound/rev/095a98547a79 part 2 - Add baseline methods to nsHTMLButtonControlFrame. r=dholbert https://hg.mozilla.org/integration/mozilla-inbound/rev/24b45bba9d5c part 3 - Add baseline methods to nsFieldSetFrame. r=dholbert https://hg.mozilla.org/integration/mozilla-inbound/rev/f1588f6e50d2 part 4 - Cleanup some #includes and make nsLegendFrame 'final'. r=dholbert https://hg.mozilla.org/integration/mozilla-inbound/rev/f0acc072ee76 part 5 - Reftests for baseline alignment of various form controls. https://hg.mozilla.org/integration/mozilla-inbound/rev/b222ec9a5d90 part 6 - Start this test using MozReftestInvalidate rather than onload.
Comment 27•6 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/e5318543f3e1 https://hg.mozilla.org/mozilla-central/rev/095a98547a79 https://hg.mozilla.org/mozilla-central/rev/24b45bba9d5c https://hg.mozilla.org/mozilla-central/rev/f1588f6e50d2 https://hg.mozilla.org/mozilla-central/rev/f0acc072ee76 https://hg.mozilla.org/mozilla-central/rev/b222ec9a5d90
Status: NEW → RESOLVED
Closed: 6 years ago
status-firefox54:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla54
You need to log in
before you can comment on or make changes to this bug.
Description
•