Bug 425981. Make first-letter frame wrapping build its own frame constructor state to ensure it's for the correct place in the frame tree. r+sr=bzbarsky
--HG-- extra : rebase_source : 7dd5de3f6b2a9e83994d7023d4cfafce205e9376
This commit is contained in:
Родитель
391814a8e4
Коммит
a153305674
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
div:first-letter { float: left; }
|
||||
</style>
|
||||
<script>
|
||||
function boom()
|
||||
{
|
||||
var v = document.getElementById("v");
|
||||
var t = v.firstChild;
|
||||
v.appendChild(document.createTextNode(" "));
|
||||
v.removeChild(t);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"><div id="v" style="-moz-column-count: 2; width: 1px;">a b</div></body>
|
||||
</html>
|
|
@ -122,6 +122,7 @@ load 420213-1.html
|
|||
load 420651-1.xhtml
|
||||
load 421203-1.xul
|
||||
load 423107-1.xhtml
|
||||
load 425981-1.html
|
||||
load 428448-1.html
|
||||
load 429088-1.html
|
||||
load 429088-2.html
|
||||
|
|
|
@ -8494,7 +8494,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
|
|||
|
||||
// Recover first-letter frames
|
||||
if (haveFirstLetterStyle) {
|
||||
RecoverLetterFrames(state, containingBlock);
|
||||
RecoverLetterFrames(containingBlock);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -8935,7 +8935,7 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
|
|||
if (haveFirstLetterStyle) {
|
||||
// Recover the letter frames for the containing block when
|
||||
// it has first-letter style.
|
||||
RecoverLetterFrames(state, state.mFloatedItems.containingBlock);
|
||||
RecoverLetterFrames(state.mFloatedItems.containingBlock);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -9379,7 +9379,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
|
|||
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
|
||||
GetAbsoluteContainingBlock(parentFrame),
|
||||
containingBlock);
|
||||
RecoverLetterFrames(state, containingBlock);
|
||||
RecoverLetterFrames(containingBlock);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -9678,7 +9678,7 @@ nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent,
|
|||
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
|
||||
GetAbsoluteContainingBlock(frame),
|
||||
block, nsnull);
|
||||
RecoverLetterFrames(state, block);
|
||||
RecoverLetterFrames(block);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11254,7 +11254,7 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
|
|||
"can't be both block and box");
|
||||
|
||||
if (haveFirstLetterStyle) {
|
||||
rv = WrapFramesInFirstLetterFrame(aState, aContent, aFrame, aFrameItems);
|
||||
rv = WrapFramesInFirstLetterFrame(aContent, aFrame, aFrameItems);
|
||||
}
|
||||
if (haveFirstLineStyle) {
|
||||
rv = WrapFramesInFirstLineFrame(aState, aContent, aFrame, aFrameItems);
|
||||
|
@ -11314,6 +11314,13 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
|
|||
// Special routine to handle placing a list of frames into a block
|
||||
// frame that has first-line style. The routine ensures that the first
|
||||
// collection of inline frames end up in a first-line frame.
|
||||
// NOTE: aState may have containing block information related to a
|
||||
// different part of the frame tree than where the first line occurs.
|
||||
// In particular aState may be set up for where ContentInserted or
|
||||
// ContentAppended is inserting content, which may be some
|
||||
// non-first-in-flow continuation of the block to which the first-line
|
||||
// belongs. So this function needs to be careful about how it uses
|
||||
// aState.
|
||||
nsresult
|
||||
nsCSSFrameConstructor::WrapFramesInFirstLineFrame(
|
||||
nsFrameConstructorState& aState,
|
||||
|
@ -11779,8 +11786,7 @@ nsCSSFrameConstructor::CreateFloatingLetterFrame(
|
|||
* a child of aParentFrame.
|
||||
*/
|
||||
nsresult
|
||||
nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState,
|
||||
nsIFrame* aBlockFrame,
|
||||
nsCSSFrameConstructor::CreateLetterFrame(nsIFrame* aBlockFrame,
|
||||
nsIContent* aTextContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsFrameItems& aResult)
|
||||
|
@ -11795,13 +11801,10 @@ nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState,
|
|||
nsFrame::CorrectStyleParentFrame(aParentFrame,
|
||||
nsCSSPseudoElements::firstLetter)->
|
||||
GetStyleContext();
|
||||
|
||||
// Use content from containing block so that we can actually
|
||||
// find a matching style rule.
|
||||
nsIContent* blockContent =
|
||||
aState.mFloatedItems.containingBlock->GetContent();
|
||||
|
||||
NS_ASSERTION(blockContent == aBlockFrame->GetContent(),
|
||||
"Unexpected block content");
|
||||
nsIContent* blockContent = aBlockFrame->GetContent();
|
||||
|
||||
// Create first-letter style rule
|
||||
nsRefPtr<nsStyleContext> sc = GetFirstLetterStyle(blockContent,
|
||||
|
@ -11814,11 +11817,17 @@ nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState,
|
|||
// pass a temporary stylecontext, the correct one will be set later
|
||||
nsIFrame* textFrame = NS_NewTextFrame(mPresShell, textSC);
|
||||
|
||||
NS_ASSERTION(aBlockFrame == GetFloatContainingBlock(aParentFrame),
|
||||
"Containing block is confused");
|
||||
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
|
||||
GetAbsoluteContainingBlock(aParentFrame),
|
||||
aBlockFrame);
|
||||
|
||||
// Create the right type of first-letter frame
|
||||
const nsStyleDisplay* display = sc->GetStyleDisplay();
|
||||
if (display->IsFloating()) {
|
||||
// Make a floating first-letter frame
|
||||
CreateFloatingLetterFrame(aState, aBlockFrame, aTextContent, textFrame,
|
||||
CreateFloatingLetterFrame(state, aBlockFrame, aTextContent, textFrame,
|
||||
blockContent, aParentFrame,
|
||||
sc, aResult);
|
||||
}
|
||||
|
@ -11833,7 +11842,7 @@ nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState,
|
|||
nsIContent* letterContent = aTextContent->GetParent();
|
||||
letterFrame->Init(letterContent, aParentFrame, nsnull);
|
||||
|
||||
InitAndRestoreFrame(aState, aTextContent, letterFrame, nsnull,
|
||||
InitAndRestoreFrame(state, aTextContent, letterFrame, nsnull,
|
||||
textFrame);
|
||||
|
||||
letterFrame->SetInitialChildList(nsnull, textFrame);
|
||||
|
@ -11848,7 +11857,6 @@ nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState,
|
|||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aBlockContent,
|
||||
nsIFrame* aBlockFrame,
|
||||
nsFrameItems& aBlockFrames)
|
||||
|
@ -11862,7 +11870,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
|||
nsIFrame* prevFrame = nsnull;
|
||||
nsFrameItems letterFrames;
|
||||
PRBool stopLooking = PR_FALSE;
|
||||
rv = WrapFramesInFirstLetterFrame(aState, aBlockFrame, aBlockFrame,
|
||||
rv = WrapFramesInFirstLetterFrame(aBlockFrame, aBlockFrame,
|
||||
aBlockFrames.childList,
|
||||
&parentFrame, &textFrame, &prevFrame,
|
||||
letterFrames, &stopLooking);
|
||||
|
@ -11894,7 +11902,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
|||
}
|
||||
else {
|
||||
// Take the old textFrame out of the inline parents child list
|
||||
::DeletingFrameSubtree(aState.mFrameManager, textFrame);
|
||||
::DeletingFrameSubtree(mPresShell->FrameManager(), textFrame);
|
||||
parentFrame->RemoveFrame(nsnull, textFrame);
|
||||
|
||||
// Insert in the letter frame(s)
|
||||
|
@ -11907,7 +11915,6 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
|||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
||||
nsFrameConstructorState& aState,
|
||||
nsIFrame* aBlockFrame,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aParentFrameList,
|
||||
|
@ -11931,7 +11938,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
|||
nsIContent* textContent = frame->GetContent();
|
||||
if (IsFirstLetterContent(textContent)) {
|
||||
// Create letter frame to wrap up the text
|
||||
rv = CreateLetterFrame(aState, aBlockFrame, textContent,
|
||||
rv = CreateLetterFrame(aBlockFrame, textContent,
|
||||
aParentFrame, aLetterFrames);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
@ -11947,7 +11954,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
|||
}
|
||||
else if (IsInlineFrame(frame) && frameType != nsGkAtoms::brFrame) {
|
||||
nsIFrame* kids = frame->GetFirstChild(nsnull);
|
||||
WrapFramesInFirstLetterFrame(aState, aBlockFrame, frame, kids,
|
||||
WrapFramesInFirstLetterFrame(aBlockFrame, frame, kids,
|
||||
aModifiedParent, aTextFrame,
|
||||
aPrevFrame, aLetterFrames, aStopLooking);
|
||||
if (*aStopLooking) {
|
||||
|
@ -12177,8 +12184,7 @@ nsCSSFrameConstructor::RemoveLetterFrames(nsPresContext* aPresContext,
|
|||
|
||||
// Fixup the letter frame situation for the given block
|
||||
nsresult
|
||||
nsCSSFrameConstructor::RecoverLetterFrames(nsFrameConstructorState& aState,
|
||||
nsIFrame* aBlockFrame)
|
||||
nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame)
|
||||
{
|
||||
aBlockFrame = aBlockFrame->GetFirstContinuation();
|
||||
|
||||
|
@ -12191,7 +12197,7 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsFrameConstructorState& aState,
|
|||
do {
|
||||
// XXX shouldn't this bit be set already (bug 408493), assert instead?
|
||||
aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE);
|
||||
rv = WrapFramesInFirstLetterFrame(aState, aBlockFrame, aBlockFrame,
|
||||
rv = WrapFramesInFirstLetterFrame(aBlockFrame, aBlockFrame,
|
||||
aBlockFrame->GetFirstChild(nsnull),
|
||||
&parentFrame, &textFrame, &prevFrame,
|
||||
letterFrames, &stopLooking);
|
||||
|
@ -12206,7 +12212,7 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsFrameConstructorState& aState,
|
|||
|
||||
if (parentFrame) {
|
||||
// Take the old textFrame out of the parents child list
|
||||
::DeletingFrameSubtree(aState.mFrameManager, textFrame);
|
||||
::DeletingFrameSubtree(mPresShell->FrameManager(), textFrame);
|
||||
parentFrame->RemoveFrame(nsnull, textFrame);
|
||||
|
||||
// Insert in the letter frame(s)
|
||||
|
|
|
@ -1014,29 +1014,25 @@ private:
|
|||
nsStyleContext* aStyleContext,
|
||||
nsFrameItems& aResult);
|
||||
|
||||
nsresult CreateLetterFrame(nsFrameConstructorState& aState,
|
||||
nsIFrame* aBlockFrame,
|
||||
nsresult CreateLetterFrame(nsIFrame* aBlockFrame,
|
||||
nsIContent* aTextContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsFrameItems& aResult);
|
||||
|
||||
nsresult WrapFramesInFirstLetterFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aBlockContent,
|
||||
nsIFrame* aBlockFrame,
|
||||
nsFrameItems& aBlockFrames);
|
||||
nsresult WrapFramesInFirstLetterFrame(nsIContent* aBlockContent,
|
||||
nsIFrame* aBlockFrame,
|
||||
nsFrameItems& aBlockFrames);
|
||||
|
||||
nsresult WrapFramesInFirstLetterFrame(nsFrameConstructorState& aState,
|
||||
nsIFrame* aBlockFrame,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aParentFrameList,
|
||||
nsIFrame** aModifiedParent,
|
||||
nsIFrame** aTextFrame,
|
||||
nsIFrame** aPrevFrame,
|
||||
nsFrameItems& aLetterFrame,
|
||||
PRBool* aStopLooking);
|
||||
nsresult WrapFramesInFirstLetterFrame(nsIFrame* aBlockFrame,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aParentFrameList,
|
||||
nsIFrame** aModifiedParent,
|
||||
nsIFrame** aTextFrame,
|
||||
nsIFrame** aPrevFrame,
|
||||
nsFrameItems& aLetterFrame,
|
||||
PRBool* aStopLooking);
|
||||
|
||||
nsresult RecoverLetterFrames(nsFrameConstructorState& aState,
|
||||
nsIFrame* aBlockFrame);
|
||||
nsresult RecoverLetterFrames(nsIFrame* aBlockFrame);
|
||||
|
||||
//
|
||||
nsresult RemoveLetterFrames(nsPresContext* aPresContext,
|
||||
|
|
Загрузка…
Ссылка в новой задаче