1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/xul/XULMenuAccessible.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,623 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "XULMenuAccessible.h" 1.10 + 1.11 +#include "Accessible-inl.h" 1.12 +#include "nsAccessibilityService.h" 1.13 +#include "nsAccUtils.h" 1.14 +#include "DocAccessible.h" 1.15 +#include "Role.h" 1.16 +#include "States.h" 1.17 +#include "XULFormControlAccessible.h" 1.18 + 1.19 +#include "nsIDOMElement.h" 1.20 +#include "nsIDOMXULElement.h" 1.21 +#include "nsIMutableArray.h" 1.22 +#include "nsIDOMXULContainerElement.h" 1.23 +#include "nsIDOMXULSelectCntrlItemEl.h" 1.24 +#include "nsIDOMXULMultSelectCntrlEl.h" 1.25 +#include "nsIDOMKeyEvent.h" 1.26 +#include "nsIServiceManager.h" 1.27 +#include "nsIPresShell.h" 1.28 +#include "nsIContent.h" 1.29 +#include "nsMenuBarFrame.h" 1.30 +#include "nsMenuPopupFrame.h" 1.31 + 1.32 +#include "mozilla/Preferences.h" 1.33 +#include "mozilla/LookAndFeel.h" 1.34 +#include "mozilla/dom/Element.h" 1.35 + 1.36 +using namespace mozilla; 1.37 +using namespace mozilla::a11y; 1.38 + 1.39 +//////////////////////////////////////////////////////////////////////////////// 1.40 +// XULMenuitemAccessible 1.41 +//////////////////////////////////////////////////////////////////////////////// 1.42 + 1.43 +XULMenuitemAccessible:: 1.44 + XULMenuitemAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.45 + AccessibleWrap(aContent, aDoc) 1.46 +{ 1.47 +} 1.48 + 1.49 +uint64_t 1.50 +XULMenuitemAccessible::NativeState() 1.51 +{ 1.52 + uint64_t state = Accessible::NativeState(); 1.53 + 1.54 + // Has Popup? 1.55 + if (mContent->NodeInfo()->Equals(nsGkAtoms::menu, kNameSpaceID_XUL)) { 1.56 + state |= states::HASPOPUP; 1.57 + if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::open)) 1.58 + state |= states::EXPANDED; 1.59 + else 1.60 + state |= states::COLLAPSED; 1.61 + } 1.62 + 1.63 + // Checkable/checked? 1.64 + static nsIContent::AttrValuesArray strings[] = 1.65 + { &nsGkAtoms::radio, &nsGkAtoms::checkbox, nullptr }; 1.66 + 1.67 + if (mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type, strings, 1.68 + eCaseMatters) >= 0) { 1.69 + 1.70 + // Checkable? 1.71 + state |= states::CHECKABLE; 1.72 + 1.73 + // Checked? 1.74 + if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked, 1.75 + nsGkAtoms::_true, eCaseMatters)) 1.76 + state |= states::CHECKED; 1.77 + } 1.78 + 1.79 + // Combo box listitem 1.80 + bool isComboboxOption = (Role() == roles::COMBOBOX_OPTION); 1.81 + if (isComboboxOption) { 1.82 + // Is selected? 1.83 + bool isSelected = false; 1.84 + nsCOMPtr<nsIDOMXULSelectControlItemElement> 1.85 + item(do_QueryInterface(mContent)); 1.86 + NS_ENSURE_TRUE(item, state); 1.87 + item->GetSelected(&isSelected); 1.88 + 1.89 + // Is collapsed? 1.90 + bool isCollapsed = false; 1.91 + Accessible* parent = Parent(); 1.92 + if (parent && parent->State() & states::INVISIBLE) 1.93 + isCollapsed = true; 1.94 + 1.95 + if (isSelected) { 1.96 + state |= states::SELECTED; 1.97 + 1.98 + // Selected and collapsed? 1.99 + if (isCollapsed) { 1.100 + // Set selected option offscreen/invisible according to combobox state 1.101 + Accessible* grandParent = parent->Parent(); 1.102 + if (!grandParent) 1.103 + return state; 1.104 + NS_ASSERTION(grandParent->Role() == roles::COMBOBOX, 1.105 + "grandparent of combobox listitem is not combobox"); 1.106 + uint64_t grandParentState = grandParent->State(); 1.107 + state &= ~(states::OFFSCREEN | states::INVISIBLE); 1.108 + state |= (grandParentState & states::OFFSCREEN) | 1.109 + (grandParentState & states::INVISIBLE) | 1.110 + (grandParentState & states::OPAQUE1); 1.111 + } // isCollapsed 1.112 + } // isSelected 1.113 + } // ROLE_COMBOBOX_OPTION 1.114 + 1.115 + return state; 1.116 +} 1.117 + 1.118 +uint64_t 1.119 +XULMenuitemAccessible::NativeInteractiveState() const 1.120 +{ 1.121 + if (NativelyUnavailable()) { 1.122 + // Note: keep in sinc with nsXULPopupManager::IsValidMenuItem() logic. 1.123 + bool skipNavigatingDisabledMenuItem = true; 1.124 + nsMenuFrame* menuFrame = do_QueryFrame(GetFrame()); 1.125 + if (!menuFrame || !menuFrame->IsOnMenuBar()) { 1.126 + skipNavigatingDisabledMenuItem = LookAndFeel:: 1.127 + GetInt(LookAndFeel::eIntID_SkipNavigatingDisabledMenuItem, 0) != 0; 1.128 + } 1.129 + 1.130 + if (skipNavigatingDisabledMenuItem) 1.131 + return states::UNAVAILABLE; 1.132 + 1.133 + return states::UNAVAILABLE | states::FOCUSABLE | states::SELECTABLE; 1.134 + } 1.135 + 1.136 + return states::FOCUSABLE | states::SELECTABLE; 1.137 +} 1.138 + 1.139 +ENameValueFlag 1.140 +XULMenuitemAccessible::NativeName(nsString& aName) 1.141 +{ 1.142 + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName); 1.143 + return eNameOK; 1.144 +} 1.145 + 1.146 +void 1.147 +XULMenuitemAccessible::Description(nsString& aDescription) 1.148 +{ 1.149 + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::description, 1.150 + aDescription); 1.151 +} 1.152 + 1.153 +KeyBinding 1.154 +XULMenuitemAccessible::AccessKey() const 1.155 +{ 1.156 + // Return menu accesskey: N or Alt+F. 1.157 + static int32_t gMenuAccesskeyModifier = -1; // magic value of -1 indicates unitialized state 1.158 + 1.159 + // We do not use nsCoreUtils::GetAccesskeyFor() because accesskeys for 1.160 + // menu are't registered by EventStateManager. 1.161 + nsAutoString accesskey; 1.162 + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, 1.163 + accesskey); 1.164 + if (accesskey.IsEmpty()) 1.165 + return KeyBinding(); 1.166 + 1.167 + uint32_t modifierKey = 0; 1.168 + 1.169 + Accessible* parentAcc = Parent(); 1.170 + if (parentAcc) { 1.171 + if (parentAcc->NativeRole() == roles::MENUBAR) { 1.172 + // If top level menu item, add Alt+ or whatever modifier text to string 1.173 + // No need to cache pref service, this happens rarely 1.174 + if (gMenuAccesskeyModifier == -1) { 1.175 + // Need to initialize cached global accesskey pref 1.176 + gMenuAccesskeyModifier = Preferences::GetInt("ui.key.menuAccessKey", 0); 1.177 + } 1.178 + 1.179 + switch (gMenuAccesskeyModifier) { 1.180 + case nsIDOMKeyEvent::DOM_VK_CONTROL: 1.181 + modifierKey = KeyBinding::kControl; 1.182 + break; 1.183 + case nsIDOMKeyEvent::DOM_VK_ALT: 1.184 + modifierKey = KeyBinding::kAlt; 1.185 + break; 1.186 + case nsIDOMKeyEvent::DOM_VK_META: 1.187 + modifierKey = KeyBinding::kMeta; 1.188 + break; 1.189 + case nsIDOMKeyEvent::DOM_VK_WIN: 1.190 + modifierKey = KeyBinding::kOS; 1.191 + break; 1.192 + } 1.193 + } 1.194 + } 1.195 + 1.196 + return KeyBinding(accesskey[0], modifierKey); 1.197 +} 1.198 + 1.199 +KeyBinding 1.200 +XULMenuitemAccessible::KeyboardShortcut() const 1.201 +{ 1.202 + nsAutoString keyElmId; 1.203 + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::key, keyElmId); 1.204 + if (keyElmId.IsEmpty()) 1.205 + return KeyBinding(); 1.206 + 1.207 + nsIContent* keyElm = mContent->OwnerDoc()->GetElementById(keyElmId); 1.208 + if (!keyElm) 1.209 + return KeyBinding(); 1.210 + 1.211 + uint32_t key = 0; 1.212 + 1.213 + nsAutoString keyStr; 1.214 + keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::key, keyStr); 1.215 + if (keyStr.IsEmpty()) { 1.216 + nsAutoString keyCodeStr; 1.217 + keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::keycode, keyCodeStr); 1.218 + nsresult errorCode; 1.219 + key = keyStr.ToInteger(&errorCode, kAutoDetect); 1.220 + } else { 1.221 + key = keyStr[0]; 1.222 + } 1.223 + 1.224 + nsAutoString modifiersStr; 1.225 + keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::modifiers, modifiersStr); 1.226 + 1.227 + uint32_t modifierMask = 0; 1.228 + if (modifiersStr.Find("shift") != -1) 1.229 + modifierMask |= KeyBinding::kShift; 1.230 + if (modifiersStr.Find("alt") != -1) 1.231 + modifierMask |= KeyBinding::kAlt; 1.232 + if (modifiersStr.Find("meta") != -1) 1.233 + modifierMask |= KeyBinding::kMeta; 1.234 + if (modifiersStr.Find("os") != -1) 1.235 + modifierMask |= KeyBinding::kOS; 1.236 + if (modifiersStr.Find("control") != -1) 1.237 + modifierMask |= KeyBinding::kControl; 1.238 + if (modifiersStr.Find("accel") != -1) { 1.239 + // Get the accelerator key value from prefs, overriding the default. 1.240 + switch (Preferences::GetInt("ui.key.accelKey", 0)) { 1.241 + case nsIDOMKeyEvent::DOM_VK_META: 1.242 + modifierMask |= KeyBinding::kMeta; 1.243 + break; 1.244 + 1.245 + case nsIDOMKeyEvent::DOM_VK_WIN: 1.246 + modifierMask |= KeyBinding::kOS; 1.247 + break; 1.248 + 1.249 + case nsIDOMKeyEvent::DOM_VK_ALT: 1.250 + modifierMask |= KeyBinding::kAlt; 1.251 + break; 1.252 + 1.253 + case nsIDOMKeyEvent::DOM_VK_CONTROL: 1.254 + modifierMask |= KeyBinding::kControl; 1.255 + break; 1.256 + 1.257 + default: 1.258 +#ifdef XP_MACOSX 1.259 + modifierMask |= KeyBinding::kMeta; 1.260 +#else 1.261 + modifierMask |= KeyBinding::kControl; 1.262 +#endif 1.263 + } 1.264 + } 1.265 + 1.266 + return KeyBinding(key, modifierMask); 1.267 +} 1.268 + 1.269 +role 1.270 +XULMenuitemAccessible::NativeRole() 1.271 +{ 1.272 + nsCOMPtr<nsIDOMXULContainerElement> xulContainer(do_QueryInterface(mContent)); 1.273 + if (xulContainer) 1.274 + return roles::PARENT_MENUITEM; 1.275 + 1.276 + if (mParent && mParent->Role() == roles::COMBOBOX_LIST) 1.277 + return roles::COMBOBOX_OPTION; 1.278 + 1.279 + if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, 1.280 + nsGkAtoms::radio, eCaseMatters)) 1.281 + return roles::RADIO_MENU_ITEM; 1.282 + 1.283 + if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, 1.284 + nsGkAtoms::checkbox, 1.285 + eCaseMatters)) 1.286 + return roles::CHECK_MENU_ITEM; 1.287 + 1.288 + return roles::MENUITEM; 1.289 +} 1.290 + 1.291 +int32_t 1.292 +XULMenuitemAccessible::GetLevelInternal() 1.293 +{ 1.294 + return nsAccUtils::GetLevelForXULContainerItem(mContent); 1.295 +} 1.296 + 1.297 +bool 1.298 +XULMenuitemAccessible::CanHaveAnonChildren() 1.299 +{ 1.300 + // That indicates we don't walk anonymous children for menuitems 1.301 + return false; 1.302 +} 1.303 + 1.304 +NS_IMETHODIMP 1.305 +XULMenuitemAccessible::DoAction(uint8_t index) 1.306 +{ 1.307 + if (index == eAction_Click) { // default action 1.308 + DoCommand(); 1.309 + return NS_OK; 1.310 + } 1.311 + 1.312 + return NS_ERROR_INVALID_ARG; 1.313 +} 1.314 + 1.315 +/** select us! close combo box if necessary*/ 1.316 +NS_IMETHODIMP 1.317 +XULMenuitemAccessible::GetActionName(uint8_t aIndex, nsAString& aName) 1.318 +{ 1.319 + if (aIndex == eAction_Click) { 1.320 + aName.AssignLiteral("click"); 1.321 + return NS_OK; 1.322 + } 1.323 + return NS_ERROR_INVALID_ARG; 1.324 +} 1.325 + 1.326 +uint8_t 1.327 +XULMenuitemAccessible::ActionCount() 1.328 +{ 1.329 + return 1; 1.330 +} 1.331 + 1.332 +//////////////////////////////////////////////////////////////////////////////// 1.333 +// XULMenuitemAccessible: Widgets 1.334 + 1.335 +bool 1.336 +XULMenuitemAccessible::IsActiveWidget() const 1.337 +{ 1.338 + // Parent menu item is a widget, it's active when its popup is open. 1.339 + nsIContent* menuPopupContent = mContent->GetFirstChild(); 1.340 + if (menuPopupContent) { 1.341 + nsMenuPopupFrame* menuPopupFrame = 1.342 + do_QueryFrame(menuPopupContent->GetPrimaryFrame()); 1.343 + return menuPopupFrame && menuPopupFrame->IsOpen(); 1.344 + } 1.345 + return false; 1.346 +} 1.347 + 1.348 +bool 1.349 +XULMenuitemAccessible::AreItemsOperable() const 1.350 +{ 1.351 + // Parent menu item is a widget, its items are operable when its popup is open. 1.352 + nsIContent* menuPopupContent = mContent->GetFirstChild(); 1.353 + if (menuPopupContent) { 1.354 + nsMenuPopupFrame* menuPopupFrame = 1.355 + do_QueryFrame(menuPopupContent->GetPrimaryFrame()); 1.356 + return menuPopupFrame && menuPopupFrame->IsOpen(); 1.357 + } 1.358 + return false; 1.359 +} 1.360 + 1.361 +Accessible* 1.362 +XULMenuitemAccessible::ContainerWidget() const 1.363 +{ 1.364 + nsMenuFrame* menuFrame = do_QueryFrame(GetFrame()); 1.365 + if (menuFrame) { 1.366 + nsMenuParent* menuParent = menuFrame->GetMenuParent(); 1.367 + if (menuParent) { 1.368 + if (menuParent->IsMenuBar()) // menubar menu 1.369 + return mParent; 1.370 + 1.371 + // a menupoup or parent menu item 1.372 + if (menuParent->IsMenu()) 1.373 + return mParent; 1.374 + 1.375 + // otherwise it's different kind of popups (like panel or tooltip), it 1.376 + // shouldn't be a real case. 1.377 + } 1.378 + } 1.379 + return nullptr; 1.380 +} 1.381 + 1.382 + 1.383 +//////////////////////////////////////////////////////////////////////////////// 1.384 +// XULMenuSeparatorAccessible 1.385 +//////////////////////////////////////////////////////////////////////////////// 1.386 + 1.387 +XULMenuSeparatorAccessible:: 1.388 + XULMenuSeparatorAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.389 + XULMenuitemAccessible(aContent, aDoc) 1.390 +{ 1.391 +} 1.392 + 1.393 +uint64_t 1.394 +XULMenuSeparatorAccessible::NativeState() 1.395 +{ 1.396 + // Isn't focusable, but can be offscreen/invisible -- only copy those states 1.397 + return XULMenuitemAccessible::NativeState() & 1.398 + (states::OFFSCREEN | states::INVISIBLE); 1.399 +} 1.400 + 1.401 +ENameValueFlag 1.402 +XULMenuSeparatorAccessible::NativeName(nsString& aName) 1.403 +{ 1.404 + return eNameOK; 1.405 +} 1.406 + 1.407 +role 1.408 +XULMenuSeparatorAccessible::NativeRole() 1.409 +{ 1.410 + return roles::SEPARATOR; 1.411 +} 1.412 + 1.413 +NS_IMETHODIMP 1.414 +XULMenuSeparatorAccessible::DoAction(uint8_t index) 1.415 +{ 1.416 + return NS_ERROR_NOT_IMPLEMENTED; 1.417 +} 1.418 + 1.419 +NS_IMETHODIMP 1.420 +XULMenuSeparatorAccessible::GetActionName(uint8_t aIndex, nsAString& aName) 1.421 +{ 1.422 + return NS_ERROR_NOT_IMPLEMENTED; 1.423 +} 1.424 + 1.425 +uint8_t 1.426 +XULMenuSeparatorAccessible::ActionCount() 1.427 +{ 1.428 + return 0; 1.429 +} 1.430 + 1.431 +//////////////////////////////////////////////////////////////////////////////// 1.432 +// XULMenupopupAccessible 1.433 +//////////////////////////////////////////////////////////////////////////////// 1.434 + 1.435 +XULMenupopupAccessible:: 1.436 + XULMenupopupAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.437 + XULSelectControlAccessible(aContent, aDoc) 1.438 +{ 1.439 + nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetFrame()); 1.440 + if (menuPopupFrame && menuPopupFrame->IsMenu()) 1.441 + mType = eMenuPopupType; 1.442 + 1.443 + // May be the anonymous <menupopup> inside <menulist> (a combobox) 1.444 + mSelectControl = do_QueryInterface(mContent->GetFlattenedTreeParent()); 1.445 + if (!mSelectControl) 1.446 + mGenericTypes &= ~eSelect; 1.447 +} 1.448 + 1.449 +uint64_t 1.450 +XULMenupopupAccessible::NativeState() 1.451 +{ 1.452 + uint64_t state = Accessible::NativeState(); 1.453 + 1.454 +#ifdef DEBUG 1.455 + // We are onscreen if our parent is active 1.456 + bool isActive = mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::menuactive); 1.457 + if (!isActive) { 1.458 + Accessible* parent = Parent(); 1.459 + if (parent) { 1.460 + nsIContent* parentContent = parent->GetContent(); 1.461 + if (parentContent) 1.462 + isActive = parentContent->HasAttr(kNameSpaceID_None, nsGkAtoms::open); 1.463 + } 1.464 + } 1.465 + 1.466 + NS_ASSERTION(isActive || (state & states::INVISIBLE), 1.467 + "XULMenupopup doesn't have INVISIBLE when it's inactive"); 1.468 +#endif 1.469 + 1.470 + if (state & states::INVISIBLE) 1.471 + state |= states::OFFSCREEN | states::COLLAPSED; 1.472 + 1.473 + return state; 1.474 +} 1.475 + 1.476 +ENameValueFlag 1.477 +XULMenupopupAccessible::NativeName(nsString& aName) 1.478 +{ 1.479 + nsIContent* content = mContent; 1.480 + while (content && aName.IsEmpty()) { 1.481 + content->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName); 1.482 + content = content->GetFlattenedTreeParent(); 1.483 + } 1.484 + 1.485 + return eNameOK; 1.486 +} 1.487 + 1.488 +role 1.489 +XULMenupopupAccessible::NativeRole() 1.490 +{ 1.491 + // If accessible is not bound to the tree (this happens while children are 1.492 + // cached) return general role. 1.493 + if (mParent) { 1.494 + roles::Role role = mParent->Role(); 1.495 + if (role == roles::COMBOBOX || role == roles::AUTOCOMPLETE) 1.496 + return roles::COMBOBOX_LIST; 1.497 + 1.498 + if (role == roles::PUSHBUTTON) { 1.499 + // Some widgets like the search bar have several popups, owned by buttons. 1.500 + Accessible* grandParent = mParent->Parent(); 1.501 + if (grandParent && grandParent->Role() == roles::AUTOCOMPLETE) 1.502 + return roles::COMBOBOX_LIST; 1.503 + } 1.504 + } 1.505 + 1.506 + return roles::MENUPOPUP; 1.507 +} 1.508 + 1.509 +//////////////////////////////////////////////////////////////////////////////// 1.510 +// XULMenupopupAccessible: Widgets 1.511 + 1.512 +bool 1.513 +XULMenupopupAccessible::IsWidget() const 1.514 +{ 1.515 + return true; 1.516 +} 1.517 + 1.518 +bool 1.519 +XULMenupopupAccessible::IsActiveWidget() const 1.520 +{ 1.521 + // If menupopup is a widget (the case of context menus) then active when open. 1.522 + nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetFrame()); 1.523 + return menuPopupFrame && menuPopupFrame->IsOpen(); 1.524 +} 1.525 + 1.526 +bool 1.527 +XULMenupopupAccessible::AreItemsOperable() const 1.528 +{ 1.529 + nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetFrame()); 1.530 + return menuPopupFrame && menuPopupFrame->IsOpen(); 1.531 +} 1.532 + 1.533 +Accessible* 1.534 +XULMenupopupAccessible::ContainerWidget() const 1.535 +{ 1.536 + DocAccessible* document = Document(); 1.537 + 1.538 + nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetFrame()); 1.539 + while (menuPopupFrame) { 1.540 + Accessible* menuPopup = 1.541 + document->GetAccessible(menuPopupFrame->GetContent()); 1.542 + if (!menuPopup) // shouldn't be a real case 1.543 + return nullptr; 1.544 + 1.545 + nsMenuFrame* menuFrame = do_QueryFrame(menuPopupFrame->GetParent()); 1.546 + if (!menuFrame) // context menu or popups 1.547 + return nullptr; 1.548 + 1.549 + nsMenuParent* menuParent = menuFrame->GetMenuParent(); 1.550 + if (!menuParent) // menulist or menubutton 1.551 + return menuPopup->Parent(); 1.552 + 1.553 + if (menuParent->IsMenuBar()) { // menubar menu 1.554 + nsMenuBarFrame* menuBarFrame = static_cast<nsMenuBarFrame*>(menuParent); 1.555 + return document->GetAccessible(menuBarFrame->GetContent()); 1.556 + } 1.557 + 1.558 + // different kind of popups like panel or tooltip 1.559 + if (!menuParent->IsMenu()) 1.560 + return nullptr; 1.561 + 1.562 + menuPopupFrame = static_cast<nsMenuPopupFrame*>(menuParent); 1.563 + } 1.564 + 1.565 + NS_NOTREACHED("Shouldn't be a real case."); 1.566 + return nullptr; 1.567 +} 1.568 + 1.569 +//////////////////////////////////////////////////////////////////////////////// 1.570 +// XULMenubarAccessible 1.571 +//////////////////////////////////////////////////////////////////////////////// 1.572 + 1.573 +XULMenubarAccessible:: 1.574 + XULMenubarAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.575 + AccessibleWrap(aContent, aDoc) 1.576 +{ 1.577 +} 1.578 + 1.579 +ENameValueFlag 1.580 +XULMenubarAccessible::NativeName(nsString& aName) 1.581 +{ 1.582 + aName.AssignLiteral("Application"); 1.583 + return eNameOK; 1.584 +} 1.585 + 1.586 +role 1.587 +XULMenubarAccessible::NativeRole() 1.588 +{ 1.589 + return roles::MENUBAR; 1.590 +} 1.591 + 1.592 +//////////////////////////////////////////////////////////////////////////////// 1.593 +// XULMenubarAccessible: Widgets 1.594 + 1.595 +bool 1.596 +XULMenubarAccessible::IsActiveWidget() const 1.597 +{ 1.598 + nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame()); 1.599 + return menuBarFrame && menuBarFrame->IsActive(); 1.600 +} 1.601 + 1.602 +bool 1.603 +XULMenubarAccessible::AreItemsOperable() const 1.604 +{ 1.605 + return true; 1.606 +} 1.607 + 1.608 +Accessible* 1.609 +XULMenubarAccessible::CurrentItem() 1.610 +{ 1.611 + nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame()); 1.612 + if (menuBarFrame) { 1.613 + nsMenuFrame* menuFrame = menuBarFrame->GetCurrentMenuItem(); 1.614 + if (menuFrame) { 1.615 + nsIContent* menuItemNode = menuFrame->GetContent(); 1.616 + return mDoc->GetAccessible(menuItemNode); 1.617 + } 1.618 + } 1.619 + return nullptr; 1.620 +} 1.621 + 1.622 +void 1.623 +XULMenubarAccessible::SetCurrentItem(Accessible* aItem) 1.624 +{ 1.625 + NS_ERROR("XULMenubarAccessible::SetCurrentItem not implemented"); 1.626 +}