tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

XULSelectControlAccessible.cpp (8145B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "XULSelectControlAccessible.h"
      8 
      9 #include "nsAccessibilityService.h"
     10 #include "DocAccessible.h"
     11 
     12 #include "nsIDOMXULSelectCntrlItemEl.h"
     13 #include "nsIDOMXULMultSelectCntrlEl.h"
     14 
     15 #include "mozilla/dom/Element.h"
     16 #include "mozilla/dom/KeyboardEventBinding.h"
     17 
     18 using namespace mozilla;
     19 using namespace mozilla::a11y;
     20 
     21 ////////////////////////////////////////////////////////////////////////////////
     22 // XULSelectControlAccessible
     23 ////////////////////////////////////////////////////////////////////////////////
     24 
     25 XULSelectControlAccessible::XULSelectControlAccessible(nsIContent* aContent,
     26                                                       DocAccessible* aDoc)
     27    : AccessibleWrap(aContent, aDoc) {
     28  mGenericTypes |= eSelect;
     29  mSelectControl = aContent->AsElement();
     30 }
     31 
     32 ////////////////////////////////////////////////////////////////////////////////
     33 // XULSelectControlAccessible: LocalAccessible
     34 
     35 void XULSelectControlAccessible::Shutdown() {
     36  mSelectControl = nullptr;
     37  AccessibleWrap::Shutdown();
     38 }
     39 
     40 ////////////////////////////////////////////////////////////////////////////////
     41 // XULSelectControlAccessible: SelectAccessible
     42 
     43 void XULSelectControlAccessible::SelectedItems(nsTArray<Accessible*>* aItems) {
     44  // For XUL multi-select control
     45  nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
     46      mSelectControl->AsXULMultiSelectControl();
     47  if (xulMultiSelect) {
     48    int32_t length = 0;
     49    xulMultiSelect->GetSelectedCount(&length);
     50    for (int32_t index = 0; index < length; index++) {
     51      RefPtr<dom::Element> element;
     52      xulMultiSelect->MultiGetSelectedItem(index, getter_AddRefs(element));
     53      LocalAccessible* item = mDoc->GetAccessible(element);
     54      if (item) aItems->AppendElement(item);
     55    }
     56  } else {  // Single select?
     57    nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
     58        mSelectControl->AsXULSelectControl();
     59    RefPtr<dom::Element> element;
     60    selectControl->GetSelectedItem(getter_AddRefs(element));
     61    if (element) {
     62      LocalAccessible* item = mDoc->GetAccessible(element);
     63      if (item) aItems->AppendElement(item);
     64    }
     65  }
     66 }
     67 
     68 Accessible* XULSelectControlAccessible::GetSelectedItem(uint32_t aIndex) {
     69  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
     70      mSelectControl->AsXULMultiSelectControl();
     71 
     72  RefPtr<dom::Element> element;
     73  if (multiSelectControl) {
     74    multiSelectControl->MultiGetSelectedItem(aIndex, getter_AddRefs(element));
     75  } else if (aIndex == 0) {
     76    nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
     77        mSelectControl->AsXULSelectControl();
     78    if (selectControl) {
     79      selectControl->GetSelectedItem(getter_AddRefs(element));
     80    }
     81  }
     82 
     83  return element && mDoc ? mDoc->GetAccessible(element) : nullptr;
     84 }
     85 
     86 uint32_t XULSelectControlAccessible::SelectedItemCount() {
     87  // For XUL multi-select control
     88  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
     89      mSelectControl->AsXULMultiSelectControl();
     90  if (multiSelectControl) {
     91    int32_t count = 0;
     92    multiSelectControl->GetSelectedCount(&count);
     93    return count;
     94  }
     95 
     96  // For XUL single-select control/menulist
     97  nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
     98      mSelectControl->AsXULSelectControl();
     99  if (selectControl) {
    100    int32_t index = -1;
    101    selectControl->GetSelectedIndex(&index);
    102    return (index >= 0) ? 1 : 0;
    103  }
    104 
    105  return 0;
    106 }
    107 
    108 bool XULSelectControlAccessible::AddItemToSelection(uint32_t aIndex) {
    109  LocalAccessible* item = LocalChildAt(aIndex);
    110  if (!item || !item->GetContent()) return false;
    111 
    112  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
    113      item->GetContent()->AsElement()->AsXULSelectControlItem();
    114  if (!itemElm) return false;
    115 
    116  bool isItemSelected = false;
    117  itemElm->GetSelected(&isItemSelected);
    118  if (isItemSelected) return true;
    119 
    120  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
    121      mSelectControl->AsXULMultiSelectControl();
    122 
    123  if (multiSelectControl) {
    124    multiSelectControl->AddItemToSelection(itemElm);
    125  } else {
    126    nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
    127        mSelectControl->AsXULSelectControl();
    128    if (selectControl) {
    129      selectControl->SetSelectedItem(item->Elm());
    130    }
    131  }
    132 
    133  return true;
    134 }
    135 
    136 bool XULSelectControlAccessible::RemoveItemFromSelection(uint32_t aIndex) {
    137  LocalAccessible* item = LocalChildAt(aIndex);
    138  if (!item || !item->GetContent()) return false;
    139 
    140  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
    141      item->GetContent()->AsElement()->AsXULSelectControlItem();
    142  if (!itemElm) return false;
    143 
    144  bool isItemSelected = false;
    145  itemElm->GetSelected(&isItemSelected);
    146  if (!isItemSelected) return true;
    147 
    148  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
    149      mSelectControl->AsXULMultiSelectControl();
    150 
    151  if (multiSelectControl) {
    152    multiSelectControl->RemoveItemFromSelection(itemElm);
    153  } else {
    154    nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
    155        mSelectControl->AsXULSelectControl();
    156    if (selectControl) {
    157      selectControl->SetSelectedItem(nullptr);
    158    }
    159  }
    160 
    161  return true;
    162 }
    163 
    164 bool XULSelectControlAccessible::IsItemSelected(uint32_t aIndex) {
    165  LocalAccessible* item = LocalChildAt(aIndex);
    166  if (!item || !item->GetContent()) return false;
    167 
    168  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
    169      item->GetContent()->AsElement()->AsXULSelectControlItem();
    170  if (!itemElm) return false;
    171 
    172  bool isItemSelected = false;
    173  itemElm->GetSelected(&isItemSelected);
    174  return isItemSelected;
    175 }
    176 
    177 bool XULSelectControlAccessible::UnselectAll() {
    178  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
    179      mSelectControl->AsXULMultiSelectControl();
    180  if (multiSelectControl) {
    181    multiSelectControl->ClearSelection();
    182  } else {
    183    nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
    184        mSelectControl->AsXULSelectControl();
    185    if (selectControl) {
    186      selectControl->SetSelectedIndex(-1);
    187    }
    188  }
    189 
    190  return true;
    191 }
    192 
    193 bool XULSelectControlAccessible::SelectAll() {
    194  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
    195      mSelectControl->AsXULMultiSelectControl();
    196  if (multiSelectControl) {
    197    multiSelectControl->SelectAll();
    198    return true;
    199  }
    200 
    201  // otherwise, don't support this method
    202  return false;
    203 }
    204 
    205 ////////////////////////////////////////////////////////////////////////////////
    206 // XULSelectControlAccessible: Widgets
    207 
    208 LocalAccessible* XULSelectControlAccessible::CurrentItem() const {
    209  // aria-activedescendant should override.
    210  LocalAccessible* current = AccessibleWrap::CurrentItem();
    211  if (current) {
    212    return current;
    213  }
    214 
    215  if (!mSelectControl) return nullptr;
    216 
    217  RefPtr<dom::Element> currentItemElm;
    218  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
    219      mSelectControl->AsXULMultiSelectControl();
    220  if (multiSelectControl) {
    221    multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm));
    222  } else {
    223    nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
    224        mSelectControl->AsXULSelectControl();
    225    if (selectControl) {
    226      selectControl->GetSelectedItem(getter_AddRefs(currentItemElm));
    227    }
    228  }
    229 
    230  if (currentItemElm) {
    231    DocAccessible* document = Document();
    232    if (document) return document->GetAccessible(currentItemElm);
    233  }
    234 
    235  return nullptr;
    236 }
    237 
    238 void XULSelectControlAccessible::SetCurrentItem(const LocalAccessible* aItem) {
    239  if (!mSelectControl) return;
    240 
    241  nsCOMPtr<dom::Element> itemElm = aItem->Elm();
    242  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
    243      itemElm->AsXULMultiSelectControl();
    244  if (multiSelectControl) {
    245    multiSelectControl->SetCurrentItem(itemElm);
    246  } else {
    247    nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
    248        mSelectControl->AsXULSelectControl();
    249    if (selectControl) {
    250      selectControl->SetSelectedItem(itemElm);
    251    }
    252  }
    253 }