accessible/src/mac/mozActionElements.mm

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

michael@0 1 /* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #import "mozActionElements.h"
michael@0 7
michael@0 8 #import "MacUtils.h"
michael@0 9 #include "Accessible-inl.h"
michael@0 10 #include "DocAccessible.h"
michael@0 11 #include "XULTabAccessible.h"
michael@0 12
michael@0 13 #include "nsDeckFrame.h"
michael@0 14 #include "nsObjCExceptions.h"
michael@0 15
michael@0 16 using namespace mozilla::a11y;
michael@0 17
michael@0 18 enum CheckboxValue {
michael@0 19 // these constants correspond to the values in the OS
michael@0 20 kUnchecked = 0,
michael@0 21 kChecked = 1,
michael@0 22 kMixed = 2
michael@0 23 };
michael@0 24
michael@0 25 @implementation mozButtonAccessible
michael@0 26
michael@0 27 - (NSArray*)accessibilityAttributeNames
michael@0 28 {
michael@0 29 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 30
michael@0 31 static NSArray *attributes = nil;
michael@0 32 if (!attributes) {
michael@0 33 attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
michael@0 34 NSAccessibilityRoleAttribute, // required
michael@0 35 NSAccessibilityRoleDescriptionAttribute,
michael@0 36 NSAccessibilityPositionAttribute, // required
michael@0 37 NSAccessibilitySizeAttribute, // required
michael@0 38 NSAccessibilityWindowAttribute, // required
michael@0 39 NSAccessibilityPositionAttribute, // required
michael@0 40 NSAccessibilityTopLevelUIElementAttribute, // required
michael@0 41 NSAccessibilityHelpAttribute,
michael@0 42 NSAccessibilityEnabledAttribute, // required
michael@0 43 NSAccessibilityFocusedAttribute, // required
michael@0 44 NSAccessibilityTitleAttribute, // required
michael@0 45 NSAccessibilityDescriptionAttribute,
michael@0 46 #if DEBUG
michael@0 47 @"AXMozDescription",
michael@0 48 #endif
michael@0 49 nil];
michael@0 50 }
michael@0 51 return attributes;
michael@0 52
michael@0 53 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 54 }
michael@0 55
michael@0 56 - (id)accessibilityAttributeValue:(NSString *)attribute
michael@0 57 {
michael@0 58 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 59
michael@0 60 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
michael@0 61 return nil;
michael@0 62 if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
michael@0 63 if ([self isTab])
michael@0 64 return utils::LocalizedString(NS_LITERAL_STRING("tab"));
michael@0 65
michael@0 66 return NSAccessibilityRoleDescription([self role], nil);
michael@0 67 }
michael@0 68
michael@0 69 return [super accessibilityAttributeValue:attribute];
michael@0 70
michael@0 71 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 72 }
michael@0 73
michael@0 74 - (BOOL)accessibilityIsIgnored
michael@0 75 {
michael@0 76 return !mGeckoAccessible;
michael@0 77 }
michael@0 78
michael@0 79 - (NSArray*)accessibilityActionNames
michael@0 80 {
michael@0 81 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 82
michael@0 83 if ([self isEnabled])
michael@0 84 return [NSArray arrayWithObject:NSAccessibilityPressAction];
michael@0 85
michael@0 86 return nil;
michael@0 87
michael@0 88 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 89 }
michael@0 90
michael@0 91 - (NSString*)accessibilityActionDescription:(NSString*)action
michael@0 92 {
michael@0 93 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 94
michael@0 95 if ([action isEqualToString:NSAccessibilityPressAction]) {
michael@0 96 if ([self isTab])
michael@0 97 return utils::LocalizedString(NS_LITERAL_STRING("switch"));
michael@0 98
michael@0 99 return @"press button"; // XXX: localize this later?
michael@0 100 }
michael@0 101
michael@0 102 return nil;
michael@0 103
michael@0 104 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 105 }
michael@0 106
michael@0 107 - (void)accessibilityPerformAction:(NSString*)action
michael@0 108 {
michael@0 109 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
michael@0 110
michael@0 111 if ([action isEqualToString:NSAccessibilityPressAction])
michael@0 112 [self click];
michael@0 113
michael@0 114 NS_OBJC_END_TRY_ABORT_BLOCK;
michael@0 115 }
michael@0 116
michael@0 117 - (void)click
michael@0 118 {
michael@0 119 // both buttons and checkboxes have only one action. we should really stop using arbitrary
michael@0 120 // arrays with actions, and define constants for these actions.
michael@0 121 mGeckoAccessible->DoAction(0);
michael@0 122 }
michael@0 123
michael@0 124 - (BOOL)isTab
michael@0 125 {
michael@0 126 return (mGeckoAccessible && (mGeckoAccessible->Role() == roles::PAGETAB));
michael@0 127 }
michael@0 128
michael@0 129 @end
michael@0 130
michael@0 131 @implementation mozCheckboxAccessible
michael@0 132
michael@0 133 - (NSString*)accessibilityActionDescription:(NSString*)action
michael@0 134 {
michael@0 135 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 136
michael@0 137 if ([action isEqualToString:NSAccessibilityPressAction]) {
michael@0 138 if ([self isChecked] != kUnchecked)
michael@0 139 return @"uncheck checkbox"; // XXX: localize this later?
michael@0 140
michael@0 141 return @"check checkbox"; // XXX: localize this later?
michael@0 142 }
michael@0 143
michael@0 144 return nil;
michael@0 145
michael@0 146 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 147 }
michael@0 148
michael@0 149 - (int)isChecked
michael@0 150 {
michael@0 151 uint64_t state = mGeckoAccessible->NativeState();
michael@0 152
michael@0 153 // check if we're checked or in a mixed state
michael@0 154 if (state & states::CHECKED) {
michael@0 155 return (state & states::MIXED) ? kMixed : kChecked;
michael@0 156 }
michael@0 157
michael@0 158 return kUnchecked;
michael@0 159 }
michael@0 160
michael@0 161 - (id)value
michael@0 162 {
michael@0 163 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 164
michael@0 165 return [NSNumber numberWithInt:[self isChecked]];
michael@0 166
michael@0 167 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 168 }
michael@0 169
michael@0 170 @end
michael@0 171
michael@0 172 @implementation mozPopupButtonAccessible
michael@0 173
michael@0 174 - (NSArray *)accessibilityAttributeNames
michael@0 175 {
michael@0 176 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 177
michael@0 178 static NSArray *attributes = nil;
michael@0 179
michael@0 180 if (!attributes) {
michael@0 181 attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
michael@0 182 NSAccessibilityPositionAttribute, // required
michael@0 183 NSAccessibilityRoleAttribute, // required
michael@0 184 NSAccessibilitySizeAttribute, // required
michael@0 185 NSAccessibilityWindowAttribute, // required
michael@0 186 NSAccessibilityTopLevelUIElementAttribute, // required
michael@0 187 NSAccessibilityHelpAttribute,
michael@0 188 NSAccessibilityEnabledAttribute, // required
michael@0 189 NSAccessibilityFocusedAttribute, // required
michael@0 190 NSAccessibilityTitleAttribute, // required for popupmenus, and for menubuttons with a title
michael@0 191 NSAccessibilityChildrenAttribute, // required
michael@0 192 NSAccessibilityDescriptionAttribute, // required if it has no title attr
michael@0 193 #if DEBUG
michael@0 194 @"AXMozDescription",
michael@0 195 #endif
michael@0 196 nil];
michael@0 197 }
michael@0 198 return attributes;
michael@0 199
michael@0 200 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 201 }
michael@0 202
michael@0 203 - (id)accessibilityAttributeValue:(NSString *)attribute
michael@0 204 {
michael@0 205 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 206
michael@0 207 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
michael@0 208 return [super children];
michael@0 209 }
michael@0 210 return [super accessibilityAttributeValue:attribute];
michael@0 211
michael@0 212 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 213 }
michael@0 214
michael@0 215 - (NSArray *)accessibilityActionNames
michael@0 216 {
michael@0 217 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 218
michael@0 219 if ([self isEnabled]) {
michael@0 220 return [NSArray arrayWithObjects:NSAccessibilityPressAction,
michael@0 221 NSAccessibilityShowMenuAction,
michael@0 222 nil];
michael@0 223 }
michael@0 224 return nil;
michael@0 225
michael@0 226 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 227 }
michael@0 228
michael@0 229 - (NSString *)accessibilityActionDescription:(NSString *)action
michael@0 230 {
michael@0 231 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
michael@0 232
michael@0 233 if ([action isEqualToString:NSAccessibilityShowMenuAction])
michael@0 234 return @"show menu";
michael@0 235 return [super accessibilityActionDescription:action];
michael@0 236
michael@0 237 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
michael@0 238 }
michael@0 239
michael@0 240 - (void)accessibilityPerformAction:(NSString *)action
michael@0 241 {
michael@0 242 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
michael@0 243
michael@0 244 // both the ShowMenu and Click action do the same thing.
michael@0 245 if ([self isEnabled]) {
michael@0 246 // TODO: this should bring up the menu, but currently doesn't.
michael@0 247 // once msaa and atk have merged better, they will implement
michael@0 248 // the action needed to show the menu.
michael@0 249 [super click];
michael@0 250 }
michael@0 251
michael@0 252 NS_OBJC_END_TRY_ABORT_BLOCK;
michael@0 253 }
michael@0 254
michael@0 255 @end
michael@0 256
michael@0 257 @implementation mozTabsAccessible
michael@0 258
michael@0 259 - (void)dealloc
michael@0 260 {
michael@0 261 [mTabs release];
michael@0 262
michael@0 263 [super dealloc];
michael@0 264 }
michael@0 265
michael@0 266 - (NSArray*)accessibilityAttributeNames
michael@0 267 {
michael@0 268 // standard attributes that are shared and supported by root accessible (AXMain) elements.
michael@0 269 static NSMutableArray* attributes = nil;
michael@0 270
michael@0 271 if (!attributes) {
michael@0 272 attributes = [[super accessibilityAttributeNames] mutableCopy];
michael@0 273 [attributes addObject:NSAccessibilityContentsAttribute];
michael@0 274 [attributes addObject:NSAccessibilityTabsAttribute];
michael@0 275 }
michael@0 276
michael@0 277 return attributes;
michael@0 278 }
michael@0 279
michael@0 280 - (id)accessibilityAttributeValue:(NSString *)attribute
michael@0 281 {
michael@0 282 if ([attribute isEqualToString:NSAccessibilityContentsAttribute])
michael@0 283 return [super children];
michael@0 284 if ([attribute isEqualToString:NSAccessibilityTabsAttribute])
michael@0 285 return [self tabs];
michael@0 286
michael@0 287 return [super accessibilityAttributeValue:attribute];
michael@0 288 }
michael@0 289
michael@0 290 /**
michael@0 291 * Returns the selected tab (the mozAccessible)
michael@0 292 */
michael@0 293 - (id)value
michael@0 294 {
michael@0 295 if (!mGeckoAccessible)
michael@0 296 return nil;
michael@0 297
michael@0 298 Accessible* accessible = mGeckoAccessible->GetSelectedItem(0);
michael@0 299 if (!accessible)
michael@0 300 return nil;
michael@0 301
michael@0 302 mozAccessible* nativeAcc = nil;
michael@0 303 nsresult rv = accessible->GetNativeInterface((void**)&nativeAcc);
michael@0 304 NS_ENSURE_SUCCESS(rv, nil);
michael@0 305
michael@0 306 return nativeAcc;
michael@0 307 }
michael@0 308
michael@0 309 /**
michael@0 310 * Return the mozAccessibles that are the tabs.
michael@0 311 */
michael@0 312 - (id)tabs
michael@0 313 {
michael@0 314 if (mTabs)
michael@0 315 return mTabs;
michael@0 316
michael@0 317 NSArray* children = [self children];
michael@0 318 NSEnumerator* enumerator = [children objectEnumerator];
michael@0 319 mTabs = [[NSMutableArray alloc] init];
michael@0 320
michael@0 321 id obj;
michael@0 322 while ((obj = [enumerator nextObject]))
michael@0 323 if ([obj isTab])
michael@0 324 [mTabs addObject:obj];
michael@0 325
michael@0 326 return mTabs;
michael@0 327 }
michael@0 328
michael@0 329 - (void)invalidateChildren
michael@0 330 {
michael@0 331 [super invalidateChildren];
michael@0 332
michael@0 333 [mTabs release];
michael@0 334 mTabs = nil;
michael@0 335 }
michael@0 336
michael@0 337 @end
michael@0 338
michael@0 339 @implementation mozPaneAccessible
michael@0 340
michael@0 341 - (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
michael@0 342 {
michael@0 343 if (!mGeckoAccessible)
michael@0 344 return 0;
michael@0 345
michael@0 346 // By default this calls -[[mozAccessible children] count].
michael@0 347 // Since we don't cache mChildren. This is faster.
michael@0 348 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
michael@0 349 return mGeckoAccessible->ChildCount() ? 1 : 0;
michael@0 350
michael@0 351 return [super accessibilityArrayAttributeCount:attribute];
michael@0 352 }
michael@0 353
michael@0 354 - (NSArray*)children
michael@0 355 {
michael@0 356 if (!mGeckoAccessible)
michael@0 357 return nil;
michael@0 358
michael@0 359 nsDeckFrame* deckFrame = do_QueryFrame(mGeckoAccessible->GetFrame());
michael@0 360 nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
michael@0 361
michael@0 362 Accessible* selectedAcc = nullptr;
michael@0 363 if (selectedFrame) {
michael@0 364 nsINode* node = selectedFrame->GetContent();
michael@0 365 selectedAcc = mGeckoAccessible->Document()->GetAccessible(node);
michael@0 366 }
michael@0 367
michael@0 368 if (selectedAcc) {
michael@0 369 mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
michael@0 370 if (curNative)
michael@0 371 return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
michael@0 372 }
michael@0 373
michael@0 374 return nil;
michael@0 375 }
michael@0 376
michael@0 377 @end

mercurial