bug 1127402 - proxy RelationByType method r=davidb

This commit is contained in:
Trevor Saunders 2015-01-29 11:58:34 -05:00
Родитель b33a23f60b
Коммит 45d9b7831f
7 изменённых файлов: 169 добавлений и 1 удалений

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

@ -961,6 +961,40 @@ refRelationSetCB(AtkObject *aAtkObj)
AtkRelationSet* relation_set =
ATK_OBJECT_CLASS(parent_class)->ref_relation_set(aAtkObj);
const AtkRelationType typeMap[] = {
#define RELATIONTYPE(gecko, s, atk, m, i) atk,
#include "RelationTypeMap.h"
#undef RELATIONTYPE
};
if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
nsTArray<RelationType> types;
nsTArray<nsTArray<ProxyAccessible*>> targetSets;
proxy->Relations(&types, &targetSets);
size_t relationCount = types.Length();
for (size_t i = 0; i < relationCount; i++) {
if (typeMap[static_cast<uint32_t>(types[i])] == ATK_RELATION_NULL)
continue;
size_t targetCount = targetSets[i].Length();
nsAutoTArray<AtkObject*, 5> wrappers;
for (size_t j = 0; j < targetCount; j++)
wrappers.AppendElement(GetWrapperFor(targetSets[i][j]));
AtkRelationType atkType = typeMap[static_cast<uint32_t>(types[i])];
AtkRelation* atkRelation =
atk_relation_set_get_relation_by_type(relation_set, atkType);
if (atkRelation)
atk_relation_set_remove(relation_set, atkRelation);
atkRelation = atk_relation_new(wrappers.Elements(), wrappers.Length(),
atkType);
atk_relation_set_add(relation_set, atkRelation);
g_object_unref(atkRelation);
}
}
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
if (!accWrap)
return relation_set;

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

@ -8,6 +8,7 @@
#include "Accessible-inl.h"
#include "ProxyAccessible.h"
#include "Relation.h"
#include "nsIPersistentProperties2.h"
#include "nsISimpleEnumerator.h"
@ -156,6 +157,56 @@ DocAccessibleChild::RecvAttributes(const uint64_t& aID, nsTArray<Attribute>* aAt
return true;
}
bool
DocAccessibleChild::RecvRelationByType(const uint64_t& aID,
const uint32_t& aType,
nsTArray<uint64_t>* aTargets)
{
Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID);
if (!acc)
return false;
auto type = static_cast<RelationType>(aType);
Relation rel = acc->RelationByType(type);
while (Accessible* target = rel.Next())
aTargets->AppendElement(reinterpret_cast<uintptr_t>(target));
return true;
}
static void
AddRelation(Accessible* aAcc, RelationType aType,
nsTArray<RelationTargets>* aTargets)
{
Relation rel = aAcc->RelationByType(aType);
nsTArray<uint64_t> targets;
while (Accessible* target = rel.Next())
targets.AppendElement(reinterpret_cast<uintptr_t>(target));
if (!targets.IsEmpty()) {
RelationTargets* newRelation =
aTargets->AppendElement(RelationTargets(static_cast<uint32_t>(aType),
nsTArray<uint64_t>()));
newRelation->Targets().SwapElements(targets);
}
}
bool
DocAccessibleChild::RecvRelations(const uint64_t& aID,
nsTArray<RelationTargets>* aRelations)
{
Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID);
if (!aID)
return false;
#define RELATIONTYPE(gecko, s, a, m, i) AddRelation(acc, RelationType::gecko, aRelations);
#include "RelationTypeMap.h"
#undef RELATIONTYPE
return true;
}
bool
DocAccessibleChild::RecvTextSubstring(const uint64_t& aID,
const int32_t& aStartOffset,

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

@ -55,8 +55,14 @@ public:
* Get the description for the accessible with given id.
*/
virtual bool RecvDescription(const uint64_t& aID, nsString* aDesc) MOZ_OVERRIDE;
virtual bool RecvRelationByType(const uint64_t& aID, const uint32_t& aType,
nsTArray<uint64_t>* aTargets) MOZ_OVERRIDE;
virtual bool RecvRelations(const uint64_t& aID,
nsTArray<RelationTargets>* aRelations)
MOZ_OVERRIDE;
virtual bool RecvAttributes(const uint64_t& aID, nsTArray<Attribute> *aAttributes) MOZ_OVERRIDE;
virtual bool RecvAttributes(const uint64_t& aID,
nsTArray<Attribute> *aAttributes) MOZ_OVERRIDE;
virtual bool RecvTextSubstring(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset, nsString* aText)

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

@ -82,6 +82,15 @@ public:
mAccessibles.RemoveEntry(aAccessible->ID());
}
/**
* Return the accessible for given id.
*/
ProxyAccessible* GetAccessible(uintptr_t aID) const
{
ProxyEntry* e = mAccessibles.GetEntry(aID);
return e ? e->mProxy : nullptr;
}
private:
class ProxyEntry : public PLDHashEntryHdr

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

