1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
/* -*- 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 "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "DocAccessible.h"
#include "nsMai.h"
#include "ProxyAccessible.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
static const char* const kDocTypeName = "W3C-doctype";
static const char* const kDocUrlName = "DocURL";
static const char* const kMimeTypeName = "MimeType";
// below functions are vfuncs on an ATK interface so they need to be C call
extern "C" {
static const gchar* getDocumentLocaleCB(AtkDocument* aDocument);
static AtkAttributeSet* getDocumentAttributesCB(AtkDocument* aDocument);
static const gchar* getDocumentAttributeValueCB(AtkDocument* aDocument,
const gchar* aAttrName);
void
documentInterfaceInitCB(AtkDocumentIface *aIface)
{
NS_ASSERTION(aIface, "Invalid Interface");
if(MOZ_UNLIKELY(!aIface))
return;
/*
* We don't support get_document or set_attribute right now.
* get_document_type is deprecated, we return DocType in
* get_document_attribute_value and get_document_attributes instead.
*/
aIface->get_document_attributes = getDocumentAttributesCB;
aIface->get_document_attribute_value = getDocumentAttributeValueCB;
aIface->get_document_locale = getDocumentLocaleCB;
}
const gchar *
getDocumentLocaleCB(AtkDocument *aDocument)
{
nsAutoString locale;
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
if (accWrap) {
accWrap->Language(locale);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aDocument))) {
proxy->Language(locale);
}
return locale.IsEmpty() ? nullptr : AccessibleWrap::ReturnString(locale);
}
static inline GSList *
prependToList(GSList *aList, const char *const aName, const nsAutoString &aValue)
{
if (aValue.IsEmpty()) {
return aList;
}
// libspi will free these
AtkAttribute *atkAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
atkAttr->name = g_strdup(aName);
atkAttr->value = g_strdup(NS_ConvertUTF16toUTF8(aValue).get());
return g_slist_prepend(aList, atkAttr);
}
AtkAttributeSet *
getDocumentAttributesCB(AtkDocument *aDocument)
{
nsAutoString url;
nsAutoString w3cDocType;
nsAutoString mimeType;
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
if (accWrap) {
if (!accWrap->IsDoc()) {
return nullptr;
}
DocAccessible* document = accWrap->AsDoc();
document->URL(url);
document->DocType(w3cDocType);
document->MimeType(mimeType);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aDocument))) {
proxy->URLDocTypeMimeType(url, w3cDocType, mimeType);
} else {
return nullptr;
}
// according to atkobject.h, AtkAttributeSet is a GSList
GSList* attributes = nullptr;
attributes = prependToList(attributes, kDocUrlName, url);
attributes = prependToList(attributes, kDocTypeName, w3cDocType);
attributes = prependToList(attributes, kMimeTypeName, mimeType);
return attributes;
}
const gchar *
getDocumentAttributeValueCB(AtkDocument *aDocument,
const gchar *aAttrName)
{
ProxyAccessible* proxy = nullptr;
DocAccessible* document = nullptr;
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
if (accWrap) {
if (!accWrap->IsDoc()) {
return nullptr;
}
document = accWrap->AsDoc();
} else {
proxy = GetProxy(ATK_OBJECT(aDocument));
if (!proxy) {
return nullptr;
}
}
nsAutoString attrValue;
if (!strcasecmp(aAttrName, kDocTypeName)) {
if (document) {
document->DocType(attrValue);
} else {
proxy->DocType(attrValue);
}
} else if (!strcasecmp(aAttrName, kDocUrlName)) {
if (document) {
document->URL(attrValue);
} else {
proxy->URL(attrValue);
}
} else if (!strcasecmp(aAttrName, kMimeTypeName)) {
if (document) {
document->MimeType(attrValue);
} else {
proxy->MimeType(attrValue);
}
} else {
return nullptr;
}
return attrValue.IsEmpty() ? nullptr : AccessibleWrap::ReturnString(attrValue);
}
}
|