Bug 923289 - introduce relation type map, r=tbsaunde

--HG--
rename : accessible/src/base/RoleAsserts.cpp => accessible/src/base/Asserts.cpp
This commit is contained in:
Alexander Surkov 2013-10-22 19:55:27 -04:00
parent a8629d8ffb
commit 77b21c00d2
10 changed files with 207 additions and 192 deletions

View File

@ -871,6 +871,32 @@ refStateSetCB(AtkObject *aAtkObj)
return state_set;
}
static void
UpdateAtkRelation(RelationType aType, Accessible* aAcc,
AtkRelationType aAtkType, AtkRelationSet* aAtkSet)
{
if (aAtkType == ATK_RELATION_NULL)
return;
AtkRelation* atkRelation =
atk_relation_set_get_relation_by_type(aAtkSet, aAtkType);
if (atkRelation)
atk_relation_set_remove(aAtkSet, atkRelation);
Relation rel(aAcc->RelationByType(aType));
nsTArray<AtkObject*> targets;
Accessible* tempAcc = nullptr;
while ((tempAcc = rel.Next()))
targets.AppendElement(AccessibleWrap::GetAtkObject(tempAcc));
if (targets.Length()) {
atkRelation = atk_relation_new(targets.Elements(),
targets.Length(), aAtkType);
atk_relation_set_add(aAtkSet, atkRelation);
g_object_unref(atkRelation);
}
}
AtkRelationSet *
refRelationSetCB(AtkObject *aAtkObj)
{
@ -881,46 +907,12 @@ refRelationSetCB(AtkObject *aAtkObj)
if (!accWrap)
return relation_set;
// Keep in sync with AtkRelationType enum.
static const RelationType relationTypes[] = {
RelationType::CONTROLLED_BY,
RelationType::CONTROLLER_FOR,
RelationType::LABEL_FOR,
RelationType::LABELLED_BY,
RelationType::MEMBER_OF,
RelationType::NODE_CHILD_OF,
RelationType::FLOWS_TO,
RelationType::FLOWS_FROM,
RelationType::SUBWINDOW_OF,
RelationType::EMBEDS,
RelationType::EMBEDDED_BY,
RelationType::POPUP_FOR,
RelationType::PARENT_WINDOW_OF,
RelationType::DESCRIBED_BY,
RelationType::DESCRIPTION_FOR,
RelationType::NODE_PARENT_OF
};
#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \
UpdateAtkRelation(RelationType::geckoType, accWrap, atkType, relation_set);
for (uint32_t i = 0; i < ArrayLength(relationTypes); i++) {
// Shift to 1 to skip ATK_RELATION_NULL.
AtkRelationType atkType = static_cast<AtkRelationType>(i + 1);
AtkRelation* atkRelation =
atk_relation_set_get_relation_by_type(relation_set, atkType);
if (atkRelation)
atk_relation_set_remove(relation_set, atkRelation);
#include "RelationTypeMap.h"
Relation rel(accWrap->RelationByType(relationTypes[i]));
nsTArray<AtkObject*> targets;
Accessible* tempAcc = nullptr;
while ((tempAcc = rel.Next()))
targets.AppendElement(AccessibleWrap::GetAtkObject(tempAcc));
if (targets.Length()) {
atkRelation = atk_relation_new(targets.Elements(), targets.Length(), atkType);
atk_relation_set_add(relation_set, atkRelation);
g_object_unref(atkRelation);
}
}
#undef RELATIONTYPE
return relation_set;
}

View File

