tor-browser

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

ia2AccessibleTextSelectionContainer.cpp (3869B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:expandtab:shiftwidth=2:tabstop=2:
      3 */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "ia2AccessibleTextSelectionContainer.h"
      9 
     10 #include "AccessibleTextSelectionContainer_i.c"
     11 #include "ia2AccessibleHypertext.h"
     12 #include "mozilla/a11y/HyperTextAccessibleBase.h"
     13 #include "TextRange.h"
     14 #include "TextLeafRange.h"
     15 
     16 using namespace mozilla::a11y;
     17 
     18 // IAccessibleTextSelectionContainer
     19 
     20 STDMETHODIMP
     21 ia2AccessibleTextSelectionContainer::get_selections(
     22    IA2TextSelection** selections, long* nSelections) {
     23  if (!selections || !nSelections) {
     24    return E_INVALIDARG;
     25  }
     26  *nSelections = 0;
     27  HyperTextAccessibleBase* text = TextAcc();
     28  if (!text) {
     29    return CO_E_OBJNOTCONNECTED;
     30  }
     31  AutoTArray<TextRange, 1> ranges;
     32  text->CroppedSelectionRanges(ranges);
     33  *nSelections = ranges.Length();
     34  *selections = static_cast<IA2TextSelection*>(
     35      ::CoTaskMemAlloc(sizeof(IA2TextSelection) * *nSelections));
     36  if (!*selections) {
     37    return E_OUTOFMEMORY;
     38  }
     39  for (uint32_t idx = 0; idx < static_cast<uint32_t>(*nSelections); idx++) {
     40    RefPtr<IAccessibleText> startObj =
     41        GetIATextFrom(ranges[idx].StartContainer());
     42    startObj.forget(&(*selections)[idx].startObj);
     43    (*selections)[idx].startOffset = ranges[idx].StartOffset();
     44    RefPtr<IAccessibleText> endObj = GetIATextFrom(ranges[idx].EndContainer());
     45    endObj.forget(&(*selections)[idx].endObj);
     46    (*selections)[idx].endOffset = ranges[idx].EndOffset();
     47    // XXX Expose this properly somehow.
     48    (*selections)[idx].startIsActive = true;
     49  }
     50  return S_OK;
     51 }
     52 
     53 STDMETHODIMP
     54 ia2AccessibleTextSelectionContainer::setSelections(
     55    long nSelections, IA2TextSelection* selections) {
     56  if (nSelections < 0 || !selections) {
     57    return E_INVALIDARG;
     58  }
     59  HyperTextAccessibleBase* text = TextAcc();
     60  if (!text) {
     61    return CO_E_OBJNOTCONNECTED;
     62  }
     63  if (nSelections == 0) {
     64    text->RemoveFromSelection(TextLeafRange::kRemoveAllExistingSelectedRanges);
     65    return S_OK;
     66  }
     67  // Build and validate new selection ranges.
     68  AutoTArray<TextLeafRange, 1> newRanges;
     69  newRanges.SetCapacity(nSelections);
     70  for (long r = 0; r < nSelections; ++r) {
     71    TextLeafRange range(
     72        GetTextLeafPointFrom(selections[r].startObj, selections[r].startOffset),
     73        GetTextLeafPointFrom(selections[r].endObj, selections[r].endOffset));
     74    if (!range) {
     75      return E_INVALIDARG;
     76    }
     77    newRanges.AppendElement(range);
     78  }
     79  // Set the new selections.
     80  newRanges[0].SetSelection(TextLeafRange::kRemoveAllExistingSelectedRanges);
     81  for (long r = 1; r < nSelections; ++r) {
     82    newRanges[r].SetSelection(r);
     83  }
     84  return S_OK;
     85 }
     86 
     87 // ia2AccessibleTextSelectionContainer
     88 
     89 HyperTextAccessibleBase* ia2AccessibleTextSelectionContainer::TextAcc() {
     90  auto hyp = static_cast<ia2AccessibleHypertext*>(this);
     91  Accessible* acc = hyp->Acc();
     92  return acc ? acc->AsHyperTextBase() : nullptr;
     93 }
     94 
     95 /* static */
     96 RefPtr<IAccessibleText> ia2AccessibleTextSelectionContainer::GetIATextFrom(
     97    Accessible* aAcc) {
     98  MsaaAccessible* msaa = MsaaAccessible::GetFrom(aAcc);
     99  MOZ_ASSERT(msaa);
    100  RefPtr<IAccessibleText> text;
    101  msaa->QueryInterface(IID_IAccessibleText, getter_AddRefs(text));
    102  MOZ_ASSERT(text);
    103  return text;
    104 }
    105 
    106 /* static */
    107 TextLeafPoint ia2AccessibleTextSelectionContainer::GetTextLeafPointFrom(
    108    IAccessibleText* aText, long aOffset) {
    109  if (!aText) {
    110    return TextLeafPoint();
    111  }
    112  Accessible* acc = MsaaAccessible::GetAccessibleFrom(aText);
    113  if (!acc) {
    114    return TextLeafPoint();
    115  }
    116  HyperTextAccessibleBase* hyp = acc->AsHyperTextBase();
    117  if (!hyp) {
    118    return TextLeafPoint();
    119  }
    120  return hyp->ToTextLeafPoint(aOffset);
    121 }