зеркало из https://github.com/mozilla/gecko-dev.git
229 строки
5.7 KiB
Plaintext
229 строки
5.7 KiB
Plaintext
/* clang-format off */
|
|
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* clang-format on */
|
|
/* 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/. */
|
|
|
|
#import "mozActionElements.h"
|
|
|
|
#import "MacUtils.h"
|
|
#include "LocalAccessible-inl.h"
|
|
#include "DocAccessible.h"
|
|
#include "XULTabAccessible.h"
|
|
#include "HTMLFormControlAccessible.h"
|
|
|
|
#include "nsCocoaUtils.h"
|
|
#include "mozilla/FloatingPoint.h"
|
|
|
|
using namespace mozilla::a11y;
|
|
|
|
@implementation mozButtonAccessible
|
|
|
|
- (NSNumber*)moxHasPopup {
|
|
return @([self stateWithMask:states::HASPOPUP] != 0);
|
|
}
|
|
|
|
- (NSString*)moxPopupValue {
|
|
if ([self stateWithMask:states::HASPOPUP] != 0) {
|
|
return utils::GetAccAttr(self, nsGkAtoms::aria_haspopup);
|
|
}
|
|
|
|
return nil;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation mozPopupButtonAccessible
|
|
|
|
- (NSString*)moxTitle {
|
|
// Popup buttons don't have titles.
|
|
return @"";
|
|
}
|
|
|
|
- (BOOL)moxBlockSelector:(SEL)selector {
|
|
if (selector == @selector(moxHasPopup)) {
|
|
return YES;
|
|
}
|
|
|
|
return [super moxBlockSelector:selector];
|
|
}
|
|
|
|
- (NSArray*)moxChildren {
|
|
if ([self stateWithMask:states::EXPANDED] == 0) {
|
|
// If the popup button is collapsed don't return its children.
|
|
return @[];
|
|
}
|
|
|
|
return [super moxChildren];
|
|
}
|
|
|
|
- (void)stateChanged:(uint64_t)state isEnabled:(BOOL)enabled {
|
|
[super stateChanged:state isEnabled:enabled];
|
|
|
|
if (state == states::EXPANDED) {
|
|
// If the EXPANDED state is updated, fire AXMenu events on the
|
|
// popups child which is the actual menu.
|
|
if (mozAccessible* popup = (mozAccessible*)[self childAt:0]) {
|
|
[popup moxPostNotification:(enabled ? @"AXMenuOpened" : @"AXMenuClosed")];
|
|
}
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation mozRadioButtonAccessible
|
|
|
|
- (NSArray*)moxLinkedUIElements {
|
|
return [[self getRelationsByType:RelationType::MEMBER_OF]
|
|
arrayByAddingObjectsFromArray:[super moxLinkedUIElements]];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation mozCheckboxAccessible
|
|
|
|
- (int)isChecked {
|
|
// check if we're checked or in a mixed state
|
|
uint64_t state =
|
|
[self stateWithMask:(states::CHECKED | states::PRESSED | states::MIXED)];
|
|
if (state & (states::CHECKED | states::PRESSED)) {
|
|
return kChecked;
|
|
}
|
|
|
|
if (state & states::MIXED) {
|
|
return kMixed;
|
|
}
|
|
|
|
return kUnchecked;
|
|
}
|
|
|
|
- (id)moxValue {
|
|
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
|
|
|
|
return [NSNumber numberWithInt:[self isChecked]];
|
|
|
|
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
|
|
}
|
|
|
|
- (void)stateChanged:(uint64_t)state isEnabled:(BOOL)enabled {
|
|
[super stateChanged:state isEnabled:enabled];
|
|
|
|
if (state & (states::CHECKED | states::PRESSED | states::MIXED)) {
|
|
[self moxPostNotification:NSAccessibilityValueChangedNotification];
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation mozPaneAccessible
|
|
|
|
- (NSArray*)moxChildren {
|
|
// By default, all tab panels are exposed in the a11y tree
|
|
// even if the tab they represent isn't the active tab. To
|
|
// prevent VoiceOver from navigating background tab content,
|
|
// only expose the tab panel that is currently on screen.
|
|
for (mozAccessible* child in [super moxChildren]) {
|
|
if (!([child state] & states::OFFSCREEN)) {
|
|
return [NSArray arrayWithObject:GetObjectOrRepresentedView(child)];
|
|
}
|
|
}
|
|
MOZ_ASSERT_UNREACHABLE("We have no on screen tab content?");
|
|
return @[];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation mozIncrementableAccessible
|
|
|
|
- (id)moxValue {
|
|
return [NSNumber numberWithDouble:mGeckoAccessible->CurValue()];
|
|
}
|
|
|
|
- (NSString*)moxValueDescription {
|
|
nsAutoString valueDesc;
|
|
mGeckoAccessible->Value(valueDesc);
|
|
return nsCocoaUtils::ToNSString(valueDesc);
|
|
}
|
|
- (id)moxMinValue {
|
|
return [NSNumber numberWithDouble:mGeckoAccessible->MinValue()];
|
|
}
|
|
|
|
- (id)moxMaxValue {
|
|
return [NSNumber numberWithDouble:mGeckoAccessible->MaxValue()];
|
|
}
|
|
|
|
- (void)moxSetValue:(id)value {
|
|
[self setValue:([value doubleValue])];
|
|
}
|
|
|
|
- (void)moxPerformIncrement {
|
|
[self changeValueBySteps:1];
|
|
}
|
|
|
|
- (void)moxPerformDecrement {
|
|
[self changeValueBySteps:-1];
|
|
}
|
|
|
|
- (NSString*)moxOrientation {
|
|
RefPtr<AccAttributes> attributes = mGeckoAccessible->Attributes();
|
|
if (attributes) {
|
|
nsAutoString result;
|
|
attributes->GetAttribute(nsGkAtoms::aria_orientation, result);
|
|
if (result.Equals(u"horizontal"_ns)) {
|
|
return NSAccessibilityHorizontalOrientationValue;
|
|
} else if (result.Equals(u"vertical"_ns)) {
|
|
return NSAccessibilityVerticalOrientationValue;
|
|
}
|
|
}
|
|
|
|
return NSAccessibilityUnknownOrientationValue;
|
|
}
|
|
|
|
- (void)handleAccessibleEvent:(uint32_t)eventType {
|
|
switch (eventType) {
|
|
case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
|
|
case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
|
|
[self moxPostNotification:NSAccessibilityValueChangedNotification];
|
|
break;
|
|
default:
|
|
[super handleAccessibleEvent:eventType];
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Updates the accessible's current value by factor and step.
|
|
*
|
|
* factor: A signed integer representing the number of times to
|
|
* apply step to the current value. A positive value will increment,
|
|
* while a negative one will decrement.
|
|
* step: An unsigned integer specified by the webauthor and indicating the
|
|
* amount by which to increment/decrement the current value.
|
|
*/
|
|
- (void)changeValueBySteps:(int)factor {
|
|
MOZ_ASSERT(mGeckoAccessible, "mGeckoAccessible is null");
|
|
|
|
double newValue =
|
|
mGeckoAccessible->CurValue() + (mGeckoAccessible->Step() * factor);
|
|
[self setValue:(newValue)];
|
|
}
|
|
|
|
/*
|
|
* Updates the accessible's current value to the specified value
|
|
*/
|
|
- (void)setValue:(double)value {
|
|
MOZ_ASSERT(mGeckoAccessible, "mGeckoAccessible is null");
|
|
mGeckoAccessible->SetCurValue(value);
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation mozDatePickerAccessible
|
|
|
|
- (NSString*)moxTitle {
|
|
return utils::LocalizedString(u"dateField"_ns);
|
|
}
|
|
|
|
@end
|