Fix for bug #13233. Changed CantRenderReplacedEledment() so it handles OBJECT

frames that are out-of-flow
This commit is contained in:
troy%netscape.com 1999-09-15 04:03:08 +00:00
Родитель b4a2844cd7
Коммит 994aaa4cee
2 изменённых файлов: 198 добавлений и 90 удалений

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

@ -6864,37 +6864,19 @@ nsCSSFrameConstructor::ConstructAlternateImageFrame(nsIPresContext* aPresContex
return rv; return rv;
} }
static inline void #ifdef NS_DEBUG
ReplaceFrame(nsIPresContext* aPresContext, static PRBool
nsIPresShell* aPresShell, IsPlaceholderFrame(nsIFrame* aFrame)
nsIFrameManager* aFrameManager,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIAtom* aListName,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame,
nsIFrame* aPlaceholderFrame)
{ {
// Reset the primary frame mapping nsIAtom* frameType;
aFrameManager->SetPrimaryFrameFor(aContent, aNewFrame); PRBool result;
if (aPlaceholderFrame) { aFrame->GetFrameType(&frameType);
// Remove the association between the old frame and its placeholder result = frameType == nsLayoutAtoms::placeholderFrame;
aFrameManager->SetPlaceholderFrameFor(aOldFrame, nsnull); NS_IF_RELEASE(frameType);
return result;
// Reuse the existing placeholder frame, and add an association to the
// new frame
aFrameManager->SetPlaceholderFrameFor(aNewFrame, aPlaceholderFrame);
// Placeholder frames have a pointer back to the out-of-flow frame.
// Make sure that's correct
((nsPlaceholderFrame*)aPlaceholderFrame)->SetOutOfFlowFrame(aNewFrame);
}
// Replace the old frame with the new frame
aFrameManager->ReplaceFrame(*aPresContext, *aPresShell, aParentFrame,
aListName, aOldFrame, aNewFrame);
} }
#endif
NS_IMETHODIMP NS_IMETHODIMP
nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresContext* aPresContext, nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresContext* aPresContext,
@ -6944,41 +6926,114 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresContext* aPresContext,
presShell->GetFrameManager(getter_AddRefs(frameManager)); presShell->GetFrameManager(getter_AddRefs(frameManager));
// Replace the old frame with the new frame // Replace the old frame with the new frame
ReplaceFrame(aPresContext, presShell, frameManager, content, // Reset the primary frame mapping
parentFrame, listName, aFrame, newFrame, placeholderFrame); frameManager->SetPrimaryFrameFor(content, newFrame);
if (placeholderFrame) {
// Remove the association between the old frame and its placeholder
frameManager->SetPlaceholderFrameFor(aFrame, nsnull);
// Reuse the existing placeholder frame, and add an association to the
// new frame
frameManager->SetPlaceholderFrameFor(newFrame, placeholderFrame);
// Placeholder frames have a pointer back to the out-of-flow frame.
// Make sure that's correct
((nsPlaceholderFrame*)placeholderFrame)->SetOutOfFlowFrame(newFrame);
}
// Replace the old frame with the new frame
frameManager->ReplaceFrame(*aPresContext, *presShell, parentFrame,
listName, aFrame, newFrame);
} }
} else if ((nsHTMLAtoms::object == tag.get()) || } else if ((nsHTMLAtoms::object == tag.get()) ||
(nsHTMLAtoms::embed == tag.get()) || (nsHTMLAtoms::embed == tag.get()) ||
(nsHTMLAtoms::applet == tag.get())) { (nsHTMLAtoms::applet == tag.get())) {
// It's an OBJECT element or APPLET, so we should display the contents
// It's an OBJECT, EMBED, or APPLET, so we should display the contents
// instead // instead
nsIFrame* absoluteContainingBlock;
nsIFrame* floaterContainingBlock;
nsIFrame* inFlowParent = parentFrame;
// If the OBJECT frame is out-of-flow, then get the placeholder frame's
// parent and use that when determining the absolute containing block and
// floater containing block
if (placeholderFrame) {
placeholderFrame->GetParent(&inFlowParent);
}
absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, inFlowParent),
floaterContainingBlock = GetFloaterContainingBlock(aPresContext, inFlowParent);
#ifdef NS_DEBUG
// Verify that we calculated the same containing block
if (listName.get() == nsLayoutAtoms::absoluteList) {
NS_ASSERTION(absoluteContainingBlock == parentFrame,
"wrong absolute containing block");
} else if (listName.get() == nsLayoutAtoms::floaterList) {
NS_ASSERTION(floaterContainingBlock == parentFrame,
"wrong floater containing block");
}
#endif
// Now initialize the frame construction state
nsFrameConstructorState state(aPresContext, mFixedContainingBlock, nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
GetAbsoluteContainingBlock(aPresContext, parentFrame), absoluteContainingBlock, floaterContainingBlock);
GetFloaterContainingBlock(aPresContext, parentFrame));
nsFrameItems frameItems; nsFrameItems frameItems;
const nsStyleDisplay* display = (const nsStyleDisplay*) const nsStyleDisplay* display = (const nsStyleDisplay*)
styleContext->GetStyleData(eStyleStruct_Display); styleContext->GetStyleData(eStyleStruct_Display);
// Create a frame based on the display type // Create a new frame based on the display type.
// Note: if the old frame was out-of-flow, then so will the new frame
// and we'll get a new placeholder frame
rv = ConstructFrameByDisplayType(aPresContext, state, display, content, rv = ConstructFrameByDisplayType(aPresContext, state, display, content,
parentFrame, styleContext, PR_FALSE, frameItems); inFlowParent, styleContext, PR_FALSE, frameItems);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
nsIFrame* newFrame = frameItems.childList; nsIFrame* newFrame = frameItems.childList;
// Replace the old frame with the new frame
ReplaceFrame(aPresContext, presShell, state.mFrameManager, content,
parentFrame, listName, aFrame, newFrame, placeholderFrame);
if (placeholderFrame) {
// Remove the association between the old frame and its placeholder
// Note: ConstructFrameByDisplayType() will already have added an
// association for the new placeholder frame
state.mFrameManager->SetPlaceholderFrameFor(aFrame, nsnull);
// Verify that the new frame is also a placeholder frame
NS_ASSERTION(IsPlaceholderFrame(newFrame), "unexpected frame type");
// Replace the old placeholder frame with the new placeholder frame
state.mFrameManager->ReplaceFrame(*aPresContext, *presShell, inFlowParent,
nsnull, placeholderFrame, newFrame);
}
// Replace the primary frame
if (listName.get() == nsLayoutAtoms::absoluteList) {
newFrame = state.mAbsoluteItems.childList;
state.mAbsoluteItems.childList = nsnull;
} else if (listName.get() == nsLayoutAtoms::fixedList) {
newFrame = state.mFixedItems.childList;
state.mFixedItems.childList = nsnull;
} else if (listName.get() == nsLayoutAtoms::floaterList) {
newFrame = state.mFloatedItems.childList;
state.mFloatedItems.childList = nsnull;
}
state.mFrameManager->ReplaceFrame(*aPresContext, *presShell, parentFrame,
listName, aFrame, newFrame);
// Reset the primary frame mapping. Don't assume that
// ConstructFrameByDisplayType() has done this
state.mFrameManager->SetPrimaryFrameFor(content, newFrame);
// If there are new absolutely positioned child frames, then notify // If there are new absolutely positioned child frames, then notify
// the parent // the parent
// XXX We can't just assume these frames are being appended, we need to // XXX We can't just assume these frames are being appended, we need to
// determine where in the list they should be inserted... // determine where in the list they should be inserted...
if (state.mAbsoluteItems.childList) { if (state.mAbsoluteItems.childList) {
rv = state.mAbsoluteItems.containingBlock->AppendFrames(*aPresContext, *presShell, rv = state.mAbsoluteItems.containingBlock->AppendFrames(*aPresContext, *presShell,
nsLayoutAtoms::absoluteList, nsLayoutAtoms::absoluteList,
state.mAbsoluteItems.childList); state.mAbsoluteItems.childList);
} }
// If there are new fixed positioned child frames, then notify // If there are new fixed positioned child frames, then notify
@ -6987,12 +7042,11 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresContext* aPresContext,
// determine where in the list they should be inserted... // determine where in the list they should be inserted...
if (state.mFixedItems.childList) { if (state.mFixedItems.childList) {
rv = state.mFixedItems.containingBlock->AppendFrames(*aPresContext, *presShell, rv = state.mFixedItems.containingBlock->AppendFrames(*aPresContext, *presShell,
nsLayoutAtoms::fixedList, nsLayoutAtoms::fixedList,
state.mFixedItems.childList); state.mFixedItems.childList);
} }
// If there are new floating child frames, then notify // If there are new floating child frames, then notify the parent
// the parent
// XXX We can't just assume these frames are being appended, we need to // XXX We can't just assume these frames are being appended, we need to
// determine where in the list they should be inserted... // determine where in the list they should be inserted...
if (state.mFloatedItems.childList) { if (state.mFloatedItems.childList) {

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

@ -6864,37 +6864,19 @@ nsCSSFrameConstructor::ConstructAlternateImageFrame(nsIPresContext* aPresContex
return rv; return rv;
} }
static inline void #ifdef NS_DEBUG
ReplaceFrame(nsIPresContext* aPresContext, static PRBool
nsIPresShell* aPresShell, IsPlaceholderFrame(nsIFrame* aFrame)
nsIFrameManager* aFrameManager,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIAtom* aListName,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame,
nsIFrame* aPlaceholderFrame)
{ {
// Reset the primary frame mapping nsIAtom* frameType;
aFrameManager->SetPrimaryFrameFor(aContent, aNewFrame); PRBool result;
if (aPlaceholderFrame) { aFrame->GetFrameType(&frameType);
// Remove the association between the old frame and its placeholder result = frameType == nsLayoutAtoms::placeholderFrame;
aFrameManager->SetPlaceholderFrameFor(aOldFrame, nsnull); NS_IF_RELEASE(frameType);
return result;
// Reuse the existing placeholder frame, and add an association to the
// new frame
aFrameManager->SetPlaceholderFrameFor(aNewFrame, aPlaceholderFrame);
// Placeholder frames have a pointer back to the out-of-flow frame.
// Make sure that's correct
((nsPlaceholderFrame*)aPlaceholderFrame)->SetOutOfFlowFrame(aNewFrame);
}
// Replace the old frame with the new frame
aFrameManager->ReplaceFrame(*aPresContext, *aPresShell, aParentFrame,
aListName, aOldFrame, aNewFrame);
} }
#endif
NS_IMETHODIMP NS_IMETHODIMP
nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresContext* aPresContext, nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresContext* aPresContext,
@ -6944,41 +6926,114 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresContext* aPresContext,
presShell->GetFrameManager(getter_AddRefs(frameManager)); presShell->GetFrameManager(getter_AddRefs(frameManager));
// Replace the old frame with the new frame // Replace the old frame with the new frame
ReplaceFrame(aPresContext, presShell, frameManager, content, // Reset the primary frame mapping
parentFrame, listName, aFrame, newFrame, placeholderFrame); frameManager->SetPrimaryFrameFor(content, newFrame);
if (placeholderFrame) {
// Remove the association between the old frame and its placeholder
frameManager->SetPlaceholderFrameFor(aFrame, nsnull);
// Reuse the existing placeholder frame, and add an association to the
// new frame
frameManager->SetPlaceholderFrameFor(newFrame, placeholderFrame);
// Placeholder frames have a pointer back to the out-of-flow frame.
// Make sure that's correct
((nsPlaceholderFrame*)placeholderFrame)->SetOutOfFlowFrame(newFrame);
}
// Replace the old frame with the new frame
frameManager->ReplaceFrame(*aPresContext, *presShell, parentFrame,
listName, aFrame, newFrame);
} }
} else if ((nsHTMLAtoms::object == tag.get()) || } else if ((nsHTMLAtoms::object == tag.get()) ||
(nsHTMLAtoms::embed == tag.get()) || (nsHTMLAtoms::embed == tag.get()) ||
(nsHTMLAtoms::applet == tag.get())) { (nsHTMLAtoms::applet == tag.get())) {
// It's an OBJECT element or APPLET, so we should display the contents
// It's an OBJECT, EMBED, or APPLET, so we should display the contents
// instead // instead
nsIFrame* absoluteContainingBlock;
nsIFrame* floaterContainingBlock;
nsIFrame* inFlowParent = parentFrame;
// If the OBJECT frame is out-of-flow, then get the placeholder frame's
// parent and use that when determining the absolute containing block and
// floater containing block
if (placeholderFrame) {
placeholderFrame->GetParent(&inFlowParent);
}
absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, inFlowParent),
floaterContainingBlock = GetFloaterContainingBlock(aPresContext, inFlowParent);
#ifdef NS_DEBUG
// Verify that we calculated the same containing block
if (listName.get() == nsLayoutAtoms::absoluteList) {
NS_ASSERTION(absoluteContainingBlock == parentFrame,
"wrong absolute containing block");
} else if (listName.get() == nsLayoutAtoms::floaterList) {
NS_ASSERTION(floaterContainingBlock == parentFrame,
"wrong floater containing block");
}
#endif
// Now initialize the frame construction state
nsFrameConstructorState state(aPresContext, mFixedContainingBlock, nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
GetAbsoluteContainingBlock(aPresContext, parentFrame), absoluteContainingBlock, floaterContainingBlock);
GetFloaterContainingBlock(aPresContext, parentFrame));
nsFrameItems frameItems; nsFrameItems frameItems;
const nsStyleDisplay* display = (const nsStyleDisplay*) const nsStyleDisplay* display = (const nsStyleDisplay*)
styleContext->GetStyleData(eStyleStruct_Display); styleContext->GetStyleData(eStyleStruct_Display);
// Create a frame based on the display type // Create a new frame based on the display type.
// Note: if the old frame was out-of-flow, then so will the new frame
// and we'll get a new placeholder frame
rv = ConstructFrameByDisplayType(aPresContext, state, display, content, rv = ConstructFrameByDisplayType(aPresContext, state, display, content,
parentFrame, styleContext, PR_FALSE, frameItems); inFlowParent, styleContext, PR_FALSE, frameItems);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
nsIFrame* newFrame = frameItems.childList; nsIFrame* newFrame = frameItems.childList;
// Replace the old frame with the new frame
ReplaceFrame(aPresContext, presShell, state.mFrameManager, content,
parentFrame, listName, aFrame, newFrame, placeholderFrame);
if (placeholderFrame) {
// Remove the association between the old frame and its placeholder
// Note: ConstructFrameByDisplayType() will already have added an
// association for the new placeholder frame
state.mFrameManager->SetPlaceholderFrameFor(aFrame, nsnull);
// Verify that the new frame is also a placeholder frame
NS_ASSERTION(IsPlaceholderFrame(newFrame), "unexpected frame type");
// Replace the old placeholder frame with the new placeholder frame
state.mFrameManager->ReplaceFrame(*aPresContext, *presShell, inFlowParent,
nsnull, placeholderFrame, newFrame);
}
// Replace the primary frame
if (listName.get() == nsLayoutAtoms::absoluteList) {
newFrame = state.mAbsoluteItems.childList;
state.mAbsoluteItems.childList = nsnull;
} else if (listName.get() == nsLayoutAtoms::fixedList) {
newFrame = state.mFixedItems.childList;
state.mFixedItems.childList = nsnull;
} else if (listName.get() == nsLayoutAtoms::floaterList) {
newFrame = state.mFloatedItems.childList;
state.mFloatedItems.childList = nsnull;
}
state.mFrameManager->ReplaceFrame(*aPresContext, *presShell, parentFrame,
listName, aFrame, newFrame);
// Reset the primary frame mapping. Don't assume that
// ConstructFrameByDisplayType() has done this
state.mFrameManager->SetPrimaryFrameFor(content, newFrame);
// If there are new absolutely positioned child frames, then notify // If there are new absolutely positioned child frames, then notify
// the parent // the parent
// XXX We can't just assume these frames are being appended, we need to // XXX We can't just assume these frames are being appended, we need to
// determine where in the list they should be inserted... // determine where in the list they should be inserted...
if (state.mAbsoluteItems.childList) { if (state.mAbsoluteItems.childList) {
rv = state.mAbsoluteItems.containingBlock->AppendFrames(*aPresContext, *presShell, rv = state.mAbsoluteItems.containingBlock->AppendFrames(*aPresContext, *presShell,
nsLayoutAtoms::absoluteList, nsLayoutAtoms::absoluteList,
state.mAbsoluteItems.childList); state.mAbsoluteItems.childList);
} }
// If there are new fixed positioned child frames, then notify // If there are new fixed positioned child frames, then notify
@ -6987,12 +7042,11 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresContext* aPresContext,
// determine where in the list they should be inserted... // determine where in the list they should be inserted...
if (state.mFixedItems.childList) { if (state.mFixedItems.childList) {
rv = state.mFixedItems.containingBlock->AppendFrames(*aPresContext, *presShell, rv = state.mFixedItems.containingBlock->AppendFrames(*aPresContext, *presShell,
nsLayoutAtoms::fixedList, nsLayoutAtoms::fixedList,
state.mFixedItems.childList); state.mFixedItems.childList);
} }
// If there are new floating child frames, then notify // If there are new floating child frames, then notify the parent
// the parent
// XXX We can't just assume these frames are being appended, we need to // XXX We can't just assume these frames are being appended, we need to
// determine where in the list they should be inserted... // determine where in the list they should be inserted...
if (state.mFloatedItems.childList) { if (state.mFloatedItems.childList) {