зеркало из https://github.com/mozilla/pjs.git
Bug 500882 part 2. Switch setting of primary frames to the new API; switch nsFrameManager::GetPrimaryFrameFor to the new API; remove resulting gobs of dead code. r=roc
This commit is contained in:
Родитель
f62bd5f370
Коммит
644c5ccda9
|
@ -884,7 +884,11 @@ public:
|
|||
* frame is the out of flow frame, not the placeholder.
|
||||
*/
|
||||
nsIFrame* GetPrimaryFrame() const { return mPrimaryFrame; }
|
||||
void SetPrimaryFrame(nsIFrame* aFrame) { mPrimaryFrame = aFrame; }
|
||||
void SetPrimaryFrame(nsIFrame* aFrame) {
|
||||
NS_PRECONDITION(!aFrame || !mPrimaryFrame,
|
||||
"Losing track of existing primary frame");
|
||||
mPrimaryFrame = aFrame;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
/*
|
||||
|
|
|
@ -239,7 +239,6 @@ nsIXBLService * nsCSSFrameConstructor::gXBLService = nsnull;
|
|||
static PRBool gNoisyContentUpdates = PR_FALSE;
|
||||
static PRBool gReallyNoisyContentUpdates = PR_FALSE;
|
||||
static PRBool gNoisyInlineConstruction = PR_FALSE;
|
||||
static PRBool gVerifyFastFindFrame = PR_FALSE;
|
||||
|
||||
struct FrameCtorDebugFlags {
|
||||
const char* name;
|
||||
|
@ -249,8 +248,7 @@ struct FrameCtorDebugFlags {
|
|||
static FrameCtorDebugFlags gFlags[] = {
|
||||
{ "content-updates", &gNoisyContentUpdates },
|
||||
{ "really-noisy-content-updates", &gReallyNoisyContentUpdates },
|
||||
{ "noisy-inline", &gNoisyInlineConstruction },
|
||||
{ "fast-find-frame", &gVerifyFastFindFrame }
|
||||
{ "noisy-inline", &gNoisyInlineConstruction }
|
||||
};
|
||||
|
||||
#define NUM_DEBUG_FLAGS (sizeof(gFlags) / sizeof(gFlags[0]))
|
||||
|
@ -2489,7 +2487,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIContent* aDocEle
|
|||
}
|
||||
|
||||
// set the primary frame
|
||||
state.mFrameManager->SetPrimaryFrameFor(aDocElement, contentFrame);
|
||||
aDocElement->SetPrimaryFrame(contentFrame);
|
||||
|
||||
NS_ASSERTION(processChildren ? !mRootElementFrame :
|
||||
mRootElementFrame == contentFrame,
|
||||
|
@ -3433,9 +3431,8 @@ nsCSSFrameConstructor::ConstructTextFrame(const FrameConstructionData* aData,
|
|||
// Add the newly constructed frame to the flow
|
||||
aFrameItems.AddChild(newFrame);
|
||||
|
||||
// Text frames don't go in the content->frame hash table, because
|
||||
// they're anonymous. This keeps the hash table smaller
|
||||
|
||||
aContent->SetPrimaryFrame(newFrame);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -3550,8 +3547,7 @@ nsCSSFrameConstructor::FindHTMLData(nsIContent* aContent,
|
|||
SIMPLE_TAG_CHAIN(mozgeneratedcontentimage,
|
||||
nsCSSFrameConstructor::FindImgData),
|
||||
{ &nsGkAtoms::br,
|
||||
FCDATA_DECL(FCDATA_SKIP_FRAMEMAP | FCDATA_IS_LINE_PARTICIPANT |
|
||||
FCDATA_IS_LINE_BREAK,
|
||||
FCDATA_DECL(FCDATA_IS_LINE_PARTICIPANT | FCDATA_IS_LINE_BREAK,
|
||||
NS_NewBRFrame) },
|
||||
SIMPLE_TAG_CREATE(wbr, NS_NewWBRFrame),
|
||||
SIMPLE_TAG_CHAIN(input, nsCSSFrameConstructor::FindInputData),
|
||||
|
@ -3747,9 +3743,8 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
|
|||
display->IsScrollableOverflow()) {
|
||||
BuildScrollFrame(aState, content, styleContext, newFrame,
|
||||
geometricParent, frameToAddToList);
|
||||
// No need to add to frame map later, since BuildScrollFrame did it
|
||||
// already
|
||||
bits |= FCDATA_SKIP_FRAMEMAP;
|
||||
// No need to set the primary frame, since BuildScrollFrame did it already
|
||||
bits |= FCDATA_SKIP_FRAMESET;
|
||||
} else {
|
||||
rv = InitAndRestoreFrame(aState, content, geometricParent, nsnull,
|
||||
newFrame);
|
||||
|
@ -3855,8 +3850,8 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
|
|||
((bits & FCDATA_IS_LINE_PARTICIPANT) != 0),
|
||||
"Incorrectly set FCDATA_IS_LINE_PARTICIPANT bits");
|
||||
|
||||
if (!(bits & FCDATA_SKIP_FRAMEMAP)) {
|
||||
aState.mFrameManager->SetPrimaryFrameFor(aItem.mContent, newFrame);
|
||||
if (!(bits & FCDATA_SKIP_FRAMESET)) {
|
||||
aItem.mContent->SetPrimaryFrame(newFrame);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -4334,7 +4329,7 @@ nsCSSFrameConstructor::BuildScrollFrame(nsFrameConstructorState& aState,
|
|||
FinishBuildingScrollFrame(aNewFrame, aScrolledFrame);
|
||||
|
||||
// now set the primary frame to the ScrollFrame
|
||||
aState.mFrameManager->SetPrimaryFrameFor( aContent, aNewFrame );
|
||||
aContent->SetPrimaryFrame(aNewFrame);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
@ -4394,56 +4389,50 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
|
|||
// find them if we need to.
|
||||
// XXXbz the "quickly" part is a bald-faced lie!
|
||||
{ NS_STYLE_DISPLAY_INLINE,
|
||||
FULL_CTOR_FCDATA(FCDATA_SKIP_FRAMEMAP | FCDATA_IS_INLINE |
|
||||
FCDATA_IS_LINE_PARTICIPANT,
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_INLINE | FCDATA_IS_LINE_PARTICIPANT,
|
||||
&nsCSSFrameConstructor::ConstructInline) },
|
||||
{ NS_STYLE_DISPLAY_MARKER,
|
||||
FULL_CTOR_FCDATA(FCDATA_SKIP_FRAMEMAP | FCDATA_IS_INLINE |
|
||||
FCDATA_IS_LINE_PARTICIPANT,
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_INLINE | FCDATA_IS_LINE_PARTICIPANT,
|
||||
&nsCSSFrameConstructor::ConstructInline) },
|
||||
{ NS_STYLE_DISPLAY_TABLE,
|
||||
FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
|
||||
{ NS_STYLE_DISPLAY_INLINE_TABLE,
|
||||
FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_CAPTION,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FCDATA_ALLOW_BLOCK_STYLES | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_ALLOW_BLOCK_STYLES |
|
||||
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableCaptionFrame) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_ROW_GROUP,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_MAY_NEED_SCROLLFRAME |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_MAY_NEED_SCROLLFRAME | FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableRowGroupFrame) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_HEADER_GROUP,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_MAY_NEED_SCROLLFRAME |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_MAY_NEED_SCROLLFRAME | FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableRowGroupFrame) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_MAY_NEED_SCROLLFRAME |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_MAY_NEED_SCROLLFRAME | FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableRowGroupFrame) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableColGroupFrame) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_COLUMN,
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeColGroup),
|
||||
&nsCSSFrameConstructor::ConstructTableCol) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_ROW,
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
|
||||
&nsCSSFrameConstructor::ConstructTableRow) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_CELL,
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
|
||||
&nsCSSFrameConstructor::ConstructTableCell) }
|
||||
};
|
||||
|
@ -4644,8 +4633,7 @@ nsCSSFrameConstructor::FlushAccumulatedBlock(nsFrameConstructorState& aState,
|
|||
{ &nsGkAtoms::_tag, \
|
||||
FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW | \
|
||||
FCDATA_FORCE_NULL_ABSPOS_CONTAINER | \
|
||||
FCDATA_WRAP_KIDS_IN_BLOCKS | \
|
||||
FCDATA_SKIP_FRAMEMAP, _func) }
|
||||
FCDATA_WRAP_KIDS_IN_BLOCKS, _func) }
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
|
@ -4663,17 +4651,14 @@ nsCSSFrameConstructor::FindMathMLData(nsIContent* aContent,
|
|||
if (aStyleContext->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_BLOCK) {
|
||||
static const FrameConstructionData sBlockMathData =
|
||||
FCDATA_DECL(FCDATA_FORCE_NULL_ABSPOS_CONTAINER |
|
||||
FCDATA_WRAP_KIDS_IN_BLOCKS |
|
||||
FCDATA_SKIP_FRAMEMAP,
|
||||
FCDATA_WRAP_KIDS_IN_BLOCKS,
|
||||
NS_CreateNewMathMLmathBlockFrame);
|
||||
return &sBlockMathData;
|
||||
}
|
||||
|
||||
static const FrameConstructionData sInlineMathData =
|
||||
FCDATA_DECL(FCDATA_FORCE_NULL_ABSPOS_CONTAINER |
|
||||
FCDATA_WRAP_KIDS_IN_BLOCKS |
|
||||
FCDATA_SKIP_FRAMEMAP |
|
||||
FCDATA_IS_LINE_PARTICIPANT,
|
||||
FCDATA_WRAP_KIDS_IN_BLOCKS,
|
||||
NS_NewMathMLmathInlineFrame);
|
||||
return &sInlineMathData;
|
||||
}
|
||||
|
@ -4718,7 +4703,7 @@ nsCSSFrameConstructor::FindMathMLData(nsIContent* aContent,
|
|||
// should be in-flow.
|
||||
#define SIMPLE_SVG_FCDATA(_func) \
|
||||
FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW | \
|
||||
FCDATA_SKIP_ABSPOS_PUSH | FCDATA_SKIP_FRAMEMAP | \
|
||||
FCDATA_SKIP_ABSPOS_PUSH | \
|
||||
FCDATA_DISALLOW_GENERATED_CONTENT, _func)
|
||||
#define SIMPLE_SVG_CREATE(_tag, _func) \
|
||||
{ &nsGkAtoms::_tag, SIMPLE_SVG_FCDATA(_func) }
|
||||
|
@ -4770,8 +4755,6 @@ nsCSSFrameConstructor::FindSVGData(nsIContent* aContent,
|
|||
//
|
||||
// Style mutation can't change this situation, so don't bother
|
||||
// adding to the undisplayed content map.
|
||||
// XXXbz except of course that this makes GetPrimaryFrameFor for this stuff
|
||||
// that much slower.
|
||||
//
|
||||
// We don't currently handle any UI for desc/title
|
||||
return &sSuppressData;
|
||||
|
@ -4801,7 +4784,7 @@ nsCSSFrameConstructor::FindSVGData(nsIContent* aContent,
|
|||
|
||||
static const FrameConstructionData sOuterSVGData =
|
||||
FCDATA_DECL(FCDATA_FORCE_VIEW | FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_SKIP_FRAMEMAP | FCDATA_DISALLOW_GENERATED_CONTENT,
|
||||
FCDATA_DISALLOW_GENERATED_CONTENT,
|
||||
NS_NewSVGOuterSVGFrame);
|
||||
return &sOuterSVGData;
|
||||
}
|
||||
|
@ -4980,7 +4963,7 @@ nsCSSFrameConstructor::AddPageBreakItem(nsIContent* aContent,
|
|||
NS_STYLE_DISPLAY_BLOCK, "Unexpected display");
|
||||
|
||||
static const FrameConstructionData sPageBreakData =
|
||||
FCDATA_DECL(FCDATA_SKIP_FRAMEMAP, NS_NewPageBreakFrame);
|
||||
FCDATA_DECL(FCDATA_SKIP_FRAMESET, NS_NewPageBreakFrame);
|
||||
|
||||
// Lie about the tag and namespace so we don't trigger anything
|
||||
// interesting during frame construction.
|
||||
|
@ -7486,8 +7469,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
|||
"Reflow hint bits set without actually asking for a reflow");
|
||||
|
||||
if (frame && frame->GetContent() != content) {
|
||||
// XXXbz this is due to image maps messing with the primary frame map.
|
||||
// See bug 135040. Remove this block once that's fixed.
|
||||
// XXXbz this is due to image maps messing with the primary frame of
|
||||
// <area>s. See bug 135040. Remove this block once that's fixed.
|
||||
frame = nsnull;
|
||||
if (!(hint & nsChangeHint_ReconstructFrame)) {
|
||||
continue;
|
||||
|
@ -7576,8 +7559,8 @@ nsCSSFrameConstructor::RestyleElement(nsIContent *aContent,
|
|||
NS_ASSERTION(aPrimaryFrame == mPresShell->GetPrimaryFrameFor(aContent),
|
||||
"frame/content mismatch");
|
||||
if (aPrimaryFrame && aPrimaryFrame->GetContent() != aContent) {
|
||||
// XXXbz this is due to image maps messing with the primary frame mapping.
|
||||
// See bug 135040. We can remove this block once that's fixed.
|
||||
// XXXbz this is due to image maps messing with the primary frame pointer
|
||||
// of <area>s. See bug 135040. We can remove this block once that's fixed.
|
||||
aPrimaryFrame = nsnull;
|
||||
}
|
||||
NS_ASSERTION(!aPrimaryFrame || aPrimaryFrame->GetContent() == aContent,
|
||||
|
@ -8290,251 +8273,6 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsBindingAncestor(nsIContent* aContent, nsIContent* aBindingRoot)
|
||||
{
|
||||
while (PR_TRUE) {
|
||||
// Native-anonymous content doesn't contain insertion points, so
|
||||
// we don't need to search through it.
|
||||
if (aContent->IsRootOfNativeAnonymousSubtree())
|
||||
return PR_FALSE;
|
||||
nsIContent* bindingParent = aContent->GetBindingParent();
|
||||
if (!bindingParent)
|
||||
return PR_FALSE;
|
||||
if (bindingParent == aBindingRoot)
|
||||
return PR_TRUE;
|
||||
aContent = bindingParent;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function that searches the immediate child frames
|
||||
// (and their children if the frames are "special")
|
||||
// for a frame that maps the specified content object
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::FindFrameWithContent(nsFrameManager* aFrameManager,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIContent* aParentContent,
|
||||
nsIContent* aContent,
|
||||
nsFindFrameHint* aHint)
|
||||
{
|
||||
NS_PRECONDITION(aParentFrame, "Must have a frame");
|
||||
|
||||
#ifdef NOISY_FINDFRAME
|
||||
FFWC_totalCount++;
|
||||
printf("looking for content=%p, given aParentFrame %p parentContent %p, hint is %s\n",
|
||||
aContent, aParentFrame, aParentContent, aHint ? "set" : "NULL");
|
||||
#endif
|
||||
|
||||
// Search for the frame in each child list that aParentFrame supports.
|
||||
nsIAtom* listName = nsnull;
|
||||
PRInt32 listIndex = 0;
|
||||
PRBool searchAgain;
|
||||
|
||||
do {
|
||||
#ifdef NOISY_FINDFRAME
|
||||
FFWC_doLoop++;
|
||||
#endif
|
||||
nsIFrame* kidFrame = nsnull;
|
||||
|
||||
searchAgain = PR_FALSE;
|
||||
|
||||
// if we were given an hint, try to use it here to find a good
|
||||
// previous frame to start our search (|kidFrame|).
|
||||
if (aHint) {
|
||||
#ifdef NOISY_FINDFRAME
|
||||
printf(" hint frame is %p\n", aHint->mPrimaryFrameForPrevSibling);
|
||||
#endif
|
||||
// start with the primary frame for aContent's previous sibling
|
||||
kidFrame = aHint->mPrimaryFrameForPrevSibling;
|
||||
// But if it's out of flow, start from its placeholder.
|
||||
if (kidFrame && (kidFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
|
||||
kidFrame = aFrameManager->GetPlaceholderFrameFor(kidFrame);
|
||||
}
|
||||
|
||||
if (kidFrame) {
|
||||
// then use the next sibling frame as our starting point
|
||||
if (kidFrame->GetNextSibling()) {
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
}
|
||||
else {
|
||||
// The hint frame had no next sibling. Try the next-in-flow or
|
||||
// special sibling of the parent of the hint frame (or its
|
||||
// associated placeholder).
|
||||
nsIFrame *parentFrame = kidFrame->GetParent();
|
||||
kidFrame = nsnull;
|
||||
if (parentFrame) {
|
||||
parentFrame = nsLayoutUtils::GetNextContinuationOrSpecialSibling(parentFrame);
|
||||
}
|
||||
if (parentFrame) {
|
||||
// Found it, continue the search with its first child.
|
||||
kidFrame = parentFrame->GetFirstChild(listName);
|
||||
// Leave |aParentFrame| as-is, since the only time we'll
|
||||
// reuse it is if the hint fails.
|
||||
}
|
||||
}
|
||||
#ifdef NOISY_FINDFRAME
|
||||
printf(" hint gives us kidFrame=%p with parent frame %p content %p\n",
|
||||
kidFrame, aParentFrame, aParentContent);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!kidFrame) { // we didn't have enough info to prune, start searching from the beginning
|
||||
kidFrame = aParentFrame->GetFirstChild(listName);
|
||||
}
|
||||
while (kidFrame) {
|
||||
// See if the child frame points to the content object we're
|
||||
// looking for
|
||||
nsIContent* kidContent = kidFrame->GetContent();
|
||||
if (kidContent == aContent) {
|
||||
// We found a match. Return the out-of-flow if it's a placeholder.
|
||||
return nsPlaceholderFrame::GetRealFrameFor(kidFrame);
|
||||
}
|
||||
|
||||
// only do this if there is content
|
||||
if (kidContent) {
|
||||
// We search the immediate children only, but if the child frame has
|
||||
// the same content pointer as its parent then we need to search its
|
||||
// child frames, too.
|
||||
// We also need to search if the child content is anonymous and scoped
|
||||
// to the parent content.
|
||||
// XXXldb What makes us continue the search once we're inside
|
||||
// the anonymous subtree?
|
||||
if (aParentContent == kidContent ||
|
||||
(aParentContent && IsBindingAncestor(kidContent, aParentContent))) {
|
||||
#ifdef NOISY_FINDFRAME
|
||||
FFWC_recursions++;
|
||||
printf(" recursing with new parent set to kidframe=%p, parentContent=%p\n",
|
||||
kidFrame, aParentContent);
|
||||
#endif
|
||||
nsIFrame* matchingFrame =
|
||||
FindFrameWithContent(aFrameManager,
|
||||
nsPlaceholderFrame::GetRealFrameFor(kidFrame),
|
||||
aParentContent, aContent, nsnull);
|
||||
|
||||
if (matchingFrame) {
|
||||
return matchingFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
|
||||
#ifdef NOISY_FINDFRAME
|
||||
if (kidFrame) {
|
||||
FFWC_doSibling++;
|
||||
printf(" searching sibling frame %p\n", kidFrame);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (aHint) {
|
||||
// If we get here, and we had a hint, then we didn't find a frame.
|
||||
// The hint may have been a frame whose location in the frame tree
|
||||
// doesn't match the location of its corresponding element in the
|
||||
// DOM tree, e.g. a floated or absolutely positioned frame, or e.g.
|
||||
// a <col> frame, in which case we'd be off in the weeds looking
|
||||
// through something other than the primary frame list.
|
||||
// Reboot the search from scratch, without the hint, but using the
|
||||
// null child list again.
|
||||
aHint = nsnull;
|
||||
searchAgain = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
do {
|
||||
listName = aParentFrame->GetAdditionalChildListName(listIndex++);
|
||||
} while (IsOutOfFlowList(listName));
|
||||
}
|
||||
} while (listName || searchAgain);
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Request to find the primary frame associated with a given content object.
|
||||
// This is typically called by the pres shell when there is no mapping in
|
||||
// the pres shell hash table
|
||||
nsresult
|
||||
nsCSSFrameConstructor::FindPrimaryFrameFor(nsFrameManager* aFrameManager,
|
||||
nsIContent* aContent,
|
||||
nsIFrame** aFrame,
|
||||
nsFindFrameHint* aHint)
|
||||
{
|
||||
NS_ASSERTION(aFrameManager && aContent && aFrame, "bad arg");
|
||||
|
||||
*aFrame = nsnull; // initialize OUT parameter
|
||||
|
||||
// We want to be able to quickly map from a content object to its frame,
|
||||
// but we also want to keep the hash table small. Therefore, many frames
|
||||
// are not added to the hash table when they're first created:
|
||||
// - text frames
|
||||
// - inline frames (often things like FONT and B)
|
||||
// - BR frames
|
||||
// - internal table frames (row-group, row, cell, col-group, col)
|
||||
//
|
||||
// That means we need to need to search for the frame
|
||||
nsIFrame* parentFrame; // this pointer is used to iterate across all frames that map to parentContent
|
||||
|
||||
// Get the frame that corresponds to the parent content object.
|
||||
// Note that this may recurse indirectly, because the pres shell will
|
||||
// call us back if there is no mapping in the hash table
|
||||
nsCOMPtr<nsIContent> parentContent = aContent->GetParent(); // Get this once
|
||||
if (parentContent) {
|
||||
parentFrame = aFrameManager->GetPrimaryFrameFor(parentContent, -1);
|
||||
while (parentFrame) {
|
||||
// Search the child frames for a match
|
||||
*aFrame = FindFrameWithContent(aFrameManager, parentFrame,
|
||||
parentContent, aContent, aHint);
|
||||
#ifdef NOISY_FINDFRAME
|
||||
printf("FindFrameWithContent returned %p\n", *aFrame);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
// if we're given a hint and we were told to verify, then compare the resulting frame with
|
||||
// the frame we get by calling FindFrameWithContent *without* the hint.
|
||||
// Assert if they do not match
|
||||
// Note that this makes finding frames *slower* than it was before the fix.
|
||||
if (gVerifyFastFindFrame && aHint) {
|
||||
#ifdef NOISY_FINDFRAME
|
||||
printf("VERIFYING...\n");
|
||||
#endif
|
||||
nsIFrame *verifyTestFrame =
|
||||
FindFrameWithContent(aFrameManager, parentFrame,
|
||||
parentContent, aContent, nsnull);
|
||||
#ifdef NOISY_FINDFRAME
|
||||
printf("VERIFY returned %p\n", verifyTestFrame);
|
||||
#endif
|
||||
NS_ASSERTION(verifyTestFrame == *aFrame, "hint shortcut found wrong frame");
|
||||
}
|
||||
#endif
|
||||
// If we found a match, then add a mapping to the hash table so
|
||||
// next time this will be quick
|
||||
if (*aFrame) {
|
||||
aFrameManager->SetPrimaryFrameFor(aContent, *aFrame);
|
||||
break;
|
||||
}
|
||||
|
||||
// We didn't find a matching frame. If parentFrame has a next-in-flow
|
||||
// or special sibling, then continue looking there.
|
||||
parentFrame = nsLayoutUtils::GetNextContinuationOrSpecialSibling(parentFrame);
|
||||
#ifdef NOISY_FINDFRAME
|
||||
if (parentFrame) {
|
||||
FFWC_nextInFlows++;
|
||||
printf(" searching NIF frame %p\n", parentFrame);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NOISY_FINDFRAME
|
||||
printf("%10s %10s %10s %10s %10s\n",
|
||||
"total", "doLoop", "doSibling", "recur", "nextIF");
|
||||
printf("%10d %10d %10d %10d %10d\n",
|
||||
FFWC_totalCount, FFWC_doLoop, FFWC_doSibling, FFWC_recursions,
|
||||
FFWC_nextInFlows);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::GetInsertionPoint(nsIFrame* aParentFrame,
|
||||
nsIContent* aChildContent,
|
||||
|
@ -8980,21 +8718,21 @@ nsCSSFrameConstructor::ShouldHaveSpecialBlockStyle(nsIContent* aContent,
|
|||
const nsCSSFrameConstructor::PseudoParentData
|
||||
nsCSSFrameConstructor::sPseudoParentData[eParentTypeCount] = {
|
||||
{ // Cell
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
|
||||
FCDATA_USE_CHILD_ITEMS |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
|
||||
&nsCSSFrameConstructor::ConstructTableCell),
|
||||
&nsCSSAnonBoxes::tableCell
|
||||
},
|
||||
{ // Row
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
|
||||
FCDATA_USE_CHILD_ITEMS |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
|
||||
&nsCSSFrameConstructor::ConstructTableRow),
|
||||
&nsCSSAnonBoxes::tableRow
|
||||
},
|
||||
{ // Row group
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
|
||||
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_USE_CHILD_ITEMS |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
|
@ -9002,7 +8740,7 @@ nsCSSFrameConstructor::sPseudoParentData[eParentTypeCount] = {
|
|||
&nsCSSAnonBoxes::tableRowGroup
|
||||
},
|
||||
{ // Column group
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMEMAP |
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
|
||||
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_USE_CHILD_ITEMS |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
|
@ -9010,7 +8748,7 @@ nsCSSFrameConstructor::sPseudoParentData[eParentTypeCount] = {
|
|||
&nsCSSAnonBoxes::tableColGroup
|
||||
},
|
||||
{ // Table
|
||||
FULL_CTOR_FCDATA(FCDATA_SKIP_FRAMEMAP | FCDATA_USE_CHILD_ITEMS,
|
||||
FULL_CTOR_FCDATA(FCDATA_SKIP_FRAMESET | FCDATA_USE_CHILD_ITEMS,
|
||||
&nsCSSFrameConstructor::ConstructTable),
|
||||
&nsCSSAnonBoxes::table
|
||||
}
|
||||
|
@ -9907,6 +9645,7 @@ nsCSSFrameConstructor::CreateLetterFrame(nsIFrame* aBlockFrame,
|
|||
aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD);
|
||||
}
|
||||
}
|
||||
aTextContent->SetPrimaryFrame(textFrame);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -10084,6 +9823,7 @@ nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames(
|
|||
return NS_ERROR_OUT_OF_MEMORY;;
|
||||
}
|
||||
newTextFrame->Init(textContent, parentFrame, nsnull);
|
||||
textContent->SetPrimaryFrame(newTextFrame);
|
||||
|
||||
// Destroy the old text frame's continuations (the old text frame
|
||||
// will be destroyed when its letter frame is destroyed).
|
||||
|
@ -10146,6 +9886,7 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext,
|
|||
}
|
||||
textFrame = NS_NewTextFrame(aPresShell, newSC);
|
||||
textFrame->Init(textContent, aFrame, nsnull);
|
||||
textContent->SetPrimaryFrame(textFrame);
|
||||
|
||||
// Next rip out the kid and replace it with the text frame
|
||||
aFrameManager->RemoveFrame(nsnull, kid);
|
||||
|
|
|
@ -72,12 +72,6 @@ class nsICSSAnonBoxPseudo;
|
|||
class nsPageContentFrame;
|
||||
struct PendingBinding;
|
||||
|
||||
struct nsFindFrameHint
|
||||
{
|
||||
nsIFrame *mPrimaryFrameForPrevSibling; // weak ref to the primary frame for the content for which we need a frame
|
||||
nsFindFrameHint() : mPrimaryFrameForPrevSibling(nsnull) { }
|
||||
};
|
||||
|
||||
typedef void (nsLazyFrameConstructionCallback)
|
||||
(nsIContent* aContent, nsIFrame* aFrame, void* aArg);
|
||||
|
||||
|
@ -286,14 +280,6 @@ public:
|
|||
// Copy over fixed frames from aParentFrame's prev-in-flow
|
||||
nsresult ReplicateFixedFrames(nsPageContentFrame* aParentFrame);
|
||||
|
||||
// Request to find the primary frame associated with a given content object.
|
||||
// This is typically called by the pres shell when there is no mapping in
|
||||
// the pres shell hash table
|
||||
nsresult FindPrimaryFrameFor(nsFrameManager* aFrameManager,
|
||||
nsIContent* aContent,
|
||||
nsIFrame** aFrame,
|
||||
nsFindFrameHint* aHint);
|
||||
|
||||
// Get the XBL insertion point for a child
|
||||
nsresult GetInsertionPoint(nsIFrame* aParentFrame,
|
||||
nsIContent* aChildContent,
|
||||
|
@ -337,6 +323,7 @@ private:
|
|||
PRInt32 aStateMask);
|
||||
|
||||
/* aMinHint is the minimal change that should be made to the element */
|
||||
// XXXbz do we really need the aPrimaryFrame argument here?
|
||||
void RestyleElement(nsIContent* aContent,
|
||||
nsIFrame* aPrimaryFrame,
|
||||
nsChangeHint aMinHint);
|
||||
|
@ -551,7 +538,7 @@ private:
|
|||
not the thing that ends up in aFrameItems? If not, would it be safe to do
|
||||
the add into the frame construction state after processing kids? Look
|
||||
into this as a followup!), process children as needed, etc. It is NOT
|
||||
expected to deal with the primary frame map.
|
||||
expected to deal with setting the frame on the content.
|
||||
|
||||
@param aState the frame construction state to use.
|
||||
@param aItem the frame construction item to use
|
||||
|
@ -561,7 +548,7 @@ private:
|
|||
@param aFrameItems the frame list to add the new frame (or its
|
||||
placeholder) to.
|
||||
@param aFrame out param handing out the frame that was constructed. This
|
||||
frame is what the caller will add to the primary frame map.
|
||||
frame is what the caller will set as the frame on the content.
|
||||
*/
|
||||
typedef nsresult
|
||||
(nsCSSFrameConstructor::* FrameFullConstructor)(nsFrameConstructorState& aState,
|
||||
|
@ -573,11 +560,11 @@ private:
|
|||
|
||||
/* Bits that modify the way a FrameConstructionData is handled */
|
||||
|
||||
/* If the FCDATA_SKIP_FRAMEMAP bit is set, then the frame created should not
|
||||
be added to the primary frame map. This flag might get ignored when used
|
||||
with FCDATA_MAY_NEED_SCROLLFRAME, since scrollframe construction will add
|
||||
to the frame map. */
|
||||
#define FCDATA_SKIP_FRAMEMAP 0x1
|
||||
/* If the FCDATA_SKIP_FRAMESET bit is set, then the frame created should not
|
||||
be set as the primary frame on the content node. This should only be used
|
||||
in very rare cases when we create more than one frame for a given content
|
||||
node. */
|
||||
#define FCDATA_SKIP_FRAMESET 0x1
|
||||
/* If the FCDATA_FUNC_IS_DATA_GETTER bit is set, then the mFunc of the
|
||||
FrameConstructionData is a getter function that can be used to get the
|
||||
actual FrameConstructionData to use. */
|
||||
|
@ -1129,8 +1116,8 @@ private:
|
|||
FindObjectData(nsIContent* aContent, nsStyleContext* aStyleContext);
|
||||
|
||||
/* Construct a frame from the given FrameConstructionItem. This function
|
||||
will handle adding the frame to frame lists, processing children, adding
|
||||
it to the primary frame map, and so forth.
|
||||
will handle adding the frame to frame lists, processing children, setting
|
||||
the frame as the primary frame for the item's content, and so forth.
|
||||
|
||||
@param aItem the FrameConstructionItem to use.
|
||||
@param aState the frame construction state to use.
|
||||
|
@ -1393,10 +1380,11 @@ private:
|
|||
// containing block (either of aFrame or of its parent) due to {ib} splits or
|
||||
// table pseudo-frames, recreate the relevant frame subtree. The return value
|
||||
// indicates whether this happened. If this method returns true, *aResult is
|
||||
// the return value of ReframeContainingBlock or RecreateFramesForContent.
|
||||
// If this method returns false, the value of *aResult is not affected.
|
||||
// aFrame and aResult must not be null. aFrame must be the result of a
|
||||
// GetPrimaryFrameFor() call (which means its parent is also not null).
|
||||
// the return value of ReframeContainingBlock or RecreateFramesForContent. If
|
||||
// this method returns false, the value of *aResult is not affected. aFrame
|
||||
// and aResult must not be null. aFrame must be the result of a
|
||||
// GetPrimaryFrame() call on a content node (which means its parent is also
|
||||
// not null).
|
||||
PRBool MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame,
|
||||
nsresult* aResult);
|
||||
|
||||
|
@ -1526,21 +1514,6 @@ private:
|
|||
|
||||
nsresult StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint);
|
||||
|
||||
/** Helper function that searches the immediate child frames
|
||||
* (and their children if the frames are "special")
|
||||
* for a frame that maps the specified content object
|
||||
*
|
||||
* @param aParentFrame the primary frame for aParentContent
|
||||
* @param aContent the content node for which we seek a frame
|
||||
* @param aParentContent the parent for aContent
|
||||
* @param aHint an optional hint used to make the search for aFrame faster
|
||||
*/
|
||||
nsIFrame* FindFrameWithContent(nsFrameManager* aFrameManager,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIContent* aParentContent,
|
||||
nsIContent* aContent,
|
||||
nsFindFrameHint* aHint);
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// Methods support :first-letter style
|
||||
|
|
|
@ -150,41 +150,6 @@ static PLDHashTableOps PlaceholderMapOps = {
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
struct PrimaryFrameMapEntry : public PLDHashEntryHdr {
|
||||
// key (the content node) can almost always be obtained through the
|
||||
// frame. If it weren't for the way image maps (mis)used the primary
|
||||
// frame map, we'd be able to have a 2 word entry instead of a 3 word
|
||||
// entry.
|
||||
nsIContent *content;
|
||||
nsIFrame *frame;
|
||||
};
|
||||
|
||||
// These ops should be used if/when we switch back to a 2-word entry.
|
||||
// See comment in |PrimaryFrameMapEntry| above.
|
||||
#if 0
|
||||
static PRBool
|
||||
PrimaryFrameMapMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
|
||||
const void *key)
|
||||
{
|
||||
const PrimaryFrameMapEntry *entry =
|
||||
static_cast<const PrimaryFrameMapEntry*>(hdr);
|
||||
return entry->frame->GetContent() == key;
|
||||
}
|
||||
|
||||
static PLDHashTableOps PrimaryFrameMapOps = {
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
PL_DHashVoidPtrKeyStub,
|
||||
PrimaryFrameMapMatchEntry,
|
||||
PL_DHashMoveEntryStub,
|
||||
PL_DHashClearEntryStub,
|
||||
PL_DHashFinalizeStub,
|
||||
NULL
|
||||
};
|
||||
#endif /* 0 */
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// XXXldb This seems too complicated for what I think it's doing, and it
|
||||
// should also be using pldhash rather than plhash to use less memory.
|
||||
|
||||
|
@ -292,7 +257,6 @@ nsFrameManager::Destroy()
|
|||
mRootFrame = nsnull;
|
||||
}
|
||||
|
||||
nsFrameManager::ClearPrimaryFrameMap();
|
||||
delete mUndisplayedMap;
|
||||
mUndisplayedMap = nsnull;
|
||||
|
||||
|
@ -340,145 +304,19 @@ nsFrameManager::GetPrimaryFrameFor(nsIContent* aContent,
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
if (!aContent->MayHaveFrame()) {
|
||||
if (aContent->GetCurrentDoc() != mPresShell->GetDocument()) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (mPrimaryFrameMap.ops) {
|
||||
PrimaryFrameMapEntry *entry = static_cast<PrimaryFrameMapEntry*>
|
||||
(PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
return entry->frame;
|
||||
}
|
||||
|
||||
// XXX: todo: Add a lookup into the undisplay map to skip searches
|
||||
// if we already know the content has no frame.
|
||||
// nsCSSFrameConstructor calls SetUndisplayedContent() for every
|
||||
// content node that has display: none.
|
||||
// Today, the undisplay map doesn't quite support what we need.
|
||||
// We need to see if we can add a method to make a search for aContent
|
||||
// very fast in the embedded hash table.
|
||||
// This would almost completely remove the lookup penalty for things
|
||||
// like <SCRIPT> and comments in very large documents.
|
||||
// XXX with the nsIContent::MayHaveFrame bit, is that really necessary now?
|
||||
|
||||
// Give the frame construction code the opportunity to return the
|
||||
// frame that maps the content object
|
||||
|
||||
// if the prev sibling of aContent has a cached primary frame,
|
||||
// pass that data in to the style set to speed things up
|
||||
// if any methods in here fail, don't report that failure
|
||||
// we're just trying to enhance performance here, not test for correctness
|
||||
nsFindFrameHint hint;
|
||||
nsIContent* parent = aContent->GetParent();
|
||||
if (parent)
|
||||
{
|
||||
PRInt32 index = aIndexHint >= 0 ? aIndexHint : parent->IndexOf(aContent);
|
||||
if (index > 0) // no use looking if it's the first child
|
||||
{
|
||||
nsIContent *prevSibling;
|
||||
do {
|
||||
prevSibling = parent->GetChildAt(--index);
|
||||
} while (index &&
|
||||
(prevSibling->IsNodeOfType(nsINode::eTEXT) ||
|
||||
prevSibling->IsNodeOfType(nsINode::eCOMMENT) ||
|
||||
prevSibling->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)));
|
||||
if (prevSibling) {
|
||||
entry = static_cast<PrimaryFrameMapEntry*>
|
||||
(PL_DHashTableOperate(&mPrimaryFrameMap, prevSibling,
|
||||
PL_DHASH_LOOKUP));
|
||||
// XXXbz the GetContent() == prevSibling check is needed due to bug
|
||||
// 135040. Remove it once that's fixed.
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->frame &&
|
||||
entry->frame->GetContent() == prevSibling)
|
||||
hint.mPrimaryFrameForPrevSibling = entry->frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// walk the frame tree to find the frame that maps aContent.
|
||||
// Use the hint if we have it.
|
||||
nsIFrame *result;
|
||||
|
||||
mPresShell->FrameConstructor()->
|
||||
FindPrimaryFrameFor(this, aContent, &result,
|
||||
hint.mPrimaryFrameForPrevSibling ? &hint : nsnull);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameManager::SetPrimaryFrameFor(nsIContent* aContent,
|
||||
nsIFrame* aPrimaryFrame)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aContent);
|
||||
NS_ASSERTION(aPrimaryFrame && aPrimaryFrame->GetParent(),
|
||||
"BOGUS!");
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsIFrame *docElementCB =
|
||||
mPresShell->FrameConstructor()->GetDocElementContainingBlock();
|
||||
NS_ASSERTION(aPrimaryFrame != docElementCB &&
|
||||
!nsLayoutUtils::IsProperAncestorFrame(aPrimaryFrame,
|
||||
docElementCB),
|
||||
"too high in the frame tree to be a primary frame");
|
||||
}
|
||||
#endif
|
||||
|
||||
// This code should be used if/when we switch back to a 2-word entry
|
||||
// in the primary frame map.
|
||||
#if 0
|
||||
NS_PRECONDITION(aPrimaryFrame->GetContent() == aContent, "wrong content");
|
||||
#endif
|
||||
|
||||
// Create a new hashtable if necessary
|
||||
if (!mPrimaryFrameMap.ops) {
|
||||
if (!PL_DHashTableInit(&mPrimaryFrameMap, PL_DHashGetStubOps(), nsnull,
|
||||
sizeof(PrimaryFrameMapEntry), 16)) {
|
||||
mPrimaryFrameMap.ops = nsnull;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a mapping to the hash table
|
||||
PrimaryFrameMapEntry *entry = static_cast<PrimaryFrameMapEntry*>
|
||||
(PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_ADD));
|
||||
#ifdef DEBUG_dbaron
|
||||
if (entry->frame) {
|
||||
NS_WARNING("already have primary frame for content");
|
||||
}
|
||||
#endif
|
||||
entry->frame = aPrimaryFrame;
|
||||
entry->content = aContent;
|
||||
|
||||
return NS_OK;
|
||||
return aContent->GetPrimaryFrame();
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameManager::RemoveAsPrimaryFrame(nsIContent* aContent,
|
||||
nsIFrame* aPrimaryFrame)
|
||||
{
|
||||
NS_PRECONDITION(aPrimaryFrame, "Must have a frame");
|
||||
if (aContent && mPrimaryFrameMap.ops) {
|
||||
PrimaryFrameMapEntry *entry = static_cast<PrimaryFrameMapEntry*>
|
||||
(PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->frame == aPrimaryFrame) {
|
||||
// Don't use PL_DHashTableRawRemove, since we want the table to
|
||||
// shrink as needed.
|
||||
PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_REMOVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameManager::ClearPrimaryFrameMap()
|
||||
{
|
||||
if (mPrimaryFrameMap.ops) {
|
||||
PL_DHashTableFinish(&mPrimaryFrameMap);
|
||||
mPrimaryFrameMap.ops = nsnull;
|
||||
if (aContent->GetPrimaryFrame() == aPrimaryFrame) {
|
||||
aContent->SetPrimaryFrame(nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,20 +110,12 @@ public:
|
|||
NS_HIDDEN_(nsIFrame*) GetCanvasFrame();
|
||||
|
||||
// Primary frame functions
|
||||
// If aIndexHint it not -1, it will be used as when determining a frame hint
|
||||
// instead of calling IndexOf(aContent).
|
||||
NS_HIDDEN_(nsIFrame*) GetPrimaryFrameFor(nsIContent* aContent,
|
||||
PRInt32 aIndexHint);
|
||||
// aPrimaryFrame must not be null. If you're trying to remove a primary frame
|
||||
// mapping, use RemoveAsPrimaryFrame.
|
||||
NS_HIDDEN_(nsresult) SetPrimaryFrameFor(nsIContent* aContent,
|
||||
nsIFrame* aPrimaryFrame);
|
||||
// If aPrimaryFrame is the current primary frame for aContent, remove the
|
||||
// relevant hashtable entry. If the current primary frame for aContent is
|
||||
// null, this does nothing. aPrimaryFrame must not be null.
|
||||
// If aPrimaryFrame is the current primary frame for aContent, set its
|
||||
// primary frame to null. aPrimaryFrame must not be null.
|
||||
NS_HIDDEN_(void) RemoveAsPrimaryFrame(nsIContent* aContent,
|
||||
nsIFrame* aPrimaryFrame);
|
||||
NS_HIDDEN_(void) ClearPrimaryFrameMap();
|
||||
|
||||
// Placeholder frame functions
|
||||
NS_HIDDEN_(nsPlaceholderFrame*) GetPlaceholderFrameFor(nsIFrame* aFrame);
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
class nsImageLoader;
|
||||
#ifdef IBMBIDI
|
||||
|
@ -82,7 +83,6 @@ struct nsRect;
|
|||
|
||||
class imgIRequest;
|
||||
|
||||
class nsIContent;
|
||||
class nsIFontMetrics;
|
||||
class nsIFrame;
|
||||
class nsFrameManager;
|
||||
|
@ -904,6 +904,22 @@ public:
|
|||
*/
|
||||
void SMILOverrideStyleChanged(nsIContent* aContent);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
/**
|
||||
* If we have a presshell, and if the given content's current
|
||||
* document is the same as our presshell's document, return the
|
||||
* content's primary frame. Otherwise, return null. Only use this
|
||||
* if you care about which presshell the primary frame is in.
|
||||
*/
|
||||
nsIFrame* GetPrimaryFrameFor(nsIContent* aContent) {
|
||||
NS_PRECONDITION(aContent, "Don't do that");
|
||||
if (GetPresShell() &&
|
||||
GetPresShell()->GetDocument() == aContent->GetCurrentDoc()) {
|
||||
return aContent->GetPrimaryFrame();
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class nsRunnableMethod<nsPresContext>;
|
||||
NS_HIDDEN_(void) ThemeChangedInternal();
|
||||
|
|
|
@ -339,8 +339,6 @@ nsFrame::Init(nsIContent* aContent,
|
|||
|
||||
if (aContent) {
|
||||
NS_ADDREF(aContent);
|
||||
aContent->SetMayHaveFrame(PR_TRUE);
|
||||
NS_ASSERTION(mContent->MayHaveFrame(), "SetMayHaveFrame failed?");
|
||||
}
|
||||
|
||||
if (aPrevInFlow) {
|
||||
|
@ -466,6 +464,11 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
|||
view->Destroy();
|
||||
}
|
||||
|
||||
// Make sure that our deleted frame can't be returned from GetPrimaryFrame()
|
||||
if (mContent && mContent->GetPrimaryFrame() == this) {
|
||||
mContent->SetPrimaryFrame(nsnull);
|
||||
}
|
||||
|
||||
// Must retrieve the object ID before calling destructors, so the
|
||||
// vtable is still valid.
|
||||
//
|
||||
|
|
|
@ -284,7 +284,7 @@ nsSubDocumentFrame::Init(nsIContent* aContent,
|
|||
// Set the primary frame now so that
|
||||
// DocumentViewerImpl::FindContainerView called by ShowViewer below
|
||||
// can find it if necessary.
|
||||
PresContext()->FrameManager()->SetPrimaryFrameFor(aContent, this);
|
||||
aContent->SetPrimaryFrame(this);
|
||||
|
||||
ShowViewer();
|
||||
return NS_OK;
|
||||
|
|
|
@ -414,6 +414,7 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
|
|||
mChildFrameborder[mChildCount] = GetFrameBorder(child);
|
||||
mChildBorderColors[mChildCount].Set(GetBorderColor(child));
|
||||
}
|
||||
child->SetPrimaryFrame(frame);
|
||||
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
|
|
@ -900,9 +900,7 @@ nsImageMap::AddArea(nsIContent* aArea)
|
|||
// nsCSSFrameConstructor::ContentRemoved (both hacks there), and
|
||||
// nsCSSFrameConstructor::ProcessRestyledFrames to work around this issue can
|
||||
// be removed.
|
||||
mPresShell->FrameManager()->SetPrimaryFrameFor(aArea, mImageFrame);
|
||||
aArea->SetMayHaveFrame(PR_TRUE);
|
||||
NS_ASSERTION(aArea->MayHaveFrame(), "SetMayHaveFrame failed?");
|
||||
aArea->SetPrimaryFrame(mImageFrame);
|
||||
|
||||
area->ParseCoords(coords);
|
||||
mAreas.AppendElement(area);
|
||||
|
|
Загрузка…
Ссылка в новой задаче