Closed Bug 1127107 Opened 10 years ago Closed 10 years ago

"white-space: nowrap" and "pre" are nerfed (i.e. lines get wrapped) when combined with "-moz-hyphens: auto; word-break: break-all;"

Categories

(Core :: Layout: Text and Fonts, defect)

x86_64
Linux
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla38

People

(Reporter: dholbert, Assigned: jfkthame)

References

Details

(Keywords: testcase)

Attachments

(5 files)

Attached file testcase 1 (deleted) —
STR: 1. Load attached testcase. EXPECTED RESULTS: No wrapping (I think). ACTUAL RESULTS: Wrapping. The testcase has a fixed-width <div> with: white-space: nowrap; -moz-hyphens: auto; word-break: break-all; I'd expect "white-space: nowrap" to prevent wrapping here. (see discussion below). However, when combined with *both* of the other two declarations, we end up wrapping at the right edge of the div. (You need *both* declarations, -moz-hyphens *and* word-break, to trigger this issue. If I only include one or the other of those, then I get EXPECTED RESULTS.) DISCUSSION: The CSS Text 3 spec says: > [...] like 'pre', it does not allow wrapping. http://dev.w3.org/csswg/css-text-3/#valdef-white-space-nowrap ...and the chunk of the 'pre' definition that it's referring to is (I think): > Lines only break at forced line breaks; content that > does not fit within the block container overflows it. http://dev.w3.org/csswg/css-text-3/#valdef-white-space-pre In that definition, "forced line breaks" is linkified to this chunk: http://dev.w3.org/csswg/css-text-3/#forced-line-break ...which explains that "forced lines breaks" are distinct from "soft line breaks". And the "word-break" & "hyphens" properties are each defined as creating "soft wrap opportunities". http://dev.w3.org/csswg/css-text-3/#word-break-property http://dev.w3.org/csswg/css-text-3/#hyphens-property So I don't think these properties should introduce any "forced breaks", which (per white-space:pre text quoted above definition) means there shouldn't be any breaks in this testcase, AFAICT. Neither IE nor Chrome have linebreaks in this testcase.
Attached video screencast.ogv (deleted) —
This bug seems to be responsible for text wrapping (instead of overflowing and ellipsisizing) at http://music.baidu.com/rings -- screencast attached, showing me disabling both "-moz-hyphens: auto" decls that affect the element. This fixes their layout and lets their desired ellipsizing happen. (Note: this site only loads if you have a mobile UA -- I'm using the User Agent Overrider extension's "Firefox 29 for Android" UA. With a desktop UA, I just get a 404.) This is our #2 fixlist site for mainland china, according to bug 1107378 comment 4.
(In reply to Daniel Holbert [:dholbert] from comment #1) > This is our #2 fixlist site for mainland china, according to bug 1107378 > comment 4. (Though I suspect the issues that got it on the fixlist may have been unrelated, worse problems that are now fixed [I think])
Attached file testcase 2 (with "white-space: pre") (deleted) —
Here's a testcase with "white-space: pre" to show that that's affected, too. There are no forced linebreaks in the <div> here, and yet we wrap eagerly.
For thoroughness' sake: I'm using Nightly 38.0a1 (2015-01-28), and it goes back at least as far as Nightly 20.0a1 (2013-01-01) -- so it's not a recent regression. I'm betting it was introduced when bug 253317 added "-moz-hyphens" support. (I did confirm that a build before that -- Minefield 4.09b13pre (2011-03-18) gives EXPECTED RESULTS.) (I tried a few other intermediate builds just for fun, but a lot of old builds hit startup crashes these days, for some reason; probably a library mismatch or something.)
Depends on: 253317
Keywords: testcase
I think I see the problem: the equality test at [1] is broken due to the addition of the BREAK_USE_AUTO_HYPHENATION flag, which should be ignored there. I'll post a patch in a while, after testing whether it breaks other stuff....
(In reply to Jonathan Kew (:jfkthame) from comment #5) > I think I see the problem: the equality test at [1] is broken due to the > addition of the BREAK_USE_AUTO_HYPHENATION flag, which should be ignored > there. Oops.... [1] there was meant to refer to [1] http://mxr.mozilla.org/mozilla-central/source/dom/base/nsLineBreaker.cpp#197
Inspecting the code reveals that it's not only "-moz-hyphens:auto" that will trigger this incorrect wrapping. You can get a similar effect by applying "text-transform:capitalize": data:text/html,<div style="width:100px;white-space:nowrap;word-break:break-all; text-transform:capitalize">this text is not supposed to wrap Fixing this as well, without breaking the text-transform behavior, is going to add a few more lines to the necessary patch. Re-testing...
Assignee: nobody → jfkthame
Status: NEW → ASSIGNED
I believe reftests are all happy with the patch above, but I've started a try run to double-check: https://treeherder.mozilla.org/#/jobs?repo=try&revision=dd8e0a48d189
Attachment #8556587 - Flags: review?(dholbert) → review+
Comment on attachment 8556586 [details] [diff] [review] The presence of hyphens:auto and/or text-transform:capitalize should not affect no-wrap behavior Thanks for the quick action on this! >diff --git a/dom/base/nsLineBreaker.cpp b/dom/base/nsLineBreaker.cpp [...] > >+#define NO_BREAKS_NEEDED_FLAGS (BREAK_SUPPRESS_INITIAL | \ >+ BREAK_SUPPRESS_INSIDE | \ >+ BREAK_SKIP_SETTING_NO_BREAKS) Could you add a brief comment explaining the significance of this mask? e.g.... // If aFlags has *all* these bits set, then we don't need to worry about // finding break opportunities in the appended text. ...or something along those lines. >+ bool capitalizationNeeded = false; > nsTArray<bool> capitalizationState; > if (aSink && (aFlags & BREAK_NEED_CAPITALIZATION)) { > if (!capitalizationState.AppendElements(aLength)) > return NS_ERROR_OUT_OF_MEMORY; > memset(capitalizationState.Elements(), false, aLength*sizeof(bool)); >+ capitalizationNeeded = true; > } (Maybe this should be "noCapitalizationNeeded", with flipped polarity, so it matches "noBreaksNeeded" in all their combined or adjacent checks? Maybe that's more confusing, though. Whatever you prefer on this WFM.) >+ if (noBreaksNeeded && !capitalizationNeeded) { > // Skip to the space before the last word, since either the break data > // here is not needed, or no breaks are set in the sink and there cannot > // be any breaks in this chunk; all we need is the context for the next > // chunk (if any) It looks like this comment needs an update, to match its updated condition. (We're skipping because we don't need breaks *and we don't need capitalization* for this stretch.) r=me
Attachment #8556586 - Flags: review?(dholbert) → review+
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: