зеркало из https://github.com/mozilla/pjs.git
Make sure that Init() failures for image frames don't mean no alt text. Also
fixes a crasher when reframing fixed-pos frames. This change adds an assertion in ConstructHTMLFrame that InitAndRestoreFrame should succeed (unless it returns NS_ERROR_FRAME_REPLACED). This is an interim change; eventually we want to bail out on errors, but there may be frame impls that return errors in non-error conditions from Init() (eg nsFrameSetFrame did that) and we're a little close to freeze. Bug 202506, r=rbs, sr=roc+moz
This commit is contained in:
Родитель
de711ed4d0
Коммит
c72ee5ce87
|
@ -1421,10 +1421,18 @@ nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIPresContext* aPresContex
|
|||
content->SetDocument(aDocument, PR_TRUE, PR_TRUE);
|
||||
|
||||
// Create an image frame and initialize it
|
||||
nsIFrame* imageFrame;
|
||||
NS_NewImageFrame(shell, &imageFrame);
|
||||
imageFrame->Init(aPresContext, content, aParentFrame, aStyleContext, nsnull);
|
||||
|
||||
nsIFrame* imageFrame = nsnull;
|
||||
rv = NS_NewImageFrame(shell, &imageFrame);
|
||||
if (!imageFrame) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = imageFrame->Init(aPresContext, content, aParentFrame, aStyleContext, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
imageFrame->Destroy(aPresContext);
|
||||
return rv == NS_ERROR_FRAME_REPLACED ? NS_OK : rv;
|
||||
}
|
||||
|
||||
// Return the image frame
|
||||
*aFrame = imageFrame;
|
||||
|
||||
|
@ -4973,69 +4981,89 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsIPresShell* aPresShell,
|
|||
}
|
||||
}
|
||||
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
geometricParent, aStyleContext, nsnull, newFrame);
|
||||
rv = InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
geometricParent, aStyleContext, nsnull, newFrame);
|
||||
if (rv == NS_ERROR_FRAME_REPLACED) {
|
||||
// The frame called CantRenderReplacedElement from inside Init(). That
|
||||
// failed to do anything useful, since the frame was not in the frame
|
||||
// tree yet... Create an alternate frame ourselves
|
||||
newFrame->Destroy(aPresContext);
|
||||
|
||||
// See if we need to create a view, e.g. the frame is absolutely
|
||||
// positioned
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
||||
aStyleContext, aParentFrame, PR_FALSE);
|
||||
if (aTag != nsHTMLAtoms::img && aTag != nsHTMLAtoms::input) {
|
||||
// XXXbz This should really be made to work for <object> too...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Process the child content if requested
|
||||
nsFrameItems childItems;
|
||||
if (processChildren) {
|
||||
if (isPositionedContainingBlock) {
|
||||
// The area frame becomes a container for child frames that are
|
||||
// absolutely positioned
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
aState.PushAbsoluteContainingBlock(aPresContext, newFrame, absoluteSaveState);
|
||||
// Try to construct the alternate frame
|
||||
newFrame = nsnull;
|
||||
rv = ConstructAlternateFrame(aPresShell, aPresContext, aContent,
|
||||
aStyleContext, geometricParent,
|
||||
aParentFrame, newFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(newFrame, "ConstructAlternateFrame needs better error-checking");
|
||||
} else {
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "InitAndRestoreFrame failed");
|
||||
// See if we need to create a view, e.g. the frame is absolutely
|
||||
// positioned
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
||||
aStyleContext, aParentFrame, PR_FALSE);
|
||||
|
||||
// Process the child content if requested
|
||||
nsFrameItems childItems;
|
||||
if (processChildren) {
|
||||
if (isPositionedContainingBlock) {
|
||||
// The area frame becomes a container for child frames that are
|
||||
// absolutely positioned
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
aState.PushAbsoluteContainingBlock(aPresContext, newFrame, absoluteSaveState);
|
||||
|
||||
// Process the child frames
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
// Process the child frames
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
|
||||
// Set the frame's absolute list if there were any absolutely positioned children
|
||||
if (aState.mAbsoluteItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext,
|
||||
nsLayoutAtoms::absoluteList,
|
||||
aState.mAbsoluteItems.childList);
|
||||
// Set the frame's absolute list if there were any absolutely positioned children
|
||||
if (aState.mAbsoluteItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext,
|
||||
nsLayoutAtoms::absoluteList,
|
||||
aState.mAbsoluteItems.childList);
|
||||
}
|
||||
}
|
||||
else if (isFloaterContainer) {
|
||||
// If the frame can contain floaters, then push a floater
|
||||
// containing block
|
||||
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
||||
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
||||
&haveFirstLetterStyle, &haveFirstLineStyle);
|
||||
nsFrameConstructorSaveState floaterSaveState;
|
||||
aState.PushFloaterContainingBlock(newFrame, floaterSaveState,
|
||||
PR_FALSE, PR_FALSE);
|
||||
|
||||
// Process the child frames
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
|
||||
// Set the frame's floater list if there were any floated children
|
||||
if (aState.mFloatedItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext,
|
||||
nsLayoutAtoms::floaterList,
|
||||
aState.mFloatedItems.childList);
|
||||
}
|
||||
|
||||
} else {
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
}
|
||||
}
|
||||
else if (isFloaterContainer) {
|
||||
// If the frame can contain floaters, then push a floater
|
||||
// containing block
|
||||
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
||||
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
||||
&haveFirstLetterStyle, &haveFirstLineStyle);
|
||||
nsFrameConstructorSaveState floaterSaveState;
|
||||
aState.PushFloaterContainingBlock(newFrame, floaterSaveState,
|
||||
PR_FALSE, PR_FALSE);
|
||||
|
||||
// Process the child frames
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
|
||||
// Set the frame's floater list if there were any floated children
|
||||
if (aState.mFloatedItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext,
|
||||
nsLayoutAtoms::floaterList,
|
||||
aState.mFloatedItems.childList);
|
||||
}
|
||||
|
||||
} else {
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
// if there are any anonymous children create frames for them
|
||||
CreateAnonymousFrames(aPresShell, aPresContext, aTag, aState, aContent, newFrame,
|
||||
PR_FALSE, childItems);
|
||||
|
||||
// Set the frame's initial child list
|
||||
if (childItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
||||
}
|
||||
}
|
||||
|
||||
// if there are any anonymous children create frames for them
|
||||
CreateAnonymousFrames(aPresShell, aPresContext, aTag, aState, aContent, newFrame,
|
||||
PR_FALSE, childItems);
|
||||
|
||||
// Set the frame's initial child list
|
||||
if (childItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
||||
}
|
||||
}
|
||||
|
||||
// If the frame is positioned, then create a placeholder frame
|
||||
|
@ -10757,7 +10785,8 @@ nsCSSFrameConstructor::ConstructAlternateFrame(nsIPresShell* aPresShell,
|
|||
nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aGeometricParent,
|
||||
nsIFrame* aContentParent,
|
||||
nsIFrame*& aFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -10802,9 +10831,10 @@ nsCSSFrameConstructor::ConstructAlternateFrame(nsIPresShell* aPresShell,
|
|||
} else {
|
||||
NS_NewInlineFrame(aPresShell, &containerFrame);
|
||||
}
|
||||
containerFrame->Init(aPresContext, aContent, aParentFrame, aStyleContext, nsnull);
|
||||
containerFrame->Init(aPresContext, aContent, aGeometricParent, aStyleContext, nsnull);
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, containerFrame,
|
||||
aStyleContext, nsnull, PR_FALSE);
|
||||
aStyleContext, aContentParent,
|
||||
PR_FALSE);
|
||||
|
||||
// If the frame is out-of-flow, then mark it as such
|
||||
if (isOutOfFlow) {
|
||||
|
@ -10942,7 +10972,7 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresShell* aPresShell,
|
|||
// image can't be rendered
|
||||
nsIFrame* newFrame;
|
||||
rv = ConstructAlternateFrame(aPresShell, aPresContext, content, styleContext,
|
||||
parentFrame, newFrame);
|
||||
parentFrame, nsnull, newFrame);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
|
@ -10956,6 +10986,7 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresShell* aPresShell,
|
|||
frameManager->SetPrimaryFrameFor(content, newFrame);
|
||||
|
||||
// Replace the old frame with the new frame
|
||||
// XXXbz If this fails, we leak the content node newFrame points to!
|
||||
frameManager->ReplaceFrame(aPresContext, *presShell, parentFrame,
|
||||
listName, aFrame, newFrame);
|
||||
|
||||
|
@ -12035,11 +12066,21 @@ nsCSSFrameConstructor::RecreateFramesForContent(nsIPresContext* aPresContext,
|
|||
// state onto a temporary state object.
|
||||
CaptureStateForFramesOf(aPresContext, aContent, mTempFrameTreeState);
|
||||
|
||||
// Save parent frame because this frame is going away
|
||||
// Save parent frame because this frame is going away. But if
|
||||
// this is an out-of-flow, we want to get the _placeholder_'s
|
||||
// parent.
|
||||
nsIFrame* parent = nsnull;
|
||||
if (frame)
|
||||
frame->GetParent(&parent);
|
||||
if (frame) {
|
||||
nsFrameState state;
|
||||
frame->GetFrameState(&state);
|
||||
if (state & NS_FRAME_OUT_OF_FLOW) {
|
||||
shell->GetPlaceholderFrameFor(frame, &frame);
|
||||
NS_ASSERTION(frame, "Out-of-flow with no placeholder?");
|
||||
}
|
||||
|
||||
frame->GetParent(&parent);
|
||||
}
|
||||
|
||||
// Remove the frames associated with the content object on which the
|
||||
// attribute change occurred.
|
||||
rv = ContentRemoved(aPresContext, container, aContent, indexInContainer, PR_FALSE);
|
||||
|
|
|
@ -472,7 +472,8 @@ protected:
|
|||
nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aGeometricParent,
|
||||
nsIFrame* aContentParent,
|
||||
nsIFrame*& aFrame);
|
||||
|
||||
nsWidgetRendering GetFormElementRenderingMode(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -56,4 +56,8 @@
|
|||
#define NS_POSITION_BEFORE_TABLE \
|
||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 3)
|
||||
|
||||
/** Error code to return from nsIFrame::Init() if the frame got
|
||||
replaced by alt text or something like that **/
|
||||
#define NS_ERROR_FRAME_REPLACED \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_LAYOUT, 4)
|
||||
#endif // nsLayoutErrors_h___
|
||||
|
|
|
@ -56,4 +56,8 @@
|
|||
#define NS_POSITION_BEFORE_TABLE \
|
||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 3)
|
||||
|
||||
/** Error code to return from nsIFrame::Init() if the frame got
|
||||
replaced by alt text or something like that **/
|
||||
#define NS_ERROR_FRAME_REPLACED \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_LAYOUT, 4)
|
||||
#endif // nsLayoutErrors_h___
|
||||
|
|
|
@ -326,15 +326,15 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext,
|
|||
// find the highest ancestor that is a frameset
|
||||
nsresult rv = NS_OK;
|
||||
nsIFrame* parentFrame = nsnull;
|
||||
GetParent((nsIFrame**)&parentFrame);
|
||||
GetParent(&parentFrame);
|
||||
mTopLevelFrameset = (nsHTMLFramesetFrame*)this;
|
||||
while (parentFrame) {
|
||||
nsHTMLFramesetFrame* frameset;
|
||||
rv = parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame),
|
||||
(void**)&frameset);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsHTMLFramesetFrame* frameset = nsnull;
|
||||
CallQueryInterface(parentFrame, &frameset);
|
||||
|
||||
if (frameset) {
|
||||
mTopLevelFrameset = frameset;
|
||||
parentFrame->GetParent((nsIFrame**)&parentFrame);
|
||||
parentFrame->GetParent(&parentFrame);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -342,8 +342,7 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
// create the view. a view is needed since it needs to be a mouse grabber
|
||||
nsIView* view;
|
||||
nsresult result = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView),
|
||||
(void **)&view);
|
||||
nsresult result = CallCreateInstance(kViewCID, &view);
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIViewManager> viewMan;
|
||||
|
|
|
@ -98,6 +98,8 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#include "nsLayoutErrors.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef NOISY_IMAGE_LOADING
|
||||
#undef NOISY_ICON_LOADING
|
||||
|
@ -320,8 +322,8 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
PRBool loadBlocked = PR_FALSE;
|
||||
imageLoader->GetImageBlocked(&loadBlocked);
|
||||
HandleLoadError(loadBlocked ? NS_ERROR_IMAGE_BLOCKED : NS_ERROR_FAILURE,
|
||||
presShell);
|
||||
rv = HandleLoadError(loadBlocked ? NS_ERROR_IMAGE_BLOCKED : NS_ERROR_FAILURE,
|
||||
presShell);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -425,14 +427,14 @@ nsImageFrame::ConvertPxRectToTwips(const nsRect& aRect) const
|
|||
NSIntPixelsToTwips(aRect.height, p2t)); // height
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsImageFrame::HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell)
|
||||
{
|
||||
if (aStatus == NS_ERROR_IMAGE_BLOCKED &&
|
||||
!(mIconLoad && mIconLoad->mPrefAllImagesBlocked)) {
|
||||
// don't display any alt feedback in this case; we're blocking images
|
||||
// from that site and don't care to see anything from them
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we have an image map, don't do anything here
|
||||
|
@ -442,7 +444,7 @@ nsImageFrame::HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell)
|
|||
nsAutoString usemap;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::usemap, usemap);
|
||||
if (!usemap.IsEmpty()) {
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check if we want to honor the ALT text in the IMG frame, or let the preShell make it into inline text
|
||||
|
@ -465,7 +467,7 @@ nsImageFrame::HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell)
|
|||
|
||||
// check for style property that indicates the icon should always be shown
|
||||
const nsStyleUIReset* styleData;
|
||||
GetStyleData(eStyleStruct_UIReset, (const nsStyleStruct*&) styleData);
|
||||
::GetStyleData(this, &styleData);
|
||||
if (styleData->mForceBrokenImageIcon) {
|
||||
forceIcon = PR_TRUE;
|
||||
}
|
||||
|
@ -489,11 +491,13 @@ nsImageFrame::HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell)
|
|||
aPresShell->GetPrimaryFrameFor(mContent, &primaryFrame);
|
||||
aPresShell->CantRenderReplacedElement(mPresContext,
|
||||
primaryFrame ? primaryFrame : this);
|
||||
} else {
|
||||
// we are handling it
|
||||
// invalidate the icon area (it may change states)
|
||||
InvalidateIcon(mPresContext);
|
||||
return NS_ERROR_FRAME_REPLACED;
|
||||
}
|
||||
|
||||
// we are handling it
|
||||
// invalidate the icon area (it may change states)
|
||||
InvalidateIcon(mPresContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -233,9 +233,10 @@ private:
|
|||
|
||||
/**
|
||||
* Function to call when a load fails; this handles things like alt
|
||||
* text, broken image icons, etc
|
||||
* text, broken image icons, etc. Returns NS_ERROR_FRAME_REPLACED
|
||||
* if it called CantRenderReplacedElement, NS_OK otherwise.
|
||||
*/
|
||||
void HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell);
|
||||
nsresult HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell);
|
||||
|
||||
nsImageMap* mImageMap;
|
||||
|
||||
|
|
|
@ -638,13 +638,13 @@ nsObjectFrame::Init(nsIPresContext* aPresContext,
|
|||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsIFrame * aNewFrame = nsnull;
|
||||
rv = NS_NewImageFrame(shell, &aNewFrame);
|
||||
if(rv != NS_OK)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// XXX we're using the same style context for ourselves and the
|
||||
// image frame. If this ever changes, please fix HandleChild() to deal.
|
||||
rv = aNewFrame->Init(aPresContext, aContent, this, aContext, aPrevInFlow);
|
||||
if(rv == NS_OK)
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aNewFrame, aContext, nsnull, PR_FALSE);
|
||||
mFrames.AppendFrame(this, aNewFrame);
|
||||
|
|
|
@ -98,6 +98,8 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#include "nsLayoutErrors.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef NOISY_IMAGE_LOADING
|
||||
#undef NOISY_ICON_LOADING
|
||||
|
@ -320,8 +322,8 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
PRBool loadBlocked = PR_FALSE;
|
||||
imageLoader->GetImageBlocked(&loadBlocked);
|
||||
HandleLoadError(loadBlocked ? NS_ERROR_IMAGE_BLOCKED : NS_ERROR_FAILURE,
|
||||
presShell);
|
||||
rv = HandleLoadError(loadBlocked ? NS_ERROR_IMAGE_BLOCKED : NS_ERROR_FAILURE,
|
||||
presShell);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -425,14 +427,14 @@ nsImageFrame::ConvertPxRectToTwips(const nsRect& aRect) const
|
|||
NSIntPixelsToTwips(aRect.height, p2t)); // height
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsImageFrame::HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell)
|
||||
{
|
||||
if (aStatus == NS_ERROR_IMAGE_BLOCKED &&
|
||||
!(mIconLoad && mIconLoad->mPrefAllImagesBlocked)) {
|
||||
// don't display any alt feedback in this case; we're blocking images
|
||||
// from that site and don't care to see anything from them
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we have an image map, don't do anything here
|
||||
|
@ -442,7 +444,7 @@ nsImageFrame::HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell)
|
|||
nsAutoString usemap;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::usemap, usemap);
|
||||
if (!usemap.IsEmpty()) {
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check if we want to honor the ALT text in the IMG frame, or let the preShell make it into inline text
|
||||
|
@ -465,7 +467,7 @@ nsImageFrame::HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell)
|
|||
|
||||
// check for style property that indicates the icon should always be shown
|
||||
const nsStyleUIReset* styleData;
|
||||
GetStyleData(eStyleStruct_UIReset, (const nsStyleStruct*&) styleData);
|
||||
::GetStyleData(this, &styleData);
|
||||
if (styleData->mForceBrokenImageIcon) {
|
||||
forceIcon = PR_TRUE;
|
||||
}
|
||||
|
@ -489,11 +491,13 @@ nsImageFrame::HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell)
|
|||
aPresShell->GetPrimaryFrameFor(mContent, &primaryFrame);
|
||||
aPresShell->CantRenderReplacedElement(mPresContext,
|
||||
primaryFrame ? primaryFrame : this);
|
||||
} else {
|
||||
// we are handling it
|
||||
// invalidate the icon area (it may change states)
|
||||
InvalidateIcon(mPresContext);
|
||||
return NS_ERROR_FRAME_REPLACED;
|
||||
}
|
||||
|
||||
// we are handling it
|
||||
// invalidate the icon area (it may change states)
|
||||
InvalidateIcon(mPresContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -233,9 +233,10 @@ private:
|
|||
|
||||
/**
|
||||
* Function to call when a load fails; this handles things like alt
|
||||
* text, broken image icons, etc
|
||||
* text, broken image icons, etc. Returns NS_ERROR_FRAME_REPLACED
|
||||
* if it called CantRenderReplacedElement, NS_OK otherwise.
|
||||
*/
|
||||
void HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell);
|
||||
nsresult HandleLoadError(nsresult aStatus, nsIPresShell* aPresShell);
|
||||
|
||||
nsImageMap* mImageMap;
|
||||
|
||||
|
|
|
@ -638,13 +638,13 @@ nsObjectFrame::Init(nsIPresContext* aPresContext,
|
|||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsIFrame * aNewFrame = nsnull;
|
||||
rv = NS_NewImageFrame(shell, &aNewFrame);
|
||||
if(rv != NS_OK)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// XXX we're using the same style context for ourselves and the
|
||||
// image frame. If this ever changes, please fix HandleChild() to deal.
|
||||
rv = aNewFrame->Init(aPresContext, aContent, this, aContext, aPrevInFlow);
|
||||
if(rv == NS_OK)
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aNewFrame, aContext, nsnull, PR_FALSE);
|
||||
mFrames.AppendFrame(this, aNewFrame);
|
||||
|
|
|
@ -326,15 +326,15 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext,
|
|||
// find the highest ancestor that is a frameset
|
||||
nsresult rv = NS_OK;
|
||||
nsIFrame* parentFrame = nsnull;
|
||||
GetParent((nsIFrame**)&parentFrame);
|
||||
GetParent(&parentFrame);
|
||||
mTopLevelFrameset = (nsHTMLFramesetFrame*)this;
|
||||
while (parentFrame) {
|
||||
nsHTMLFramesetFrame* frameset;
|
||||
rv = parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame),
|
||||
(void**)&frameset);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsHTMLFramesetFrame* frameset = nsnull;
|
||||
CallQueryInterface(parentFrame, &frameset);
|
||||
|
||||
if (frameset) {
|
||||
mTopLevelFrameset = frameset;
|
||||
parentFrame->GetParent((nsIFrame**)&parentFrame);
|
||||
parentFrame->GetParent(&parentFrame);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -342,8 +342,7 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
// create the view. a view is needed since it needs to be a mouse grabber
|
||||
nsIView* view;
|
||||
nsresult result = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView),
|
||||
(void **)&view);
|
||||
nsresult result = CallCreateInstance(kViewCID, &view);
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIViewManager> viewMan;
|
||||
|
|
|
@ -1421,10 +1421,18 @@ nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIPresContext* aPresContex
|
|||
content->SetDocument(aDocument, PR_TRUE, PR_TRUE);
|
||||
|
||||
// Create an image frame and initialize it
|
||||
nsIFrame* imageFrame;
|
||||
NS_NewImageFrame(shell, &imageFrame);
|
||||
imageFrame->Init(aPresContext, content, aParentFrame, aStyleContext, nsnull);
|
||||
|
||||
nsIFrame* imageFrame = nsnull;
|
||||
rv = NS_NewImageFrame(shell, &imageFrame);
|
||||
if (!imageFrame) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = imageFrame->Init(aPresContext, content, aParentFrame, aStyleContext, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
imageFrame->Destroy(aPresContext);
|
||||
return rv == NS_ERROR_FRAME_REPLACED ? NS_OK : rv;
|
||||
}
|
||||
|
||||
// Return the image frame
|
||||
*aFrame = imageFrame;
|
||||
|
||||
|
@ -4973,69 +4981,89 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsIPresShell* aPresShell,
|
|||
}
|
||||
}
|
||||
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
geometricParent, aStyleContext, nsnull, newFrame);
|
||||
rv = InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
geometricParent, aStyleContext, nsnull, newFrame);
|
||||
if (rv == NS_ERROR_FRAME_REPLACED) {
|
||||
// The frame called CantRenderReplacedElement from inside Init(). That
|
||||
// failed to do anything useful, since the frame was not in the frame
|
||||
// tree yet... Create an alternate frame ourselves
|
||||
newFrame->Destroy(aPresContext);
|
||||
|
||||
// See if we need to create a view, e.g. the frame is absolutely
|
||||
// positioned
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
||||
aStyleContext, aParentFrame, PR_FALSE);
|
||||
if (aTag != nsHTMLAtoms::img && aTag != nsHTMLAtoms::input) {
|
||||
// XXXbz This should really be made to work for <object> too...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Process the child content if requested
|
||||
nsFrameItems childItems;
|
||||
if (processChildren) {
|
||||
if (isPositionedContainingBlock) {
|
||||
// The area frame becomes a container for child frames that are
|
||||
// absolutely positioned
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
aState.PushAbsoluteContainingBlock(aPresContext, newFrame, absoluteSaveState);
|
||||
// Try to construct the alternate frame
|
||||
newFrame = nsnull;
|
||||
rv = ConstructAlternateFrame(aPresShell, aPresContext, aContent,
|
||||
aStyleContext, geometricParent,
|
||||
aParentFrame, newFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(newFrame, "ConstructAlternateFrame needs better error-checking");
|
||||
} else {
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "InitAndRestoreFrame failed");
|
||||
// See if we need to create a view, e.g. the frame is absolutely
|
||||
// positioned
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
||||
aStyleContext, aParentFrame, PR_FALSE);
|
||||
|
||||
// Process the child content if requested
|
||||
nsFrameItems childItems;
|
||||
if (processChildren) {
|
||||
if (isPositionedContainingBlock) {
|
||||
// The area frame becomes a container for child frames that are
|
||||
// absolutely positioned
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
aState.PushAbsoluteContainingBlock(aPresContext, newFrame, absoluteSaveState);
|
||||
|
||||
// Process the child frames
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
// Process the child frames
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
|
||||
// Set the frame's absolute list if there were any absolutely positioned children
|
||||
if (aState.mAbsoluteItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext,
|
||||
nsLayoutAtoms::absoluteList,
|
||||
aState.mAbsoluteItems.childList);
|
||||
// Set the frame's absolute list if there were any absolutely positioned children
|
||||
if (aState.mAbsoluteItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext,
|
||||
nsLayoutAtoms::absoluteList,
|
||||
aState.mAbsoluteItems.childList);
|
||||
}
|
||||
}
|
||||
else if (isFloaterContainer) {
|
||||
// If the frame can contain floaters, then push a floater
|
||||
// containing block
|
||||
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
||||
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
||||
&haveFirstLetterStyle, &haveFirstLineStyle);
|
||||
nsFrameConstructorSaveState floaterSaveState;
|
||||
aState.PushFloaterContainingBlock(newFrame, floaterSaveState,
|
||||
PR_FALSE, PR_FALSE);
|
||||
|
||||
// Process the child frames
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
|
||||
// Set the frame's floater list if there were any floated children
|
||||
if (aState.mFloatedItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext,
|
||||
nsLayoutAtoms::floaterList,
|
||||
aState.mFloatedItems.childList);
|
||||
}
|
||||
|
||||
} else {
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
}
|
||||
}
|
||||
else if (isFloaterContainer) {
|
||||
// If the frame can contain floaters, then push a floater
|
||||
// containing block
|
||||
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
||||
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
||||
&haveFirstLetterStyle, &haveFirstLineStyle);
|
||||
nsFrameConstructorSaveState floaterSaveState;
|
||||
aState.PushFloaterContainingBlock(newFrame, floaterSaveState,
|
||||
PR_FALSE, PR_FALSE);
|
||||
|
||||
// Process the child frames
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
|
||||
// Set the frame's floater list if there were any floated children
|
||||
if (aState.mFloatedItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext,
|
||||
nsLayoutAtoms::floaterList,
|
||||
aState.mFloatedItems.childList);
|
||||
}
|
||||
|
||||
} else {
|
||||
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
||||
PR_TRUE, childItems, PR_FALSE);
|
||||
// if there are any anonymous children create frames for them
|
||||
CreateAnonymousFrames(aPresShell, aPresContext, aTag, aState, aContent, newFrame,
|
||||
PR_FALSE, childItems);
|
||||
|
||||
// Set the frame's initial child list
|
||||
if (childItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
||||
}
|
||||
}
|
||||
|
||||
// if there are any anonymous children create frames for them
|
||||
CreateAnonymousFrames(aPresShell, aPresContext, aTag, aState, aContent, newFrame,
|
||||
PR_FALSE, childItems);
|
||||
|
||||
// Set the frame's initial child list
|
||||
if (childItems.childList) {
|
||||
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
||||
}
|
||||
}
|
||||
|
||||
// If the frame is positioned, then create a placeholder frame
|
||||
|
@ -10757,7 +10785,8 @@ nsCSSFrameConstructor::ConstructAlternateFrame(nsIPresShell* aPresShell,
|
|||
nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aGeometricParent,
|
||||
nsIFrame* aContentParent,
|
||||
nsIFrame*& aFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -10802,9 +10831,10 @@ nsCSSFrameConstructor::ConstructAlternateFrame(nsIPresShell* aPresShell,
|
|||
} else {
|
||||
NS_NewInlineFrame(aPresShell, &containerFrame);
|
||||
}
|
||||
containerFrame->Init(aPresContext, aContent, aParentFrame, aStyleContext, nsnull);
|
||||
containerFrame->Init(aPresContext, aContent, aGeometricParent, aStyleContext, nsnull);
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, containerFrame,
|
||||
aStyleContext, nsnull, PR_FALSE);
|
||||
aStyleContext, aContentParent,
|
||||
PR_FALSE);
|
||||
|
||||
// If the frame is out-of-flow, then mark it as such
|
||||
if (isOutOfFlow) {
|
||||
|
@ -10942,7 +10972,7 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresShell* aPresShell,
|
|||
// image can't be rendered
|
||||
nsIFrame* newFrame;
|
||||
rv = ConstructAlternateFrame(aPresShell, aPresContext, content, styleContext,
|
||||
parentFrame, newFrame);
|
||||
parentFrame, nsnull, newFrame);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
|
@ -10956,6 +10986,7 @@ nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresShell* aPresShell,
|
|||
frameManager->SetPrimaryFrameFor(content, newFrame);
|
||||
|
||||
// Replace the old frame with the new frame
|
||||
// XXXbz If this fails, we leak the content node newFrame points to!
|
||||
frameManager->ReplaceFrame(aPresContext, *presShell, parentFrame,
|
||||
listName, aFrame, newFrame);
|
||||
|
||||
|
@ -12035,11 +12066,21 @@ nsCSSFrameConstructor::RecreateFramesForContent(nsIPresContext* aPresContext,
|
|||
// state onto a temporary state object.
|
||||
CaptureStateForFramesOf(aPresContext, aContent, mTempFrameTreeState);
|
||||
|
||||
// Save parent frame because this frame is going away
|
||||
// Save parent frame because this frame is going away. But if
|
||||
// this is an out-of-flow, we want to get the _placeholder_'s
|
||||
// parent.
|
||||
nsIFrame* parent = nsnull;
|
||||
if (frame)
|
||||
frame->GetParent(&parent);
|
||||
if (frame) {
|
||||
nsFrameState state;
|
||||
frame->GetFrameState(&state);
|
||||
if (state & NS_FRAME_OUT_OF_FLOW) {
|
||||
shell->GetPlaceholderFrameFor(frame, &frame);
|
||||
NS_ASSERTION(frame, "Out-of-flow with no placeholder?");
|
||||
}
|
||||
|
||||
frame->GetParent(&parent);
|
||||
}
|
||||
|
||||
// Remove the frames associated with the content object on which the
|
||||
// attribute change occurred.
|
||||
rv = ContentRemoved(aPresContext, container, aContent, indexInContainer, PR_FALSE);
|
||||
|
|
|
@ -472,7 +472,8 @@ protected:
|
|||
nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aGeometricParent,
|
||||
nsIFrame* aContentParent,
|
||||
nsIFrame*& aFrame);
|
||||
|
||||
nsWidgetRendering GetFormElementRenderingMode(nsIPresContext* aPresContext,
|
||||
|
|
Загрузка…
Ссылка в новой задаче