Bumping manifests a=b2g-bump
[gecko.git] / accessible / mac / mozActionElements.mm
blobc361f2d765aa01c43cd658af89f2ae51d68f3fea
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"
8 #import "MacUtils.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;
18 enum CheckboxValue {
19   // these constants correspond to the values in the OS
20   kUnchecked = 0,
21   kChecked = 1,
22   kMixed = 2
25 @implementation mozButtonAccessible
27 - (NSArray*)accessibilityAttributeNames
29   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
31   static NSArray *attributes = nil;
32   if (!attributes) {
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,
46 #if DEBUG
47                                                   @"AXMozDescription",
48 #endif
49                                                   nil];
50   }
51   return attributes;
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])
61     return nil;
62   if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
63     if ([self isTab])
64       return utils::LocalizedString(NS_LITERAL_STRING("tab"));
65     
66     return NSAccessibilityRoleDescription([self role], nil);
67   }
68   
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;
83   if ([self isEnabled])
84     return [NSArray arrayWithObject:NSAccessibilityPressAction];
85     
86   return nil;
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]) {
96     if ([self isTab])
97       return utils::LocalizedString(NS_LITERAL_STRING("switch"));
98   
99     return @"press button"; // XXX: localize this later?
100   }
101   
102   return nil;
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])
112     [self click];
114   NS_OBJC_END_TRY_ABORT_BLOCK;
117 - (void)click
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);
124 - (BOOL)isTab
126   return (mGeckoAccessible && (mGeckoAccessible->Role() == roles::PAGETAB));
129 @end
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?
140     
141     return @"check checkbox"; // XXX: localize this later?
142   }
143   
144   return nil;
146   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
149 - (int)isChecked
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;
156   }
157   
158   return kUnchecked;
161 - (id)value
163   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
165   return [NSNumber numberWithInt:[self isChecked]];
167   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
170 @end
172 @implementation mozPopupButtonAccessible
174 - (NSArray *)accessibilityAttributeNames
176   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
178   static NSArray *attributes = nil;
179   
180   if (!attributes) {
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
193 #if DEBUG
194                                                   @"AXMozDescription",
195 #endif
196                                                   nil];
197   }
198   return attributes;
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];
209   }
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,
222                                      nil];
223   }
224   return nil;
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])
234     return @"show menu";
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.
249     [super click];
250   }
252   NS_OBJC_END_TRY_ABORT_BLOCK;
255 @end
257 @implementation mozTabsAccessible
259 - (void)dealloc
261   [mTabs release];
263   [super dealloc];
266 - (NSArray*)accessibilityAttributeNames
268   // standard attributes that are shared and supported by root accessible (AXMain) elements.
269   static NSMutableArray* attributes = nil;
270   
271   if (!attributes) {
272     attributes = [[super accessibilityAttributeNames] mutableCopy];
273     [attributes addObject:NSAccessibilityContentsAttribute];
274     [attributes addObject:NSAccessibilityTabsAttribute];
275   }
276   
277   return attributes;  
280 - (id)accessibilityAttributeValue:(NSString *)attribute
281 {  
282   if ([attribute isEqualToString:NSAccessibilityContentsAttribute])
283     return [super children];
284   if ([attribute isEqualToString:NSAccessibilityTabsAttribute])
285     return [self tabs];
286   
287   return [super accessibilityAttributeValue:attribute];  
291  * Returns the selected tab (the mozAccessible)
292  */
293 - (id)value
295   if (!mGeckoAccessible)
296     return nil;
298   Accessible* accessible = mGeckoAccessible->GetSelectedItem(0);
299   if (!accessible)
300     return nil;
302   mozAccessible* nativeAcc = nil;
303   accessible->GetNativeInterface((void**)&nativeAcc);
305   return nativeAcc;
309  * Return the mozAccessibles that are the tabs.
310  */
311 - (id)tabs
313   if (mTabs)
314     return mTabs;
316   NSArray* children = [self children];
317   NSEnumerator* enumerator = [children objectEnumerator];
318   mTabs = [[NSMutableArray alloc] init];
319   
320   id obj;
321   while ((obj = [enumerator nextObject]))
322     if ([obj isTab])
323       [mTabs addObject:obj];
325   return mTabs;
328 - (void)invalidateChildren
330   [super invalidateChildren];
332   [mTabs release];
333   mTabs = nil;
336 @end
338 @implementation mozPaneAccessible
340 - (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
342   if (!mGeckoAccessible)
343     return 0;
345   // By default this calls -[[mozAccessible children] count].
346   // Since we don't cache mChildren. This is faster.
347   if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
348     return mGeckoAccessible->ChildCount() ? 1 : 0;
350   return [super accessibilityArrayAttributeCount:attribute];
353 - (NSArray*)children
355   if (!mGeckoAccessible)
356     return nil;
358   nsDeckFrame* deckFrame = do_QueryFrame(mGeckoAccessible->GetFrame());
359   nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
361   Accessible* selectedAcc = nullptr;
362   if (selectedFrame) {
363     nsINode* node = selectedFrame->GetContent();
364     selectedAcc = mGeckoAccessible->Document()->GetAccessible(node);
365   }
367   if (selectedAcc) {
368     mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
369     if (curNative)
370       return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
371   }
373   return nil;
376 @end