XULMenuElement.cpp (2501B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/XULMenuElement.h" 8 9 #include "mozilla/StaticAnalysisFunctions.h" 10 #include "mozilla/dom/KeyboardEvent.h" 11 #include "mozilla/dom/KeyboardEventBinding.h" 12 #include "mozilla/dom/XULButtonElement.h" 13 #include "mozilla/dom/XULMenuElementBinding.h" 14 #include "mozilla/dom/XULPopupElement.h" 15 #include "nsMenuPopupFrame.h" 16 #include "nsXULPopupManager.h" 17 18 namespace mozilla::dom { 19 20 JSObject* XULMenuElement::WrapNode(JSContext* aCx, 21 JS::Handle<JSObject*> aGivenProto) { 22 return XULMenuElement_Binding::Wrap(aCx, this, aGivenProto); 23 } 24 25 Element* XULMenuElement::GetActiveMenuChild() { 26 RefPtr popup = GetMenuPopupContent(); 27 return popup ? popup->GetActiveMenuChild() : nullptr; 28 } 29 30 void XULMenuElement::SetActiveMenuChild(Element* aChild) { 31 RefPtr popup = GetMenuPopupContent(); 32 if (NS_WARN_IF(!popup)) { 33 return; 34 } 35 36 if (!aChild) { 37 popup->SetActiveMenuChild(nullptr); 38 return; 39 } 40 auto* button = XULButtonElement::FromNode(aChild); 41 if (NS_WARN_IF(!button) || NS_WARN_IF(!button->IsMenu())) { 42 return; 43 } 44 // KnownLive because it's aChild. 45 popup->SetActiveMenuChild(MOZ_KnownLive(button)); 46 } 47 48 bool XULButtonElement::HandleKeyPress(KeyboardEvent& keyEvent) { 49 RefPtr<nsXULPopupManager> pm = nsXULPopupManager::GetInstance(); 50 if (!pm) { 51 return false; 52 } 53 54 // if event has already been handled, bail 55 if (keyEvent.DefaultPrevented()) { 56 return false; 57 } 58 59 if (keyEvent.IsMenuAccessKeyPressed()) { 60 return false; 61 } 62 63 nsMenuPopupFrame* popupFrame = GetMenuPopup(FlushType::Frames); 64 if (NS_WARN_IF(!popupFrame)) { 65 return false; 66 } 67 68 uint32_t keyCode = keyEvent.KeyCode(); 69 switch (keyCode) { 70 case KeyboardEvent_Binding::DOM_VK_UP: 71 case KeyboardEvent_Binding::DOM_VK_DOWN: 72 case KeyboardEvent_Binding::DOM_VK_HOME: 73 case KeyboardEvent_Binding::DOM_VK_END: { 74 nsNavigationDirection theDirection; 75 theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode); 76 return pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection); 77 } 78 default: 79 return pm->HandleShortcutNavigation(keyEvent, popupFrame); 80 } 81 } 82 83 } // namespace mozilla::dom