2016-08-23 21:15:15 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* 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 "AccessibleNode.h"
|
|
|
|
#include "mozilla/dom/AccessibleNodeBinding.h"
|
|
|
|
#include "mozilla/dom/BindingDeclarations.h"
|
2016-12-14 01:36:19 +03:00
|
|
|
#include "mozilla/dom/DOMStringList.h"
|
2019-08-01 23:08:09 +03:00
|
|
|
#include "mozilla/StaticPrefs_accessibility.h"
|
2016-12-21 21:04:49 +03:00
|
|
|
#include "nsIPersistentProperties2.h"
|
2016-12-23 22:36:55 +03:00
|
|
|
#include "nsISimpleEnumerator.h"
|
2016-08-23 21:15:15 +03:00
|
|
|
|
|
|
|
#include "Accessible-inl.h"
|
|
|
|
#include "nsAccessibilityService.h"
|
|
|
|
#include "DocAccessible.h"
|
|
|
|
|
|
|
|
using namespace mozilla;
|
|
|
|
using namespace mozilla::a11y;
|
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
2018-05-28 20:40:41 +03:00
|
|
|
bool AccessibleNode::IsAOMEnabled(JSContext* aCx, JSObject* /*unused*/) {
|
2019-08-01 23:08:09 +03:00
|
|
|
return nsContentUtils::IsSystemCaller(aCx) ||
|
|
|
|
StaticPrefs::accessibility_AOM_enabled();
|
2018-05-28 20:40:41 +03:00
|
|
|
}
|
|
|
|
|
2018-08-04 13:47:50 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AccessibleNode, mRelationProperties,
|
|
|
|
mIntl, mDOMNode, mStates)
|
2016-08-23 21:15:15 +03:00
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AccessibleNode)
|
|
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
|
|
|
|
|
2018-07-06 12:29:49 +03:00
|
|
|
AccessibleNode::AccessibleNode(nsINode* aNode)
|
2018-07-21 21:45:22 +03:00
|
|
|
: mDoubleProperties(3),
|
|
|
|
mIntProperties(3),
|
|
|
|
mUIntProperties(6),
|
2018-07-06 12:29:49 +03:00
|
|
|
mBooleanProperties(0),
|
2018-07-17 02:37:37 +03:00
|
|
|
mRelationProperties(3),
|
2018-07-13 15:33:51 +03:00
|
|
|
mStringProperties(16),
|
2018-07-06 12:29:49 +03:00
|
|
|
mDOMNode(aNode) {
|
2017-11-29 00:02:04 +03:00
|
|
|
nsAccessibilityService* accService = GetOrCreateAccService();
|
|
|
|
if (!accService) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DocAccessible* doc = accService->GetDocAccessible(mDOMNode->OwnerDoc());
|
2016-08-23 21:15:15 +03:00
|
|
|
if (doc) {
|
|
|
|
mIntl = doc->GetAccessible(mDOMNode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AccessibleNode::~AccessibleNode() {}
|
|
|
|
|
2019-02-26 01:02:26 +03:00
|
|
|
/* virtual */
|
|
|
|
JSObject* AccessibleNode::WrapObject(JSContext* aCx,
|
|
|
|
JS::Handle<JSObject*> aGivenProto) {
|
2018-06-26 00:20:54 +03:00
|
|
|
return AccessibleNode_Binding::Wrap(aCx, this, aGivenProto);
|
2016-08-23 21:15:15 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:02:26 +03:00
|
|
|
/* virtual */
|
|
|
|
ParentObject AccessibleNode::GetParentObject() const {
|
2016-08-23 21:15:15 +03:00
|
|
|
return mDOMNode->GetParentObject();
|
|
|
|
}
|
|
|
|
|
2018-07-13 15:33:51 +03:00
|
|
|
void AccessibleNode::GetComputedRole(nsAString& aRole) {
|
2016-08-23 21:15:15 +03:00
|
|
|
if (mIntl) {
|
2017-11-29 00:02:04 +03:00
|
|
|
nsAccessibilityService* accService = GetOrCreateAccService();
|
|
|
|
if (accService) {
|
|
|
|
accService->GetStringRole(mIntl->Role(), aRole);
|
|
|
|
return;
|
|
|
|
}
|
2016-08-23 21:15:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
aRole.AssignLiteral("unknown");
|
|
|
|
}
|
|
|
|
|
2016-12-14 01:36:19 +03:00
|
|
|
void AccessibleNode::GetStates(nsTArray<nsString>& aStates) {
|
2017-11-29 00:02:04 +03:00
|
|
|
nsAccessibilityService* accService = GetOrCreateAccService();
|
|
|
|
if (!mIntl || !accService) {
|
2020-07-01 11:29:29 +03:00
|
|
|
aStates.AppendElement(u"defunct"_ns);
|
2017-11-29 00:02:04 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mStates) {
|
2020-04-30 12:36:14 +03:00
|
|
|
aStates = mStates->StringArray().Clone();
|
2016-12-14 01:36:19 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-11-29 00:02:04 +03:00
|
|
|
mStates = accService->GetStringStates(mIntl->State());
|
2020-04-30 12:36:14 +03:00
|
|
|
aStates = mStates->StringArray().Clone();
|
2016-12-14 01:36:19 +03:00
|
|
|
}
|
|
|
|
|
2016-12-23 22:36:55 +03:00
|
|
|
void AccessibleNode::GetAttributes(nsTArray<nsString>& aAttributes) {
|
|
|
|
if (!mIntl) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPersistentProperties> attrs = mIntl->Attributes();
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> props;
|
|
|
|
attrs->Enumerate(getter_AddRefs(props));
|
|
|
|
|
|
|
|
bool hasMore = false;
|
|
|
|
while (NS_SUCCEEDED(props->HasMoreElements(&hasMore)) && hasMore) {
|
|
|
|
nsCOMPtr<nsISupports> supp;
|
|
|
|
props->GetNext(getter_AddRefs(supp));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPropertyElement> prop(do_QueryInterface(supp));
|
|
|
|
|
|
|
|
nsAutoCString attr;
|
|
|
|
prop->GetKey(attr);
|
|
|
|
aAttributes.AppendElement(NS_ConvertUTF8toUTF16(attr));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-15 22:37:27 +03:00
|
|
|
bool AccessibleNode::Is(const Sequence<nsString>& aFlavors) {
|
2017-11-29 00:02:04 +03:00
|
|
|
nsAccessibilityService* accService = GetOrCreateAccService();
|
|
|
|
if (!mIntl || !accService) {
|
2016-12-15 22:37:27 +03:00
|
|
|
for (const auto& flavor : aFlavors) {
|
|
|
|
if (!flavor.EqualsLiteral("unknown") &&
|
|
|
|
!flavor.EqualsLiteral("defunct")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString role;
|
2017-11-29 00:02:04 +03:00
|
|
|
accService->GetStringRole(mIntl->Role(), role);
|
2016-12-15 22:37:27 +03:00
|
|
|
|
|
|
|
if (!mStates) {
|
2017-11-29 00:02:04 +03:00
|
|
|
mStates = accService->GetStringStates(mIntl->State());
|
2016-12-15 22:37:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto& flavor : aFlavors) {
|
|
|
|
if (!flavor.Equals(role) && !mStates->Contains(flavor)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-12-22 15:47:49 +03:00
|
|
|
bool AccessibleNode::Has(const Sequence<nsString>& aAttributes) {
|
|
|
|
if (!mIntl) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIPersistentProperties> attrs = mIntl->Attributes();
|
|
|
|
for (const auto& attr : aAttributes) {
|
|
|
|
bool has = false;
|
|
|
|
attrs->Has(NS_ConvertUTF16toUTF8(attr).get(), &has);
|
|
|
|
if (!has) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-12-21 21:04:49 +03:00
|
|
|
void AccessibleNode::Get(JSContext* aCX, const nsAString& aAttribute,
|
|
|
|
JS::MutableHandle<JS::Value> aValue,
|
|
|
|
ErrorResult& aRv) {
|
|
|
|
if (!mIntl) {
|
2020-02-05 06:11:50 +03:00
|
|
|
aRv.ThrowInvalidStateError("No attributes available");
|
2017-02-28 22:43:50 +03:00
|
|
|
return;
|
2016-12-21 21:04:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPersistentProperties> attrs = mIntl->Attributes();
|
|
|
|
nsAutoString value;
|
|
|
|
attrs->GetStringProperty(NS_ConvertUTF16toUTF8(aAttribute), value);
|
|
|
|
|
2020-02-05 06:11:50 +03:00
|
|
|
if (!ToJSValue(aCX, value, aValue)) {
|
|
|
|
aRv.NoteJSContextException(aCX);
|
2017-02-28 22:43:50 +03:00
|
|
|
return;
|
2016-12-21 21:04:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-23 21:15:15 +03:00
|
|
|
nsINode* AccessibleNode::GetDOMNode() { return mDOMNode; }
|