Bug 586408 document.popup node doesn't work with nested popups (regression from bug 383930) r=Enn a=beltzner

This commit is contained in:
Neil Rashbrook 2010-09-10 21:24:25 +01:00
Родитель 76109c40cc
Коммит fbf64ada43
5 изменённых файлов: 48 добавлений и 29 удалений

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

@ -504,6 +504,28 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, P
}
}
nsIContent*
nsMenuPopupFrame::GetTriggerContent(nsMenuPopupFrame* aMenuPopupFrame)
{
while (aMenuPopupFrame) {
if (aMenuPopupFrame->mTriggerContent)
return aMenuPopupFrame->mTriggerContent;
// check up the menu hierarchy until a popup with a trigger node is found
nsMenuFrame* menuFrame = aMenuPopupFrame->GetParentMenu();
if (!menuFrame)
break;
nsMenuParent* parentPopup = menuFrame->GetMenuParent();
if (!parentPopup || !parentPopup->IsMenu())
break;
aMenuPopupFrame = static_cast<nsMenuPopupFrame *>(parentPopup);
}
return nsnull;
}
void
nsMenuPopupFrame::InitPositionFromAnchorAlign(const nsAString& aAnchor,
const nsAString& aAlign)

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

@ -235,8 +235,8 @@ public:
return nsnull;
}
nsIContent* GetTriggerContent() { return mTriggerContent; }
void SetTriggerContent(nsIContent* aTriggerContent) { mTriggerContent = aTriggerContent; }
static nsIContent* GetTriggerContent(nsMenuPopupFrame* aMenuPopupFrame);
void ClearTriggerContent() { mTriggerContent = nsnull; }
// returns true if the popup is in a content shell, or false for a popup in
// a chrome shell

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

@ -268,25 +268,9 @@ nsPopupBoxObject::GetTriggerNode(nsIDOMNode** aTriggerNode)
{
*aTriggerNode = nsnull;
nsMenuPopupFrame *menuPopupFrame = GetMenuPopupFrame();
while (menuPopupFrame) {
nsIContent* triggerContent = menuPopupFrame->GetTriggerContent();
if (triggerContent) {
CallQueryInterface(triggerContent, aTriggerNode);
break;
}
// check up the menu hierarchy until a popup with a trigger node is found
nsMenuFrame* menuFrame = menuPopupFrame->GetParentMenu();
if (!menuFrame)
break;
nsMenuParent* parentPopup = menuFrame->GetMenuParent();
if (!parentPopup || !parentPopup->IsMenu())
break;
menuPopupFrame = static_cast<nsMenuPopupFrame *>(parentPopup);
}
nsIContent* triggerContent = nsMenuPopupFrame::GetTriggerContent(GetMenuPopupFrame());
if (triggerContent)
CallQueryInterface(triggerContent, aTriggerNode);
return NS_OK;
}

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

@ -1179,7 +1179,7 @@ nsXULPopupManager::FirePopupShowingEvent(nsIContent* aPopup,
// to closed and clear its trigger content.
if (status == nsEventStatus_eConsumeNoDefault) {
popupFrame->SetPopupState(ePopupClosed);
popupFrame->SetTriggerContent(nsnull);
popupFrame->ClearTriggerContent();
}
else {
ShowPopupCallback(aPopup, popupFrame, aIsContextMenu, aSelectFirstItem);
@ -1341,9 +1341,7 @@ nsXULPopupManager::GetLastTriggerNode(nsIDocument* aDocument, PRBool aIsTooltip)
// the list of open popups.
if (mOpeningPopup && mOpeningPopup->GetCurrentDoc() == aDocument &&
aIsTooltip == (mOpeningPopup->Tag() == nsGkAtoms::tooltip)) {
nsMenuPopupFrame* popupFrame = GetPopupFrameForContent(mOpeningPopup, PR_FALSE);
if (popupFrame)
node = do_QueryInterface(popupFrame->GetTriggerContent());
node = do_QueryInterface(nsMenuPopupFrame::GetTriggerContent(GetPopupFrameForContent(mOpeningPopup, PR_FALSE)));
}
else {
nsMenuChainItem* item = aIsTooltip ? mNoHidePanels : mPopups;
@ -1351,8 +1349,9 @@ nsXULPopupManager::GetLastTriggerNode(nsIDocument* aDocument, PRBool aIsTooltip)
// look for a popup of the same type and document.
if ((item->PopupType() == ePopupTypeTooltip) == aIsTooltip &&
item->Content()->GetCurrentDoc() == aDocument) {
node = do_QueryInterface(item->Frame()->GetTriggerContent());
break;
node = do_QueryInterface(nsMenuPopupFrame::GetTriggerContent(item->Frame()));
if (node)
break;
}
item = item->GetParent();
}

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

@ -42,7 +42,10 @@ var popupTests = [
testname: "open outer popup",
events: [ "popupshowing outermain", "popupshown outermain" ],
test: function () synthesizeMouse($("popuparea"), 4, 4, {}),
result: function (testname) is($("outermain").triggerNode, $("popuparea"), testname)
result: function (testname) {
is($("outermain").triggerNode, $("popuparea"), testname);
is(document.popupNode, $("popuparea"), testname + " document.popupNode");
}
},
{
testname: "open inner popup",
@ -55,6 +58,7 @@ var popupTests = [
is($("outermain").triggerNode, $("popuparea"), testname + " outer");
is($("innermain").triggerNode, $("popuparea"), testname + " inner");
is($("outercontext").triggerNode, null, testname + " outer context");
is(document.popupNode, $("popuparea"), testname + " document.popupNode");
}
},
{
@ -66,6 +70,7 @@ var popupTests = [
is($("outermain").triggerNode, $("popuparea"), testname + " outer");
is($("innermain").triggerNode, $("popuparea"), testname + " inner");
is($("outercontext").triggerNode, $("innermenu"), testname + " outer context");
is(document.popupNode, $("innermenu"), testname + " document.popupNode");
}
},
{
@ -81,6 +86,7 @@ var popupTests = [
is($("innermain").triggerNode, $("popuparea"), testname + " inner");
is($("outercontext").triggerNode, $("innermenu"), testname + " outer context");
is($("innercontext").triggerNode, $("innermenu"), testname + " inner context");
is(document.popupNode, $("innermenu"), testname + " document.popupNode");
}
},
{
@ -91,7 +97,14 @@ var popupTests = [
"DOMMenuInactive innercontext",
"DOMMenuItemInactive outercontextmenu", "DOMMenuItemInactive outercontextmenu",
"DOMMenuInactive outercontext" ],
test: function () $("outercontext").hidePopup()
test: function () $("outercontext").hidePopup(),
result: function (testname) {
is($("outermain").triggerNode, $("popuparea"), testname + " outer");
is($("innermain").triggerNode, $("popuparea"), testname + " inner");
is($("outercontext").triggerNode, null, testname + " outer context");
is($("innercontext").triggerNode, null, testname + " inner context");
is(document.popupNode, $("popuparea"), testname + " document.popupNode");
}
},
{
testname: "hide menus",
@ -107,6 +120,7 @@ var popupTests = [
is($("innermain").triggerNode, null, testname + " inner");
is($("outercontext").triggerNode, null, testname + " outer context");
is($("innercontext").triggerNode, null, testname + " inner context");
is(document.popupNode, null, testname + " document.popupNode");
}
}
];