Bug 1824986 - Use element more in popup manager code. r=mstange

We know these are elements, take advantage of that.

Depends on D173836

Differential Revision: https://phabricator.services.mozilla.com/D173837
This commit is contained in:
Emilio Cobos Álvarez 2023-03-28 14:33:19 +00:00
parent 28e6c8dbfe
commit 7fd5088695
7 changed files with 119 additions and 120 deletions

View file

@ -1710,7 +1710,7 @@ void nsMenuPopupFrame::PerformMove(const Rects& aRects) {
mUsedScreenRect = aRects.mUsedRect; mUsedScreenRect = aRects.mUsedRect;
if (!HasAnyStateBits(NS_FRAME_FIRST_REFLOW) && !mPendingPositionedEvent) { if (!HasAnyStateBits(NS_FRAME_FIRST_REFLOW) && !mPendingPositionedEvent) {
mPendingPositionedEvent = mPendingPositionedEvent =
nsXULPopupPositionedEvent::DispatchIfNeeded(mContent); nsXULPopupPositionedEvent::DispatchIfNeeded(mContent->AsElement());
} }
} }
@ -2411,7 +2411,7 @@ void nsMenuPopupFrame::CheckForAnchorChange(nsRect& aRect) {
if (pm) { if (pm) {
// As the caller will be iterating over the open popups, hide // As the caller will be iterating over the open popups, hide
// asyncronously. // asyncronously.
pm->HidePopup(mContent, pm->HidePopup(mContent->AsElement(),
{HidePopupOption::DeselectMenu, HidePopupOption::Async}); {HidePopupOption::DeselectMenu, HidePopupOption::Async});
} }

View file

@ -106,7 +106,7 @@ const nsNavigationDirection DirectionFromKeyCodeTable[2][6] = {
nsXULPopupManager* nsXULPopupManager::sInstance = nullptr; nsXULPopupManager* nsXULPopupManager::sInstance = nullptr;
PendingPopup::PendingPopup(nsIContent* aPopup, mozilla::dom::Event* aEvent) PendingPopup::PendingPopup(Element* aPopup, mozilla::dom::Event* aEvent)
: mPopup(aPopup), mEvent(aEvent), mModifiers(0) { : mPopup(aPopup), mEvent(aEvent), mModifiers(0) {
InitMousePoint(); InitMousePoint();
} }
@ -189,7 +189,7 @@ uint16_t PendingPopup::MouseInputSource() const {
return MouseEvent_Binding::MOZ_SOURCE_UNKNOWN; return MouseEvent_Binding::MOZ_SOURCE_UNKNOWN;
} }
nsIContent* nsMenuChainItem::Content() { return mFrame->GetContent(); } XULPopupElement* nsMenuChainItem::Element() { return &mFrame->PopupElement(); }
void nsMenuChainItem::SetParent(UniquePtr<nsMenuChainItem> aParent) { void nsMenuChainItem::SetParent(UniquePtr<nsMenuChainItem> aParent) {
MOZ_ASSERT_IF(aParent, !aParent->mChild); MOZ_ASSERT_IF(aParent, !aParent->mChild);
@ -343,7 +343,7 @@ bool nsXULPopupManager::RollupInternal(RollupKind aKind,
first = parent; first = parent;
} }
*aLastRolledUp = first->Content(); *aLastRolledUp = first->Element();
} }
ConsumeOutsideClicksResult consumeResult = ConsumeOutsideClicksResult consumeResult =
@ -434,7 +434,7 @@ bool nsXULPopupManager::RollupInternal(RollupKind aKind,
// If a number of popups to close has been specified, determine the last // If a number of popups to close has been specified, determine the last
// popup to close. // popup to close.
nsIContent* lastPopup = nullptr; Element* lastPopup = nullptr;
uint32_t count = aOptions.mCount; uint32_t count = aOptions.mCount;
if (count && count != UINT32_MAX) { if (count && count != UINT32_MAX) {
nsMenuChainItem* last = item; nsMenuChainItem* last = item;
@ -442,7 +442,7 @@ bool nsXULPopupManager::RollupInternal(RollupKind aKind,
last = last->GetParent(); last = last->GetParent();
} }
if (last) { if (last) {
lastPopup = last->Content(); lastPopup = last->Element();
} }
} }
@ -457,7 +457,7 @@ bool nsXULPopupManager::RollupInternal(RollupKind aKind,
options += HidePopupOption::DisableAnimations; options += HidePopupOption::DisableAnimations;
} }
HidePopup(item->Content(), options, lastPopup); HidePopup(item->Element(), options, lastPopup);
if (aOptions.mFlush == FlushViews::Yes) { if (aOptions.mFlush == FlushViews::Yes) {
// The popup's visibility doesn't update until the minimize animation // The popup's visibility doesn't update until the minimize animation
@ -806,12 +806,11 @@ void nsXULPopupManager::ShowMenu(nsIContent* aMenu, bool aSelectFirstItem) {
// there is no trigger event for menus // there is no trigger event for menus
popupFrame->InitializePopup(aMenu, nullptr, position, 0, 0, popupFrame->InitializePopup(aMenu, nullptr, position, 0, 0,
MenuPopupAnchorType_Node, true); MenuPopupAnchorType_Node, true);
PendingPopup pendingPopup(popupFrame->GetContent(), nullptr); PendingPopup pendingPopup(&popupFrame->PopupElement(), nullptr);
BeginShowingPopup(pendingPopup, parentIsContextMenu, aSelectFirstItem); BeginShowingPopup(pendingPopup, parentIsContextMenu, aSelectFirstItem);
} }
void nsXULPopupManager::ShowPopup(nsIContent* aPopup, void nsXULPopupManager::ShowPopup(Element* aPopup, nsIContent* aAnchorContent,
nsIContent* aAnchorContent,
const nsAString& aPosition, int32_t aXPos, const nsAString& aPosition, int32_t aXPos,
int32_t aYPos, bool aIsContextMenu, int32_t aYPos, bool aIsContextMenu,
bool aAttributesOverride, bool aAttributesOverride,
@ -839,7 +838,7 @@ static bool ShouldUseNativeContextMenus() {
#endif #endif
} }
void nsXULPopupManager::ShowPopupAtScreen(nsIContent* aPopup, int32_t aXPos, void nsXULPopupManager::ShowPopupAtScreen(Element* aPopup, int32_t aXPos,
int32_t aYPos, bool aIsContextMenu, int32_t aYPos, bool aIsContextMenu,
Event* aTriggerEvent) { Event* aTriggerEvent) {
if (aIsContextMenu && ShouldUseNativeContextMenus() && if (aIsContextMenu && ShouldUseNativeContextMenus() &&
@ -859,7 +858,7 @@ void nsXULPopupManager::ShowPopupAtScreen(nsIContent* aPopup, int32_t aXPos,
BeginShowingPopup(pendingPopup, aIsContextMenu, false); BeginShowingPopup(pendingPopup, aIsContextMenu, false);
} }
bool nsXULPopupManager::ShowPopupAsNativeMenu(nsIContent* aPopup, int32_t aXPos, bool nsXULPopupManager::ShowPopupAsNativeMenu(Element* aPopup, int32_t aXPos,
int32_t aYPos, int32_t aYPos,
bool aIsContextMenu, bool aIsContextMenu,
Event* aTriggerEvent) { Event* aTriggerEvent) {
@ -873,10 +872,7 @@ bool nsXULPopupManager::ShowPopupAsNativeMenu(nsIContent* aPopup, int32_t aXPos,
RefPtr<NativeMenu> menu; RefPtr<NativeMenu> menu;
#ifdef HAS_NATIVE_MENU_SUPPORT #ifdef HAS_NATIVE_MENU_SUPPORT
if (aPopup->IsElement()) { menu = mozilla::widget::NativeMenuSupport::CreateNativeContextMenu(aPopup);
menu = mozilla::widget::NativeMenuSupport::CreateNativeContextMenu(
aPopup->AsElement());
}
#endif #endif
if (!menu) { if (!menu) {
@ -890,8 +886,7 @@ bool nsXULPopupManager::ShowPopupAsNativeMenu(nsIContent* aPopup, int32_t aXPos,
// Hide the menu from our accessibility code so that we don't dispatch custom // Hide the menu from our accessibility code so that we don't dispatch custom
// accessibility notifications which would conflict with the system ones. // accessibility notifications which would conflict with the system ones.
aPopup->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_hidden, aPopup->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_hidden, u"true"_ns, true);
u"true"_ns, true);
PendingPopup pendingPopup(aPopup, aTriggerEvent); PendingPopup pendingPopup(aPopup, aTriggerEvent);
nsCOMPtr<nsIContent> triggerContent = pendingPopup.GetTriggerContent(); nsCOMPtr<nsIContent> triggerContent = pendingPopup.GetTriggerContent();
@ -904,7 +899,7 @@ bool nsXULPopupManager::ShowPopupAsNativeMenu(nsIContent* aPopup, int32_t aXPos,
// if the event was cancelled, don't open the popup, reset its state back // if the event was cancelled, don't open the popup, reset its state back
// to closed and clear its trigger content. // to closed and clear its trigger content.
if (status == nsEventStatus_eConsumeNoDefault) { if (status == nsEventStatus_eConsumeNoDefault) {
if (nsMenuPopupFrame* popupFrame = GetPopupFrameForContent(aPopup, true)) { if ((popupFrame = GetPopupFrameForContent(aPopup, true))) {
popupFrame->SetPopupState(ePopupClosed); popupFrame->SetPopupState(ePopupClosed);
popupFrame->ClearTriggerContent(); popupFrame->ClearTriggerContent();
} }
@ -979,7 +974,7 @@ void nsXULPopupManager::OnNativeMenuClosed() {
// menus. // menus.
// Close the non-native menus now. This matches the HidePopup call in // Close the non-native menus now. This matches the HidePopup call in
// nsXULMenuCommandEvent::Run. // nsXULMenuCommandEvent::Run.
HidePopup(mPopups->Content(), {HidePopupOption::HideChain}); HidePopup(mPopups->Element(), {HidePopupOption::HideChain});
} }
} }
@ -1016,7 +1011,7 @@ void nsXULPopupManager::OnNativeMenuWillActivateItem(
} }
void nsXULPopupManager::ShowPopupAtScreenRect( void nsXULPopupManager::ShowPopupAtScreenRect(
nsIContent* aPopup, const nsAString& aPosition, const nsIntRect& aRect, Element* aPopup, const nsAString& aPosition, const nsIntRect& aRect,
bool aIsContextMenu, bool aAttributesOverride, Event* aTriggerEvent) { bool aIsContextMenu, bool aAttributesOverride, Event* aTriggerEvent) {
nsMenuPopupFrame* popupFrame = GetPopupFrameForContent(aPopup, true); nsMenuPopupFrame* popupFrame = GetPopupFrameForContent(aPopup, true);
if (!popupFrame || !MayShowPopup(popupFrame)) return; if (!popupFrame || !MayShowPopup(popupFrame)) return;
@ -1031,7 +1026,7 @@ void nsXULPopupManager::ShowPopupAtScreenRect(
} }
void nsXULPopupManager::ShowTooltipAtScreen( void nsXULPopupManager::ShowTooltipAtScreen(
nsIContent* aPopup, nsIContent* aTriggerContent, Element* aPopup, nsIContent* aTriggerContent,
const LayoutDeviceIntPoint& aScreenPoint) { const LayoutDeviceIntPoint& aScreenPoint) {
nsMenuPopupFrame* popupFrame = GetPopupFrameForContent(aPopup, true); nsMenuPopupFrame* popupFrame = GetPopupFrameForContent(aPopup, true);
if (!popupFrame || !MayShowPopup(popupFrame)) { if (!popupFrame || !MayShowPopup(popupFrame)) {
@ -1085,7 +1080,7 @@ static void CheckCaretDrawingState() {
} }
} }
void nsXULPopupManager::ShowPopupCallback(nsIContent* aPopup, void nsXULPopupManager::ShowPopupCallback(Element* aPopup,
nsMenuPopupFrame* aPopupFrame, nsMenuPopupFrame* aPopupFrame,
bool aIsContextMenu, bool aIsContextMenu,
bool aSelectFirstItem) { bool aSelectFirstItem) {
@ -1107,10 +1102,7 @@ void nsXULPopupManager::ShowPopupCallback(nsIContent* aPopup,
// attribute may be used to disable adding these event listeners for popups // attribute may be used to disable adding these event listeners for popups
// that want to handle their own keyboard events. // that want to handle their own keyboard events.
nsAutoString ignorekeys; nsAutoString ignorekeys;
if (aPopup->IsElement()) { aPopup->GetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys, ignorekeys);
aPopup->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys,
ignorekeys);
}
if (ignorekeys.EqualsLiteral("true")) { if (ignorekeys.EqualsLiteral("true")) {
item->SetIgnoreKeys(eIgnoreKeys_True); item->SetIgnoreKeys(eIgnoreKeys_True);
} else if (ignorekeys.EqualsLiteral("shortcuts")) { } else if (ignorekeys.EqualsLiteral("shortcuts")) {
@ -1137,7 +1129,7 @@ void nsXULPopupManager::ShowPopupCallback(nsIContent* aPopup,
// listener will handle closing the tooltip also. // listener will handle closing the tooltip also.
nsIContent* oldmenu = nullptr; nsIContent* oldmenu = nullptr;
if (mPopups) { if (mPopups) {
oldmenu = mPopups->Content(); oldmenu = mPopups->Element();
} }
item->SetParent(std::move(mPopups)); item->SetParent(std::move(mPopups));
mPopups = std::move(item); mPopups = std::move(item);
@ -1156,7 +1148,7 @@ void nsXULPopupManager::ShowPopupCallback(nsIContent* aPopup,
CheckCaretDrawingState(); CheckCaretDrawingState();
} }
nsMenuChainItem* nsXULPopupManager::FindPopup(nsIContent* aPopup) const { nsMenuChainItem* nsXULPopupManager::FindPopup(Element* aPopup) const {
for (nsMenuChainItem* item = mPopups.get(); item; item = item->GetParent()) { for (nsMenuChainItem* item = mPopups.get(); item; item = item->GetParent()) {
if (item->Frame()->GetContent() == aPopup) { if (item->Frame()->GetContent() == aPopup) {
return item; return item;
@ -1165,8 +1157,8 @@ nsMenuChainItem* nsXULPopupManager::FindPopup(nsIContent* aPopup) const {
return nullptr; return nullptr;
} }
void nsXULPopupManager::HidePopup(nsIContent* aPopup, HidePopupOptions aOptions, void nsXULPopupManager::HidePopup(Element* aPopup, HidePopupOptions aOptions,
nsIContent* aLastPopup) { Element* aLastPopup) {
if (mNativeMenu && mNativeMenu->Element() == aPopup) { if (mNativeMenu && mNativeMenu->Element() == aPopup) {
RefPtr<NativeMenu> menu = mNativeMenu; RefPtr<NativeMenu> menu = mNativeMenu;
(void)menu->Close(); (void)menu->Close();
@ -1180,7 +1172,7 @@ void nsXULPopupManager::HidePopup(nsIContent* aPopup, HidePopupOptions aOptions,
nsMenuChainItem* foundPopup = FindPopup(aPopup); nsMenuChainItem* foundPopup = FindPopup(aPopup);
nsCOMPtr<nsIContent> popupToHide, nextPopup, lastPopup; RefPtr<Element> popupToHide, nextPopup, lastPopup;
if (foundPopup) { if (foundPopup) {
if (foundPopup->IsNoAutoHide()) { if (foundPopup->IsNoAutoHide()) {
@ -1218,7 +1210,7 @@ void nsXULPopupManager::HidePopup(nsIContent* aPopup, HidePopupOptions aOptions,
} }
} }
popupToHide = topMenu->Content(); popupToHide = topMenu->Element();
popupFrame = topMenu->Frame(); popupFrame = topMenu->Frame();
const bool hideChain = aOptions.contains(HidePopupOption::HideChain); const bool hideChain = aOptions.contains(HidePopupOption::HideChain);
@ -1232,7 +1224,7 @@ void nsXULPopupManager::HidePopup(nsIContent* aPopup, HidePopupOptions aOptions,
} }
if (parent) { if (parent) {
nextPopup = parent->Content(); nextPopup = parent->Element();
} }
} }
@ -1297,7 +1289,7 @@ void nsXULPopupManager::HideMenu(nsIContent* aMenu) {
class TransitionEnder final : public nsIDOMEventListener { class TransitionEnder final : public nsIDOMEventListener {
private: private:
// Effectively const but is cycle collected // Effectively const but is cycle collected
MOZ_KNOWN_LIVE RefPtr<nsIContent> mContent; MOZ_KNOWN_LIVE RefPtr<Element> mElement;
protected: protected:
virtual ~TransitionEnder() = default; virtual ~TransitionEnder() = default;
@ -1308,13 +1300,13 @@ class TransitionEnder final : public nsIDOMEventListener {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(TransitionEnder) NS_DECL_CYCLE_COLLECTION_CLASS(TransitionEnder)
TransitionEnder(nsIContent* aContent, HidePopupOptions aOptions) TransitionEnder(Element* aElement, HidePopupOptions aOptions)
: mContent(aContent), mOptions(aOptions) {} : mElement(aElement), mOptions(aOptions) {}
MOZ_CAN_RUN_SCRIPT NS_IMETHOD HandleEvent(Event* aEvent) override { MOZ_CAN_RUN_SCRIPT NS_IMETHOD HandleEvent(Event* aEvent) override {
mContent->RemoveSystemEventListener(u"transitionend"_ns, this, false); mElement->RemoveSystemEventListener(u"transitionend"_ns, this, false);
nsMenuPopupFrame* popupFrame = do_QueryFrame(mContent->GetPrimaryFrame()); nsMenuPopupFrame* popupFrame = do_QueryFrame(mElement->GetPrimaryFrame());
if (!popupFrame) { if (!popupFrame) {
return NS_OK; return NS_OK;
} }
@ -1323,7 +1315,7 @@ class TransitionEnder final : public nsIDOMEventListener {
// we'll assume they all end at the same time and just hide the popup upon // we'll assume they all end at the same time and just hide the popup upon
// the first one ending. // the first one ending.
if (RefPtr<nsXULPopupManager> pm = nsXULPopupManager::GetInstance()) { if (RefPtr<nsXULPopupManager> pm = nsXULPopupManager::GetInstance()) {
pm->HidePopupCallback(mContent, popupFrame, nullptr, nullptr, pm->HidePopupCallback(mElement, popupFrame, nullptr, nullptr,
popupFrame->GetPopupType(), mOptions); popupFrame->GetPopupType(), mOptions);
} }
@ -1338,10 +1330,10 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TransitionEnder)
NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(TransitionEnder, mContent); NS_IMPL_CYCLE_COLLECTION(TransitionEnder, mElement);
void nsXULPopupManager::HidePopupCallback( void nsXULPopupManager::HidePopupCallback(
nsIContent* aPopup, nsMenuPopupFrame* aPopupFrame, nsIContent* aNextPopup, Element* aPopup, nsMenuPopupFrame* aPopupFrame, Element* aNextPopup,
nsIContent* aLastPopup, PopupType aPopupType, HidePopupOptions aOptions) { Element* aLastPopup, PopupType aPopupType, HidePopupOptions aOptions) {
if (mCloseTimer && mTimerMenu == aPopupFrame) { if (mCloseTimer && mTimerMenu == aPopupFrame) {
mCloseTimer->Cancel(); mCloseTimer->Cancel();
mCloseTimer = nullptr; mCloseTimer = nullptr;
@ -1354,7 +1346,7 @@ void nsXULPopupManager::HidePopupCallback(
// or removed a popup frame during the event processing so the item isn't at // or removed a popup frame during the event processing so the item isn't at
// the front anymore. // the front anymore.
for (nsMenuChainItem* item = mPopups.get(); item; item = item->GetParent()) { for (nsMenuChainItem* item = mPopups.get(); item; item = item->GetParent()) {
if (item->Content() == aPopup) { if (item->Element() == aPopup) {
RemoveMenuChainItem(item); RemoveMenuChainItem(item);
SetCaptureState(aPopup); SetCaptureState(aPopup);
break; break;
@ -1388,11 +1380,11 @@ void nsXULPopupManager::HidePopupCallback(
// last check is needed so that a menulist inside a non-menu panel only // last check is needed so that a menulist inside a non-menu panel only
// closes the menu and not the panel as well. // closes the menu and not the panel as well.
if (foundMenu && (aLastPopup || aPopupType == foundMenu->GetPopupType())) { if (foundMenu && (aLastPopup || aPopupType == foundMenu->GetPopupType())) {
nsCOMPtr<nsIContent> popupToHide = foundMenu->Content(); nsCOMPtr<Element> popupToHide = foundMenu->Element();
nsMenuChainItem* parent = foundMenu->GetParent(); nsMenuChainItem* parent = foundMenu->GetParent();
nsCOMPtr<nsIContent> nextPopup; nsCOMPtr<Element> nextPopup;
if (parent && popupToHide != aLastPopup) nextPopup = parent->Content(); if (parent && popupToHide != aLastPopup) nextPopup = parent->Element();
nsMenuPopupFrame* popupFrame = foundMenu->Frame(); nsMenuPopupFrame* popupFrame = foundMenu->Frame();
nsPopupState state = popupFrame->PopupState(); nsPopupState state = popupFrame->PopupState();
@ -1474,7 +1466,7 @@ void nsXULPopupManager::HidePopupsInDocShell(
// Get the parent before calling detach so that we can keep iterating. // Get the parent before calling detach so that we can keep iterating.
nsMenuChainItem* parent = item->GetParent(); nsMenuChainItem* parent = item->GetParent();
if (item->Frame()->PopupState() != ePopupInvisible && if (item->Frame()->PopupState() != ePopupInvisible &&
IsChildOfDocShell(item->Content()->OwnerDoc(), aDocShellToHide)) { IsChildOfDocShell(item->Element()->OwnerDoc(), aDocShellToHide)) {
nsMenuPopupFrame* frame = item->Frame(); nsMenuPopupFrame* frame = item->Frame();
RemoveMenuChainItem(item); RemoveMenuChainItem(item);
popupsToHide.AppendElement(frame); popupsToHide.AppendElement(frame);
@ -1588,7 +1580,7 @@ nsEventStatus nsXULPopupManager::FirePopupShowingEvent(
void nsXULPopupManager::BeginShowingPopup(const PendingPopup& aPendingPopup, void nsXULPopupManager::BeginShowingPopup(const PendingPopup& aPendingPopup,
bool aIsContextMenu, bool aIsContextMenu,
bool aSelectFirstItem) { bool aSelectFirstItem) {
RefPtr<nsIContent> popup = aPendingPopup.mPopup; RefPtr<Element> popup = aPendingPopup.mPopup;
nsMenuPopupFrame* popupFrame = do_QueryFrame(popup->GetPrimaryFrame()); nsMenuPopupFrame* popupFrame = do_QueryFrame(popup->GetPrimaryFrame());
if (NS_WARN_IF(!popupFrame)) { if (NS_WARN_IF(!popupFrame)) {
@ -1609,9 +1601,8 @@ void nsXULPopupManager::BeginShowingPopup(const PendingPopup& aPendingPopup,
// Using noautofocus="true" will disable this behaviour, which is needed for // Using noautofocus="true" will disable this behaviour, which is needed for
// the autocomplete widget as it manages focus itself. // the autocomplete widget as it manages focus itself.
if (popupType == PopupType::Panel && if (popupType == PopupType::Panel &&
!popup->AsElement()->AttrValueIs(kNameSpaceID_None, !popup->AttrValueIs(kNameSpaceID_None, nsGkAtoms::noautofocus,
nsGkAtoms::noautofocus, nsGkAtoms::_true, nsGkAtoms::_true, eCaseMatters)) {
eCaseMatters)) {
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) { if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
Document* doc = popup->GetUncomposedDoc(); Document* doc = popup->GetUncomposedDoc();
@ -1648,8 +1639,8 @@ void nsXULPopupManager::BeginShowingPopup(const PendingPopup& aPendingPopup,
// Now check if we need to fire the popuppositioned event. If not, call // Now check if we need to fire the popuppositioned event. If not, call
// ShowPopupCallback directly. // ShowPopupCallback directly.
// The popuppositioned event only fires on arrow panels for now. // The popuppositioned event only fires on arrow panels for now.
if (popup->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, if (popup->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, nsGkAtoms::arrow,
nsGkAtoms::arrow, eCaseMatters)) { eCaseMatters)) {
popupFrame->ShowWithPositionedEvent(); popupFrame->ShowWithPositionedEvent();
presShell->FrameNeedsReflow(popupFrame, IntrinsicDirty::FrameAndAncestors, presShell->FrameNeedsReflow(popupFrame, IntrinsicDirty::FrameAndAncestors,
NS_FRAME_HAS_DIRTY_CHILDREN); NS_FRAME_HAS_DIRTY_CHILDREN);
@ -1658,9 +1649,9 @@ void nsXULPopupManager::BeginShowingPopup(const PendingPopup& aPendingPopup,
} }
} }
void nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup, void nsXULPopupManager::FirePopupHidingEvent(Element* aPopup,
nsIContent* aNextPopup, Element* aNextPopup,
nsIContent* aLastPopup, Element* aLastPopup,
nsPresContext* aPresContext, nsPresContext* aPresContext,
PopupType aPopupType, PopupType aPopupType,
HidePopupOptions aOptions) { HidePopupOptions aOptions) {
@ -1676,9 +1667,8 @@ void nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
// when a panel is closed, blur whatever has focus inside the popup // when a panel is closed, blur whatever has focus inside the popup
if (aPopupType == PopupType::Panel && if (aPopupType == PopupType::Panel &&
(!aPopup->IsElement() || !aPopup->AsElement()->AttrValueIs( (!aPopup->AttrValueIs(kNameSpaceID_None, nsGkAtoms::noautofocus,
kNameSpaceID_None, nsGkAtoms::noautofocus, nsGkAtoms::_true, eCaseMatters))) {
nsGkAtoms::_true, eCaseMatters))) {
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) { if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
Document* doc = aPopup->GetUncomposedDoc(); Document* doc = aPopup->GetUncomposedDoc();
@ -1729,8 +1719,7 @@ void nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
return false; return false;
} }
nsAutoString animate; nsAutoString animate;
if (!aPopup->IsElement() || if (!aPopup->GetAttr(nsGkAtoms::animate, animate)) {
!aPopup->AsElement()->GetAttr(nsGkAtoms::animate, animate)) {
return false; return false;
} }
// If animate="false" then don't transition at all. // If animate="false" then don't transition at all.
@ -1750,7 +1739,7 @@ void nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
// The transition would still occur either way, but if we don't wait the // The transition would still occur either way, but if we don't wait the
// view will be hidden and you won't be able to see it. // view will be hidden and you won't be able to see it.
if (shouldAnimate && AnimationUtils::HasCurrentTransitions( if (shouldAnimate && AnimationUtils::HasCurrentTransitions(
aPopup->AsElement(), PseudoStyleType::NotPseudo)) { aPopup, PseudoStyleType::NotPseudo)) {
RefPtr<TransitionEnder> ender = new TransitionEnder(aPopup, aOptions); RefPtr<TransitionEnder> ender = new TransitionEnder(aPopup, aOptions);
aPopup->AddSystemEventListener(u"transitionend"_ns, ender, false, false); aPopup->AddSystemEventListener(u"transitionend"_ns, ender, false, false);
return; return;
@ -1760,7 +1749,7 @@ void nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
aOptions); aOptions);
} }
bool nsXULPopupManager::IsPopupOpen(nsIContent* aPopup) { bool nsXULPopupManager::IsPopupOpen(Element* aPopup) {
if (mNativeMenu && mNativeMenu->Element() == aPopup) { if (mNativeMenu && mNativeMenu->Element() == aPopup) {
return true; return true;
} }
@ -1838,7 +1827,7 @@ already_AddRefed<nsINode> nsXULPopupManager::GetLastTriggerNode(
item = item->GetParent()) { item = item->GetParent()) {
// look for a popup of the same type and document. // look for a popup of the same type and document.
if ((item->GetPopupType() == PopupType::Tooltip) == aIsTooltip && if ((item->GetPopupType() == PopupType::Tooltip) == aIsTooltip &&
item->Content()->GetUncomposedDoc() == aDocument) { item->Element()->GetUncomposedDoc() == aDocument) {
node = nsMenuPopupFrame::GetTriggerContent(item->Frame()); node = nsMenuPopupFrame::GetTriggerContent(item->Frame());
if (node) { if (node) {
break; break;
@ -1853,14 +1842,14 @@ already_AddRefed<nsINode> nsXULPopupManager::GetLastTriggerNode(
bool nsXULPopupManager::MayShowPopup(nsMenuPopupFrame* aPopup) { bool nsXULPopupManager::MayShowPopup(nsMenuPopupFrame* aPopup) {
// if a popup's IsOpen method returns true, then the popup must always be in // if a popup's IsOpen method returns true, then the popup must always be in
// the popup chain scanned in IsPopupOpen. // the popup chain scanned in IsPopupOpen.
NS_ASSERTION(!aPopup->IsOpen() || IsPopupOpen(aPopup->GetContent()), NS_ASSERTION(!aPopup->IsOpen() || IsPopupOpen(&aPopup->PopupElement()),
"popup frame state doesn't match XULPopupManager open state"); "popup frame state doesn't match XULPopupManager open state");
nsPopupState state = aPopup->PopupState(); nsPopupState state = aPopup->PopupState();
// if the popup is not in the open popup chain, then it must have a state that // if the popup is not in the open popup chain, then it must have a state that
// is either closed, in the process of being shown, or invisible. // is either closed, in the process of being shown, or invisible.
NS_ASSERTION(IsPopupOpen(aPopup->GetContent()) || state == ePopupClosed || NS_ASSERTION(IsPopupOpen(&aPopup->PopupElement()) || state == ePopupClosed ||
state == ePopupShowing || state == ePopupPositioning || state == ePopupShowing || state == ePopupPositioning ||
state == ePopupInvisible, state == ePopupInvisible,
"popup not in XULPopupManager open list is open"); "popup not in XULPopupManager open list is open");
@ -1869,7 +1858,7 @@ bool nsXULPopupManager::MayShowPopup(nsMenuPopupFrame* aPopup) {
if (state != ePopupClosed && state != ePopupInvisible) return false; if (state != ePopupClosed && state != ePopupInvisible) return false;
// Don't show popups that we already have in our popup chain // Don't show popups that we already have in our popup chain
if (IsPopupOpen(aPopup->GetContent())) { if (IsPopupOpen(&aPopup->PopupElement())) {
NS_WARNING("Refusing to show duplicate popup"); NS_WARNING("Refusing to show duplicate popup");
return false; return false;
} }
@ -1956,7 +1945,7 @@ void nsXULPopupManager::PopupDestroyed(nsMenuPopupFrame* aPopup) {
// when a popup frame is destroyed, just unhook it from the list of popups // when a popup frame is destroyed, just unhook it from the list of popups
CancelMenuTimer(aPopup); CancelMenuTimer(aPopup);
nsMenuChainItem* item = FindPopup(aPopup->GetContent()); nsMenuChainItem* item = FindPopup(&aPopup->PopupElement());
if (!item) { if (!item) {
return; return;
} }
@ -1979,7 +1968,7 @@ void nsXULPopupManager::PopupDestroyed(nsMenuPopupFrame* aPopup) {
} else { } else {
// HidePopup will take care of hiding any of its children, so // HidePopup will take care of hiding any of its children, so
// break out afterwards // break out afterwards
HidePopup(child->Content(), {HidePopupOption::Async}); HidePopup(child->Element(), {HidePopupOption::Async});
break; break;
} }
} }
@ -2001,7 +1990,7 @@ bool nsXULPopupManager::HasContextMenu(nsMenuPopupFrame* aPopup) {
void nsXULPopupManager::SetCaptureState(nsIContent* aOldPopup) { void nsXULPopupManager::SetCaptureState(nsIContent* aOldPopup) {
nsMenuChainItem* item = GetTopVisibleMenu(); nsMenuChainItem* item = GetTopVisibleMenu();
if (item && aOldPopup == item->Content()) return; if (item && aOldPopup == item->Element()) return;
if (mWidget) { if (mWidget) {
mWidget->CaptureRollupEvents(false); mWidget->CaptureRollupEvents(false);
@ -2024,7 +2013,7 @@ void nsXULPopupManager::UpdateKeyboardListeners() {
bool isForMenu = false; bool isForMenu = false;
if (nsMenuChainItem* item = GetTopVisibleMenu()) { if (nsMenuChainItem* item = GetTopVisibleMenu()) {
if (item->IgnoreKeys() != eIgnoreKeys_True) { if (item->IgnoreKeys() != eIgnoreKeys_True) {
newTarget = item->Content()->GetComposedDoc(); newTarget = item->Element()->GetComposedDoc();
} }
isForMenu = item->GetPopupType() == PopupType::Menu; isForMenu = item->GetPopupType() == PopupType::Menu;
} else if (mActiveMenuBar && mActiveMenuBar->IsActiveByKeyboard()) { } else if (mActiveMenuBar && mActiveMenuBar->IsActiveByKeyboard()) {
@ -2054,7 +2043,7 @@ void nsXULPopupManager::UpdateKeyboardListeners() {
} }
} }
void nsXULPopupManager::UpdateMenuItems(nsIContent* aPopup) { void nsXULPopupManager::UpdateMenuItems(Element* aPopup) {
// Walk all of the menu's children, checking to see if any of them has a // Walk all of the menu's children, checking to see if any of them has a
// command attribute. If so, then several attributes must potentially be // command attribute. If so, then several attributes must potentially be
// updated. // updated.
@ -2182,7 +2171,7 @@ void nsXULPopupManager::KillMenuTimer() {
mCloseTimer = nullptr; mCloseTimer = nullptr;
if (mTimerMenu->IsOpen()) { if (mTimerMenu->IsOpen()) {
HidePopup(mTimerMenu->GetContent(), {HidePopupOption::Async}); HidePopup(&mTimerMenu->PopupElement(), {HidePopupOption::Async});
} }
} }
@ -2251,7 +2240,7 @@ bool nsXULPopupManager::HandleShortcutNavigation(KeyboardEvent& aKeyEvent,
bool nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) { bool nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) {
if (nsMenuChainItem* nextitem = GetTopVisibleMenu()) { if (nsMenuChainItem* nextitem = GetTopVisibleMenu()) {
nextitem->Content()->OwnerDoc()->FlushPendingNotifications( nextitem->Element()->OwnerDoc()->FlushPendingNotifications(
FlushType::Frames); FlushType::Frames);
} }
@ -2423,7 +2412,7 @@ bool nsXULPopupManager::HandleKeyboardNavigationInPopup(
// close a submenu when Left is pressed // close a submenu when Left is pressed
if (nsMenuPopupFrame* popupFrame = if (nsMenuPopupFrame* popupFrame =
currentItem->GetMenuPopup(FlushType::None)) { currentItem->GetMenuPopup(FlushType::None)) {
HidePopup(popupFrame->GetContent(), {}); HidePopup(&popupFrame->PopupElement(), {});
} }
return true; return true;
} }
@ -2439,7 +2428,7 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode(
if (aTopVisibleMenuItem && if (aTopVisibleMenuItem &&
aTopVisibleMenuItem->GetPopupType() != PopupType::Menu) { aTopVisibleMenuItem->GetPopupType() != PopupType::Menu) {
if (keyCode == KeyboardEvent_Binding::DOM_VK_ESCAPE) { if (keyCode == KeyboardEvent_Binding::DOM_VK_ESCAPE) {
HidePopup(aTopVisibleMenuItem->Content(), {HidePopupOption::IsRollup}); HidePopup(aTopVisibleMenuItem->Element(), {HidePopupOption::IsRollup});
aKeyEvent->StopPropagation(); aKeyEvent->StopPropagation();
aKeyEvent->StopCrossProcessForwarding(); aKeyEvent->StopCrossProcessForwarding();
aKeyEvent->PreventDefault(); aKeyEvent->PreventDefault();
@ -2482,7 +2471,7 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode(
// though in this latter case, a menu didn't actually close, the effect // though in this latter case, a menu didn't actually close, the effect
// ends up being the same. Similar for the tab key below. // ends up being the same. Similar for the tab key below.
if (aTopVisibleMenuItem) { if (aTopVisibleMenuItem) {
HidePopup(aTopVisibleMenuItem->Content(), {HidePopupOption::IsRollup}); HidePopup(aTopVisibleMenuItem->Element(), {HidePopupOption::IsRollup});
} else if (mActiveMenuBar) { } else if (mActiveMenuBar) {
RefPtr menubar = mActiveMenuBar; RefPtr menubar = mActiveMenuBar;
menubar->SetActive(false); menubar->SetActive(false);
@ -2705,9 +2694,9 @@ nsXULPopupHidingEvent::Run() {
Document* document = mPopup->GetUncomposedDoc(); Document* document = mPopup->GetUncomposedDoc();
if (pm && document) { if (pm && document) {
if (RefPtr<nsPresContext> presContext = document->GetPresContext()) { if (RefPtr<nsPresContext> presContext = document->GetPresContext()) {
nsCOMPtr<nsIContent> popup = mPopup; nsCOMPtr<Element> popup = mPopup;
nsCOMPtr<nsIContent> nextPopup = mNextPopup; nsCOMPtr<Element> nextPopup = mNextPopup;
nsCOMPtr<nsIContent> lastPopup = mLastPopup; nsCOMPtr<Element> lastPopup = mLastPopup;
pm->FirePopupHidingEvent(popup, nextPopup, lastPopup, presContext, pm->FirePopupHidingEvent(popup, nextPopup, lastPopup, presContext,
mPopupType, mOptions); mPopupType, mOptions);
} }
@ -2715,11 +2704,10 @@ nsXULPopupHidingEvent::Run() {
return NS_OK; return NS_OK;
} }
bool nsXULPopupPositionedEvent::DispatchIfNeeded(nsIContent* aPopup) { bool nsXULPopupPositionedEvent::DispatchIfNeeded(Element* aPopup) {
// The popuppositioned event only fires on arrow panels for now. // The popuppositioned event only fires on arrow panels for now.
if (aPopup->IsElement() && if (aPopup->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, nsGkAtoms::arrow,
aPopup->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, eCaseMatters)) {
nsGkAtoms::arrow, eCaseMatters)) {
nsCOMPtr<nsIRunnable> event = new nsXULPopupPositionedEvent(aPopup); nsCOMPtr<nsIRunnable> event = new nsXULPopupPositionedEvent(aPopup);
aPopup->OwnerDoc()->Dispatch(TaskCategory::Other, event.forget()); aPopup->OwnerDoc()->Dispatch(TaskCategory::Other, event.forget());
return true; return true;

View file

@ -64,6 +64,7 @@ class KeyboardEvent;
class UIEvent; class UIEvent;
class XULButtonElement; class XULButtonElement;
class XULMenuBarElement; class XULMenuBarElement;
class XULPopupElement;
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla
@ -189,10 +190,13 @@ extern const nsNavigationDirection DirectionFromKeyCodeTable[2][6];
// Used to hold information about a popup that is about to be opened. // Used to hold information about a popup that is about to be opened.
struct PendingPopup { struct PendingPopup {
PendingPopup(nsIContent* aPopup, mozilla::dom::Event* aEvent); using Element = mozilla::dom::Element;
using Event = mozilla::dom::Event;
const RefPtr<nsIContent> mPopup; PendingPopup(Element* aPopup, Event* aEvent);
const RefPtr<mozilla::dom::Event> mEvent;
const RefPtr<Element> mPopup;
const RefPtr<Event> mEvent;
// Device pixels relative to the showing popup's presshell's // Device pixels relative to the showing popup's presshell's
// root prescontext's root frame. // root prescontext's root frame.
@ -252,7 +256,7 @@ class nsMenuChainItem {
MOZ_COUNTED_DTOR(nsMenuChainItem) MOZ_COUNTED_DTOR(nsMenuChainItem)
nsIContent* Content(); mozilla::dom::XULPopupElement* Element();
nsMenuPopupFrame* Frame() { return mFrame; } nsMenuPopupFrame* Frame() { return mFrame; }
PopupType GetPopupType() { return mPopupType; } PopupType GetPopupType() { return mPopupType; }
bool IsNoAutoHide() { return mNoAutoHide; } bool IsNoAutoHide() { return mNoAutoHide; }
@ -279,10 +283,11 @@ class nsMenuChainItem {
// this class is used for dispatching popuphiding events asynchronously. // this class is used for dispatching popuphiding events asynchronously.
class nsXULPopupHidingEvent : public mozilla::Runnable { class nsXULPopupHidingEvent : public mozilla::Runnable {
using PopupType = mozilla::widget::PopupType; using PopupType = mozilla::widget::PopupType;
using Element = mozilla::dom::Element;
public: public:
nsXULPopupHidingEvent(nsIContent* aPopup, nsIContent* aNextPopup, nsXULPopupHidingEvent(Element* aPopup, Element* aNextPopup,
nsIContent* aLastPopup, PopupType aPopupType, Element* aLastPopup, PopupType aPopupType,
HidePopupOptions aOptions) HidePopupOptions aOptions)
: mozilla::Runnable("nsXULPopupHidingEvent"), : mozilla::Runnable("nsXULPopupHidingEvent"),
mPopup(aPopup), mPopup(aPopup),
@ -298,17 +303,19 @@ class nsXULPopupHidingEvent : public mozilla::Runnable {
NS_IMETHOD Run() override; NS_IMETHOD Run() override;
private: private:
nsCOMPtr<nsIContent> mPopup; nsCOMPtr<Element> mPopup;
nsCOMPtr<nsIContent> mNextPopup; nsCOMPtr<Element> mNextPopup;
nsCOMPtr<nsIContent> mLastPopup; nsCOMPtr<Element> mLastPopup;
PopupType mPopupType; PopupType mPopupType;
HidePopupOptions mOptions; HidePopupOptions mOptions;
}; };
// this class is used for dispatching popuppositioned events asynchronously. // this class is used for dispatching popuppositioned events asynchronously.
class nsXULPopupPositionedEvent : public mozilla::Runnable { class nsXULPopupPositionedEvent : public mozilla::Runnable {
using Element = mozilla::dom::Element;
public: public:
explicit nsXULPopupPositionedEvent(nsIContent* aPopup) explicit nsXULPopupPositionedEvent(Element* aPopup)
: mozilla::Runnable("nsXULPopupPositionedEvent"), mPopup(aPopup) { : mozilla::Runnable("nsXULPopupPositionedEvent"), mPopup(aPopup) {
MOZ_ASSERT(aPopup); MOZ_ASSERT(aPopup);
} }
@ -317,16 +324,18 @@ class nsXULPopupPositionedEvent : public mozilla::Runnable {
// Asynchronously dispatch a popuppositioned event at aPopup if this is a // Asynchronously dispatch a popuppositioned event at aPopup if this is a
// panel that should receieve such events. Return true if the event was sent. // panel that should receieve such events. Return true if the event was sent.
static bool DispatchIfNeeded(nsIContent* aPopup); static bool DispatchIfNeeded(Element* aPopup);
private: private:
const nsCOMPtr<nsIContent> mPopup; const nsCOMPtr<Element> mPopup;
}; };
// this class is used for dispatching menu command events asynchronously. // this class is used for dispatching menu command events asynchronously.
class nsXULMenuCommandEvent : public mozilla::Runnable { class nsXULMenuCommandEvent : public mozilla::Runnable {
using Element = mozilla::dom::Element;
public: public:
nsXULMenuCommandEvent(mozilla::dom::Element* aMenu, bool aIsTrusted, nsXULMenuCommandEvent(Element* aMenu, bool aIsTrusted,
mozilla::Modifiers aModifiers, bool aUserInput, mozilla::Modifiers aModifiers, bool aUserInput,
bool aFlipChecked, int16_t aButton) bool aFlipChecked, int16_t aButton)
: mozilla::Runnable("nsXULMenuCommandEvent"), : mozilla::Runnable("nsXULMenuCommandEvent"),
@ -348,7 +357,7 @@ class nsXULMenuCommandEvent : public mozilla::Runnable {
} }
private: private:
RefPtr<mozilla::dom::Element> mMenu; RefPtr<Element> mMenu;
mozilla::Modifiers mModifiers; mozilla::Modifiers mModifiers;
int16_t mButton; int16_t mButton;
@ -369,6 +378,7 @@ class nsXULPopupManager final : public nsIDOMEventListener,
friend class TransitionEnder; friend class TransitionEnder;
using PopupType = mozilla::widget::PopupType; using PopupType = mozilla::widget::PopupType;
using Element = mozilla::dom::Element;
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER NS_DECL_NSIOBSERVER
@ -457,7 +467,7 @@ class nsXULPopupManager final : public nsIDOMEventListener,
* *
* This fires the popupshowing event synchronously. * This fires the popupshowing event synchronously.
*/ */
void ShowPopup(nsIContent* aPopup, nsIContent* aAnchorContent, void ShowPopup(Element* aPopup, nsIContent* aAnchorContent,
const nsAString& aPosition, int32_t aXPos, int32_t aYPos, const nsAString& aPosition, int32_t aXPos, int32_t aYPos,
bool aIsContextMenu, bool aAttributesOverride, bool aIsContextMenu, bool aAttributesOverride,
bool aSelectFirstItem, mozilla::dom::Event* aTriggerEvent); bool aSelectFirstItem, mozilla::dom::Event* aTriggerEvent);
@ -472,14 +482,14 @@ class nsXULPopupManager final : public nsIDOMEventListener,
* offset from aXPos/aYPos to ensure that it is not under the mouse * offset from aXPos/aYPos to ensure that it is not under the mouse
* cursor. * cursor.
*/ */
void ShowPopupAtScreen(nsIContent* aPopup, int32_t aXPos, int32_t aYPos, void ShowPopupAtScreen(Element* aPopup, int32_t aXPos, int32_t aYPos,
bool aIsContextMenu, bool aIsContextMenu,
mozilla::dom::Event* aTriggerEvent); mozilla::dom::Event* aTriggerEvent);
/* Open a popup anchored at a screen rectangle specified by aRect. /* Open a popup anchored at a screen rectangle specified by aRect.
* The remaining arguments are similar to ShowPopup. * The remaining arguments are similar to ShowPopup.
*/ */
void ShowPopupAtScreenRect(nsIContent* aPopup, const nsAString& aPosition, void ShowPopupAtScreenRect(Element* aPopup, const nsAString& aPosition,
const nsIntRect& aRect, bool aIsContextMenu, const nsIntRect& aRect, bool aIsContextMenu,
bool aAttributesOverride, bool aAttributesOverride,
mozilla::dom::Event* aTriggerEvent); mozilla::dom::Event* aTriggerEvent);
@ -494,14 +504,14 @@ class nsXULPopupManager final : public nsIDOMEventListener,
* TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230) * TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
*/ */
MOZ_CAN_RUN_SCRIPT_BOUNDARY bool ShowPopupAsNativeMenu( MOZ_CAN_RUN_SCRIPT_BOUNDARY bool ShowPopupAsNativeMenu(
nsIContent* aPopup, int32_t aXPos, int32_t aYPos, bool aIsContextMenu, Element* aPopup, int32_t aXPos, int32_t aYPos, bool aIsContextMenu,
mozilla::dom::Event* aTriggerEvent); mozilla::dom::Event* aTriggerEvent);
/** /**
* Open a tooltip at a specific screen position specified by aXPos and aYPos, * Open a tooltip at a specific screen position specified by aXPos and aYPos,
* measured in device pixels. This fires the popupshowing event synchronously. * measured in device pixels. This fires the popupshowing event synchronously.
*/ */
void ShowTooltipAtScreen(nsIContent* aPopup, nsIContent* aTriggerContent, void ShowTooltipAtScreen(Element* aPopup, nsIContent* aTriggerContent,
const mozilla::LayoutDeviceIntPoint&); const mozilla::LayoutDeviceIntPoint&);
/* /*
@ -510,8 +520,8 @@ class nsXULPopupManager final : public nsIDOMEventListener,
* aLastPopup - optional popup to close last when hiding a chain of menus. * aLastPopup - optional popup to close last when hiding a chain of menus.
* If null, then all popups will be closed. * If null, then all popups will be closed.
*/ */
void HidePopup(nsIContent* aPopup, HidePopupOptions, void HidePopup(Element* aPopup, HidePopupOptions,
nsIContent* aLastPopup = nullptr); Element* aLastPopup = nullptr);
/* /*
* Hide the popup of a <menu>. * Hide the popup of a <menu>.
@ -566,7 +576,7 @@ class nsXULPopupManager final : public nsIDOMEventListener,
/** /**
* Return true if the popup for the supplied content node is open. * Return true if the popup for the supplied content node is open.
*/ */
bool IsPopupOpen(nsIContent* aPopup); bool IsPopupOpen(Element* aPopup);
/** /**
* Return the frame for the topmost open popup of a given type, or null if * Return the frame for the topmost open popup of a given type, or null if
@ -642,7 +652,7 @@ class nsXULPopupManager final : public nsIDOMEventListener,
* changes attributes on the children of aPopup, and deals only with the * changes attributes on the children of aPopup, and deals only with the
* content of the popup, not the frames. * content of the popup, not the frames.
*/ */
void UpdateMenuItems(nsIContent* aPopup); void UpdateMenuItems(Element* aPopup);
/** /**
* Stop the timer which hides a popup after a delay, started by a previous * Stop the timer which hides a popup after a delay, started by a previous
@ -737,13 +747,13 @@ class nsXULPopupManager final : public nsIDOMEventListener,
MOZ_CAN_RUN_SCRIPT void HideOpenMenusBeforeExecutingMenu(CloseMenuMode aMode); MOZ_CAN_RUN_SCRIPT void HideOpenMenusBeforeExecutingMenu(CloseMenuMode aMode);
// callbacks for ShowPopup and HidePopup as events may be done asynchronously // callbacks for ShowPopup and HidePopup as events may be done asynchronously
MOZ_CAN_RUN_SCRIPT void ShowPopupCallback(nsIContent* aPopup, MOZ_CAN_RUN_SCRIPT void ShowPopupCallback(Element* aPopup,
nsMenuPopupFrame* aPopupFrame, nsMenuPopupFrame* aPopupFrame,
bool aIsContextMenu, bool aIsContextMenu,
bool aSelectFirstItem); bool aSelectFirstItem);
MOZ_CAN_RUN_SCRIPT void HidePopupCallback( MOZ_CAN_RUN_SCRIPT void HidePopupCallback(
nsIContent* aPopup, nsMenuPopupFrame* aPopupFrame, nsIContent* aNextPopup, Element* aPopup, nsMenuPopupFrame* aPopupFrame, Element* aNextPopup,
nsIContent* aLastPopup, PopupType aPopupType, HidePopupOptions); Element* aLastPopup, PopupType aPopupType, HidePopupOptions);
/** /**
* Trigger frame construction and reflow in the popup, fire a popupshowing * Trigger frame construction and reflow in the popup, fire a popupshowing
@ -779,8 +789,8 @@ class nsXULPopupManager final : public nsIDOMEventListener,
* at. * at.
*/ */
MOZ_CAN_RUN_SCRIPT_BOUNDARY MOZ_CAN_RUN_SCRIPT_BOUNDARY
void FirePopupHidingEvent(nsIContent* aPopup, nsIContent* aNextPopup, void FirePopupHidingEvent(Element* aPopup, Element* aNextPopup,
nsIContent* aLastPopup, nsPresContext* aPresContext, Element* aLastPopup, nsPresContext* aPresContext,
PopupType aPopupType, HidePopupOptions aOptions); PopupType aPopupType, HidePopupOptions aOptions);
/** /**
@ -843,7 +853,7 @@ class nsXULPopupManager final : public nsIDOMEventListener,
nsIDocShellTreeItem* aExpected); nsIDocShellTreeItem* aExpected);
// Finds a chain item in mPopups. // Finds a chain item in mPopups.
nsMenuChainItem* FindPopup(nsIContent* aPopup) const; nsMenuChainItem* FindPopup(Element* aPopup) const;
// the document the key event listener is attached to // the document the key event listener is attached to
nsCOMPtr<mozilla::dom::EventTarget> mKeyListener; nsCOMPtr<mozilla::dom::EventTarget> mKeyListener;

View file

@ -472,7 +472,7 @@ void nsXULTooltipListener::LaunchTooltip() {
} }
nsresult nsXULTooltipListener::HideTooltip() { nsresult nsXULTooltipListener::HideTooltip() {
if (nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip)) { if (nsCOMPtr<Element> currentTooltip = do_QueryReferent(mCurrentTooltip)) {
if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) { if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
pm->HidePopup(currentTooltip, {}); pm->HidePopup(currentTooltip, {});
} }

View file

@ -1051,7 +1051,8 @@ void nsView::DynamicToolbarOffsetChanged(ScreenIntCoord aOffset) {
bool nsView::RequestWindowClose(nsIWidget* aWidget) { bool nsView::RequestWindowClose(nsIWidget* aWidget) {
if (mFrame && IsPopupWidget(aWidget) && mFrame->IsMenuPopupFrame()) { if (mFrame && IsPopupWidget(aWidget) && mFrame->IsMenuPopupFrame()) {
if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) { if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
pm->HidePopup(mFrame->GetContent(), {HidePopupOption::DeselectMenu}); pm->HidePopup(mFrame->GetContent()->AsElement(),
{HidePopupOption::DeselectMenu});
return true; return true;
} }
} }
@ -1124,7 +1125,7 @@ void nsView::RequestRepaint() {
bool nsView::ShouldNotBeVisible() { bool nsView::ShouldNotBeVisible() {
if (mFrame && mFrame->IsMenuPopupFrame()) { if (mFrame && mFrame->IsMenuPopupFrame()) {
nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
return !pm || !pm->IsPopupOpen(mFrame->GetContent()); return !pm || !pm->IsPopupOpen(mFrame->GetContent()->AsElement());
} }
return false; return false;

View file

@ -854,7 +854,7 @@ nsresult nsBaseDragService::DrawDrag(nsINode* aDOMNode,
nsIFrame* frame = content->GetPrimaryFrame(); nsIFrame* frame = content->GetPrimaryFrame();
if (frame && frame->IsMenuPopupFrame()) { if (frame && frame->IsMenuPopupFrame()) {
mDragPopup = content; mDragPopup = content->AsElement();
} }
} }

View file

@ -191,7 +191,7 @@ class nsBaseDragService : public nsIDragService, public nsIDragSession {
// set if the image in mImage is a popup. If this case, the popup will be // set if the image in mImage is a popup. If this case, the popup will be
// opened and moved instead of using a drag image. // opened and moved instead of using a drag image.
nsCOMPtr<nsIContent> mDragPopup; nsCOMPtr<mozilla::dom::Element> mDragPopup;
// the screen position where drag gesture occurred, used for positioning the // the screen position where drag gesture occurred, used for positioning the
// drag image. // drag image.