2016-08-16 02:14:53 +03:00
|
|
|
/* -*- 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 "mozilla/a11y/DocAccessibleChildBase.h"
|
2021-08-26 22:40:04 +03:00
|
|
|
#include "mozilla/a11y/CacheConstants.h"
|
2021-02-20 02:14:33 +03:00
|
|
|
#include "mozilla/a11y/RemoteAccessible.h"
|
2021-06-08 10:20:53 +03:00
|
|
|
#include "mozilla/StaticPrefs_accessibility.h"
|
2016-08-16 02:14:53 +03:00
|
|
|
|
2021-02-20 02:14:32 +03:00
|
|
|
#include "LocalAccessible-inl.h"
|
2016-08-16 02:14:53 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace a11y {
|
|
|
|
|
2019-02-26 01:02:26 +03:00
|
|
|
/* static */
|
2021-08-17 21:17:38 +03:00
|
|
|
void DocAccessibleChildBase::FlattenTree(LocalAccessible* aRoot,
|
|
|
|
nsTArray<LocalAccessible*>& aTree) {
|
|
|
|
MOZ_ASSERT(!aRoot->IsDoc(), "documents shouldn't be serialized");
|
2016-08-16 02:14:53 +03:00
|
|
|
|
2021-08-17 21:17:38 +03:00
|
|
|
aTree.AppendElement(aRoot);
|
2016-08-16 02:14:53 +03:00
|
|
|
// OuterDocAccessibles are special because we don't want to serialize the
|
|
|
|
// child doc here, we'll call PDocAccessibleConstructor in
|
|
|
|
// NotificationController.
|
2021-08-17 21:17:38 +03:00
|
|
|
uint32_t childCount = aRoot->IsOuterDoc() ? 0 : aRoot->ChildCount();
|
2016-08-16 02:14:53 +03:00
|
|
|
|
2021-08-17 21:17:38 +03:00
|
|
|
for (uint32_t i = 0; i < childCount; i++) {
|
|
|
|
FlattenTree(aRoot->LocalChildAt(i), aTree);
|
2021-03-02 19:32:24 +03:00
|
|
|
}
|
2021-08-17 21:17:38 +03:00
|
|
|
}
|
2021-03-02 19:32:24 +03:00
|
|
|
|
2021-08-17 21:17:38 +03:00
|
|
|
/* static */
|
|
|
|
void DocAccessibleChildBase::SerializeTree(nsTArray<LocalAccessible*>& aTree,
|
|
|
|
nsTArray<AccessibleData>& aData) {
|
|
|
|
for (LocalAccessible* acc : aTree) {
|
|
|
|
uint64_t id = reinterpret_cast<uint64_t>(acc->UniqueID());
|
2016-08-16 02:14:53 +03:00
|
|
|
#if defined(XP_WIN)
|
2021-08-17 21:17:38 +03:00
|
|
|
int32_t msaaId = StaticPrefs::accessibility_cache_enabled_AtStartup()
|
|
|
|
? 0
|
|
|
|
: MsaaAccessible::GetChildIDFor(acc);
|
2016-08-16 02:14:53 +03:00
|
|
|
#endif
|
2021-08-17 21:17:38 +03:00
|
|
|
a11y::role role = acc->Role();
|
|
|
|
uint32_t childCount = acc->IsOuterDoc() ? 0 : acc->ChildCount();
|
2016-08-16 02:14:53 +03:00
|
|
|
|
2021-08-17 21:17:38 +03:00
|
|
|
uint32_t genericTypes = acc->mGenericTypes;
|
|
|
|
if (acc->ARIAHasNumericValue()) {
|
|
|
|
// XXX: We need to do this because this requires a state check.
|
|
|
|
genericTypes |= eNumericValue;
|
|
|
|
}
|
|
|
|
if (acc->ActionCount()) {
|
|
|
|
genericTypes |= eActionable;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
aData.AppendElement(AccessibleData(
|
|
|
|
id, msaaId, role, childCount, static_cast<AccType>(acc->mType),
|
|
|
|
static_cast<AccGenericType>(genericTypes), acc->mRoleMapEntryIndex));
|
|
|
|
#else
|
|
|
|
aData.AppendElement(AccessibleData(
|
|
|
|
id, role, childCount, static_cast<AccType>(acc->mType),
|
|
|
|
static_cast<AccGenericType>(genericTypes), acc->mRoleMapEntryIndex));
|
|
|
|
#endif
|
2016-08-16 02:14:53 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-20 02:14:32 +03:00
|
|
|
void DocAccessibleChildBase::InsertIntoIpcTree(LocalAccessible* aParent,
|
|
|
|
LocalAccessible* aChild,
|
2021-08-17 21:17:38 +03:00
|
|
|
uint32_t aIdxInParent,
|
|
|
|
bool aSuppressShowEvent) {
|
2017-10-03 17:58:27 +03:00
|
|
|
uint64_t parentID =
|
|
|
|
aParent->IsDoc() ? 0 : reinterpret_cast<uint64_t>(aParent->UniqueID());
|
2021-08-17 21:17:38 +03:00
|
|
|
nsTArray<LocalAccessible*> shownTree;
|
|
|
|
FlattenTree(aChild, shownTree);
|
|
|
|
ShowEventData data(parentID, aIdxInParent,
|
|
|
|
nsTArray<AccessibleData>(shownTree.Length()),
|
|
|
|
aSuppressShowEvent);
|
|
|
|
SerializeTree(shownTree, data.NewTree());
|
2017-10-03 17:58:27 +03:00
|
|
|
MaybeSendShowEvent(data, false);
|
2021-08-17 21:17:39 +03:00
|
|
|
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
|
|
|
|
nsTArray<CacheData> cache(shownTree.Length());
|
|
|
|
for (LocalAccessible* acc : shownTree) {
|
2021-08-26 22:40:04 +03:00
|
|
|
RefPtr<AccAttributes> fields =
|
2021-09-02 01:20:09 +03:00
|
|
|
acc->BundleFieldsForCache(CacheDomain::All, CacheUpdateType::Initial);
|
|
|
|
if (fields->Count()) {
|
|
|
|
uint64_t id = reinterpret_cast<uint64_t>(acc->UniqueID());
|
|
|
|
cache.AppendElement(CacheData(id, fields));
|
|
|
|
}
|
2021-08-17 21:17:39 +03:00
|
|
|
}
|
2021-09-01 23:32:17 +03:00
|
|
|
Unused << SendCache(CacheUpdateType::Initial, cache, true);
|
2021-08-17 21:17:39 +03:00
|
|
|
}
|
2017-10-03 17:58:27 +03:00
|
|
|
}
|
|
|
|
|
2016-08-16 02:14:53 +03:00
|
|
|
void DocAccessibleChildBase::ShowEvent(AccShowEvent* aShowEvent) {
|
2021-08-17 21:17:38 +03:00
|
|
|
LocalAccessible* child = aShowEvent->GetAccessible();
|
|
|
|
InsertIntoIpcTree(aShowEvent->LocalParent(), child, child->IndexInParent(),
|
|
|
|
false);
|
2016-08-16 02:14:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace a11y
|
|
|
|
} // namespace mozilla
|