@ -4,7 +4,9 @@
* 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 "nsIAccessibleRelation.h"
#include "nsIAccessibleRole.h"
#include "RelationType.h"
#include "Role.h"
using namespace mozilla::a11y;
@ -15,3 +17,10 @@ using namespace mozilla::a11y;
"internal and xpcom roles differ!");
#include "RoleMap.h"
#undef ROLE
#define RELATIONTYPE(geckoType, stringType, atkType, msaaType, ia2Type) \
static_assert(static_cast<uint32_t>(RelationType::geckoType) \
== static_cast<uint32_t>(nsIAccessibleRelation::RELATION_ ## geckoType), \
"internal and xpcom relations differ!");
#include "RelationTypeMap.h"
#undef RELATIONTYPE

View File

@ -0,0 +1,112 @@
/* -*- 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/. */
/**
* Usage: declare the macro RELATIONTYPE()with the following arguments:
* RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type)
*/
RELATIONTYPE(LABELLED_BY,
"labelled by",
ATK_RELATION_LABELLED_BY,
NAVRELATION_LABELLED_BY,
IA2_RELATION_LABELLED_BY)
RELATIONTYPE(LABEL_FOR,
"label for",
ATK_RELATION_LABEL_FOR,
NAVRELATION_LABEL_FOR,
IA2_RELATION_LABEL_FOR)
RELATIONTYPE(DESCRIBED_BY,
"described by",
ATK_RELATION_DESCRIBED_BY,
NAVRELATION_DESCRIBED_BY,
IA2_RELATION_DESCRIBED_BY)
RELATIONTYPE(DESCRIPTION_FOR,
"description for",
ATK_RELATION_DESCRIPTION_FOR,
NAVRELATION_DESCRIPTION_FOR,
IA2_RELATION_DESCRIPTION_FOR)
RELATIONTYPE(NODE_CHILD_OF,
"node child of",
ATK_RELATION_NODE_CHILD_OF,
NAVRELATION_NODE_CHILD_OF,
IA2_RELATION_NODE_CHILD_OF)
RELATIONTYPE(NODE_PARENT_OF,
"node parent of",
ATK_RELATION_NODE_PARENT_OF,
NAVRELATION_NODE_PARENT_OF,
IA2_RELATION_NODE_PARENT_OF)
RELATIONTYPE(CONTROLLED_BY,
"controlled by",
ATK_RELATION_CONTROLLED_BY,
NAVRELATION_CONTROLLED_BY,
IA2_RELATION_CONTROLLED_BY)
RELATIONTYPE(CONTROLLER_FOR,
"controller for",
ATK_RELATION_CONTROLLER_FOR,
NAVRELATION_CONTROLLER_FOR,
IA2_RELATION_CONTROLLER_FOR)
RELATIONTYPE(FLOWS_TO,
"flows to",
ATK_RELATION_FLOWS_TO,
NAVRELATION_FLOWS_TO,
IA2_RELATION_FLOWS_TO)
RELATIONTYPE(FLOWS_FROM,
"flows from",
ATK_RELATION_FLOWS_FROM,
NAVRELATION_FLOWS_FROM,
IA2_RELATION_FLOWS_FROM)
RELATIONTYPE(MEMBER_OF,
"member of",
ATK_RELATION_MEMBER_OF,
NAVRELATION_MEMBER_OF,
IA2_RELATION_MEMBER_OF)
RELATIONTYPE(SUBWINDOW_OF,
"subwindow of",
ATK_RELATION_SUBWINDOW_OF,
NAVRELATION_SUBWINDOW_OF,
IA2_RELATION_SUBWINDOW_OF)
RELATIONTYPE(EMBEDS,
"embeds",
ATK_RELATION_EMBEDS,
NAVRELATION_EMBEDS,
IA2_RELATION_EMBEDS)
RELATIONTYPE(EMBEDDED_BY,
"embedded by",
ATK_RELATION_EMBEDDED_BY,
NAVRELATION_EMBEDDED_BY,
IA2_RELATION_EMBEDDED_BY)
RELATIONTYPE(POPUP_FOR,
"popup for",
ATK_RELATION_POPUP_FOR,
NAVRELATION_POPUP_FOR,
IA2_RELATION_POPUP_FOR)
RELATIONTYPE(PARENT_WINDOW_OF,
"parent window of",
ATK_RELATION_PARENT_WINDOW_OF,
NAVRELATION_PARENT_WINDOW_OF,
IA2_RELATION_PARENT_WINDOW_OF)
RELATIONTYPE(DEFAULT_BUTTON,
"default button",
ATK_RELATION_NULL,
NAVRELATION_DEFAULT_BUTTON,
IA2_RELATION_NULL)

View File

@ -37,6 +37,7 @@ CPP_SOURCES += [
'AccIterator.cpp',
'ARIAMap.cpp',
'ARIAStateMap.cpp',
'Asserts.cpp',
'DocManager.cpp',
'EventQueue.cpp',
'Filters.cpp',
@ -49,7 +50,6 @@ CPP_SOURCES += [
'nsCoreUtils.cpp',
'nsEventShell.cpp',
'nsTextEquivUtils.cpp',
'RoleAsserts.cpp',
'SelectionManager.cpp',
'StyleInfo.cpp',
'TextAttrs.cpp',

View File

@ -713,13 +713,22 @@ NS_IMETHODIMP
nsAccessibilityService::GetStringRelationType(uint32_t aRelationType,
nsAString& aString)
{
if (aRelationType >= ArrayLength(kRelationTypeNames)) {
aString.AssignLiteral("unknown");
NS_ENSURE_ARG(aRelationType <= static_cast<uint32_t>(RelationType::LAST));
#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \
case RelationType::geckoType: \
aString.AssignLiteral(geckoTypeName); \
return NS_OK;
RelationType relationType = static_cast<RelationType>(aRelationType);
switch (relationType) {
#include "RelationTypeMap.h"
default:
aString.AssignLiteral("unknown");
return NS_OK;
}
CopyUTF8toUTF16(kRelationTypeNames[aRelationType], aString);
return NS_OK;
#undef RELATIONTYPE
}
NS_IMETHODIMP

View File

@ -332,29 +332,5 @@ static const char kEventTypeNames[][40] = {
"virtual cursor changed" // EVENT_VIRTUALCURSOR_CHANGED
};
/**
* Map nsIAccessibleRelation constants to strings. Used by
* nsIAccessibleRetrieval::getStringRelationType() method.
*/
static const char kRelationTypeNames[][20] = {
"labelled by", // RELATION_LABELLED_BY
"label for", // RELATION_LABEL_FOR
"described by", // RELATION_DESCRIBED_BY
"description for", // RELATION_DESCRIPTION_FOR
"node child of", // RELATION_NODE_CHILD_OF
"node parent of", // RELATION_NODE_PARENT_OF
"controlled by", // RELATION_CONTROLLED_BY
"controller for", // RELATION_CONTROLLER_FOR
"flows to", // RELATION_FLOWS_TO
"flows from", // RELATION_FLOWS_FROM
"member of", // RELATION_MEMBER_OF
"subwindow of", // RELATION_SUBWINDOW_OF
"embeds", // RELATION_EMBEDS
"embedded by", // RELATION_EMBEDDED_BY
"popup for", // RELATION_POPUP_FOR
"parent window of", // RELATION_PARENT_WINDOW_OF
"default button" // RELATION_DEFAULT_BUTTON
};
#endif /* __nsIAccessibilityService_h__ */

View File

@ -60,8 +60,11 @@ ia2Accessible::get_nRelations(long* aNRelations)
if (acc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) {
Relation rel = acc->RelationByType(sRelationTypesForIA2[idx]);
for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) {
if (sRelationTypePairs[idx].second == IA2_RELATION_NULL)
continue;
Relation rel = acc->RelationByType(sRelationTypePairs[idx].first);
if (rel.Next())
(*aNRelations)++;
}
@ -85,8 +88,11 @@ ia2Accessible::get_relation(long aRelationIndex,
return CO_E_OBJNOTCONNECTED;
long relIdx = 0;
for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) {
RelationType relationType = sRelationTypesForIA2[idx];
for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) {
if (sRelationTypePairs[idx].second == IA2_RELATION_NULL)
continue;
RelationType relationType = sRelationTypePairs[idx].first;
Relation rel = acc->RelationByType(relationType);
nsRefPtr<ia2AccessibleRelation> ia2Relation =
new ia2AccessibleRelation(relationType, &rel);
@ -120,9 +126,12 @@ ia2Accessible::get_relations(long aMaxRelations,
if (acc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2) &&
for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs) &&
*aNRelations < aMaxRelations; idx++) {
RelationType relationType = sRelationTypesForIA2[idx];
if (sRelationTypePairs[idx].second == IA2_RELATION_NULL)
continue;
RelationType relationType = sRelationTypePairs[idx].first;
Relation rel = acc->RelationByType(relationType);
nsRefPtr<ia2AccessibleRelation> ia2Rel =
new ia2AccessibleRelation(relationType, &rel);

View File

@ -33,7 +33,7 @@ IMPL_IUNKNOWN_QUERY_TAIL
// IAccessibleRelation
STDMETHODIMP
ia2AccessibleRelation::get_relationType(BSTR *aRelationType)
ia2AccessibleRelation::get_relationType(BSTR* aRelationType)
{
A11Y_TRYBLOCK_BEGIN
@ -42,55 +42,13 @@ ia2AccessibleRelation::get_relationType(BSTR *aRelationType)
*aRelationType = nullptr;
#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \
case RelationType::geckoType: \
*aRelationType = ::SysAllocString(ia2Type); \
break;
switch (mType) {
case RelationType::CONTROLLED_BY:
*aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLED_BY);
break;
case RelationType::CONTROLLER_FOR:
*aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLER_FOR);
break;
case RelationType::DESCRIBED_BY:
*aRelationType = ::SysAllocString(IA2_RELATION_DESCRIBED_BY);
break;
case RelationType::DESCRIPTION_FOR:
*aRelationType = ::SysAllocString(IA2_RELATION_DESCRIPTION_FOR);
break;
case RelationType::EMBEDDED_BY:
*aRelationType = ::SysAllocString(IA2_RELATION_EMBEDDED_BY);
break;
case RelationType::EMBEDS:
*aRelationType = ::SysAllocString(IA2_RELATION_EMBEDS);
break;
case RelationType::FLOWS_FROM:
*aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_FROM);
break;
case RelationType::FLOWS_TO:
*aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_TO);
break;
case RelationType::LABEL_FOR:
*aRelationType = ::SysAllocString(IA2_RELATION_LABEL_FOR);
break;
case RelationType::LABELLED_BY:
*aRelationType = ::SysAllocString(IA2_RELATION_LABELED_BY);
break;
case RelationType::MEMBER_OF:
*aRelationType = ::SysAllocString(IA2_RELATION_MEMBER_OF);
break;
case RelationType::NODE_CHILD_OF:
*aRelationType = ::SysAllocString(IA2_RELATION_NODE_CHILD_OF);
break;
case RelationType::NODE_PARENT_OF:
*aRelationType = ::SysAllocString(IA2_RELATION_NODE_PARENT_OF);
break;
case RelationType::PARENT_WINDOW_OF:
*aRelationType = ::SysAllocString(IA2_RELATION_PARENT_WINDOW_OF);
break;
case RelationType::POPUP_FOR:
*aRelationType = ::SysAllocString(IA2_RELATION_POPUP_FOR);
break;
case RelationType::SUBWINDOW_OF:
*aRelationType = ::SysAllocString(IA2_RELATION_SUBWINDOW_OF);
break;
#include "RelationTypeMap.h"
}
return *aRelationType ? S_OK : E_OUTOFMEMORY;
@ -166,4 +124,3 @@ ia2AccessibleRelation::get_targets(long aMaxTargets, IUnknown **aTargets,
A11Y_TRYBLOCK_END
}

View File

@ -12,6 +12,7 @@
#include "IUnknownImpl.h"
#include "nsIAccessibleRelation.h"
#include <utility>
#include "nsTArray.h"
#include "AccessibleRelation.h"
@ -60,27 +61,20 @@ private:
/**
* Relations exposed to IAccessible2.
* Gecko to IAccessible2 relation types map.
*/
static const RelationType sRelationTypesForIA2[] = {
RelationType::LABELLED_BY,
RelationType::LABEL_FOR,
RelationType::DESCRIBED_BY,
RelationType::DESCRIPTION_FOR,
RelationType::NODE_CHILD_OF,
RelationType::NODE_PARENT_OF,
RelationType::CONTROLLED_BY,
RelationType::CONTROLLER_FOR,
RelationType::FLOWS_TO,
RelationType::FLOWS_FROM,
RelationType::MEMBER_OF,
RelationType::SUBWINDOW_OF,
RelationType::EMBEDS,
RelationType::EMBEDDED_BY,
RelationType::POPUP_FOR,
RelationType::PARENT_WINDOW_OF
const WCHAR *const IA2_RELATION_NULL = L"";
#define RELATIONTYPE(geckoType, name, atkType, msaaType, ia2Type) \
std::pair<RelationType, const WCHAR *const>(RelationType::geckoType, ia2Type),
static const std::pair<RelationType, const WCHAR *const> sRelationTypePairs[] = {
#include "RelationTypeMap.h"
};
#undef RELATIONTYPE
} // namespace a11y
} // namespace mozilla

View File

@ -898,6 +898,11 @@ AccessibleWrap::accNavigate(
Accessible* navAccessible = nullptr;
Maybe<RelationType> xpRelation;
#define RELATIONTYPE(geckoType, stringType, atkType, msaaType, ia2Type) \
case msaaType: \
xpRelation.construct(RelationType::geckoType); \
break;
switch(navDir) {
case NAVDIR_FIRSTCHILD:
if (!nsAccUtils::MustPrune(accessible))
@ -920,62 +925,14 @@ AccessibleWrap::accNavigate(
return E_NOTIMPL;
// MSAA relationship extensions to accNavigate
case NAVRELATION_CONTROLLED_BY:
xpRelation.construct(RelationType::CONTROLLED_BY);
break;
case NAVRELATION_CONTROLLER_FOR:
xpRelation.construct(RelationType::CONTROLLER_FOR);
break;
case NAVRELATION_LABEL_FOR:
xpRelation.construct(RelationType::LABEL_FOR);
break;
case NAVRELATION_LABELLED_BY:
xpRelation.construct(RelationType::LABELLED_BY);
break;
case NAVRELATION_MEMBER_OF:
xpRelation.construct(RelationType::MEMBER_OF);
break;
case NAVRELATION_NODE_CHILD_OF:
xpRelation.construct(RelationType::NODE_CHILD_OF);
break;
case NAVRELATION_FLOWS_TO:
xpRelation.construct(RelationType::FLOWS_TO);
break;
case NAVRELATION_FLOWS_FROM:
xpRelation.construct(RelationType::FLOWS_FROM);
break;
case NAVRELATION_SUBWINDOW_OF:
xpRelation.construct(RelationType::SUBWINDOW_OF);
break;
case NAVRELATION_EMBEDS:
xpRelation.construct(RelationType::EMBEDS);
break;
case NAVRELATION_EMBEDDED_BY:
xpRelation.construct(RelationType::EMBEDDED_BY);
break;
case NAVRELATION_POPUP_FOR:
xpRelation.construct(RelationType::POPUP_FOR);
break;
case NAVRELATION_PARENT_WINDOW_OF:
xpRelation.construct(RelationType::PARENT_WINDOW_OF);
break;
case NAVRELATION_DEFAULT_BUTTON:
xpRelation.construct(RelationType::DEFAULT_BUTTON);
break;
case NAVRELATION_DESCRIBED_BY:
xpRelation.construct(RelationType::DESCRIBED_BY);
break;
case NAVRELATION_DESCRIPTION_FOR:
xpRelation.construct(RelationType::DESCRIPTION_FOR);
break;
case NAVRELATION_NODE_PARENT_OF:
xpRelation.construct(RelationType::NODE_PARENT_OF);
break;
#include "RelationTypeMap.h"
default:
return E_INVALIDARG;
}
#undef RELATIONTYPE
pvarEndUpAt->vt = VT_EMPTY;
if (!xpRelation.empty()) {