gecko-dev/accessible/xpcom/xpcAccessibleDocument.cpp
James Teh 196146ecb6 Bug 1756728 part 2: Support retrieving the URL for cached remote documents. r=morgan
The BrowsingContext already has this information, so we use that instead of redundantly caching it in RemoteAccessible.
This implementation works even when the a11y cache is disabled, so stop using the sync IPDL URL method.
We can't entirely unify the URL method because we don't have a base class for local/remote documents.
However, a method was added in nsAccUtils to unify this as much as possible.

Differential Revision: https://phabricator.services.mozilla.com/D147717
2022-06-01 00:34:17 +00:00

192 lines
5.3 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 "nsAccUtils.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 && mCache.Count() == 0) {
if (mIntl->IsLocal()) {
GetAccService()->RemoveFromXPCDocumentCache(mIntl->AsLocal()->AsDoc());
} else {
GetAccService()->RemoveFromRemoteXPCDocumentCache(
mIntl->AsRemote()->AsDoc());
}
}
return r;
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleDocument
NS_IMETHODIMP
xpcAccessibleDocument::GetURL(nsAString& aURL) {
if (!mIntl) return NS_ERROR_FAILURE;
nsAccUtils::DocumentURL(mIntl, 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) {
if (aAccessible->IsLocal() &&
ToXPCDocument(aAccessible->AsLocal()->Document()) != this) {
NS_ERROR(
"This XPCOM document is not related with given internal accessible!");
return nullptr;
}
if (aAccessible->IsRemote() &&
ToXPCDocument(aAccessible->AsRemote()->Document()) != this) {
NS_ERROR(
"This XPCOM document is not related with given internal accessible!");
return nullptr;
}
if (aAccessible->IsDoc()) return this;
return mCache.LookupOrInsertWith(aAccessible, [&]() -> xpcAccessibleGeneric* {
if (aAccessible->IsImage()) {
return new xpcAccessibleImage(aAccessible);
}
if (aAccessible->IsTable()) {
return new xpcAccessibleTable(aAccessible);
}
if (aAccessible->IsTableCell()) {
return new xpcAccessibleTableCell(aAccessible);
}
if (aAccessible->IsHyperText()) {
return new xpcAccessibleHyperText(aAccessible);
}
return new xpcAccessibleGeneric(aAccessible);
});
}
void xpcAccessibleDocument::Shutdown() {
for (auto iter = mCache.Iter(); !iter.Done(); iter.Next()) {
iter.Data()->Shutdown();
iter.Remove();
}
xpcAccessibleGeneric::Shutdown();
}