Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "AccessibleNode.h"
7 : #include "mozilla/dom/AccessibleNodeBinding.h"
8 : #include "mozilla/dom/BindingDeclarations.h"
9 : #include "mozilla/dom/DOMStringList.h"
10 : #include "nsIPersistentProperties2.h"
11 : #include "nsISimpleEnumerator.h"
12 :
13 : #include "Accessible-inl.h"
14 : #include "nsAccessibilityService.h"
15 : #include "DocAccessible.h"
16 :
17 : using namespace mozilla;
18 : using namespace mozilla::a11y;
19 : using namespace mozilla::dom;
20 :
21 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(AccessibleNode)
22 :
23 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AccessibleNode)
24 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
25 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
26 0 : NS_INTERFACE_MAP_END
27 :
28 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode)
29 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
30 :
31 0 : AccessibleNode::AccessibleNode(nsINode* aNode) : mDOMNode(aNode)
32 : {
33 : DocAccessible* doc =
34 0 : GetOrCreateAccService()->GetDocAccessible(mDOMNode->OwnerDoc());
35 0 : if (doc) {
36 0 : mIntl = doc->GetAccessible(mDOMNode);
37 : }
38 0 : }
39 :
40 0 : AccessibleNode::~AccessibleNode()
41 : {
42 0 : }
43 :
44 : /* virtual */ JSObject*
45 0 : AccessibleNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
46 : {
47 0 : return AccessibleNodeBinding::Wrap(aCx, this, aGivenProto);
48 : }
49 :
50 : /* virtual */ ParentObject
51 0 : AccessibleNode::GetParentObject() const
52 : {
53 0 : return mDOMNode->GetParentObject();
54 : }
55 :
56 : void
57 0 : AccessibleNode::GetRole(nsAString& aRole)
58 : {
59 0 : if (mIntl) {
60 0 : GetOrCreateAccService()->GetStringRole(mIntl->Role(), aRole);
61 0 : return;
62 : }
63 :
64 0 : aRole.AssignLiteral("unknown");
65 : }
66 :
67 : void
68 0 : AccessibleNode::GetStates(nsTArray<nsString>& aStates)
69 : {
70 0 : if (mIntl) {
71 0 : if (!mStates) {
72 0 : mStates = GetOrCreateAccService()->GetStringStates(mIntl->State());
73 : }
74 0 : aStates = mStates->StringArray();
75 0 : return;
76 : }
77 :
78 0 : aStates.AppendElement(NS_LITERAL_STRING("defunct"));
79 : }
80 :
81 : void
82 0 : AccessibleNode::GetAttributes(nsTArray<nsString>& aAttributes)
83 : {
84 0 : if (!mIntl) {
85 0 : return;
86 : }
87 :
88 0 : nsCOMPtr<nsIPersistentProperties> attrs = mIntl->Attributes();
89 :
90 0 : nsCOMPtr<nsISimpleEnumerator> props;
91 0 : attrs->Enumerate(getter_AddRefs(props));
92 :
93 0 : bool hasMore = false;
94 0 : while (NS_SUCCEEDED(props->HasMoreElements(&hasMore)) && hasMore) {
95 0 : nsCOMPtr<nsISupports> supp;
96 0 : props->GetNext(getter_AddRefs(supp));
97 :
98 0 : nsCOMPtr<nsIPropertyElement> prop(do_QueryInterface(supp));
99 :
100 0 : nsAutoCString attr;
101 0 : prop->GetKey(attr);
102 0 : aAttributes.AppendElement(NS_ConvertUTF8toUTF16(attr));
103 : }
104 : }
105 :
106 : bool
107 0 : AccessibleNode::Is(const Sequence<nsString>& aFlavors)
108 : {
109 0 : if (!mIntl) {
110 0 : for (const auto& flavor : aFlavors) {
111 0 : if (!flavor.EqualsLiteral("unknown") && !flavor.EqualsLiteral("defunct")) {
112 0 : return false;
113 : }
114 : }
115 0 : return true;
116 : }
117 :
118 0 : nsAutoString role;
119 0 : GetOrCreateAccService()->GetStringRole(mIntl->Role(), role);
120 :
121 0 : if (!mStates) {
122 0 : mStates = GetOrCreateAccService()->GetStringStates(mIntl->State());
123 : }
124 :
125 0 : for (const auto& flavor : aFlavors) {
126 0 : if (!flavor.Equals(role) && !mStates->Contains(flavor)) {
127 0 : return false;
128 : }
129 : }
130 0 : return true;
131 : }
132 :
133 : bool
134 0 : AccessibleNode::Has(const Sequence<nsString>& aAttributes)
135 : {
136 0 : if (!mIntl) {
137 0 : return false;
138 : }
139 0 : nsCOMPtr<nsIPersistentProperties> attrs = mIntl->Attributes();
140 0 : for (const auto& attr : aAttributes) {
141 0 : bool has = false;
142 0 : attrs->Has(NS_ConvertUTF16toUTF8(attr).get(), &has);
143 0 : if (!has) {
144 0 : return false;
145 : }
146 : }
147 0 : return true;
148 : }
149 :
150 : void
151 0 : AccessibleNode::Get(JSContext* aCX, const nsAString& aAttribute,
152 : JS::MutableHandle<JS::Value> aValue,
153 : ErrorResult& aRv)
154 : {
155 0 : if (!mIntl) {
156 0 : aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
157 0 : return;
158 : }
159 :
160 0 : nsCOMPtr<nsIPersistentProperties> attrs = mIntl->Attributes();
161 0 : nsAutoString value;
162 0 : attrs->GetStringProperty(NS_ConvertUTF16toUTF8(aAttribute), value);
163 :
164 0 : JS::Rooted<JS::Value> jsval(aCX);
165 0 : if (!ToJSValue(aCX, value, &jsval)) {
166 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
167 0 : return;
168 : }
169 :
170 0 : aValue.set(jsval);
171 : }
172 :
173 : nsINode*
174 0 : AccessibleNode::GetDOMNode()
175 : {
176 0 : return mDOMNode;
177 : }
|