зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322532: Add support for live regions to the com handler dll; r=tbsaunde
MozReview-Commit-ID: 1JPaUw5PrxU --HG-- extra : rebase_source : e74cf6b3a2e9d78a3e939231ea06e0e3088fd538
This commit is contained in:
Родитель
c279528885
Коммит
ba24d548f9
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "AccessibleHandler.h"
|
||||
#include "AccessibleHandlerControl.h"
|
||||
#include "AccessibleTextTearoff.h"
|
||||
|
||||
#include "Factory.h"
|
||||
#include "HandlerData.h"
|
||||
|
@ -183,6 +184,12 @@ AccessibleHandler::QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if (aIid == IID_IAccessibleText || aIid == IID_IAccessibleHypertext) {
|
||||
RefPtr<IAccessibleHypertext> textTearoff(new AccessibleTextTearoff(this));
|
||||
textTearoff.forget(aOutInterface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (aIid == IID_IProvideClassInfo) {
|
||||
RefPtr<IProvideClassInfo> clsInfo(this);
|
||||
clsInfo.forget(aOutInterface);
|
||||
|
|
|
@ -22,6 +22,103 @@ namespace a11y {
|
|||
|
||||
mscom::SingletonFactory<AccessibleHandlerControl> gControlFactory;
|
||||
|
||||
namespace detail {
|
||||
|
||||
TextChange::TextChange()
|
||||
: mIA2UniqueId(0)
|
||||
, mIsInsert(false)
|
||||
, mText()
|
||||
{
|
||||
}
|
||||
|
||||
TextChange::TextChange(long aIA2UniqueId, bool aIsInsert,
|
||||
NotNull<IA2TextSegment*> aText)
|
||||
: mIA2UniqueId(aIA2UniqueId)
|
||||
, mIsInsert(aIsInsert)
|
||||
, mText{BSTRCopy(aText->text), aText->start, aText->end}
|
||||
{
|
||||
}
|
||||
|
||||
TextChange::TextChange(TextChange&& aOther)
|
||||
: mText()
|
||||
{
|
||||
*this = Move(aOther);
|
||||
}
|
||||
|
||||
TextChange::TextChange(const TextChange& aOther)
|
||||
: mText()
|
||||
{
|
||||
*this = aOther;
|
||||
}
|
||||
|
||||
TextChange&
|
||||
TextChange::operator=(TextChange&& aOther)
|
||||
{
|
||||
mIA2UniqueId = aOther.mIA2UniqueId;
|
||||
mIsInsert = aOther.mIsInsert;
|
||||
aOther.mIA2UniqueId = 0;
|
||||
::SysFreeString(mText.text);
|
||||
mText = aOther.mText;
|
||||
aOther.mText.text = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TextChange&
|
||||
TextChange::operator=(const TextChange& aOther)
|
||||
{
|
||||
mIA2UniqueId = aOther.mIA2UniqueId;
|
||||
mIsInsert = aOther.mIsInsert;
|
||||
::SysFreeString(mText.text);
|
||||
mText = {BSTRCopy(aOther.mText.text), aOther.mText.start, aOther.mText.end};
|
||||
return *this;
|
||||
}
|
||||
|
||||
TextChange::~TextChange()
|
||||
{
|
||||
::SysFreeString(mText.text);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
TextChange::GetOld(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutOldSegment)
|
||||
{
|
||||
if (mIsInsert || aIA2UniqueId != mIA2UniqueId) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return SegCopy(*aOutOldSegment, mText);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
TextChange::GetNew(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutNewSegment)
|
||||
{
|
||||
if (!mIsInsert || aIA2UniqueId != mIA2UniqueId) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return SegCopy(*aOutNewSegment, mText);
|
||||
}
|
||||
|
||||
/* static */ BSTR
|
||||
TextChange::BSTRCopy(const BSTR& aIn)
|
||||
{
|
||||
return ::SysAllocStringLen(aIn, ::SysStringLen(aIn));
|
||||
}
|
||||
|
||||
/* static */ HRESULT
|
||||
TextChange::SegCopy(IA2TextSegment& aDest, const IA2TextSegment& aSrc)
|
||||
{
|
||||
aDest = {BSTRCopy(aSrc.text), aSrc.start, aSrc.end};
|
||||
if (aSrc.text && !aDest.text) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!::SysStringLen(aDest.text)) {
|
||||
return S_FALSE;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
HRESULT
|
||||
AccessibleHandlerControl::Create(AccessibleHandlerControl** aOutObject)
|
||||
{
|
||||
|
@ -35,46 +132,14 @@ AccessibleHandlerControl::Create(AccessibleHandlerControl** aOutObject)
|
|||
}
|
||||
|
||||
AccessibleHandlerControl::AccessibleHandlerControl()
|
||||
: mRefCnt(0)
|
||||
, mCacheGen(0)
|
||||
: mCacheGen(0)
|
||||
, mIA2Proxy(mscom::RegisterProxy(L"ia2marshal.dll"))
|
||||
, mHandlerProxy(mscom::RegisterProxy())
|
||||
{
|
||||
MOZ_ASSERT(mIA2Proxy);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleHandlerControl::QueryInterface(REFIID aIid, void** aOutInterface)
|
||||
{
|
||||
if (!aOutInterface) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (aIid == IID_IUnknown || aIid == IID_IHandlerControl) {
|
||||
RefPtr<IHandlerControl> ctl(this);
|
||||
ctl.forget(aOutInterface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*aOutInterface = nullptr;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG
|
||||
AccessibleHandlerControl::AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
|
||||
ULONG
|
||||
AccessibleHandlerControl::Release()
|
||||
{
|
||||
ULONG result = --mRefCnt;
|
||||
if (!result) {
|
||||
delete this;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
IMPL_IUNKNOWN1(AccessibleHandlerControl, IHandlerControl)
|
||||
|
||||
HRESULT
|
||||
AccessibleHandlerControl::Invalidate()
|
||||
|
@ -83,6 +148,36 @@ AccessibleHandlerControl::Invalidate()
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleHandlerControl::OnTextChange(long aHwnd, long aIA2UniqueId,
|
||||
VARIANT_BOOL aIsInsert,
|
||||
IA2TextSegment* aText)
|
||||
{
|
||||
if (!aText) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
mTextChange = detail::TextChange(aIA2UniqueId, aIsInsert, WrapNotNull(aText));
|
||||
NotifyWinEvent(aIsInsert ? IA2_EVENT_TEXT_INSERTED : IA2_EVENT_TEXT_REMOVED,
|
||||
reinterpret_cast<HWND>(static_cast<uintptr_t>(aHwnd)),
|
||||
OBJID_CLIENT, aIA2UniqueId);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleHandlerControl::GetNewText(long aIA2UniqueId,
|
||||
NotNull<IA2TextSegment*> aOutNewText)
|
||||
{
|
||||
return mTextChange.GetNew(aIA2UniqueId, aOutNewText);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleHandlerControl::GetOldText(long aIA2UniqueId,
|
||||
NotNull<IA2TextSegment*> aOutOldText)
|
||||
{
|
||||
return mTextChange.GetOld(aIA2UniqueId, aOutOldText);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleHandlerControl::GetHandlerTypeInfo(ITypeInfo** aOutTypeInfo)
|
||||
{
|
||||
|
|
|
@ -13,37 +13,70 @@
|
|||
|
||||
#include "Factory.h"
|
||||
#include "HandlerData.h"
|
||||
#include "IUnknownImpl.h"
|
||||
#include "mozilla/mscom/Registration.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class TextChange final
|
||||
{
|
||||
public:
|
||||
TextChange();
|
||||
TextChange(long aIA2UniqueId, bool aIsInsert, NotNull<IA2TextSegment*> aText);
|
||||
TextChange(TextChange&& aOther);
|
||||
TextChange(const TextChange& aOther);
|
||||
|
||||
TextChange& operator=(TextChange&& aOther);
|
||||
TextChange& operator=(const TextChange& aOther);
|
||||
|
||||
~TextChange();
|
||||
|
||||
HRESULT GetOld(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutOldSegment);
|
||||
HRESULT GetNew(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutNewSegment);
|
||||
|
||||
private:
|
||||
static BSTR BSTRCopy(const BSTR& aIn);
|
||||
static HRESULT SegCopy(IA2TextSegment& aDest, const IA2TextSegment& aSrc);
|
||||
|
||||
long mIA2UniqueId;
|
||||
bool mIsInsert;
|
||||
IA2TextSegment mText;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class AccessibleHandlerControl final : public IHandlerControl
|
||||
{
|
||||
public:
|
||||
static HRESULT Create(AccessibleHandlerControl** aOutObject);
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
|
||||
STDMETHODIMP_(ULONG) AddRef() override;
|
||||
STDMETHODIMP_(ULONG) Release() override;
|
||||
DECL_IUNKNOWN
|
||||
|
||||
// IHandlerControl
|
||||
STDMETHODIMP Invalidate() override;
|
||||
STDMETHODIMP OnTextChange(long aHwnd, long aIA2UniqueId,
|
||||
VARIANT_BOOL aIsInsert, IA2TextSegment* aText) override;
|
||||
|
||||
uint32_t GetCacheGen() const
|
||||
{
|
||||
return mCacheGen;
|
||||
}
|
||||
|
||||
HRESULT GetNewText(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutNewText);
|
||||
HRESULT GetOldText(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutOldText);
|
||||
|
||||
HRESULT GetHandlerTypeInfo(ITypeInfo** aOutTypeInfo);
|
||||
|
||||
private:
|
||||
AccessibleHandlerControl();
|
||||
~AccessibleHandlerControl() = default;
|
||||
|
||||
ULONG mRefCnt;
|
||||
uint32_t mCacheGen;
|
||||
detail::TextChange mTextChange;
|
||||
UniquePtr<mscom::RegisteredProxy> mIA2Proxy;
|
||||
UniquePtr<mscom::RegisteredProxy> mHandlerProxy;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,359 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
#error This code is NOT for internal Gecko use!
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
#include "AccessibleTextTearoff.h"
|
||||
|
||||
#include "AccessibleHandlerControl.h"
|
||||
#include "AccessibleText_i.c"
|
||||
#include "AccessibleHypertext_i.c"
|
||||
#include "Factory.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
AccessibleTextTearoff::AccessibleTextTearoff(AccessibleHandler* aHandler)
|
||||
: mHandler(aHandler)
|
||||
{
|
||||
MOZ_ASSERT(aHandler);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::ResolveAccText()
|
||||
{
|
||||
if (mAccTextProxy) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RefPtr<IUnknown> proxy(mHandler->GetProxy());
|
||||
if (!proxy) {
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
return proxy->QueryInterface(IID_IAccessibleText,
|
||||
getter_AddRefs(mAccTextProxy));
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::ResolveAccHypertext()
|
||||
{
|
||||
if (mAccHypertextProxy) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RefPtr<IUnknown> proxy(mHandler->GetProxy());
|
||||
if (!proxy) {
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
return proxy->QueryInterface(IID_IAccessibleHypertext,
|
||||
getter_AddRefs(mAccHypertextProxy));
|
||||
}
|
||||
|
||||
IMPL_IUNKNOWN_QUERY_HEAD(AccessibleTextTearoff)
|
||||
IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleText)
|
||||
IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleHypertext)
|
||||
IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mHandler)
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::addSelection(long startOffset, long endOffset)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->addSelection(startOffset, endOffset);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_attributes(long offset, long *startOffset,
|
||||
long *endOffset, BSTR *textAttributes)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_attributes(offset, startOffset, endOffset,
|
||||
textAttributes);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_caretOffset(long *offset)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_caretOffset(offset);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_characterExtents(long offset,
|
||||
enum IA2CoordinateType coordType,
|
||||
long *x, long *y, long *width,
|
||||
long *height)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_characterExtents(offset, coordType, x, y, width,
|
||||
height);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_nSelections(long *nSelections)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_nSelections(nSelections);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_offsetAtPoint(long x, long y,
|
||||
enum IA2CoordinateType coordType,
|
||||
long *offset)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_offsetAtPoint(x, y, coordType, offset);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_selection(long selectionIndex, long *startOffset,
|
||||
long *endOffset)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_selection(selectionIndex, startOffset, endOffset);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_text(long startOffset, long endOffset, BSTR *text)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_text(startOffset, endOffset, text);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_textBeforeOffset(long offset,
|
||||
enum IA2TextBoundaryType boundaryType,
|
||||
long *startOffset, long *endOffset,
|
||||
BSTR *text)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_textBeforeOffset(offset, boundaryType, startOffset,
|
||||
endOffset, text);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_textAfterOffset(long offset,
|
||||
enum IA2TextBoundaryType boundaryType,
|
||||
long *startOffset, long *endOffset,
|
||||
BSTR *text)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_textAfterOffset(offset, boundaryType,
|
||||
startOffset, endOffset, text);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_textAtOffset(long offset,
|
||||
enum IA2TextBoundaryType boundaryType,
|
||||
long *startOffset, long *endOffset,
|
||||
BSTR *text)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_textAtOffset(offset, boundaryType, startOffset,
|
||||
endOffset, text);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::removeSelection(long selectionIndex)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->removeSelection(selectionIndex);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::setCaretOffset(long offset)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->setCaretOffset(offset);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::setSelection(long selectionIndex, long startOffset,
|
||||
long endOffset)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->setSelection(selectionIndex, startOffset, endOffset);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_nCharacters(long *nCharacters)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->get_nCharacters(nCharacters);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::scrollSubstringTo(long startIndex, long endIndex,
|
||||
enum IA2ScrollType scrollType)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->scrollSubstringTo(startIndex, endIndex, scrollType);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::scrollSubstringToPoint(long startIndex, long endIndex,
|
||||
enum IA2CoordinateType coordinateType,
|
||||
long x, long y)
|
||||
{
|
||||
HRESULT hr = ResolveAccText();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccTextProxy->scrollSubstringToPoint(startIndex, endIndex,
|
||||
coordinateType, x, y);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_newText(IA2TextSegment *newText)
|
||||
{
|
||||
if (!newText) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetSingleton());
|
||||
MOZ_ASSERT(ctl);
|
||||
if (!ctl) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
long id;
|
||||
HRESULT hr = mHandler->get_uniqueID(&id);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return ctl->GetNewText(id, WrapNotNull(newText));
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_oldText(IA2TextSegment *oldText)
|
||||
{
|
||||
if (!oldText) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetSingleton());
|
||||
MOZ_ASSERT(ctl);
|
||||
if (!ctl) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
long id;
|
||||
HRESULT hr = mHandler->get_uniqueID(&id);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return ctl->GetOldText(id, WrapNotNull(oldText));
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_nHyperlinks(long *hyperlinkCount)
|
||||
{
|
||||
HRESULT hr = ResolveAccHypertext();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccHypertextProxy->get_nHyperlinks(hyperlinkCount);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_hyperlink(long index,
|
||||
IAccessibleHyperlink **hyperlink)
|
||||
{
|
||||
HRESULT hr = ResolveAccHypertext();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccHypertextProxy->get_hyperlink(index, hyperlink);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AccessibleTextTearoff::get_hyperlinkIndex(long charIndex, long *hyperlinkIndex)
|
||||
{
|
||||
HRESULT hr = ResolveAccHypertext();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return mAccHypertextProxy->get_hyperlinkIndex(charIndex, hyperlinkIndex);
|
||||
}
|
||||
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,88 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
#error This code is NOT for internal Gecko use!
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
#ifndef mozilla_a11y_AccessibleTextTearoff_h
|
||||
#define mozilla_a11y_AccessibleTextTearoff_h
|
||||
|
||||
#include "AccessibleHandler.h"
|
||||
#include "AccessibleHypertext.h"
|
||||
#include "IUnknownImpl.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class AccessibleTextTearoff final : public IAccessibleHypertext
|
||||
{
|
||||
public:
|
||||
explicit AccessibleTextTearoff(AccessibleHandler* aHandler);
|
||||
|
||||
DECL_IUNKNOWN
|
||||
|
||||
// IAccessibleText
|
||||
STDMETHODIMP addSelection(long startOffset, long endOffset) override;
|
||||
STDMETHODIMP get_attributes(long offset, long *startOffset, long *endOffset,
|
||||
BSTR *textAttributes) override;
|
||||
STDMETHODIMP get_caretOffset(long *offset) override;
|
||||
STDMETHODIMP get_characterExtents(long offset,
|
||||
enum IA2CoordinateType coordType, long *x,
|
||||
long *y, long *width, long *height) override;
|
||||
STDMETHODIMP get_nSelections(long *nSelections) override;
|
||||
STDMETHODIMP get_offsetAtPoint(long x, long y,
|
||||
enum IA2CoordinateType coordType,
|
||||
long *offset) override;
|
||||
STDMETHODIMP get_selection(long selectionIndex, long *startOffset,
|
||||
long *endOffset) override;
|
||||
STDMETHODIMP get_text(long startOffset, long endOffset, BSTR *text) override;
|
||||
STDMETHODIMP get_textBeforeOffset(long offset,
|
||||
enum IA2TextBoundaryType boundaryType,
|
||||
long *startOffset, long *endOffset,
|
||||
BSTR *text) override;
|
||||
STDMETHODIMP get_textAfterOffset(long offset,
|
||||
enum IA2TextBoundaryType boundaryType,
|
||||
long *startOffset, long *endOffset,
|
||||
BSTR *text) override;
|
||||
STDMETHODIMP get_textAtOffset(long offset,
|
||||
enum IA2TextBoundaryType boundaryType,
|
||||
long *startOffset, long *endOffset,
|
||||
BSTR *text) override;
|
||||
STDMETHODIMP removeSelection(long selectionIndex) override;
|
||||
STDMETHODIMP setCaretOffset(long offset) override;
|
||||
STDMETHODIMP setSelection(long selectionIndex, long startOffset,
|
||||
long endOffset) override;
|
||||
STDMETHODIMP get_nCharacters(long *nCharacters) override;
|
||||
STDMETHODIMP scrollSubstringTo(long startIndex, long endIndex,
|
||||
enum IA2ScrollType scrollType) override;
|
||||
STDMETHODIMP scrollSubstringToPoint(long startIndex, long endIndex,
|
||||
enum IA2CoordinateType coordinateType,
|
||||
long x, long y) override;
|
||||
STDMETHODIMP get_newText(IA2TextSegment *newText) override;
|
||||
STDMETHODIMP get_oldText(IA2TextSegment *oldText) override;
|
||||
|
||||
// IAccessibleHypertext
|
||||
STDMETHODIMP get_nHyperlinks(long *hyperlinkCount) override;
|
||||
STDMETHODIMP get_hyperlink(long index,
|
||||
IAccessibleHyperlink **hyperlink) override;
|
||||
STDMETHODIMP get_hyperlinkIndex(long charIndex, long *hyperlinkIndex) override;
|
||||
|
||||
private:
|
||||
~AccessibleTextTearoff() = default;
|
||||
HRESULT ResolveAccText();
|
||||
HRESULT ResolveAccHypertext();
|
||||
|
||||
RefPtr<AccessibleHandler> mHandler;
|
||||
RefPtr<IAccessibleText> mAccTextProxy;
|
||||
RefPtr<IAccessibleHypertext> mAccHypertextProxy;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_a11y_AccessibleTextTearoff_h
|
|
@ -9,6 +9,8 @@
|
|||
import "ocidl.idl";
|
||||
import "ServProv.idl";
|
||||
|
||||
import "AccessibleText.idl";
|
||||
|
||||
typedef struct _IA2Data
|
||||
{
|
||||
long mUniqueId;
|
||||
|
@ -84,6 +86,9 @@ interface HandlerData
|
|||
interface IHandlerControl : IUnknown
|
||||
{
|
||||
HRESULT Invalidate();
|
||||
HRESULT OnTextChange([in] long aHwnd, [in] long aIA2UniqueId,
|
||||
[in] VARIANT_BOOL aIsInsert,
|
||||
[in] IA2TextSegment* aText);
|
||||
}
|
||||
|
||||
[object,
|
||||
|
|
|
@ -20,6 +20,7 @@ SOURCES += [
|
|||
'!HandlerData_p.c',
|
||||
'AccessibleHandler.cpp',
|
||||
'AccessibleHandlerControl.cpp',
|
||||
'AccessibleTextTearoff.cpp',
|
||||
]
|
||||
|
||||
GENERATED_FILES += [
|
||||
|
|
Загрузка…
Ссылка в новой задаче