diff --git a/accessible/mac/AccessibleWrap.mm b/accessible/mac/AccessibleWrap.mm index 9467988dcf23..e8481e8565d1 100644 --- a/accessible/mac/AccessibleWrap.mm +++ b/accessible/mac/AccessibleWrap.mm @@ -232,6 +232,9 @@ Class a11y::GetTypeFromRole(roles::Role aRole) { case roles::TOGGLE_BUTTON: return [mozCheckboxAccessible class]; + case roles::SLIDER: + return [mozSliderAccessible class]; + case roles::HEADING: return [mozHeadingAccessible class]; diff --git a/accessible/mac/mozActionElements.h b/accessible/mac/mozActionElements.h index 68197fc88872..3ccb421f16ca 100644 --- a/accessible/mac/mozActionElements.h +++ b/accessible/mac/mozActionElements.h @@ -25,3 +25,10 @@ @interface mozPaneAccessible : mozAccessible @end + +/** + * Accessible for a slider + */ +@interface mozSliderAccessible : mozAccessible + +@end diff --git a/accessible/mac/mozActionElements.mm b/accessible/mac/mozActionElements.mm index 0328598631df..732f1279efd6 100644 --- a/accessible/mac/mozActionElements.mm +++ b/accessible/mac/mozActionElements.mm @@ -220,3 +220,72 @@ enum CheckboxValue { } @end + +@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