зеркало из https://github.com/mozilla/pjs.git
Fix 2 cases where ReResolveStyleContext was broken, causing serious problems with dynamic style reresolution. Change nsIFrame::GetStyleContextProvider to GetParentStyleContextFrame, always use its result rather than using the parent frame in some cases, and move a bit of the complexity into the GetParentStyleContextFrame implementations. Fix block-within-inline case (bug 129350) using a special-previous-sibling frame property and ensuring that NS_FRAME_IS_SPECIAL is copied when frames are split. Fix out-of-flow frame case (bug 88154) by going to the placeholder map and by parenting the placeholder frame style contexts to the style context from their frame parent rather than the out-of-flow frame. b=129350 r=attinasi sr=hyatt a=asa
This commit is contained in:
Родитель
4d8709600c
Коммит
43acd755dd
|
@ -58,6 +58,7 @@
|
|||
#include "nsRuleWalker.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
||||
#ifdef MOZ_PERF_METRICS
|
||||
#include "nsITimeRecorder.h"
|
||||
|
@ -1109,7 +1110,8 @@ nsIStyleContext* StyleSetImpl::ResolveStyleForNonElement(
|
|||
mDocRuleProcessors ||
|
||||
mOverrideRuleProcessors) {
|
||||
EnsureRuleWalker(aPresContext);
|
||||
result = GetContext(aPresContext, aParentContext, nsnull, aForceUnique);
|
||||
result = GetContext(aPresContext, aParentContext,
|
||||
nsHTMLAtoms::mozNonElementPseudo, aForceUnique);
|
||||
NS_ASSERTION(mRuleWalker->AtRoot(), "rule walker must be at root");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ HTML_ATOM(mozFirstLineFixup, ":-moz-first-line-fixup")
|
|||
HTML_ATOM(mozLineFrame, ":-moz-line-frame")
|
||||
HTML_ATOM(mozListBulletPseudo, ":-moz-list-bullet")
|
||||
HTML_ATOM(mozListNumberPseudo, ":-moz-list-number")
|
||||
HTML_ATOM(mozNonElementPseudo, ":-moz-non-element")
|
||||
HTML_ATOM(mozSingleLineTextControlFrame, ":-moz-singleline-textcontrol-frame")
|
||||
HTML_ATOM(mozFocusInnerPseudo, ":-moz-focus-inner")
|
||||
HTML_ATOM(mozFocusOuterPseudo, ":-moz-focus-outer")
|
||||
|
|
|
@ -58,6 +58,7 @@ HTML_ATOM(mozFirstLineFixup, ":-moz-first-line-fixup")
|
|||
HTML_ATOM(mozLineFrame, ":-moz-line-frame")
|
||||
HTML_ATOM(mozListBulletPseudo, ":-moz-list-bullet")
|
||||
HTML_ATOM(mozListNumberPseudo, ":-moz-list-number")
|
||||
HTML_ATOM(mozNonElementPseudo, ":-moz-non-element")
|
||||
HTML_ATOM(mozSingleLineTextControlFrame, ":-moz-singleline-textcontrol-frame")
|
||||
HTML_ATOM(mozFocusInnerPseudo, ":-moz-focus-inner")
|
||||
HTML_ATOM(mozFocusOuterPseudo, ":-moz-focus-outer")
|
||||
|
|
|
@ -139,7 +139,8 @@ LAYOUT_ATOM(viewportFrame, "ViewportFrame")
|
|||
|
||||
// Alphabetical list of frame property names
|
||||
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
|
||||
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation") // BOOL
|
||||
LAYOUT_ATOM(IBSplitSpecialPrevSibling, "IBSplitSpecialPrevSibling")// nsIFrame*
|
||||
LAYOUT_ATOM(IBSplitSpecialSibling, "IBSplitSpecialSibling") // nsIFrame*
|
||||
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
|
||||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||
|
|
|
@ -384,7 +384,7 @@ GetSpecialSibling(nsIFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame** a
|
|||
}
|
||||
|
||||
void* value;
|
||||
aFrameManager->GetFrameProperty(aFrame, nsLayoutAtoms::inlineFrameAnnotation, 0, &value);
|
||||
aFrameManager->GetFrameProperty(aFrame, nsLayoutAtoms::IBSplitSpecialSibling, 0, &value);
|
||||
*aResult = NS_STATIC_CAST(nsIFrame*, value);
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,8 @@ SetFrameIsSpecial(nsIFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame* aS
|
|||
|
||||
// Store the "special sibling" (if we were given one) with the
|
||||
// first frame in the flow.
|
||||
aFrameManager->SetFrameProperty(aFrame, nsLayoutAtoms::inlineFrameAnnotation,
|
||||
aFrameManager->SetFrameProperty(aFrame,
|
||||
nsLayoutAtoms::IBSplitSpecialSibling,
|
||||
aSpecialSibling, nsnull);
|
||||
}
|
||||
}
|
||||
|
@ -492,10 +493,7 @@ IsBlockFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
|||
// don't we use display->IsBlockLevel() here?
|
||||
const nsStyleDisplay* display;
|
||||
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
|
||||
if (NS_STYLE_DISPLAY_INLINE == display->mDisplay) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
return NS_STYLE_DISPLAY_INLINE != display->mDisplay;
|
||||
}
|
||||
|
||||
static nsIFrame*
|
||||
|
@ -527,6 +525,27 @@ FindLastBlock(nsIPresContext* aPresContext, nsIFrame* aKid)
|
|||
return lastBlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlike the special (next) sibling, the special previous sibling
|
||||
* property points only from the anonymous block to the original inline
|
||||
* that preceded it. It is useful for finding the "special parent" of a
|
||||
* frame (i.e., a frame from which a good parent style context can be
|
||||
* obtained), one looks at the special previous sibling annotation of
|
||||
* the real parent of the frame (if the real parent has
|
||||
* NS_FRAME_IS_SPECIAL).
|
||||
*/
|
||||
inline void
|
||||
MarkIBSpecialPrevSibling(nsIPresContext* aPresContext,
|
||||
nsIFrameManager *aFrameManager,
|
||||
nsIFrame *aAnonymousFrame,
|
||||
nsIFrame *aSpecialParent)
|
||||
{
|
||||
aFrameManager->SetFrameProperty(aAnonymousFrame,
|
||||
nsLayoutAtoms::IBSplitSpecialPrevSibling,
|
||||
aSpecialParent,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves frames to a new parent, updating the style context and
|
||||
* propagating relevant frame state bits. |aNewParentSC| may be null,
|
||||
|
@ -3803,7 +3822,9 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell,
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
// The placeholder frame gets a pseudo style context
|
||||
nsCOMPtr<nsIStyleContext> placeholderStyle;
|
||||
aPresContext->ResolveStyleContextForNonElement(aStyleContext, PR_FALSE,
|
||||
nsCOMPtr<nsIStyleContext> parentContext =
|
||||
dont_AddRef(aStyleContext->GetParent());
|
||||
aPresContext->ResolveStyleContextForNonElement(parentContext, PR_FALSE,
|
||||
getter_AddRefs(placeholderStyle));
|
||||
placeholderFrame->Init(aPresContext, aContent, aParentFrame,
|
||||
placeholderStyle, nsnull);
|
||||
|
@ -9231,15 +9252,18 @@ DeletingFrameSubtree(nsIPresContext* aPresContext,
|
|||
if (aFrameManager) {
|
||||
nsAutoVoidArray destroyQueue;
|
||||
|
||||
while (aFrame) {
|
||||
// If it's a "special" block-in-inline frame, then we need to
|
||||
// remember to delete our special siblings, too.
|
||||
if (IsFrameSpecial(aFrame)) {
|
||||
nsIFrame* specialSibling;
|
||||
GetSpecialSibling(aFrameManager, aFrame, &specialSibling);
|
||||
DeletingFrameSubtree(aPresContext, aPresShell, aFrameManager, specialSibling);
|
||||
}
|
||||
// If it's a "special" block-in-inline frame, then we need to
|
||||
// remember to delete our special siblings, too. Since every one of
|
||||
// the next-in-flows has the same special sibling, just do this
|
||||
// once, rather than in the loop below.
|
||||
if (IsFrameSpecial(aFrame)) {
|
||||
nsIFrame* specialSibling;
|
||||
GetSpecialSibling(aFrameManager, aFrame, &specialSibling);
|
||||
DeletingFrameSubtree(aPresContext, aPresShell, aFrameManager,
|
||||
specialSibling);
|
||||
}
|
||||
|
||||
while (aFrame) {
|
||||
DoDeletingFrameSubtree(aPresContext, aPresShell, aFrameManager,
|
||||
destroyQueue, aFrame, aFrame);
|
||||
|
||||
|
@ -10483,9 +10507,15 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
|||
nsIFrame* primaryFrame;
|
||||
shell->GetPrimaryFrameFor(aContent, &primaryFrame);
|
||||
// Get the frame associated with the content whose style context is highest in the style context tree
|
||||
nsIFrame* primaryStyleFrame = nsnull;
|
||||
nsIFrame* primaryStyleFrame = primaryFrame;
|
||||
if (primaryFrame) {
|
||||
primaryFrame->GetStyleContextProvider(aPresContext, &primaryStyleFrame);
|
||||
PRBool providerIsChild = PR_FALSE;
|
||||
nsIFrame *styleContextProvider;
|
||||
primaryFrame->GetParentStyleContextFrame(aPresContext,
|
||||
&styleContextProvider,
|
||||
&providerIsChild);
|
||||
if (providerIsChild)
|
||||
primaryStyleFrame = styleContextProvider;
|
||||
}
|
||||
|
||||
PRBool reconstruct = PR_FALSE;
|
||||
|
@ -11220,6 +11250,8 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresShell* aPresShell,
|
|||
lastBlock->SetNextSibling(nsnull);
|
||||
|
||||
// Create "special" inline-block linkage between the frames
|
||||
// XXXldb Do we really need to do this? It doesn't seem
|
||||
// consistent with the use in ConstructInline.
|
||||
SetFrameIsSpecial(state.mFrameManager, list1, list2);
|
||||
SetFrameIsSpecial(state.mFrameManager, list2, list3);
|
||||
SetFrameIsSpecial(state.mFrameManager, list3, nsnull);
|
||||
|
@ -13742,6 +13774,8 @@ nsCSSFrameConstructor::ConstructInline(nsIPresShell* aPresShell,
|
|||
// containing block will be reframed instead.
|
||||
SetFrameIsSpecial(aState.mFrameManager, aNewFrame, blockFrame);
|
||||
SetFrameIsSpecial(aState.mFrameManager, blockFrame, inlineFrame);
|
||||
MarkIBSpecialPrevSibling(aPresContext, aState.mFrameManager,
|
||||
blockFrame, aNewFrame);
|
||||
|
||||
if (inlineFrame)
|
||||
SetFrameIsSpecial(aState.mFrameManager, inlineFrame, nsnull);
|
||||
|
@ -14169,6 +14203,7 @@ nsCSSFrameConstructor::SplitToContainingBlock(nsIPresContext* aPresContext,
|
|||
// Create an anonymous inline frame that will parent
|
||||
// aRightInlineChildFrame. The new frame won't have a parent yet:
|
||||
// the recursion will parent it.
|
||||
// XXXldb Why bother if |aRightInlineChildFrame| is null?
|
||||
nsIFrame* inlineFrame = nsnull;
|
||||
NS_NewInlineFrame(shell, &inlineFrame);
|
||||
if (! inlineFrame)
|
||||
|
@ -14196,6 +14231,9 @@ nsCSSFrameConstructor::SplitToContainingBlock(nsIPresContext* aPresContext,
|
|||
SetFrameIsSpecial(aState.mFrameManager, blockFrame, inlineFrame);
|
||||
SetFrameIsSpecial(aState.mFrameManager, inlineFrame, nsnull);
|
||||
|
||||
MarkIBSpecialPrevSibling(aPresContext, aState.mFrameManager,
|
||||
blockFrame, firstInFlow);
|
||||
|
||||
// If we have a continuation frame, then we need to break the
|
||||
// continuation.
|
||||
nsIFrame* nextInFlow;
|
||||
|
|
|
@ -417,7 +417,6 @@ private:
|
|||
|
||||
void ReResolveStyleContext(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIStyleContext* aParentContext,
|
||||
nsIContent* aParentContent,
|
||||
PRInt32 aAttrNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -1275,8 +1274,6 @@ static void
|
|||
VerifyContextParent(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
||||
nsIStyleContext* aContext, nsIStyleContext* aParentContext)
|
||||
{
|
||||
nsIAtom* frameType;
|
||||
|
||||
// get the contexts not provided
|
||||
if (!aContext) {
|
||||
aFrame->GetStyleContext(&aContext);
|
||||
|
@ -1289,24 +1286,15 @@ VerifyContextParent(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
|||
// Get the correct parent context from the frame
|
||||
// - if the frame is a placeholder, we get the out of flow frame's context
|
||||
// as the parent context instead of asking the frame
|
||||
aFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder
|
||||
// get out of flow frame's context as the parent context
|
||||
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)aFrame)->GetOutOfFlowFrame();
|
||||
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
|
||||
outOfFlowFrame->GetStyleContext(&aParentContext);
|
||||
} else {
|
||||
// get the parent context from the frame (indirectly)
|
||||
nsIFrame* providerFrame = nsnull;
|
||||
aFrame->GetStyleContextProvider(aPresContext, &providerFrame);
|
||||
ENSURE_TRUE(providerFrame);
|
||||
nsCOMPtr<nsIStyleContext> providerContext;
|
||||
providerFrame->GetStyleContext(getter_AddRefs(providerContext));
|
||||
ENSURE_TRUE(providerContext);
|
||||
aParentContext = providerContext->GetParent(); // released later
|
||||
// aParentContext could still be null, since some contexts don't have parents
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
|
||||
// get the parent context from the frame (indirectly)
|
||||
nsIFrame* providerFrame = nsnull;
|
||||
PRBool providerIsChild;
|
||||
aFrame->GetParentStyleContextFrame(aPresContext,
|
||||
&providerFrame, &providerIsChild);
|
||||
if (providerFrame)
|
||||
providerFrame->GetStyleContext(&aParentContext);
|
||||
// aParentContext could still be null
|
||||
} else {
|
||||
// addref the parent context so we can release it at end
|
||||
NS_ADDREF(aParentContext);
|
||||
|
@ -1351,7 +1339,7 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext*
|
|||
nsIStyleContext* context;
|
||||
aFrame->GetStyleContext(&context);
|
||||
|
||||
VerifyContextParent(aPresContext, aFrame, context, aParentContext);
|
||||
VerifyContextParent(aPresContext, aFrame, context, nsnull);
|
||||
|
||||
PRInt32 listIndex = 0;
|
||||
nsIAtom* childList = nsnull;
|
||||
|
@ -1372,15 +1360,13 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext*
|
|||
// then verify the placeholder's context
|
||||
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
|
||||
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
|
||||
nsIStyleContext* outOfFlowContext;
|
||||
|
||||
// recurse to out of flow frame, letting the parent context get resolved
|
||||
VerifyStyleTree(aPresContext, outOfFlowFrame, nsnull);
|
||||
|
||||
// verify placeholder using the out of flow's context as parent context
|
||||
outOfFlowFrame->GetStyleContext(&outOfFlowContext);
|
||||
VerifyContextParent(aPresContext,child, nsnull, outOfFlowContext);
|
||||
NS_IF_RELEASE(outOfFlowContext);
|
||||
// verify placeholder using the parent frame's context as
|
||||
// parent context
|
||||
VerifyContextParent(aPresContext, child, nsnull, nsnull);
|
||||
}
|
||||
else { // regular frame
|
||||
VerifyStyleTree(aPresContext, child, nsnull);
|
||||
|
@ -1585,7 +1571,6 @@ CaptureChange(nsIStyleContext* aOldContext, nsIStyleContext* aNewContext,
|
|||
void
|
||||
FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIStyleContext* aParentContextIn,
|
||||
nsIContent* aParentContent,
|
||||
PRInt32 aAttrNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -1620,73 +1605,51 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIStyleContext> parentContext;
|
||||
nsIFrame* resolvedDescendant = nsnull;
|
||||
// Get the frame providing the style context. If it differs from aFrame, then
|
||||
// reslove the provider first, since the provider's context is the parent of aFrame's
|
||||
nsIFrame* resolvedChild = nsnull;
|
||||
// Get the frame providing the parent style context. If it is a
|
||||
// child, then resolve the provider first.
|
||||
nsIFrame* providerFrame = nsnull;
|
||||
aFrame->GetStyleContextProvider(aPresContext, &providerFrame);
|
||||
ENSURE_TRUE(providerFrame);
|
||||
if (providerFrame == aFrame) {
|
||||
if (aParentContextIn) {
|
||||
parentContext = aParentContextIn;
|
||||
NOISY_TRACE_FRAME("non-null parent context provided: using it and assuming already resolved",aFrame);
|
||||
} else {
|
||||
nsIFrame* parentFrame;
|
||||
aFrame->GetParent(&parentFrame);
|
||||
if (parentFrame) {
|
||||
parentFrame->GetStyleContext(getter_AddRefs(parentContext));
|
||||
}
|
||||
}
|
||||
PRBool providerIsChild = PR_FALSE;
|
||||
aFrame->GetParentStyleContextFrame(aPresContext,
|
||||
&providerFrame, &providerIsChild);
|
||||
if (!providerIsChild) {
|
||||
if (providerFrame)
|
||||
providerFrame->GetStyleContext(getter_AddRefs(parentContext));
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
// check to make sure that the provider is the child of aFrame
|
||||
nsIFrame* providerFrameParent;
|
||||
providerFrame->GetParent(&providerFrameParent);
|
||||
NS_ASSERTION(providerFrameParent == aFrame, "invalid style context provider");
|
||||
#endif
|
||||
// resolve the provider here (before aFrame below)
|
||||
nsCOMPtr<nsIStyleContext> providerContextParent;
|
||||
nsIFrame* grandParentFrame;
|
||||
aFrame->GetParent(&grandParentFrame);
|
||||
if (grandParentFrame) {
|
||||
grandParentFrame->GetStyleContext(getter_AddRefs(providerContextParent));
|
||||
}
|
||||
ReResolveStyleContext(aPresContext, providerFrame, providerContextParent, content,
|
||||
aAttrNameSpaceID, aAttribute, aChangeList, aMinChange, aResultChange);
|
||||
// the provider's new context becomes the parent context of aFrame's context
|
||||
ReResolveStyleContext(aPresContext, providerFrame, content,
|
||||
aAttrNameSpaceID, aAttribute, aChangeList,
|
||||
aMinChange, aResultChange);
|
||||
// The provider's new context becomes the parent context of
|
||||
// aFrame's context.
|
||||
providerFrame->GetStyleContext(getter_AddRefs(parentContext));
|
||||
resolvedDescendant = providerFrame; // don't want to re-resolve the provider again
|
||||
// Set |resolvedChild| so we don't bother resolving the
|
||||
// provider again.
|
||||
resolvedChild = providerFrame;
|
||||
}
|
||||
|
||||
// do primary context
|
||||
nsIStyleContext* newContext = nsnull;
|
||||
if (pseudoTag) {
|
||||
nsIContent* pseudoContent = (aParentContent) ? aParentContent : localContent;
|
||||
aPresContext->ResolvePseudoStyleContextFor(pseudoContent, pseudoTag, parentContext,
|
||||
if (pseudoTag == nsHTMLAtoms::mozNonElementPseudo) {
|
||||
NS_ASSERTION(localContent,
|
||||
"non pseudo-element frame without content node");
|
||||
aPresContext->ResolveStyleContextForNonElement(parentContext,
|
||||
PR_TRUE, &newContext);
|
||||
}
|
||||
else if (pseudoTag) {
|
||||
nsIContent* pseudoContent =
|
||||
aParentContent ? aParentContent : localContent;
|
||||
aPresContext->ResolvePseudoStyleContextFor(pseudoContent, pseudoTag,
|
||||
parentContext,
|
||||
PR_FALSE, &newContext);
|
||||
NS_RELEASE(pseudoTag);
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(localContent,
|
||||
"non pseudo-element frame without content node");
|
||||
// XXX This frame type check is a little ugly. However, it should
|
||||
// be cheaper than doing useless style resolution on placeholder
|
||||
// frames, and it should be able to go away if we make it so that
|
||||
// placeholder frames don't have style contexts at all.
|
||||
//
|
||||
// XXX We also probably need to descend into the style contexts of
|
||||
// the placeholder's out-of-flow frame.
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (content->IsContentOfType(nsIContent::eELEMENT) &&
|
||||
frameType != nsLayoutAtoms::placeholderFrame) {
|
||||
aPresContext->ResolveStyleContextFor(content, parentContext,
|
||||
PR_TRUE, &newContext);
|
||||
} else {
|
||||
aPresContext->ResolveStyleContextForNonElement(parentContext,
|
||||
PR_TRUE, &newContext);
|
||||
}
|
||||
aPresContext->ResolveStyleContextFor(content, parentContext,
|
||||
PR_TRUE, &newContext);
|
||||
}
|
||||
NS_ASSERTION(newContext, "failed to get new style context");
|
||||
if (newContext) {
|
||||
|
@ -1730,7 +1693,9 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
if (oldExtraContext) {
|
||||
nsIStyleContext* newExtraContext = nsnull;
|
||||
oldExtraContext->GetPseudoType(pseudoTag);
|
||||
NS_ASSERTION(pseudoTag, "extra style context is not pseudo element");
|
||||
NS_ASSERTION(pseudoTag &&
|
||||
pseudoTag != nsHTMLAtoms::mozNonElementPseudo,
|
||||
"extra style context is not pseudo element");
|
||||
result = aPresContext->ResolvePseudoStyleContextFor(content, pseudoTag, newContext,
|
||||
PR_FALSE, &newExtraContext);
|
||||
NS_RELEASE(pseudoTag);
|
||||
|
@ -1770,6 +1735,10 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
aPresContext->ResolveStyleContextFor(undisplayed->mContent, newContext,
|
||||
PR_TRUE, &undisplayedContext);
|
||||
}
|
||||
else if (pseudoTag == nsHTMLAtoms::mozNonElementPseudo) {
|
||||
aPresContext->ResolveStyleContextForNonElement(newContext,
|
||||
PR_TRUE, &undisplayedContext);
|
||||
}
|
||||
else { // pseudo element
|
||||
NS_ASSERTION(pseudoTag, "pseudo element without tag");
|
||||
aPresContext->ResolvePseudoStyleContextFor(localContent, pseudoTag, newContext, PR_FALSE,
|
||||
|
@ -1786,8 +1755,12 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {
|
||||
aChangeList.AppendChange(nsnull, ((undisplayed->mContent) ? undisplayed->mContent : localContent),
|
||||
NS_STYLE_HINT_FRAMECHANGE);
|
||||
NS_RELEASE(undisplayedContext);
|
||||
} else {
|
||||
// update the undisplayed node with the new context
|
||||
NS_RELEASE(undisplayed->mStyle);
|
||||
undisplayed->mStyle = undisplayedContext;
|
||||
}
|
||||
NS_RELEASE(undisplayedContext);
|
||||
}
|
||||
undisplayed = undisplayed->mNext;
|
||||
}
|
||||
|
@ -1805,42 +1778,40 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
PRInt32 listIndex = 0;
|
||||
nsIAtom* childList = nsnull;
|
||||
PRInt32 childChange;
|
||||
nsIFrame* child;
|
||||
|
||||
do {
|
||||
child = nsnull;
|
||||
nsIFrame* child = nsnull;
|
||||
result = aFrame->FirstChild(aPresContext, childList, &child);
|
||||
while ((NS_SUCCEEDED(result)) && (child)) {
|
||||
while (NS_SUCCEEDED(result) && child) {
|
||||
nsFrameState state;
|
||||
child->GetFrameState(&state);
|
||||
if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) {
|
||||
if (!(state & NS_FRAME_OUT_OF_FLOW)) {
|
||||
// only do frames that are in flow
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
child->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::placeholderFrame == frameType.get()) { // placeholder
|
||||
// get out of flow frame and recurse there
|
||||
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
|
||||
if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder
|
||||
// get out of flow frame and recur there
|
||||
nsIFrame* outOfFlowFrame =
|
||||
NS_STATIC_CAST(nsPlaceholderFrame*,child)->GetOutOfFlowFrame();
|
||||
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
|
||||
NS_ASSERTION(outOfFlowFrame != resolvedChild,
|
||||
"out-of-flow frame not a true descendant");
|
||||
|
||||
if (outOfFlowFrame != resolvedDescendant) {
|
||||
ReResolveStyleContext(aPresContext, outOfFlowFrame, nsnull, content,
|
||||
aAttrNameSpaceID, aAttribute,
|
||||
aChangeList, aMinChange, childChange);
|
||||
} else {
|
||||
NOISY_TRACE("out of flow frame already resolved as descendent\n");
|
||||
}
|
||||
// |nsFrame::GetParentStyleContextFrame| checks being out
|
||||
// of flow so that this works correctly.
|
||||
ReResolveStyleContext(aPresContext, outOfFlowFrame, content,
|
||||
aAttrNameSpaceID, aAttribute,
|
||||
aChangeList, aMinChange, childChange);
|
||||
|
||||
// reresolve placeholder's context under out of flow frame
|
||||
nsIStyleContext* outOfFlowContext;
|
||||
outOfFlowFrame->GetStyleContext(&outOfFlowContext);
|
||||
ReResolveStyleContext(aPresContext, child, outOfFlowContext, content,
|
||||
// reresolve placeholder's context under the same parent
|
||||
// as the out-of-flow frame
|
||||
ReResolveStyleContext(aPresContext, child, content,
|
||||
kNameSpaceID_Unknown, nsnull,
|
||||
aChangeList, aMinChange, childChange);
|
||||
NS_RELEASE(outOfFlowContext);
|
||||
}
|
||||
else { // regular child frame
|
||||
if (child != resolvedDescendant) {
|
||||
ReResolveStyleContext(aPresContext, child, nsnull, content,
|
||||
if (child != resolvedChild) {
|
||||
ReResolveStyleContext(aPresContext, child, content,
|
||||
aAttrNameSpaceID, aAttribute,
|
||||
aChangeList, aMinChange, childChange);
|
||||
} else {
|
||||
|
@ -1884,18 +1855,13 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext,
|
|||
#endif
|
||||
|
||||
do {
|
||||
nsIStyleContext* styleContext = nsnull;
|
||||
frame->GetStyleContext(&styleContext);
|
||||
nsIStyleContext* parentContext = styleContext->GetParent();
|
||||
PRInt32 frameChange;
|
||||
ReResolveStyleContext(aPresContext, frame, parentContext, nsnull,
|
||||
ReResolveStyleContext(aPresContext, frame, nsnull,
|
||||
aAttrNameSpaceID, aAttribute,
|
||||
aChangeList, aMinChange, frameChange);
|
||||
#ifdef NS_DEBUG
|
||||
VerifyStyleTree(aPresContext, frame, parentContext);
|
||||
VerifyStyleTree(aPresContext, frame, nsnull);
|
||||
#endif
|
||||
NS_IF_RELEASE(parentContext);
|
||||
NS_RELEASE(styleContext);
|
||||
if (aTopLevelChange < frameChange) {
|
||||
aTopLevelChange = frameChange;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,8 @@ LAYOUT_ATOM(viewportFrame, "ViewportFrame")
|
|||
|
||||
// Alphabetical list of frame property names
|
||||
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
|
||||
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation") // BOOL
|
||||
LAYOUT_ATOM(IBSplitSpecialPrevSibling, "IBSplitSpecialPrevSibling")// nsIFrame*
|
||||
LAYOUT_ATOM(IBSplitSpecialSibling, "IBSplitSpecialSibling") // nsIFrame*
|
||||
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
|
||||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||
|
|
|
@ -1091,15 +1091,25 @@ public:
|
|||
PRBool aCommandAdded) = 0;
|
||||
|
||||
/**
|
||||
* Get the frame that is the primary frame associated with the content.
|
||||
* aProviderFrame == this except in the case of an outer table, in
|
||||
* which case it is the inner table.
|
||||
* Get the frame whose style context should be the parent of this
|
||||
* frame's style context (i.e., provide the parent style context).
|
||||
* This frame must either be an ancestor of this frame or a child. If
|
||||
* this frame returns a child frame, then the child frame must be sure
|
||||
* to return a grandparent or higher!
|
||||
*
|
||||
* @param aPresContext: PresContext
|
||||
* @param aProviderFrame: Set to the primary frame associated with the content
|
||||
* @param aProviderFrame: The frame whose style context should be the
|
||||
* parent of this frame's style context. Null
|
||||
* is permitted, and means that this frame's
|
||||
* style context should be the root of the
|
||||
* style context tree.
|
||||
* @param aIsChild: True if |aProviderFrame| is set to a child
|
||||
* of this frame; false if it is an ancestor or
|
||||
* null.
|
||||
*/
|
||||
NS_IMETHOD GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame) = 0;
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild) = 0;
|
||||
|
||||
/**
|
||||
* Determines whether a frame is visible for painting
|
||||
|
|
|
@ -336,33 +336,28 @@ nsFrame::Init(nsIPresContext* aPresContext,
|
|||
mContent = aContent;
|
||||
NS_IF_ADDREF(mContent);
|
||||
mParent = aParent;
|
||||
nsFrameState state;
|
||||
|
||||
if (aPrevInFlow) {
|
||||
// Make sure the general flags bits are the same
|
||||
nsFrameState state;
|
||||
aPrevInFlow->GetFrameState(&state);
|
||||
if ((state & NS_FRAME_SYNC_FRAME_AND_VIEW) == 0) {
|
||||
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
|
||||
}
|
||||
if (state & NS_FRAME_REPLACED_ELEMENT) {
|
||||
mState |= NS_FRAME_REPLACED_ELEMENT;
|
||||
}
|
||||
if (state & NS_FRAME_SELECTED_CONTENT) {
|
||||
mState |= NS_FRAME_SELECTED_CONTENT;
|
||||
}
|
||||
if (state & NS_FRAME_INDEPENDENT_SELECTION) {
|
||||
mState |= NS_FRAME_INDEPENDENT_SELECTION;
|
||||
}
|
||||
|
||||
// Make bits that are currently on (see constructor) the same:
|
||||
mState &= state | ~(NS_FRAME_SYNC_FRAME_AND_VIEW);
|
||||
|
||||
// Make bits that are currently off (see constructor) the same:
|
||||
mState |= state & (NS_FRAME_REPLACED_ELEMENT |
|
||||
NS_FRAME_SELECTED_CONTENT |
|
||||
NS_FRAME_INDEPENDENT_SELECTION |
|
||||
NS_FRAME_IS_SPECIAL);
|
||||
}
|
||||
if(mParent)
|
||||
{
|
||||
if (mParent) {
|
||||
nsFrameState state;
|
||||
mParent->GetFrameState(&state);
|
||||
if (state & NS_FRAME_INDEPENDENT_SELECTION) {
|
||||
mState |= NS_FRAME_INDEPENDENT_SELECTION;
|
||||
}
|
||||
if (state & NS_FRAME_GENERATED_CONTENT){
|
||||
mState |= NS_FRAME_GENERATED_CONTENT;
|
||||
}
|
||||
|
||||
// Make bits that are currently off (see constructor) the same:
|
||||
mState |= state & (NS_FRAME_INDEPENDENT_SELECTION |
|
||||
NS_FRAME_GENERATED_CONTENT);
|
||||
}
|
||||
return SetStyleContext(aPresContext, aContext);
|
||||
}
|
||||
|
@ -4006,10 +4001,85 @@ nsFrame::ReflowCommandNotify(nsIPresShell* aShell,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrame::GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame)
|
||||
nsFrame::GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild)
|
||||
{
|
||||
*aProviderFrame = this;
|
||||
return DoGetParentStyleContextFrame(aPresContext, aProviderFrame, aIsChild);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrame::DoGetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild)
|
||||
{
|
||||
*aIsChild = PR_FALSE;
|
||||
if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
|
||||
// If this frame is one of the blocks that split an inline, we must
|
||||
// return the "special" inline parent, i.e., the parent that this
|
||||
// frame would have if we didn't mangle the frame structure.
|
||||
return GetIBSpecialParent(aPresContext, aProviderFrame);
|
||||
}
|
||||
|
||||
// For out-of-flow frames, we must resolve underneath the
|
||||
// placeholder's parent.
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
nsIFrame *placeholder;
|
||||
frameManager->GetPlaceholderFrameFor(this, &placeholder);
|
||||
if (!placeholder) {
|
||||
NS_NOTREACHED("no placeholder frame for out-of-flow frame");
|
||||
GetIBSpecialParent(aPresContext, aProviderFrame);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_STATIC_CAST(nsFrame*, placeholder)->GetParent(aProviderFrame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent, corrected for the mangled frame tree resulting from
|
||||
* having a block within an inline. The result only differs from the
|
||||
* result of |GetParent| when |GetParent| returns an anonymous block
|
||||
* that was created for an element that was 'display: inline' because
|
||||
* that element contained a block.
|
||||
*/
|
||||
nsresult
|
||||
nsFrame::GetIBSpecialParent(nsIPresContext* aPresContext,
|
||||
nsIFrame** aSpecialParent)
|
||||
{
|
||||
*aSpecialParent = mParent;
|
||||
if (mParent) {
|
||||
nsFrameState parentState;
|
||||
mParent->GetFrameState(&parentState);
|
||||
if (parentState & NS_FRAME_IS_SPECIAL) {
|
||||
// Find the first-in-flow of the parent. (Ugh. This ends up
|
||||
// being O(N^2) when it is called O(N) times.)
|
||||
nsIFrame *parentFIF = mParent;
|
||||
for (;;) {
|
||||
nsIFrame *prevInFlow;
|
||||
parentFIF->GetPrevInFlow(&prevInFlow);
|
||||
if (!prevInFlow)
|
||||
break;
|
||||
parentFIF = prevInFlow;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
nsIFrame *specialParent;
|
||||
nsresult rv =
|
||||
frameManager->GetFrameProperty(parentFIF,
|
||||
nsLayoutAtoms::IBSplitSpecialPrevSibling,
|
||||
0, (void**)&specialParent);
|
||||
if (NS_OK == rv) {
|
||||
NS_ASSERTION(specialParent, "null special parent");
|
||||
*aSpecialParent = specialParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -282,8 +282,9 @@ public:
|
|||
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame);
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild);
|
||||
|
||||
// Check Style Visibility and mState for Selection (when printing)
|
||||
NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext,
|
||||
|
@ -375,6 +376,18 @@ public:
|
|||
nsIAtom* aAttribute,
|
||||
nsIAtom* aListName);
|
||||
|
||||
// Do the work for getting the parent style context frame so that
|
||||
// other frame's |GetParentStyleContextFrame| methods can call this
|
||||
// method on *another* frame. (This function handles out-of-flow
|
||||
// frames by using the frame manager's placeholder map and it handles
|
||||
// block-within-inline by calling |GetIBSpecialParent|.)
|
||||
nsresult DoGetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild);
|
||||
|
||||
nsresult GetIBSpecialParent(nsIPresContext* aPresContext,
|
||||
nsIFrame** aSpecialParent);
|
||||
|
||||
//Mouse Capturing code used by the frames to tell the view to capture all the following events
|
||||
NS_IMETHOD CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
|
||||
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
|
||||
|
|
|
@ -1091,15 +1091,25 @@ public:
|
|||
PRBool aCommandAdded) = 0;
|
||||
|
||||
/**
|
||||
* Get the frame that is the primary frame associated with the content.
|
||||
* aProviderFrame == this except in the case of an outer table, in
|
||||
* which case it is the inner table.
|
||||
* Get the frame whose style context should be the parent of this
|
||||
* frame's style context (i.e., provide the parent style context).
|
||||
* This frame must either be an ancestor of this frame or a child. If
|
||||
* this frame returns a child frame, then the child frame must be sure
|
||||
* to return a grandparent or higher!
|
||||
*
|
||||
* @param aPresContext: PresContext
|
||||
* @param aProviderFrame: Set to the primary frame associated with the content
|
||||
* @param aProviderFrame: The frame whose style context should be the
|
||||
* parent of this frame's style context. Null
|
||||
* is permitted, and means that this frame's
|
||||
* style context should be the root of the
|
||||
* style context tree.
|
||||
* @param aIsChild: True if |aProviderFrame| is set to a child
|
||||
* of this frame; false if it is an ancestor or
|
||||
* null.
|
||||
*/
|
||||
NS_IMETHOD GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame) = 0;
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild) = 0;
|
||||
|
||||
/**
|
||||
* Determines whether a frame is visible for painting
|
||||
|
|
|
@ -55,19 +55,6 @@ nsSplittableFrame::Init(nsIPresContext* aPresContext,
|
|||
// Hook the frame into the flow
|
||||
mPrevInFlow = aPrevInFlow;
|
||||
aPrevInFlow->SetNextInFlow(this);
|
||||
|
||||
// Make sure the general flags bits are the same
|
||||
nsFrameState state;
|
||||
aPrevInFlow->GetFrameState(&state);
|
||||
if ((state & NS_FRAME_SYNC_FRAME_AND_VIEW) == 0) {
|
||||
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
|
||||
}
|
||||
if (state & NS_FRAME_REPLACED_ELEMENT) {
|
||||
mState |= NS_FRAME_REPLACED_ELEMENT;
|
||||
}
|
||||
if (state & NS_FRAME_SELECTED_CONTENT) {
|
||||
mState |= NS_FRAME_SELECTED_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -336,33 +336,28 @@ nsFrame::Init(nsIPresContext* aPresContext,
|
|||
mContent = aContent;
|
||||
NS_IF_ADDREF(mContent);
|
||||
mParent = aParent;
|
||||
nsFrameState state;
|
||||
|
||||
if (aPrevInFlow) {
|
||||
// Make sure the general flags bits are the same
|
||||
nsFrameState state;
|
||||
aPrevInFlow->GetFrameState(&state);
|
||||
if ((state & NS_FRAME_SYNC_FRAME_AND_VIEW) == 0) {
|
||||
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
|
||||
}
|
||||
if (state & NS_FRAME_REPLACED_ELEMENT) {
|
||||
mState |= NS_FRAME_REPLACED_ELEMENT;
|
||||
}
|
||||
if (state & NS_FRAME_SELECTED_CONTENT) {
|
||||
mState |= NS_FRAME_SELECTED_CONTENT;
|
||||
}
|
||||
if (state & NS_FRAME_INDEPENDENT_SELECTION) {
|
||||
mState |= NS_FRAME_INDEPENDENT_SELECTION;
|
||||
}
|
||||
|
||||
// Make bits that are currently on (see constructor) the same:
|
||||
mState &= state | ~(NS_FRAME_SYNC_FRAME_AND_VIEW);
|
||||
|
||||
// Make bits that are currently off (see constructor) the same:
|
||||
mState |= state & (NS_FRAME_REPLACED_ELEMENT |
|
||||
NS_FRAME_SELECTED_CONTENT |
|
||||
NS_FRAME_INDEPENDENT_SELECTION |
|
||||
NS_FRAME_IS_SPECIAL);
|
||||
}
|
||||
if(mParent)
|
||||
{
|
||||
if (mParent) {
|
||||
nsFrameState state;
|
||||
mParent->GetFrameState(&state);
|
||||
if (state & NS_FRAME_INDEPENDENT_SELECTION) {
|
||||
mState |= NS_FRAME_INDEPENDENT_SELECTION;
|
||||
}
|
||||
if (state & NS_FRAME_GENERATED_CONTENT){
|
||||
mState |= NS_FRAME_GENERATED_CONTENT;
|
||||
}
|
||||
|
||||
// Make bits that are currently off (see constructor) the same:
|
||||
mState |= state & (NS_FRAME_INDEPENDENT_SELECTION |
|
||||
NS_FRAME_GENERATED_CONTENT);
|
||||
}
|
||||
return SetStyleContext(aPresContext, aContext);
|
||||
}
|
||||
|
@ -4006,10 +4001,85 @@ nsFrame::ReflowCommandNotify(nsIPresShell* aShell,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrame::GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame)
|
||||
nsFrame::GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild)
|
||||
{
|
||||
*aProviderFrame = this;
|
||||
return DoGetParentStyleContextFrame(aPresContext, aProviderFrame, aIsChild);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrame::DoGetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild)
|
||||
{
|
||||
*aIsChild = PR_FALSE;
|
||||
if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
|
||||
// If this frame is one of the blocks that split an inline, we must
|
||||
// return the "special" inline parent, i.e., the parent that this
|
||||
// frame would have if we didn't mangle the frame structure.
|
||||
return GetIBSpecialParent(aPresContext, aProviderFrame);
|
||||
}
|
||||
|
||||
// For out-of-flow frames, we must resolve underneath the
|
||||
// placeholder's parent.
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
nsIFrame *placeholder;
|
||||
frameManager->GetPlaceholderFrameFor(this, &placeholder);
|
||||
if (!placeholder) {
|
||||
NS_NOTREACHED("no placeholder frame for out-of-flow frame");
|
||||
GetIBSpecialParent(aPresContext, aProviderFrame);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_STATIC_CAST(nsFrame*, placeholder)->GetParent(aProviderFrame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent, corrected for the mangled frame tree resulting from
|
||||
* having a block within an inline. The result only differs from the
|
||||
* result of |GetParent| when |GetParent| returns an anonymous block
|
||||
* that was created for an element that was 'display: inline' because
|
||||
* that element contained a block.
|
||||
*/
|
||||
nsresult
|
||||
nsFrame::GetIBSpecialParent(nsIPresContext* aPresContext,
|
||||
nsIFrame** aSpecialParent)
|
||||
{
|
||||
*aSpecialParent = mParent;
|
||||
if (mParent) {
|
||||
nsFrameState parentState;
|
||||
mParent->GetFrameState(&parentState);
|
||||
if (parentState & NS_FRAME_IS_SPECIAL) {
|
||||
// Find the first-in-flow of the parent. (Ugh. This ends up
|
||||
// being O(N^2) when it is called O(N) times.)
|
||||
nsIFrame *parentFIF = mParent;
|
||||
for (;;) {
|
||||
nsIFrame *prevInFlow;
|
||||
parentFIF->GetPrevInFlow(&prevInFlow);
|
||||
if (!prevInFlow)
|
||||
break;
|
||||
parentFIF = prevInFlow;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
nsIFrame *specialParent;
|
||||
nsresult rv =
|
||||
frameManager->GetFrameProperty(parentFIF,
|
||||
nsLayoutAtoms::IBSplitSpecialPrevSibling,
|
||||
0, (void**)&specialParent);
|
||||
if (NS_OK == rv) {
|
||||
NS_ASSERTION(specialParent, "null special parent");
|
||||
*aSpecialParent = specialParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -282,8 +282,9 @@ public:
|
|||
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame);
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild);
|
||||
|
||||
// Check Style Visibility and mState for Selection (when printing)
|
||||
NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext,
|
||||
|
@ -375,6 +376,18 @@ public:
|
|||
nsIAtom* aAttribute,
|
||||
nsIAtom* aListName);
|
||||
|
||||
// Do the work for getting the parent style context frame so that
|
||||
// other frame's |GetParentStyleContextFrame| methods can call this
|
||||
// method on *another* frame. (This function handles out-of-flow
|
||||
// frames by using the frame manager's placeholder map and it handles
|
||||
// block-within-inline by calling |GetIBSpecialParent|.)
|
||||
nsresult DoGetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild);
|
||||
|
||||
nsresult GetIBSpecialParent(nsIPresContext* aPresContext,
|
||||
nsIFrame** aSpecialParent);
|
||||
|
||||
//Mouse Capturing code used by the frames to tell the view to capture all the following events
|
||||
NS_IMETHOD CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
|
||||
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
|
||||
|
|
|
@ -417,7 +417,6 @@ private:
|
|||
|
||||
void ReResolveStyleContext(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIStyleContext* aParentContext,
|
||||
nsIContent* aParentContent,
|
||||
PRInt32 aAttrNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -1275,8 +1274,6 @@ static void
|
|||
VerifyContextParent(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
||||
nsIStyleContext* aContext, nsIStyleContext* aParentContext)
|
||||
{
|
||||
nsIAtom* frameType;
|
||||
|
||||
// get the contexts not provided
|
||||
if (!aContext) {
|
||||
aFrame->GetStyleContext(&aContext);
|
||||
|
@ -1289,24 +1286,15 @@ VerifyContextParent(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
|||
// Get the correct parent context from the frame
|
||||
// - if the frame is a placeholder, we get the out of flow frame's context
|
||||
// as the parent context instead of asking the frame
|
||||
aFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder
|
||||
// get out of flow frame's context as the parent context
|
||||
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)aFrame)->GetOutOfFlowFrame();
|
||||
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
|
||||
outOfFlowFrame->GetStyleContext(&aParentContext);
|
||||
} else {
|
||||
// get the parent context from the frame (indirectly)
|
||||
nsIFrame* providerFrame = nsnull;
|
||||
aFrame->GetStyleContextProvider(aPresContext, &providerFrame);
|
||||
ENSURE_TRUE(providerFrame);
|
||||
nsCOMPtr<nsIStyleContext> providerContext;
|
||||
providerFrame->GetStyleContext(getter_AddRefs(providerContext));
|
||||
ENSURE_TRUE(providerContext);
|
||||
aParentContext = providerContext->GetParent(); // released later
|
||||
// aParentContext could still be null, since some contexts don't have parents
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
|
||||
// get the parent context from the frame (indirectly)
|
||||
nsIFrame* providerFrame = nsnull;
|
||||
PRBool providerIsChild;
|
||||
aFrame->GetParentStyleContextFrame(aPresContext,
|
||||
&providerFrame, &providerIsChild);
|
||||
if (providerFrame)
|
||||
providerFrame->GetStyleContext(&aParentContext);
|
||||
// aParentContext could still be null
|
||||
} else {
|
||||
// addref the parent context so we can release it at end
|
||||
NS_ADDREF(aParentContext);
|
||||
|
@ -1351,7 +1339,7 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext*
|
|||
nsIStyleContext* context;
|
||||
aFrame->GetStyleContext(&context);
|
||||
|
||||
VerifyContextParent(aPresContext, aFrame, context, aParentContext);
|
||||
VerifyContextParent(aPresContext, aFrame, context, nsnull);
|
||||
|
||||
PRInt32 listIndex = 0;
|
||||
nsIAtom* childList = nsnull;
|
||||
|
@ -1372,15 +1360,13 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext*
|
|||
// then verify the placeholder's context
|
||||
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
|
||||
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
|
||||
nsIStyleContext* outOfFlowContext;
|
||||
|
||||
// recurse to out of flow frame, letting the parent context get resolved
|
||||
VerifyStyleTree(aPresContext, outOfFlowFrame, nsnull);
|
||||
|
||||
// verify placeholder using the out of flow's context as parent context
|
||||
outOfFlowFrame->GetStyleContext(&outOfFlowContext);
|
||||
VerifyContextParent(aPresContext,child, nsnull, outOfFlowContext);
|
||||
NS_IF_RELEASE(outOfFlowContext);
|
||||
// verify placeholder using the parent frame's context as
|
||||
// parent context
|
||||
VerifyContextParent(aPresContext, child, nsnull, nsnull);
|
||||
}
|
||||
else { // regular frame
|
||||
VerifyStyleTree(aPresContext, child, nsnull);
|
||||
|
@ -1585,7 +1571,6 @@ CaptureChange(nsIStyleContext* aOldContext, nsIStyleContext* aNewContext,
|
|||
void
|
||||
FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIStyleContext* aParentContextIn,
|
||||
nsIContent* aParentContent,
|
||||
PRInt32 aAttrNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -1620,73 +1605,51 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIStyleContext> parentContext;
|
||||
nsIFrame* resolvedDescendant = nsnull;
|
||||
// Get the frame providing the style context. If it differs from aFrame, then
|
||||
// reslove the provider first, since the provider's context is the parent of aFrame's
|
||||
nsIFrame* resolvedChild = nsnull;
|
||||
// Get the frame providing the parent style context. If it is a
|
||||
// child, then resolve the provider first.
|
||||
nsIFrame* providerFrame = nsnull;
|
||||
aFrame->GetStyleContextProvider(aPresContext, &providerFrame);
|
||||
ENSURE_TRUE(providerFrame);
|
||||
if (providerFrame == aFrame) {
|
||||
if (aParentContextIn) {
|
||||
parentContext = aParentContextIn;
|
||||
NOISY_TRACE_FRAME("non-null parent context provided: using it and assuming already resolved",aFrame);
|
||||
} else {
|
||||
nsIFrame* parentFrame;
|
||||
aFrame->GetParent(&parentFrame);
|
||||
if (parentFrame) {
|
||||
parentFrame->GetStyleContext(getter_AddRefs(parentContext));
|
||||
}
|
||||
}
|
||||
PRBool providerIsChild = PR_FALSE;
|
||||
aFrame->GetParentStyleContextFrame(aPresContext,
|
||||
&providerFrame, &providerIsChild);
|
||||
if (!providerIsChild) {
|
||||
if (providerFrame)
|
||||
providerFrame->GetStyleContext(getter_AddRefs(parentContext));
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
// check to make sure that the provider is the child of aFrame
|
||||
nsIFrame* providerFrameParent;
|
||||
providerFrame->GetParent(&providerFrameParent);
|
||||
NS_ASSERTION(providerFrameParent == aFrame, "invalid style context provider");
|
||||
#endif
|
||||
// resolve the provider here (before aFrame below)
|
||||
nsCOMPtr<nsIStyleContext> providerContextParent;
|
||||
nsIFrame* grandParentFrame;
|
||||
aFrame->GetParent(&grandParentFrame);
|
||||
if (grandParentFrame) {
|
||||
grandParentFrame->GetStyleContext(getter_AddRefs(providerContextParent));
|
||||
}
|
||||
ReResolveStyleContext(aPresContext, providerFrame, providerContextParent, content,
|
||||
aAttrNameSpaceID, aAttribute, aChangeList, aMinChange, aResultChange);
|
||||
// the provider's new context becomes the parent context of aFrame's context
|
||||
ReResolveStyleContext(aPresContext, providerFrame, content,
|
||||
aAttrNameSpaceID, aAttribute, aChangeList,
|
||||
aMinChange, aResultChange);
|
||||
// The provider's new context becomes the parent context of
|
||||
// aFrame's context.
|
||||
providerFrame->GetStyleContext(getter_AddRefs(parentContext));
|
||||
resolvedDescendant = providerFrame; // don't want to re-resolve the provider again
|
||||
// Set |resolvedChild| so we don't bother resolving the
|
||||
// provider again.
|
||||
resolvedChild = providerFrame;
|
||||
}
|
||||
|
||||
// do primary context
|
||||
nsIStyleContext* newContext = nsnull;
|
||||
if (pseudoTag) {
|
||||
nsIContent* pseudoContent = (aParentContent) ? aParentContent : localContent;
|
||||
aPresContext->ResolvePseudoStyleContextFor(pseudoContent, pseudoTag, parentContext,
|
||||
if (pseudoTag == nsHTMLAtoms::mozNonElementPseudo) {
|
||||
NS_ASSERTION(localContent,
|
||||
"non pseudo-element frame without content node");
|
||||
aPresContext->ResolveStyleContextForNonElement(parentContext,
|
||||
PR_TRUE, &newContext);
|
||||
}
|
||||
else if (pseudoTag) {
|
||||
nsIContent* pseudoContent =
|
||||
aParentContent ? aParentContent : localContent;
|
||||
aPresContext->ResolvePseudoStyleContextFor(pseudoContent, pseudoTag,
|
||||
parentContext,
|
||||
PR_FALSE, &newContext);
|
||||
NS_RELEASE(pseudoTag);
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(localContent,
|
||||
"non pseudo-element frame without content node");
|
||||
// XXX This frame type check is a little ugly. However, it should
|
||||
// be cheaper than doing useless style resolution on placeholder
|
||||
// frames, and it should be able to go away if we make it so that
|
||||
// placeholder frames don't have style contexts at all.
|
||||
//
|
||||
// XXX We also probably need to descend into the style contexts of
|
||||
// the placeholder's out-of-flow frame.
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (content->IsContentOfType(nsIContent::eELEMENT) &&
|
||||
frameType != nsLayoutAtoms::placeholderFrame) {
|
||||
aPresContext->ResolveStyleContextFor(content, parentContext,
|
||||
PR_TRUE, &newContext);
|
||||
} else {
|
||||
aPresContext->ResolveStyleContextForNonElement(parentContext,
|
||||
PR_TRUE, &newContext);
|
||||
}
|
||||
aPresContext->ResolveStyleContextFor(content, parentContext,
|
||||
PR_TRUE, &newContext);
|
||||
}
|
||||
NS_ASSERTION(newContext, "failed to get new style context");
|
||||
if (newContext) {
|
||||
|
@ -1730,7 +1693,9 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
if (oldExtraContext) {
|
||||
nsIStyleContext* newExtraContext = nsnull;
|
||||
oldExtraContext->GetPseudoType(pseudoTag);
|
||||
NS_ASSERTION(pseudoTag, "extra style context is not pseudo element");
|
||||
NS_ASSERTION(pseudoTag &&
|
||||
pseudoTag != nsHTMLAtoms::mozNonElementPseudo,
|
||||
"extra style context is not pseudo element");
|
||||
result = aPresContext->ResolvePseudoStyleContextFor(content, pseudoTag, newContext,
|
||||
PR_FALSE, &newExtraContext);
|
||||
NS_RELEASE(pseudoTag);
|
||||
|
@ -1770,6 +1735,10 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
aPresContext->ResolveStyleContextFor(undisplayed->mContent, newContext,
|
||||
PR_TRUE, &undisplayedContext);
|
||||
}
|
||||
else if (pseudoTag == nsHTMLAtoms::mozNonElementPseudo) {
|
||||
aPresContext->ResolveStyleContextForNonElement(newContext,
|
||||
PR_TRUE, &undisplayedContext);
|
||||
}
|
||||
else { // pseudo element
|
||||
NS_ASSERTION(pseudoTag, "pseudo element without tag");
|
||||
aPresContext->ResolvePseudoStyleContextFor(localContent, pseudoTag, newContext, PR_FALSE,
|
||||
|
@ -1786,8 +1755,12 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {
|
||||
aChangeList.AppendChange(nsnull, ((undisplayed->mContent) ? undisplayed->mContent : localContent),
|
||||
NS_STYLE_HINT_FRAMECHANGE);
|
||||
NS_RELEASE(undisplayedContext);
|
||||
} else {
|
||||
// update the undisplayed node with the new context
|
||||
NS_RELEASE(undisplayed->mStyle);
|
||||
undisplayed->mStyle = undisplayedContext;
|
||||
}
|
||||
NS_RELEASE(undisplayedContext);
|
||||
}
|
||||
undisplayed = undisplayed->mNext;
|
||||
}
|
||||
|
@ -1805,42 +1778,40 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
|
|||
PRInt32 listIndex = 0;
|
||||
nsIAtom* childList = nsnull;
|
||||
PRInt32 childChange;
|
||||
nsIFrame* child;
|
||||
|
||||
do {
|
||||
child = nsnull;
|
||||
nsIFrame* child = nsnull;
|
||||
result = aFrame->FirstChild(aPresContext, childList, &child);
|
||||
while ((NS_SUCCEEDED(result)) && (child)) {
|
||||
while (NS_SUCCEEDED(result) && child) {
|
||||
nsFrameState state;
|
||||
child->GetFrameState(&state);
|
||||
if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) {
|
||||
if (!(state & NS_FRAME_OUT_OF_FLOW)) {
|
||||
// only do frames that are in flow
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
child->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::placeholderFrame == frameType.get()) { // placeholder
|
||||
// get out of flow frame and recurse there
|
||||
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
|
||||
if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder
|
||||
// get out of flow frame and recur there
|
||||
nsIFrame* outOfFlowFrame =
|
||||
NS_STATIC_CAST(nsPlaceholderFrame*,child)->GetOutOfFlowFrame();
|
||||
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
|
||||
NS_ASSERTION(outOfFlowFrame != resolvedChild,
|
||||
"out-of-flow frame not a true descendant");
|
||||
|
||||
if (outOfFlowFrame != resolvedDescendant) {
|
||||
ReResolveStyleContext(aPresContext, outOfFlowFrame, nsnull, content,
|
||||
aAttrNameSpaceID, aAttribute,
|
||||
aChangeList, aMinChange, childChange);
|
||||
} else {
|
||||
NOISY_TRACE("out of flow frame already resolved as descendent\n");
|
||||
}
|
||||
// |nsFrame::GetParentStyleContextFrame| checks being out
|
||||
// of flow so that this works correctly.
|
||||
ReResolveStyleContext(aPresContext, outOfFlowFrame, content,
|
||||
aAttrNameSpaceID, aAttribute,
|
||||
aChangeList, aMinChange, childChange);
|
||||
|
||||
// reresolve placeholder's context under out of flow frame
|
||||
nsIStyleContext* outOfFlowContext;
|
||||
outOfFlowFrame->GetStyleContext(&outOfFlowContext);
|
||||
ReResolveStyleContext(aPresContext, child, outOfFlowContext, content,
|
||||
// reresolve placeholder's context under the same parent
|
||||
// as the out-of-flow frame
|
||||
ReResolveStyleContext(aPresContext, child, content,
|
||||
kNameSpaceID_Unknown, nsnull,
|
||||
aChangeList, aMinChange, childChange);
|
||||
NS_RELEASE(outOfFlowContext);
|
||||
}
|
||||
else { // regular child frame
|
||||
if (child != resolvedDescendant) {
|
||||
ReResolveStyleContext(aPresContext, child, nsnull, content,
|
||||
if (child != resolvedChild) {
|
||||
ReResolveStyleContext(aPresContext, child, content,
|
||||
aAttrNameSpaceID, aAttribute,
|
||||
aChangeList, aMinChange, childChange);
|
||||
} else {
|
||||
|
@ -1884,18 +1855,13 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext,
|
|||
#endif
|
||||
|
||||
do {
|
||||
nsIStyleContext* styleContext = nsnull;
|
||||
frame->GetStyleContext(&styleContext);
|
||||
nsIStyleContext* parentContext = styleContext->GetParent();
|
||||
PRInt32 frameChange;
|
||||
ReResolveStyleContext(aPresContext, frame, parentContext, nsnull,
|
||||
ReResolveStyleContext(aPresContext, frame, nsnull,
|
||||
aAttrNameSpaceID, aAttribute,
|
||||
aChangeList, aMinChange, frameChange);
|
||||
#ifdef NS_DEBUG
|
||||
VerifyStyleTree(aPresContext, frame, parentContext);
|
||||
VerifyStyleTree(aPresContext, frame, nsnull);
|
||||
#endif
|
||||
NS_IF_RELEASE(parentContext);
|
||||
NS_RELEASE(styleContext);
|
||||
if (aTopLevelChange < frameChange) {
|
||||
aTopLevelChange = frameChange;
|
||||
}
|
||||
|
|
|
@ -55,19 +55,6 @@ nsSplittableFrame::Init(nsIPresContext* aPresContext,
|
|||
// Hook the frame into the flow
|
||||
mPrevInFlow = aPrevInFlow;
|
||||
aPrevInFlow->SetNextInFlow(this);
|
||||
|
||||
// Make sure the general flags bits are the same
|
||||
nsFrameState state;
|
||||
aPrevInFlow->GetFrameState(&state);
|
||||
if ((state & NS_FRAME_SYNC_FRAME_AND_VIEW) == 0) {
|
||||
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
|
||||
}
|
||||
if (state & NS_FRAME_REPLACED_ELEMENT) {
|
||||
mState |= NS_FRAME_REPLACED_ELEMENT;
|
||||
}
|
||||
if (state & NS_FRAME_SELECTED_CONTENT) {
|
||||
mState |= NS_FRAME_SELECTED_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -384,7 +384,7 @@ GetSpecialSibling(nsIFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame** a
|
|||
}
|
||||
|
||||
void* value;
|
||||
aFrameManager->GetFrameProperty(aFrame, nsLayoutAtoms::inlineFrameAnnotation, 0, &value);
|
||||
aFrameManager->GetFrameProperty(aFrame, nsLayoutAtoms::IBSplitSpecialSibling, 0, &value);
|
||||
*aResult = NS_STATIC_CAST(nsIFrame*, value);
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,8 @@ SetFrameIsSpecial(nsIFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame* aS
|
|||
|
||||
// Store the "special sibling" (if we were given one) with the
|
||||
// first frame in the flow.
|
||||
aFrameManager->SetFrameProperty(aFrame, nsLayoutAtoms::inlineFrameAnnotation,
|
||||
aFrameManager->SetFrameProperty(aFrame,
|
||||
nsLayoutAtoms::IBSplitSpecialSibling,
|
||||
aSpecialSibling, nsnull);
|
||||
}
|
||||
}
|
||||
|
@ -492,10 +493,7 @@ IsBlockFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
|||
// don't we use display->IsBlockLevel() here?
|
||||
const nsStyleDisplay* display;
|
||||
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
|
||||
if (NS_STYLE_DISPLAY_INLINE == display->mDisplay) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
return NS_STYLE_DISPLAY_INLINE != display->mDisplay;
|
||||
}
|
||||
|
||||
static nsIFrame*
|
||||
|
@ -527,6 +525,27 @@ FindLastBlock(nsIPresContext* aPresContext, nsIFrame* aKid)
|
|||
return lastBlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlike the special (next) sibling, the special previous sibling
|
||||
* property points only from the anonymous block to the original inline
|
||||
* that preceded it. It is useful for finding the "special parent" of a
|
||||
* frame (i.e., a frame from which a good parent style context can be
|
||||
* obtained), one looks at the special previous sibling annotation of
|
||||
* the real parent of the frame (if the real parent has
|
||||
* NS_FRAME_IS_SPECIAL).
|
||||
*/
|
||||
inline void
|
||||
MarkIBSpecialPrevSibling(nsIPresContext* aPresContext,
|
||||
nsIFrameManager *aFrameManager,
|
||||
nsIFrame *aAnonymousFrame,
|
||||
nsIFrame *aSpecialParent)
|
||||
{
|
||||
aFrameManager->SetFrameProperty(aAnonymousFrame,
|
||||
nsLayoutAtoms::IBSplitSpecialPrevSibling,
|
||||
aSpecialParent,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves frames to a new parent, updating the style context and
|
||||
* propagating relevant frame state bits. |aNewParentSC| may be null,
|
||||
|
@ -3803,7 +3822,9 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell,
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
// The placeholder frame gets a pseudo style context
|
||||
nsCOMPtr<nsIStyleContext> placeholderStyle;
|
||||
aPresContext->ResolveStyleContextForNonElement(aStyleContext, PR_FALSE,
|
||||
nsCOMPtr<nsIStyleContext> parentContext =
|
||||
dont_AddRef(aStyleContext->GetParent());
|
||||
aPresContext->ResolveStyleContextForNonElement(parentContext, PR_FALSE,
|
||||
getter_AddRefs(placeholderStyle));
|
||||
placeholderFrame->Init(aPresContext, aContent, aParentFrame,
|
||||
placeholderStyle, nsnull);
|
||||
|
@ -9231,15 +9252,18 @@ DeletingFrameSubtree(nsIPresContext* aPresContext,
|
|||
if (aFrameManager) {
|
||||
nsAutoVoidArray destroyQueue;
|
||||
|
||||
while (aFrame) {
|
||||
// If it's a "special" block-in-inline frame, then we need to
|
||||
// remember to delete our special siblings, too.
|
||||
if (IsFrameSpecial(aFrame)) {
|
||||
nsIFrame* specialSibling;
|
||||
GetSpecialSibling(aFrameManager, aFrame, &specialSibling);
|
||||
DeletingFrameSubtree(aPresContext, aPresShell, aFrameManager, specialSibling);
|
||||
}
|
||||
// If it's a "special" block-in-inline frame, then we need to
|
||||
// remember to delete our special siblings, too. Since every one of
|
||||
// the next-in-flows has the same special sibling, just do this
|
||||
// once, rather than in the loop below.
|
||||
if (IsFrameSpecial(aFrame)) {
|
||||
nsIFrame* specialSibling;
|
||||
GetSpecialSibling(aFrameManager, aFrame, &specialSibling);
|
||||
DeletingFrameSubtree(aPresContext, aPresShell, aFrameManager,
|
||||
specialSibling);
|
||||
}
|
||||
|
||||
while (aFrame) {
|
||||
DoDeletingFrameSubtree(aPresContext, aPresShell, aFrameManager,
|
||||
destroyQueue, aFrame, aFrame);
|
||||
|
||||
|
@ -10483,9 +10507,15 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
|||
nsIFrame* primaryFrame;
|
||||
shell->GetPrimaryFrameFor(aContent, &primaryFrame);
|
||||
// Get the frame associated with the content whose style context is highest in the style context tree
|
||||
nsIFrame* primaryStyleFrame = nsnull;
|
||||
nsIFrame* primaryStyleFrame = primaryFrame;
|
||||
if (primaryFrame) {
|
||||
primaryFrame->GetStyleContextProvider(aPresContext, &primaryStyleFrame);
|
||||
PRBool providerIsChild = PR_FALSE;
|
||||
nsIFrame *styleContextProvider;
|
||||
primaryFrame->GetParentStyleContextFrame(aPresContext,
|
||||
&styleContextProvider,
|
||||
&providerIsChild);
|
||||
if (providerIsChild)
|
||||
primaryStyleFrame = styleContextProvider;
|
||||
}
|
||||
|
||||
PRBool reconstruct = PR_FALSE;
|
||||
|
@ -11220,6 +11250,8 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresShell* aPresShell,
|
|||
lastBlock->SetNextSibling(nsnull);
|
||||
|
||||
// Create "special" inline-block linkage between the frames
|
||||
// XXXldb Do we really need to do this? It doesn't seem
|
||||
// consistent with the use in ConstructInline.
|
||||
SetFrameIsSpecial(state.mFrameManager, list1, list2);
|
||||
SetFrameIsSpecial(state.mFrameManager, list2, list3);
|
||||
SetFrameIsSpecial(state.mFrameManager, list3, nsnull);
|
||||
|
@ -13742,6 +13774,8 @@ nsCSSFrameConstructor::ConstructInline(nsIPresShell* aPresShell,
|
|||
// containing block will be reframed instead.
|
||||
SetFrameIsSpecial(aState.mFrameManager, aNewFrame, blockFrame);
|
||||
SetFrameIsSpecial(aState.mFrameManager, blockFrame, inlineFrame);
|
||||
MarkIBSpecialPrevSibling(aPresContext, aState.mFrameManager,
|
||||
blockFrame, aNewFrame);
|
||||
|
||||
if (inlineFrame)
|
||||
SetFrameIsSpecial(aState.mFrameManager, inlineFrame, nsnull);
|
||||
|
@ -14169,6 +14203,7 @@ nsCSSFrameConstructor::SplitToContainingBlock(nsIPresContext* aPresContext,
|
|||
// Create an anonymous inline frame that will parent
|
||||
// aRightInlineChildFrame. The new frame won't have a parent yet:
|
||||
// the recursion will parent it.
|
||||
// XXXldb Why bother if |aRightInlineChildFrame| is null?
|
||||
nsIFrame* inlineFrame = nsnull;
|
||||
NS_NewInlineFrame(shell, &inlineFrame);
|
||||
if (! inlineFrame)
|
||||
|
@ -14196,6 +14231,9 @@ nsCSSFrameConstructor::SplitToContainingBlock(nsIPresContext* aPresContext,
|
|||
SetFrameIsSpecial(aState.mFrameManager, blockFrame, inlineFrame);
|
||||
SetFrameIsSpecial(aState.mFrameManager, inlineFrame, nsnull);
|
||||
|
||||
MarkIBSpecialPrevSibling(aPresContext, aState.mFrameManager,
|
||||
blockFrame, firstInFlow);
|
||||
|
||||
// If we have a continuation frame, then we need to break the
|
||||
// continuation.
|
||||
nsIFrame* nextInFlow;
|
||||
|
|
|
@ -175,6 +175,19 @@ struct BCPropertyData
|
|||
PRUint8 mLeftBorderWidth;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableFrame::GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild)
|
||||
{
|
||||
// Since our parent, the table outer frame, returned this frame, we
|
||||
// must return whatever our parent would normally have returned.
|
||||
|
||||
NS_PRECONDITION(mParent, "table constructed without outer table");
|
||||
return NS_STATIC_CAST(nsFrame*, mParent)->
|
||||
DoGetParentStyleContextFrame(aPresContext, aProviderFrame, aIsChild);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableFrame::GetFrameType(nsIAtom** aType) const
|
||||
|
|
|
@ -381,6 +381,10 @@ public:
|
|||
|
||||
nsFrameList& GetColGroups();
|
||||
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild);
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
|
|
|
@ -414,20 +414,30 @@ NS_IMETHODIMP nsTableOuterFrame::SetSelected(nsIPresContext* aPresContext,
|
|||
return result;
|
||||
}
|
||||
|
||||
// GetStyleContextProvider:
|
||||
// The innerTableFame is the style context provider, which is cached in a data member
|
||||
NS_IMETHODIMP
|
||||
nsTableOuterFrame::GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame)
|
||||
nsTableOuterFrame::GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild)
|
||||
{
|
||||
NS_ASSERTION(aProviderFrame && aPresContext, "null argument: aPresContext and-or aProviderFrame");
|
||||
if (aProviderFrame) {
|
||||
if (mInnerTableFrame)
|
||||
*aProviderFrame = mInnerTableFrame;
|
||||
else
|
||||
*aProviderFrame = this;
|
||||
// The table outer frame and the (inner) table frame split the style
|
||||
// data by giving the table frame the style context associated with
|
||||
// the table content node and creating a style context for the outer
|
||||
// frame that is a *child* of the table frame's style context,
|
||||
// matching the :table-outer (should be :-moz-table-outer!)
|
||||
// pseudo-element. html.css has a rule that causes that
|
||||
// pseudo-element (and thus the outer table) to inherit *some* style
|
||||
// properties from the table frame. The children of the table inherit
|
||||
// directly from the inner table, and the outer table's style context
|
||||
// is a leaf.
|
||||
|
||||
if (!mInnerTableFrame) {
|
||||
*aProviderFrame = this;
|
||||
*aIsChild = PR_FALSE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return (aProviderFrame && mInnerTableFrame) ? NS_OK : NS_ERROR_FAILURE;
|
||||
*aProviderFrame = mInnerTableFrame;
|
||||
*aIsChild = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// INCREMENTAL REFLOW HELPER FUNCTIONS
|
||||
|
|
|
@ -171,8 +171,9 @@ public:
|
|||
*/
|
||||
nscoord GetMinCaptionWidth();
|
||||
|
||||
NS_IMETHOD GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame);
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild);
|
||||
|
||||
/*---------------- nsITableLayout methods ------------------------*/
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "nsRuleWalker.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
||||
#ifdef MOZ_PERF_METRICS
|
||||
#include "nsITimeRecorder.h"
|
||||
|
@ -1109,7 +1110,8 @@ nsIStyleContext* StyleSetImpl::ResolveStyleForNonElement(
|
|||
mDocRuleProcessors ||
|
||||
mOverrideRuleProcessors) {
|
||||
EnsureRuleWalker(aPresContext);
|
||||
result = GetContext(aPresContext, aParentContext, nsnull, aForceUnique);
|
||||
result = GetContext(aPresContext, aParentContext,
|
||||
nsHTMLAtoms::mozNonElementPseudo, aForceUnique);
|
||||
NS_ASSERTION(mRuleWalker->AtRoot(), "rule walker must be at root");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,6 +175,19 @@ struct BCPropertyData
|
|||
PRUint8 mLeftBorderWidth;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableFrame::GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild)
|
||||
{
|
||||
// Since our parent, the table outer frame, returned this frame, we
|
||||
// must return whatever our parent would normally have returned.
|
||||
|
||||
NS_PRECONDITION(mParent, "table constructed without outer table");
|
||||
return NS_STATIC_CAST(nsFrame*, mParent)->
|
||||
DoGetParentStyleContextFrame(aPresContext, aProviderFrame, aIsChild);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableFrame::GetFrameType(nsIAtom** aType) const
|
||||
|
|
|
@ -381,6 +381,10 @@ public:
|
|||
|
||||
nsFrameList& GetColGroups();
|
||||
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild);
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
|
|
|
@ -414,20 +414,30 @@ NS_IMETHODIMP nsTableOuterFrame::SetSelected(nsIPresContext* aPresContext,
|
|||
return result;
|
||||
}
|
||||
|
||||
// GetStyleContextProvider:
|
||||
// The innerTableFame is the style context provider, which is cached in a data member
|
||||
NS_IMETHODIMP
|
||||
nsTableOuterFrame::GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame)
|
||||
nsTableOuterFrame::GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild)
|
||||
{
|
||||
NS_ASSERTION(aProviderFrame && aPresContext, "null argument: aPresContext and-or aProviderFrame");
|
||||
if (aProviderFrame) {
|
||||
if (mInnerTableFrame)
|
||||
*aProviderFrame = mInnerTableFrame;
|
||||
else
|
||||
*aProviderFrame = this;
|
||||
// The table outer frame and the (inner) table frame split the style
|
||||
// data by giving the table frame the style context associated with
|
||||
// the table content node and creating a style context for the outer
|
||||
// frame that is a *child* of the table frame's style context,
|
||||
// matching the :table-outer (should be :-moz-table-outer!)
|
||||
// pseudo-element. html.css has a rule that causes that
|
||||
// pseudo-element (and thus the outer table) to inherit *some* style
|
||||
// properties from the table frame. The children of the table inherit
|
||||
// directly from the inner table, and the outer table's style context
|
||||
// is a leaf.
|
||||
|
||||
if (!mInnerTableFrame) {
|
||||
*aProviderFrame = this;
|
||||
*aIsChild = PR_FALSE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return (aProviderFrame && mInnerTableFrame) ? NS_OK : NS_ERROR_FAILURE;
|
||||
*aProviderFrame = mInnerTableFrame;
|
||||
*aIsChild = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// INCREMENTAL REFLOW HELPER FUNCTIONS
|
||||
|
|
|
@ -171,8 +171,9 @@ public:
|
|||
*/
|
||||
nscoord GetMinCaptionWidth();
|
||||
|
||||
NS_IMETHOD GetStyleContextProvider(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame);
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
PRBool* aIsChild);
|
||||
|
||||
/*---------------- nsITableLayout methods ------------------------*/
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче