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:
Robert O'Callahan 2009-01-05 13:36:56 +13:00
Родитель 2d4be2ffc2
Коммит aecc41d780
11 изменённых файлов: 133 добавлений и 18 удалений

Просмотреть файл

@ -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