gecko-dev/accessible/xpcom/xpcAccessibleDocument.cpp

235 строки
6.1 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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/. */
#include "xpcAccessibleDocument.h"
#include "xpcAccessibleImage.h"
#include "xpcAccessibleTable.h"
#include "xpcAccessibleTableCell.h"
#include "mozilla/a11y/DocAccessibleParent.h"
#include "DocAccessible-inl.h"
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_QUERY_INTERFACE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText,
nsIAccessibleDocument)
NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
NS_IMETHODIMP_(MozExternalRefCountType) xpcAccessibleDocument::Release(void) {
nsrefcnt r = xpcAccessibleHyperText::Release();
NS_LOG_RELEASE(this, r, "xpcAccessibleDocument");
// The only reference to the xpcAccessibleDocument is in DocManager's cache.
if (r == 1 && !mIntl.IsNull() && mCache.Count() == 0) {
if (mIntl.IsAccessible()) {
GetAccService()->RemoveFromXPCDocumentCache(
mIntl.AsAccessible()->AsDoc());
} else {
GetAccService()->RemoveFromRemoteXPCDocumentCache(
mIntl.AsProxy()->AsDoc());
}
}
return r;
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleDocument
NS_IMETHODIMP
xpcAccessibleDocument::GetURL(nsAString& aURL) {
if (!Intl()) return NS_ERROR_FAILURE;
Intl()->URL(aURL);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetTitle(nsAString& aTitle) {
if (!Intl()) return NS_ERROR_FAILURE;
nsAutoString title;
Intl()->Title(title);
aTitle = title;
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetMimeType(nsAString& aType) {
if (!Intl()) return NS_ERROR_FAILURE;
Intl()->MimeType(aType);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetDocType(nsAString& aType) {
if (!Intl()) return NS_ERROR_FAILURE;
Intl()->DocType(aType);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetDOMDocument(dom::Document** aDOMDocument) {
NS_ENSURE_ARG_POINTER(aDOMDocument);
*aDOMDocument = nullptr;
if (!Intl()) return NS_ERROR_FAILURE;
if (Intl()->DocumentNode()) NS_ADDREF(*aDOMDocument = Intl()->DocumentNode());
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetWindow(mozIDOMWindowProxy** aDOMWindow) {
NS_ENSURE_ARG_POINTER(aDOMWindow);
*aDOMWindow = nullptr;
if (!Intl()) return NS_ERROR_FAILURE;
NS_IF_ADDREF(*aDOMWindow = Intl()->DocumentNode()->GetWindow());
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetParentDocument(nsIAccessibleDocument** aDocument) {
NS_ENSURE_ARG_POINTER(aDocument);
*aDocument = nullptr;
if (!Intl()) return NS_ERROR_FAILURE;
NS_IF_ADDREF(*aDocument = ToXPCDocument(Intl()->ParentDocument()));
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetChildDocumentCount(uint32_t* aCount) {
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
if (!Intl()) return NS_ERROR_FAILURE;
*aCount = Intl()->ChildDocumentCount();
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetChildDocumentAt(uint32_t aIndex,
nsIAccessibleDocument** aDocument) {
NS_ENSURE_ARG_POINTER(aDocument);
*aDocument = nullptr;
if (!Intl()) return NS_ERROR_FAILURE;
NS_IF_ADDREF(*aDocument = ToXPCDocument(Intl()->GetChildDocumentAt(aIndex)));
return *aDocument ? NS_OK : NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor) {
NS_ENSURE_ARG_POINTER(aVirtualCursor);
*aVirtualCursor = nullptr;
if (!Intl()) return NS_ERROR_FAILURE;
NS_ADDREF(*aVirtualCursor = Intl()->VirtualCursor());
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// xpcAccessibleDocument
xpcAccessibleGeneric* xpcAccessibleDocument::GetAccessible(
Accessible* aAccessible) {
MOZ_ASSERT(!mRemote);
if (ToXPCDocument(aAccessible->Document()) != this) {
NS_ERROR(
"This XPCOM document is not related with given internal accessible!");
return nullptr;
}
if (aAccessible->IsDoc()) return this;
xpcAccessibleGeneric* xpcAcc = mCache.Get(aAccessible);
if (xpcAcc) return xpcAcc;
if (aAccessible->IsImage())
xpcAcc = new xpcAccessibleImage(aAccessible);
else if (aAccessible->IsTable())
xpcAcc = new xpcAccessibleTable(aAccessible);
else if (aAccessible->IsTableCell())
xpcAcc = new xpcAccessibleTableCell(aAccessible);
else if (aAccessible->IsHyperText())
xpcAcc = new xpcAccessibleHyperText(aAccessible);
else
xpcAcc = new xpcAccessibleGeneric(aAccessible);
mCache.Put(aAccessible, xpcAcc);
return xpcAcc;
}
xpcAccessibleGeneric* xpcAccessibleDocument::GetXPCAccessible(
ProxyAccessible* aProxy) {
MOZ_ASSERT(mRemote);
MOZ_ASSERT(aProxy->Document() == mIntl.AsProxy());
if (aProxy->IsDoc()) {
return this;
}
xpcAccessibleGeneric* acc = mCache.Get(aProxy);
if (acc) {
return acc;
}
// XXX support exposing optional interfaces.
uint8_t interfaces = 0;
if (aProxy->mHasValue) {
interfaces |= eValue;
}
if (aProxy->mIsHyperLink) {
interfaces |= eHyperLink;
}
if (aProxy->mIsHyperText) {
interfaces |= eText;
acc = new xpcAccessibleHyperText(aProxy, interfaces);
mCache.Put(aProxy, acc);
return acc;
}
acc = new xpcAccessibleGeneric(aProxy, interfaces);
mCache.Put(aProxy, acc);
return acc;
}
void xpcAccessibleDocument::Shutdown() {
for (auto iter = mCache.Iter(); !iter.Done(); iter.Next()) {
iter.Data()->Shutdown();
iter.Remove();
}
xpcAccessibleGeneric::Shutdown();
}
xpcAccessibleGeneric* a11y::ToXPC(AccessibleOrProxy aAcc) {
if (aAcc.IsNull()) {
return nullptr;
}
if (aAcc.IsAccessible()) {
return ToXPC(aAcc.AsAccessible());
}
xpcAccessibleDocument* doc = ToXPCDocument(aAcc.AsProxy()->Document());
return doc->GetXPCAccessible(aAcc.AsProxy());
}