tor-browser

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

MsaaDocAccessible.cpp (4155B)


      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 "MsaaDocAccessible.h"
      8 
      9 #include "MsaaDocAccessible.h"
     10 #include "DocAccessibleChild.h"
     11 #include "mozilla/a11y/DocAccessibleParent.h"
     12 #include "nsAccessibilityService.h"
     13 #include "nsAccUtils.h"
     14 #include "nsWinUtils.h"
     15 #include "mozilla/a11y/Role.h"
     16 #include "ISimpleDOM.h"
     17 
     18 using namespace mozilla;
     19 using namespace mozilla::a11y;
     20 
     21 DocAccessible* MsaaDocAccessible::DocAcc() {
     22  return static_cast<DocAccessible*>(LocalAcc());
     23 }
     24 
     25 /* static */
     26 MsaaDocAccessible* MsaaDocAccessible::GetFrom(DocAccessible* aDoc) {
     27  return static_cast<MsaaDocAccessible*>(MsaaAccessible::GetFrom(aDoc));
     28 }
     29 
     30 /* static */
     31 MsaaDocAccessible* MsaaDocAccessible::GetFrom(DocAccessibleParent* aDoc) {
     32  return static_cast<MsaaDocAccessible*>(
     33      reinterpret_cast<MsaaAccessible*>(aDoc->GetWrapper()));
     34 }
     35 
     36 /* static */
     37 MsaaDocAccessible* MsaaDocAccessible::GetFromOwned(Accessible* aAcc) {
     38  if (RemoteAccessible* remoteAcc = aAcc->AsRemote()) {
     39    DocAccessibleParent* doc = remoteAcc->Document();
     40    if (!doc) {
     41      return nullptr;
     42    }
     43    return MsaaDocAccessible::GetFrom(doc);
     44  }
     45  DocAccessible* doc = aAcc->AsLocal()->Document();
     46  if (!doc) {
     47    return nullptr;
     48  }
     49  return MsaaDocAccessible::GetFrom(doc);
     50 }
     51 
     52 // IUnknown
     53 IMPL_IUNKNOWN_QUERY_HEAD(MsaaDocAccessible)
     54 IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(ia2AccessibleHypertext)
     55 
     56 STDMETHODIMP
     57 MsaaDocAccessible::get_accParent(
     58    /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispParent) {
     59  if (!mAcc) {
     60    return CO_E_OBJNOTCONNECTED;
     61  }
     62 
     63  if (mAcc->IsRemote()) {
     64    DocAccessibleParent* remoteDoc = mAcc->AsRemote()->AsDoc();
     65    if (nsWinUtils::IsWindowEmulationStarted() && remoteDoc->IsTopLevel()) {
     66      // Window emulation is enabled and this is a top level document. Return
     67      // window system accessible object.
     68      HWND hwnd = remoteDoc->GetEmulatedWindowHandle();
     69      MOZ_ASSERT(hwnd);
     70      if (hwnd &&
     71          SUCCEEDED(::CreateStdAccessibleObject(
     72              hwnd, OBJID_WINDOW, IID_IAccessible, (void**)ppdispParent))) {
     73        return S_OK;
     74      }
     75    }
     76    return MsaaAccessible::get_accParent(ppdispParent);
     77  }
     78 
     79  DocAccessible* docAcc = DocAcc();
     80  MOZ_ASSERT(docAcc);
     81 
     82  // Return window system accessible object for root document accessibles, as
     83  // well as tab document accessibles if window emulation is enabled.
     84  MOZ_ASSERT(XRE_IsParentProcess());
     85  if ((!docAcc->ParentDocument() ||
     86       (nsWinUtils::IsWindowEmulationStarted() &&
     87        nsCoreUtils::IsTopLevelContentDocInProcess(docAcc->DocumentNode())))) {
     88    HWND hwnd = static_cast<HWND>(docAcc->GetNativeWindow());
     89    if (hwnd &&
     90        SUCCEEDED(::CreateStdAccessibleObject(
     91            hwnd, OBJID_WINDOW, IID_IAccessible, (void**)ppdispParent))) {
     92      return S_OK;
     93    }
     94  }
     95 
     96  return MsaaAccessible::get_accParent(ppdispParent);
     97 }
     98 
     99 STDMETHODIMP
    100 MsaaDocAccessible::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue) {
    101  if (!aValue) return E_INVALIDARG;
    102  *aValue = nullptr;
    103 
    104  // For backwards-compat, we still support old MSAA hack to provide URL in
    105  // accValue Check for real value first
    106  HRESULT hr = MsaaAccessible::get_accValue(aVarChild, aValue);
    107  if (FAILED(hr) || *aValue || aVarChild.lVal != CHILDID_SELF) return hr;
    108 
    109  // MsaaAccessible::get_accValue should have failed (and thus we should have
    110  // returned early) if the Accessible is dead.
    111  MOZ_ASSERT(mAcc);
    112  // If document is being used to create a widget, don't use the URL hack
    113  roles::Role role = mAcc->Role();
    114  if (role != roles::DOCUMENT && role != roles::APPLICATION &&
    115      role != roles::DIALOG && role != roles::ALERT &&
    116      role != roles::NON_NATIVE_DOCUMENT)
    117    return hr;
    118 
    119  nsAutoString url;
    120  nsAccUtils::DocumentURL(mAcc, url);
    121  if (url.IsEmpty()) return S_FALSE;
    122 
    123  *aValue = ::SysAllocStringLen(url.get(), url.Length());
    124  return *aValue ? S_OK : E_OUTOFMEMORY;
    125 }