Improve detection of blocks with first-letter style. Bug 372550, r+sr=dbaron

This commit is contained in:
bzbarsky@mit.edu 2007-04-15 17:42:54 -07:00
Родитель 34b2a1abb4
Коммит 884eb773c8
7 изменённых файлов: 104 добавлений и 17 удалений

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

@ -9465,10 +9465,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
// Examine the containing-block for the removed content and see if
// :first-letter style applies.
nsIFrame* containingBlock = GetFloatContainingBlock(parentFrame);
PRBool haveFLS = containingBlock ?
HaveFirstLetterStyle(containingBlock->GetContent(),
containingBlock->GetStyleContext()) :
PR_FALSE;
PRBool haveFLS = containingBlock && HaveFirstLetterStyle(containingBlock);
if (haveFLS) {
// Trap out to special routine that handles adjusting a blocks
// frame tree when first-letter style is present.
@ -9846,7 +9843,7 @@ nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent,
// See if the block has first-letter style applied to it.
nsIContent* blockContent = block->GetContent();
nsStyleContext* blockSC = block->GetStyleContext();
haveFirstLetterStyle = HaveFirstLetterStyle(blockContent, blockSC);
haveFirstLetterStyle = HaveFirstLetterStyle(block);
if (haveFirstLetterStyle) {
RemoveLetterFrames(mPresShell->GetPresContext(), mPresShell,
mPresShell->FrameManager(), block);
@ -11176,6 +11173,22 @@ nsCSSFrameConstructor::HaveFirstLetterStyle(nsIContent* aContent,
mPresShell->GetPresContext());
}
PRBool
nsCSSFrameConstructor::HaveFirstLetterStyle(nsIFrame* aBlockFrame)
{
NS_PRECONDITION(aBlockFrame, "Need a frame");
#ifdef DEBUG
nsBlockFrame* block;
NS_ASSERTION(NS_SUCCEEDED(aBlockFrame->QueryInterface(kBlockFrameCID,
(void**)&block)) &&
block,
"Not a block frame?");
#endif
return (aBlockFrame->GetStateBits() & NS_BLOCK_HAS_FIRST_LETTER_STYLE) != 0;
}
PRBool
nsCSSFrameConstructor::HaveFirstLineStyle(nsIContent* aContent,
nsStyleContext* aStyleContext)
@ -11775,6 +11788,16 @@ nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState,
NS_PRECONDITION(aTextContent->IsNodeOfType(nsINode::eTEXT),
"aTextContent isn't text");
#ifdef DEBUG
{
nsBlockFrame* block;
NS_ASSERTION(NS_SUCCEEDED(aBlockFrame->QueryInterface(kBlockFrameCID,
(void**)&block)) &&
block,
"Not a block frame?");
}
#endif
// Get style context for the first-letter-frame
nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext();
if (parentStyleContext) {
@ -11840,6 +11863,8 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
{
nsresult rv = NS_OK;
aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE);
nsIFrame* parentFrame = nsnull;
nsIFrame* textFrame = nsnull;
nsIFrame* prevFrame = nsnull;
@ -12159,6 +12184,8 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsFrameConstructorState& aState,
{
nsresult rv = NS_OK;
aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE);
nsIFrame* blockKids = aBlockFrame->GetFirstChild(nsnull);
nsIFrame* parentFrame = nsnull;
nsIFrame* textFrame = nsnull;

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

@ -762,6 +762,10 @@ private:
PRBool HaveFirstLetterStyle(nsIContent* aContent,
nsStyleContext* aStyleContext);
// Check whether a given block has first-letter style. Make sure to
// only pass in blocks! And don't pass in null either.
PRBool HaveFirstLetterStyle(nsIFrame* aBlockFrame);
PRBool HaveFirstLineStyle(nsIContent* aContent,
nsStyleContext* aStyleContext);

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

@ -5942,18 +5942,12 @@ nsBlockFrame::SetInitialChildList(nsIAtom* aListName,
else {
nsPresContext* presContext = PresContext();
// Lookup up the two pseudo style contexts
if (nsnull == GetPrevInFlow()) {
nsRefPtr<nsStyleContext> firstLetterStyle = GetFirstLetterStyle(presContext);
if (nsnull != firstLetterStyle) {
mState |= NS_BLOCK_HAS_FIRST_LETTER_STYLE;
#ifdef NOISY_FIRST_LETTER
ListTag(stdout);
printf(": first-letter style found\n");
#endif
}
}
NS_ASSERTION(GetPrevContinuation() ||
(nsRefPtr<nsStyleContext>(GetFirstLetterStyle(presContext)) !=
nsnull) ==
((mState & NS_BLOCK_HAS_FIRST_LETTER_STYLE) != 0),
"NS_BLOCK_HAS_FIRST_LETTER_STYLE state out of sync");
rv = AddFrames(aChildList, nsnull);
if (NS_FAILED(rv)) {
return rv;

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

@ -291,12 +291,14 @@ protected:
}
virtual ~nsBlockFrame();
#ifdef DEBUG
already_AddRefed<nsStyleContext> GetFirstLetterStyle(nsPresContext* aPresContext)
{
return aPresContext->StyleSet()->
ProbePseudoStyleFor(mContent,
nsCSSPseudoElements::firstLetter, mStyleContext);
}
#endif
/*
* Overides member function of nsHTMLContainerFrame. Needed to handle the

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

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green }
</style>
</head>
<body>
<div><span>T</span>ext</div>
<div style="overflow: auto"><span>T</span>ext</div>
<fieldset><span>T</span>ext</fieldset>
<table><tr><td><span>T</span>ext</td></tr></table>
<div><span>T</span>ext</div>
<div style="overflow: auto"><span>T</span>ext</div>
<fieldset><span>T</span>ext</fieldset>
<table><tr><td><span>T</span>ext</td></tr></table>
<div><span>T</span>extMore Text</div>
<div style="overflow: auto"><span>T</span>extMore Text</div>
<fieldset><span>T</span>extMore Text</fieldset>
<table><tr><td><span>T</span>extMore Text</td></tr></table>
</body>
</html>

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

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<style>
.f::first-letter { color: green }
</style>
<script>
window.onload = function() {
var lst = document.getElementsByClassName("d");
for (var i = 0; i < lst.length; ++i) {
lst[i].insertBefore(document.createTextNode("Text"),
lst[i].firstChild);
}
}
</script>
</head>
<body>
<div class="f">Text</div>
<div class="f" style="overflow: auto">Text</div>
<fieldset class="f">Text</fieldset>
<table><tr><td class="f">Text</td></tr></table>
<div class="f d"></div>
<div class="f d" style="overflow: auto"></div>
<fieldset class="f d"></fieldset>
<table><tr><td class="f d"></td></tr></table>
<div class="f d">More Text</div>
<div class="f d" style="overflow: auto">More Text</div>
<fieldset class="f d">More Text</fieldset>
<table><tr><td class="f d">More Text</td></tr></table>
</body>
</html>

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

@ -157,6 +157,7 @@ fails == 351641-2b.html 351641-2-ref.html # bug 358433 (2006-10-19)
!= 362594-2b.html 362594-1-standards-ref.html
== 362594-2b.html 362594-2-standards-ref.html
== 362594-2c.html 362594-2-standards-ref.html
== 362901-1.html 362901-1-ref.html
== 363329-1.html 363329-1-ref.html
== 363329-2.html 363329-2-ref.html
== 363637-1.html 363637-1-ref.html