author | Jonathan Kew <jkew@mozilla.com> |
Mon, 11 Oct 2021 12:54:44 +0000 | |
changeset 595339 | 49f06640fdee2aa53ce8d9f0bc5959f95f376e88 |
parent 595338 | df62726f3d16bb27d0c408e204151148035871dd |
child 595340 | b3e0e27d7ba7127694a955b5e5e59a0afb7f95ce |
push id | 38868 |
push user | mlaza@mozilla.com |
push date | Mon, 11 Oct 2021 21:46:13 +0000 |
treeherder | mozilla-central@32a3cf57dd43 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | emilio |
bugs | 1731120 |
milestone | 95.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -4500,17 +4500,18 @@ class nsContinuingTextFrame final : publ // If there's a prev-prev, then we can safely cast mPrevContinuation to // an nsContinuingTextFrame and access its mFirstContinuation pointer // directly, to avoid recursively calling FirstContinuation(), leading // to exponentially-slow behavior in the assertion. if (mPrevContinuation->GetPrevContinuation()) { auto* prev = static_cast<nsContinuingTextFrame*>(mPrevContinuation); MOZ_ASSERT(mFirstContinuation == prev->mFirstContinuation); } else { - MOZ_ASSERT(mFirstContinuation == mPrevContinuation->FirstContinuation()); + MOZ_ASSERT(mFirstContinuation == + mPrevContinuation->FirstContinuation()); } } else { MOZ_ASSERT(!mFirstContinuation); } #endif return mFirstContinuation; }; @@ -10173,18 +10174,23 @@ nsIFrame::RenderedText nsTextFrame::GetR bool nsTextFrame::IsEmpty() { NS_ASSERTION(!(mState & TEXT_IS_ONLY_WHITESPACE) || !(mState & TEXT_ISNOT_ONLY_WHITESPACE), "Invalid state"); // XXXldb Should this check compatibility mode as well??? const nsStyleText* textStyle = StyleText(); if (textStyle->WhiteSpaceIsSignificant()) { - // XXX shouldn't we return true if the length is zero? - return false; + // When WhiteSpaceIsSignificant styles are in effect, we only treat the + // frame as empty if its content really is entirely *empty* (not just + // whitespace), AND it is NOT editable or within an <input> element. + // In these cases we consider that the whitespace-preserving style makes + // the frame behave as non-empty so that its height doesn't become zero. + return GetContentLength() == 0 && !GetContent()->IsEditable() && + !GetContent()->GetParent()->IsHTMLElement(nsGkAtoms::input); } if (mState & TEXT_ISNOT_ONLY_WHITESPACE) { return false; } if (mState & TEXT_IS_ONLY_WHITESPACE) { return true;
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/css/css-inline/empty-text-node-001-ref.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html lang=en> +<meta charset="utf-8"> +<title>CSS Inline reference</title> +<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> +<style> +.green { color: green; } +.red { color: red; } +.ref { + display: inline-block; +} +div div { + width: 50px; + height: 0px; + border: 20px solid green; + margin: 10px; +} +</style> +<p>Test passes if the <span class=green>green</span> boxes have <span class=red>no red</span> in the middle.</p> + +<div class=ref> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> +</div> + +<div class=ref> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> +</div> + +<div class=ref> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> +</div>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/css/css-inline/empty-text-node-001.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<html lang=en> +<meta charset="utf-8"> +<title>CSS Inline test: empty text node</title> +<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> +<link rel="help" title="2.1. Layout of Line Boxes" href="https://drafts.csswg.org/css-inline/#line-boxes"> +<link rel="match" href="empty-text-node-001-ref.html"> +<meta name="assert" content="Empty text node in a line box is treated as zero height."> +<style> +.green { color: green; } +.red { color: red; } +.testContent, .testBefore, .testAfter { + display: inline-block; +} +div div { + width: 50px; + line-height: 30px; + border: 20px solid green; + background-color: red; + margin: 10px; +} +.testBefore div::before { + content: ""; +} +.testAfter div::after { + content: ""; +} +.normal { white-space: normal; } +.nowrap { white-space: nowrap; } +.pre { white-space: pre; } +.prewrap { white-space: pre-wrap; } +.preline { white-space: pre-line; } +.breakspaces { white-space: break-spaces; } +</style> +<p>Test passes if the <span class=green>green</span> boxes have <span class=red>no red</span> in the middle.</p> + +<div class=testContent> + <div class=normal></div> + <div class=nowrap></div> + <div class=pre></div> + <div class=prewrap></div> + <div class=preline></div> + <div class=breakspaces></div> + <script> + [...document.querySelectorAll(".testContent div")].forEach((node, i) => node.appendChild(document.createTextNode(""))); + </script> +</div> + +<div class=testBefore> + <div class=normal></div> + <div class=nowrap></div> + <div class=pre></div> + <div class=prewrap></div> + <div class=preline></div> + <div class=breakspaces></div> +</div> + +<div class=testAfter> + <div class=normal></div> + <div class=nowrap></div> + <div class=pre></div> + <div class=prewrap></div> + <div class=preline></div> + <div class=breakspaces></div> +</div>