Bug 1714390 - P7: Add custom de/serializer for AccAttributes. r=Jamie

Differential Revision: https://phabricator.services.mozilla.com/D116788
This commit is contained in:
Eitan Isaacson 2021-06-10 23:07:07 +00:00
Родитель 349592fb91
Коммит 6ac35e15fc
28 изменённых файлов: 165 добавлений и 242 удалений

Просмотреть файл

@ -564,18 +564,6 @@ void AccessibleWrap::GetRoleDescription(role aRole, AccAttributes* aAttributes,
LocalizeString(NS_ConvertUTF16toUTF8(aGeckoRole).get(), aRoleDescription);
}
already_AddRefed<AccAttributes> AccessibleWrap::AttributeArrayToProperties(
const nsTArray<Attribute>& aAttributes) {
RefPtr<AccAttributes> props = new AccAttributes();
for (size_t i = 0; i < aAttributes.Length(); i++) {
props->SetAttribute(NS_ConvertUTF8toUTF16(aAttributes.ElementAt(i).Name()),
aAttributes.ElementAt(i).Value());
}
return props.forget();
}
int32_t AccessibleWrap::GetAndroidClass(role aRole) {
#define ROLE(geckoRole, stringRole, atkRole, macRole, macSubrole, msaaRole, \
ia2Role, androidClass, nameRule) \

Просмотреть файл

@ -72,9 +72,6 @@ class AccessibleWrap : public LocalAccessible {
: GetAndroidClass(WrapperRole());
}
static already_AddRefed<AccAttributes> AttributeArrayToProperties(
const nsTArray<Attribute>& aAttributes);
static const int32_t kNoID = -1;
protected:

Просмотреть файл

@ -151,7 +151,7 @@ void DocAccessibleWrap::CacheViewportCallback(nsITimer* aTimer,
accessible->State(), accessible->Bounds(), accessible->ActionCount(),
name, textValue, nodeID, description, UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(), UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(), nsTArray<Attribute>()));
UnspecifiedNaN<double>(), nullptr));
}
ipcDoc->SendBatch(eBatch_Viewport, cacheData);
@ -239,9 +239,7 @@ void DocAccessibleWrap::CacheFocusPath(AccessibleWrap* aAccessible) {
acc->WrapperDOMNodeID(nodeID);
nsAutoString description;
acc->Description(description);
RefPtr<AccAttributes> props = acc->Attributes();
nsTArray<Attribute> attributes;
nsAccUtils::PersistentPropertiesToArray(props, &attributes);
RefPtr<AccAttributes> attributes = acc->Attributes();
cacheData.AppendElement(
BatchData(acc->Document()->IPCDoc(), UNIQUE_ID(acc), acc->State(),
acc->Bounds(), acc->ActionCount(), name, textValue, nodeID,
@ -279,12 +277,11 @@ void DocAccessibleWrap::UpdateFocusPathBounds() {
continue;
}
boundsData.AppendElement(
BatchData(accessible->Document()->IPCDoc(), UNIQUE_ID(accessible), 0,
accessible->Bounds(), 0, nsString(), nsString(), nsString(),
nsString(), UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(), UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(), nsTArray<Attribute>()));
boundsData.AppendElement(BatchData(
accessible->Document()->IPCDoc(), UNIQUE_ID(accessible), 0,
accessible->Bounds(), 0, nsString(), nsString(), nsString(),
nsString(), UnspecifiedNaN<double>(), UnspecifiedNaN<double>(),
UnspecifiedNaN<double>(), UnspecifiedNaN<double>(), nullptr));
}
ipcDoc->SendBatch(eBatch_BoundsUpdate, boundsData);

Просмотреть файл

@ -51,9 +51,9 @@ void RemoteAccessibleWrap::Shutdown() {
// LocalAccessible
already_AddRefed<AccAttributes> RemoteAccessibleWrap::Attributes() {
AutoTArray<Attribute, 10> attrs;
RefPtr<AccAttributes> attrs;
Proxy()->Attributes(&attrs);
return AttributeArrayToProperties(attrs);
return attrs.forget();
}
uint32_t RemoteAccessibleWrap::ChildCount() const {

Просмотреть файл

@ -416,13 +416,11 @@ void SessionAccessibility::ReplaceFocusPathCache(
if (aData.Length() == aAccessibles.Length()) {
const BatchData& data = aData.ElementAt(i);
RefPtr<AccAttributes> props =
AccessibleWrap::AttributeArrayToProperties(data.Attributes());
auto bundle =
acc->ToBundle(data.State(), data.Bounds(), data.ActionCount(),
data.Name(), data.TextValue(), data.DOMNodeID(),
data.Description(), data.CurValue(), data.MinValue(),
data.MaxValue(), data.Step(), props);
data.MaxValue(), data.Step(), data.Attributes());
infos->SetElement(i, bundle);
} else {
infos->SetElement(i, acc->ToBundle());

Просмотреть файл

@ -670,23 +670,9 @@ AtkAttributeSet* getAttributesCB(AtkObject* aAtkObj) {
RemoteAccessible* proxy = GetProxy(aAtkObj);
if (!proxy) return nullptr;
AutoTArray<Attribute, 10> attrs;
proxy->Attributes(&attrs);
if (attrs.IsEmpty()) return nullptr;
AtkAttributeSet* objAttributeSet = nullptr;
for (uint32_t i = 0; i < attrs.Length(); i++) {
AtkAttribute* objAttr = (AtkAttribute*)g_malloc(sizeof(AtkAttribute));
// On ATK, the placeholder attribute is called placeholder-text.
if (attrs[i].Name().Equals("placeholder")) {
attrs[i].Name().AssignLiteral("placeholder-text");
}
objAttr->name = g_strdup(attrs[i].Name().get());
objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(attrs[i].Value()).get());
objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
}
return objAttributeSet;
RefPtr<AccAttributes> attributes = nullptr;
proxy->Attributes(&attributes);
return ConvertToAtkAttributeSet(attributes);
}
const gchar* GetLocaleCB(AtkObject* aAtkObj) {

Просмотреть файл

@ -67,21 +67,6 @@ void ConvertTextAttributeToAtkAttribute(const nsACString& aName,
}
}
static AtkAttributeSet* ConvertToAtkTextAttributeSet(
nsTArray<Attribute>& aAttributes) {
AtkAttributeSet* objAttributeSet = nullptr;
for (size_t i = 0; i < aAttributes.Length(); ++i) {
AtkAttribute* objAttr = (AtkAttribute*)g_malloc(sizeof(AtkAttribute));
objAttr->name = g_strdup(aAttributes[i].Name().get());
objAttr->value =
g_strdup(NS_ConvertUTF16toUTF8(aAttributes[i].Value()).get());
objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
ConvertTextAttributeToAtkAttribute(
aAttributes[i].Name(), aAttributes[i].Value(), &objAttributeSet);
}
return objAttributeSet;
}
static AtkAttributeSet* ConvertToAtkTextAttributeSet(
AccAttributes* aAttributes) {
AtkAttributeSet* objAttributeSet = nullptr;
@ -311,7 +296,7 @@ static AtkAttributeSet* getRunAttributesCB(AtkText* aText, gint aOffset,
return nullptr;
}
AutoTArray<Attribute, 10> attrs;
RefPtr<AccAttributes> attrs;
proxy->TextAttributes(false, aOffset, &attrs, &startOffset, &endOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
@ -335,7 +320,7 @@ static AtkAttributeSet* getDefaultAttributesCB(AtkText* aText) {
return nullptr;
}
AutoTArray<Attribute, 10> attrs;
RefPtr<AccAttributes> attrs;
proxy->DefaultTextAttributes(&attrs);
return ConvertToAtkTextAttributeSet(attrs);
}

Просмотреть файл

@ -36,7 +36,7 @@ struct Color {
};
class AccAttributes {
friend struct IPC::ParamTraits<AccAttributes>;
friend struct IPC::ParamTraits<AccAttributes*>;
using AttrValueType = Variant<nsString, bool, float, int32_t, RefPtr<nsAtom>,
CSSCoord, FontSize, Color>;

Просмотреть файл

@ -415,22 +415,6 @@ bool nsAccUtils::MustPrune(AccessibleOrProxy aAccessible) {
return childRole == roles::TEXT_LEAF || childRole == roles::STATICTEXT;
}
bool nsAccUtils::PersistentPropertiesToArray(AccAttributes* aProps,
nsTArray<Attribute>* aAttributes) {
for (auto iter : *aProps) {
nsAutoString name;
iter.NameAsString(name);
nsAutoString value;
iter.ValueAsString(value);
aAttributes->AppendElement(
Attribute(NS_ConvertUTF16toUTF8(name), value));
}
return true;
}
bool nsAccUtils::IsARIALive(const LocalAccessible* aAccessible) {
// Get computed aria-live property based on the closest container with the
// attribute. Inner nodes override outer nodes within the same

Просмотреть файл

@ -230,9 +230,6 @@ class nsAccUtils {
*/
static bool MustPrune(AccessibleOrProxy aAccessible);
static bool PersistentPropertiesToArray(AccAttributes* aProps,
nsTArray<Attribute>* aAttributes);
/**
* Return true if the given accessible is within an ARIA live region; i.e.
* the container-live attribute would be something other than "off" or empty.

Просмотреть файл

@ -8,9 +8,12 @@
#define mozilla_a11y_IPCTypes_h
#ifdef ACCESSIBILITY
# include "mozilla/a11y/AccAttributes.h"
# include "mozilla/a11y/AccTypes.h"
# include "mozilla/a11y/Role.h"
# include "mozilla/GfxMessageUtils.h"
# include "ipc/EnumSerializer.h"
# include "ipc/IPCMessageUtilsSpecializations.h"
namespace IPC {
@ -33,6 +36,87 @@ struct ParamTraits<mozilla::a11y::AccGenericType>
mozilla::a11y::AccGenericType,
mozilla::a11y::AccGenericType::eAllGenericTypes> {};
template <>
struct ParamTraits<mozilla::a11y::FontSize> {
typedef mozilla::a11y::FontSize paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mValue);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
return ReadParam(aMsg, aIter, &(aResult->mValue));
}
};
template <>
struct ParamTraits<mozilla::a11y::Color> {
typedef mozilla::a11y::Color paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mValue);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
return ReadParam(aMsg, aIter, &(aResult->mValue));
}
};
template <>
struct ParamTraits<mozilla::a11y::AccAttributes*> {
typedef mozilla::a11y::AccAttributes paramType;
static void Write(Message* aMsg, const paramType* aParam) {
if (!aParam) {
WriteParam(aMsg, true);
return;
}
WriteParam(aMsg, false);
uint32_t count = aParam->mData.Count();
WriteParam(aMsg, count);
for (auto iter = aParam->mData.ConstIter(); !iter.Done(); iter.Next()) {
RefPtr<nsAtom> key = iter.Key();
WriteParam(aMsg, key);
const paramType::AttrValueType& data = iter.Data();
WriteParam(aMsg, data);
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
RefPtr<paramType>* aResult) {
bool isNull = false;
if (!ReadParam(aMsg, aIter, &isNull)) {
return false;
}
if (isNull) {
*aResult = nullptr;
return true;
}
*aResult = mozilla::MakeRefPtr<mozilla::a11y::AccAttributes>();
uint32_t count;
if (!ReadParam(aMsg, aIter, &count)) {
return false;
}
for (uint32_t i = 0; i < count; ++i) {
RefPtr<nsAtom> key;
if (!ReadParam(aMsg, aIter, &key)) {
return false;
}
paramType::AttrValueType val(0);
if (!ReadParam(aMsg, aIter, &val)) {
return false;
}
(*aResult)->mData.InsertOrUpdate(key, val);
}
return true;
}
};
} // namespace IPC
#else
namespace mozilla {

Просмотреть файл

@ -46,7 +46,7 @@ void Description(nsString& aDesc) const;
/**
* Get the set of attributes on the proxied accessible.
*/
void Attributes(nsTArray<Attribute>* aAttrs) const;
void Attributes(RefPtr<AccAttributes>* aAttributes) const;
/**
* Return set of targets of given relation type.
@ -99,9 +99,9 @@ void GetTextBeforeOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
char16_t CharAt(int32_t aOffset);
void TextAttributes(bool aIncludeDefAttrs, const int32_t aOffset,
nsTArray<Attribute>* aAttributes, int32_t* aStartOffset,
RefPtr<AccAttributes>* aAttributes, int32_t* aStartOffset,
int32_t* aEndOffset);
void DefaultTextAttributes(nsTArray<Attribute>* aAttrs);
void DefaultTextAttributes(RefPtr<AccAttributes>* aAttrs);
nsIntRect TextBounds(
int32_t aStartOffset, int32_t aEndOffset,

Просмотреть файл

@ -221,10 +221,9 @@ DocAccessiblePlatformExtChild::RecvAttributedTextForRange(
texts.Length() == containers.Length());
for (size_t i = 0; i < texts.Length(); i++) {
nsTArray<Attribute> textAttrArray;
nsAccUtils::PersistentPropertiesToArray(props.ElementAt(i), &textAttrArray);
aAttributes->AppendElement(TextAttributesRun(
texts.ElementAt(i), UNIQUE_ID(containers.ElementAt(i)), textAttrArray));
texts.ElementAt(i), UNIQUE_ID(containers.ElementAt(i)),
props.ElementAt(i)));
}
return IPC_OK();

Просмотреть файл

@ -6,17 +6,23 @@
include protocol PDocAccessible;
include DocAccessibleTypes;
include "mozilla/GfxMessageUtils.h";
using mozilla::a11y::EWhichRange from "mozilla/a11y/IPCTypes.h";
using mozilla::a11y::EWhichPostFilter from "mozilla/a11y/IPCTypes.h";
[RefCounted] using mozilla::a11y::AccAttributes from "mozilla/a11y/IPCTypes.h";
using nsIntRect from "nsRect.h";
namespace mozilla {
namespace a11y {
struct TextAttributesRun {
nsString Text;
uint64_t ContainerID;
AccAttributes TextAttributes;
};
nested(upto inside_sync) sync protocol PDocAccessiblePlatformExt {
manager PDocAccessible;

Просмотреть файл

@ -16,11 +16,11 @@
#include "ImageAccessible.h"
#include "TableAccessible.h"
#include "TableCellAccessible.h"
#include "nsIPersistentProperties2.h"
#include "nsAccUtils.h"
#ifdef MOZ_ACCESSIBILITY_ATK
# include "AccessibleWrap.h"
#endif
#include "AccAttributes.h"
#include "mozilla/PresShell.h"
#include "mozilla/a11y/DocAccessiblePlatformExtChild.h"
@ -145,14 +145,11 @@ mozilla::ipc::IPCResult DocAccessibleChild::RecvDescription(const uint64_t& aID,
}
mozilla::ipc::IPCResult DocAccessibleChild::RecvAttributes(
const uint64_t& aID, nsTArray<Attribute>* aAttributes) {
const uint64_t& aID, RefPtr<AccAttributes>* aAttributes) {
LocalAccessible* acc = IdToAccessible(aID);
if (!acc) return IPC_OK();
RefPtr<AccAttributes> props = acc->Attributes();
if (!nsAccUtils::PersistentPropertiesToArray(props, aAttributes)) {
return IPC_FAIL_NO_REASON(this);
}
*aAttributes = acc->Attributes();
return IPC_OK();
}
@ -403,32 +400,28 @@ mozilla::ipc::IPCResult DocAccessibleChild::RecvCharAt(const uint64_t& aID,
mozilla::ipc::IPCResult DocAccessibleChild::RecvTextAttributes(
const uint64_t& aID, const bool& aIncludeDefAttrs, const int32_t& aOffset,
nsTArray<Attribute>* aAttributes, int32_t* aStartOffset,
RefPtr<AccAttributes>* aAttributes, int32_t* aStartOffset,
int32_t* aEndOffset) {
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (!acc || !acc->IsTextRole()) {
return IPC_OK();
}
RefPtr<AccAttributes> props =
*aAttributes =
acc->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset);
if (!nsAccUtils::PersistentPropertiesToArray(props, aAttributes)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult DocAccessibleChild::RecvDefaultTextAttributes(
const uint64_t& aID, nsTArray<Attribute>* aAttributes) {
const uint64_t& aID, RefPtr<AccAttributes>* aAttributes) {
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (!acc || !acc->IsTextRole()) {
return IPC_OK();
}
RefPtr<AccAttributes> props = acc->DefaultTextAttributes();
if (!nsAccUtils::PersistentPropertiesToArray(props, aAttributes)) {
return IPC_FAIL_NO_REASON(this);
}
*aAttributes = acc->DefaultTextAttributes();
return IPC_OK();
}

Просмотреть файл

@ -90,7 +90,7 @@ class DocAccessibleChild : public DocAccessibleChildBase {
int32_t* aPositionInGroup) override;
virtual mozilla::ipc::IPCResult RecvAttributes(
const uint64_t& aID, nsTArray<Attribute>* aAttributes) override;
const uint64_t& aID, RefPtr<AccAttributes>* aAttributes) override;
MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual mozilla::ipc::IPCResult RecvScrollTo(
const uint64_t& aID, const uint32_t& aScrollType) override;
@ -137,11 +137,11 @@ class DocAccessibleChild : public DocAccessibleChildBase {
virtual mozilla::ipc::IPCResult RecvTextAttributes(
const uint64_t& aID, const bool& aIncludeDefAttrs, const int32_t& aOffset,
nsTArray<Attribute>* aAttributes, int32_t* aStartOffset,
RefPtr<AccAttributes>* aAttributes, int32_t* aStartOffset,
int32_t* aEndOffset) override;
virtual mozilla::ipc::IPCResult RecvDefaultTextAttributes(
const uint64_t& aID, nsTArray<Attribute>* aAttributes) override;
const uint64_t& aID, RefPtr<AccAttributes>* aAttributes) override;
virtual mozilla::ipc::IPCResult RecvTextBounds(const uint64_t& aID,
const int32_t& aStartOffset,

Просмотреть файл

@ -1,23 +0,0 @@
/* -*- 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/. */
namespace mozilla {
namespace a11y {
struct Attribute
{
nsCString Name;
nsString Value;
};
struct TextAttributesRun {
nsString Text;
uint64_t ContainerID;
Attribute[] TextAttributes;
};
}
}

Просмотреть файл

@ -8,14 +8,13 @@ include protocol PFileDescriptorSet;
include protocol PBrowser;
include protocol PDocAccessiblePlatformExt;
include DocAccessibleTypes;
include "mozilla/GfxMessageUtils.h";
using nsIntRect from "nsRect.h";
using mozilla::a11y::role from "mozilla/a11y/IPCTypes.h";
using mozilla::a11y::AccType from "mozilla/a11y/IPCTypes.h";
using mozilla::a11y::AccGenericType from "mozilla/a11y/IPCTypes.h";
[RefCounted] using mozilla::a11y::AccAttributes from "mozilla/a11y/IPCTypes.h";
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h";
@ -52,7 +51,7 @@ struct BatchData
double MinValue;
double MaxValue;
double Step;
Attribute[] Attributes;
AccAttributes Attributes;
};
struct ShowEventData
@ -145,7 +144,7 @@ child:
[Nested=inside_sync] sync Value(uint64_t aID) returns(nsString value);
[Nested=inside_sync] sync Help(uint64_t aID) returns(nsString help);
[Nested=inside_sync] sync Description(uint64_t aID) returns(nsString desc);
[Nested=inside_sync] sync Attributes(uint64_t aID) returns(Attribute[] attributes);
[Nested=inside_sync] sync Attributes(uint64_t aID) returns(AccAttributes attributes);
[Nested=inside_sync] sync RelationByType(uint64_t aID, uint32_t aRelationType)
returns(uint64_t[] targets);
[Nested=inside_sync] sync Relations(uint64_t aID) returns(RelationTargets[] relations);
@ -179,8 +178,8 @@ child:
[Nested=inside_sync] sync CharAt(uint64_t aID, int32_t aOffset) returns(uint16_t aChar);
[Nested=inside_sync] sync TextAttributes(uint64_t aID, bool aIncludeDefAttrs, int32_t aOffset)
returns(Attribute[] aAttributes, int32_t aStartOffset, int32_t aEndOffset);
[Nested=inside_sync] sync DefaultTextAttributes(uint64_t aID) returns(Attribute[] aAttributes);
returns(AccAttributes aAttributes, int32_t aStartOffset, int32_t aEndOffset);
[Nested=inside_sync] sync DefaultTextAttributes(uint64_t aID) returns(AccAttributes aAttributes);
[Nested=inside_sync] sync TextBounds(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
uint32_t aCoordType)

Просмотреть файл

@ -48,8 +48,8 @@ void RemoteAccessible::Description(nsString& aDesc) const {
Unused << mDoc->SendDescription(mID, &aDesc);
}
void RemoteAccessible::Attributes(nsTArray<Attribute>* aAttrs) const {
Unused << mDoc->SendAttributes(mID, aAttrs);
void RemoteAccessible::Attributes(RefPtr<AccAttributes>* aAttributes) const {
Unused << mDoc->SendAttributes(mID, aAttributes);
}
nsTArray<RemoteAccessible*> RemoteAccessible::RelationByType(
@ -206,14 +206,14 @@ char16_t RemoteAccessible::CharAt(int32_t aOffset) {
}
void RemoteAccessible::TextAttributes(bool aIncludeDefAttrs, int32_t aOffset,
nsTArray<Attribute>* aAttributes,
RefPtr<AccAttributes>* aAttributes,
int32_t* aStartOffset,
int32_t* aEndOffset) {
Unused << mDoc->SendTextAttributes(mID, aIncludeDefAttrs, aOffset,
aAttributes, aStartOffset, aEndOffset);
}
void RemoteAccessible::DefaultTextAttributes(nsTArray<Attribute>* aAttrs) {
void RemoteAccessible::DefaultTextAttributes(RefPtr<AccAttributes>* aAttrs) {
Unused << mDoc->SendDefaultTextAttributes(mID, aAttrs);
}

Просмотреть файл

@ -7,7 +7,6 @@
if CONFIG["ACCESSIBILITY"]:
IPDL_SOURCES += [
"DocAccessibleTypes.ipdlh",
"PDocAccessible.ipdl",
]

Просмотреть файл

@ -39,12 +39,6 @@ struct ShowEventData
bool EventSuppressed;
};
struct Attribute
{
nsCString Name;
nsString Value;
};
sync protocol PDocAccessible
{
manager PBrowser;

Просмотреть файл

@ -280,12 +280,10 @@ static bool IsEscapedChar(const wchar_t c) {
return c == L'\\' || c == L':' || c == ',' || c == '=' || c == ';';
}
static bool ConvertBSTRAttributesToArray(const nsAString& aStr,
nsTArray<Attribute>* aAttrs) {
if (!aAttrs) {
return false;
}
// XXX: This creates an all-strings AccAttributes, this isn't ideal
// but an OK temporary stop-gap before IPC goes full IPDL.
static bool ConvertBSTRAttributesToAccAttributes(
const nsAString& aStr, RefPtr<AccAttributes>& aAttrs) {
enum { eName = 0, eValue = 1, eNumStates } state;
nsAutoString tokens[eNumStates];
auto itr = aStr.BeginReading(), end = aStr.EndReading();
@ -309,18 +307,19 @@ static bool ConvertBSTRAttributesToArray(const nsAString& aStr,
state = eValue;
++itr;
continue;
case L';':
case L';': {
if (state != eValue) {
// Bad, should be looking at value
return false;
}
state = eName;
aAttrs->AppendElement(
Attribute(NS_ConvertUTF16toUTF8(tokens[eName]), tokens[eValue]));
RefPtr<nsAtom> nameAtom = NS_Atomize(tokens[eName]);
aAttrs->SetAttribute(nameAtom, tokens[eValue]);
tokens[eName].Truncate();
tokens[eValue].Truncate();
++itr;
continue;
}
default:
break;
}
@ -330,9 +329,7 @@ static bool ConvertBSTRAttributesToArray(const nsAString& aStr,
return true;
}
void RemoteAccessible::Attributes(nsTArray<Attribute>* aAttrs) const {
aAttrs->Clear();
void RemoteAccessible::Attributes(RefPtr<AccAttributes>* aAttrs) const {
RefPtr<IAccessible> acc;
if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
return;
@ -351,8 +348,9 @@ void RemoteAccessible::Attributes(nsTArray<Attribute>* aAttrs) const {
return;
}
ConvertBSTRAttributesToArray(
nsDependentString((wchar_t*)attrs, attrsWrap.length()), aAttrs);
*aAttrs = new AccAttributes();
ConvertBSTRAttributesToAccAttributes(
nsDependentString((wchar_t*)attrs, attrsWrap.length()), *aAttrs);
}
nsTArray<RemoteAccessible*> RemoteAccessible::RelationByType(

Просмотреть файл

@ -496,14 +496,8 @@ NSAttributedString* GeckoTextMarkerRange::AttributedText() const {
mEnd.mContainer.AsProxy()->ID(), mEnd.mOffset, &textAttributesRuns);
for (size_t i = 0; i < textAttributesRuns.Length(); i++) {
nsTArray<Attribute>& attribs =
AccAttributes* attributes =
textAttributesRuns.ElementAt(i).TextAttributes();
RefPtr<AccAttributes> attributes = new AccAttributes();
for (size_t ii = 0; ii < attribs.Length(); ii++) {
attributes->SetAttribute(
NS_ConvertUTF8toUTF16(attribs.ElementAt(ii).Name()),
attribs.ElementAt(ii).Value());
}
RemoteAccessible* container =
ipcDoc->GetAccessible(textAttributesRuns.ElementAt(i).ContainerID());

Просмотреть файл

@ -62,22 +62,17 @@ NSString* LocalizedString(const nsString& aString) {
NSString* GetAccAttr(mozAccessible* aNativeAccessible, nsAtom* aAttrName) {
nsAutoString result;
RefPtr<AccAttributes> attributes;
if (LocalAccessible* acc =
[aNativeAccessible geckoAccessible].AsAccessible()) {
RefPtr<AccAttributes> attributes = acc->Attributes();
attributes->GetAttribute(aAttrName, result);
attributes = acc->Attributes();
} else if (RemoteAccessible* proxy =
[aNativeAccessible geckoAccessible].AsProxy()) {
AutoTArray<Attribute, 10> attrs;
proxy->Attributes(&attrs);
for (size_t i = 0; i < attrs.Length(); i++) {
if (aAttrName->Equals(NS_ConvertUTF8toUTF16(attrs.ElementAt(i).Name()))) {
result = attrs.ElementAt(i).Value();
break;
}
}
proxy->Attributes(&attributes);
}
attributes->GetAttribute(aAttrName, result);
if (!result.IsEmpty()) {
return nsCocoaUtils::ToNSString(result);
}

Просмотреть файл

@ -76,43 +76,25 @@ inline NSString* ToNSString(id aValue) {
// If the attribute exists, it has one of four values: true, false,
// grammar, or spelling. We query the attribute value here in order
// to find the correct string to return.
RefPtr<AccAttributes> attributes;
if (LocalAccessible* acc = mGeckoAccessible.AsAccessible()) {
HyperTextAccessible* text = acc->AsHyperText();
if (!text || !text->IsTextRole()) {
// we can't get the attribute, but we should still respect the
// invalid state flag
return @"true";
if (text && text->IsTextRole()) {
attributes = text->DefaultTextAttributes();
}
nsAutoString invalidStr;
RefPtr<AccAttributes> attributes = text->DefaultTextAttributes();
attributes->GetAttribute(nsGkAtoms::invalid, invalidStr);
if (invalidStr.IsEmpty()) {
// if the attribute had no value, we should still respect the
// invalid state flag.
return @"true";
}
return nsCocoaUtils::ToNSString(invalidStr);
} else {
RemoteAccessible* proxy = mGeckoAccessible.AsProxy();
// Similar to the acc case above, we iterate through our attributes
// to find the value for `invalid`.
AutoTArray<Attribute, 10> attrs;
proxy->DefaultTextAttributes(&attrs);
for (size_t i = 0; i < attrs.Length(); i++) {
if (attrs.ElementAt(i).Name() == "invalid") {
nsString invalidStr = attrs.ElementAt(i).Value();
if (invalidStr.IsEmpty()) {
break;
}
return nsCocoaUtils::ToNSString(invalidStr);
}
}
// if we iterated through our attributes and didn't find `invalid`,
// or if the invalid attribute had no value, we should still respect
// the invalid flag and return true.
proxy->DefaultTextAttributes(&attributes);
}
nsAutoString invalidStr;
if (!attributes ||
!attributes->GetAttribute(nsGkAtoms::invalid, invalidStr)) {
return @"true";
}
return nsCocoaUtils::ToNSString(invalidStr);
}
// If the flag is not set, we return false.
return @"false";
}

Просмотреть файл

@ -622,26 +622,6 @@ static inline void EscapeAttributeChars(String& aStr) {
}
}
HRESULT
ia2Accessible::ConvertToIA2Attributes(nsTArray<Attribute>* aAttributes,
BSTR* aIA2Attributes) {
nsString attrStr;
size_t attrCount = aAttributes->Length();
for (size_t i = 0; i < attrCount; i++) {
EscapeAttributeChars(aAttributes->ElementAt(i).Name());
EscapeAttributeChars(aAttributes->ElementAt(i).Value());
AppendUTF8toUTF16(aAttributes->ElementAt(i).Name(), attrStr);
attrStr.Append(':');
attrStr.Append(aAttributes->ElementAt(i).Value());
attrStr.Append(';');
}
if (attrStr.IsEmpty()) return S_FALSE;
*aIA2Attributes = ::SysAllocStringLen(attrStr.get(), attrStr.Length());
return *aIA2Attributes ? S_OK : E_OUTOFMEMORY;
}
HRESULT
ia2Accessible::ConvertToIA2Attributes(AccAttributes* aAttributes,
BSTR* aIA2Attributes) {

Просмотреть файл

@ -14,7 +14,6 @@
namespace mozilla {
namespace a11y {
class Attribute;
class Accessible;
class AccAttributes;
class AccessibleWrap;
@ -114,8 +113,6 @@ class ia2Accessible : public IAccessible2_3 {
// Helper method
static HRESULT ConvertToIA2Attributes(AccAttributes* aAttributes,
BSTR* aIA2Attributes);
static HRESULT ConvertToIA2Attributes(nsTArray<Attribute>* aAttributes,
BSTR* aIA2Attributes);
private:
AccessibleWrap* LocalAcc();

Просмотреть файл

@ -369,18 +369,12 @@ xpcAccessible::GetAttributes(nsIPersistentProperties** aAttributes) {
RefPtr<nsPersistentProperties> props = new nsPersistentProperties();
RefPtr<AccAttributes> attributes = new AccAttributes();
RefPtr<AccAttributes> attributes;
if (LocalAccessible* acc = Intl()) {
attributes = acc->Attributes();
} else {
RemoteAccessible* proxy = IntlGeneric()->AsRemote();
AutoTArray<Attribute, 10> attrs;
proxy->Attributes(&attrs);
uint32_t attrCount = attrs.Length();
for (uint32_t i = 0; i < attrCount; i++) {
RefPtr<nsAtom> nameAttr = NS_Atomize(attrs[i].Name());
attributes->SetAttribute(nameAttr, attrs[i].Value());
}
proxy->Attributes(&attributes);
}
nsAutoString unused;