michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:expandtab:shiftwidth=2:tabstop=2: michael@0: */ 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 "Accessible2.h" michael@0: #include "AccessibleHyperlink.h" michael@0: #include "AccessibleHyperlink_i.c" michael@0: michael@0: #include "AccessibleWrap.h" michael@0: #include "IUnknownImpl.h" michael@0: #include "nsIURI.h" michael@0: michael@0: using namespace mozilla::a11y; michael@0: michael@0: // IUnknown michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv) michael@0: { michael@0: if (!ppv) michael@0: return E_INVALIDARG; michael@0: michael@0: *ppv = nullptr; michael@0: michael@0: if (IID_IAccessibleHyperlink == iid) { michael@0: if (!static_cast(this)->IsLink()) michael@0: return E_NOINTERFACE; michael@0: michael@0: *ppv = static_cast(this); michael@0: (reinterpret_cast(*ppv))->AddRef(); michael@0: return S_OK; michael@0: } michael@0: michael@0: return ia2AccessibleAction::QueryInterface(iid, ppv); michael@0: } michael@0: michael@0: // IAccessibleHyperlink michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleHyperlink::get_anchor(long aIndex, VARIANT* aAnchor) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aAnchor) michael@0: return E_INVALIDARG; michael@0: michael@0: VariantInit(aAnchor); michael@0: michael@0: Accessible* thisObj = static_cast(this); michael@0: if (thisObj->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: if (aIndex < 0 || aIndex >= static_cast(thisObj->AnchorCount())) michael@0: return E_INVALIDARG; michael@0: michael@0: if (!thisObj->IsLink()) michael@0: return S_FALSE; michael@0: michael@0: AccessibleWrap* anchor = michael@0: static_cast(thisObj->AnchorAt(aIndex)); michael@0: if (!anchor) michael@0: return S_FALSE; michael@0: michael@0: void* instancePtr = nullptr; michael@0: HRESULT result = anchor->QueryInterface(IID_IUnknown, &instancePtr); michael@0: if (FAILED(result)) michael@0: return result; michael@0: michael@0: IUnknown* unknownPtr = static_cast(instancePtr); michael@0: aAnchor->ppunkVal = &unknownPtr; michael@0: aAnchor->vt = VT_UNKNOWN; michael@0: return S_OK; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aAnchorTarget) michael@0: return E_INVALIDARG; michael@0: michael@0: VariantInit(aAnchorTarget); michael@0: michael@0: Accessible* thisObj = static_cast(this); michael@0: if (thisObj->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: if (aIndex < 0 || aIndex >= static_cast(thisObj->AnchorCount())) michael@0: return E_INVALIDARG; michael@0: michael@0: if (!thisObj->IsLink()) michael@0: return S_FALSE; michael@0: michael@0: nsCOMPtr uri = thisObj->AnchorURIAt(aIndex); michael@0: if (!uri) michael@0: return S_FALSE; michael@0: michael@0: nsAutoCString prePath; michael@0: nsresult rv = uri->GetPrePath(prePath); michael@0: if (NS_FAILED(rv)) michael@0: return GetHRESULT(rv); michael@0: michael@0: nsAutoCString path; michael@0: rv = uri->GetPath(path); michael@0: if (NS_FAILED(rv)) michael@0: return GetHRESULT(rv); michael@0: michael@0: nsAutoString stringURI; michael@0: AppendUTF8toUTF16(prePath, stringURI); michael@0: AppendUTF8toUTF16(path, stringURI); michael@0: michael@0: aAnchorTarget->vt = VT_BSTR; michael@0: aAnchorTarget->bstrVal = ::SysAllocStringLen(stringURI.get(), michael@0: stringURI.Length()); michael@0: return aAnchorTarget->bstrVal ? S_OK : E_OUTOFMEMORY; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleHyperlink::get_startIndex(long* aIndex) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aIndex) michael@0: return E_INVALIDARG; michael@0: michael@0: *aIndex = 0; michael@0: michael@0: Accessible* thisObj = static_cast(this); michael@0: if (thisObj->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: if (!thisObj->IsLink()) michael@0: return S_FALSE; michael@0: michael@0: *aIndex = thisObj->StartOffset(); michael@0: return S_OK; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleHyperlink::get_endIndex(long* aIndex) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aIndex) michael@0: return E_INVALIDARG; michael@0: michael@0: *aIndex = 0; michael@0: michael@0: Accessible* thisObj = static_cast(this); michael@0: if (thisObj->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: if (!thisObj->IsLink()) michael@0: return S_FALSE; michael@0: michael@0: *aIndex = thisObj->EndOffset(); michael@0: return S_OK; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleHyperlink::get_valid(boolean* aValid) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aValid) michael@0: return E_INVALIDARG; michael@0: michael@0: *aValid = false; michael@0: michael@0: Accessible* thisObj = static_cast(this); michael@0: if (thisObj->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: if (!thisObj->IsLink()) michael@0: return S_FALSE; michael@0: michael@0: *aValid = thisObj->IsLinkValid(); michael@0: return S_OK; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: