1 /* -*- Mode: Objective-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/. */
6 #import "mozActionElements.h"
9 #include "Accessible-inl.h"
10 #include "DocAccessible.h"
11 #include "XULTabAccessible.h"
13 #include "nsDeckFrame.h"
14 #include "nsObjCExceptions.h"
16 using namespace mozilla::a11y;
19 // these constants correspond to the values in the OS
25 @implementation mozButtonAccessible
27 - (NSArray*)accessibilityAttributeNames
29 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
31 static NSArray *attributes = nil;
33 attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
34 NSAccessibilityRoleAttribute, // required
35 NSAccessibilityRoleDescriptionAttribute,
36 NSAccessibilityPositionAttribute, // required
37 NSAccessibilitySizeAttribute, // required
38 NSAccessibilityWindowAttribute, // required
39 NSAccessibilityPositionAttribute, // required
40 NSAccessibilityTopLevelUIElementAttribute, // required
41 NSAccessibilityHelpAttribute,
42 NSAccessibilityEnabledAttribute, // required
43 NSAccessibilityFocusedAttribute, // required
44 NSAccessibilityTitleAttribute, // required
45 NSAccessibilityDescriptionAttribute,
53 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
56 - (id)accessibilityAttributeValue:(NSString *)attribute
58 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
60 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
62 if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
64 return utils::LocalizedString(NS_LITERAL_STRING("tab"));
66 return NSAccessibilityRoleDescription([self role], nil);
69 return [super accessibilityAttributeValue:attribute];
71 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
74 - (BOOL)accessibilityIsIgnored
76 return !mGeckoAccessible;
79 - (NSArray*)accessibilityActionNames
81 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
84 return [NSArray arrayWithObject:NSAccessibilityPressAction];
88 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
91 - (NSString*)accessibilityActionDescription:(NSString*)action
93 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
95 if ([action isEqualToString:NSAccessibilityPressAction]) {
97 return utils::LocalizedString(NS_LITERAL_STRING("switch"));
99 return @"press button"; // XXX: localize this later?
104 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
107 - (void)accessibilityPerformAction:(NSString*)action
109 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
111 if ([action isEqualToString:NSAccessibilityPressAction])
114 NS_OBJC_END_TRY_ABORT_BLOCK;
119 // both buttons and checkboxes have only one action. we should really stop using arbitrary
120 // arrays with actions, and define constants for these actions.
121 mGeckoAccessible->DoAction(0);
126 return (mGeckoAccessible && (mGeckoAccessible->Role() == roles::PAGETAB));
131 @implementation mozCheckboxAccessible
133 - (NSString*)accessibilityActionDescription:(NSString*)action
135 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
137 if ([action isEqualToString:NSAccessibilityPressAction]) {
138 if ([self isChecked] != kUnchecked)
139 return @"uncheck checkbox"; // XXX: localize this later?
141 return @"check checkbox"; // XXX: localize this later?
146 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
151 uint64_t state = mGeckoAccessible->NativeState();
153 // check if we're checked or in a mixed state
154 if (state & states::CHECKED) {
155 return (state & states::MIXED) ? kMixed : kChecked;
163 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
165 return [NSNumber numberWithInt:[self isChecked]];
167 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
172 @implementation mozPopupButtonAccessible
174 - (NSArray *)accessibilityAttributeNames
176 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
178 static NSArray *attributes = nil;
181 attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
182 NSAccessibilityPositionAttribute, // required
183 NSAccessibilityRoleAttribute, // required
184 NSAccessibilitySizeAttribute, // required
185 NSAccessibilityWindowAttribute, // required
186 NSAccessibilityTopLevelUIElementAttribute, // required
187 NSAccessibilityHelpAttribute,
188 NSAccessibilityEnabledAttribute, // required
189 NSAccessibilityFocusedAttribute, // required
190 NSAccessibilityTitleAttribute, // required for popupmenus, and for menubuttons with a title
191 NSAccessibilityChildrenAttribute, // required
192 NSAccessibilityDescriptionAttribute, // required if it has no title attr
200 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
203 - (id)accessibilityAttributeValue:(NSString *)attribute
205 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
207 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
208 return [super children];
210 return [super accessibilityAttributeValue:attribute];
212 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
215 - (NSArray *)accessibilityActionNames
217 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
219 if ([self isEnabled]) {
220 return [NSArray arrayWithObjects:NSAccessibilityPressAction,
221 NSAccessibilityShowMenuAction,
226 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
229 - (NSString *)accessibilityActionDescription:(NSString *)action
231 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
233 if ([action isEqualToString:NSAccessibilityShowMenuAction])
235 return [super accessibilityActionDescription:action];
237 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
240 - (void)accessibilityPerformAction:(NSString *)action
242 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
244 // both the ShowMenu and Click action do the same thing.
245 if ([self isEnabled]) {
246 // TODO: this should bring up the menu, but currently doesn't.
247 // once msaa and atk have merged better, they will implement
248 // the action needed to show the menu.
252 NS_OBJC_END_TRY_ABORT_BLOCK;
257 @implementation mozTabsAccessible
266 - (NSArray*)accessibilityAttributeNames
268 // standard attributes that are shared and supported by root accessible (AXMain) elements.
269 static NSMutableArray* attributes = nil;
272 attributes = [[super accessibilityAttributeNames] mutableCopy];
273 [attributes addObject:NSAccessibilityContentsAttribute];
274 [attributes addObject:NSAccessibilityTabsAttribute];
280 - (id)accessibilityAttributeValue:(NSString *)attribute
282 if ([attribute isEqualToString:NSAccessibilityContentsAttribute])
283 return [super children];
284 if ([attribute isEqualToString:NSAccessibilityTabsAttribute])
287 return [super accessibilityAttributeValue:attribute];
291 * Returns the selected tab (the mozAccessible)
295 if (!mGeckoAccessible)
298 Accessible* accessible = mGeckoAccessible->GetSelectedItem(0);
302 mozAccessible* nativeAcc = nil;
303 nsresult rv = accessible->GetNativeInterface((void**)&nativeAcc);
304 NS_ENSURE_SUCCESS(rv, nil);
310 * Return the mozAccessibles that are the tabs.
317 NSArray* children = [self children];
318 NSEnumerator* enumerator = [children objectEnumerator];
319 mTabs = [[NSMutableArray alloc] init];
322 while ((obj = [enumerator nextObject]))
324 [mTabs addObject:obj];
329 - (void)invalidateChildren
331 [super invalidateChildren];
339 @implementation mozPaneAccessible
341 - (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
343 if (!mGeckoAccessible)
346 // By default this calls -[[mozAccessible children] count].
347 // Since we don't cache mChildren. This is faster.
348 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
349 return mGeckoAccessible->ChildCount() ? 1 : 0;
351 return [super accessibilityArrayAttributeCount:attribute];
356 if (!mGeckoAccessible)
359 nsDeckFrame* deckFrame = do_QueryFrame(mGeckoAccessible->GetFrame());
360 nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
362 Accessible* selectedAcc = nullptr;
364 nsINode* node = selectedFrame->GetContent();
365 selectedAcc = mGeckoAccessible->Document()->GetAccessible(node);
369 mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
371 return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];