Remove attempted workaround for CantRenderReplacedElement crash that didn't fix the crash (which is now fixed the right way).
Clean up the FrameManager a bit, mainly by moving the destruction of the frame tree into the |Destroy| method rather than doing it in the destructor. This would make it safer to convert nsIFrameManager to IDL and use the frame manager from JS. It also reduces the risk of leaks caused by having something owned by a frame own the frame manager. Breaking cycles in a destructor can be risky because the objects entrained by the cycle could include the object whose destructor would break the cycle. b=65800 r=waterson@netscape.com sr=attinasi@netscape.com git-svn-id: svn://10.0.0.236/trunk@88603 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -176,6 +176,10 @@ protected:
|
||||
|
||||
class FrameManager;
|
||||
|
||||
// A CantRenderReplacedElementEvent has a weak pointer to the frame
|
||||
// manager, and the frame manager has a weak pointer to the event.
|
||||
// The event queue owns the event and the FrameManager will delete
|
||||
// the event if it's going to go away.
|
||||
struct CantRenderReplacedElementEvent : public PLEvent {
|
||||
CantRenderReplacedElementEvent(FrameManager* aFrameManager, nsIFrame* aFrame);
|
||||
|
||||
@@ -196,6 +200,7 @@ public:
|
||||
|
||||
// nsIFrameManager
|
||||
NS_IMETHOD Init(nsIPresShell* aPresShell, nsIStyleSet* aStyleSet);
|
||||
NS_IMETHOD Destroy();
|
||||
|
||||
// Gets and sets the root frame
|
||||
NS_IMETHOD GetRootFrame(nsIFrame** aRootFrame) const;
|
||||
@@ -252,11 +257,6 @@ public:
|
||||
NS_IMETHOD CantRenderReplacedElement(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
/** return PR_TRUE if this instance is prepared to process events
|
||||
* (specifically, CantRenderReplacedElement events.)
|
||||
*/
|
||||
NS_IMETHOD CanProcessEvents() { return mCanProcessEvents; }
|
||||
|
||||
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
||||
|
||||
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
|
||||
@@ -335,9 +335,6 @@ private:
|
||||
FrameHashTable* mPlaceholderMap;
|
||||
UndisplayedMap* mUndisplayedMap;
|
||||
CantRenderReplacedElementEvent* mPostedEvents;
|
||||
// keep around a flag that we use to prevent processing on event callbacks after
|
||||
// we've started the shutdown procedure
|
||||
PRBool mCanProcessEvents;
|
||||
PropertyList* mPropertyList;
|
||||
|
||||
void ReResolveStyleContext(nsIPresContext* aPresContext,
|
||||
@@ -350,7 +347,7 @@ private:
|
||||
PRInt32 aMinChange,
|
||||
PRInt32& aResultChange);
|
||||
|
||||
void RevokePostedEvents();
|
||||
nsresult RevokePostedEvents();
|
||||
CantRenderReplacedElementEvent** FindPostedEventFor(nsIFrame* aFrame);
|
||||
void DequeuePostedEventFor(nsIFrame* aFrame);
|
||||
void DestroyPropertyList(nsIPresContext* aPresContext);
|
||||
@@ -381,58 +378,22 @@ NS_NewFrameManager(nsIFrameManager** aInstancePtrResult)
|
||||
FrameManager::FrameManager()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mCanProcessEvents = PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(FrameManager)
|
||||
NS_IMPL_RELEASE(FrameManager)
|
||||
|
||||
FrameManager::~FrameManager()
|
||||
{
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p ~FrameManager() start\n", this);
|
||||
#endif
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
|
||||
// first, mark this FM so it no longer can accept events
|
||||
mCanProcessEvents = PR_FALSE;
|
||||
|
||||
// Revoke any events posted to the event queue that we haven't processed yet
|
||||
RevokePostedEvents();
|
||||
|
||||
// Destroy the frame hierarchy. Don't destroy the property lists until after
|
||||
// we've destroyed the frame hierarchy because some frames may expect to be
|
||||
// able to retrieve their properties during destruction
|
||||
if (mRootFrame) {
|
||||
mRootFrame->Destroy(presContext);
|
||||
mRootFrame = nsnull;
|
||||
}
|
||||
|
||||
delete mPrimaryFrameMap;
|
||||
delete mPlaceholderMap;
|
||||
delete mUndisplayedMap;
|
||||
DestroyPropertyList(presContext);
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p ~FrameManager() end\n", this);
|
||||
#endif
|
||||
NS_ASSERTION(!mPresShell, "FrameManager::Destroy never called");
|
||||
}
|
||||
|
||||
nsresult
|
||||
FrameManager::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (aIID.Equals(GetIID())) {
|
||||
*aInstancePtr = (void*)(nsIFrameManager*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
NS_IMPL_ISUPPORTS1(FrameManager, nsIFrameManager)
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::Init(nsIPresShell* aPresShell,
|
||||
nsIStyleSet* aStyleSet)
|
||||
{
|
||||
NS_ASSERTION(aPresShell, "null aPresShell");
|
||||
NS_ASSERTION(aStyleSet, "null aStyleSet");
|
||||
|
||||
mPresShell = aPresShell;
|
||||
mStyleSet = aStyleSet;
|
||||
|
||||
@@ -445,9 +406,44 @@ FrameManager::Init(nsIPresShell* aPresShell,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::Destroy()
|
||||
{
|
||||
NS_ASSERTION(mPresShell, "Frame manager already shut down.");
|
||||
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
|
||||
// Destroy the frame hierarchy. Don't destroy the property lists until after
|
||||
// we've destroyed the frame hierarchy because some frames may expect to be
|
||||
// able to retrieve their properties during destruction
|
||||
if (mRootFrame) {
|
||||
mRootFrame->Destroy(presContext);
|
||||
mRootFrame = nsnull;
|
||||
}
|
||||
|
||||
delete mPrimaryFrameMap;
|
||||
delete mPlaceholderMap;
|
||||
delete mUndisplayedMap;
|
||||
DestroyPropertyList(presContext);
|
||||
|
||||
// If we're not going to be used anymore, we should revoke the
|
||||
// pending |CantRenderReplacedElementEvent|s being sent to us.
|
||||
nsresult rv = RevokePostedEvents();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "RevokePostedEvents failed: might crash");
|
||||
|
||||
mPresShell = nsnull; // mPresShell isn't valid anymore. We
|
||||
// won't use it, either, but we check it
|
||||
// at the start of every function so that we'll
|
||||
// be OK when nsIPresShell is converted to IDL.
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetRootFrame(nsIFrame** aRootFrame) const
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aRootFrame);
|
||||
*aRootFrame = mRootFrame;
|
||||
return NS_OK;
|
||||
@@ -456,6 +452,7 @@ FrameManager::GetRootFrame(nsIFrame** aRootFrame) const
|
||||
NS_IMETHODIMP
|
||||
FrameManager::SetRootFrame(nsIFrame* aRootFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(!mRootFrame, "already have a root frame");
|
||||
if (mRootFrame) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
@@ -468,6 +465,7 @@ FrameManager::SetRootFrame(nsIFrame* aRootFrame)
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetCanvasFrame(nsIPresContext* aPresContext, nsIFrame** aCanvasFrame) const
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(aCanvasFrame, "aCanvasFrame argument cannot be null");
|
||||
NS_PRECONDITION(aPresContext, "aPresContext argument cannot be null");
|
||||
|
||||
@@ -503,6 +501,7 @@ FrameManager::GetCanvasFrame(nsIPresContext* aPresContext, nsIFrame** aCanvasFra
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetPrimaryFrameFor(nsIContent* aContent, nsIFrame** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_ARG_POINTER(aContent);
|
||||
if (!aContent || !aResult) {
|
||||
@@ -571,6 +570,7 @@ NS_IMETHODIMP
|
||||
FrameManager::SetPrimaryFrameFor(nsIContent* aContent,
|
||||
nsIFrame* aPrimaryFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aContent);
|
||||
// it's ok if aPrimaryFrame is null
|
||||
|
||||
@@ -598,6 +598,7 @@ FrameManager::SetPrimaryFrameFor(nsIContent* aContent,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearPrimaryFrameMap()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mPrimaryFrameMap) {
|
||||
mPrimaryFrameMap->Clear();
|
||||
}
|
||||
@@ -609,6 +610,7 @@ NS_IMETHODIMP
|
||||
FrameManager::GetPlaceholderFrameFor(nsIFrame* aFrame,
|
||||
nsIFrame** aResult) const
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_ARG_POINTER(aFrame);
|
||||
if (!aResult || !aFrame) {
|
||||
@@ -628,6 +630,7 @@ NS_IMETHODIMP
|
||||
FrameManager::SetPlaceholderFrameFor(nsIFrame* aFrame,
|
||||
nsIFrame* aPlaceholderFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aFrame);
|
||||
#ifdef NS_DEBUG
|
||||
// Verify that the placeholder frame is of the correct type
|
||||
@@ -663,6 +666,7 @@ FrameManager::SetPlaceholderFrameFor(nsIFrame* aFrame,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearPlaceholderFrameMap()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mPlaceholderMap) {
|
||||
mPlaceholderMap->Clear();
|
||||
}
|
||||
@@ -675,6 +679,7 @@ NS_IMETHODIMP
|
||||
FrameManager::SetUndisplayedContent(nsIContent* aContent,
|
||||
nsIStyleContext* aStyleContext)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (! mUndisplayedMap) {
|
||||
mUndisplayedMap = new UndisplayedMap;
|
||||
}
|
||||
@@ -695,6 +700,7 @@ NS_IMETHODIMP
|
||||
FrameManager::SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext,
|
||||
nsIContent* aParentContent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (! mUndisplayedMap) {
|
||||
mUndisplayedMap = new UndisplayedMap;
|
||||
}
|
||||
@@ -707,6 +713,7 @@ FrameManager::SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mUndisplayedMap) {
|
||||
UndisplayedNode* node = mUndisplayedMap->GetFirstNode(aParentContent);
|
||||
while (node) {
|
||||
@@ -722,6 +729,7 @@ FrameManager::ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParen
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mUndisplayedMap) {
|
||||
return mUndisplayedMap->RemoveNodesFor(aParentContent);
|
||||
}
|
||||
@@ -731,6 +739,7 @@ FrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent)
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearUndisplayedContentMap()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mUndisplayedMap) {
|
||||
mUndisplayedMap->Clear();
|
||||
}
|
||||
@@ -746,6 +755,7 @@ FrameManager::AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
nsIFrame* insertionPoint = nsnull;
|
||||
GetInsertionPoint(&aPresShell, aParentFrame, aFrameList, &insertionPoint);
|
||||
if (insertionPoint) {
|
||||
@@ -776,6 +786,7 @@ FrameManager::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
nsIFrame* insertionPoint = nsnull;
|
||||
GetInsertionPoint(&aPresShell, aParentFrame, aFrameList, &insertionPoint);
|
||||
if (insertionPoint) {
|
||||
@@ -805,6 +816,7 @@ FrameManager::RemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
nsIFrame* insertionPoint = nsnull;
|
||||
GetInsertionPoint(&aPresShell, aParentFrame, aOldFrame, &insertionPoint);
|
||||
if (insertionPoint)
|
||||
@@ -822,6 +834,7 @@ FrameManager::ReplaceFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aOldFrame,
|
||||
nsIFrame* aNewFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
return aParentFrame->ReplaceFrame(aPresContext, aPresShell, aListName,
|
||||
aOldFrame, aNewFrame);
|
||||
}
|
||||
@@ -831,6 +844,7 @@ FrameManager::ReplaceFrame(nsIPresContext* aPresContext,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::NotifyDestroyingFrame(nsIFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
// Dequeue and destroy and posted events for this frame
|
||||
DequeuePostedEventFor(aFrame);
|
||||
|
||||
@@ -842,9 +856,10 @@ FrameManager::NotifyDestroyingFrame(nsIFrame* aFrame)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
FrameManager::RevokePostedEvents()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p ~RevokePostedEvents() start\n", this);
|
||||
#endif
|
||||
@@ -853,7 +868,6 @@ FrameManager::RevokePostedEvents()
|
||||
|
||||
// Revoke any events in the event queue that are owned by us
|
||||
nsIEventQueueService* eventService;
|
||||
nsresult rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
||||
NS_GET_IID(nsIEventQueueService),
|
||||
@@ -865,13 +879,14 @@ FrameManager::RevokePostedEvents()
|
||||
nsServiceManager::ReleaseService(kEventQueueServiceCID, eventService);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && eventQueue) {
|
||||
eventQueue->RevokeEvents(this);
|
||||
rv = eventQueue->RevokeEvents(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p ~RevokePostedEvents() end\n", this);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
CantRenderReplacedElementEvent**
|
||||
@@ -907,16 +922,22 @@ FrameManager::DequeuePostedEventFor(nsIFrame* aFrame)
|
||||
rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
||||
NS_GET_IID(nsIEventQueueService),
|
||||
(nsISupports **)&eventService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"will crash soon due to event holding dangling pointer to frame");
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIEventQueue> eventQueue;
|
||||
rv = eventService->GetThreadEventQueue(NS_CURRENT_THREAD,
|
||||
getter_AddRefs(eventQueue));
|
||||
nsServiceManager::ReleaseService(kEventQueueServiceCID, eventService);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && eventQueue,
|
||||
"will crash soon due to event holding dangling pointer to frame");
|
||||
if (NS_SUCCEEDED(rv) && eventQueue) {
|
||||
PLEventQueue* plqueue;
|
||||
|
||||
eventQueue->GetPLEventQueue(&plqueue);
|
||||
NS_ASSERTION(plqueue,
|
||||
"will crash soon due to event holding dangling pointer to frame");
|
||||
if (plqueue) {
|
||||
// Removes the event and destroys it
|
||||
PL_DequeueEvent(tmp, plqueue);
|
||||
@@ -927,34 +948,37 @@ FrameManager::DequeuePostedEventFor(nsIFrame* aFrame)
|
||||
}
|
||||
|
||||
void
|
||||
FrameManager::HandlePLEvent(CantRenderReplacedElementEvent* aEvent) {
|
||||
FrameManager::HandlePLEvent(CantRenderReplacedElementEvent* aEvent)
|
||||
{
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("FrameManager::HandlePLEvent() start for FM %p\n", aEvent->owner);
|
||||
#endif
|
||||
FrameManager* frameManager = (FrameManager*)aEvent->owner;
|
||||
NS_ASSERTION(frameManager, "null frame manager");
|
||||
|
||||
//adding a ptr check since talkback is complaining about a crash here.
|
||||
//I suspect that if the event->owner is really null, bad things will happen
|
||||
//elsewhere.
|
||||
if(frameManager && frameManager->CanProcessEvents()) {
|
||||
|
||||
// Remove the posted event from the linked list
|
||||
CantRenderReplacedElementEvent** events = &frameManager->mPostedEvents;
|
||||
while (*events) {
|
||||
if (*events == aEvent) {
|
||||
*events = (*events)->mNext;
|
||||
break;
|
||||
} else {
|
||||
events = &(*events)->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the style system and then process any reflow commands that
|
||||
// are generated
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
frameManager->mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
frameManager->mStyleSet->CantRenderReplacedElement(presContext, aEvent->mFrame);
|
||||
if (!frameManager->mPresShell) {
|
||||
NS_ASSERTION(frameManager->mPresShell,
|
||||
"event not removed from queue on shutdown");
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the posted event from the linked list
|
||||
CantRenderReplacedElementEvent** events = &frameManager->mPostedEvents;
|
||||
while (*events) {
|
||||
if (*events == aEvent) {
|
||||
*events = (*events)->mNext;
|
||||
break;
|
||||
}
|
||||
events = &(*events)->mNext;
|
||||
NS_ASSERTION(*events, "event not in queue");
|
||||
}
|
||||
|
||||
// Notify the style system and then process any reflow commands that
|
||||
// are generated
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
frameManager->mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
frameManager->mStyleSet->CantRenderReplacedElement(presContext,
|
||||
aEvent->mFrame);
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("FrameManager::HandlePLEvent() end for FM %p\n", aEvent->owner);
|
||||
#endif
|
||||
@@ -969,9 +993,8 @@ FrameManager::DestroyPLEvent(CantRenderReplacedElementEvent* aEvent)
|
||||
CantRenderReplacedElementEvent::CantRenderReplacedElementEvent(FrameManager* aFrameManager,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
// Note: because the frame manager owns us we don't hold a reference to the
|
||||
// frame manager
|
||||
PL_InitEvent(this, aFrameManager, (PLHandleEventProc)&FrameManager::HandlePLEvent,
|
||||
PL_InitEvent(this, aFrameManager,
|
||||
(PLHandleEventProc)&FrameManager::HandlePLEvent,
|
||||
(PLDestroyEventProc)&FrameManager::DestroyPLEvent);
|
||||
mFrame = aFrame;
|
||||
}
|
||||
@@ -980,6 +1003,7 @@ NS_IMETHODIMP
|
||||
FrameManager::CantRenderReplacedElement(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p FrameManager::CantRenderReplacedElement called\n", this);
|
||||
#endif
|
||||
@@ -1033,10 +1057,10 @@ DumpContext(nsIFrame* aFrame, nsIStyleContext* aContext)
|
||||
frameDebug->GetFrameName(name);
|
||||
fputs(name, stdout);
|
||||
}
|
||||
fprintf(stdout, " (%p)", aFrame);
|
||||
fprintf(stdout, " (%p)", NS_STATIC_CAST(void*, aFrame));
|
||||
}
|
||||
if (aContext) {
|
||||
fprintf(stdout, " style: %p ", aContext);
|
||||
fprintf(stdout, " style: %p ", NS_STATIC_CAST(void*, aContext));
|
||||
|
||||
nsIAtom* pseudoTag;
|
||||
aContext->GetPseudoType(pseudoTag);
|
||||
@@ -1209,6 +1233,7 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext*
|
||||
NS_IMETHODIMP
|
||||
FrameManager::DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (aFrame) {
|
||||
nsIStyleContext* context;
|
||||
aFrame->GetStyleContext(&context);
|
||||
@@ -1328,6 +1353,7 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext*
|
||||
NS_IMETHODIMP
|
||||
FrameManager::DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (aFrame) {
|
||||
nsIStyleContext* context;
|
||||
aFrame->GetStyleContext(&context);
|
||||
@@ -1346,6 +1372,7 @@ FrameManager::ReParentStyleContext(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIStyleContext* aNewParentContext)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
nsresult result = NS_ERROR_NULL_POINTER;
|
||||
if (aFrame) {
|
||||
#ifdef NS_DEBUG
|
||||
@@ -1955,6 +1982,7 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext,
|
||||
PRInt32 aMinChange,
|
||||
PRInt32& aTopLevelChange)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
aTopLevelChange = NS_STYLE_HINT_NONE;
|
||||
nsIFrame* frame = aFrame;
|
||||
|
||||
@@ -1986,6 +2014,7 @@ FrameManager::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
@@ -2007,6 +2036,7 @@ NS_IMETHODIMP
|
||||
FrameManager::CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
|
||||
|
||||
// See if the frame is stateful.
|
||||
@@ -2051,6 +2081,7 @@ NS_IMETHODIMP
|
||||
FrameManager::CaptureFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
|
||||
|
||||
rv = CaptureFrameStateFor(aPresContext, aFrame, aState);
|
||||
@@ -2079,6 +2110,7 @@ NS_IMETHODIMP
|
||||
FrameManager::RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
|
||||
|
||||
// See if the frame is stateful.
|
||||
@@ -2122,6 +2154,7 @@ NS_IMETHODIMP
|
||||
FrameManager::RestoreFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
|
||||
|
||||
rv = RestoreFrameStateFor(aPresContext, aFrame, aState);
|
||||
@@ -2287,6 +2320,7 @@ FrameManager::GetFrameProperty(nsIFrame* aFrame,
|
||||
PRUint32 aOptions,
|
||||
void** aPropertyValue)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
nsresult result;
|
||||
@@ -2308,6 +2342,7 @@ FrameManager::SetFrameProperty(nsIFrame* aFrame,
|
||||
void* aPropertyValue,
|
||||
NSFMPropertyDtorFunc aPropDtorFunc)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
nsresult result = NS_OK;
|
||||
@@ -2348,6 +2383,7 @@ NS_IMETHODIMP
|
||||
FrameManager::RemoveFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
nsresult result = NS_IFRAME_MGR_PROP_NOT_THERE;
|
||||
@@ -2367,6 +2403,7 @@ FrameManager::RemoveFrameProperty(nsIFrame* aFrame,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFrame* aChild, nsIFrame** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
*aResult = nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
|
||||
@@ -1339,7 +1339,10 @@ PresShell::~PresShell()
|
||||
}
|
||||
|
||||
// Destroy the frame manager. This will destroy the frame hierarchy
|
||||
NS_IF_RELEASE(mFrameManager);
|
||||
if (mFrameManager) {
|
||||
mFrameManager->Destroy();
|
||||
NS_RELEASE(mFrameManager);
|
||||
}
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->DeleteShell(this);
|
||||
|
||||
@@ -73,6 +73,14 @@ public:
|
||||
// Initialization
|
||||
NS_IMETHOD Init(nsIPresShell* aPresShell, nsIStyleSet* aStyleSet) = 0;
|
||||
|
||||
/**
|
||||
* After Destroy is called, all methods should return
|
||||
* NS_ERROR_NOT_AVAILABLE. Destroy should be called when the
|
||||
* frame tree managed by the frame manager is no longer being
|
||||
* displayed.
|
||||
*/
|
||||
NS_IMETHOD Destroy() = 0;
|
||||
|
||||
// Gets and sets the root frame (typically the viewport). The lifetime of the
|
||||
// root frame is controlled by the frame manager. When the frame manager is
|
||||
// destroyed it destroys the entire frame hierarchy
|
||||
|
||||
@@ -176,6 +176,10 @@ protected:
|
||||
|
||||
class FrameManager;
|
||||
|
||||
// A CantRenderReplacedElementEvent has a weak pointer to the frame
|
||||
// manager, and the frame manager has a weak pointer to the event.
|
||||
// The event queue owns the event and the FrameManager will delete
|
||||
// the event if it's going to go away.
|
||||
struct CantRenderReplacedElementEvent : public PLEvent {
|
||||
CantRenderReplacedElementEvent(FrameManager* aFrameManager, nsIFrame* aFrame);
|
||||
|
||||
@@ -196,6 +200,7 @@ public:
|
||||
|
||||
// nsIFrameManager
|
||||
NS_IMETHOD Init(nsIPresShell* aPresShell, nsIStyleSet* aStyleSet);
|
||||
NS_IMETHOD Destroy();
|
||||
|
||||
// Gets and sets the root frame
|
||||
NS_IMETHOD GetRootFrame(nsIFrame** aRootFrame) const;
|
||||
@@ -252,11 +257,6 @@ public:
|
||||
NS_IMETHOD CantRenderReplacedElement(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
/** return PR_TRUE if this instance is prepared to process events
|
||||
* (specifically, CantRenderReplacedElement events.)
|
||||
*/
|
||||
NS_IMETHOD CanProcessEvents() { return mCanProcessEvents; }
|
||||
|
||||
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
||||
|
||||
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
|
||||
@@ -335,9 +335,6 @@ private:
|
||||
FrameHashTable* mPlaceholderMap;
|
||||
UndisplayedMap* mUndisplayedMap;
|
||||
CantRenderReplacedElementEvent* mPostedEvents;
|
||||
// keep around a flag that we use to prevent processing on event callbacks after
|
||||
// we've started the shutdown procedure
|
||||
PRBool mCanProcessEvents;
|
||||
PropertyList* mPropertyList;
|
||||
|
||||
void ReResolveStyleContext(nsIPresContext* aPresContext,
|
||||
@@ -350,7 +347,7 @@ private:
|
||||
PRInt32 aMinChange,
|
||||
PRInt32& aResultChange);
|
||||
|
||||
void RevokePostedEvents();
|
||||
nsresult RevokePostedEvents();
|
||||
CantRenderReplacedElementEvent** FindPostedEventFor(nsIFrame* aFrame);
|
||||
void DequeuePostedEventFor(nsIFrame* aFrame);
|
||||
void DestroyPropertyList(nsIPresContext* aPresContext);
|
||||
@@ -381,58 +378,22 @@ NS_NewFrameManager(nsIFrameManager** aInstancePtrResult)
|
||||
FrameManager::FrameManager()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mCanProcessEvents = PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(FrameManager)
|
||||
NS_IMPL_RELEASE(FrameManager)
|
||||
|
||||
FrameManager::~FrameManager()
|
||||
{
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p ~FrameManager() start\n", this);
|
||||
#endif
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
|
||||
// first, mark this FM so it no longer can accept events
|
||||
mCanProcessEvents = PR_FALSE;
|
||||
|
||||
// Revoke any events posted to the event queue that we haven't processed yet
|
||||
RevokePostedEvents();
|
||||
|
||||
// Destroy the frame hierarchy. Don't destroy the property lists until after
|
||||
// we've destroyed the frame hierarchy because some frames may expect to be
|
||||
// able to retrieve their properties during destruction
|
||||
if (mRootFrame) {
|
||||
mRootFrame->Destroy(presContext);
|
||||
mRootFrame = nsnull;
|
||||
}
|
||||
|
||||
delete mPrimaryFrameMap;
|
||||
delete mPlaceholderMap;
|
||||
delete mUndisplayedMap;
|
||||
DestroyPropertyList(presContext);
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p ~FrameManager() end\n", this);
|
||||
#endif
|
||||
NS_ASSERTION(!mPresShell, "FrameManager::Destroy never called");
|
||||
}
|
||||
|
||||
nsresult
|
||||
FrameManager::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (aIID.Equals(GetIID())) {
|
||||
*aInstancePtr = (void*)(nsIFrameManager*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
NS_IMPL_ISUPPORTS1(FrameManager, nsIFrameManager)
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::Init(nsIPresShell* aPresShell,
|
||||
nsIStyleSet* aStyleSet)
|
||||
{
|
||||
NS_ASSERTION(aPresShell, "null aPresShell");
|
||||
NS_ASSERTION(aStyleSet, "null aStyleSet");
|
||||
|
||||
mPresShell = aPresShell;
|
||||
mStyleSet = aStyleSet;
|
||||
|
||||
@@ -445,9 +406,44 @@ FrameManager::Init(nsIPresShell* aPresShell,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::Destroy()
|
||||
{
|
||||
NS_ASSERTION(mPresShell, "Frame manager already shut down.");
|
||||
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
|
||||
// Destroy the frame hierarchy. Don't destroy the property lists until after
|
||||
// we've destroyed the frame hierarchy because some frames may expect to be
|
||||
// able to retrieve their properties during destruction
|
||||
if (mRootFrame) {
|
||||
mRootFrame->Destroy(presContext);
|
||||
mRootFrame = nsnull;
|
||||
}
|
||||
|
||||
delete mPrimaryFrameMap;
|
||||
delete mPlaceholderMap;
|
||||
delete mUndisplayedMap;
|
||||
DestroyPropertyList(presContext);
|
||||
|
||||
// If we're not going to be used anymore, we should revoke the
|
||||
// pending |CantRenderReplacedElementEvent|s being sent to us.
|
||||
nsresult rv = RevokePostedEvents();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "RevokePostedEvents failed: might crash");
|
||||
|
||||
mPresShell = nsnull; // mPresShell isn't valid anymore. We
|
||||
// won't use it, either, but we check it
|
||||
// at the start of every function so that we'll
|
||||
// be OK when nsIPresShell is converted to IDL.
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetRootFrame(nsIFrame** aRootFrame) const
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aRootFrame);
|
||||
*aRootFrame = mRootFrame;
|
||||
return NS_OK;
|
||||
@@ -456,6 +452,7 @@ FrameManager::GetRootFrame(nsIFrame** aRootFrame) const
|
||||
NS_IMETHODIMP
|
||||
FrameManager::SetRootFrame(nsIFrame* aRootFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(!mRootFrame, "already have a root frame");
|
||||
if (mRootFrame) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
@@ -468,6 +465,7 @@ FrameManager::SetRootFrame(nsIFrame* aRootFrame)
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetCanvasFrame(nsIPresContext* aPresContext, nsIFrame** aCanvasFrame) const
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(aCanvasFrame, "aCanvasFrame argument cannot be null");
|
||||
NS_PRECONDITION(aPresContext, "aPresContext argument cannot be null");
|
||||
|
||||
@@ -503,6 +501,7 @@ FrameManager::GetCanvasFrame(nsIPresContext* aPresContext, nsIFrame** aCanvasFra
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetPrimaryFrameFor(nsIContent* aContent, nsIFrame** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_ARG_POINTER(aContent);
|
||||
if (!aContent || !aResult) {
|
||||
@@ -571,6 +570,7 @@ NS_IMETHODIMP
|
||||
FrameManager::SetPrimaryFrameFor(nsIContent* aContent,
|
||||
nsIFrame* aPrimaryFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aContent);
|
||||
// it's ok if aPrimaryFrame is null
|
||||
|
||||
@@ -598,6 +598,7 @@ FrameManager::SetPrimaryFrameFor(nsIContent* aContent,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearPrimaryFrameMap()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mPrimaryFrameMap) {
|
||||
mPrimaryFrameMap->Clear();
|
||||
}
|
||||
@@ -609,6 +610,7 @@ NS_IMETHODIMP
|
||||
FrameManager::GetPlaceholderFrameFor(nsIFrame* aFrame,
|
||||
nsIFrame** aResult) const
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_ARG_POINTER(aFrame);
|
||||
if (!aResult || !aFrame) {
|
||||
@@ -628,6 +630,7 @@ NS_IMETHODIMP
|
||||
FrameManager::SetPlaceholderFrameFor(nsIFrame* aFrame,
|
||||
nsIFrame* aPlaceholderFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aFrame);
|
||||
#ifdef NS_DEBUG
|
||||
// Verify that the placeholder frame is of the correct type
|
||||
@@ -663,6 +666,7 @@ FrameManager::SetPlaceholderFrameFor(nsIFrame* aFrame,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearPlaceholderFrameMap()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mPlaceholderMap) {
|
||||
mPlaceholderMap->Clear();
|
||||
}
|
||||
@@ -675,6 +679,7 @@ NS_IMETHODIMP
|
||||
FrameManager::SetUndisplayedContent(nsIContent* aContent,
|
||||
nsIStyleContext* aStyleContext)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (! mUndisplayedMap) {
|
||||
mUndisplayedMap = new UndisplayedMap;
|
||||
}
|
||||
@@ -695,6 +700,7 @@ NS_IMETHODIMP
|
||||
FrameManager::SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext,
|
||||
nsIContent* aParentContent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (! mUndisplayedMap) {
|
||||
mUndisplayedMap = new UndisplayedMap;
|
||||
}
|
||||
@@ -707,6 +713,7 @@ FrameManager::SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mUndisplayedMap) {
|
||||
UndisplayedNode* node = mUndisplayedMap->GetFirstNode(aParentContent);
|
||||
while (node) {
|
||||
@@ -722,6 +729,7 @@ FrameManager::ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParen
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mUndisplayedMap) {
|
||||
return mUndisplayedMap->RemoveNodesFor(aParentContent);
|
||||
}
|
||||
@@ -731,6 +739,7 @@ FrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent)
|
||||
NS_IMETHODIMP
|
||||
FrameManager::ClearUndisplayedContentMap()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (mUndisplayedMap) {
|
||||
mUndisplayedMap->Clear();
|
||||
}
|
||||
@@ -746,6 +755,7 @@ FrameManager::AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
nsIFrame* insertionPoint = nsnull;
|
||||
GetInsertionPoint(&aPresShell, aParentFrame, aFrameList, &insertionPoint);
|
||||
if (insertionPoint) {
|
||||
@@ -776,6 +786,7 @@ FrameManager::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
nsIFrame* insertionPoint = nsnull;
|
||||
GetInsertionPoint(&aPresShell, aParentFrame, aFrameList, &insertionPoint);
|
||||
if (insertionPoint) {
|
||||
@@ -805,6 +816,7 @@ FrameManager::RemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
nsIFrame* insertionPoint = nsnull;
|
||||
GetInsertionPoint(&aPresShell, aParentFrame, aOldFrame, &insertionPoint);
|
||||
if (insertionPoint)
|
||||
@@ -822,6 +834,7 @@ FrameManager::ReplaceFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aOldFrame,
|
||||
nsIFrame* aNewFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
return aParentFrame->ReplaceFrame(aPresContext, aPresShell, aListName,
|
||||
aOldFrame, aNewFrame);
|
||||
}
|
||||
@@ -831,6 +844,7 @@ FrameManager::ReplaceFrame(nsIPresContext* aPresContext,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::NotifyDestroyingFrame(nsIFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
// Dequeue and destroy and posted events for this frame
|
||||
DequeuePostedEventFor(aFrame);
|
||||
|
||||
@@ -842,9 +856,10 @@ FrameManager::NotifyDestroyingFrame(nsIFrame* aFrame)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
FrameManager::RevokePostedEvents()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p ~RevokePostedEvents() start\n", this);
|
||||
#endif
|
||||
@@ -853,7 +868,6 @@ FrameManager::RevokePostedEvents()
|
||||
|
||||
// Revoke any events in the event queue that are owned by us
|
||||
nsIEventQueueService* eventService;
|
||||
nsresult rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
||||
NS_GET_IID(nsIEventQueueService),
|
||||
@@ -865,13 +879,14 @@ FrameManager::RevokePostedEvents()
|
||||
nsServiceManager::ReleaseService(kEventQueueServiceCID, eventService);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && eventQueue) {
|
||||
eventQueue->RevokeEvents(this);
|
||||
rv = eventQueue->RevokeEvents(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p ~RevokePostedEvents() end\n", this);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
CantRenderReplacedElementEvent**
|
||||
@@ -907,16 +922,22 @@ FrameManager::DequeuePostedEventFor(nsIFrame* aFrame)
|
||||
rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
||||
NS_GET_IID(nsIEventQueueService),
|
||||
(nsISupports **)&eventService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"will crash soon due to event holding dangling pointer to frame");
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIEventQueue> eventQueue;
|
||||
rv = eventService->GetThreadEventQueue(NS_CURRENT_THREAD,
|
||||
getter_AddRefs(eventQueue));
|
||||
nsServiceManager::ReleaseService(kEventQueueServiceCID, eventService);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && eventQueue,
|
||||
"will crash soon due to event holding dangling pointer to frame");
|
||||
if (NS_SUCCEEDED(rv) && eventQueue) {
|
||||
PLEventQueue* plqueue;
|
||||
|
||||
eventQueue->GetPLEventQueue(&plqueue);
|
||||
NS_ASSERTION(plqueue,
|
||||
"will crash soon due to event holding dangling pointer to frame");
|
||||
if (plqueue) {
|
||||
// Removes the event and destroys it
|
||||
PL_DequeueEvent(tmp, plqueue);
|
||||
@@ -927,34 +948,37 @@ FrameManager::DequeuePostedEventFor(nsIFrame* aFrame)
|
||||
}
|
||||
|
||||
void
|
||||
FrameManager::HandlePLEvent(CantRenderReplacedElementEvent* aEvent) {
|
||||
FrameManager::HandlePLEvent(CantRenderReplacedElementEvent* aEvent)
|
||||
{
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("FrameManager::HandlePLEvent() start for FM %p\n", aEvent->owner);
|
||||
#endif
|
||||
FrameManager* frameManager = (FrameManager*)aEvent->owner;
|
||||
NS_ASSERTION(frameManager, "null frame manager");
|
||||
|
||||
//adding a ptr check since talkback is complaining about a crash here.
|
||||
//I suspect that if the event->owner is really null, bad things will happen
|
||||
//elsewhere.
|
||||
if(frameManager && frameManager->CanProcessEvents()) {
|
||||
|
||||
// Remove the posted event from the linked list
|
||||
CantRenderReplacedElementEvent** events = &frameManager->mPostedEvents;
|
||||
while (*events) {
|
||||
if (*events == aEvent) {
|
||||
*events = (*events)->mNext;
|
||||
break;
|
||||
} else {
|
||||
events = &(*events)->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the style system and then process any reflow commands that
|
||||
// are generated
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
frameManager->mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
frameManager->mStyleSet->CantRenderReplacedElement(presContext, aEvent->mFrame);
|
||||
if (!frameManager->mPresShell) {
|
||||
NS_ASSERTION(frameManager->mPresShell,
|
||||
"event not removed from queue on shutdown");
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the posted event from the linked list
|
||||
CantRenderReplacedElementEvent** events = &frameManager->mPostedEvents;
|
||||
while (*events) {
|
||||
if (*events == aEvent) {
|
||||
*events = (*events)->mNext;
|
||||
break;
|
||||
}
|
||||
events = &(*events)->mNext;
|
||||
NS_ASSERTION(*events, "event not in queue");
|
||||
}
|
||||
|
||||
// Notify the style system and then process any reflow commands that
|
||||
// are generated
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
frameManager->mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
frameManager->mStyleSet->CantRenderReplacedElement(presContext,
|
||||
aEvent->mFrame);
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("FrameManager::HandlePLEvent() end for FM %p\n", aEvent->owner);
|
||||
#endif
|
||||
@@ -969,9 +993,8 @@ FrameManager::DestroyPLEvent(CantRenderReplacedElementEvent* aEvent)
|
||||
CantRenderReplacedElementEvent::CantRenderReplacedElementEvent(FrameManager* aFrameManager,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
// Note: because the frame manager owns us we don't hold a reference to the
|
||||
// frame manager
|
||||
PL_InitEvent(this, aFrameManager, (PLHandleEventProc)&FrameManager::HandlePLEvent,
|
||||
PL_InitEvent(this, aFrameManager,
|
||||
(PLHandleEventProc)&FrameManager::HandlePLEvent,
|
||||
(PLDestroyEventProc)&FrameManager::DestroyPLEvent);
|
||||
mFrame = aFrame;
|
||||
}
|
||||
@@ -980,6 +1003,7 @@ NS_IMETHODIMP
|
||||
FrameManager::CantRenderReplacedElement(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
#ifdef NOISY_EVENTS
|
||||
printf("%p FrameManager::CantRenderReplacedElement called\n", this);
|
||||
#endif
|
||||
@@ -1033,10 +1057,10 @@ DumpContext(nsIFrame* aFrame, nsIStyleContext* aContext)
|
||||
frameDebug->GetFrameName(name);
|
||||
fputs(name, stdout);
|
||||
}
|
||||
fprintf(stdout, " (%p)", aFrame);
|
||||
fprintf(stdout, " (%p)", NS_STATIC_CAST(void*, aFrame));
|
||||
}
|
||||
if (aContext) {
|
||||
fprintf(stdout, " style: %p ", aContext);
|
||||
fprintf(stdout, " style: %p ", NS_STATIC_CAST(void*, aContext));
|
||||
|
||||
nsIAtom* pseudoTag;
|
||||
aContext->GetPseudoType(pseudoTag);
|
||||
@@ -1209,6 +1233,7 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext*
|
||||
NS_IMETHODIMP
|
||||
FrameManager::DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (aFrame) {
|
||||
nsIStyleContext* context;
|
||||
aFrame->GetStyleContext(&context);
|
||||
@@ -1328,6 +1353,7 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext*
|
||||
NS_IMETHODIMP
|
||||
FrameManager::DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
if (aFrame) {
|
||||
nsIStyleContext* context;
|
||||
aFrame->GetStyleContext(&context);
|
||||
@@ -1346,6 +1372,7 @@ FrameManager::ReParentStyleContext(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIStyleContext* aNewParentContext)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
nsresult result = NS_ERROR_NULL_POINTER;
|
||||
if (aFrame) {
|
||||
#ifdef NS_DEBUG
|
||||
@@ -1955,6 +1982,7 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext,
|
||||
PRInt32 aMinChange,
|
||||
PRInt32& aTopLevelChange)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
aTopLevelChange = NS_STYLE_HINT_NONE;
|
||||
nsIFrame* frame = aFrame;
|
||||
|
||||
@@ -1986,6 +2014,7 @@ FrameManager::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
@@ -2007,6 +2036,7 @@ NS_IMETHODIMP
|
||||
FrameManager::CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
|
||||
|
||||
// See if the frame is stateful.
|
||||
@@ -2051,6 +2081,7 @@ NS_IMETHODIMP
|
||||
FrameManager::CaptureFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
|
||||
|
||||
rv = CaptureFrameStateFor(aPresContext, aFrame, aState);
|
||||
@@ -2079,6 +2110,7 @@ NS_IMETHODIMP
|
||||
FrameManager::RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
|
||||
|
||||
// See if the frame is stateful.
|
||||
@@ -2122,6 +2154,7 @@ NS_IMETHODIMP
|
||||
FrameManager::RestoreFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
|
||||
|
||||
rv = RestoreFrameStateFor(aPresContext, aFrame, aState);
|
||||
@@ -2287,6 +2320,7 @@ FrameManager::GetFrameProperty(nsIFrame* aFrame,
|
||||
PRUint32 aOptions,
|
||||
void** aPropertyValue)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
nsresult result;
|
||||
@@ -2308,6 +2342,7 @@ FrameManager::SetFrameProperty(nsIFrame* aFrame,
|
||||
void* aPropertyValue,
|
||||
NSFMPropertyDtorFunc aPropDtorFunc)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
nsresult result = NS_OK;
|
||||
@@ -2348,6 +2383,7 @@ NS_IMETHODIMP
|
||||
FrameManager::RemoveFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG_POINTER(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
nsresult result = NS_IFRAME_MGR_PROP_NOT_THERE;
|
||||
@@ -2367,6 +2403,7 @@ FrameManager::RemoveFrameProperty(nsIFrame* aFrame,
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFrame* aChild, nsIFrame** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
*aResult = nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
|
||||
@@ -1339,7 +1339,10 @@ PresShell::~PresShell()
|
||||
}
|
||||
|
||||
// Destroy the frame manager. This will destroy the frame hierarchy
|
||||
NS_IF_RELEASE(mFrameManager);
|
||||
if (mFrameManager) {
|
||||
mFrameManager->Destroy();
|
||||
NS_RELEASE(mFrameManager);
|
||||
}
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->DeleteShell(this);
|
||||
|
||||
Reference in New Issue
Block a user