2006-11-24 17:37:00 +03:00
|
|
|
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2006-11-24 17:37:00 +03:00
|
|
|
|
2006-11-15 14:08:14 +03:00
|
|
|
#import "mozActionElements.h"
|
2012-01-27 10:14:09 +04:00
|
|
|
|
|
|
|
#import "MacUtils.h"
|
2012-04-13 18:17:03 +04:00
|
|
|
#include "Accessible-inl.h"
|
2012-06-29 03:04:50 +04:00
|
|
|
#include "DocAccessible.h"
|
2012-06-11 03:44:50 +04:00
|
|
|
#include "XULTabAccessible.h"
|
2006-11-15 14:08:14 +03:00
|
|
|
|
2012-06-29 03:04:50 +04:00
|
|
|
#include "nsDeckFrame.h"
|
2008-02-22 23:13:17 +03:00
|
|
|
#include "nsObjCExceptions.h"
|
|
|
|
|
2011-07-27 16:43:01 +04:00
|
|
|
using namespace mozilla::a11y;
|
|
|
|
|
2006-11-24 17:37:00 +03:00
|
|
|
enum CheckboxValue {
|
|
|
|
// these constants correspond to the values in the OS
|
|
|
|
kUnchecked = 0,
|
|
|
|
kChecked = 1,
|
|
|
|
kMixed = 2
|
|
|
|
};
|
|
|
|
|
2006-11-15 14:08:14 +03:00
|
|
|
@implementation mozButtonAccessible
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (NSArray*)accessibilityAttributeNames {
|
2008-02-22 23:13:17 +03:00
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
static NSArray* attributes = nil;
|
2006-11-15 14:08:14 +03:00
|
|
|
if (!attributes) {
|
2019-01-21 20:18:16 +03:00
|
|
|
attributes = [[NSArray alloc]
|
|
|
|
initWithObjects:NSAccessibilityParentAttribute, // required
|
|
|
|
NSAccessibilityRoleAttribute, // required
|
|
|
|
NSAccessibilityRoleDescriptionAttribute,
|
|
|
|
NSAccessibilityPositionAttribute, // required
|
|
|
|
NSAccessibilitySizeAttribute, // required
|
|
|
|
NSAccessibilityWindowAttribute, // required
|
|
|
|
NSAccessibilityPositionAttribute, // required
|
|
|
|
NSAccessibilityTopLevelUIElementAttribute, // required
|
|
|
|
NSAccessibilityHelpAttribute,
|
|
|
|
NSAccessibilityEnabledAttribute, // required
|
|
|
|
NSAccessibilityFocusedAttribute, // required
|
|
|
|
NSAccessibilityTitleAttribute, // required
|
|
|
|
NSAccessibilityChildrenAttribute, NSAccessibilityDescriptionAttribute,
|
2012-01-27 19:50:04 +04:00
|
|
|
#if DEBUG
|
2019-01-21 20:18:16 +03:00
|
|
|
@"AXMozDescription",
|
2012-01-27 19:50:04 +04:00
|
|
|
#endif
|
2019-01-21 20:18:16 +03:00
|
|
|
nil];
|
2006-11-15 14:08:14 +03:00
|
|
|
}
|
|
|
|
return attributes;
|
2008-02-22 23:13:17 +03:00
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
2006-11-15 14:08:14 +03:00
|
|
|
}
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (id)accessibilityAttributeValue:(NSString*)attribute {
|
2008-02-22 23:13:17 +03:00
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
|
|
|
|
2015-05-29 18:41:54 +03:00
|
|
|
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
2019-01-21 20:18:16 +03:00
|
|
|
if ([self hasPopup]) return [self children];
|
2006-12-06 16:35:56 +03:00
|
|
|
return nil;
|
2015-05-29 18:41:54 +03:00
|
|
|
}
|
|
|
|
|
2006-12-06 16:35:56 +03:00
|
|
|
return [super accessibilityAttributeValue:attribute];
|
2008-02-22 23:13:17 +03:00
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
2006-12-06 16:35:56 +03:00
|
|
|
}
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (BOOL)accessibilityIsIgnored {
|
2015-07-17 00:35:29 +03:00
|
|
|
return ![self getGeckoAccessible] && ![self getProxyAccessible];
|
2006-11-15 14:08:14 +03:00
|
|
|
}
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (BOOL)hasPopup {
|
2015-08-04 21:56:18 +03:00
|
|
|
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
|
|
|
return accWrap->NativeState() & states::HASPOPUP;
|
|
|
|
|
|
|
|
if (ProxyAccessible* proxy = [self getProxyAccessible])
|
|
|
|
return proxy->NativeState() & states::HASPOPUP;
|
|
|
|
|
|
|
|
return false;
|
2015-05-29 18:41:54 +03:00
|
|
|
}
|
|
|
|
|
2006-11-15 14:08:14 +03:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation mozCheckboxAccessible
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (NSString*)accessibilityActionDescription:(NSString*)action {
|
2008-02-22 23:13:17 +03:00
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
|
|
|
|
2006-11-15 14:08:14 +03:00
|
|
|
if ([action isEqualToString:NSAccessibilityPressAction]) {
|
2019-01-21 20:18:16 +03:00
|
|
|
if ([self isChecked] != kUnchecked) return @"uncheck checkbox"; // XXX: localize this later?
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
return @"check checkbox"; // XXX: localize this later?
|
2006-11-15 14:08:14 +03:00
|
|
|
}
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2006-11-15 14:08:14 +03:00
|
|
|
return nil;
|
2008-02-22 23:13:17 +03:00
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
2006-11-15 14:08:14 +03:00
|
|
|
}
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (int)isChecked {
|
2006-11-24 17:37:00 +03:00
|
|
|
// check if we're checked or in a mixed state
|
2020-03-14 08:39:59 +03:00
|
|
|
uint64_t state = [self state];
|
|
|
|
if (state & (states::CHECKED | states::PRESSED)) {
|
|
|
|
return kChecked;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state & states::MIXED) {
|
|
|
|
return kMixed;
|
2006-11-24 17:37:00 +03:00
|
|
|
}
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2006-11-24 17:37:00 +03:00
|
|
|
return kUnchecked;
|
2006-11-15 14:08:14 +03:00
|
|
|
}
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (id)value {
|
2008-02-22 23:13:17 +03:00
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
|
|
|
|
2006-11-24 17:37:00 +03:00
|
|
|
return [NSNumber numberWithInt:[self isChecked]];
|
2008-02-22 23:13:17 +03:00
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
2006-11-15 14:08:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
2006-12-06 16:35:56 +03:00
|
|
|
|
2012-06-29 03:04:50 +04:00
|
|
|
@implementation mozPaneAccessible
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute {
|
2015-08-04 21:56:18 +03:00
|
|
|
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
|
|
|
ProxyAccessible* proxy = [self getProxyAccessible];
|
2019-01-21 20:18:16 +03:00
|
|
|
if (!accWrap && !proxy) return 0;
|
2012-07-12 04:29:19 +04:00
|
|
|
|
|
|
|
// By default this calls -[[mozAccessible children] count].
|
|
|
|
// Since we don't cache mChildren. This is faster.
|
2015-08-04 21:56:18 +03:00
|
|
|
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
2019-01-21 20:18:16 +03:00
|
|
|
if (accWrap) return accWrap->ChildCount() ? 1 : 0;
|
2015-08-04 21:56:18 +03:00
|
|
|
|
|
|
|
return proxy->ChildrenCount() ? 1 : 0;
|
|
|
|
}
|
2012-07-12 04:29:19 +04:00
|
|
|
|
|
|
|
return [super accessibilityArrayAttributeCount:attribute];
|
|
|
|
}
|
|
|
|
|
2019-01-21 20:18:16 +03:00
|
|
|
- (NSArray*)children {
|
|
|
|
if (![self getGeckoAccessible]) return nil;
|
2012-06-29 03:04:50 +04:00
|
|
|
|
2019-10-21 17:13:44 +03:00
|
|
|
nsDeckFrame* deckFrame = do_QueryFrame([self getGeckoAccessible]->GetFrame());
|
2012-07-30 18:20:58 +04:00
|
|
|
nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
|
2012-06-29 03:04:50 +04:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
Accessible* selectedAcc = nullptr;
|
2012-06-29 03:04:50 +04:00
|
|
|
if (selectedFrame) {
|
|
|
|
nsINode* node = selectedFrame->GetContent();
|
2019-10-21 17:13:44 +03:00
|
|
|
selectedAcc = [self getGeckoAccessible]->Document() -> GetAccessible(node);
|
2012-06-29 03:04:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (selectedAcc) {
|
2019-01-21 20:18:16 +03:00
|
|
|
mozAccessible* curNative = GetNativeFromGeckoAccessible(selectedAcc);
|
|
|
|
if (curNative) return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
|
2012-06-29 03:04:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
2020-03-17 20:32:33 +03:00
|
|
|
|
|
|
|
@implementation mozSliderAccessible
|
|
|
|
|
|
|
|
- (NSArray*)accessibilityActionNames {
|
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
|
|
|
NSArray* actions = [super accessibilityActionNames];
|
|
|
|
|
|
|
|
static NSArray* sliderAttrs = nil;
|
|
|
|
if (!sliderAttrs) {
|
|
|
|
NSMutableArray* tempArray = [NSMutableArray new];
|
|
|
|
[tempArray addObject:NSAccessibilityIncrementAction];
|
|
|
|
[tempArray addObject:NSAccessibilityDecrementAction];
|
|
|
|
sliderAttrs = [[NSArray alloc] initWithArray:tempArray];
|
|
|
|
[tempArray release];
|
|
|
|
}
|
|
|
|
|
|
|
|
return [actions arrayByAddingObjectsFromArray:sliderAttrs];
|
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)accessibilityPerformAction:(NSString*)action {
|
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
|
|
|
|
|
|
|
if ([action isEqualToString:NSAccessibilityIncrementAction]) {
|
|
|
|
[self changeValueBySteps:1];
|
|
|
|
} else if ([action isEqualToString:NSAccessibilityDecrementAction]) {
|
|
|
|
[self changeValueBySteps:-1];
|
|
|
|
} else {
|
|
|
|
[super accessibilityPerformAction:action];
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Updates the accessible's current value by (factor * step).
|
|
|
|
* If incrementing factor should be positive, if decrementing
|
|
|
|
* factor should be negative.
|
|
|
|
*/
|
|
|
|
|
|
|
|
- (void)changeValueBySteps:(int)factor {
|
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
|
|
|
|
|
|
|
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
|
|
|
double newVal = accWrap->CurValue() + (accWrap->Step() * factor);
|
|
|
|
if (newVal >= accWrap->MinValue() && newVal <= accWrap->MaxValue()) {
|
|
|
|
accWrap->SetCurValue(newVal);
|
|
|
|
}
|
|
|
|
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
|
|
|
double newVal = proxy->CurValue() + (proxy->Step() * factor);
|
|
|
|
if (newVal >= proxy->MinValue() && newVal <= proxy->MaxValue()) {
|
|
|
|
proxy->SetCurValue(newVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)valueDidChange {
|
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
|
|
|
|
|
|
|
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
|
|
|
|
NSAccessibilityValueChangedNotification);
|
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|