зеркало из https://github.com/mozilla/gecko-dev.git
Bug 429968. Handle situations where first-letter text detects first-letter style should not be applied, by creating a zero-length 'first letter'. r+sr=dbaron
--HG-- extra : rebase_source : 650611aec3adb1498dc5d8d6d38212ddf09e32fc
This commit is contained in:
Родитель
df952174cf
Коммит
1523a6fb34
|
@ -224,23 +224,26 @@ nsFirstLetterFrame::Reflow(nsPresContext* aPresContext,
|
|||
ll.BeginLineReflow(bp.left, bp.top, availSize.width, NS_UNCONSTRAINEDSIZE,
|
||||
PR_FALSE, PR_TRUE);
|
||||
rs.mLineLayout = ≪
|
||||
ll.SetInFirstLetter(PR_TRUE);
|
||||
ll.SetFirstLetterStyleOK(PR_TRUE);
|
||||
|
||||
kid->WillReflow(aPresContext);
|
||||
kid->Reflow(aPresContext, aMetrics, rs, aReflowStatus);
|
||||
|
||||
ll.EndLineReflow();
|
||||
ll.SetInFirstLetter(PR_FALSE);
|
||||
}
|
||||
else {
|
||||
// Pretend we are a span and reflow the child frame
|
||||
nsLineLayout* ll = aReflowState.mLineLayout;
|
||||
PRBool pushedFrame;
|
||||
|
||||
NS_ASSERTION(ll->GetFirstLetterStyleOK() || GetPrevContinuation(),
|
||||
"First-continuation first-letter should have first-letter style enabled in nsLineLayout!");
|
||||
ll->SetInFirstLetter(
|
||||
mStyleContext->GetPseudoType() == nsCSSPseudoElements::firstLetter);
|
||||
ll->BeginSpan(this, &aReflowState, bp.left, availSize.width);
|
||||
ll->ReflowFrame(kid, aReflowStatus, &aMetrics, pushedFrame);
|
||||
ll->EndSpan(this);
|
||||
ll->SetInFirstLetter(PR_FALSE);
|
||||
}
|
||||
|
||||
// Place and size the child and update the output metrics
|
||||
|
|
|
@ -163,7 +163,8 @@ protected:
|
|||
#define LL_NEEDBACKUP 0x00000400
|
||||
#define LL_INFIRSTLINE 0x00000800
|
||||
#define LL_GOTLINEBOX 0x00001000
|
||||
#define LL_LASTFLAG LL_GOTLINEBOX
|
||||
#define LL_INFIRSTLETTER 0x00002000
|
||||
#define LL_LASTFLAG LL_INFIRSTLETTER
|
||||
|
||||
PRUint16 mFlags;
|
||||
|
||||
|
@ -245,6 +246,14 @@ public:
|
|||
SetFlag(LL_FIRSTLETTERSTYLEOK, aSetting);
|
||||
}
|
||||
|
||||
PRBool GetInFirstLetter() const {
|
||||
return GetFlag(LL_INFIRSTLETTER);
|
||||
}
|
||||
|
||||
void SetInFirstLetter(PRBool aSetting) {
|
||||
SetFlag(LL_INFIRSTLETTER, aSetting);
|
||||
}
|
||||
|
||||
PRBool GetInFirstLine() const {
|
||||
return GetFlag(LL_INFIRSTLINE);
|
||||
}
|
||||
|
|
|
@ -5757,10 +5757,10 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
PRBool completedFirstLetter = PR_FALSE;
|
||||
// Layout dependent styles are a problem because we need to reconstruct
|
||||
// the gfxTextRun based on our layout.
|
||||
if (lineLayout.GetFirstLetterStyleOK() || lineLayout.GetInFirstLine()) {
|
||||
if (lineLayout.GetInFirstLetter() || lineLayout.GetInFirstLine()) {
|
||||
SetLength(maxContentLength);
|
||||
|
||||
if (lineLayout.GetFirstLetterStyleOK()) {
|
||||
if (lineLayout.GetInFirstLetter()) {
|
||||
// floating first-letter boundaries are significant in textrun
|
||||
// construction, so clear the textrun out every time we hit a first-letter
|
||||
// and have changed our length (which controls the first-letter boundary)
|
||||
|
@ -5771,17 +5771,27 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
|
||||
if (mTextRun) {
|
||||
PRInt32 firstLetterLength = length;
|
||||
completedFirstLetter =
|
||||
FindFirstLetterRange(frag, mTextRun, offset, iter, &firstLetterLength);
|
||||
if (newLineOffset >= 0) {
|
||||
// Don't allow a preformatted newline to be part of a first-letter.
|
||||
firstLetterLength = PR_MIN(firstLetterLength, length - 1);
|
||||
if (length == 1) {
|
||||
// There is no text to be consumed by the first-letter before the
|
||||
// preformatted newline. Note that the first letter is therefore
|
||||
// complete (FindFirstLetterRange will have returned false).
|
||||
completedFirstLetter = PR_TRUE;
|
||||
if (lineLayout.GetFirstLetterStyleOK()) {
|
||||
completedFirstLetter =
|
||||
FindFirstLetterRange(frag, mTextRun, offset, iter, &firstLetterLength);
|
||||
if (newLineOffset >= 0) {
|
||||
// Don't allow a preformatted newline to be part of a first-letter.
|
||||
firstLetterLength = PR_MIN(firstLetterLength, length - 1);
|
||||
if (length == 1) {
|
||||
// There is no text to be consumed by the first-letter before the
|
||||
// preformatted newline. Note that the first letter is therefore
|
||||
// complete (FindFirstLetterRange will have returned false).
|
||||
completedFirstLetter = PR_TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We're in a first-letter frame's first in flow, so if there
|
||||
// was a first-letter, we'd be it. However, for one reason
|
||||
// or another (e.g., preformatted line break before this text),
|
||||
// we're not actually supposed to have first-letter style. So
|
||||
// just make a zero-length first-letter.
|
||||
firstLetterLength = 0;
|
||||
completedFirstLetter = PR_TRUE;
|
||||
}
|
||||
length = firstLetterLength;
|
||||
if (length) {
|
||||
|
@ -6049,9 +6059,6 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
eNormalBreak);
|
||||
}
|
||||
}
|
||||
if (completedFirstLetter) {
|
||||
lineLayout.SetFirstLetterStyleOK(PR_FALSE);
|
||||
}
|
||||
|
||||
// Compute reflow status
|
||||
aStatus = contentLength == maxContentLength
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { white-space:pre; color:black; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
AB</body>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { white-space:pre; color:black; }
|
||||
#inner::first-letter { color:red; text-decoration:underline; font-size:200%; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div id="inner"><span>
|
||||
</span>AB</div></body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { white-space:pre; color:blue; }
|
||||
#inner::first-letter { color:red; text-decoration:underline; font-size:200%; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div id="inner"><span>
|
||||
</span>AB</div></body>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
document.body.style.color = "black";
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { color:black; }
|
||||
span { color:lime; }
|
||||
</style>
|
||||
</head>
|
||||
<body><span>A</span>B</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { white-space:pre; color:black; }
|
||||
#inner::first-letter { color:lime; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div id="inner"><span id="s">
|
||||
</span>AB</div></body>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
document.getElementById("s").textContent = "";
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { white-space:pre; color:black; }
|
||||
#inner::first-letter { color:lime; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div id="inner"><span id="s">
|
||||
</span>AB</div></body>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
document.getElementById("s").firstChild.data = "";
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { white-space:pre; color:black; }
|
||||
#inner::first-letter { color:lime; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div id="inner"><span id="s">
|
||||
</span>AB</div></body>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
document.getElementById("s").style.whiteSpace = "normal";
|
||||
</script>
|
||||
</html>
|
|
@ -43,5 +43,10 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 329069-1.html 329069-1-ref.html # failu
|
|||
== 399941-7.html 399941-7-ref.html
|
||||
== 399941-8.html 399941-8-ref.html
|
||||
== 399941-9.html 399941-9-ref.html
|
||||
== 429968-1a.html 429968-1-ref.html
|
||||
== 429968-1b.html 429968-1-ref.html
|
||||
== 429968-2a.html 429968-2-ref.html
|
||||
== 429968-2b.html 429968-2-ref.html
|
||||
== 429968-2c.html 429968-2-ref.html
|
||||
== 441418-1.html 441418-1-ref.html
|
||||
== 469227-1.html 469227-1-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче