michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=8 sts=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 "ServiceProvider.h" michael@0: michael@0: #include "ApplicationAccessibleWrap.h" michael@0: #include "Compatibility.h" michael@0: #include "DocAccessible.h" michael@0: #include "nsAccUtils.h" michael@0: #include "nsCoreUtils.h" michael@0: #include "Relation.h" michael@0: #include "uiaRawElmProvider.h" michael@0: michael@0: #include "mozilla/Preferences.h" michael@0: #include "nsIDocShell.h" michael@0: michael@0: #include "ISimpleDOMNode_i.c" michael@0: michael@0: namespace mozilla { michael@0: namespace a11y { michael@0: michael@0: IMPL_IUNKNOWN_QUERY_HEAD(ServiceProvider) michael@0: IMPL_IUNKNOWN_QUERY_IFACE(IServiceProvider) michael@0: IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAccessible) michael@0: michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // IServiceProvider michael@0: michael@0: STDMETHODIMP michael@0: ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID, michael@0: void** aInstancePtr) michael@0: { michael@0: if (!aInstancePtr) michael@0: return E_INVALIDARG; michael@0: michael@0: *aInstancePtr = nullptr; michael@0: michael@0: // UIA IAccessibleEx michael@0: if (aGuidService == IID_IAccessibleEx && michael@0: Preferences::GetBool("accessibility.uia.enable")) { michael@0: uiaRawElmProvider* accEx = new uiaRawElmProvider(mAccessible); michael@0: HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr); michael@0: if (FAILED(hr)) michael@0: delete accEx; michael@0: michael@0: return hr; michael@0: } michael@0: michael@0: // Provide a special service ID for getting the accessible for the browser tab michael@0: // document that contains this accessible object. If this accessible object michael@0: // is not inside a browser tab then the service fails with E_NOINTERFACE. michael@0: // A use case for this is for screen readers that need to switch context or michael@0: // 'virtual buffer' when focus moves from one browser tab area to another. michael@0: static const GUID SID_IAccessibleContentDocument = michael@0: { 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} }; michael@0: if (aGuidService == SID_IAccessibleContentDocument) { michael@0: if (aIID != IID_IAccessible) michael@0: return E_NOINTERFACE; michael@0: michael@0: Relation rel = mAccessible->RelationByType(RelationType::CONTAINING_TAB_PANE); michael@0: AccessibleWrap* tabDoc = static_cast(rel.Next()); michael@0: if (!tabDoc) michael@0: return E_NOINTERFACE; michael@0: michael@0: *aInstancePtr = static_cast(tabDoc); michael@0: (reinterpret_cast(*aInstancePtr))->AddRef(); michael@0: return S_OK; michael@0: } michael@0: michael@0: // Can get to IAccessibleApplication from any node via QS michael@0: if (aGuidService == IID_IAccessibleApplication || michael@0: (Compatibility::IsJAWS() && aIID == IID_IAccessibleApplication)) { michael@0: ApplicationAccessibleWrap* applicationAcc = michael@0: static_cast(ApplicationAcc()); michael@0: if (!applicationAcc) michael@0: return E_NOINTERFACE; michael@0: michael@0: return applicationAcc->QueryInterface(aIID, aInstancePtr); michael@0: } michael@0: michael@0: static const GUID IID_SimpleDOMDeprecated = michael@0: { 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} }; michael@0: if (aGuidService == IID_ISimpleDOMNode || michael@0: aGuidService == IID_SimpleDOMDeprecated || michael@0: aGuidService == IID_IAccessible || aGuidService == IID_IAccessible2) michael@0: return mAccessible->QueryInterface(aIID, aInstancePtr); michael@0: michael@0: return E_INVALIDARG; michael@0: } michael@0: michael@0: } // namespace a11y michael@0: } // namespace mozilla