@ -32,6 +32,12 @@ struct Attribute
nsString Value;
};
struct RelationTargets
{
uint32_t Type;
uint64_t[] Targets;
};
prio(normal upto high) sync protocol PDocAccessible
{
manager PContent;
@ -54,6 +60,9 @@ child:
prio(high) sync Value(uint64_t aID) returns(nsString value);
prio(high) sync Description(uint64_t aID) returns(nsString desc);
prio(high) sync Attributes(uint64_t aID) returns(Attribute[] attributes);
prio(high) sync RelationByType(uint64_t aID, uint32_t aRelationType)
returns(uint64_t[] targets);
prio(high) sync Relations(uint64_t aID) returns(RelationTargets[] relations);
// AccessibleText

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

@ -8,6 +8,7 @@
#include "DocAccessibleParent.h"
#include "mozilla/unused.h"
#include "mozilla/a11y/Platform.h"
#include "RelationType.h"
#include "mozilla/a11y/Role.h"
namespace mozilla {
@ -102,6 +103,52 @@ ProxyAccessible::Attributes(nsTArray<Attribute> *aAttrs) const
unused << mDoc->SendAttributes(mID, aAttrs);
}
nsTArray<ProxyAccessible*>
ProxyAccessible::RelationByType(RelationType aType) const
{
nsTArray<uint64_t> targetIDs;
unused << mDoc->SendRelationByType(mID, static_cast<uint32_t>(aType),
&targetIDs);
size_t targetCount = targetIDs.Length();
nsTArray<ProxyAccessible*> targets(targetCount);
for (size_t i = 0; i < targetCount; i++)
if (ProxyAccessible* proxy = mDoc->GetAccessible(targetIDs[i]))
targets.AppendElement(proxy);
return Move(targets);
}
void
ProxyAccessible::Relations(nsTArray<RelationType>* aTypes,
nsTArray<nsTArray<ProxyAccessible*>>* aTargetSets)
const
{
nsTArray<RelationTargets> ipcRelations;
unused << mDoc->SendRelations(mID, &ipcRelations);
size_t relationCount = ipcRelations.Length();
aTypes->SetCapacity(relationCount);
aTargetSets->SetCapacity(relationCount);
for (size_t i = 0; i < relationCount; i++) {
uint32_t type = ipcRelations[i].Type();
if (type > static_cast<uint32_t>(RelationType::LAST))
continue;
size_t targetCount = ipcRelations[i].Targets().Length();
nsTArray<ProxyAccessible*> targets(targetCount);
for (size_t j = 0; j < targetCount; j++)
if (ProxyAccessible* proxy = mDoc->GetAccessible(ipcRelations[i].Targets()[j]))
targets.AppendElement(proxy);
if (targets.IsEmpty())
continue;
aTargetSets->AppendElement(Move(targets));
aTypes->AppendElement(static_cast<RelationType>(type));
}
}
void
ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOfset,
nsString& aText) const

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

@ -17,6 +17,7 @@ namespace a11y {
class Attribute;
class DocAccessibleParent;
enum class RelationType;
class ProxyAccessible
{
@ -87,6 +88,17 @@ public:
*/
void Attributes(nsTArray<Attribute> *aAttrs) const;
/**
* Return set of targets of given relation type.
*/
nsTArray<ProxyAccessible*> RelationByType(RelationType aType) const;
/**
* Get all relations for this accessible.
*/
void Relations(nsTArray<RelationType>* aTypes,
nsTArray<nsTArray<ProxyAccessible*>>* aTargetSets) const;
/**
* Get the text between the given offsets.
*/