summaryrefslogtreecommitdiffstats
path: root/accessible/xul/XULSelectControlAccessible.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/xul/XULSelectControlAccessible.cpp')
-rw-r--r--accessible/xul/XULSelectControlAccessible.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/accessible/xul/XULSelectControlAccessible.cpp b/accessible/xul/XULSelectControlAccessible.cpp
new file mode 100644
index 000000000..a1cc65d78
--- /dev/null
+++ b/accessible/xul/XULSelectControlAccessible.cpp
@@ -0,0 +1,256 @@
+/* -*- 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
+
+void
+XULSelectControlAccessible::SelectedItems(nsTArray<Accessible*>* aItems)
+{
+ // For XUL multi-select control
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
+ do_QueryInterface(mSelectControl);
+ if (xulMultiSelect) {
+ int32_t length = 0;
+ xulMultiSelect->GetSelectedCount(&length);
+ for (int32_t index = 0; index < length; index++) {
+ nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
+ xulMultiSelect->MultiGetSelectedItem(index, getter_AddRefs(itemElm));
+ nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
+ Accessible* item = mDoc->GetAccessible(itemNode);
+ if (item)
+ aItems->AppendElement(item);
+ }
+ } else { // Single select?
+ nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
+ mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
+ nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
+ if (itemNode) {
+ Accessible* item = mDoc->GetAccessible(itemNode);
+ if (item)
+ aItems->AppendElement(item);
+ }
+ }
+}
+
+Accessible*
+XULSelectControlAccessible::GetSelectedItem(uint32_t aIndex)
+{
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+ do_QueryInterface(mSelectControl);
+
+ nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
+ if (multiSelectControl)
+ multiSelectControl->MultiGetSelectedItem(aIndex, getter_AddRefs(itemElm));
+ else if (aIndex == 0)
+ mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
+
+ nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
+ return itemNode && mDoc ? mDoc->GetAccessible(itemNode) : nullptr;
+}
+
+uint32_t
+XULSelectControlAccessible::SelectedItemCount()
+{
+ // For XUL multi-select control
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> 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<nsIDOMXULSelectControlItemElement> itemElm =
+ do_QueryInterface(item->GetContent());
+ if (!itemElm)
+ return false;
+
+ bool isItemSelected = false;
+ itemElm->GetSelected(&isItemSelected);
+ if (isItemSelected)
+ return true;
+
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> 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<nsIDOMXULSelectControlItemElement> itemElm =
+ do_QueryInterface(item->GetContent());
+ if (!itemElm)
+ return false;
+
+ bool isItemSelected = false;
+ itemElm->GetSelected(&isItemSelected);
+ if (!isItemSelected)
+ return true;
+
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> 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<nsIDOMXULSelectControlItemElement> itemElm =
+ do_QueryInterface(item->GetContent());
+ if (!itemElm)
+ return false;
+
+ bool isItemSelected = false;
+ itemElm->GetSelected(&isItemSelected);
+ return isItemSelected;
+}
+
+bool
+XULSelectControlAccessible::UnselectAll()
+{
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+ do_QueryInterface(mSelectControl);
+ multiSelectControl ?
+ multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1);
+
+ return true;
+}
+
+bool
+XULSelectControlAccessible::SelectAll()
+{
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> 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<nsIDOMXULSelectControlItemElement> currentItemElm;
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+ do_QueryInterface(mSelectControl);
+ if (multiSelectControl)
+ multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm));
+ else
+ mSelectControl->GetSelectedItem(getter_AddRefs(currentItemElm));
+
+ nsCOMPtr<nsINode> 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<nsIDOMXULSelectControlItemElement> itemElm =
+ do_QueryInterface(aItem->GetContent());
+ nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+ do_QueryInterface(mSelectControl);
+ if (multiSelectControl)
+ multiSelectControl->SetCurrentItem(itemElm);
+ else
+ mSelectControl->SetSelectedItem(itemElm);
+}