summaryrefslogtreecommitdiff
path: root/accessible/mac/mozAccessible.mm
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/mac/mozAccessible.mm')
-rw-r--r--accessible/mac/mozAccessible.mm1197
1 files changed, 0 insertions, 1197 deletions
diff --git a/accessible/mac/mozAccessible.mm b/accessible/mac/mozAccessible.mm
deleted file mode 100644
index a02779ef25..0000000000
--- a/accessible/mac/mozAccessible.mm
+++ /dev/null
@@ -1,1197 +0,0 @@
-/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 "mozAccessible.h"
-
-#import "MacUtils.h"
-#import "mozView.h"
-
-#include "Accessible-inl.h"
-#include "nsAccUtils.h"
-#include "nsIAccessibleRelation.h"
-#include "nsIAccessibleEditableText.h"
-#include "nsIPersistentProperties2.h"
-#include "Relation.h"
-#include "Role.h"
-#include "RootAccessible.h"
-#include "TableAccessible.h"
-#include "TableCellAccessible.h"
-#include "mozilla/a11y/PDocAccessible.h"
-#include "OuterDocAccessible.h"
-
-#include "mozilla/Services.h"
-#include "nsRect.h"
-#include "nsCocoaUtils.h"
-#include "nsCoord.h"
-#include "nsObjCExceptions.h"
-#include "nsWhitespaceTokenizer.h"
-#include <prdtoa.h>
-
-using namespace mozilla;
-using namespace mozilla::a11y;
-
-#define NSAccessibilityMathRootRadicandAttribute @"AXMathRootRadicand"
-#define NSAccessibilityMathRootIndexAttribute @"AXMathRootIndex"
-#define NSAccessibilityMathFractionNumeratorAttribute @"AXMathFractionNumerator"
-#define NSAccessibilityMathFractionDenominatorAttribute @"AXMathFractionDenominator"
-#define NSAccessibilityMathBaseAttribute @"AXMathBase"
-#define NSAccessibilityMathSubscriptAttribute @"AXMathSubscript"
-#define NSAccessibilityMathSuperscriptAttribute @"AXMathSuperscript"
-#define NSAccessibilityMathUnderAttribute @"AXMathUnder"
-#define NSAccessibilityMathOverAttribute @"AXMathOver"
-#define NSAccessibilityMathLineThicknessAttribute @"AXMathLineThickness"
-// XXX WebKit also defines the following attributes.
-// See bugs 1176970 and 1176983.
-// - NSAccessibilityMathFencedOpenAttribute @"AXMathFencedOpen"
-// - NSAccessibilityMathFencedCloseAttribute @"AXMathFencedClose"
-// - NSAccessibilityMathPrescriptsAttribute @"AXMathPrescripts"
-// - NSAccessibilityMathPostscriptsAttribute @"AXMathPostscripts"
-
-#pragma mark -
-
-@implementation mozAccessible
-
-- (id)initWithAccessible:(uintptr_t)aGeckoAccessible
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- if ((self = [super init])) {
- mGeckoAccessible = aGeckoAccessible;
- if (aGeckoAccessible & IS_PROXY)
- mRole = [self getProxyAccessible]->Role();
- else
- mRole = [self getGeckoAccessible]->Role();
- }
-
- return self;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (void)dealloc
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- [mChildren release];
- [super dealloc];
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (mozilla::a11y::AccessibleWrap*)getGeckoAccessible
-{
- // Check if mGeckoAccessible points at a proxy
- if (mGeckoAccessible & IS_PROXY)
- return nil;
-
- return reinterpret_cast<AccessibleWrap*>(mGeckoAccessible);
-}
-
-- (mozilla::a11y::ProxyAccessible*)getProxyAccessible
-{
- // Check if mGeckoAccessible points at a proxy
- if (!(mGeckoAccessible & IS_PROXY))
- return nil;
-
- return reinterpret_cast<ProxyAccessible*>(mGeckoAccessible & ~IS_PROXY);
-}
-
-#pragma mark -
-
-- (BOOL)accessibilityIsIgnored
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
-
- // unknown (either unimplemented, or irrelevant) elements are marked as ignored
- // as well as expired elements.
-
- bool noRole = [[self role] isEqualToString:NSAccessibilityUnknownRole];
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- return (noRole && !(accWrap->InteractiveState() & states::FOCUSABLE));
-
- if (ProxyAccessible* proxy = [self getProxyAccessible])
- return (noRole && !(proxy->State() & states::FOCUSABLE));
-
- return true;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
-}
-
-- (NSArray*)additionalAccessibilityAttributeNames
-{
- NSMutableArray* additional = [NSMutableArray array];
- switch (mRole) {
- case roles::MATHML_ROOT:
- [additional addObject:NSAccessibilityMathRootIndexAttribute];
- [additional addObject:NSAccessibilityMathRootRadicandAttribute];
- break;
- case roles::MATHML_SQUARE_ROOT:
- [additional addObject:NSAccessibilityMathRootRadicandAttribute];
- break;
- case roles::MATHML_FRACTION:
- [additional addObject:NSAccessibilityMathFractionNumeratorAttribute];
- [additional addObject:NSAccessibilityMathFractionDenominatorAttribute];
- [additional addObject:NSAccessibilityMathLineThicknessAttribute];
- break;
- case roles::MATHML_SUB:
- case roles::MATHML_SUP:
- case roles::MATHML_SUB_SUP:
- [additional addObject:NSAccessibilityMathBaseAttribute];
- [additional addObject:NSAccessibilityMathSubscriptAttribute];
- [additional addObject:NSAccessibilityMathSuperscriptAttribute];
- break;
- case roles::MATHML_UNDER:
- case roles::MATHML_OVER:
- case roles::MATHML_UNDER_OVER:
- [additional addObject:NSAccessibilityMathBaseAttribute];
- [additional addObject:NSAccessibilityMathUnderAttribute];
- [additional addObject:NSAccessibilityMathOverAttribute];
- break;
- // XXX bug 1176983
- // roles::MATHML_MULTISCRIPTS should also have the following attributes:
- // - NSAccessibilityMathPrescriptsAttribute
- // - NSAccessibilityMathPostscriptsAttribute
- // XXX bug 1176970
- // roles::MATHML_FENCED should also have the following attributes:
- // - NSAccessibilityMathFencedOpenAttribute
- // - NSAccessibilityMathFencedCloseAttribute
- default:
- break;
- }
-
- return additional;
-}
-
-- (NSArray*)accessibilityAttributeNames
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- // if we're expired, we don't support any attributes.
- AccessibleWrap* accWrap = [self getGeckoAccessible];
- ProxyAccessible* proxy = [self getProxyAccessible];
- if (!accWrap && !proxy)
- return [NSArray array];
-
- static NSArray* generalAttributes = nil;
-
- if (!generalAttributes) {
- // standard attributes that are shared and supported by all generic elements.
- generalAttributes = [[NSArray alloc] initWithObjects: NSAccessibilityChildrenAttribute,
- NSAccessibilityParentAttribute,
- NSAccessibilityRoleAttribute,
- NSAccessibilityTitleAttribute,
- NSAccessibilityValueAttribute,
- NSAccessibilitySubroleAttribute,
- NSAccessibilityRoleDescriptionAttribute,
- NSAccessibilityPositionAttribute,
- NSAccessibilityEnabledAttribute,
- NSAccessibilitySizeAttribute,
- NSAccessibilityWindowAttribute,
- NSAccessibilityFocusedAttribute,
- NSAccessibilityHelpAttribute,
- NSAccessibilityTitleUIElementAttribute,
- NSAccessibilityTopLevelUIElementAttribute,
-#if DEBUG
- @"AXMozDescription",
-#endif
- nil];
- }
-
- NSArray* objectAttributes = generalAttributes;
-
- NSArray* additionalAttributes = [self additionalAccessibilityAttributeNames];
- if ([additionalAttributes count])
- objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:additionalAttributes];
-
- return objectAttributes;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (id)childAt:(uint32_t)i
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
- Accessible* child = accWrap->GetChildAt(i);
- return child ? GetNativeFromGeckoAccessible(child) : nil;
- } else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
- ProxyAccessible* child = proxy->ChildAt(i);
- return child ? GetNativeFromProxy(child) : nil;
- }
-
- return nil;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (id)accessibilityAttributeValue:(NSString*)attribute
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- AccessibleWrap* accWrap = [self getGeckoAccessible];
- ProxyAccessible* proxy = [self getProxyAccessible];
- if (!accWrap && !proxy)
- return nil;
-
-#if DEBUG
- if ([attribute isEqualToString:@"AXMozDescription"])
- return [NSString stringWithFormat:@"role = %u native = %@", mRole, [self class]];
-#endif
-
- if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
- return [self children];
- if ([attribute isEqualToString:NSAccessibilityParentAttribute])
- return [self parent];
-
-#ifdef DEBUG_hakan
- NSLog (@"(%@ responding to attr %@)", self, attribute);
-#endif
-
- if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
- return [self role];
- if ([attribute isEqualToString:NSAccessibilityPositionAttribute])
- return [self position];
- if ([attribute isEqualToString:NSAccessibilitySubroleAttribute])
- return [self subrole];
- if ([attribute isEqualToString:NSAccessibilityEnabledAttribute])
- return [NSNumber numberWithBool:[self isEnabled]];
- if ([attribute isEqualToString:NSAccessibilityValueAttribute])
- return [self value];
- if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
- return [self roleDescription];
- if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
- return [NSNumber numberWithBool:[self isFocused]];
- if ([attribute isEqualToString:NSAccessibilitySizeAttribute])
- return [self size];
- if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
- return [self window];
- if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
- return [self window];
- if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
- return [self title];
- if ([attribute isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
- if (accWrap) {
- Relation rel = accWrap->RelationByType(RelationType::LABELLED_BY);
- Accessible* tempAcc = rel.Next();
- return tempAcc ? GetNativeFromGeckoAccessible(tempAcc) : nil;
- }
- nsTArray<ProxyAccessible*> rel = proxy->RelationByType(RelationType::LABELLED_BY);
- ProxyAccessible* tempProxy = rel.SafeElementAt(0);
- return tempProxy ? GetNativeFromProxy(tempProxy) : nil;
- }
- if ([attribute isEqualToString:NSAccessibilityHelpAttribute])
- return [self help];
-
- switch (mRole) {
- case roles::MATHML_ROOT:
- if ([attribute isEqualToString:NSAccessibilityMathRootRadicandAttribute])
- return [self childAt:0];
- if ([attribute isEqualToString:NSAccessibilityMathRootIndexAttribute])
- return [self childAt:1];
- break;
- case roles::MATHML_SQUARE_ROOT:
- if ([attribute isEqualToString:NSAccessibilityMathRootRadicandAttribute])
- return [self childAt:0];
- break;
- case roles::MATHML_FRACTION:
- if ([attribute isEqualToString:NSAccessibilityMathFractionNumeratorAttribute])
- return [self childAt:0];
- if ([attribute isEqualToString:NSAccessibilityMathFractionDenominatorAttribute])
- return [self childAt:1];
- if ([attribute isEqualToString:NSAccessibilityMathLineThicknessAttribute]) {
- // WebKit sets line thickness to some logical value parsed in the
- // renderer object of the <mfrac> element. It's not clear whether the
- // exact value is relevant to assistive technologies. From a semantic
- // point of view, the only important point is to distinguish between
- // <mfrac> elements that have a fraction bar and those that do not.
- // Per the MathML 3 spec, the latter happens iff the linethickness
- // attribute is of the form [zero-float][optional-unit]. In that case we
- // set line thickness to zero and in the other cases we set it to one.
- nsAutoString thickness;
- if (accWrap) {
- nsCOMPtr<nsIPersistentProperties> attributes = accWrap->Attributes();
- nsAccUtils::GetAccAttr(attributes, nsGkAtoms::linethickness_, thickness);
- } else {
- AutoTArray<Attribute, 10> attrs;
- proxy->Attributes(&attrs);
- for (size_t i = 0 ; i < attrs.Length() ; i++) {
- if (attrs.ElementAt(i).Name() == "thickness") {
- thickness = attrs.ElementAt(i).Value();
- break;
- }
- }
- }
- double value = 1.0;
- if (!thickness.IsEmpty())
- value = PR_strtod(NS_LossyConvertUTF16toASCII(thickness).get(),
- nullptr);
- return [NSNumber numberWithInteger:(value ? 1 : 0)];
- }
- break;
- case roles::MATHML_SUB:
- if ([attribute isEqualToString:NSAccessibilityMathBaseAttribute])
- return [self childAt:0];
- if ([attribute isEqualToString:NSAccessibilityMathSubscriptAttribute])
- return [self childAt:1];
-#ifdef DEBUG
- if ([attribute isEqualToString:NSAccessibilityMathSuperscriptAttribute])
- return nil;
-#endif
- break;
- case roles::MATHML_SUP:
- if ([attribute isEqualToString:NSAccessibilityMathBaseAttribute])
- return [self childAt:0];
-#ifdef DEBUG
- if ([attribute isEqualToString:NSAccessibilityMathSubscriptAttribute])
- return nil;
-#endif
- if ([attribute isEqualToString:NSAccessibilityMathSuperscriptAttribute])
- return [self childAt:1];
- break;
- case roles::MATHML_SUB_SUP:
- if ([attribute isEqualToString:NSAccessibilityMathBaseAttribute])
- return [self childAt:0];
- if ([attribute isEqualToString:NSAccessibilityMathSubscriptAttribute])
- return [self childAt:1];
- if ([attribute isEqualToString:NSAccessibilityMathSuperscriptAttribute])
- return [self childAt:2];
- break;
- case roles::MATHML_UNDER:
- if ([attribute isEqualToString:NSAccessibilityMathBaseAttribute])
- return [self childAt:0];
- if ([attribute isEqualToString:NSAccessibilityMathUnderAttribute])
- return [self childAt:1];
-#ifdef DEBUG
- if ([attribute isEqualToString:NSAccessibilityMathOverAttribute])
- return nil;
-#endif
- break;
- case roles::MATHML_OVER:
- if ([attribute isEqualToString:NSAccessibilityMathBaseAttribute])
- return [self childAt:0];
-#ifdef DEBUG
- if ([attribute isEqualToString:NSAccessibilityMathUnderAttribute])
- return nil;
-#endif
- if ([attribute isEqualToString:NSAccessibilityMathOverAttribute])
- return [self childAt:1];
- break;
- case roles::MATHML_UNDER_OVER:
- if ([attribute isEqualToString:NSAccessibilityMathBaseAttribute])
- return [self childAt:0];
- if ([attribute isEqualToString:NSAccessibilityMathUnderAttribute])
- return [self childAt:1];
- if ([attribute isEqualToString:NSAccessibilityMathOverAttribute])
- return [self childAt:2];
- break;
- // XXX bug 1176983
- // roles::MATHML_MULTISCRIPTS should also have the following attributes:
- // - NSAccessibilityMathPrescriptsAttribute
- // - NSAccessibilityMathPostscriptsAttribute
- // XXX bug 1176970
- // roles::MATHML_FENCED should also have the following attributes:
- // - NSAccessibilityMathFencedOpenAttribute
- // - NSAccessibilityMathFencedCloseAttribute
- default:
- break;
- }
-
-#ifdef DEBUG
- NSLog (@"!!! %@ can't respond to attribute %@", self, attribute);
-#endif
- return nil;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
-
- if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
- return [self canBeFocused];
-
- return NO;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
-}
-
-- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
-#ifdef DEBUG_hakan
- NSLog (@"[%@] %@='%@'", self, attribute, value);
-#endif
-
- // we only support focusing elements so far.
- if ([attribute isEqualToString:NSAccessibilityFocusedAttribute] && [value boolValue])
- [self focus];
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (id)accessibilityHitTest:(NSPoint)point
-{
- AccessibleWrap* accWrap = [self getGeckoAccessible];
- ProxyAccessible* proxy = [self getProxyAccessible];
- if (!accWrap && !proxy)
- return nil;
-
- // Convert the given screen-global point in the cocoa coordinate system (with
- // origin in the bottom-left corner of the screen) into point in the Gecko
- // coordinate system (with origin in a top-left screen point).
- NSScreen* mainView = [[NSScreen screens] objectAtIndex:0];
- NSPoint tmpPoint = NSMakePoint(point.x,
- [mainView frame].size.height - point.y);
- LayoutDeviceIntPoint geckoPoint = nsCocoaUtils::
- CocoaPointsToDevPixels(tmpPoint, nsCocoaUtils::GetBackingScaleFactor(mainView));
-
- mozAccessible* nativeChild = nil;
- if (accWrap) {
- Accessible* child = accWrap->ChildAtPoint(geckoPoint.x, geckoPoint.y,
- Accessible::eDeepestChild);
- if (child)
- nativeChild = GetNativeFromGeckoAccessible(child);
- } else if (proxy) {
- ProxyAccessible* child = proxy->ChildAtPoint(geckoPoint.x, geckoPoint.y,
- Accessible::eDeepestChild);
- if (child)
- nativeChild = GetNativeFromProxy(child);
- }
-
- if (nativeChild)
- return nativeChild;
-
- // if we didn't find anything, return ourself or child view.
- return GetObjectOrRepresentedView(self);
-}
-
-- (NSArray*)accessibilityActionNames
-{
- return nil;
-}
-
-- (NSString*)accessibilityActionDescription:(NSString*)action
-{
- // by default we return whatever the MacOS API know about.
- // if you have custom actions, override.
- return NSAccessibilityActionDescription(action);
-}
-
-- (void)accessibilityPerformAction:(NSString*)action
-{
-}
-
-- (id)accessibilityFocusedUIElement
-{
- AccessibleWrap* accWrap = [self getGeckoAccessible];
- ProxyAccessible* proxy = [self getProxyAccessible];
- if (!accWrap && !proxy)
- return nil;
-
- mozAccessible* focusedChild = nil;
- if (accWrap) {
- Accessible* focusedGeckoChild = accWrap->FocusedChild();
- if (focusedGeckoChild)
- focusedChild = GetNativeFromGeckoAccessible(focusedGeckoChild);
- } else if (proxy) {
- ProxyAccessible* focusedGeckoChild = proxy->FocusedChild();
- if (focusedGeckoChild)
- focusedChild = GetNativeFromProxy(focusedGeckoChild);
- }
-
- if (focusedChild)
- return GetObjectOrRepresentedView(focusedChild);
-
- // return ourself if we can't get a native focused child.
- return GetObjectOrRepresentedView(self);
-}
-
-#pragma mark -
-
-- (id <mozAccessible>)parent
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- id nativeParent = nil;
- if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
- Accessible* accessibleParent = accWrap->Parent();
- if (accessibleParent)
- nativeParent = GetNativeFromGeckoAccessible(accessibleParent);
- if (nativeParent)
- return GetObjectOrRepresentedView(nativeParent);
-
- // Return native of root accessible if we have no direct parent
- nativeParent = GetNativeFromGeckoAccessible(accWrap->RootAccessible());
- } else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
- if (ProxyAccessible* proxyParent = proxy->Parent()) {
- nativeParent = GetNativeFromProxy(proxyParent);
- }
-
- if (nativeParent)
- return GetObjectOrRepresentedView(nativeParent);
-
- Accessible* outerDoc = proxy->OuterDocOfRemoteBrowser();
- nativeParent = outerDoc ?
- GetNativeFromGeckoAccessible(outerDoc) : nil;
- } else {
- return nil;
- }
-
- NSAssert1 (nativeParent, @"!!! we can't find a parent for %@", self);
-
- return GetObjectOrRepresentedView(nativeParent);
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (BOOL)hasRepresentedView
-{
- return NO;
-}
-
-- (id)representedView
-{
- return nil;
-}
-
-- (BOOL)isRoot
-{
- return NO;
-}
-
-// gets our native children lazily.
-// returns nil when there are no children.
-- (NSArray*)children
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- if (mChildren)
- return mChildren;
-
- // get the array of children.
- mChildren = [[NSMutableArray alloc] init];
-
- AccessibleWrap* accWrap = [self getGeckoAccessible];
- if (accWrap) {
- uint32_t childCount = accWrap->ChildCount();
- for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
- mozAccessible* nativeChild = GetNativeFromGeckoAccessible(accWrap->GetChildAt(childIdx));
- if (nativeChild)
- [mChildren addObject:nativeChild];
- }
-
- // children from child if this is an outerdoc
- OuterDocAccessible* docOwner = accWrap->AsOuterDoc();
- if (docOwner) {
- if (ProxyAccessible* proxyDoc = docOwner->RemoteChildDoc()) {
- mozAccessible* nativeRemoteChild = GetNativeFromProxy(proxyDoc);
- [mChildren insertObject:nativeRemoteChild atIndex:0];
- NSAssert1 (nativeRemoteChild, @"%@ found a child remote doc missing a native\n", self);
- }
- }
- } else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
- uint32_t childCount = proxy->ChildrenCount();
- for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
- mozAccessible* nativeChild = GetNativeFromProxy(proxy->ChildAt(childIdx));
- if (nativeChild)
- [mChildren addObject:nativeChild];
- }
-
- }
-
- return mChildren;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (NSValue*)position
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- nsIntRect rect;
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- rect = accWrap->Bounds();
- else if (ProxyAccessible* proxy = [self getProxyAccessible])
- rect = proxy->Bounds();
- else
- return nil;
-
- NSScreen* mainView = [[NSScreen screens] objectAtIndex:0];
- CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(mainView);
- NSPoint p = NSMakePoint(static_cast<CGFloat>(rect.x) / scaleFactor,
- [mainView frame].size.height - static_cast<CGFloat>(rect.y + rect.height) / scaleFactor);
-
- return [NSValue valueWithPoint:p];
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (NSValue*)size
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- nsIntRect rect;
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- rect = accWrap->Bounds();
- else if (ProxyAccessible* proxy = [self getProxyAccessible])
- rect = proxy->Bounds();
- else
- return nil;
-
- CGFloat scaleFactor =
- nsCocoaUtils::GetBackingScaleFactor([[NSScreen screens] objectAtIndex:0]);
- return [NSValue valueWithSize:NSMakeSize(static_cast<CGFloat>(rect.width) / scaleFactor,
- static_cast<CGFloat>(rect.height) / scaleFactor)];
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (NSString*)role
-{
- AccessibleWrap* accWrap = [self getGeckoAccessible];
- if (accWrap) {
- #ifdef DEBUG_A11Y
- NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap),
- "Does not support Text when it should");
- #endif
- } else if (![self getProxyAccessible]) {
- return nil;
- }
-
-#define ROLE(geckoRole, stringRole, atkRole, macRole, msaaRole, ia2Role, nameRule) \
- case roles::geckoRole: \
- return macRole;
-
- switch (mRole) {
-#include "RoleMap.h"
- default:
- NS_NOTREACHED("Unknown role.");
- return NSAccessibilityUnknownRole;
- }
-
-#undef ROLE
-}
-
-- (NSString*)subrole
-{
- AccessibleWrap* accWrap = [self getGeckoAccessible];
- ProxyAccessible* proxy = [self getProxyAccessible];
-
- // Deal with landmarks first
- nsIAtom* landmark = nullptr;
- if (accWrap)
- landmark = accWrap->LandmarkRole();
- else if (proxy)
- landmark = proxy->LandmarkRole();
-
- if (landmark) {
- if (landmark == nsGkAtoms::application)
- return @"AXLandmarkApplication";
- if (landmark == nsGkAtoms::banner)
- return @"AXLandmarkBanner";
- if (landmark == nsGkAtoms::complementary)
- return @"AXLandmarkComplementary";
- if (landmark == nsGkAtoms::contentinfo)
- return @"AXLandmarkContentInfo";
- if (landmark == nsGkAtoms::form)
- return @"AXLandmarkForm";
- if (landmark == nsGkAtoms::main)
- return @"AXLandmarkMain";
- if (landmark == nsGkAtoms::navigation)
- return @"AXLandmarkNavigation";
- if (landmark == nsGkAtoms::search)
- return @"AXLandmarkSearch";
- if (landmark == nsGkAtoms::searchbox)
- return @"AXSearchField";
- }
-
- // Now, deal with widget roles
- nsIAtom* roleAtom = nullptr;
- if (accWrap && accWrap->HasARIARole()) {
- const nsRoleMapEntry* roleMap = accWrap->ARIARoleMap();
- roleAtom = *roleMap->roleAtom;
- }
- if (proxy)
- roleAtom = proxy->ARIARoleAtom();
-
- if (roleAtom) {
- if (roleAtom == nsGkAtoms::alert)
- return @"AXApplicationAlert";
- if (roleAtom == nsGkAtoms::alertdialog)
- return @"AXApplicationAlertDialog";
- if (roleAtom == nsGkAtoms::article)
- return @"AXDocumentArticle";
- if (roleAtom == nsGkAtoms::dialog)
- return @"AXApplicationDialog";
- if (roleAtom == nsGkAtoms::document)
- return @"AXDocument";
- if (roleAtom == nsGkAtoms::log_)
- return @"AXApplicationLog";
- if (roleAtom == nsGkAtoms::math)
- return @"AXDocumentMath";
- if (roleAtom == nsGkAtoms::note_)
- return @"AXDocumentNote";
- if (roleAtom == nsGkAtoms::region)
- return @"AXDocumentRegion";
- if (roleAtom == nsGkAtoms::status)
- return @"AXApplicationStatus";
- if (roleAtom == nsGkAtoms::tabpanel)
- return @"AXTabPanel";
- if (roleAtom == nsGkAtoms::timer)
- return @"AXApplicationTimer";
- if (roleAtom == nsGkAtoms::tooltip)
- return @"AXUserInterfaceTooltip";
- }
-
- switch (mRole) {
- case roles::LIST:
- return @"AXContentList"; // 10.6+ NSAccessibilityContentListSubrole;
-
- case roles::ENTRY:
- if ((accWrap && accWrap->IsSearchbox()) ||
- (proxy && proxy->IsSearchbox()))
- return @"AXSearchField";
- break;
-
- case roles::DEFINITION_LIST:
- return @"AXDefinitionList"; // 10.6+ NSAccessibilityDefinitionListSubrole;
-
- case roles::TERM:
- return @"AXTerm";
-
- case roles::DEFINITION:
- return @"AXDefinition";
-
- case roles::MATHML_MATH:
- return @"AXDocumentMath";
-
- case roles::MATHML_FRACTION:
- return @"AXMathFraction";
-
- case roles::MATHML_FENCED:
- // XXX bug 1176970
- // This should be AXMathFence, but doing so without implementing the
- // whole fence interface seems to make VoiceOver crash, so we present it
- // as a row for now.
- return @"AXMathRow";
-
- case roles::MATHML_SUB:
- case roles::MATHML_SUP:
- case roles::MATHML_SUB_SUP:
- return @"AXMathSubscriptSuperscript";
-
- case roles::MATHML_ROW:
- case roles::MATHML_STYLE:
- case roles::MATHML_ERROR:
- return @"AXMathRow";
-
- case roles::MATHML_UNDER:
- case roles::MATHML_OVER:
- case roles::MATHML_UNDER_OVER:
- return @"AXMathUnderOver";
-
- case roles::MATHML_SQUARE_ROOT:
- return @"AXMathSquareRoot";
-
- case roles::MATHML_ROOT:
- return @"AXMathRoot";
-
- case roles::MATHML_TEXT:
- return @"AXMathText";
-
- case roles::MATHML_NUMBER:
- return @"AXMathNumber";
-
- case roles::MATHML_IDENTIFIER:
- return @"AXMathIdentifier";
-
- case roles::MATHML_TABLE:
- return @"AXMathTable";
-
- case roles::MATHML_TABLE_ROW:
- return @"AXMathTableRow";
-
- case roles::MATHML_CELL:
- return @"AXMathTableCell";
-
- // XXX: NSAccessibility also uses subroles AXMathSeparatorOperator and
- // AXMathFenceOperator. We should use the NS_MATHML_OPERATOR_FENCE and
- // NS_MATHML_OPERATOR_SEPARATOR bits of nsOperatorFlags, but currently they
- // are only available from the MathML layout code. Hence we just fallback
- // to subrole AXMathOperator for now.
- // XXX bug 1175747 WebKit also creates anonymous operators for <mfenced>
- // which have subroles AXMathSeparatorOperator and AXMathFenceOperator.
- case roles::MATHML_OPERATOR:
- return @"AXMathOperator";
-
- case roles::MATHML_MULTISCRIPTS:
- return @"AXMathMultiscript";
-
- case roles::SWITCH:
- return @"AXSwitch";
-
- case roles::ALERT:
- return @"AXApplicationAlert";
-
- case roles::SEPARATOR:
- return @"AXContentSeparator";
-
- case roles::PROPERTYPAGE:
- return @"AXTabPanel";
-
- case roles::DETAILS:
- return @"AXDetails";
-
- case roles::SUMMARY:
- return @"AXSummary";
-
- default:
- break;
- }
-
- return nil;
-}
-
-struct RoleDescrMap
-{
- NSString* role;
- const nsString description;
-};
-
-static const RoleDescrMap sRoleDescrMap[] = {
- { @"AXApplicationAlert", NS_LITERAL_STRING("alert") },
- { @"AXApplicationAlertDialog", NS_LITERAL_STRING("alertDialog") },
- { @"AXApplicationLog", NS_LITERAL_STRING("log") },
- { @"AXApplicationStatus", NS_LITERAL_STRING("status") },
- { @"AXApplicationTimer", NS_LITERAL_STRING("timer") },
- { @"AXContentSeparator", NS_LITERAL_STRING("separator") },
- { @"AXDefinition", NS_LITERAL_STRING("definition") },
- { @"AXDocument", NS_LITERAL_STRING("document") },
- { @"AXDocumentArticle", NS_LITERAL_STRING("article") },
- { @"AXDocumentMath", NS_LITERAL_STRING("math") },
- { @"AXDocumentNote", NS_LITERAL_STRING("note") },
- { @"AXDocumentRegion", NS_LITERAL_STRING("region") },
- { @"AXLandmarkApplication", NS_LITERAL_STRING("application") },
- { @"AXLandmarkBanner", NS_LITERAL_STRING("banner") },
- { @"AXLandmarkComplementary", NS_LITERAL_STRING("complementary") },
- { @"AXLandmarkContentInfo", NS_LITERAL_STRING("content") },
- { @"AXLandmarkMain", NS_LITERAL_STRING("main") },
- { @"AXLandmarkNavigation", NS_LITERAL_STRING("navigation") },
- { @"AXLandmarkSearch", NS_LITERAL_STRING("search") },
- { @"AXSearchField", NS_LITERAL_STRING("searchTextField") },
- { @"AXTabPanel", NS_LITERAL_STRING("tabPanel") },
- { @"AXTerm", NS_LITERAL_STRING("term") },
- { @"AXUserInterfaceTooltip", NS_LITERAL_STRING("tooltip") }
-};
-
-struct RoleDescrComparator
-{
- const NSString* mRole;
- explicit RoleDescrComparator(const NSString* aRole) : mRole(aRole) {}
- int operator()(const RoleDescrMap& aEntry) const {
- return [mRole compare:aEntry.role];
- }
-};
-
-- (NSString*)roleDescription
-{
- if (mRole == roles::DOCUMENT)
- return utils::LocalizedString(NS_LITERAL_STRING("htmlContent"));
-
- NSString* subrole = [self subrole];
-
- if (subrole) {
- size_t idx = 0;
- if (BinarySearchIf(sRoleDescrMap, 0, ArrayLength(sRoleDescrMap),
- RoleDescrComparator(subrole), &idx)) {
- return utils::LocalizedString(sRoleDescrMap[idx].description);
- }
- }
-
- return NSAccessibilityRoleDescription([self role], subrole);
-}
-
-- (NSString*)title
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- nsAutoString title;
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- accWrap->Name(title);
- else if (ProxyAccessible* proxy = [self getProxyAccessible])
- proxy->Name(title);
-
- return nsCocoaUtils::ToNSString(title);
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (id)value
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- nsAutoString value;
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- accWrap->Value(value);
- else if (ProxyAccessible* proxy = [self getProxyAccessible])
- proxy->Value(value);
-
- return nsCocoaUtils::ToNSString(value);
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (void)valueDidChange
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
-#ifdef DEBUG_hakan
- NSLog(@"%@'s value changed!", self);
-#endif
- // sending out a notification is expensive, so we don't do it other than for really important objects,
- // like mozTextAccessible.
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (void)selectedTextDidChange
-{
- // Do nothing. mozTextAccessible will.
-}
-
-- (void)documentLoadComplete
-{
- id realSelf = GetObjectOrRepresentedView(self);
- NSAccessibilityPostNotification(realSelf, NSAccessibilityFocusedUIElementChangedNotification);
- NSAccessibilityPostNotification(realSelf, @"AXLoadComplete");
- NSAccessibilityPostNotification(realSelf, @"AXLayoutComplete");
-}
-
-- (NSString*)help
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- // What needs to go here is actually the accDescription of an item.
- // The MSAA acc_help method has nothing to do with this one.
- nsAutoString helpText;
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- accWrap->Description(helpText);
- else if (ProxyAccessible* proxy = [self getProxyAccessible])
- proxy->Description(helpText);
-
- return nsCocoaUtils::ToNSString(helpText);
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-// objc-style description (from NSObject); not to be confused with the accessible description above.
-- (NSString*)description
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- return [NSString stringWithFormat:@"(%p) %@", self, [self role]];
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (BOOL)isFocused
-{
- return FocusMgr()->IsFocused([self getGeckoAccessible]);
-}
-
-- (BOOL)canBeFocused
-{
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- return accWrap->InteractiveState() & states::FOCUSABLE;
-
- if (ProxyAccessible* proxy = [self getProxyAccessible])
- return proxy->State() & states::FOCUSABLE;
-
- return false;
-}
-
-- (BOOL)focus
-{
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- accWrap->TakeFocus();
- else if (ProxyAccessible* proxy = [self getProxyAccessible])
- proxy->TakeFocus();
- else
- return NO;
-
- return YES;
-}
-
-- (BOOL)isEnabled
-{
- if (AccessibleWrap* accWrap = [self getGeckoAccessible])
- return ((accWrap->InteractiveState() & states::UNAVAILABLE) == 0);
-
- if (ProxyAccessible* proxy = [self getProxyAccessible])
- return ((proxy->State() & states::UNAVAILABLE) == 0);
-
- return false;
-}
-
-// The root accessible calls this when the focused node was
-// changed to us.
-- (void)didReceiveFocus
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
-#ifdef DEBUG_hakan
- NSLog (@"%@ received focus!", self);
-#endif
- NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
- NSAccessibilityFocusedUIElementChangedNotification);
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (NSWindow*)window
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- // Get a pointer to the native window (NSWindow) we reside in.
- NSWindow *nativeWindow = nil;
- DocAccessible* docAcc = nullptr;
- if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
- docAcc = accWrap->Document();
- } else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
- Accessible* outerDoc = proxy->OuterDocOfRemoteBrowser();
- if (outerDoc)
- docAcc = outerDoc->Document();
- }
-
- if (docAcc)
- nativeWindow = static_cast<NSWindow*>(docAcc->GetNativeWindow());
-
- NSAssert1(nativeWindow, @"Could not get native window for %@", self);
- return nativeWindow;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (void)invalidateChildren
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- // make room for new children
- [mChildren release];
- mChildren = nil;
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (void)appendChild:(Accessible*)aAccessible
-{
- // if mChildren is nil, then we don't even need to bother
- if (!mChildren)
- return;
-
- mozAccessible *curNative = GetNativeFromGeckoAccessible(aAccessible);
- if (curNative)
- [mChildren addObject:curNative];
-}
-
-- (void)expire
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- [self invalidateChildren];
-
- mGeckoAccessible = 0;
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (BOOL)isExpired
-{
- return ![self getGeckoAccessible] && ![self getProxyAccessible];
-}
-
-#pragma mark -
-#pragma mark Debug methods
-#pragma mark -
-
-#ifdef DEBUG
-
-// will check that our children actually reference us as their
-// parent.
-- (void)sanityCheckChildren:(NSArray *)children
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- NSEnumerator *iter = [children objectEnumerator];
- mozAccessible *curObj = nil;
-
- NSLog(@"sanity checking %@", self);
-
- while ((curObj = [iter nextObject])) {
- id realSelf = GetObjectOrRepresentedView(self);
- NSLog(@"checking %@", realSelf);
- NSAssert2([curObj parent] == realSelf,
- @"!!! %@ not returning %@ as AXParent, even though it is a AXChild of it!", curObj, realSelf);
- }
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (void)sanityCheckChildren
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- [self sanityCheckChildren:[self children]];
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (void)printHierarchy
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- [self printHierarchyWithLevel:0];
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (void)printHierarchyWithLevel:(unsigned)level
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- NSAssert(![self isExpired], @"!!! trying to print hierarchy of expired object!");
-
- // print this node
- NSMutableString *indent = [NSMutableString stringWithCapacity:level];
- unsigned i=0;
- for (;i<level;i++)
- [indent appendString:@" "];
-
- NSLog (@"%@(#%i) %@", indent, level, self);
-
- // use |children| method to make sure our children are lazily fetched first.
- NSArray *children = [self children];
- if (!children)
- return;
-
- [self sanityCheckChildren];
-
- NSEnumerator *iter = [children objectEnumerator];
- mozAccessible *object = nil;
-
- while (iter && (object = [iter nextObject]))
- // print every child node's subtree, increasing the indenting
- // by two for every level.
- [object printHierarchyWithLevel:(level+1)];
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-#endif /* DEBUG */
-
-@end