Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "mozilla/dom/MenuBoxObject.h"
7 : #include "mozilla/dom/MenuBoxObjectBinding.h"
8 :
9 : #include "mozilla/dom/KeyboardEvent.h"
10 : #include "mozilla/dom/Element.h"
11 : #include "nsIDOMKeyEvent.h"
12 : #include "nsIFrame.h"
13 : #include "nsMenuBarFrame.h"
14 : #include "nsMenuBarListener.h"
15 : #include "nsMenuFrame.h"
16 : #include "nsMenuPopupFrame.h"
17 :
18 : namespace mozilla {
19 : namespace dom {
20 :
21 1 : MenuBoxObject::MenuBoxObject()
22 : {
23 1 : }
24 :
25 0 : MenuBoxObject::~MenuBoxObject()
26 : {
27 0 : }
28 :
29 1 : JSObject* MenuBoxObject::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
30 : {
31 1 : return MenuBoxObjectBinding::Wrap(aCx, this, aGivenProto);
32 : }
33 :
34 0 : void MenuBoxObject::OpenMenu(bool aOpenFlag)
35 : {
36 0 : nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
37 0 : if (pm) {
38 0 : nsIFrame* frame = GetFrame(false);
39 0 : if (frame) {
40 0 : if (aOpenFlag) {
41 0 : nsCOMPtr<nsIContent> content = mContent;
42 0 : pm->ShowMenu(content, false, false);
43 : }
44 : else {
45 0 : nsMenuFrame* menu = do_QueryFrame(frame);
46 0 : if (menu) {
47 0 : nsMenuPopupFrame* popupFrame = menu->GetPopup();
48 0 : if (popupFrame)
49 0 : pm->HidePopup(popupFrame->GetContent(), false, true, false, false);
50 : }
51 : }
52 : }
53 : }
54 0 : }
55 :
56 : already_AddRefed<Element>
57 0 : MenuBoxObject::GetActiveChild()
58 : {
59 0 : nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
60 0 : if (menu) {
61 0 : nsCOMPtr<nsIDOMElement> el;
62 0 : menu->GetActiveChild(getter_AddRefs(el));
63 0 : nsCOMPtr<Element> ret(do_QueryInterface(el));
64 0 : return ret.forget();
65 : }
66 0 : return nullptr;
67 : }
68 :
69 0 : void MenuBoxObject::SetActiveChild(Element* arg)
70 : {
71 0 : nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
72 0 : if (menu) {
73 0 : nsCOMPtr<nsIDOMElement> el(do_QueryInterface(arg));
74 0 : menu->SetActiveChild(el);
75 : }
76 0 : }
77 :
78 0 : bool MenuBoxObject::HandleKeyPress(KeyboardEvent& keyEvent)
79 : {
80 0 : nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
81 0 : if (!pm) {
82 0 : return false;
83 : }
84 :
85 : // if event has already been handled, bail
86 0 : bool eventHandled = false;
87 0 : keyEvent.GetDefaultPrevented(&eventHandled);
88 0 : if (eventHandled) {
89 0 : return false;
90 : }
91 :
92 0 : if (nsMenuBarListener::IsAccessKeyPressed(&keyEvent))
93 0 : return false;
94 :
95 0 : nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
96 0 : if (!menu) {
97 0 : return false;
98 : }
99 :
100 0 : nsMenuPopupFrame* popupFrame = menu->GetPopup();
101 0 : if (!popupFrame) {
102 0 : return false;
103 : }
104 :
105 0 : uint32_t keyCode = keyEvent.KeyCode();
106 0 : switch (keyCode) {
107 : case nsIDOMKeyEvent::DOM_VK_UP:
108 : case nsIDOMKeyEvent::DOM_VK_DOWN:
109 : case nsIDOMKeyEvent::DOM_VK_HOME:
110 : case nsIDOMKeyEvent::DOM_VK_END:
111 : {
112 : nsNavigationDirection theDirection;
113 0 : theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode);
114 0 : return pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection);
115 : }
116 : default:
117 0 : return pm->HandleShortcutNavigation(&keyEvent, popupFrame);
118 : }
119 : }
120 :
121 0 : bool MenuBoxObject::OpenedWithKey()
122 : {
123 0 : nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false));
124 0 : if (!menuframe) {
125 0 : return false;
126 : }
127 :
128 0 : nsIFrame* frame = menuframe->GetParent();
129 0 : while (frame) {
130 0 : nsMenuBarFrame* menubar = do_QueryFrame(frame);
131 0 : if (menubar) {
132 0 : return menubar->IsActiveByKeyboard();
133 : }
134 0 : frame = frame->GetParent();
135 : }
136 0 : return false;
137 : }
138 :
139 : } // namespace dom
140 : } // namespace mozilla
141 :
142 : // Creation Routine ///////////////////////////////////////////////////////////////////////
143 :
144 : using namespace mozilla::dom;
145 :
146 : nsresult
147 0 : NS_NewMenuBoxObject(nsIBoxObject** aResult)
148 : {
149 0 : NS_ADDREF(*aResult = new MenuBoxObject());
150 0 : return NS_OK;
151 : }
|