diff -r 000000000000 -r 6474c204b198 accessible/src/xul/XULSelectControlAccessible.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accessible/src/xul/XULSelectControlAccessible.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,265 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "XULSelectControlAccessible.h" + +#include "nsAccessibilityService.h" +#include "DocAccessible.h" + +#include "nsIDOMXULContainerElement.h" +#include "nsIDOMXULSelectCntrlItemEl.h" +#include "nsIDOMXULMultSelectCntrlEl.h" +#include "nsIDOMKeyEvent.h" +#include "nsIDOMElement.h" +#include "nsIDOMXULElement.h" +#include "nsIMutableArray.h" +#include "nsIServiceManager.h" + +#include "mozilla/dom/Element.h" + +using namespace mozilla; +using namespace mozilla::a11y; + +//////////////////////////////////////////////////////////////////////////////// +// XULSelectControlAccessible +//////////////////////////////////////////////////////////////////////////////// + +XULSelectControlAccessible:: + XULSelectControlAccessible(nsIContent* aContent, DocAccessible* aDoc) : + AccessibleWrap(aContent, aDoc) +{ + mGenericTypes |= eSelect; + mSelectControl = do_QueryInterface(aContent); +} + +//////////////////////////////////////////////////////////////////////////////// +// XULSelectControlAccessible: Accessible + +void +XULSelectControlAccessible::Shutdown() +{ + mSelectControl = nullptr; + AccessibleWrap::Shutdown(); +} + +//////////////////////////////////////////////////////////////////////////////// +// XULSelectControlAccessible: SelectAccessible + +already_AddRefed +XULSelectControlAccessible::SelectedItems() +{ + nsCOMPtr selectedItems = + do_CreateInstance(NS_ARRAY_CONTRACTID); + if (!selectedItems || !mDoc) + return nullptr; + + // For XUL multi-select control + nsCOMPtr xulMultiSelect = + do_QueryInterface(mSelectControl); + if (xulMultiSelect) { + int32_t length = 0; + xulMultiSelect->GetSelectedCount(&length); + for (int32_t index = 0; index < length; index++) { + nsCOMPtr itemElm; + xulMultiSelect->MultiGetSelectedItem(index, getter_AddRefs(itemElm)); + nsCOMPtr itemNode(do_QueryInterface(itemElm)); + Accessible* item = mDoc->GetAccessible(itemNode); + if (item) + selectedItems->AppendElement(static_cast(item), + false); + } + } else { // Single select? + nsCOMPtr itemElm; + mSelectControl->GetSelectedItem(getter_AddRefs(itemElm)); + nsCOMPtr itemNode(do_QueryInterface(itemElm)); + if (itemNode) { + Accessible* item = mDoc->GetAccessible(itemNode); + if (item) + selectedItems->AppendElement(static_cast(item), + false); + } + } + + return selectedItems.forget(); +} + +Accessible* +XULSelectControlAccessible::GetSelectedItem(uint32_t aIndex) +{ + nsCOMPtr multiSelectControl = + do_QueryInterface(mSelectControl); + + nsCOMPtr itemElm; + if (multiSelectControl) + multiSelectControl->MultiGetSelectedItem(aIndex, getter_AddRefs(itemElm)); + else if (aIndex == 0) + mSelectControl->GetSelectedItem(getter_AddRefs(itemElm)); + + nsCOMPtr itemNode(do_QueryInterface(itemElm)); + return itemNode && mDoc ? mDoc->GetAccessible(itemNode) : nullptr; +} + +uint32_t +XULSelectControlAccessible::SelectedItemCount() +{ + // For XUL multi-select control + nsCOMPtr multiSelectControl = + do_QueryInterface(mSelectControl); + if (multiSelectControl) { + int32_t count = 0; + multiSelectControl->GetSelectedCount(&count); + return count; + } + + // For XUL single-select control/menulist + int32_t index; + mSelectControl->GetSelectedIndex(&index); + return (index >= 0) ? 1 : 0; +} + +bool +XULSelectControlAccessible::AddItemToSelection(uint32_t aIndex) +{ + Accessible* item = GetChildAt(aIndex); + if (!item) + return false; + + nsCOMPtr itemElm = + do_QueryInterface(item->GetContent()); + if (!itemElm) + return false; + + bool isItemSelected = false; + itemElm->GetSelected(&isItemSelected); + if (isItemSelected) + return true; + + nsCOMPtr multiSelectControl = + do_QueryInterface(mSelectControl); + + if (multiSelectControl) + multiSelectControl->AddItemToSelection(itemElm); + else + mSelectControl->SetSelectedItem(itemElm); + + return true; +} + +bool +XULSelectControlAccessible::RemoveItemFromSelection(uint32_t aIndex) +{ + Accessible* item = GetChildAt(aIndex); + if (!item) + return false; + + nsCOMPtr itemElm = + do_QueryInterface(item->GetContent()); + if (!itemElm) + return false; + + bool isItemSelected = false; + itemElm->GetSelected(&isItemSelected); + if (!isItemSelected) + return true; + + nsCOMPtr multiSelectControl = + do_QueryInterface(mSelectControl); + + if (multiSelectControl) + multiSelectControl->RemoveItemFromSelection(itemElm); + else + mSelectControl->SetSelectedItem(nullptr); + + return true; +} + +bool +XULSelectControlAccessible::IsItemSelected(uint32_t aIndex) +{ + Accessible* item = GetChildAt(aIndex); + if (!item) + return false; + + nsCOMPtr itemElm = + do_QueryInterface(item->GetContent()); + if (!itemElm) + return false; + + bool isItemSelected = false; + itemElm->GetSelected(&isItemSelected); + return isItemSelected; +} + +bool +XULSelectControlAccessible::UnselectAll() +{ + nsCOMPtr multiSelectControl = + do_QueryInterface(mSelectControl); + multiSelectControl ? + multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1); + + return true; +} + +bool +XULSelectControlAccessible::SelectAll() +{ + nsCOMPtr multiSelectControl = + do_QueryInterface(mSelectControl); + if (multiSelectControl) { + multiSelectControl->SelectAll(); + return true; + } + + // otherwise, don't support this method + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// XULSelectControlAccessible: Widgets + +Accessible* +XULSelectControlAccessible::CurrentItem() +{ + if (!mSelectControl) + return nullptr; + + nsCOMPtr currentItemElm; + nsCOMPtr multiSelectControl = + do_QueryInterface(mSelectControl); + if (multiSelectControl) + multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm)); + else + mSelectControl->GetSelectedItem(getter_AddRefs(currentItemElm)); + + nsCOMPtr DOMNode; + if (currentItemElm) + DOMNode = do_QueryInterface(currentItemElm); + + if (DOMNode) { + DocAccessible* document = Document(); + if (document) + return document->GetAccessible(DOMNode); + } + + return nullptr; +} + +void +XULSelectControlAccessible::SetCurrentItem(Accessible* aItem) +{ + if (!mSelectControl) + return; + + nsCOMPtr itemElm = + do_QueryInterface(aItem->GetContent()); + nsCOMPtr multiSelectControl = + do_QueryInterface(mSelectControl); + if (multiSelectControl) + multiSelectControl->SetCurrentItem(itemElm); + else + mSelectControl->SetSelectedItem(itemElm); +}