mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 05:15:45 +00:00
backing out Bug 343457 too see if it caused btek tp regression
This commit is contained in:
parent
83c14b811f
commit
ce0745a535
@ -94,14 +94,12 @@ class nsIStyleSheet;
|
||||
class nsCSSFrameConstructor;
|
||||
class nsISelection;
|
||||
template<class E> class nsCOMArray;
|
||||
class nsWeakFrame;
|
||||
|
||||
typedef short SelectionType;
|
||||
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0x67880b18, 0xaf91, 0x431b, \
|
||||
{ 0x89, 0x69, 0xfa, 0xd9, 0x2b, 0x3c, 0x33, 0x32 } }
|
||||
|
||||
{ 0xa736d2fd, 0x0191, 0x42ea, \
|
||||
{ 0xb1, 0xb0, 0x80, 0x45, 0x1d, 0xfa, 0x03, 0x53 } }
|
||||
|
||||
// Constants uses for ScrollFrameIntoView() function
|
||||
#define NS_PRESSHELL_SCROLL_TOP 0
|
||||
@ -751,8 +749,6 @@ public:
|
||||
nscolor aBackgroundColor,
|
||||
nsIRenderingContext** aRenderedContext) = 0;
|
||||
|
||||
void AddWeakFrame(nsWeakFrame* aWeakFrame);
|
||||
void RemoveWeakFrame(nsWeakFrame* aWeakFrame);
|
||||
protected:
|
||||
// IMPORTANT: The ownership implicit in the following member variables
|
||||
// has been explicitly checked. If you add any members to this class,
|
||||
@ -783,10 +779,7 @@ protected:
|
||||
|
||||
// Set to true when the accessibility service is being used to mirror
|
||||
// the dom/layout trees
|
||||
PRPackedBool mIsAccessibilityActive;
|
||||
|
||||
// A list of weak frames. This is a pointer to the last item in the list.
|
||||
nsWeakFrame* mWeakFrames;
|
||||
PRPackedBool mIsAccessibilityActive;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1603,29 +1603,6 @@ nsIPresShell::GetVerifyReflowFlags()
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsIPresShell::AddWeakFrame(nsWeakFrame* aWeakFrame)
|
||||
{
|
||||
aWeakFrame->SetPreviousWeakFrame(mWeakFrames);
|
||||
mWeakFrames = aWeakFrame;
|
||||
}
|
||||
|
||||
void
|
||||
nsIPresShell::RemoveWeakFrame(nsWeakFrame* aWeakFrame)
|
||||
{
|
||||
if (mWeakFrames == aWeakFrame) {
|
||||
mWeakFrames = aWeakFrame->GetPreviousWeakFrame();
|
||||
return;
|
||||
}
|
||||
nsWeakFrame* nextWeak = mWeakFrames;
|
||||
while (nextWeak && nextWeak->GetPreviousWeakFrame() != aWeakFrame) {
|
||||
nextWeak = nextWeak->GetPreviousWeakFrame();
|
||||
}
|
||||
if (nextWeak) {
|
||||
nextWeak->SetPreviousWeakFrame(aWeakFrame->GetPreviousWeakFrame());
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
@ -1954,11 +1931,6 @@ PresShell::Destroy()
|
||||
mFrameConstructor->WillDestroyFrameTree();
|
||||
FrameManager()->Destroy();
|
||||
|
||||
NS_WARN_IF_FALSE(!mWeakFrames, "Weak frames alive after destroying FrameManager");
|
||||
while (mWeakFrames) {
|
||||
mWeakFrames->Clear(this);
|
||||
}
|
||||
|
||||
// Let the style set do its cleanup.
|
||||
mStyleSet->Shutdown(mPresContext);
|
||||
|
||||
@ -3200,16 +3172,6 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
|
||||
mPresContext->PropertyTable()->DeleteAllPropertiesFor(aFrame);
|
||||
}
|
||||
|
||||
nsWeakFrame* weakFrame = mWeakFrames;
|
||||
while (weakFrame) {
|
||||
nsWeakFrame* prev = weakFrame->GetPreviousWeakFrame();
|
||||
if (weakFrame->GetFrame() == aFrame) {
|
||||
// This removes weakFrame from mWeakFrames.
|
||||
weakFrame->Clear(this);
|
||||
}
|
||||
weakFrame = prev;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1690,64 +1690,6 @@ private:
|
||||
NS_IMETHOD_(nsrefcnt) Release(void) = 0;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* nsWeakFrame can be used to keep a reference to a nsIFrame in a safe way.
|
||||
* Whenever an nsIFrame object is deleted, the nsWeakFrames pointing
|
||||
* to it will be cleared.
|
||||
*
|
||||
* Create nsWeakFrame object when it is sure that nsIFrame object
|
||||
* is alive and after some operations which may destroy the nsIFrame
|
||||
* (for example any DOM modifications) use IsAlive() or GetFrame() methods to
|
||||
* check whether it is safe to continue to use the nsIFrame object.
|
||||
*
|
||||
* @note The usage of this class should be kept to a minimum.
|
||||
*/
|
||||
|
||||
class nsWeakFrame {
|
||||
public:
|
||||
nsWeakFrame(nsIFrame* aFrame)
|
||||
{
|
||||
mPrev = nsnull;
|
||||
mFrame = aFrame;
|
||||
if (mFrame) {
|
||||
nsIPresShell* shell = mFrame->GetPresContext()->GetPresShell();
|
||||
NS_WARN_IF_FALSE(shell, "Null PresShell in nsWeakFrame!");
|
||||
if (shell) {
|
||||
shell->AddWeakFrame(this);
|
||||
} else {
|
||||
mFrame = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Clear(nsIPresShell* aShell) {
|
||||
if (aShell) {
|
||||
aShell->RemoveWeakFrame(this);
|
||||
}
|
||||
mFrame = nsnull;
|
||||
mPrev = nsnull;
|
||||
}
|
||||
|
||||
PRBool IsAlive() { return !!mFrame; }
|
||||
|
||||
nsIFrame* GetFrame() { return mFrame; }
|
||||
|
||||
nsWeakFrame* GetPreviousWeakFrame() { return mPrev; }
|
||||
|
||||
void SetPreviousWeakFrame(nsWeakFrame* aPrev) { mPrev = aPrev; }
|
||||
|
||||
~nsWeakFrame()
|
||||
{
|
||||
Clear(mFrame ? mFrame->GetPresContext()->GetPresShell() : nsnull);
|
||||
}
|
||||
private:
|
||||
nsWeakFrame* mPrev;
|
||||
nsIFrame* mFrame;
|
||||
};
|
||||
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFrame, NS_IFRAME_IID)
|
||||
|
||||
#endif /* nsIFrame_h___ */
|
||||
|
@ -110,11 +110,8 @@ nsPopupBoxObject::HidePopup()
|
||||
nsIPopupSetFrame *popupSet = GetPopupSetFrame();
|
||||
nsIFrame *ourFrame = GetFrame(PR_FALSE);
|
||||
if (ourFrame && popupSet) {
|
||||
nsWeakFrame weakFrame(ourFrame);
|
||||
popupSet->HidePopup(ourFrame);
|
||||
if (weakFrame.IsAlive()) {
|
||||
popupSet->DestroyPopup(ourFrame, PR_TRUE);
|
||||
}
|
||||
popupSet->DestroyPopup(ourFrame, PR_TRUE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -321,9 +321,8 @@ nsPopupSetFrame::ShowPopup(nsIContent* aElementContent, nsIContent* aPopupConten
|
||||
const nsString& aPopupType, const nsString& anAnchorAlignment,
|
||||
const nsString& aPopupAlignment)
|
||||
{
|
||||
nsWeakFrame weakFrame(this);
|
||||
// First fire the popupshowing event.
|
||||
if (!OnCreate(aXPos, aYPos, aPopupContent) || !weakFrame.IsAlive())
|
||||
if (!OnCreate(aXPos, aYPos, aPopupContent))
|
||||
return NS_OK;
|
||||
|
||||
// See if we already have an entry in our list. We must create a new one on a miss.
|
||||
@ -349,7 +348,6 @@ nsPopupSetFrame::ShowPopup(nsIContent* aElementContent, nsIContent* aPopupConten
|
||||
entry->mPopupFrame = GetPresContext()->PresShell()
|
||||
->GetPrimaryFrameFor(aPopupContent);
|
||||
|
||||
nsWeakFrame weakPopupFrame(entry->mPopupFrame);
|
||||
#ifdef DEBUG_PINK
|
||||
printf("X Pos: %d\n", mXPos);
|
||||
printf("Y Pos: %d\n", mYPos);
|
||||
@ -358,26 +356,18 @@ nsPopupSetFrame::ShowPopup(nsIContent* aElementContent, nsIContent* aPopupConten
|
||||
// Generate the popup.
|
||||
entry->mCreateHandlerSucceeded = PR_TRUE;
|
||||
entry->mIsOpen = PR_TRUE;
|
||||
// This may destroy entry->mPopupFrame
|
||||
MarkAsGenerated(aPopupContent);
|
||||
|
||||
// determine if this menu is a context menu and flag it
|
||||
nsIFrame* activeChild = entry->mPopupFrame;
|
||||
nsIMenuParent* childPopup = nsnull;
|
||||
if (weakPopupFrame.IsAlive())
|
||||
CallQueryInterface(weakPopupFrame.GetFrame(), &childPopup);
|
||||
if (activeChild)
|
||||
CallQueryInterface(activeChild, &childPopup);
|
||||
if ( childPopup && aPopupType.EqualsLiteral("context") )
|
||||
childPopup->SetIsContextMenu(PR_TRUE);
|
||||
|
||||
if (!weakFrame.IsAlive()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Now open the popup.
|
||||
OpenPopup(entry, PR_TRUE);
|
||||
|
||||
if (!weakFrame.IsAlive()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Now fire the popupshown event.
|
||||
OnCreated(aXPos, aYPos, aPopupContent);
|
||||
@ -426,37 +416,34 @@ nsPopupSetFrame::DestroyPopup(nsIFrame* aPopup, PRBool aDestroyEntireChain)
|
||||
nsPopupFrameList* entry = mPopupList->GetEntryByFrame(aPopup);
|
||||
|
||||
if (entry && entry->mCreateHandlerSucceeded) { // ensure the popup was created before we try to destroy it
|
||||
nsWeakFrame weakFrame(this);
|
||||
OpenPopup(entry, PR_FALSE);
|
||||
nsCOMPtr<nsIContent> popupContent = entry->mPopupContent;
|
||||
if (weakFrame.IsAlive()) {
|
||||
entry->mPopupType.SetLength(0);
|
||||
|
||||
if (aDestroyEntireChain && entry->mElementContent && entry->mPopupType.EqualsLiteral("context")) {
|
||||
// If we are a context menu, and if we are attached to a
|
||||
// menupopup, then destroying us should also dismiss the parent
|
||||
// menu popup.
|
||||
if (entry->mElementContent->Tag() == nsXULAtoms::menupopup) {
|
||||
nsIFrame* popupFrame = GetPresContext()->PresShell()
|
||||
->GetPrimaryFrameFor(entry->mElementContent);
|
||||
if (popupFrame) {
|
||||
nsIMenuParent *menuParent;
|
||||
if (NS_SUCCEEDED(CallQueryInterface(popupFrame, &menuParent))) {
|
||||
menuParent->DismissChain();
|
||||
}
|
||||
entry->mPopupType.SetLength(0);
|
||||
|
||||
if (aDestroyEntireChain && entry->mElementContent && entry->mPopupType.EqualsLiteral("context")) {
|
||||
// If we are a context menu, and if we are attached to a
|
||||
// menupopup, then destroying us should also dismiss the parent
|
||||
// menu popup.
|
||||
if (entry->mElementContent->Tag() == nsXULAtoms::menupopup) {
|
||||
nsIFrame* popupFrame = GetPresContext()->PresShell()
|
||||
->GetPrimaryFrameFor(entry->mElementContent);
|
||||
if (popupFrame) {
|
||||
nsIMenuParent *menuParent;
|
||||
if (NS_SUCCEEDED(CallQueryInterface(popupFrame, &menuParent))) {
|
||||
menuParent->DismissChain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear things out for next time
|
||||
entry->mCreateHandlerSucceeded = PR_FALSE;
|
||||
entry->mElementContent = nsnull;
|
||||
entry->mXPos = entry->mYPos = 0;
|
||||
entry->mLastPref.width = -1;
|
||||
entry->mLastPref.height = -1;
|
||||
}
|
||||
|
||||
// clear things out for next time
|
||||
entry->mCreateHandlerSucceeded = PR_FALSE;
|
||||
entry->mElementContent = nsnull;
|
||||
entry->mXPos = entry->mYPos = 0;
|
||||
entry->mLastPref.width = -1;
|
||||
entry->mLastPref.height = -1;
|
||||
|
||||
// ungenerate the popup.
|
||||
popupContent->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menugenerated, PR_TRUE);
|
||||
entry->mPopupContent->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menugenerated, PR_TRUE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -478,26 +465,21 @@ nsPopupSetFrame::MarkAsGenerated(nsIContent* aPopupContent)
|
||||
void
|
||||
nsPopupSetFrame::OpenPopup(nsPopupFrameList* aEntry, PRBool aActivateFlag)
|
||||
{
|
||||
nsWeakFrame weakFrame(this);
|
||||
nsIFrame* activeChild = aEntry->mPopupFrame;
|
||||
nsWeakFrame weakPopupFrame(activeChild);
|
||||
nsCOMPtr<nsIContent> popupContent = aEntry->mPopupContent;
|
||||
PRBool createHandlerSucceeded = aEntry->mCreateHandlerSucceeded;
|
||||
nsAutoString popupType = aEntry->mPopupType;
|
||||
if (aActivateFlag) {
|
||||
ActivatePopup(aEntry, PR_TRUE);
|
||||
|
||||
// register the rollup listeners, etc, but not if we're a tooltip
|
||||
if (!popupType.EqualsLiteral("tooltip")) {
|
||||
if (!aEntry->mPopupType.EqualsLiteral("tooltip")) {
|
||||
nsIFrame* activeChild = aEntry->mPopupFrame;
|
||||
nsIMenuParent* childPopup = nsnull;
|
||||
if (weakPopupFrame.IsAlive())
|
||||
if (activeChild)
|
||||
CallQueryInterface(activeChild, &childPopup);
|
||||
|
||||
// Tooltips don't get keyboard navigation
|
||||
if (childPopup && !nsMenuDismissalListener::sInstance) {
|
||||
// First check and make sure this popup wants keyboard navigation
|
||||
if (!popupContent->AttrValueIs(kNameSpaceID_None, nsXULAtoms::ignorekeys,
|
||||
nsXULAtoms::_true, eCaseMatters))
|
||||
if (!aEntry->mPopupContent->AttrValueIs(kNameSpaceID_None, nsXULAtoms::ignorekeys,
|
||||
nsXULAtoms::_true, eCaseMatters))
|
||||
childPopup->InstallKeyboardNavigator();
|
||||
}
|
||||
|
||||
@ -507,32 +489,28 @@ nsPopupSetFrame::OpenPopup(nsPopupFrameList* aEntry, PRBool aActivateFlag)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (createHandlerSucceeded && !OnDestroy(aEntry->mPopupContent))
|
||||
if (aEntry->mCreateHandlerSucceeded && !OnDestroy(aEntry->mPopupContent))
|
||||
return;
|
||||
|
||||
// Unregister, but not if we're a tooltip
|
||||
if (!popupType.EqualsLiteral("tooltip") ) {
|
||||
if (!aEntry->mPopupType.EqualsLiteral("tooltip") ) {
|
||||
nsMenuDismissalListener::Shutdown();
|
||||
}
|
||||
|
||||
// Remove any keyboard navigators
|
||||
nsIMenuParent* childPopup = nsnull;
|
||||
if (weakPopupFrame.IsAlive())
|
||||
CallQueryInterface(activeChild, &childPopup);
|
||||
if (aEntry->mPopupFrame)
|
||||
CallQueryInterface(aEntry->mPopupFrame, &childPopup);
|
||||
if (childPopup)
|
||||
childPopup->RemoveKeyboardNavigator();
|
||||
|
||||
nsRefPtr<nsPresContext> presContext = GetPresContext();
|
||||
nsCOMPtr<nsIContent> content = aEntry->mPopupContent;
|
||||
ActivatePopup(aEntry, PR_FALSE);
|
||||
|
||||
OnDestroyed(presContext, content);
|
||||
OnDestroyed(aEntry->mPopupContent);
|
||||
}
|
||||
|
||||
if (weakFrame.IsAlive()) {
|
||||
nsBoxLayoutState state(GetPresContext());
|
||||
MarkDirtyChildren(state); // Mark ourselves dirty.
|
||||
}
|
||||
nsBoxLayoutState state(GetPresContext());
|
||||
MarkDirtyChildren(state); // Mark ourselves dirty.
|
||||
}
|
||||
|
||||
void
|
||||
@ -546,25 +524,23 @@ nsPopupSetFrame::ActivatePopup(nsPopupFrameList* aEntry, PRBool aActivateFlag)
|
||||
// XXXben hook in |width| and |height| usage here?
|
||||
aEntry->mPopupContent->SetAttr(kNameSpaceID_None, nsXULAtoms::menutobedisplayed, NS_LITERAL_STRING("true"), PR_TRUE);
|
||||
else {
|
||||
nsWeakFrame weakFrame(this);
|
||||
nsWeakFrame weakActiveChild(aEntry->mPopupFrame);
|
||||
nsCOMPtr<nsIContent> content = aEntry->mPopupContent;
|
||||
content->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
|
||||
content->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menutobedisplayed, PR_TRUE);
|
||||
aEntry->mPopupContent->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
|
||||
aEntry->mPopupContent->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menutobedisplayed, PR_TRUE);
|
||||
|
||||
// get rid of the reflows we just created. If we leave them hanging around, we
|
||||
// can get into trouble if a dialog with a modal event loop comes along and
|
||||
// processes the reflows before we get to call DestroyChain(). Processing the
|
||||
// reflow will cause the popup to show itself again. (bug 71219)
|
||||
nsIDocument* doc = content->GetDocument();
|
||||
nsIDocument* doc = aEntry->mPopupContent->GetDocument();
|
||||
if (doc)
|
||||
doc->FlushPendingNotifications(Flush_OnlyReflow);
|
||||
|
||||
|
||||
// make sure we hide the popup. We can't assume that we'll have a view
|
||||
// since we could be cleaning up after someone that didn't correctly
|
||||
// destroy the popup.
|
||||
if (weakFrame.IsAlive() && weakActiveChild.IsAlive()) {
|
||||
nsIView* view = weakActiveChild.GetFrame()->GetView();
|
||||
nsIFrame* activeChild = aEntry->mPopupFrame;
|
||||
if (activeChild) {
|
||||
nsIView* view = activeChild->GetView();
|
||||
NS_ASSERTION(view, "View is gone, looks like someone forgot to roll up the popup!");
|
||||
if (view) {
|
||||
nsIViewManager* viewManager = view->GetViewManager();
|
||||
@ -573,7 +549,7 @@ nsPopupSetFrame::ActivatePopup(nsPopupFrameList* aEntry, PRBool aActivateFlag)
|
||||
viewManager->ResizeView(view, r);
|
||||
if (aEntry->mIsOpen) {
|
||||
aEntry->mIsOpen = PR_FALSE;
|
||||
FireDOMEventSynch(NS_LITERAL_STRING("DOMMenuInactive"), content);
|
||||
FireDOMEventSynch(NS_LITERAL_STRING("DOMMenuInactive"), aEntry->mPopupContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -594,7 +570,6 @@ nsPopupSetFrame::OnCreate(PRInt32 aX, PRInt32 aY, nsIContent* aPopupContent)
|
||||
event.refPoint.y = aY;
|
||||
|
||||
if (aPopupContent) {
|
||||
nsCOMPtr<nsIContent> kungFuDeathGrip(aPopupContent);
|
||||
nsIPresShell *shell = GetPresContext()->GetPresShell();
|
||||
if (shell) {
|
||||
nsresult rv = shell->HandleDOMEventWithTarget(aPopupContent, &event,
|
||||
@ -697,15 +672,14 @@ nsPopupSetFrame::OnDestroy(nsIContent* aPopupContent)
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsPopupSetFrame::OnDestroyed(nsPresContext* aPresContext,
|
||||
nsIContent* aPopupContent)
|
||||
nsPopupSetFrame::OnDestroyed(nsIContent* aPopupContent)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event(PR_TRUE, NS_XUL_POPUP_HIDDEN, nsnull,
|
||||
nsMouseEvent::eReal);
|
||||
|
||||
if (aPopupContent && aPresContext) {
|
||||
nsIPresShell *shell = aPresContext->GetPresShell();
|
||||
if (aPopupContent) {
|
||||
nsIPresShell *shell = GetPresContext()->GetPresShell();
|
||||
if (shell) {
|
||||
nsresult rv = shell->HandleDOMEventWithTarget(aPopupContent, &event,
|
||||
&status);
|
||||
|
@ -117,8 +117,7 @@ public:
|
||||
PRBool OnCreate(PRInt32 aX, PRInt32 aY, nsIContent* aPopupContent);
|
||||
PRBool OnDestroy(nsIContent* aPopupContent);
|
||||
PRBool OnCreated(PRInt32 aX, PRInt32 aY, nsIContent* aPopupContent);
|
||||
static PRBool OnDestroyed(nsPresContext* aPresContext,
|
||||
nsIContent* aPopupContent);
|
||||
PRBool OnDestroyed(nsIContent* aPopupContent);
|
||||
|
||||
void ActivatePopup(nsPopupFrameList* aEntry, PRBool aActivateFlag);
|
||||
void OpenPopup(nsPopupFrameList* aEntry, PRBool aOpenFlag);
|
||||
|
Loading…
Reference in New Issue
Block a user