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